new file: 0.3/README.md
new file: 0.3/autoblog.php new file: 0.3/config.php new file: 0.3/icon-logo.svg new file: 0.3/index.php new file: 0.3/xsaf3.php
This commit is contained in:
parent
bc75674380
commit
34d122a50c
6 changed files with 1659 additions and 0 deletions
18
0.3/README.md
Executable file
18
0.3/README.md
Executable file
|
@ -0,0 +1,18 @@
|
|||
Projet Autoblog serie 0.3
|
||||
==============
|
||||
|
||||
PHASE BETA ! "git pullez" souvent, et merci pour vos rapports de bugs.
|
||||
|
||||
Auteurs: Mitsu (https://www.suumitsu.eu/) & Oros (https://www.ecirtam.net/)
|
||||
|
||||
Licence: Domaine Public
|
||||
|
||||
- À propos du Projet Autoblog
|
||||
|
||||
lire: http://sebsauvage.net/streisand.me/fr/
|
||||
|
||||
Instructions
|
||||
|
||||
- uploader les fichiers sur un serveur avec PHP 5.3+
|
||||
|
||||
- ..c'est tout. Hackez le code pour apprendre comment ça marche et comment le personnaliser :)
|
881
0.3/autoblog.php
Executable file
881
0.3/autoblog.php
Executable file
|
@ -0,0 +1,881 @@
|
|||
<?php
|
||||
/*
|
||||
VroumVroumBlog 0.3.0
|
||||
This blog automatically publishes articles from an external RSS 2.0 or ATOM feed.
|
||||
|
||||
Requirement for the source RSS feed:
|
||||
- Source feed MUST be a valid RSS 2.0, RDF 1.0 or ATOM 1.0 feed.
|
||||
- Source feed MUST be valid UTF-8
|
||||
- Source feed MUST contain article body
|
||||
|
||||
This program is public domain. COPY COPY COPY !
|
||||
*/
|
||||
$vvbversion = '0.3.0';
|
||||
if (!version_compare(phpversion(), '5.3.0', '>='))
|
||||
die("This software requires PHP version 5.3.0 at least, yours is ".phpversion());
|
||||
|
||||
if (!class_exists('SQLite3'))
|
||||
die("This software requires the SQLite3 PHP extension, and it can't be found on this system!");
|
||||
|
||||
libxml_disable_entity_loader(true);
|
||||
|
||||
// Config and data file locations
|
||||
|
||||
if (file_exists(__DIR__ . '/config.php'))
|
||||
{
|
||||
require_once __DIR__ . '/config.php';
|
||||
}
|
||||
|
||||
if (!defined('ROOT_DIR'))
|
||||
define('ROOT_DIR', __DIR__);
|
||||
|
||||
if (!defined('CONFIG_FILE')) define('CONFIG_FILE', ROOT_DIR . '/vvb.ini');
|
||||
if (!defined('ARTICLES_DB_FILE')) define('ARTICLES_DB_FILE', ROOT_DIR . '/articles.db');
|
||||
if (!defined('MEDIA_DIR')) define('MEDIA_DIR', ROOT_DIR . '/media');
|
||||
|
||||
if (!defined('LOCAL_URL'))
|
||||
{
|
||||
// Automagic URL discover
|
||||
$path = substr(ROOT_DIR, strlen($_SERVER['DOCUMENT_ROOT']));
|
||||
$path = (!empty($path[0]) && $path[0] != '/') ? '/' . $path : $path;
|
||||
$path = (substr($path, -1) != '/') ? $path . '/' : $path;
|
||||
define('LOCAL_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $path);
|
||||
}
|
||||
|
||||
if (!defined('LOCAL_URI'))
|
||||
{
|
||||
// filename
|
||||
define('LOCAL_URI', (basename($_SERVER['SCRIPT_FILENAME']) == 'index.php' ? '' : basename($_SERVER['SCRIPT_FILENAME'])) . '?');
|
||||
}
|
||||
|
||||
if (!function_exists('__'))
|
||||
{
|
||||
// Translation?
|
||||
function __($str)
|
||||
{
|
||||
if ($str == '_date_format')
|
||||
return '%A %e %B %Y at %H:%M';
|
||||
else
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ERROR MANAGEMENT
|
||||
|
||||
class VroumVroum_User_Exception extends Exception {}
|
||||
|
||||
class VroumVroum_Feed_Exception extends Exception
|
||||
{
|
||||
static public function getXMLErrorsAsString($errors)
|
||||
{
|
||||
$out = array();
|
||||
|
||||
foreach ($errors as $error)
|
||||
{
|
||||
$return = $xml[$error->line - 1] . "\n";
|
||||
$return .= str_repeat('-', $error->column) . "^\n";
|
||||
|
||||
switch ($error->level) {
|
||||
case LIBXML_ERR_WARNING:
|
||||
$return .= "Warning ".$error->code.": ";
|
||||
break;
|
||||
case LIBXML_ERR_ERROR:
|
||||
$return .= "Error ".$error->code.": ";
|
||||
break;
|
||||
case LIBXML_ERR_FATAL:
|
||||
$return .= "Fatal Error ".$error->code.": ";
|
||||
break;
|
||||
}
|
||||
|
||||
$return .= trim($error->message) .
|
||||
"\n Line: ".$error->line .
|
||||
"\n Column: ".$error->column;
|
||||
|
||||
if ($error->file) {
|
||||
$return .= "\n File: ".$error->file;
|
||||
}
|
||||
|
||||
$out[] = $return;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
function exception_error_handler($errno, $errstr, $errfile, $errline )
|
||||
{
|
||||
// For @ ignored errors
|
||||
if (error_reporting() === 0) return;
|
||||
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
}
|
||||
|
||||
function exception_handler($e)
|
||||
{
|
||||
if ($e instanceOf VroumVroum_User_Exception)
|
||||
{
|
||||
echo '<h3>'.$e->getMessage().'</h3>';
|
||||
exit;
|
||||
}
|
||||
|
||||
$error = "Error happened !\n\n".
|
||||
$e->getCode()." - ".$e->getMessage()."\n\nIn: ".
|
||||
$e->getFile() . ":" . $e->getLine()."\n\n";
|
||||
|
||||
if (!empty($_SERVER['HTTP_HOST']))
|
||||
$error .= 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n\n";
|
||||
|
||||
$error .= $e->getTraceAsString();
|
||||
//$error .= print_r($_SERVER, true);
|
||||
|
||||
echo $error;
|
||||
exit;
|
||||
}
|
||||
|
||||
set_error_handler("exception_error_handler");
|
||||
set_exception_handler("exception_handler");
|
||||
|
||||
// CONFIGURATION
|
||||
|
||||
class VroumVroum_Config
|
||||
{
|
||||
public $site_type = '';
|
||||
public $site_title = '';
|
||||
public $site_description = '';
|
||||
public $site_url = '';
|
||||
public $feed_url = '';
|
||||
public $articles_per_page = 10;
|
||||
public $update_interval = 3600;
|
||||
public $update_timeout = 10;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (!file_exists(CONFIG_FILE))
|
||||
throw new VroumVroum_User_Exception("Missing configuration file '".basename(CONFIG_FILE)."'.");
|
||||
|
||||
$ini = parse_ini_file(CONFIG_FILE);
|
||||
|
||||
foreach ($ini as $key=>$value)
|
||||
{
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!property_exists($this, $key))
|
||||
continue; // Unknown config
|
||||
|
||||
if (is_string($this->$key) || is_null($this->$key))
|
||||
$this->$key = trim((string) $value);
|
||||
elseif (is_int($this->$key))
|
||||
$this->$key = (int) $value;
|
||||
elseif (is_bool($this->$key))
|
||||
$this->$key = (bool) $value;
|
||||
}
|
||||
|
||||
// Check that all required values are filled
|
||||
$check = array('site_type', 'site_title', 'site_url', 'feed_url', 'update_timeout', 'update_interval', 'articles_per_page');
|
||||
foreach ($check as $c)
|
||||
{
|
||||
if (!trim($this->$c))
|
||||
throw new VroumVroum_User_Exception("Missing or empty configuration value '".$c."' which is required!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function __set($key, $value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// BLOG
|
||||
|
||||
class VroumVroum_Blog
|
||||
{
|
||||
protected $articles = null;
|
||||
protected $local = null;
|
||||
|
||||
public $config = null;
|
||||
|
||||
static public function removeHTML($str)
|
||||
{
|
||||
$str = strip_tags($str);
|
||||
$str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
|
||||
return $str;
|
||||
}
|
||||
|
||||
static public function toURI($str)
|
||||
{
|
||||
$uri = self::removeHTML(trim($str));
|
||||
$uri = substr($uri, 0, 70);
|
||||
$uri = preg_replace('/[^\w\d()\p{L}]+/u', '-', $uri);
|
||||
$uri = preg_replace('/-{2,}/', '-', $uri);
|
||||
$uri = preg_replace('/^-|-$/', '', $uri);
|
||||
return $uri;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = new VroumVroum_Config;
|
||||
|
||||
$create_articles_db = file_exists(ARTICLES_DB_FILE) ? false : true;
|
||||
|
||||
$this->articles = new SQLite3(ARTICLES_DB_FILE);
|
||||
|
||||
if ($create_articles_db)
|
||||
{
|
||||
$this->articles->exec('
|
||||
CREATE TABLE articles (
|
||||
id INTEGER PRIMARY KEY,
|
||||
feed_id TEXT,
|
||||
title TEXT,
|
||||
uri TEXT,
|
||||
url TEXT,
|
||||
date INT,
|
||||
content TEXT
|
||||
);
|
||||
CREATE TABLE update_log (
|
||||
date INT PRIMARY KEY,
|
||||
success INT,
|
||||
log TEXT
|
||||
);
|
||||
CREATE UNIQUE INDEX feed_id ON articles (feed_id);
|
||||
CREATE INDEX date ON articles (date);
|
||||
');
|
||||
}
|
||||
|
||||
$this->articles->createFunction('countintegers', array($this, 'sql_countintegers'));
|
||||
}
|
||||
|
||||
public function getLocalURL($in)
|
||||
{
|
||||
return "./?".(is_array($in) ? $in['uri'] : $in);
|
||||
}
|
||||
|
||||
protected function log_update($success, $log = '')
|
||||
{
|
||||
$this->articles->exec('INSERT INTO update_log (date, success, log) VALUES (\''.time().'\', \''.(int)(bool)$success.'\',
|
||||
\''.$this->articles->escapeString($log).'\');');
|
||||
|
||||
// Delete old log
|
||||
$this->articles->exec('DELETE FROM update_log WHERE date > (SELECT date FROM update_log ORDER BY date DESC LIMIT 100,1);');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function insertOrUpdateArticle($feed_id, $title, $url, $date, $content)
|
||||
{
|
||||
$exists = $this->articles->querySingle('SELECT date, id, title, content FROM articles WHERE feed_id = \''.$this->articles->escapeString($feed_id).'\';', true);
|
||||
|
||||
if (empty($exists))
|
||||
{
|
||||
$uri = self::toURI($title);
|
||||
|
||||
if ($this->articles->querySingle('SELECT 1 FROM articles WHERE uri = \''.$this->articles->escapeString($uri).'\';'))
|
||||
{
|
||||
$uri = date('Y-m-d-') . $uri;
|
||||
}
|
||||
|
||||
$content = $this->mirrorMediasForArticle($content, $url);
|
||||
|
||||
$this->articles->exec('INSERT INTO articles (id, feed_id, title, uri, url, date, content) VALUES (NULL,
|
||||
\''.$this->articles->escapeString($feed_id).'\', \''.$this->articles->escapeString($title).'\',
|
||||
\''.$this->articles->escapeString($uri).'\', \''.$this->articles->escapeString($url).'\',
|
||||
\''.(int)$date.'\', \''.$this->articles->escapeString($content).'\');');
|
||||
|
||||
$id = $this->articles->lastInsertRowId();
|
||||
|
||||
$title = self::removeHTML($title);
|
||||
$content = self::removeHTML($content);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Doesn't need update
|
||||
if ($date == $exists['date'] && $content == $exists['content'] && $title == $exists['title'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $exists['id'];
|
||||
|
||||
if ($content != $exists['content'])
|
||||
$content = $this->mirrorMediasForArticle($content, $url);
|
||||
|
||||
$this->articles->exec('UPDATE articles SET title=\''.$this->articles->escapeString($title).'\',
|
||||
url=\''.$this->articles->escapeString($url).'\', content=\''.$this->articles->escapeString($content).'\',
|
||||
date=\''.(int)$date.'\' WHERE id = \''.(int)$id.'\';');
|
||||
|
||||
$title = self::removeHTML($title);
|
||||
$content = self::removeHTML($content);
|
||||
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function mustUpdate()
|
||||
{
|
||||
if (isset($_GET['update']))
|
||||
return true;
|
||||
|
||||
$last_update = $this->articles->querySingle('SELECT date FROM update_log ORDER BY date DESC LIMIT 1;');
|
||||
|
||||
if (!empty($last_update) && (int) $last_update > (time() - $this->config->update_interval))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _getStreamContext()
|
||||
{
|
||||
return stream_context_create(
|
||||
array(
|
||||
'http' => array(
|
||||
'method' => 'GET',
|
||||
'timeout' => $this->config->update_timeout,
|
||||
'header' => "User-Agent: Opera/9.80 (X11; Linux i686; U; fr) Presto/2.2.15 Version/10.10\r\n",
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
if (!$this->mustUpdate())
|
||||
return false;
|
||||
|
||||
try {
|
||||
$body = file_get_contents($this->config->feed_url, false, $this->_getStreamContext());
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
$this->log_update(false, $e->getMessage() . "\n\n" . (!empty($http_response_header) ? implode("\n", $http_response_header) : ''));
|
||||
throw new VroumVroum_Feed_Exception("Can't retrieve feed: ".$e->getMessage());
|
||||
}
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$xml = @simplexml_load_string($body);
|
||||
|
||||
if (!$xml)
|
||||
{
|
||||
$errors = VroumVroum_Feed_Exception::getXMLErrorsAsString(libxml_get_errors());
|
||||
$this->log_update(false, implode("\n", $errors) . "\n\n" . $body);
|
||||
throw new VroumVroum_Feed_Exception("Feed is invalid - XML error: ".implode(" - ", $errors));
|
||||
}
|
||||
|
||||
$updated = 0;
|
||||
$this->articles->exec('BEGIN TRANSACTION;');
|
||||
|
||||
if (isset($xml->entry)) // ATOM feed
|
||||
{
|
||||
foreach ($xml->entry as $item)
|
||||
{
|
||||
$date = isset($item->published) ? (string) $item->published : (string) $item->updated;
|
||||
$guid = !empty($item->id) ? (string)$item->id : (string)$item->link['href'];
|
||||
|
||||
$id = $this->insertOrUpdateArticle($guid, (string)$item->title,
|
||||
(string)$item->link['href'], strtotime($date), (string)$item->content);
|
||||
|
||||
if ($id !== false)
|
||||
$updated++;
|
||||
}
|
||||
}
|
||||
elseif (isset($xml->item)) // RSS 1.0 /RDF
|
||||
{
|
||||
foreach ($xml->item as $item)
|
||||
{
|
||||
$guid = (string) $item->attributes('http://www.w3.org/1999/02/22-rdf-syntax-ns#')->about ?: (string)$item->link;
|
||||
$date = (string) $item->children('http://purl.org/dc/elements/1.1/')->date;
|
||||
|
||||
$id = $this->insertOrUpdateArticle($guid, (string)$item->title, (string)$item->link,
|
||||
strtotime($date), (string) $item->children('http://purl.org/rss/1.0/modules/content/'));
|
||||
|
||||
if ($id !== false)
|
||||
$updated++;
|
||||
}
|
||||
}
|
||||
elseif (isset($xml->channel->item)) // RSS 2.0
|
||||
{
|
||||
foreach ($xml->channel->item as $item)
|
||||
{
|
||||
$content = (string) $item->children('http://purl.org/rss/1.0/modules/content/');
|
||||
$guid = !empty($item->guid) ? (string) $item->guid : (string) $item->link;
|
||||
|
||||
if (empty($content) && !empty($item->description))
|
||||
$content = (string) $item->description;
|
||||
|
||||
$id = $this->insertOrUpdateArticle($guid, (string)$item->title, (string)$item->link,
|
||||
strtotime((string) $item->pubDate), $content);
|
||||
|
||||
if ($id !== false)
|
||||
$updated++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new VroumVroum_Feed_Exception("Unknown feed type?!");
|
||||
}
|
||||
|
||||
$this->log_update(true, $updated . " elements updated");
|
||||
|
||||
$this->articles->exec('END TRANSACTION;');
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
public function listArticlesByPage($page = 1)
|
||||
{
|
||||
$nb = $this->config->articles_per_page;
|
||||
$begin = ($page - 1) * $nb;
|
||||
$res = $this->articles->query('SELECT * FROM articles ORDER BY date DESC LIMIT '.(int)$begin.','.(int)$nb.';');
|
||||
|
||||
$out = array();
|
||||
|
||||
while ($row = $res->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function listLastArticles()
|
||||
{
|
||||
return array_merge($this->listArticlesByPage(1), $this->listArticlesByPage(2));
|
||||
}
|
||||
|
||||
public function countArticles()
|
||||
{
|
||||
return $this->articles->querySingle('SELECT COUNT(*) FROM articles;');
|
||||
}
|
||||
|
||||
public function getArticleFromURI($uri)
|
||||
{
|
||||
return $this->articles->querySingle('SELECT * FROM articles WHERE uri = \''.$this->articles->escapeString($uri).'\';', true);
|
||||
}
|
||||
|
||||
public function sql_countintegers($in)
|
||||
{
|
||||
return substr_count($in, ' ');
|
||||
}
|
||||
|
||||
public function searchArticles($query)
|
||||
{
|
||||
$res = $this->articles->query('SELECT id, uri, title, content
|
||||
FROM articles
|
||||
WHERE content LIKE \'%'.$this->articles->escapeString($query).'%\'
|
||||
ORDER BY id DESC
|
||||
LIMIT 0,100;');
|
||||
|
||||
$out = array();
|
||||
|
||||
while ($row = $res->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$row['url'] = $this->getLocalURL($this->articles->querySingle('SELECT uri FROM articles WHERE id = \''.(int)$row['id'].'\';'));
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function mirrorMediasForArticle($content, $url)
|
||||
{
|
||||
if (!file_exists(MEDIA_DIR))
|
||||
{
|
||||
mkdir(MEDIA_DIR);
|
||||
}
|
||||
|
||||
$schemes = array('http', 'https');
|
||||
$extensions = explode(',', preg_quote('jpg,jpeg,png,apng,gif,svg,pdf,odt,ods,epub,webp,wav,mp3,ogg,aac,wma,flac,opus,mp4,webm', '!'));
|
||||
$extensions = implode('|', $extensions);
|
||||
|
||||
$from = parse_url($url);
|
||||
$from['path'] = preg_replace('![^/]*$!', '', $from['path']);
|
||||
|
||||
preg_match_all('!(src|href)\s*=\s*[\'"]?([^"\'<>\s]+\.(?:'.$extensions.'))[\'"]?!i', $content, $match, PREG_SET_ORDER);
|
||||
|
||||
foreach ($match as $m)
|
||||
{
|
||||
$url = parse_url($m[2]);
|
||||
|
||||
if (empty($url['scheme']))
|
||||
$url['scheme'] = $from['scheme'];
|
||||
|
||||
if (empty($url['host']))
|
||||
$url['host'] = $from['host'];
|
||||
|
||||
if (!in_array(strtolower($url['scheme']), $schemes))
|
||||
continue;
|
||||
|
||||
if ($url['path'][0] != '/')
|
||||
$url['path'] = $from['path'] . $url['path'];
|
||||
|
||||
$filename = basename($url['path']);
|
||||
$url = $url['scheme'] . '://' . $url['host'] . $url['path'];
|
||||
|
||||
$filename = substr(sha1($url), -8) . '.' . substr(preg_replace('![^\w\d_.-]!', '', $filename), -64);
|
||||
$copied = false;
|
||||
|
||||
if (!file_exists(MEDIA_DIR . '/' . $filename))
|
||||
{
|
||||
try {
|
||||
$copied = $this->_copy($url, MEDIA_DIR . '/' . $filename);
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
// Ignore copy errors
|
||||
}
|
||||
}
|
||||
$content = str_replace($m[0], $m[1] . '="media/'.$filename.'" data-original-source="'.$url.'"', $content);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/* copy() is buggy with http streams and safe_mode enabled (which is bad), so here's a workaround */
|
||||
protected function _copy($from, $to)
|
||||
{
|
||||
$in = fopen($from, 'r', false, $this->_getStreamContext());
|
||||
$out = fopen($to, 'w', false);
|
||||
$size = stream_copy_to_stream($in, $out);
|
||||
fclose($in);
|
||||
fclose($out);
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
|
||||
// DISPLAY AND CONTROLLERS
|
||||
|
||||
$vvb = new VroumVroum_Blog;
|
||||
$config = $vvb->config;
|
||||
$site_type = escape($config->site_type);
|
||||
|
||||
if (isset($_GET['feed'])) // FEED
|
||||
{
|
||||
header('Content-Type: application/xhtml+xml; charset=utf-8');
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||
<channel>
|
||||
<title>'.escape($config->site_title).'</title>
|
||||
<link>'.escape($config->site_url).'</link>
|
||||
<description>'.escape(html_entity_decode(strip_tags($config->site_description), ENT_COMPAT, 'UTF-8')).'</description>
|
||||
<language></language>
|
||||
<copyright></copyright>';
|
||||
|
||||
foreach($vvb->listLastArticles() as $art)
|
||||
{
|
||||
echo '
|
||||
<item>
|
||||
<title>'.escape($art['title']).'</title>
|
||||
<guid>'.escape($art['feed_id']).'</guid>
|
||||
<link>'.$vvb->getLocalURL($art).'</link>
|
||||
<pubDate>'.date(DATE_RSS, $art['date']).'</pubDate>
|
||||
<description>
|
||||
<![CDATA['.escape_content($art['content']).']]>
|
||||
</description>
|
||||
<content:encoded>
|
||||
<![CDATA['.escape_content($art['content']).']]>
|
||||
</content:encoded>
|
||||
</item>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</channel>
|
||||
</rss>';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['media'])) // MEDIA
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
if(is_dir(MEDIA_DIR))
|
||||
{
|
||||
$files = scandir(MEDIA_DIR);
|
||||
unset($files[0]); // .
|
||||
unset($files[1]); // ..
|
||||
echo json_encode(array("url"=> LOCAL_URL.substr(MEDIA_DIR, strlen(ROOT_DIR)+1).'/', "files" => $files));
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['update']))
|
||||
{
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
}
|
||||
|
||||
// CONTROLLERS
|
||||
$search = !empty($_GET['q']) ? trim($_GET['q']) : '';
|
||||
$article = null;
|
||||
|
||||
if (!$search && !empty($_SERVER['QUERY_STRING']) && !is_numeric($_SERVER['QUERY_STRING']))
|
||||
{
|
||||
$uri = rawurldecode($_SERVER['QUERY_STRING']);
|
||||
$article = $vvb->getArticleFromURI($uri);
|
||||
|
||||
if (!$article)
|
||||
{
|
||||
header('HTTP/1.1 404 Not Found', true, 404);
|
||||
}
|
||||
}
|
||||
|
||||
// common CSS
|
||||
$css=' * { margin: 0; padding: 0; }
|
||||
body { font-family:sans-serif; background-color: #efefef; padding: 1%; color: #333; }
|
||||
img { max-width: 100%; height: auto; }
|
||||
a { text-decoration: none; color: #000;font-weight:bold; }
|
||||
.header a { text-decoration: none; color: #000;font-weight:bold; }
|
||||
.header { text-align:center; padding: 30px 3%; max-width:70em;margin:0 auto; }
|
||||
.article .title { margin-bottom: 1em; }
|
||||
.article .title h2 a:hover { color:#403976; }
|
||||
.article h4 { font-weight: normal; font-size: small; color: #666; }
|
||||
.article .source a { color: #666; }
|
||||
.searchForm { float:right; }
|
||||
.searchForm input { }
|
||||
.pagination { background-color:white;padding: 12px 10px 12px 10px;border:1px solid #aaa;max-width:70em;margin:1em auto;box-shadow:0px 5px 7px #aaa; }
|
||||
.pagination b { font-size: 1.2em; color: #333; }
|
||||
.pagination a { color:#000; margin: 0 0.5em; }
|
||||
.pagination a:hover { color:#333; }
|
||||
.footer a { color:#000; }
|
||||
.footer a:hover { color:#333; }
|
||||
.content ul, .content ol { margin-left: 2em; }
|
||||
.content h1, .content h2, .content h3, .content h4, .content h5, .content h6,
|
||||
.content ul, .content ol, .content p, .content object, .content div, .content blockquote,
|
||||
.content dl, .content pre { margin-bottom: 0.8em; }
|
||||
.content pre, .content blockquote { background: #ddd; border: 1px solid #999; padding: 0.2em; max-width: 100%; overflow: auto; }
|
||||
.content h1 { font-size: 1.5em; }
|
||||
.content h2 { font-size: 1.4em;color:#000; }
|
||||
.result h3 a { color: darkblue; text-decoration: none; text-shadow: 1px 1px 1px #fff; }
|
||||
#error { position: fixed; top: 0; left: 0; right: 0; padding: 1%; background: #fff; border-bottom: 2px solid red; color: darkred; }
|
||||
';
|
||||
|
||||
if($site_type == 'generic') // custom CSS for generic
|
||||
{
|
||||
$css = $css.'.header h1 a { color: #333;font-size:40pt;text-shadow: #ccc 0px 5px 5px;text-transform:uppercase; }
|
||||
.article .title h2 { margin: 0; color:#333; text-shadow: 1px 1px 1px #fff; }
|
||||
.article .title h2 a { color:#000; text-decoration:none; }
|
||||
.article .source { font-size: 0.8em; color: #666; }
|
||||
.article { background-color:white;padding: 12px 10px 12px 10px;border:1px solid #aaa;max-width:70em;margin:1em auto;box-shadow:0px 5px 7px #aaa; }
|
||||
.footer { text-align:center; font-size: small; color:#333; clear: both; }';
|
||||
}
|
||||
else if($site_type == 'microblog') // custom CSS for microblog
|
||||
{
|
||||
$css = $css.'.header h1 a { color: #333;font-size:40pt;text-shadow: #ccc 0px 5px 5px; }
|
||||
.article .title h2 { width: 10em;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;font-size: 0.7em;margin: 0; color:#333; text-shadow: 1px 1px 1px #fff; }
|
||||
.article .title h2 a { color:#333; text-decoration:none; }
|
||||
.article { background-color:white;padding: 12px 10px 12px 10px;border:1px solid #aaa;max-width:70em;margin:0 auto;box-shadow:0px 5px 7px #aaa; }
|
||||
.article .source { font-size: 0.8em; color: #666; }
|
||||
.footer { margin-top:1em;text-align:center; font-size: small; color:#333; clear: both; }
|
||||
.content {font-size:0.9em;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}';
|
||||
}
|
||||
else if($site_type == 'shaarli') // custom CSS for shaarli
|
||||
{
|
||||
$css = $css.'.header h1 a { color: #333;font-size:40pt;text-shadow: #ccc 0px 5px 5px; }
|
||||
.article .title h2 { margin: 0; color:#333; text-shadow: 1px 1px 1px #fff; }
|
||||
.article .title h2 a { color:#000; text-decoration:none; }
|
||||
.article { background-color:white;padding: 12px 10px 12px 10px;border:1px solid #aaa;max-width:70em;margin:1em auto;box-shadow:0px 5px 7px #aaa; }
|
||||
.article .source { margin-top:1em;font-size: 0.8em; color: #666; }
|
||||
.footer { text-align:center; font-size: small; color:#333; clear: both; }';
|
||||
}
|
||||
|
||||
|
||||
// HTML HEADER
|
||||
echo '
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>'.escape($config->site_title).'</title>
|
||||
<link rel="canonical" href="'.escape($config->site_url).'">
|
||||
<link rel="alternate" type="application/rss+xml" title="'.__('RSS Feed').'" href="?feed">
|
||||
<style type="text/css" media="screen,projection">
|
||||
'.$css.'
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1><a href="'.escape(LOCAL_URL).'">'.escape($config->site_title).'</a></h1>';
|
||||
|
||||
if (!empty($config->site_description))
|
||||
echo '<p>'.$config->site_description.'<br><a href="../">⇐ retour index</a></p>';
|
||||
|
||||
echo '
|
||||
<form method="get" action="'.escape(LOCAL_URL).'" class="searchForm">
|
||||
<div>
|
||||
<input type="text" name="q" value="'.escape($search).'">
|
||||
<input type="submit" value="'.__('Search').'">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
';
|
||||
|
||||
if ($vvb->mustUpdate())
|
||||
{
|
||||
echo '
|
||||
<div class="article">
|
||||
<div class="title">
|
||||
<h2>'.__('Update').'</h2>
|
||||
</div>
|
||||
<div class="content" id="update">
|
||||
'.__('Updating database... Please wait.').'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
if (!empty($search))
|
||||
{
|
||||
$results = $vvb->searchArticles($search);
|
||||
$text = sprintf(__('<b>%d</b> results for <i>%s</i>'), count($results), escape($search));
|
||||
echo '
|
||||
<div class="article">
|
||||
<div class="title">
|
||||
<h2>'.__('Search').'</h2>
|
||||
'.$text.'
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
foreach ($results as $art)
|
||||
{
|
||||
echo '
|
||||
<div class="article result">
|
||||
<h3><a href="./?'.escape($art['uri']).'">'.escape($art['title']).'</a></h3>
|
||||
<p>'.$art['content'].'</p>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
elseif (!is_null($article))
|
||||
{
|
||||
if (!$article)
|
||||
{
|
||||
echo '
|
||||
<div class="article">
|
||||
<div class="title">
|
||||
<h2>'.__('Not Found').'</h2>
|
||||
'.(!empty($uri) ? '<p><tt>'.escape($vvb->getLocalURL($uri)) . '</tt></p>' : '').'
|
||||
'.__('Article not found.').'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
display_article($article);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($_SERVER['QUERY_STRING']) && is_numeric($_SERVER['QUERY_STRING']))
|
||||
$page = (int) $_SERVER['QUERY_STRING'];
|
||||
else
|
||||
$page = 1;
|
||||
|
||||
$list = $vvb->listArticlesByPage($page);
|
||||
|
||||
foreach ($list as $article)
|
||||
{
|
||||
display_article($article);
|
||||
}
|
||||
|
||||
$max = $vvb->countArticles();
|
||||
if ($max > $config->articles_per_page)
|
||||
{
|
||||
echo '<div class="pagination">';
|
||||
|
||||
if ($page > 1)
|
||||
echo '<a href="'.$vvb->getLocalURL($page - 1).'">← '.__('Newer').'</a> ';
|
||||
|
||||
$last = ceil($max / $config->articles_per_page);
|
||||
for ($i = 1; $i <= $last; $i++)
|
||||
{
|
||||
echo '<a href="'.$vvb->getLocalURL($i).'">'.($i == $page ? '<b>'.$i.'</b>' : $i).'</a> ';
|
||||
}
|
||||
|
||||
if ($page < $last)
|
||||
echo '<a href="'.$vvb->getLocalURL($page + 1).'">'.__('Older').' →</a> ';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="footer">
|
||||
<p>Propulsé par <a href="https://github.com/mitsukarenai/Projet-Autoblog">Projet Autoblog '.$vvbversion.'</a> - <a href="?feed">'.__('RSS Feed').'</a></p>
|
||||
<p>'.__('Download:').' <a href="'.LOCAL_URL.basename(CONFIG_FILE).'">'.__('configuration').'</a>
|
||||
- <a href="'.LOCAL_URL.basename(ARTICLES_DB_FILE).'">'.__('articles').'</a><p/>
|
||||
<p><a href="'.LOCAL_URL.'?media">'.__('Media export').' <sup> JSON</sup></a></p>
|
||||
</div>';
|
||||
|
||||
if ($vvb->mustUpdate())
|
||||
{
|
||||
try {
|
||||
ob_end_flush();
|
||||
flush();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Silent, not critical
|
||||
}
|
||||
|
||||
try {
|
||||
$updated = $vvb->update();
|
||||
}
|
||||
catch (VroumVroum_Feed_Exception $e)
|
||||
{
|
||||
echo '
|
||||
<div id="error">
|
||||
'.escape($e->getMessage()).'
|
||||
</div>';
|
||||
$updated = 0;
|
||||
}
|
||||
|
||||
if ($updated > 0)
|
||||
{
|
||||
echo '
|
||||
<script type="text/javascript">
|
||||
window.onload = function () {
|
||||
document.getElementById("update").innerHTML = "'.__('Update complete!').' <a href=\\"#reload\\" onclick=\\"window.location.reload();\\">'.__('Click here to reload this webpage.').'</a>";
|
||||
};
|
||||
</script>';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '
|
||||
<script type="text/javascript">
|
||||
window.onload = function () {
|
||||
document.body.removeChild(document.getElementById("update").parentNode);
|
||||
};
|
||||
</script>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '
|
||||
</body>
|
||||
</html>';
|
||||
// Escaping HTML strings
|
||||
function escape($str)
|
||||
{
|
||||
return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
|
||||
function escape_content($str)
|
||||
{
|
||||
$str = preg_replace('!<\s*(style|script|link)!', '<\\1', $str);
|
||||
$str = str_replace('="media/', '="'.LOCAL_URL.'media/', $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
// ARTICLE HTML CODE
|
||||
function display_article($article)
|
||||
{
|
||||
global $vvb, $config;
|
||||
echo '
|
||||
<div class="article">
|
||||
<div class="title">
|
||||
<h2><a href="'.$vvb->getLocalURL($article).'">'.escape($article['title']).'</a></h2>
|
||||
'.strftime(__('_date_format'), $article['date']).'
|
||||
</div>
|
||||
<div class="content">'.escape_content($article['content']).'</div>
|
||||
<p class="source">'.__('Source:').' <a href="'.escape($article['url']).'">'.escape($article['url']).'</a></p>
|
||||
<br style="clear: both;" />
|
||||
</div>';
|
||||
}
|
||||
|
||||
?>
|
61
0.3/config.php
Executable file
61
0.3/config.php
Executable file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
if(!defined('ROOT_DIR'))
|
||||
{
|
||||
define('ROOT_DIR', dirname($_SERVER['SCRIPT_FILENAME']));
|
||||
}
|
||||
define('LOCAL_URI', '');
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
setlocale(LC_TIME, 'fr_FR.UTF-8', 'fr_FR', 'fr');
|
||||
|
||||
function __($str)
|
||||
{
|
||||
switch ($str)
|
||||
{
|
||||
case 'Search':
|
||||
return 'Recherche';
|
||||
case 'Update':
|
||||
return 'Mise à jour';
|
||||
case 'Updating database... Please wait.':
|
||||
return 'Mise à jour de la base de données, veuillez patienter...';
|
||||
case '<b>%d</b> results for <i>%s</i>':
|
||||
return '<b>%d</b> résultats pour la recherche <i>%s</i>';
|
||||
case 'Not Found':
|
||||
return 'Introuvable';
|
||||
case 'Article not found.':
|
||||
return 'Cet article n\'a pas été trouvé.';
|
||||
case 'Older':
|
||||
return 'Plus anciens';
|
||||
case 'Newer':
|
||||
return 'Plus récents';
|
||||
case 'RSS Feed':
|
||||
return 'Flux RSS';
|
||||
case 'Update complete!':
|
||||
return 'Mise à jour terminée !';
|
||||
case 'Click here to reload this webpage.':
|
||||
return 'Cliquez ici pour recharger cette page.';
|
||||
case 'Source:':
|
||||
return 'Source :';
|
||||
case '_date_format':
|
||||
return '%A %e %B %Y à %H:%M';
|
||||
case 'configuration':
|
||||
case 'articles':
|
||||
return $str;
|
||||
case 'Media export':
|
||||
return 'Export fichiers media';
|
||||
default:
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// Autoriser la création d'autoblogs ?
|
||||
$allow_new_autoblogs=TRUE;
|
||||
|
||||
// Logo à utiliser
|
||||
$logo="./icon-logo.svg";
|
||||
|
||||
// Marquez ici votre propre message qui apparaîtra en bas de page.
|
||||
// exemple :
|
||||
// $HTML_footer="<br/><a href='http://datalove.me/'>Love data</a><br/>Data is essential<br/>Data must flow<br/>Data must be used<br/>Data is neither good nor bad<br/>There is no illegal data<br/>Data is free<br/>Data can not be owned<br/>No man, machine or system shall interrupt the flow of data<br/>Locking data is a crime against datanity";
|
||||
$HTML_footer="";
|
||||
|
||||
?>
|
1
0.3/icon-logo.svg
Executable file
1
0.3/icon-logo.svg
Executable file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="200"><defs id="defs4" /><g transform="translate(0,-852.36218)" id="layer1"><rect width="259.5" height="82.395004" x="20.25" y="911.16467" id="rect3030" style="fill:#f2f2f2;fill-opacity:1;stroke:#000000;stroke-width:0.72559333;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /><text x="149.10121" y="936.99072" id="text3032" xml:space="preserve" style="font-size:31.44740295px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"><tspan x="149.10121" y="936.99072" id="tspan3040" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;stroke:none;font-family:Arial;-inkscape-font-specification:Arial Bold">Never surrender</tspan><tspan x="149.10121" y="982.74823" id="tspan3044" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;stroke:none;font-family:Arial;-inkscape-font-specification:Arial Bold">to <tspan id="tspan3046" style="font-size:38px">censorship</tspan></tspan></text></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
498
0.3/index.php
Executable file
498
0.3/index.php
Executable file
|
@ -0,0 +1,498 @@
|
|||
<?php
|
||||
/*
|
||||
Projet Autoblog 0.3-beta
|
||||
Code: https://github.com/mitsukarenai/Projet-Autoblog
|
||||
Authors: Mitsu https://www.suumitsu.eu/ & Oros https://www.ecirtam.net/
|
||||
License: Public Domain
|
||||
|
||||
Instructions:
|
||||
(by default, autoblog creation is allowed: you can set this to "FALSE" in config.php)
|
||||
(by default, Cross-Site Autoblog Farming [XSAF] imports a few autoblogs from https://github.com/mitsukarenai/xsaf-bootstrap/blob/master/3.json you can uncomment and add xsafimports in xsaf3.php (jump at end of file) )
|
||||
(by default, database and media transfer via XSAF is allowed)
|
||||
|
||||
- upload all files on your server (PHP 5.3+ required)
|
||||
- PROFIT !
|
||||
|
||||
*/
|
||||
define('XSAF_VERSION', 3);
|
||||
|
||||
define('ROOT_DIR', __DIR__);
|
||||
if(file_exists("config.php")){
|
||||
include "config.php";
|
||||
}
|
||||
|
||||
function get_title_from_feed($url)
|
||||
{
|
||||
// get site title from feed
|
||||
$data = file_get_contents("$url");
|
||||
if($data === false) { die('url inaccessible'); }
|
||||
$dom = new DOMDocument;
|
||||
$dom->loadXML($data) or die('xml malformé');
|
||||
$title = $dom->getElementsByTagName('title');
|
||||
return $title->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
function get_link_from_feed($url)
|
||||
{
|
||||
// get site link from feed
|
||||
$data = file_get_contents("$url");
|
||||
$xml = simplexml_load_string($data); // quick feed check
|
||||
if (isset($xml->entry)) // ATOM feed.
|
||||
{$result="true";}
|
||||
elseif (isset($xml->item)) // RSS 1.0 /RDF
|
||||
{$result="true";}
|
||||
elseif (isset($xml->channel->item)) // RSS 2.0
|
||||
{$result="true";}
|
||||
else
|
||||
{$result="false";}
|
||||
if($result == "false") { die('le flux n\'a pas une syntaxe valide'); }
|
||||
$check = substr($data, 0, 5);
|
||||
if($check !== '<?xml') { die('n\'est pas un flux valide'); }
|
||||
$xml = new SimpleXmlElement($data);
|
||||
$channel['link'] = $xml->channel->link;
|
||||
if($channel['link'] === NULL)
|
||||
{
|
||||
$dom = new DOMDocument;
|
||||
$dom->loadXML($data) or die('xml malformé');
|
||||
$link = $dom->getElementsByTagName('uri');
|
||||
return $link->item(0)->nodeValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $channel['link'];
|
||||
}
|
||||
}
|
||||
|
||||
function serverUrl()
|
||||
{
|
||||
$https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection.
|
||||
$serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]);
|
||||
return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport;
|
||||
}
|
||||
|
||||
function NoProtocolSiteURL($url)
|
||||
{
|
||||
$siteurlnoprototypes = array("http://", "https://");
|
||||
$siteurlnoproto = str_replace($siteurlnoprototypes, "", $url);
|
||||
return $siteurlnoproto;
|
||||
}
|
||||
|
||||
function DetectRedirect($url)
|
||||
{
|
||||
$response = get_headers($url, 1);
|
||||
if(!empty($response['Location']))
|
||||
{
|
||||
$response2 = get_headers($response['Location'], 1);
|
||||
if(!empty($response2['Location']))
|
||||
{die('too much redirection');}
|
||||
else { return $response['Location']; }
|
||||
}
|
||||
else
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['check']))
|
||||
{
|
||||
$randomtime=rand(86400, 259200); /* intervalle de mise à jour: de 1 à 3 jours (pour éviter que le statut de tous les autoblogs soit rafraichi en bloc et bouffe le CPU) */
|
||||
$expire=time() -$randomtime ;
|
||||
|
||||
/* SVG minimalistes */
|
||||
$svg_vert='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><g><rect width="15" height="15" x="0" y="0" style="fill:#00ff00;stroke:#008000"/></g><text style="font-size:10px;font-weight:bold;text-anchor:middle;font-family:Arial"><tspan x="7" y="11">OK</tspan></text></svg>';
|
||||
$svg_jaune='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><g><rect width="15" height="15" x="0" y="0" style="fill:#ffff00;stroke:#ffcc00"/></g><text style="font-size:10px;font-weight:bold;text-anchor:middle;font-family:Arial"><tspan x="7" y="11">mv</tspan></text></svg>';
|
||||
$svg_rouge='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><g><rect width="15" height="15" x="0" y="0" style="fill:#ff0000;stroke:#800000"/></g><text style="font-size:10px;font-weight:bold;text-anchor:middle;font-family:Arial"><tspan x="7" y="11">err</tspan></text></svg>';
|
||||
$svg_twitter='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><path d="m 11.679889,7.6290431 a 4.1668792,3.7091539 0 1 1 -8.3337586,0 4.1668792,3.7091539 0 1 1 8.3337586,0 z" style="fill:none;stroke:#3aaae1;stroke-width:4;stroke-miterlimit:4" /></svg>';
|
||||
$svg_identica='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><path d="m 11.679889,7.6290431 a 4.1668792,3.7091539 0 1 1 -8.3337586,0 4.1668792,3.7091539 0 1 1 8.3337586,0 z" style="fill:none;stroke:#a00000;stroke-width:4;stroke-miterlimit:4" /></svg>';
|
||||
$svg_statusnet='<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15"><path d="m 11.679889,7.6290431 a 4.1668792,3.7091539 0 1 1 -8.3337586,0 4.1668792,3.7091539 0 1 1 8.3337586,0 z" style="fill:none;stroke:#ff6a00;stroke-width:4;stroke-miterlimit:4" /></svg>';
|
||||
|
||||
$errorlog="./".$_GET['check']."/error.log";
|
||||
if(file_exists($errorlog) && filemtime($errorlog) < $expire) { unlink($errorlog); } /* errorlog périmé ? Suppression. */
|
||||
if(file_exists($errorlog)) /* errorlog existe encore ? se contenter de lire sa taille pour avoir le statut */
|
||||
{
|
||||
header('Content-type: image/svg+xml');
|
||||
if(filesize($errorlog) == "0") {die($svg_vert);}
|
||||
else if(filesize($errorlog) == "1") {die($svg_jaune);}
|
||||
else {die($svg_rouge);}
|
||||
}
|
||||
else /* ..sinon, lancer la procédure de contrôle */
|
||||
{
|
||||
$ini = parse_ini_file("./".$_GET['check']."/vvb.ini") or die;
|
||||
header('Content-type: image/svg+xml');
|
||||
if(strpos("$ini[SITE_TITLE]", 'twitter') !== FALSE) { die($svg_twitter); } /* Twitter */
|
||||
if(strpos("$ini[SITE_TITLE]", 'identica') !== FALSE) { die($svg_identica); } /* Identica */
|
||||
if(strpos("$ini[SITE_TYPE]", 'microblog') !== FALSE) { die($svg_statusnet); } /* Statusnet */
|
||||
$headers = get_headers("$ini[FEED_URL]");
|
||||
if(empty($headers)) { file_put_contents($errorlog, '..'); die($svg_rouge); } /* le flux est indisponible (typiquement: erreur DNS ou possible censure) - à vérifier */
|
||||
$code=explode(" ", $headers[0]);
|
||||
if($code[1] == "200") { file_put_contents($errorlog, ''); die($svg_vert);} /* code retour 200: flux disponible */
|
||||
else {file_put_contents($errorlog, '.'); die($svg_jaune);} /* autre code retour: un truc a changé (redirection, changement de CMS, .. bref vvb.ini doit être corrigé) */
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['export']))
|
||||
// autoblog exporting
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
$directory = "./";
|
||||
$subdirs = glob($directory . "*");
|
||||
foreach($subdirs as $unit)
|
||||
{
|
||||
if(is_dir($unit))
|
||||
{
|
||||
$unit=substr($unit, 2);
|
||||
$ini = parse_ini_file($unit.'/vvb.ini');
|
||||
$config = new stdClass;
|
||||
foreach ($ini as $key=>$value)
|
||||
{
|
||||
$key = strtolower($key);
|
||||
$config->$key = $value;
|
||||
}
|
||||
unset($ini);
|
||||
$type=$config->site_type;
|
||||
$title=$config->site_title;
|
||||
$url=$config->site_url;
|
||||
$feed=$config->feed_url;
|
||||
$reponse[$unit] = array("SITE_TYPE"=>"$type", "SITE_TITLE"=>"$title", "SITE_URL"=>"$url", "FEED_URL"=>"$feed");
|
||||
}
|
||||
}
|
||||
echo json_encode( array( "meta"=> array("xsaf-version"=>XSAF_VERSION,"xsaf-db_transfer"=>"true","xsaf-media_transfer"=>"true"),
|
||||
"autoblogs"=>$reponse));
|
||||
die;
|
||||
}
|
||||
|
||||
if (isset($_GET['feedexport']))
|
||||
// autoblog exporting -feed only
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
$directory = "./";
|
||||
$reponse="";
|
||||
$subdirs = glob($directory . "*");
|
||||
foreach($subdirs as $unit)
|
||||
{
|
||||
if(is_dir($unit))
|
||||
{
|
||||
$unit=substr($unit, 2);
|
||||
$ini = parse_ini_file($unit.'/vvb.ini');
|
||||
$config = new stdClass;
|
||||
foreach ($ini as $key=>$value)
|
||||
{
|
||||
$key = strtolower($key);
|
||||
$config->$key = $value;
|
||||
}
|
||||
unset($ini);
|
||||
$feed=$config->feed_url;
|
||||
$reponse=$reponse.";$feed";
|
||||
}
|
||||
}
|
||||
$reponse=substr($reponse, 1);
|
||||
echo json_encode(explode(';', $reponse));
|
||||
die;
|
||||
}
|
||||
|
||||
if (isset($_GET['sitemap']))
|
||||
// url-list sitemap
|
||||
{
|
||||
header('Content-Type: text/plain');
|
||||
$directory = "./";
|
||||
$subdirs = glob($directory . "*");
|
||||
foreach($subdirs as $unit)
|
||||
{
|
||||
if(is_dir($unit))
|
||||
{
|
||||
$unit=substr($unit, 2);
|
||||
$proto=$_SERVER['HTTPS']?"https://":"http://";
|
||||
echo $proto.$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, -9)."$unit/"."\n";
|
||||
}
|
||||
}
|
||||
die;
|
||||
}
|
||||
|
||||
function escape($str)
|
||||
{
|
||||
return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
|
||||
$form = '<form method="POST"><input placeholder="Adresse du flux RSS/ATOM" type="text" name="rssurl" id="rssurl"><br>
|
||||
<input placeholder="Antibot: \'dix sept\' en chiffre" type="text" name="number" id="number"><br><input type="submit" value="Vérifier"></form>';
|
||||
|
||||
if(!empty($_GET['via_button']) && !empty($_GET['rssurl']) && $_GET['number'] === '17' && $allow_new_autoblogs == TRUE)
|
||||
{
|
||||
if(isset($_GET['add']) && $_GET['add'] === '1' && !empty($_GET['siteurl']) && !empty($_GET['sitename']))
|
||||
{
|
||||
$rssurl = DetectRedirect(escape($_GET['rssurl']));
|
||||
$siteurl = escape($_GET['siteurl']);
|
||||
$sitetype = 'generic';
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));
|
||||
if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');}
|
||||
$sitename = escape($_GET['sitename']);
|
||||
if(file_exists($foldername) || file_exists($foldername2)) { die('Erreur: l\'autoblog <a target="_blank" href="./'.$foldername.'/">existe déjà</a>.'); }
|
||||
if ( mkdir('./'. $foldername, 0755, false) ) {
|
||||
$fp = fopen('./'. $foldername .'/index.php', 'w+');
|
||||
if( !fwrite($fp, "<?php require_once dirname(__DIR__) . '/autoblog.php'; ?>") )
|
||||
{die("Impossible d'écrire le fichier index.php");}
|
||||
fclose($fp);
|
||||
$fp = fopen('./'. $foldername .'/vvb.ini', 'w+');
|
||||
if( !fwrite($fp, '[VroumVroumBlogConfig]
|
||||
SITE_TYPE="'. $sitetype .'"
|
||||
SITE_TITLE="'. $sitename .'"
|
||||
SITE_DESCRIPTION="source: <a href="'. $siteurl .'">'. $sitename .'</a>"
|
||||
SITE_URL="'. $siteurl .'"
|
||||
FEED_URL="'. $rssurl .'"
|
||||
ARTICLES_PER_PAGE="5"
|
||||
UPDATE_INTERVAL="3600"
|
||||
UPDATE_TIMEOUT="30"') )
|
||||
{die("Impossible d'écrire le fichier vvb.ini");}
|
||||
fclose($fp);
|
||||
{die('<iframe width="1" height="1" frameborder="0" src="'.$foldername.'"></iframe><b style="color:darkgreen">autoblog crée avec succès.</b> → <a target="_blank" href="'.$foldername.'">afficher l\'autoblog</a>');}
|
||||
}
|
||||
else
|
||||
{die("Impossible de créer le répertoire.");}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// checking procedure
|
||||
$sitetype = $_GET['sitetype'];
|
||||
$rssurl = DetectRedirect($_GET['rssurl']);
|
||||
$siteurl = get_link_from_feed($rssurl);
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));
|
||||
if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');}
|
||||
$sitename = get_title_from_feed($rssurl);
|
||||
$sitedomain1 = preg_split('/\//', $siteurl, 0);$sitedomain2=$sitedomain1[2];$sitedomain3=explode(".", $sitedomain2);$sitedomain3=array_reverse($sitedomain3);$sitedomain = $sitedomain3[1].'.'.$sitedomain3[0];
|
||||
if(file_exists($foldername) || file_exists($foldername2)) { die('Erreur: l\'autoblog <a href="./'.$foldername.'/">existe déjà</a>.'); }
|
||||
$form = '<html><head></head><body><span style="color:blue">Merci de vérifier les informations suivantes, corrigez si nécessaire.</span><br>
|
||||
<form method="GET">
|
||||
<input type="hidden" name="via_button" value="1"><input type="hidden" name="add" value="1"><input type="hidden" name="number" value="17">
|
||||
<input style="width:30em;" type="text" name="sitename" id="sitename" value="'.$sitename.'"><label for="sitename">← titre du site (auto)</label><br>
|
||||
<input style="width:30em;" placeholder="Adresse du site" type="text" name="siteurl" id="siteurl" value="'.$siteurl.'"><label for="siteurl">← page d\'accueil (auto)</label><br>
|
||||
<input style="width:30em;" placeholder="Adresse du flux RSS/ATOM" type="text" name="rssurl" id="rssurl" value="'.$rssurl.'"><label for="rssurl">← adresse du flux</label><br>
|
||||
<input style="width:30em;" placeholder="generic" type="text" name="sitetype" id="sitetype" value="'.$sitetype.'" disabled><label for="sitetype">← type de site</label><br>
|
||||
<input type="submit" value="Créer"></form></body></html>';
|
||||
echo $form; die;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && $allow_new_autoblogs == TRUE)
|
||||
{
|
||||
$socialaccount = strtolower(escape($_POST['socialaccount']));
|
||||
if(escape($_POST['socialinstance']) === 'twitter') { $socialinstance = 'twitter'; }
|
||||
if(escape($_POST['socialinstance']) === 'identica') { $socialinstance = 'identica'; }
|
||||
if(escape($_POST['socialinstance']) === 'statusnet') { $socialinstance = 'statusnet'; }
|
||||
if(escape($_POST['socialinstance']) === 'shaarli') { $socialinstance = 'shaarli'; }
|
||||
if($socialinstance === 'twitter') { $sitetype = 'microblog'; $update_interval='300'; $siteurl = "http://twitter.com/$socialaccount"; $rssurl = "http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=$socialaccount"; }
|
||||
if($socialinstance === 'identica') { $sitetype = 'microblog'; $update_interval='300'; $siteurl = "http://identi.ca/$socialaccount"; $rssurl = "http://identi.ca/api/statuses/user_timeline/$socialaccount.rss"; }
|
||||
if($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { $sitetype = 'microblog'; $update_interval='300'; $siteurl=NoProtocolSiteURL(escape($_POST['statusneturl'])); if(substr($siteurl, -1) == '/'){ $siteurl = substr($siteurl, 0, -1); } $rssurl = DetectRedirect("http://".$siteurl."/api/statuses/user_timeline/$socialaccount.rss"); $siteurl = DetectRedirect("http://".$siteurl."/$socialaccount"); }
|
||||
if($socialinstance === 'shaarli' && !empty($_POST['shaarliurl'])) { $sitetype = 'shaarli'; $update_interval='1800'; $siteurl = NoProtocolSiteURL(escape($_POST['shaarliurl'])); if(substr($siteurl, -1) == '/'){ $siteurl = substr($siteurl, 0, -1); } $siteurl = DetectRedirect("http://".$siteurl."/"); $rssurl = $siteurl."?do=rss";$socialaccount = get_title_from_feed($rssurl); }
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));if(file_exists($foldername)) { die('Erreur: l\'autoblog <a href="./'.$foldername.'/">existe déjà</a>.'); }
|
||||
$rssurl=DetectRedirect($rssurl); $headers = get_headers($rssurl, 1);
|
||||
if (strpos($headers[0], '200') == FALSE) {$error[] = "Flux inaccessible (compte inexistant ?)";} else { }
|
||||
if( empty($error) ) {
|
||||
if( !preg_match('#\.\.|/#', $foldername) ) {
|
||||
if ( mkdir('./'. $foldername, 0755, false) ) {
|
||||
$fp = fopen('./'. $foldername .'/index.php', 'w+');
|
||||
if( !fwrite($fp, "<?php require_once dirname(__DIR__).'/autoblog.php'; ?>") )
|
||||
$error[] = "Impossible d'écrire le fichier index.php";
|
||||
fclose($fp);
|
||||
$fp = fopen('./'. $foldername .'/vvb.ini', 'w+');
|
||||
if( !fwrite($fp, '[VroumVroumBlogConfig]
|
||||
SITE_TYPE="'.$sitetype.'"
|
||||
SITE_TITLE="'.$socialinstance.'-'.$socialaccount.'"
|
||||
SITE_DESCRIPTION="source: <a href="'. $siteurl .'">'. $socialaccount .'</a>"
|
||||
SITE_URL="'. $siteurl .'"
|
||||
FEED_URL="'. $rssurl .'"
|
||||
ARTICLES_PER_PAGE="20"
|
||||
UPDATE_INTERVAL="'.$update_interval.'"
|
||||
UPDATE_TIMEOUT="30"') )
|
||||
$error[] = "Impossible d'écrire le fichier vvb.ini";
|
||||
fclose($fp);
|
||||
$error[] = '<iframe width="1" height="1" frameborder="0" src="'.$foldername.'"></iframe><b style="color:darkgreen">AutoMicroblog <a href="'.$foldername.'">ajouté avec succès</a>.</b>';
|
||||
}
|
||||
else
|
||||
$error[] = "Impossible de créer le répertoire.";
|
||||
}
|
||||
else
|
||||
$error[] = "Nom de site invalide.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( !empty($_POST) && empty($_POST['socialinstance']) && $allow_new_autoblogs == TRUE) {
|
||||
$error = array();
|
||||
if(empty($_POST['rssurl']))
|
||||
{$error[] = "Veuillez entrer l'adresse du flux.";}
|
||||
if(empty($_POST['number']))
|
||||
{$error[] = "Le chiffre. Écrivez le chiffre.";}
|
||||
if($_POST['number'] !== '17')
|
||||
{$error[] = "C'est pas le bon chiffre.";}
|
||||
|
||||
if(empty($error))
|
||||
{
|
||||
$rssurl = DetectRedirect(escape($_POST['rssurl']));
|
||||
if(!empty($_POST['siteurl']))
|
||||
{
|
||||
// check done, writing out
|
||||
$siteurl = escape($_POST['siteurl']);
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));$sitename = get_title_from_feed($rssurl);
|
||||
if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');}
|
||||
$sitedomain1 = preg_split('/\//', $siteurl, 0);$sitedomain2=$sitedomain1[2];$sitedomain3=explode(".", $sitedomain2);$sitedomain3=array_reverse($sitedomain3);$sitedomain = $sitedomain3[1].'.'.$sitedomain3[0];
|
||||
if(file_exists($foldername) || file_exists($foldername2)) { die('Erreur: l\'autoblog <a href="./'.$foldername.'/">existe déjà</a>.'); }
|
||||
if ( mkdir('./'. $foldername, 0755, false) ) {
|
||||
$fp = fopen('./'. $foldername .'/index.php', 'w+');
|
||||
if( !fwrite($fp, "<?php require_once dirname(__DIR__) . '/autoblog.php'; ?>") )
|
||||
$error[] = "Impossible d'écrire le fichier index.php";
|
||||
fclose($fp);
|
||||
$fp = fopen('./'. $foldername .'/vvb.ini', 'w+');
|
||||
if( !fwrite($fp, '[VroumVroumBlogConfig]
|
||||
SITE_TYPE="generic"
|
||||
SITE_TITLE="'. $sitename .'"
|
||||
SITE_DESCRIPTION="source: <a href="'. $siteurl .'">'. $sitename .'</a>"
|
||||
SITE_URL="'. $siteurl .'"
|
||||
FEED_URL="'. $rssurl .'"
|
||||
ARTICLES_PER_PAGE="5"
|
||||
UPDATE_INTERVAL="3600"
|
||||
UPDATE_TIMEOUT="30"') )
|
||||
$error[] = "Impossible d'écrire le fichier vvb.ini";
|
||||
fclose($fp);
|
||||
$error[] = '<iframe width="1" height="1" frameborder="0" src="'.$foldername.'"></iframe><b style="color:darkgreen">autoblog crée avec succès.</b> → <a target="_blank" href="'.$foldername.'">afficher l\'autoblog</a>';
|
||||
}
|
||||
else
|
||||
$error[] = "Impossible de créer le répertoire.";
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// checking procedure
|
||||
$rssurl = DetectRedirect($rssurl);
|
||||
$sitetype = 'generic';
|
||||
$siteurl = get_link_from_feed($rssurl);
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));
|
||||
$sitename = get_title_from_feed($rssurl);
|
||||
if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');}
|
||||
$sitedomain1 = preg_split('/\//', $siteurl, 0);$sitedomain2=$sitedomain1[2];$sitedomain3=explode(".", $sitedomain2);$sitedomain3=array_reverse($sitedomain3);$sitedomain = $sitedomain3[1].'.'.$sitedomain3[0];
|
||||
if(file_exists($foldername) || file_exists($foldername2)) { die('Erreur: l\'autoblog <a href="./'.$foldername.'/">existe déjà</a>.'); }
|
||||
$form = '<span style="color:blue">Merci de vérifier les informations suivantes, corrigez si nécessaire.</span><br>
|
||||
<form method="POST"><input style="color:black" type="text" id="sitename" value="'.$sitename.'" disabled><label for="sitename">← titre du site (auto)</label><br>
|
||||
<input placeholder="Adresse du site" type="text" name="siteurl" id="siteurl" value="'.$siteurl.'"><label for="siteurl">← page d\'accueil (auto)</label><br>
|
||||
<input placeholder="Adresse du flux RSS/ATOM" type="text" name="rssurl" id="rssurl" value="'.$rssurl.'"><label for="rssurl">← adresse du flux</label><br>
|
||||
<input placeholder=""Type de site" type="text" name="sitetype" id="sitetype" value="'.$sitetype.'" disabled><label for="sitetype">← type de site</label><br>
|
||||
<input placeholder="Antibot: \'dix sept\' en chiffre" type="text" name="number" id="number" value="17"><label for="number">← antibot</label><br><input type="submit" value="Créer"></form>';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Le Projet Autoblog</title>
|
||||
<style type="text/css">
|
||||
body {background-color:#efefef;text-align:center;color:#333;font-family:sans-serif}
|
||||
a {color:black;text-decoration:none;font-weight:bold;}
|
||||
a:hover {color:darkred;}
|
||||
h1 { text-align:center;font-size:40pt;text-shadow: #ccc 0px 5px 5px; }
|
||||
h2 { text-align:center;font-size: 16pt;margin:0 0 1em 0;font-style:italic;text-shadow: #ccc 0px 5px 5px; }
|
||||
.pbloc {background-color:white;padding: 12px 10px 12px 10px;border:1px solid #aaa;max-width:70em;margin:1em auto;text-align:justify;box-shadow:0px 5px 7px #aaa;}
|
||||
input {width:30em;}
|
||||
input[type="radio"] { width:1em; }
|
||||
input#socialaccount, input#statusneturl, input#shaarliurl, input#socialsub {width:12em;}
|
||||
div.form {padding:0.2em;margin:1px;}
|
||||
div.form:hover {background-color:#FAF4DA;border:1px dotted;margin:0; }
|
||||
.vignette { width:20em;height:2em;float:left;margin:0; padding:20px;background-color:#eee;border: 1px solid #888;}
|
||||
.vignette:hover { background-color:#fff;}
|
||||
.vignette .title { font-size: 14pt;text-shadow: #ccc 0px 5px 5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
||||
.vignette .title a:hover { color:darkred; text-decoration:none;}
|
||||
.vignette .source { font-size:x-small;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
||||
.vignette .source a:hover { color:darkred; text-decoration:none;}
|
||||
.clear {clear:both;text-align:right;font-size:small;}
|
||||
#logo {float: right;}
|
||||
.bouton{background: -moz-linear-gradient(center top , #EDEDED 5%, #DFDFDF 100%) repeat scroll 0 0 #EDEDED;border: 1px none;padding: 10px;border: 1px solid #7777777;border-radius: 8px 8px 8px 8px;box-shadow: 0 1px 0 0 #FFFFFF inset;display: inline-block;}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>LE PROJET AUTOBLOG</h1>
|
||||
<div class="pbloc">
|
||||
<img id="logo" src="<?php if(isset($logo)) { echo $logo; }else{ echo './icon-logo.svg'; } ?>" alt="">
|
||||
<b>Note</b><br>
|
||||
Voici une liste d'autoblogs hébergés sur <i><?php echo $_SERVER['SERVER_NAME']; ?></i> (<a href="http://sebsauvage.net/streisand.me/fr/">plus d'infos sur le projet</a>).<br><br>
|
||||
<b>Autres fermes</b><br>
|
||||
→ <a href="https://duckduckgo.com/?q=!g%20%22Voici%20une%20liste%20d'autoblogs%20hébergés%22">Rechercher</a><br><br>
|
||||
<?php if($allow_new_autoblogs == TRUE) { ?>
|
||||
<div class="form"><b>Ajouter un compte social</b><br><br>
|
||||
<form method="POST">
|
||||
<input class="text" placeholder="identifiant compte" type="text" name="socialaccount" id="socialaccount"><br>
|
||||
<input type="radio" name="socialinstance" value="twitter">Twitter<br>
|
||||
<input type="radio" name="socialinstance" value="identica">Identica<br>
|
||||
<input type="radio" name="socialinstance" value="statusnet"><input placeholder="statusnet.personnel.com" type="text" name="statusneturl" id="statusneturl"><br>
|
||||
<input id="socialsub" type="submit" value="Créer">
|
||||
</form></div><br>
|
||||
<div class="form"><b>Ajouter un Shaarli</b><br><br>
|
||||
<form method="POST">
|
||||
<input class="text" placeholder="identifiant compte" type="hidden" name="socialaccount" id="socialaccount" value="shaarli">
|
||||
<input type="hidden" name="socialinstance" value="shaarli"><input placeholder="shaarli.personnel.com" type="text" name="shaarliurl" id="shaarliurl"><br>
|
||||
<input id="socialsub" type="submit" value="Créer">
|
||||
</form></div><br>
|
||||
<div class="form"><b>Ajouter un site web</b><br>
|
||||
<?php
|
||||
if( !empty( $error )) {
|
||||
echo '<p>Erreur(s) :</p><ul>';
|
||||
foreach ( $error AS $value ) {
|
||||
echo '<li>'. $value .'</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
Si vous souhaitez que <i><?php echo $_SERVER['SERVER_NAME']; ?></i> héberge un autoblog d'un site,<br/>remplissez le formulaire suivant:<br><br>
|
||||
<?php echo $form; ?>
|
||||
</div><br>Pour ajouter facillement un autoblog d'un site web, glissez ce bouton dans votre barre de marque-pages => <a class="bouton" onclick="alert('Glissez ce bouton dans votre barre de marque-pages (ou clic-droit > marque-page sur ce lien)');return false;" href="javascript:(function(){var%20autoblog_url="<?php echo serverUrl().$_SERVER["REQUEST_URI"]; ?>";var%20popup=window.open("","Add%20autoblog",'height=180,width=670');popup.document.writeln('<html><head></head><body><form%20action="'+autoblog_url+'"%20method="GET">');popup.document.write('Url%20feed%20%20:%20<br/>');var%20feed_links=new%20Array();var%20links=document.getElementsByTagName('link');if(links.length>0){for(var%20i=0;i<links.length;i++){if(links[i].rel=="alternate"){popup.document.writeln('<label%20for="feed_'+i+'"><input%20id="feed_'+i+'"%20type="radio"%20name="rssurl"%20value="'+links[i].href+'"/>'+links[i].title+"%20(%20"+links[i].href+"%20)</label><br/>");}}}popup.document.writeln("<input%20id='number'%20type='hidden'%20name='number'%20value='17'>");popup.document.writeln("<input%20type='hidden'%20name='via_button'%20value='1'>");popup.document.writeln("<br/><input%20type='submit'%20value='Vérifier'%20name='Ajouter'%20>");popup.document.writeln("</form></body></html>");})();">Projet Autoblog</a>
|
||||
<?php } ?>
|
||||
<br></div>
|
||||
<div class="pbloc">
|
||||
<h2>Autoblogs hébergés</h2>
|
||||
<div class="clear"><a href="?export">export<sup> JSON</sup></a></div>
|
||||
<?php
|
||||
$directory = "./";
|
||||
$subdirs = glob($directory . "*");
|
||||
$autoblogs = array();
|
||||
foreach($subdirs as $unit)
|
||||
{
|
||||
if(is_dir($unit))
|
||||
{
|
||||
$ini = parse_ini_file(ROOT_DIR . '/' . $unit . '/vvb.ini');
|
||||
if($ini)
|
||||
{
|
||||
$config = new stdClass;
|
||||
$unit=substr($unit, 2);
|
||||
foreach ($ini as $key=>$value)
|
||||
{
|
||||
$key = strtolower($key);
|
||||
$config->$key = $value;
|
||||
}
|
||||
$autoblogs[$unit] = '
|
||||
<div class="vignette">
|
||||
<div class="title"><a title="'.escape($config->site_title).'" href="'.$unit.'/"><img width="15" height="15" alt="" src="./?check='.$unit.'"> '.escape($config->site_title).'</a></div>
|
||||
<div class="source"><a href="'.$unit.'/vvb.ini">config</a> | '.escape($config->site_type).' source: <a href="'.escape($config->site_url).'">'.escape($config->site_url).'</a></div>
|
||||
</div>';
|
||||
unset($ini);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($autoblogs)){
|
||||
sort($autoblogs, SORT_STRING);
|
||||
foreach ($autoblogs as $autoblog) {
|
||||
echo $autoblog;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="clear"></div>
|
||||
<?php echo "<br/>".count($autoblogs)." autoblogs hébergés"; ?>
|
||||
</div>
|
||||
Propulsé par <a href="https://github.com/mitsukarenai/Projet-Autoblog">Projet Autoblog 0.3</a> de Mitsu et Oros (Domaine Public)
|
||||
<?php if(isset($HTML_footer)){ echo "<br/>".$HTML_footer; } ?>
|
||||
<iframe width="1" height="1" style="display:none" src="xsaf3.php"></iframe>
|
||||
</body>
|
||||
</html>
|
200
0.3/xsaf3.php
Executable file
200
0.3/xsaf3.php
Executable file
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
|
||||
define('DEBUG', true);
|
||||
define('XSAF_VERSION', 3);
|
||||
define('AUTOBLOG_FILE_NAME', 'autoblog.php');
|
||||
|
||||
header("HTTP/1.0 403 Forbidden"); /* Uncivilized method to prevent bot indexing, huh :) */
|
||||
header('X-Robots-Tag: noindex'); /* more civilized method, but bots may not all take into account */
|
||||
header('Content-type: text/plain');
|
||||
$expire = time() -7200 ; $lockfile = ".xsaflock"; /* defaut delay: 7200 (2 hours) */
|
||||
|
||||
if (file_exists($lockfile)) {
|
||||
if (filemtime($lockfile) > $expire) {
|
||||
echo "too early";
|
||||
die;
|
||||
}else{
|
||||
unlink($lockfile);
|
||||
if( file_put_contents($lockfile, '') ===FALSE) {
|
||||
echo "Merci d'ajouter des droits d'écriture sur le dossier.";
|
||||
die;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if( file_put_contents($lockfile, '') ===FALSE) {
|
||||
echo "Merci d'ajouter des droits d'écriture sur le dossier.";
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
define('ROOT_DIR', __DIR__);
|
||||
function escape($str) {
|
||||
return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
|
||||
function serverUrl() {
|
||||
$https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection.
|
||||
$serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]);
|
||||
return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport;
|
||||
}
|
||||
|
||||
function NoProtocolSiteURL($url) {
|
||||
$siteurlnoprototypes = array("http://", "https://");
|
||||
$siteurlnoproto = str_replace($siteurlnoprototypes, "", $url);
|
||||
return $siteurlnoproto;
|
||||
}
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
// $max_exec_time = temps max d'exécution en seconde
|
||||
function xsafimport($xsafremote, $max_exec_time) {
|
||||
echo "\n*Traitement $xsafremote en maximum $max_exec_time secondes";
|
||||
$max_exec_time+=time()-1; // -1 car l'import prend environ 1 seconde
|
||||
/* détection de ferme autoblog */
|
||||
$json_import = file_get_contents($xsafremote);
|
||||
if(!empty($json_import)) {
|
||||
$to_update=array();
|
||||
$json_import = json_decode($json_import, true);
|
||||
|
||||
if(!isset($json_import['meta']) || !isset($json_import['meta']['xsaf-version']) || $json_import['meta']['xsaf-version'] != XSAF_VERSION){
|
||||
if(DEBUG){
|
||||
echo "\nxsaf-version différentes !";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if($json_import['meta']['xsaf-db_transfer'] != "true") {$get_remote_db="0";} else {$get_remote_db="1";}
|
||||
if($json_import['meta']['xsaf-media_transfer'] != "true") {$get_remote_media="0";} else {$get_remote_media="1";}
|
||||
if(!empty($json_import['autoblogs'])) {
|
||||
foreach ($json_import['autoblogs'] as $value) {
|
||||
$infos="";
|
||||
if(count($value)==4 && !empty($value['SITE_TYPE']) && !empty($value['SITE_TITLE']) && !empty($value['SITE_URL']) && !empty($value['FEED_URL'])) {
|
||||
$sitetype = $value['SITE_TYPE'];
|
||||
$sitename = $value['SITE_TITLE'];
|
||||
$siteurl = escape($value['SITE_URL']);
|
||||
$rssurl = escape($value['FEED_URL']);
|
||||
if($sitetype == 'shaarli') { $articles_per_page = "20"; $update_interval = "1800"; $update_timeout = "30"; }
|
||||
else if($sitetype == 'microblog') { $articles_per_page = "20"; $update_interval = "300"; $update_timeout = "30"; }
|
||||
else { $articles_per_page = "5"; $update_interval = "3600"; $update_timeout = "30"; }
|
||||
|
||||
// $foldername = $sitename;$foldername2 = $sitename;
|
||||
$foldername = sha1(NoProtocolSiteURL($siteurl));
|
||||
if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');}
|
||||
|
||||
if(!file_exists($foldername) && !file_exists($foldername2)) {
|
||||
if ( mkdir('./'. $foldername, 0755, false) ) {
|
||||
$fp = fopen('./'. $foldername .'/index.php', 'w+');
|
||||
|
||||
$response = get_headers($rssurl, 1); // check for redirections
|
||||
if(!empty($response['Location'])) {
|
||||
$result="false";
|
||||
}else{
|
||||
$xml = simplexml_load_file($rssurl); // quick feed check
|
||||
|
||||
if($xml === FALSE){
|
||||
$result="false";
|
||||
}elseif (isset($xml->entry)) { // ATOM feed.
|
||||
$result="true";
|
||||
}elseif (isset($xml->item)) { // RSS 1.0 /RDF
|
||||
$result="true";
|
||||
}elseif (isset($xml->channel->item)) { // RSS 2.0
|
||||
$result="true";
|
||||
}else{
|
||||
$result="false";
|
||||
}
|
||||
}
|
||||
|
||||
/* autoblog */
|
||||
if($result!=="false") {
|
||||
if( !fwrite($fp, "<?php require_once dirname(__DIR__) . '/".AUTOBLOG_FILE_NAME."'; ?>") ) {
|
||||
$infos = "\nImpossible d'écrire le fichier index.php dans ".$foldername;
|
||||
fclose($fp);
|
||||
}else{
|
||||
fclose($fp);
|
||||
$fp = fopen('./'. $foldername .'/vvb.ini', 'w+');
|
||||
if( !fwrite($fp, '[VroumVroumBlogConfig]
|
||||
SITE_TYPE="'. $sitetype .'"
|
||||
SITE_TITLE="'. $sitename .'"
|
||||
SITE_DESCRIPTION="source: <a href="'. $siteurl .'">'. $sitename .'</a>"
|
||||
SITE_URL="'. $siteurl .'"
|
||||
FEED_URL="'. $rssurl .'"
|
||||
ARTICLES_PER_PAGE="'. $articles_per_page .'"
|
||||
UPDATE_INTERVAL="'. $update_interval .'"
|
||||
UPDATE_TIMEOUT="'. $update_timeout .'"') ){
|
||||
fclose($fp);
|
||||
$infos = "\nImpossible d'écrire le fichier vvb.ini dans ".$foldername;
|
||||
}else{
|
||||
fclose($fp);
|
||||
/* ============================================================================================================================================================================== */
|
||||
/* récupération de la DB distante */
|
||||
if($get_remote_db == "1") { $remote_db=str_replace("?export", $foldername."/articles.db", $xsafremote); copy($remote_db, './'. $foldername .'/articles.db'); }
|
||||
if($get_remote_media == "1")
|
||||
{
|
||||
$remote_media=str_replace("?export", $foldername."/?media", $xsafremote);
|
||||
$json_media_import = file_get_contents($remote_media);
|
||||
if(!empty($json_media_import))
|
||||
{
|
||||
mkdir('./'.$foldername.'/media/');
|
||||
$json_media_import = json_decode($json_media_import, true);
|
||||
$media_path=$json_media_import['url'];
|
||||
if(!empty($json_media_import['files']))
|
||||
{
|
||||
foreach ($json_media_import['files'] as $value)
|
||||
{
|
||||
copy($media_path.$value, './'.$foldername.'/media/'.$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ============================================================================================================================================================================== */
|
||||
|
||||
//TODO : tester si articles.db est une DB valide
|
||||
|
||||
$infos = "\nautoblog crée avec succès (DB:$get_remote_db media:$get_remote_media) : $foldername";
|
||||
$to_update[]=serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$infos = "\n$rssurl -> flux invalide"; unlink("./$foldername/index.php"); rmdir($foldername);
|
||||
}
|
||||
/* end of file writing */
|
||||
}else {
|
||||
$infos = "\nImpossible de créer le répertoire ".$foldername;
|
||||
}
|
||||
} else {
|
||||
/*$infos = "\nFin d'itération ou Le répertoire ".$foldername." existe déjà ($sitename;$siteurl;$rssurl)";*/
|
||||
}
|
||||
if(DEBUG){
|
||||
echo $infos;
|
||||
}
|
||||
}
|
||||
echo "\n time : ".(time() - $max_exec_time);
|
||||
if(time() >= $max_exec_time){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if(!empty($to_update)){
|
||||
if(DEBUG){
|
||||
echo "\nupdate of autoblogs ...";
|
||||
}
|
||||
// because it's could be very long, we finish by updating new autoblogs
|
||||
foreach ($to_update as $url) {
|
||||
get_headers($url);
|
||||
}
|
||||
if(DEBUG){
|
||||
echo "done\n\n";
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* And now, the XSAF links to be imported, with maximal execusion time for import in second ! */
|
||||
xsafimport('https://raw.github.com/mitsukarenai/xsaf-bootstrap/master/3.json', 5);
|
||||
//xsafimport('https://www.ecirtam.net/autoblogs/?export', 5);
|
||||
//xsafimport('https://autoblog.suumitsu.eu/?export', 5);
|
||||
|
||||
if(DEBUG) {
|
||||
echo "\n\nXSAF import finished\n\n";
|
||||
}
|
||||
die;
|
||||
?>
|
Loading…
Reference in a new issue