From 34d122a50ccfb79fa5192307959a96dd0bb2079a Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Wed, 13 Feb 2013 11:22:51 +0100 Subject: [PATCH] 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 --- 0.3/README.md | 18 + 0.3/autoblog.php | 881 ++++++++++++++++++++++++++++++++++++++++++++++ 0.3/config.php | 61 ++++ 0.3/icon-logo.svg | 1 + 0.3/index.php | 498 ++++++++++++++++++++++++++ 0.3/xsaf3.php | 200 +++++++++++ 6 files changed, 1659 insertions(+) create mode 100755 0.3/README.md create mode 100755 0.3/autoblog.php create mode 100755 0.3/config.php create mode 100755 0.3/icon-logo.svg create mode 100755 0.3/index.php create mode 100755 0.3/xsaf3.php diff --git a/0.3/README.md b/0.3/README.md new file mode 100755 index 0000000..9976a3a --- /dev/null +++ b/0.3/README.md @@ -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 :) diff --git a/0.3/autoblog.php b/0.3/autoblog.php new file mode 100755 index 0000000..edcae2d --- /dev/null +++ b/0.3/autoblog.php @@ -0,0 +1,881 @@ +=')) + 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 '

'.$e->getMessage().'

'; + 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 ' + + + '.escape($config->site_title).' + '.escape($config->site_url).' + '.escape(html_entity_decode(strip_tags($config->site_description), ENT_COMPAT, 'UTF-8')).' + + '; + + foreach($vvb->listLastArticles() as $art) + { + echo ' + + '.escape($art['title']).' + '.escape($art['feed_id']).' + '.$vvb->getLocalURL($art).' + '.date(DATE_RSS, $art['date']).' + + + + + + + '; + } + + echo ' + + '; + 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 ' + + + + + '.escape($config->site_title).' + + + + + +
+

'.escape($config->site_title).'

'; + +if (!empty($config->site_description)) + echo '

'.$config->site_description.'
⇐ retour index

'; + +echo ' +
+
+ + +
+
+
+'; + +if ($vvb->mustUpdate()) +{ + echo ' +
+
+

'.__('Update').'

+
+
+ '.__('Updating database... Please wait.').' +
+
'; +} + +if (!empty($search)) +{ + $results = $vvb->searchArticles($search); + $text = sprintf(__('%d results for %s'), count($results), escape($search)); + echo ' +
+
+

'.__('Search').'

+ '.$text.' +
+
'; + + foreach ($results as $art) + { + echo ' +
+

'.escape($art['title']).'

+

'.$art['content'].'

+
'; + } +} +elseif (!is_null($article)) +{ + if (!$article) + { + echo ' +
+
+

'.__('Not Found').'

+ '.(!empty($uri) ? '

'.escape($vvb->getLocalURL($uri)) . '

' : '').' + '.__('Article not found.').' +
+
'; + } + 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 ''; + } +} + +echo ' +'; + +if ($vvb->mustUpdate()) +{ + try { + ob_end_flush(); + flush(); + } + catch (Exception $e) + { + // Silent, not critical + } + + try { + $updated = $vvb->update(); + } + catch (VroumVroum_Feed_Exception $e) + { + echo ' +
+ '.escape($e->getMessage()).' +
'; + $updated = 0; + } + + if ($updated > 0) + { + echo ' + '; + } + else + { + echo ' + '; + } +} + +echo ' + +'; +// 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 ' +
+
+

'.escape($article['title']).'

+ '.strftime(__('_date_format'), $article['date']).' +
+
'.escape_content($article['content']).'
+

'.__('Source:').' '.escape($article['url']).'

+
+
'; +} + +?> diff --git a/0.3/config.php b/0.3/config.php new file mode 100755 index 0000000..512abad --- /dev/null +++ b/0.3/config.php @@ -0,0 +1,61 @@ +%d results for %s': + return '%d résultats pour la recherche %s'; + 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="
Love data
Data is essential
Data must flow
Data must be used
Data is neither good nor bad
There is no illegal data
Data is free
Data can not be owned
No man, machine or system shall interrupt the flow of data
Locking data is a crime against datanity"; +$HTML_footer=""; + +?> diff --git a/0.3/icon-logo.svg b/0.3/icon-logo.svg new file mode 100755 index 0000000..1b73481 --- /dev/null +++ b/0.3/icon-logo.svg @@ -0,0 +1 @@ +Never surrenderto censorship diff --git a/0.3/index.php b/0.3/index.php new file mode 100755 index 0000000..b0a79da --- /dev/null +++ b/0.3/index.php @@ -0,0 +1,498 @@ +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 !== '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='OK'; +$svg_jaune='mv'; +$svg_rouge='err'; +$svg_twitter=''; +$svg_identica=''; +$svg_statusnet=''; + + $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 = '

+
'; + +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 existe déjà.'); } + if ( mkdir('./'. $foldername, 0755, false) ) { + $fp = fopen('./'. $foldername .'/index.php', 'w+'); + if( !fwrite($fp, "") ) + {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: '. $sitename .'" +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('autoblog crée avec succès.afficher l\'autoblog');} + } +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 existe déjà.'); } + $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
+
+ +
+
+
+
+
'; + 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 existe déjà.'); } + $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, "") ) + $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: '. $socialaccount .'" +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[] = 'AutoMicroblog ajouté avec succès.'; + } + 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 existe déjà.'); } + if ( mkdir('./'. $foldername, 0755, false) ) { + $fp = fopen('./'. $foldername .'/index.php', 'w+'); + if( !fwrite($fp, "") ) + $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: '. $sitename .'" +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[] = 'autoblog crée avec succès.afficher l\'autoblog'; + } + 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 existe déjà.'); } + $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
+

+
+
+
+
'; + } + + } +} +?> + + + + + Le Projet Autoblog + + + +

LE PROJET AUTOBLOG

+
+ + Note
+ Voici une liste d'autoblogs hébergés sur (plus d'infos sur le projet).

+ Autres fermes
+ → Rechercher

+ +
Ajouter un compte social

+
+
+ Twitter
+ Identica
+
+ +

+
Ajouter un Shaarli

+
+ +
+ +

+
Ajouter un site web
+Erreur(s) :

    '; + foreach ( $error AS $value ) { + echo '
  • '. $value .'
  • '; + } + echo '
'; +} +?> +Si vous souhaitez que héberge un autoblog d'un site,
remplissez le formulaire suivant:

+ +

Pour ajouter facillement un autoblog d'un site web, glissez ce bouton dans votre barre de marque-pages => ";var%20popup=window.open("","Add%20autoblog",'height=180,width=670');popup.document.writeln('');popup.document.write('Url%20feed%20%20:%20
');var%20feed_links=new%20Array();var%20links=document.getElementsByTagName('link');if(links.length>0){for(var%20i=0;i'+links[i].title+"%20(%20"+links[i].href+"%20)
");}}}popup.document.writeln("");popup.document.writeln("");popup.document.writeln("
");popup.document.writeln("");})();">Projet Autoblog
+ +
+
+

Autoblogs hébergés

+ +$value) + { + $key = strtolower($key); + $config->$key = $value; + } + $autoblogs[$unit] = ' +
+ +
config | '.escape($config->site_type).' source: '.escape($config->site_url).'
+
'; + unset($ini); + } + } +} +if(!empty($autoblogs)){ + sort($autoblogs, SORT_STRING); + foreach ($autoblogs as $autoblog) { + echo $autoblog; + } +} +?> +
+".count($autoblogs)." autoblogs hébergés"; ?> +
+Propulsé par Projet Autoblog 0.3 de Mitsu et Oros (Domaine Public) +".$HTML_footer; } ?> + + + diff --git a/0.3/xsaf3.php b/0.3/xsaf3.php new file mode 100755 index 0000000..4f3d7e5 --- /dev/null +++ b/0.3/xsaf3.php @@ -0,0 +1,200 @@ + $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, "") ) { + $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: '. $sitename .'" +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; +?>