From 1899213e6cf6a660c22d3170b223135704f12e82 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sun, 14 Apr 2013 00:30:54 +0200 Subject: [PATCH 01/28] Bug fix : autoblog folder on response message link --- 0.3/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0.3/index.php b/0.3/index.php index be53a6c..3aabb50 100755 --- a/0.3/index.php +++ b/0.3/index.php @@ -118,7 +118,7 @@ function create_from_opml($opml) { $error = array_merge( $error, createAutoblog( $sitetype, $sitename, $siteurl, $rssurl, $error ) ); if( empty ( $error )) - $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; + $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; } catch (Exception $e) { $error[] = $e->getMessage(); @@ -534,7 +534,7 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ if( empty($error) ) { $error = array_merge( $error, createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl, $error)); if( empty($error)) - $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; + $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; } } } From 098c0ccd4f761f88a3e9bca3e3bf8ed3cbe430a6 Mon Sep 17 00:00:00 2001 From: Oros Date: Sun, 14 Apr 2013 19:32:00 +0200 Subject: [PATCH 02/28] =?UTF-8?q?Fix=20bug=20javascript=20si=20un=20des=20?= =?UTF-8?q?boutons=20d'ajout=20est=20d=C3=A9sactiv=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0.3/index.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/0.3/index.php b/0.3/index.php index 3aabb50..e7beeeb 100755 --- a/0.3/index.php +++ b/0.3/index.php @@ -895,15 +895,15 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY From 02b74c3bf2d5694b8c6e8e9c4e47e4455aba6bc2 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Sun, 14 Apr 2013 20:00:38 +0200 Subject: [PATCH 03/28] branched --- 0.1/README.md | 20 -- 0.1/index.php | 403 --------------------- 0.1/vvb.ini | 6 - 0.2/README.md | 24 -- 0.2/autoblog.php | 897 ---------------------------------------------- 0.2/config.php | 54 --- 0.2/icon-logo.svg | 1 - 0.2/index.php | 462 ------------------------ 0.2/xsaf2.php | 179 --------- 9 files changed, 2046 deletions(-) delete mode 100755 0.1/README.md delete mode 100755 0.1/index.php delete mode 100644 0.1/vvb.ini delete mode 100755 0.2/README.md delete mode 100755 0.2/autoblog.php delete mode 100755 0.2/config.php delete mode 100755 0.2/icon-logo.svg delete mode 100755 0.2/index.php delete mode 100755 0.2/xsaf2.php diff --git a/0.1/README.md b/0.1/README.md deleted file mode 100755 index f2b41be..0000000 --- a/0.1/README.md +++ /dev/null @@ -1,20 +0,0 @@ -Projet Autoblog serie 0.1 -============== - -- version VroumVroumBlog 0.1.32 - -Auteur: Sebastien Sauvage - -Licence: Domaine Public - -- À propos du Projet Autoblog - -lire: http://sebsauvage.net/streisand.me/fr/ - -- Contraintes techniques - -voir: http://sebsauvage.net/streisand.me/fr/tech.html - -- Instructions - -Personnalisez vvb.ini. Envoyez index.php et vvb.ini sur votre site web, dans le répertoire de votre choix. Terminé ! diff --git a/0.1/index.php b/0.1/index.php deleted file mode 100755 index 7fe2161..0000000 --- a/0.1/index.php +++ /dev/null @@ -1,403 +0,0 @@ -= 0) { libxml_disable_entity_loader(true); } - -$CONFIG=parse_ini_file('vvb.ini') or die('Missing or bad config file vvb.ini'); // Read config file. -$CONFIG['ARTICLES_PER_PAGE']=10; -$CONFIG['DOWNLOAD_MEDIA_TYPES']=array('jpeg','jpg','gif','png','pdf','txt','odt'); // Media types which will be downloaded. -$CONFIG['MEDIA_TO_DOWNLOAD']=array(); // List of media to download in background. -// ================================================================================================== -/* Callback for the preg_replace_callback() function in remapImageUrls() which remaps URLs to point to local cache. - (src=... and href=...) */ -function remap_callback($matches) -{ - global $CONFIG; - $attr = $matches[1]; $url = $matches[2]; $srchost=parse_url($url,PHP_URL_HOST); - if (!mediaAuthorized($url)) { return $attr.'="'.$url.'"'; } // Not authorized: do not remap URL. - if (!file_exists('media/'.sanitize($url)) ) { $CONFIG['MEDIA_TO_DOWNLOAD'][] = $url; } // If media not present in the cache, add URL to list of media to download in background. - return $attr.'="?m='.$url.'"'; // Return remapped URL. -} - -/* Remaps image URL to point to local cache (src= and href=) -eg. src="http://toto.com/..." --> src="?m=http://toto.com/..." -*/ -function remapImageUrls($html) -{ - return preg_replace_callback("@(src|href)=[\"\'](.+?)[\"\']@i",'remap_callback',$html); -} - -/* updateFeed(): Update articles database from a RSS2.0 feed. - Articles deleted from the feed are not deleted from the database. - You can force the refresh by passing ?force_the_refresh in URL. -*/ -function updateFeed() -{ - global $CONFIG; - // Only update feed if last check was > 60 minutes - // but you can force it with force_the_refresh in GET parameters. - if (@filemtime('store')>time()-(3600) && !isset($_GET['force_the_refresh'])) { return; } - - // Read database from disk - $feed_items=(file_exists('store') ? unserialize(file_get_contents('store')) : array() ); - - // Read the feed and update the database. - $xml = simplexml_load_file($CONFIG['FEED_URL']); - if (isset($xml->entry)) // ATOM feed. - { - foreach ($xml->entry as $item) - { - $pubDate=$item->published; if (!$pubDate) { $pubDate=$item->updated; } - $i=array('title'=>strval($item->title),'link'=>strval($item->link['href']),'guid'=>strval($item->id),'pubDate'=>strval($pubDate), - 'description'=>'','content'=>remapImageUrls(strval($item->content))); - $i['dateiso'] = date('Ymd_His', strtotime($i['pubDate'])); - $feed_items[$i['dateiso']] = $i; - } - } - elseif (isset($xml->item)) // RSS 1.0 /RDF - { - foreach ($xml->item as $item) - { - $guid =$item->attributes('http://www.w3.org/1999/02/22-rdf-syntax-ns#')->about; - $date =$item->children('http://purl.org/dc/elements/1.1/')->date; - $content = $item->children('http://purl.org/rss/1.0/modules/content/'); - $i=array('title'=>strval($item->title),'link'=>strval($item->link),'guid'=>strval($guid),'pubDate'=>strval($date), - 'description'=>strval($item->description),'content'=>remapImageUrls(strval($content))); - $i['dateiso'] = date('Ymd_His', strtotime($i['pubDate'])); - $feed_items[$i['dateiso']] = $i; - } - } - elseif (isset($xml->channel->item)) // RSS 2.0 - { - foreach ($xml->channel->item as $item) - { - $content = strval($item->children('http://purl.org/rss/1.0/modules/content/')); // Get - if (!$content) { $content = strval($item->description); } // Some feeds put content in the description. - $pubDate = $item->pubDate; - if (!$pubDate) { $pubDate=$item->children('http://purl.org/dc/elements/1.1/')->date; } // To read the tag content. - $i=array('title'=>strval($item->title),'link'=>strval($item->link),'guid'=>strval($item->guid),'pubDate'=>strval($pubDate), - 'description'=>strval($item->description),'content'=>remapImageUrls($content)); - $i['dateiso'] = date('Ymd_His', strtotime($i['pubDate'])); - $feed_items[$i['dateiso']] = $i; - } - } - krsort($feed_items); // Sort array, latest articles first. - file_put_contents('store', serialize($feed_items)); // Write database to disk -} - -/* feed(): Returns the feed as an associative array (latest articles first). - Key is timestamp in compact iso format (eg. '20110628_073208') - Value is an associative array (title,link,content,pubDate...) -*/ -function feed() -{ - $data=file_get_contents('store'); - if ($data===FALSE) { $feed_items=array(); } else { $feed_items = unserialize($data); } - return $feed_items; -} - -/* Remove accents (é-->e) */ -function replace_accents($str) { - $str = htmlentities($str, ENT_COMPAT, "UTF-8"); - $str = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/','$1',$str); - return html_entity_decode($str); -} - -// Sanitize strings for use in filename or URLs -function sanitize($name) -{ - $fname=replace_accents($name); - $replace="_"; - $pattern="/([[:alnum:]_\.-]*)/"; // The autorized characters. - $fname=str_replace(str_split(preg_replace($pattern,$replace,$fname)),$replace,$fname); - return $fname; -} - -// Tells if a string start with a substring or not. -function startsWith($haystack,$needle,$case=true) { - if($case){return (strcmp(substr($haystack, 0, strlen($needle)),$needle)===0);} - return (strcasecmp(substr($haystack, 0, strlen($needle)),$needle)===0); -} -// Tells if a string ends with a substring or not. -function endsWith($haystack,$needle,$case=true) { - if($case){return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);} - return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0); -} - -/* Returns the CSS stylesheet to include in HTML document */ -function css() -{ - return << - - -HTML; -} - -/* Render a single article - $article : the article itself (associative array with title,pubDate,content,dateiso keys.) -*/ -function renderArticle($article) -{ - echo '
'; - echo '

'.$article['title'].'

'.$article['pubDate']; - if ($article['link']!='') { echo ' - (source)'; } - echo '
'.$article['content'].'
'; - echo '
'; -} - -function rssHeaderLink() { return ''; } -function searchForm() { return ''; } -function powered() { return '
Powered by VroumVroumBlog 0.1.32 - RSS Feed
Download config articles
'; } -function canonical_metatag($url) { return ''; } - -/* Show a single article - $articleid = article identifier (eg.'20110629_010334') -*/ -function showArticle($articleid) -{ - global $CONFIG; - header('Content-Type: text/html; charset=utf-8'); - $feed=feed();if (!array_key_exists($articleid,$feed)) { die('Article not found.'); } - $a=$feed[$articleid]; - echo ''.$a['title'].' - '.$CONFIG['SITE_TITLE'].''.canonical_metatag($a['link']).css().rssHeaderLink().''; - echo '

'.$CONFIG['SITE_TITLE'].'

'.$CONFIG['SITE_DESCRIPTION'].searchForm().'
'; - renderArticle($a); - echo ''.powered().''; -} - -/* Show a list of articles, starting at a specific page. - $page = start page. First page is page 1. -*/ -function showArticles($page) -{ - global $CONFIG; - header('Content-Type: text/html; charset=utf-8'); - $feed=feed(); - $keys=array_keys($feed); - echo ''.$CONFIG['SITE_TITLE'].''.canonical_metatag($CONFIG['SITE_URL']).css().rssHeaderLink().''; - echo '

'.$CONFIG['SITE_TITLE'].'

'.$CONFIG['SITE_DESCRIPTION'].searchForm().'
'; - $i = ($page-1)*$CONFIG['ARTICLES_PER_PAGE']; // Start index. - $end = $i+$CONFIG['ARTICLES_PER_PAGE']; - while ($i<$end && $i
'; - if ($i!=count($keys)) { echo ''; } - echo ''; - if ($page>1) { echo ''; } - echo '
'.powered().''; -} - -/* Search for text in articles content and title. - $textpage = text to search. -*/ -function search($text) -{ - global $CONFIG; - header('Content-Type: text/html; charset=utf-8'); - $txt = urldecode($text); - echo ''.$CONFIG['SITE_TITLE'].''.css().rssHeaderLink().''; - echo '

'.$CONFIG['SITE_TITLE'].'

'.$CONFIG['SITE_DESCRIPTION'].searchForm().'
'; - echo '
Search for '.htmlspecialchars($txt).' :
'; - $feed=feed(); - foreach($feed as $article) - { - if (stripos($article['content'],$txt) || stripos($article['title'],$txt)) { renderArticle($article); } - } - echo ''.powered().''; -} - -/* Tells if a media URL should be downloaded or not. - Input: $url = absolute URL of a media (jpeg,pdf...) - Output: true= can download. false= should not download (wrong host, wrong file extension) */ -function mediaAuthorized($url) -{ - global $CONFIG; - $goodhost=false; $srchost=parse_url($url,PHP_URL_HOST); - foreach( explode(',',$CONFIG['DOWNLOAD_MEDIA_FROM']) as $host) // Does the URL point to an authorized host ? - { if ($srchost==$host) { $goodhost=true; } } - if (!$goodhost) { return false; } // Wrong host. - $ext = pathinfo($url, PATHINFO_EXTENSION); // Get file extension (eg.'png','gif'...) - if (!in_array(strtolower($ext),$CONFIG['DOWNLOAD_MEDIA_TYPES'])) { return false; } // Not in authorized file extensions. - return true; -} - -// Returns the MIME type corresponding to a file extension. -// (I do not trust mime_content_type() because of some dodgy hosting providers with ill-configured magic.mime file.) -function mime_type($filename) -{ - $MIME_TYPES=array('.jpg'=>'image/jpeg','.jpeg'=>'image/jpeg','.png'=>'image/png','.gif'=>'image/gif', - '.txt'=>'text/plain','.odt'=>'application/vnd.oasis.opendocument.text'); - foreach($MIME_TYPES as $extension=>$mime_type) { if (endswith($filename,$extension,false)) { return $mime_type; } } - return 'application/octet-stream'; // For an unkown extension. -} -// Returns a media from the local cache (and download it if not available). -function showMedia($imgurl) -{ - if (!mediaAuthorized($imgurl)) { header('HTTP/1.1 404 Not Found'); return; } - downloadMedia($imgurl); // Will only download if necessary. - $filename = 'media/'.sanitize($imgurl); - header('Content-Type: '.mime_type($filename)); - readfile($filename); -} - -// Download a media to local cache (if necessary) -function downloadMedia($imgurl) -{ - $filename = 'media/'.sanitize($imgurl); - if (!file_exists($filename) ) // Only download image if not present - { - if (!is_dir('media')) { mkdir('media',0705); file_put_contents('media/index.html',' '); } - file_put_contents($filename, file_get_contents($imgurl,NULL, NULL, 0, 4000000)); // We download at most 4 Mb from source. - } -} - -/* Output the whole feed in RSS 2.0 format with article content (BIG!) */ -function outputFeed() -{ - global $CONFIG; - header('Content-Type: application/xhtml+xml; charset=utf-8'); - echo ''; - echo ''.htmlspecialchars($CONFIG['SITE_TITLE']).''.htmlspecialchars($CONFIG['SITE_URL']).''; - echo ''.htmlspecialchars($CONFIG['SITE_URL']).''."\n\n"; - $feed=feed(); - foreach($feed as $a) - { - echo ''.$a['title'].''.$a['guid'].'http://'.$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"].'?'.$a['dateiso'].'_'.sanitize($a['title']).''.$a['pubDate'].''; - echo ''."\n\n"; - } - echo ''; -} - -// ================================================================================================== -// Update feed if necessary. (you can force refresh with ?force_the_refresh in URL) -updateFeed(); - -// Handle media download requests (eg. http://myserver.com/?m=http___anotherserver.net_images_myimage.jpg) -if (startswith($_SERVER["QUERY_STRING"],'m=')) { showMedia(substr($_SERVER["QUERY_STRING"],2)); } - -// Handle single article URI (eg. http://myserver.com/?20110506_224455-chit-chat) -elseif (preg_match('/^(\d{8}_\d{6})/',$_SERVER["QUERY_STRING"],$matches)) { showArticle($matches[1]); } - -// Handle page URI (eg. http://myserver.com/?page5) -elseif (preg_match('/^page(\d+)/',$_SERVER["QUERY_STRING"],$matches)) { showArticles($matches[1]); } - -// Handle RSS 2.0 feed request (http://myserver.com/?feed) -elseif (startswith($_SERVER["QUERY_STRING"],'feed')) { outputFeed(); } - -// Handle search request (eg. http://myserver.com/?s=tuto4pc) -elseif (startswith($_SERVER["QUERY_STRING"],'s=')) { search(substr($_SERVER["QUERY_STRING"],2)); } - -// Nothing ? Then render page1. -else { showArticles(1); } - -// Force flush, rendered page is fully sent to browser. -ob_end_flush(); -flush(); - -// Now we've finised rendering the page and sending to the user, -// it's time for some background tasks: Are there media to download ? -foreach($CONFIG['MEDIA_TO_DOWNLOAD'] as $url) { downloadMedia($url); } - -exit; -?> \ No newline at end of file diff --git a/0.1/vvb.ini b/0.1/vvb.ini deleted file mode 100644 index 60ebaa3..0000000 --- a/0.1/vvb.ini +++ /dev/null @@ -1,6 +0,0 @@ -[VroumVroumBlogConfig] -SITE_TITLE="Autoblog de Sebsauvage" -SITE_DESCRIPTION="Ce site n'est pas le site officiel de Sebsauvage
C'est un blog automatisé qui réplique les articles de sebsauvage.net" -SITE_URL=http://sebsauvage.net/rhaa/ -FEED_URL=http://sebsauvage.net/rhaa/rss_fulltext.php -DOWNLOAD_MEDIA_FROM=sebsauvage.net diff --git a/0.2/README.md b/0.2/README.md deleted file mode 100755 index a071631..0000000 --- a/0.2/README.md +++ /dev/null @@ -1,24 +0,0 @@ -Projet Autoblog serie 0.2 -============== - -- version VroumVroumBlog 0.2.11 - -Auteurs: BohwaZ (VVB) & Arthur Hoaro, Mitsukarenai, Oros (index ferme d'autoblogs) - -Licence: Domaine Public - -- À propos du Projet Autoblog - -lire: http://sebsauvage.net/streisand.me/fr/ - -- Présentation et Instructions pour VVB 0.2 (par BohwaZ) - -voir: http://blogs.kd2.org/bohwaz/?2011/07/14/369-auto-blog-vroumvroumblog-et-effet-streisand - -- Présentation et Instructions pour la ferme d'autoblogs (par Arthur Hoaro) - -voir: http://wiki.hoa.ro/doku.php?id=web%3Aferme-autoblog - -- Améliorations pour la ferme d'autoblogs et XSAF (par Mitsukarenai et Oros) - -voir: https://www.suumitsu.eu/2012/08/autoblogs-petites-ameliorations/ diff --git a/0.2/autoblog.php b/0.2/autoblog.php deleted file mode 100755 index 647d4d1..0000000 --- a/0.2/autoblog.php +++ /dev/null @@ -1,897 +0,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('LOCAL_DB_FILE')) define('LOCAL_DB_FILE', ROOT_DIR . '/local.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_title = ''; - public $site_description = ''; - public $site_url = ''; - public $feed_url = ''; - public $download_media_from = null; - public $download_media_types = 'jpg,jpeg,png,gif,pdf'; - 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_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!"); - } - - // Default value - if (is_null($this->download_media_from)) - { - $this->download_media_from = preg_replace('!^https?://([^/]+).*$!', '\\1', $this->site_url); - } - } - - public function __set($key, $value) - { - return; - } -} - -// BLOG - -class VroumVroum_Blog -{ - const VERSION = '0.2.11'; - - 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; - $create_local_db = file_exists(LOCAL_DB_FILE) ? false : true; - - $this->articles = new SQLite3(ARTICLES_DB_FILE); - $this->local = new SQLite3(LOCAL_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 UNIQUE INDEX feed_id ON articles (feed_id); - CREATE INDEX date ON articles (date); - '); - } - - if ($create_local_db) - { - $this->local->exec(' - CREATE VIRTUAL TABLE search USING fts3 ( - id INT PRIMARY KEY, - title TEXT, - content TEXT - ); - - CREATE TABLE update_log ( - date INT PRIMARY KEY, - success INT, - log TEXT - );'); - } - - $this->local->createFunction('countintegers', array($this, 'sql_countintegers')); - } - - public function getLocalURL($in) - { - return LOCAL_URL . LOCAL_URI . (is_array($in) ? $in['uri'] : $in); - } - - protected function log_update($success, $log = '') - { - $this->local->exec('INSERT INTO update_log (date, success, log) VALUES (\''.time().'\', \''.(int)(bool)$success.'\', - \''.$this->articles->escapeString($log).'\');'); - - // Delete old log - $this->local->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; - } - - if (!empty($this->config->download_media_from) && !empty($this->config->download_media_types)) - $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); - - $this->local->exec('INSERT INTO search (id, title, content) VALUES (\''.(int)$id.'\', - \''.$this->local->escapeString($title).'\', \''.$this->local->escapeString($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'] && !empty($this->config->download_media_from) && !empty($this->config->download_media_types)) - $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); - - $this->local->exec('UPDATE search SET title=\''.$this->local->escapeString($title).'\', - content=\''.$this->local->escapeString($content).'\' WHERE id = \''.(int)$id.'\';'); - } - - return $id; - } - - public function mustUpdate() - { - if (isset($_GET['update'])) - return true; - - $last_update = $this->local->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->local->exec('BEGIN TRANSACTION;'); - $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;'); - $this->local->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->local->query('SELECT id, title, snippet(search, "", "", "...", -1, -40) AS snippet - FROM search - WHERE search MATCH \''.$this->local->escapeString($query).'\' - ORDER BY countintegers(offsets(search)) 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); - } - - $extensions = explode(',', preg_quote($this->config->download_media_types, '!')); - $extensions = implode('|', $extensions); - - $hosts = explode(',', preg_quote($this->config->download_media_from, '!')); - $hosts = implode('|', $hosts); - $hosts = str_replace('\\*', '.*', $hosts); - - $schemes = array('http', 'https'); - - $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 (!preg_match('!^(?:'.$hosts.')$!i', $url['host'])) - 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 - } - } - - if ($copied) - { - $content = str_replace($m[0], $m[1] . '="media/'.$filename.'" data-original-source="'.$url.'"', $content); - } - else - { - $content = str_replace($m[0], $m[1] . '="'.$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; - -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['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); - } -} - -// HTML HEADER -echo ' - - - - - '.escape($config->site_title).' - - - - - -
-

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

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

'.$config->site_description.'

'; - -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['snippet'].'

-
'; - } -} -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']).'

-
-
'; -} - -function get_css() -{ - return ' - * { margin: 0; padding: 0; } - body { font-family:"Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; background-color: #3E4B50; padding: 1%; color: #000; } - img { max-width: 100%; height: auto; } - .header h1 { text-shadow: 2px 2px 2px #000; } - .header h1 a { text-decoration: none; color: #eee; } - .header { padding: 1% 3%; color: #eee; margin: 0 10%; border-bottom: 1px solid #aaa; background: #6A6A6A; } - .header p a { color: #bbb; } - .header p a:hover { color:#FFFFC9; text-decoration:none;} - .article .title h2 { margin: 0; color:#666; text-shadow: 1px 1px 1px #fff; } - .article .title h2 a { color:#666; text-decoration:none; } - .article .title h2 a:hover { color:#403976; } - .pagination { margin: 0 10%; padding: 1% 2%; background: #6A6A6A; } - .pagination b { font-size: 1.2em; color: #ffffc9; } - .pagination a { color:#ccc; margin: 0 0.5em; } - .pagination a:hover { color:#FFFFC9; } - .article { margin: 0 10%; padding: 1% 2%; background: #ccc; border-bottom: 1px solid #888; } - .article h4 { font-weight: normal; font-size: small; color: #666; } - .article .title { margin-bottom: 1em; } - .article .source { font-size: 0.8em; color: #666; } - .article .source a { color: #666; } - .searchForm { float:right; background: #6a6a6a; border: 1px solid #aaa; border-top: none; padding: 0 0.3em 0.3em; margin-top: 1.3%; } - .searchForm input { padding: 0.2em; border: 1px solid #999; background: #eee; color: #000; } - .footer { text-align:center; font-size: small; color:#aaa; clear: both; } - .footer a { color:#ccc; } - .footer a:hover { color:#FFFFC9; } - .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; } - .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; }'; -} - -?> diff --git a/0.2/config.php b/0.2/config.php deleted file mode 100755 index 1c3ec6a..0000000 --- a/0.2/config.php +++ /dev/null @@ -1,54 +0,0 @@ -%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; - } -} - -// 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.2/icon-logo.svg b/0.2/icon-logo.svg deleted file mode 100755 index 1b73481..0000000 --- a/0.2/icon-logo.svg +++ /dev/null @@ -1 +0,0 @@ -Never surrenderto censorship diff --git a/0.2/index.php b/0.2/index.php deleted file mode 100755 index e57fc2b..0000000 --- a/0.2/index.php +++ /dev/null @@ -1,462 +0,0 @@ -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=''; - - if(strpos($_GET['check'], 'twitter') !== FALSE) { header('Content-type: image/svg+xml');die($svg_twitter); } - if(strpos($_GET['check'], 'identica') !== FALSE) { header('Content-type: image/svg+xml');die($svg_identica); } - if(strpos($_GET['check'], 'statusnet') !== FALSE) { header('Content-type: image/svg+xml');die($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'); - $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); - $title=$config->site_title; - $url=$config->site_url; - $feed=$config->feed_url; - $reponse[$unit] = array("$title", "$url", "$feed"); - } - } -echo json_encode($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') -{ - if(isset($_GET['add']) && $_GET['add'] === '1' && !empty($_GET['siteurl']) && !empty($_GET['sitename'])) - { - $rssurl = DetectRedirect(escape($_GET['rssurl'])); - $siteurl = escape($_GET['siteurl']); - $foldername = sha1(NoProtocolSiteURL($siteurl)); - if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');} - $sitename = escape($_GET['sitename']); - $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, "") ) - {die("Impossible d'écrire le fichier index.php");} - fclose($fp); - $fp = fopen('./'. $foldername .'/vvb.ini', 'w+'); - if( !fwrite($fp, '[VroumVroumBlogConfig] -SITE_TITLE="'. $sitename .'" -SITE_DESCRIPTION="Ce site n\'est pas le site officiel de '. $sitename .'
C\'est un blog automatisé qui réplique les articles de '. $sitename .'" -SITE_URL="'. $siteurl .'" -FEED_URL="'. $rssurl .'" -DOWNLOAD_MEDIA_FROM='.$sitedomain) ) - {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 - $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'])) -{ -$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'; } - $folder = "$socialinstance-$socialaccount";if(file_exists($folder)) { die('Erreur: l\'autoblog existe déjà.'); } - if($socialinstance === 'twitter') { $siteurl = "http://twitter.com/$socialaccount"; $rssurl = "http://api.twitter.com.nyud.net/1/statuses/user_timeline.rss?screen_name=$socialaccount"; } - if($socialinstance === 'identica') { $siteurl = "http://identi.ca/$socialaccount"; $rssurl = "http://identi.ca.nyud.net/api/statuses/user_timeline/$socialaccount.rss"; } - if($socialinstance === 'statusnet' && !empty($_POST['socialurl'])) { $siteurl = "http://".escape($_POST['socialurl'])."/$socialaccount"; $rssurl = "http://".escape($_POST['socialurl'])."/api/statuses/user_timeline/$socialaccount.rss"; } - $headers = get_headers($rssurl, 1); - if (strpos($headers[0], '200') == FALSE) {$error[] = "Flux inaccessible (compte inexistant ?)";} else { } -if( empty($error) ) { - if( !preg_match('#\.\.|/#', $folder) ) { - if ( mkdir('./'. $folder, 0755, false) ) { - $fp = fopen('./'. $folder .'/index.php', 'w+'); - if( !fwrite($fp, "") ) - $error[] = "Impossible d'écrire le fichier index.php"; - fclose($fp); - $fp = fopen('./'. $folder .'/vvb.ini', 'w+'); - if( !fwrite($fp, '[VroumVroumBlogConfig] -SITE_TITLE="'.$socialinstance.'-'.$socialaccount.'" -SITE_DESCRIPTION="AutoMicroblog automatisé de " -SITE_URL='. $siteurl .' -FEED_URL="'. $rssurl .'"') ) - $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']) ) { - $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_TITLE="'. $sitename .'" -SITE_DESCRIPTION="Ce site n\'est pas le site officiel de '. $sitename .'
C\'est un blog automatisé qui réplique les articles de '. $sitename .'" -SITE_URL="'. $siteurl .'" -FEED_URL="'. $rssurl .'" -DOWNLOAD_MEDIA_FROM='.$sitedomain) ) - $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); - $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 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, 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] = ' - '; - unset($ini); - } - } -} -if(!empty($autoblogs)){ - sort($autoblogs, SORT_STRING); - foreach ($autoblogs as $autoblog) { - echo $autoblog; - } -} -?> -
-".count($autoblogs)." autoblogs d'hébergés"; ?> -
-Autoblogs propulsés par VroumVroumBlog 0.2.10 [SQLite] (Domaine Public)
index2 inspiré par Arthur et développé par Mitsu et Oros (Domaine Public) -
Code source du projet -".$HTML_footer; } ?> - - - diff --git a/0.2/xsaf2.php b/0.2/xsaf2.php deleted file mode 100755 index ff896fc..0000000 --- a/0.2/xsaf2.php +++ /dev/null @@ -1,179 +0,0 @@ - $expire) { - echo "too early"; - die; - }else{ - unlink($lockfile); - file_put_contents($lockfile, ''); - } -}else{ - file_put_contents($lockfile, ''); -} - -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 - - $json_import = file_get_contents($xsafremote); - if(!empty($json_import)) { - $to_update=array(); - foreach (json_decode($json_import) as $value) { - $infos=""; - if(count($value)==3 && !empty($value[0]) && !empty($value[1]) && !empty($value[2])) { - $sitename = $value[0]; - $siteurl = escape($value[1]); - $rssurl = escape($value[2]); - if(strpos($siteurl, 'twitter.com') !== FALSE or strpos($siteurl, 'identi.ca') !== FALSE or strpos($sitename, 'statusnet-') !== FALSE) {$social=TRUE;} else {$social=FALSE;} - if($social==FALSE) { - $foldername = sha1(NoProtocolSiteURL($siteurl)); - if(substr($siteurl, -1) == '/'){ $foldername2 = sha1(NoProtocolSiteURL(substr($siteurl, 0, -1))); }else{ $foldername2 = sha1(NoProtocolSiteURL($siteurl).'/');} - } else{ - $foldername = $sitename;$foldername2 = $sitename; - } - - $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)) { - 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($social==FALSE and $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_TITLE="'. $sitename .'" -SITE_DESCRIPTION="Ce site n\'est pas le site officiel de '. $sitename .'
C\'est un blog automatisé qui réplique les articles de '. $sitename .'" -SITE_URL="'. $siteurl .'" -FEED_URL="'. $rssurl .'" -DOWNLOAD_MEDIA_FROM='.$sitedomain) ){ - fclose($fp); - $infos = "\nImpossible d'écrire le fichier vvb.ini dans ".$foldername; - }else{ - fclose($fp); - $infos = "\nautoblog crée avec succès : $foldername"; - $to_update[]=serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog - } - } - } - /* automicroblog */ - else if($social!==FALSE and $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_TITLE="'. $sitename .'" -SITE_DESCRIPTION="AutoMicroblog automatisé de " -SITE_URL="'. $siteurl .'" -FEED_URL="'. $rssurl .'"') ){ - fclose($fp); - $infos = "\nImpossible d'écrire le fichier vvb.ini dans ".$foldername; - }else{ - fclose($fp); - $infos = "\nautomicroblog crée avec succès : $foldername"; - $to_update[]=serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog - } - } - } else { - $infos = "\n$rssurl -> flux invalide"; - } - /* 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/2.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; -?> From fd9f5db323590df9dfa38370c2d2cd35873b2848 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Sat, 20 Apr 2013 13:25:24 +0200 Subject: [PATCH 04/28] =?UTF-8?q?v=C3=A9rifier=20existance=20de=20vvb.ini?= =?UTF-8?q?=20avant=20ouverture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0.3/index.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0.3/index.php b/0.3/index.php index e7beeeb..c797b0f 100755 --- a/0.3/index.php +++ b/0.3/index.php @@ -852,6 +852,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY if(is_dir($unit)) { if( !file_exists(ROOT_DIR . '/' . $unit . '/.disabled')) { + if( file_exists(ROOT_DIR . '/' . $unit . '/vvb.ini')) { $ini = parse_ini_file(ROOT_DIR . '/' . $unit . '/vvb.ini'); if($ini) { @@ -865,6 +866,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY $autoblogs[$unit] = $config; unset($ini); } + } } } } From e201da73c02217c18cc8d1c5e016c50ab30f8c33 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Sat, 20 Apr 2013 14:32:59 +0200 Subject: [PATCH 05/28] WORK IN PROGRESS: rss_tmp (JSON status updates) -read comment --- 0.3/functions.php | 24 ++++++++++++++++++++++++ 0.3/index.php | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/0.3/functions.php b/0.3/functions.php index 0989289..0db7ae2 100755 --- a/0.3/functions.php +++ b/0.3/functions.php @@ -237,4 +237,28 @@ function __($str) return $str; } } + +function displayXML_tmp() { +header('Content-type: application/rss+xml; charset=utf-8'); +echo ' +'; +echo ''.serverUrl(true).'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; +if(file_exists(RESOURCES_FOLDER.'rss.json')) +{ + $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); + foreach ($json as $item) + { + echo ''; + echo ''.$item[autoblog_title].''; + echo ''.$item[status].$item[response_code].$item[autoblog_url].$item[autoblog_title].$item[autoblog_sourceurl].$item[autoblog_sourcefeed].''; + echo ''.serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url].''; + echo ''.serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url].''; + echo 'admin@'.serverUrl(true).''; + echo ''.date("r", $item[timestamp]).''; + echo ''; + } +} +echo ' +'; +} ?> diff --git a/0.3/index.php b/0.3/index.php index c797b0f..c0a512f 100755 --- a/0.3/index.php +++ b/0.3/index.php @@ -173,6 +173,11 @@ if (isset($_GET['rss'])) { die; } +if (isset($_GET['rss_tmp'])) { + displayXML_tmp(); + die; +} + /** * SVG **/ From 4838b0bac5258f83ab2d0d6440cdb3220550d659 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Sat, 20 Apr 2013 23:28:25 +0200 Subject: [PATCH 06/28] =?UTF-8?q?BETA:=20stockage=20et=20traitement=20en?= =?UTF-8?q?=20JSON=20des=20changements=20de=20dispo=20=C3=80=20consid?= =?UTF-8?q?=C3=A9rer=20comme=20possible=20rempla=C3=A7ant=20de=20class=5Fr?= =?UTF-8?q?ssfeed=20et=20fonctions=20li=C3=A9es=20(TODO:=20trouver=20un=20?= =?UTF-8?q?traitement=20d'import=20OPML=20fiable)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0.3/functions.php | 66 +++++++++++++++++++++++++++++++++++++---------- 0.3/index.php | 7 +++++ 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/0.3/functions.php b/0.3/functions.php index 0db7ae2..e78272b 100755 --- a/0.3/functions.php +++ b/0.3/functions.php @@ -111,7 +111,7 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { /** * RSS **/ - try { + try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); $rss->addNewAutoblog($sitename, $foldername, $siteurl, $rssurl); @@ -140,7 +140,7 @@ UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) } else $error[] = "Impossible de créer le répertoire."; - + updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); /* éventuellement une conditionnelle ici: if(empty($error)) ? */ return $error; } @@ -238,27 +238,65 @@ function __($str) } } +function updateXML($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) +{ +$json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); +$json[] = array( + 'timestamp'=>time(), + 'autoblog_url'=>$autoblog_url, + 'autoblog_title'=>$autoblog_title, + 'autoblog_sourceurl'=>$autoblog_sourceurl, + 'autoblog_sourcefeed'=>$autoblog_sourcefeed, + 'status'=>$status, + 'response_code'=>$response_code + ); +file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX); +} + +function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { + switch ($status) + { + case 'unavailable': + return 'Autoblog "'.$autoblog_title.'": site distant inaccessible (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'moved': + return 'Autoblog "'.$autoblog_title.'": site distant redirigé (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'not_found': + return 'Autoblog "'.$autoblog_title.'": site distant introuvable (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'remote_error': + return 'Autoblog "'.$autoblog_title.'": site distant a problème serveur (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'available': + return 'Autoblog "'.$autoblog_title.'": site distant à nouveau opérationnel (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'new_autoblog_added': + return 'Autoblog "'.$autoblog_title.'" ajouté (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + } +} + function displayXML_tmp() { header('Content-type: application/rss+xml; charset=utf-8'); echo ' -'; -echo ''.serverUrl(true).'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; +'.serverUrl(true).''; +echo 'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; if(file_exists(RESOURCES_FOLDER.'rss.json')) { $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); foreach ($json as $item) { - echo ''; - echo ''.$item[autoblog_title].''; - echo ''.$item[status].$item[response_code].$item[autoblog_url].$item[autoblog_title].$item[autoblog_sourceurl].$item[autoblog_sourcefeed].''; - echo ''.serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url].''; - echo ''.serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url].''; - echo 'admin@'.serverUrl(true).''; - echo ''.date("r", $item[timestamp]).''; - echo ''; + $description = displayXMLstatus_tmp($item[status],$item[response_code],$item[autoblog_url],$item[autoblog_title],$item[autoblog_sourceurl],$item[autoblog_sourcefeed]); + $link = serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url]; + $date = date("r", $item[timestamp]); + print << + {$item[autoblog_title]} + + {$link} + {$item[timestamp]} + admin@{$_SERVER[SERVER_NAME]} + {$date} + +EOT; } } -echo ' -'; +echo ''; } ?> diff --git a/0.3/index.php b/0.3/index.php index c0a512f..be3c7e4 100755 --- a/0.3/index.php +++ b/0.3/index.php @@ -173,6 +173,10 @@ if (isset($_GET['rss'])) { die; } +if( !file_exists(RESOURCES_FOLDER.'rss.json')) { + file_put_contents(RESOURCES_FOLDER.'rss.json', '', LOCK_EX); +} + if (isset($_GET['rss_tmp'])) { displayXML_tmp(); die; @@ -222,6 +226,7 @@ if (isset($_GET['check'])) require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); $rss->addUnavailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); + updateXML('unavailable', 'nxdomain', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, '..'); die($svg_rouge); @@ -233,6 +238,7 @@ if (isset($_GET['check'])) require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); $rss->addAvailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); + updateXML('available', '200', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, ''); die($svg_vert); @@ -243,6 +249,7 @@ if (isset($_GET['check'])) require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); $rss->addCodeChanged($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL'], $code[1]); + updateXML('moved', '3xx', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, '.'); die($svg_jaune); From 5e03a591c165e01816091d6df1f5f269435be799 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Sat, 20 Apr 2013 23:44:23 +0200 Subject: [PATCH 07/28] fixage de quelques warn PHP --- 0.3/functions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/0.3/functions.php b/0.3/functions.php index e78272b..b1f68d1 100755 --- a/0.3/functions.php +++ b/0.3/functions.php @@ -281,17 +281,17 @@ if(file_exists(RESOURCES_FOLDER.'rss.json')) $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); foreach ($json as $item) { - $description = displayXMLstatus_tmp($item[status],$item[response_code],$item[autoblog_url],$item[autoblog_title],$item[autoblog_sourceurl],$item[autoblog_sourcefeed]); - $link = serverUrl(true).AUTOBLOGS_FOLDER.$item[autoblog_url]; - $date = date("r", $item[timestamp]); + $description = displayXMLstatus_tmp($item['status'],$item['response_code'],$item['autoblog_url'],$item['autoblog_title'],$item['autoblog_sourceurl'],$item['autoblog_sourcefeed']); + $link = serverUrl(true).AUTOBLOGS_FOLDER.$item['autoblog_url']; + $date = date("r", $item['timestamp']); print << - {$item[autoblog_title]} + {$item['autoblog_title']} {$link} - {$item[timestamp]} - admin@{$_SERVER[SERVER_NAME]} + {$item['timestamp']} + admin@{$_SERVER['SERVER_NAME']} {$date} EOT; From 2c11dfcb4d9eddd96013c3ba0e0053ede87fb9a9 Mon Sep 17 00:00:00 2001 From: mitsukarenai Date: Sun, 21 Apr 2013 13:06:38 +0300 Subject: [PATCH 08/28] Update README.md --- README.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 13bd966..87eb396 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,27 @@ -Projet-Autoblog +Projet Autoblog =============== Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ) -- serie 0.1 par Sebsauvage +Branche MASTER: -- serie 0.2 par BohwaZ, Arthur Hoaro, Mitsu, Oros +- script de migration 0.2 to 0.3 par Arthur Hoaro -- serie 0.3 par Mitsu, Oros, Arthur Hoaro +- Autoblog Project serie 0.3 par Mitsu, Oros, Arthur Hoaro + +Nouveautés majeures +=================== + +- "ferme" d'autoblogs avec ajout facile par différents formulaires (générique, microblogging, OPML, marque-pages) +- échange de références entre fermes avec XSAF (Cross-Site Autoblog Farming) +- vérification du statut des sites distants, et flux de suivi des changements +- export facile des références, articles et médias +- contrôle de version et alerte de mise à jour +- apparence de l'autoblog selon son type +- CSS utilisateur personnalisable +- hébergement de documents spécifiques + +Pré-requis techniques +===================== + +- serveur web avec PHP 5.3 et son support SQLite From b0fb1a8d70e4f2e42cece8a32fa67d948331f3b5 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Mon, 22 Apr 2013 11:59:04 +0200 Subject: [PATCH 09/28] =?UTF-8?q?(j'esp=C3=A8re=20je=20casse=20rien)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 14 +- 0.2to0.3/migrate.php | 138 ----- 0.3/README.md | 18 - 0.3/autoblogs/autoblog.php | 908 -------------------------------- 0.3/class_rssfeed.php | 277 ---------- 0.3/config.php | 43 -- 0.3/docs/docs.txt | 4 - 0.3/functions.php | 302 ----------- 0.3/index.php | 926 --------------------------------- 0.3/resources/autoblog.css | 48 -- 0.3/resources/icon-logo.svg | 218 -------- 0.3/resources/rss.png | Bin 691 -> 0 bytes 0.3/resources/user.css.example | 10 - 0.3/version | 1 - 0.3/xsaf3.php | 169 ------ README.md | 29 +- 16 files changed, 17 insertions(+), 3088 deletions(-) delete mode 100755 0.2to0.3/migrate.php delete mode 100755 0.3/README.md delete mode 100644 0.3/autoblogs/autoblog.php delete mode 100755 0.3/class_rssfeed.php delete mode 100755 0.3/config.php delete mode 100644 0.3/docs/docs.txt delete mode 100755 0.3/functions.php delete mode 100755 0.3/index.php delete mode 100644 0.3/resources/autoblog.css delete mode 100644 0.3/resources/icon-logo.svg delete mode 100644 0.3/resources/rss.png delete mode 100644 0.3/resources/user.css.example delete mode 100644 0.3/version delete mode 100755 0.3/xsaf3.php mode change 100644 => 100755 README.md diff --git a/.gitignore b/.gitignore index f71ddba..bba9c93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -0.3/config.php -0.3/.versionlock -0.3/.xsaflock -0.3/resources/rss.xml +config.php +.versionlock +.xsaflock +resources/rss.xml .project -0.3/resources/user.css -0.3/autoblogs/* -!0.3/autoblogs/autoblog.php +resources/user.css +autoblogs/* +!autoblogs/autoblog.php diff --git a/0.2to0.3/migrate.php b/0.2to0.3/migrate.php deleted file mode 100755 index d562c5a..0000000 --- a/0.2to0.3/migrate.php +++ /dev/null @@ -1,138 +0,0 @@ -exec(' - CREATE TABLE update_log ( - date INT PRIMARY KEY, - success INT, - log TEXT - ); - '); - - $vals=array(); - $ini = parse_ini_file($dir.$blog."/vvb.ini"); - - if(is_dir(urlToFolderWithTrailingSlash( $ini['SITE_URL'] )) || is_dir(urlToFolder( $ini['SITE_URL'] ))) - continue; - - $foldername = urlToFolderWithTrailingSlash($ini['SITE_URL']); - mkdir( $dir . $foldername ); - mkdir( $dir . $foldername . '/media'); - recursiveMove( $dir . $blog . '/media', $dir . $foldername .'/media' ); - copy($dir . $blog . '/index.php', $dir . $foldername .'/index.php'); - copy($dir . $blog . '/articles.db', $dir . $foldername .'/articles.db'); - deleteDir($dir . $blog ); - - - if( strpos($ini['SITE_TITLE'], 'Autoblog de') !== false ) { - $ini['SITE_TITLE'] = preg_replace('#^Autoblog de (.*)$#', '$1', $ini['SITE_TITLE']); - } - - switch(substr($ini['SITE_TITLE'], 0, 7)) { - case 'twitter': - case 'statusn': - case 'identic': - $ini['SITE_TYPE']="microblog"; - $ini['ARTICLES_PER_PAGE'] = "20"; - $ini['UPDATE_INTERVAL'] = "300"; - $ini['UPDATE_TIMEOUT'] = "30"; - break; - default: - $ini['SITE_TYPE']="generic"; - $ini['ARTICLES_PER_PAGE'] = "5"; - $ini['UPDATE_INTERVAL'] = "3600"; - $ini['UPDATE_TIMEOUT'] = "30"; - break; - } - - $fp = fopen($dir.$foldername."/vvb.ini", 'w+'); - fwrite($fp, << \ No newline at end of file diff --git a/0.3/README.md b/0.3/README.md deleted file mode 100755 index 1a0fa83..0000000 --- a/0.3/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Projet Autoblog serie 0.3 -============== - -- version VroumVroumBlog 0.3.0 BETA - -Auteurs: Mitsu (https://www.suumitsu.eu/), Oros (https://www.ecirtam.net/) et Arthur Hoaro (http://hoa.ro) - -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/autoblogs/autoblog.php b/0.3/autoblogs/autoblog.php deleted file mode 100644 index 87a8b28..0000000 --- a/0.3/autoblogs/autoblog.php +++ /dev/null @@ -1,908 +0,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'; -} -//else die("Configuration file not found."); - -if (file_exists(__DIR__ . '/../functions.php')){ - require_once __DIR__ . '/../functions.php'; -} -else die("Functions file not found."); - -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 - define('LOCAL_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '')."://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); -} - -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: Mozilla/5.0 (X11; Linux x86_64; rv:20.0; Autoblogs; +https://github.com/mitsukarenai/Projet-Autoblog/) Gecko/20100101 Firefox/20.0\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); - if( isset($from['path']) ) { // not exist if http://exemple.com - $from['path'] = preg_replace('![^/]*$!', '', $from['path']); - }else{ - $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/atom+xml; charset=UTF-8'); - echo ' - - '.escape($config->site_title).' - '.escape(html_entity_decode(strip_tags($config->site_description), ENT_COMPAT, 'UTF-8')).' - '.date(DATE_ATOM, filemtime(ARTICLES_DB_FILE)).' - - '.LOCAL_URL.' - - Projet Autoblog'; - - foreach($vvb->listLastArticles() as $art) - { - echo ' - - - '.escape($config->site_title).' - '.escape($config->site_url).' - - <![CDATA['.escape($art['title']).']]> - - '.str_replace('?feed', '?', LOCAL_URL).urlencode(str_replace('./?', '', $vvb->getLocalURL($art))).' - '.date(DATE_ATOM, $art['date']).' - - - source)
'.escape_content($art['content']).']]> -
-
'; - } - - echo ' -
'; - exit; -} - -if (isset($_GET['opml'])) // OPML -{ - //header('Content-Type: application/octet-stream'); - header('Content-type: text/xml'); - header('Content-Disposition: attachment; filename="'.escape($config->site_title).'.xml"'); - $opmlfile = new SimpleXMLElement(''); - $opmlfile->addAttribute('version', '1.0'); - $opmlhead = $opmlfile->addChild('head'); - $opmlhead->addChild('title', escape($config->site_title)); - $opmlhead->addChild('dateCreated', date('r', time())); - $opmlbody = $opmlfile->addChild('body'); - $outline = $opmlbody->addChild('outline'); - $outline->addAttribute('title', escape($config->site_title)); - $outline->addAttribute('text', escape($config->site_type)); - $outline->addAttribute('htmlUrl', escape($config->site_url)); - $outline->addAttribute('xmlUrl', escape($config->feed_url)); - - echo $opmlfile->asXML(); - exit; -} - -if (isset($_GET['media'])) // MEDIA -{ - header('Content-Type: application/json'); - if(is_dir(MEDIA_DIR)) - { - $url = str_replace('?media', 'media/', LOCAL_URL); - $files = scandir(MEDIA_DIR); - unset($files[0]); // . - unset($files[1]); // .. - echo json_encode(array("url"=> $url, "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' || $site_type == 'twitter' || $site_type == 'identica') // 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).' - - - - - -
-

PROJET AUTOBLOG'. (strlen(HEAD_TITLE) > 0 ? ' ~ '. HEAD_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 ' - -'; - - -function escape_content($str) -{ - $str = preg_replace('!<\s*(style|script|link)!', '<\\1', $str); - $str = str_replace('="media/', '="./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/class_rssfeed.php b/0.3/class_rssfeed.php deleted file mode 100755 index 59fd431..0000000 --- a/0.3/class_rssfeed.php +++ /dev/null @@ -1,277 +0,0 @@ - - * - * + 03/2013 - * Few changes, AutoblogRSS and FileRSSFeed - * @author Arthur Hoaro - */ -class RSSFeed { - protected $xml; - - /** - * Construct a RSS feed - */ - public function __construct() { - $template = << - - - - -END; - - $this->xml = new SimpleXMLElement($template); - } - - /** - * Set RSS Feed headers - * @param $title the title of the feed - * @param $link link to the website where you can find the RSS feed - * @param $description a description of the RSS feed - * @param $rsslink the link to this RSS feed - */ - public function setHeaders($title, $link, $description, $rsslink) { - $atomlink = $this->xml->channel->addChild("atom:link","","http://www.w3.org/2005/Atom"); - $atomlink->addAttribute("href",$rsslink); - $atomlink->addAttribute("rel","self"); - $atomlink->addAttribute("type","application/rss+xml"); - - $this->xml->channel->title = $title; - $this->xml->channel->link = $link; - $this->xml->channel->description = $description; - } - - /** - * Set the language of the RSS feed - * @param $lang the language of the RSS feed - */ - public function setLanguage($lang) { - $this->xml->channel->addChild("language",$lang); - } - /** - * Adds a picture to the RSS feed - * @param $url URL to the image - * @param $title The image title. Usually same as the RSS feed's title - * @param $link Where the image should link to. Usually same as the RSS feed's link - */ - public function setImage($url, $title, $link) { - $image = $this->xml->channel->addChild("image"); - $image->url = $url; - $image->title = $title; - $image->link = $link; - } - /** - * Add a item to the RSS feed - * @param $title The title of the RSS feed - * @param $link Link to the item's url - * @param $description The description of the item - * @param $author The author who wrote this item - * @param $guid Unique ID for this post - * @param $timestamp Unix timestamp for making a date - */ - public function addItem($title, $link, $description, $author, $guid, $timestamp) { - $item = $this->xml->channel->addChild("item"); - $item->title = $title; - $item->description = $description; - $item->link = $link; - $item->guid = $guid; - if( isset($guid['isPermaLink'])) - $item->guid['isPermaLink'] = $guid['isPermaLink']; - if( !empty( $author) ) - $item->author = $author; - $item->pubDate = date(DATE_RSS,intval($timestamp)); - } - /** - * Displays the RSS feed - */ - public function displayXML() { - header('Content-type: application/rss+xml; charset=utf-8'); - echo $this->xml->asXML(); - exit; - } - - public function getXML() { - return $this->xml; - } -} - -class RSSMerger { - private $feeds = array(); - - /** - * Constructs a RSSmerger object - */ - function __construct() { - - } - - /** - * Populates the feeds array from the given url which is a rss feed - * @param $url - */ - function add($xml) { - - foreach($xml->channel->item as $item) { - $item->sitetitle = $xml->channel->title; - $item->sitelink = $xml->channel->link; - - preg_match("/^[A-Za-z]{3}, ([0-9]{2}) ([A-Za-z]{3}) ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([\+|\-]?[0-9]{4})$/", $item->pubDate, $match); - $item->time = time($match[4]+($match[6]/100),$match[5],$match[6],date("m",strtotime($match[2])),$match[1],$match[3]); - - $this->feeds[] = $item; - } - } - /** - * Comparing function for sorting the feeds - * @param $value1 - * @param $value2 - */ - function feeds_cmp($value1,$value2) { - if(intval($value1->time) == intval($value2->time)) - return 0; - - return (intval($value1->time) < intval($value2->time)) ? +1 : -1; - } - - /** - * Sorts the feeds array using the Compare function feeds_cmp - */ - function sort() { - usort($this->feeds,Array("RssMerger","feeds_cmp")); - } - - /** - * This function return the feed items. - * @param $limit how many feed items that should be returned - * @return the feeds array - */ - function getFeeds($limit) { - return array_slice($this->feeds,0,$limit); - } -} - -class FileRSSFeed extends RSSFeed { - protected $filename; - - public function __construct($filename) { - parent::__construct(); - $this->filename = $filename; - - $this->load(); - } - - public function load() { - if ( file_exists( $this->filename )) { - $this->xml = simplexml_load_file($this->filename); - } - } - - public function create($title, $link, $description, $rsslink) { - parent::setHeaders($title, $link, $description, $rsslink); - $this->write(); - } - - public function addItem($title, $link, $description, $author, $guid, $timestamp) { - parent::addItem($title, $link, $description, $author, $guid, $timestamp); - $this->write(); - } - - private function write() { - if ( file_exists( $this->filename )) { - unlink($this->filename); - } - - $outputXML = new RSSFeed(); - foreach($this->xml->channel->item as $f) { - $item = $outputXML->addItem($f->title,$f->link,$f->description,$f->author,$f->guid, strtotime($f->pubDate)); - } - - $merger = new RssMerger(); - $merger->add($outputXML->getXML()); - $merger->sort(); - - unset($this->xml->channel->item); - foreach($merger->getFeeds(20) as $f) { - parent::addItem($f->title,$f->link,$f->description,$f->author,$f->guid,$f->time); - } - - file_put_contents( $this->filename, $this->xml->asXML(), LOCK_EX ); - } -} - -class AutoblogRSS extends FileRSSFeed { - public function __construct($filename) { - parent::__construct($filename); - } - - public function addUnavailable($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" est indisponible', $autobHref, - 'Autoblog: '.$title.'
- Site: '. $siteurl .'
- RSS: '.$rssurl.'
- Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addAvailable($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" est de nouveau disponible', $autobHref, - 'Autoblog : '.$title.'
- Site: '. $siteurl .'
- RSS: '.$rssurl.'
- Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addCodeChanged($title, $folder, $siteurl, $rssurl, $code) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" a renvoyé un code imprévu', $autobHref, - 'Code: '. $code .'
- Autoblog : '.$title.'
- Site: '. $siteurl .'
- RSS: '.$rssurl.'
- Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addNewAutoblog($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" a été ajouté à la ferme', $autobHref, - 'Autoblog : '.$title.'
- Site: '. $siteurl .'
- RSS: '.$rssurl.'
- Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } -} - -?> diff --git a/0.3/config.php b/0.3/config.php deleted file mode 100755 index 8f98017..0000000 --- a/0.3/config.php +++ /dev/null @@ -1,43 +0,0 @@ -SebSauvage et Bohwaz.'); - -// define( 'ALLOW_FULL_UPDATE', TRUE ); -// define( 'ALLOW_CHECK_UPDATE', TRUE ); - -/** - * If you set ALLOW_NEW_AUTOBLOGS to FALSE, the following options do not matter. - **/ -// define( 'ALLOW_NEW_AUTOBLOGS', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_LINKS', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_SOCIAL', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_BUTTON', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK', TRUE ); -// define( 'ALLOW_NEW_AUTOBLOGS_BY_XSAF', TRUE ); - -/** - * More about TwitterBridge : https://github.com/mitsukarenai/twitterbridge - **/ -// define( 'API_TWITTER', FALSE ); - -/** - * Import autoblogs from friend's autoblog farm - Add a link to the JSON export - **/ -$friends_autoblog_farm = array( - 'https://raw.github.com/mitsukarenai/xsaf-bootstrap/master/3.json', - // 'https://www.ecirtam.net/autoblogs/?export', - // 'https://autoblog.suumitsu.eu/?export', - // 'http://streisand.hoa.ro/?export', -); -?> diff --git a/0.3/docs/docs.txt b/0.3/docs/docs.txt deleted file mode 100644 index a4c763e..0000000 --- a/0.3/docs/docs.txt +++ /dev/null @@ -1,4 +0,0 @@ -You can manually add files in the /docs/ directory, such as PDF, docs, images, etc. -You can also add subfolders in /docs/ for website mirroring. Be sure that your subfolder contains a file named index.html. - -Delete this file to hide the 'Autres documents' block in your autoblogs homepage. diff --git a/0.3/functions.php b/0.3/functions.php deleted file mode 100755 index b1f68d1..0000000 --- a/0.3/functions.php +++ /dev/null @@ -1,302 +0,0 @@ -SebSauvage et Bohwaz.'); - -// Functions -function NoProtocolSiteURL($url) { - $protocols = array("http://", "https://"); - $siteurlnoproto = str_replace($protocols, "", $url); - - // Remove the / at the end of string - if ( $siteurlnoproto[strlen($siteurlnoproto) - 1] == '/' ) - $siteurlnoproto = substr($siteurlnoproto, 0, -1); - - // Remove index.php/html at the end of string - if( strpos($url, 'index.php') || strpos($url, 'index.html') ) { - $siteurlnoproto = preg_replace('#(.*)/index\.(html|php)$#', '$1', $siteurlnoproto); - } - - return $siteurlnoproto; -} - - -function DetectRedirect($url) -{ - if(parse_url($url, PHP_URL_HOST)==FALSE) { - //die('Not a URL'); - throw new Exception('Not a URL: '. escape ($url) ); - } - $response = get_headers($url, 1); - if(!empty($response['Location'])) { - $response2 = get_headers($response['Location'], 1); - if(!empty($response2['Location'])) { - //die('too much redirection'); - throw new Exception('too much redirection: '. escape ($url) ); - } - else { return $response['Location']; } - } - else { - return $url; - } -} - -function urlToFolder($url) { - return sha1(NoProtocolSiteURL($url)); -} - -function urlToFolderSlash($url) { - return sha1(NoProtocolSiteURL($url).'/'); -} - -function folderExists($url) { - return file_exists(AUTOBLOGS_FOLDER . urlToFolder($url)) || file_exists(AUTOBLOGS_FOLDER . urlToFolderSlash($url)); -} - -function escape($str) { - return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false); -} - -function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { - if( $type == 'generic' || empty( $type )) { - $var = updateType( $siteurl ); - $type = $var['type']; - if( !empty( $var['name']) ) { - if( !stripos($siteurl, $var['name'] === false) ) - $sitename = ucfirst($var['name']) . ' - ' . $sitename; - } - } - - if(folderExists($siteurl)) { - $error[] = 'Erreur : l\'autoblog '. $sitename .' existe déjà.'; - return $error; - } - - $foldername = AUTOBLOGS_FOLDER . urlToFolderSlash($siteurl); - - if ( mkdir($foldername, 0755, false) ) { - - /** - * RSS - **/ - try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addNewAutoblog($sitename, $foldername, $siteurl, $rssurl); - } - catch (Exception $e) { - ; - } - - $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="'. $type .'" -SITE_TITLE="'. $sitename .'" -SITE_DESCRIPTION="Site original : '. $sitename .'" -SITE_URL="'. $siteurl .'" -FEED_URL="'. $rssurl .'" -ARTICLES_PER_PAGE="'. getArticlesPerPage( $type ) .'" -UPDATE_INTERVAL="'. getInterval( $type ) .'" -UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) - $error[] = "Impossible d'écrire le fichier vvb.ini"; - fclose($fp); - } - else - $error[] = "Impossible de créer le répertoire."; - updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); /* éventuellement une conditionnelle ici: if(empty($error)) ? */ - return $error; -} - -function getArticlesPerPage( $type ) { - switch( $type ) { - case 'microblog': - return 20; - case 'shaarli': - return 20; - default: - return 5; - } -} - -function getInterval( $type ) { - switch( $type ) { - case 'microblog': - return 300; - case 'shaarli': - return 1800; - default: - return 3600; - } -} - -function getTimeout( $type ) { - switch( $type ) { - case 'microblog': - return 30; - case 'shaarli': - return 30; - default: - return 30; - } -} - -function updateType($siteurl) { - if( strpos($siteurl, 'twitter.com') !== FALSE ) { - return array('type' => 'twitter', 'name' => 'twitter'); - } - elseif ( strpos( $siteurl, 'identi.ca') !== FALSE ) { - return array('type' => 'identica', 'name' => 'identica'); - } - elseif( strpos( $siteurl, 'shaarli' ) !== FALSE ) { - return array('type' => 'shaarli', 'name' => 'shaarli'); - } - else - return array('type' => 'generic', 'name' => ''); -} - -function debug($data) -{ - echo '
';
-	var_dump($data);
-	echo '
'; -} - -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 '%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 'ATOM Feed': - return 'Flux ATOM'; - 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; - } -} - -function updateXML($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) -{ -$json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); -$json[] = array( - 'timestamp'=>time(), - 'autoblog_url'=>$autoblog_url, - 'autoblog_title'=>$autoblog_title, - 'autoblog_sourceurl'=>$autoblog_sourceurl, - 'autoblog_sourcefeed'=>$autoblog_sourcefeed, - 'status'=>$status, - 'response_code'=>$response_code - ); -file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX); -} - -function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { - switch ($status) - { - case 'unavailable': - return 'Autoblog "'.$autoblog_title.'": site distant inaccessible (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - case 'moved': - return 'Autoblog "'.$autoblog_title.'": site distant redirigé (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - case 'not_found': - return 'Autoblog "'.$autoblog_title.'": site distant introuvable (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - case 'remote_error': - return 'Autoblog "'.$autoblog_title.'": site distant a problème serveur (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - case 'available': - return 'Autoblog "'.$autoblog_title.'": site distant à nouveau opérationnel (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - case 'new_autoblog_added': - return 'Autoblog "'.$autoblog_title.'" ajouté (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; - } -} - -function displayXML_tmp() { -header('Content-type: application/rss+xml; charset=utf-8'); -echo ' -'.serverUrl(true).''; -echo 'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; -if(file_exists(RESOURCES_FOLDER.'rss.json')) -{ - $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); - foreach ($json as $item) - { - $description = displayXMLstatus_tmp($item['status'],$item['response_code'],$item['autoblog_url'],$item['autoblog_title'],$item['autoblog_sourceurl'],$item['autoblog_sourcefeed']); - $link = serverUrl(true).AUTOBLOGS_FOLDER.$item['autoblog_url']; - $date = date("r", $item['timestamp']); - print << - {$item['autoblog_title']} - - {$link} - {$item['timestamp']} - admin@{$_SERVER['SERVER_NAME']} - {$date} - -EOT; - } -} -echo ''; -} -?> diff --git a/0.3/index.php b/0.3/index.php deleted file mode 100755 index be3c7e4..0000000 --- a/0.3/index.php +++ /dev/null @@ -1,926 +0,0 @@ -loadXML($data) or die('xml malformé'); - $title = $dom->getElementsByTagName('title'); - return $title->item(0)->nodeValue; -} - -function get_link_from_feed($url) { - return get_link_from_datafeed(file_get_contents($url)); -} - -function get_link_from_datafeed($data) { - if($data === false) { return 'url inaccessible'; } - $xml = simplexml_load_string($data); // quick feed check - - // ATOM feed && RSS 1.0 /RDF && RSS 2.0 - if (!isset($xml->entry) && !isset($xml->item) && !isset($xml->channel->item)) - 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($return_subfolder = false) -{ - $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"]); - if($return_subfolder === true) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $subfolder = $path['dirname'] .'/'; - } else $subfolder = ''; - return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport.$subfolder; -} - -function objectCmp($a, $b) { - return strcasecmp ($a->site_title, $b->site_title); -} - -function generate_antibot() { - $letters = array('zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt'); - return $letters[mt_rand(1, 20)]; -} - -function check_antibot($number, $text_number) { - $letters = array('zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt'); - return ( array_search( $text_number, $letters ) === intval($number) ) ? true : false; -} - -function create_from_opml($opml) { - global $error, $success; - - foreach( $opml->body->outline as $outline ) { - if ( !empty( $outline['title'] ) && !empty( $outline['text'] ) && !empty( $outline['xmlUrl']) && !empty( $outline['htmlUrl'] )) { - try { - $rssurl = DetectRedirect(escape( $outline['xmlUrl'])); - - $sitename = escape( $outline['title'] ); - $siteurl = escape($outline['htmlUrl']); - $sitetype = escape($outline['text']); if ( $sitetype == 'generic' or $sitetype == 'microblog' or $sitetype == 'shaarli') { } else { $sitetype = 'generic'; } - - $error = array_merge( $error, createAutoblog( $sitetype, $sitename, $siteurl, $rssurl, $error ) ); - - if( empty ( $error )) - $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; - } - catch (Exception $e) { - $error[] = $e->getMessage(); - } - } - } -} - -/** - * Simple version check - **/ -function versionCheck() { - $versionfile = 'version'; - $lastestUrl = 'https://raw.github.com/mitsukarenai/Projet-Autoblog/master/0.3/version'; - - $expire = time() - 84600 ; // 23h30 en secondes - $lockfile = '.versionlock'; - - if (file_exists($lockfile) && filemtime($lockfile) > $expire) { - if( file_get_contents($lockfile) == 'NEW' ) { - // No new version installed - if( filemtime( $lockfile ) > filemtime( $versionfile ) ) - return true; - else unlink($lockfile); - } - else return false; - } - - if (file_exists($lockfile) && filemtime($lockfile) < $expire) { unlink($lockfile); } - - if( file_get_contents($versionfile) != file_get_contents($lastestUrl) ) { - file_put_contents($lockfile, 'NEW'); - return true; - } - file_put_contents($lockfile, '.'); - return false; - } - $update_available = (ALLOW_CHECK_UPDATE) ? versionCheck() : false; - -/** -* RSS Feed -**/ -if( !file_exists(RSS_FILE)) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->create('Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : ''), serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.", serverUrl(true) . RSS_FILE); -} -if (isset($_GET['rss'])) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->displayXML(); - die; -} - -if( !file_exists(RESOURCES_FOLDER.'rss.json')) { - file_put_contents(RESOURCES_FOLDER.'rss.json', '', LOCK_EX); -} - -if (isset($_GET['rss_tmp'])) { - displayXML_tmp(); - die; -} - -/** - * SVG - **/ -if (isset($_GET['check'])) -{ - //echo "1"; - header('Content-type: image/svg+xml'); - $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="./".escape( $_GET['check'] ) ."/error.log"; - - $oldvalue = null; - if(file_exists($errorlog)) { $oldvalue = file_get_contents($errorlog); }; - 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 */ - { - 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("./". escape( $_GET['check'] ) ."/vvb.ini") or die; - - if(strpos(strtolower($ini['SITE_TITLE']), 'twitter') !== FALSE) { die($svg_twitter); } /* Twitter */ - if(strpos(strtolower($ini['SITE_TITLE']), 'identica') !== FALSE) { die($svg_identica); } /* Identica */ - if(strpos(strtolower($ini['SITE_TYPE']), 'microblog') !== FALSE) { die($svg_statusnet); } /* Statusnet */ - - $headers = get_headers($ini['FEED_URL']); - /* le flux est indisponible (typiquement: erreur DNS ou possible censure) - à vérifier */ - if(empty($headers) || $headers === FALSE ) { - if( $oldvalue !== null && $oldvalue != '..' ) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addUnavailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); - updateXML('unavailable', 'nxdomain', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); - } - file_put_contents($errorlog, '..'); - die($svg_rouge); - } - $code=explode(" ", $headers[0]); - /* code retour 200: flux disponible */ - if($code[1] == "200") { - if( $oldvalue !== null && $oldvalue != '' ) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addAvailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); - updateXML('available', '200', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); - } - file_put_contents($errorlog, ''); - die($svg_vert); - } - /* autre code retour: un truc a changé (redirection, changement de CMS, .. bref vvb.ini doit être corrigé) */ - else { - if( $oldvalue !== null && $oldvalue != '.' ) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addCodeChanged($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL'], $code[1]); - updateXML('moved', '3xx', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); - } - file_put_contents($errorlog, '.'); - die($svg_jaune); - } - } -} - -/** - * JSON Export - **/ -if (isset($_GET['export'])) { - header('Content-Type: application/json'); - $subdirs = glob(AUTOBLOGS_FOLDER . "*"); - - 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; - $type=$config->site_type; - $title=$config->site_title; - $url=$config->site_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; -} - -/** - * JSON Allowed Twitter accounts export - **/ -if (isset($_GET['export_twitter'])) { - header('Content-Type: application/json'); - $subdirs = glob(AUTOBLOGS_FOLDER . "*"); - $response = array(); - - foreach($subdirs as $unit) { - if(is_dir($unit)) { - $unit=substr($unit, 2); - $ini = parse_ini_file($unit.'/vvb.ini'); - if( $ini['SITE_TYPE'] == 'twitter' ) { - preg_match('#twitter\.com/(.+)#', $ini['SITE_URL'], $username); - $response[] = $username[1]; - } - unset($ini); - } - } - echo json_encode( $response ); - die; -} - -/** - * OPML Full Export - **/ -if (isset($_GET['exportopml'])) // OPML -{ - //header('Content-Type: application/octet-stream'); - header('Content-type: text/xml'); - header('Content-Disposition: attachment; filename="autoblogs-'. $_SERVER['SERVER_NAME'] .'.xml"'); - - $opmlfile = new SimpleXMLElement(''); - $opmlfile->addAttribute('version', '1.0'); - $opmlhead = $opmlfile->addChild('head'); - $opmlhead->addChild('title', 'Autoblog OPML export from '. $_SERVER['SERVER_NAME'] ); - $opmlhead->addChild('dateCreated', date('r', time())); - $opmlbody = $opmlfile->addChild('body'); - - $subdirs = glob(AUTOBLOGS_FOLDER . "*"); - - 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); - - $outline = $opmlbody->addChild('outline'); - $outline->addAttribute('title', escape($config->site_title)); - $outline->addAttribute('text', escape($config->site_type)); - $outline->addAttribute('htmlUrl', escape($config->site_url)); - $outline->addAttribute('xmlUrl', escape($config->feed_url)); - } - } - echo $opmlfile->asXML(); - exit; -} - -/** - * Site map - * NEW AUTOBLOG FOLDER - Need update - **/ -if (isset($_GET['sitemap'])) -{ - header('Content-Type: application/xml'); - $proto=(!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS'])=='on')?"https://":"http://"; - echo ''; - echo ''.$proto."{$_SERVER['HTTP_HOST']}".str_replace('?sitemap', '', $_SERVER['REQUEST_URI'])."\n"; - echo ''.date('c', time())."\n"; - echo 'daily'; - $subdirs = glob(AUTOBLOGS_FOLDER . "*"); - foreach($subdirs as $unit) { - if(is_dir($unit)) { - $unit=substr($unit, 2); - echo ''.$proto.$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, -9)."$unit/"."\n"; - echo ''.date('c', filemtime($unit))."\n"; - echo 'hourly'; - } - } - echo ''; - die; -} - -/** - * Update ALL autblogs (except .disabled) - * This action can be very slow and consume CPU if you have a lot of autoblogs - **/ -if( isset($_GET['updateall']) && ALLOW_FULL_UPDATE) { - - $expire = time() - 84600 ; // 23h30 en secondes - $lockfile = ".updatealllock"; - if (file_exists($lockfile) && filemtime($lockfile) > $expire) { - echo "too early"; - die; - } - else { - if( file_exists($lockfile) ) - unlink($lockfile); - - if( file_put_contents($lockfile, date(DATE_RFC822)) ===FALSE) { - echo "Merci d'ajouter des droits d'écriture sur le fichier."; - die; - } - } - - $subdirs = glob(AUTOBLOGS_FOLDER . "*"); - foreach($subdirs as $unit) { - if(is_dir($unit)) { - if( !file_exists(ROOT_DIR . '/' . $unit . '/.disabled')) { - file_get_contents(serverUrl() . substr($_SERVER['PHP_SELF'], 0, -9) . $unit . '/index.php'); - } - } - } -} - -$antibot = generate_antibot(); -$form = '
-
-
- - -
'; - -/** - * ADD BY BOOKMARK BUTTON - **/ -if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_BUTTON ) -{ - $form = ''; - - if( empty($_GET['rssurl']) ) { - $form .= '

URL du flux RSS incorrect.
Fermer la fenêtre.

'; - } - else { - if(isset($_GET['add']) && $_GET['add'] === '1' && !empty($_GET['siteurl']) && !empty($_GET['sitename'])) { - try { - $rssurl = DetectRedirect(escape($_GET['rssurl'])); - - $siteurl = escape($_GET['siteurl']); - $sitename = escape($_GET['sitename']); - $sitetype = updateType($siteurl); // Disabled input doesn't send POST data - $sitetype = $sitetype['type']; - - $error = array_merge( $error, createAutoblog($sitetype, $sitename, $siteurl, $rssurl, $error)); - if( empty($error)) { - $form .= ''; - $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; - } - else { - $form .= '

    '; - foreach ( $error AS $value ) - $form .= '
  • '. $value .'
  • '; - $form .= '
'; - } - } - catch (Exception $e) { - $form .= $e->getMessage(); - } - $form .= 'Fermer la fenêtre.

'; - } - else { - try { - $rssurl = DetectRedirect(escape($_GET['rssurl'])); - $datafeed = file_get_contents($rssurl); - if( $datafeed !== false ) { - $siteurl = get_link_from_datafeed($datafeed); - $sitename = get_title_from_datafeed($datafeed); - $sitetype = updateType($siteurl); - $sitetype = $sitetype['type']; - - $form .= 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
-
- -
-
-
-
-
'; - } - else { - $form .= '

URL du flux RSS incorrecte.
Fermer la fenêtre.

'; - } - } - catch (Exception $e) { - $form .= $e->getMessage() .'
Fermer la fenêtre.

'; - } - } - } - $form .= ''; - echo $form; die; -} - -/** - * ADD BY SOCIAL / SHAARLI - **/ -if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) -{ - if( !empty($_POST['number']) && !empty($_POST['antibot']) && check_antibot($_POST['number'], $_POST['antibot']) ) { - - $socialaccount = strtolower(escape($_POST['socialaccount'])); - $socialinstance = strtolower(escape($_POST['socialinstance'])); - - if($socialinstance === 'twitter') { - if( API_TWITTER !== FALSE ) { - $sitetype = 'twitter'; - $siteurl = "http://twitter.com/$socialaccount"; - $rssurl = API_TWITTER.$socialaccount; - } - else - $error[] = "Twitter veut mettre à mort son API ouverte. Du coup on peut plus faire ça comme ça."; - } - elseif($socialinstance === 'identica') { - $sitetype = 'identica'; - $siteurl = "http://identi.ca/$socialaccount"; - $rssurl = "http://identi.ca/api/statuses/user_timeline/$socialaccount.rss"; - } - elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { - $sitetype = 'microblog'; - $siteurl= NoProtocolSiteURL(escape($_POST['statusneturl'])); - try { - $rssurl = DetectRedirect("http://".$siteurl."/api/statuses/user_timeline/$socialaccount.rss"); - $siteurl = DetectRedirect("http://".$siteurl."/$socialaccount"); - } - catch (Exception $e) { - echo $error[] = $e->getMessage(); - } - } - elseif($socialinstance === 'shaarli' && !empty($_POST['shaarliurl'])) { - $sitetype = 'shaarli'; - $siteurl = NoProtocolSiteURL(escape($_POST['shaarliurl'])); - try { - $siteurl = DetectRedirect("http://".$siteurl."/"); - } - catch (Exception $e) { - echo $error[] = $e->getMessage(); - } - $rssurl = $siteurl."?do=rss"; - $socialaccount = get_title_from_feed($rssurl); - } - - if( empty($error) ) { - // Twitterbridge do NOT allow this user yet => No check - if( $sitetype != 'twitter' ) { - $headers = get_headers($rssurl, 1); - if (strpos($headers[0], '200') == FALSE) { - $error[] = "Flux inaccessible (compte inexistant ?)"; - } - } - if( empty($error) ) { - $error = array_merge( $error, createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl, $error)); - if( empty($error)) - $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; - } - } - } - else - $error[] = 'Antibot : Chiffres incorrects.'; -} - -/** - * ADD BY GENERIC LINK - **/ -if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_LINKS) { - if(empty($_POST['rssurl'])) - {$error[] = "Veuillez entrer l'adresse du flux.";} - if(empty($_POST['number']) || empty($_POST['antibot']) ) - {$error[] = "Vous êtes un bot ?";} - elseif(! check_antibot($_POST['number'], $_POST['antibot'])) - {$error[] = "Antibot : Ce n'est pas le bon nombre.";} - - if(empty($error)) { - try { - $rssurl = DetectRedirect(escape($_POST['rssurl'])); - - if(!empty($_POST['siteurl'])) { - - $siteurl = escape($_POST['siteurl']); - $sitename = get_title_from_feed($rssurl); - - $error = array_merge( $error, createAutoblog('generic', $sitename, $siteurl, $rssurl, $error)); - - if( empty($error)) - $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; - } - else { - // checking procedure - - $datafeed = file_get_contents($rssurl); - if( $datafeed === false ) { - $error[] = 'URL "'. $rssurl .'" inaccessible.'; - } - $sitetype = 'generic'; - $siteurl = get_link_from_datafeed($datafeed); - $sitename = get_title_from_datafeed($datafeed); - - $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
-
-
-
-
-
-
-
'; - - } - } - catch (Exception $e) { - echo $error[] = $e->getMessage(); - } - } -} - -/** - * ADD BY OPML File - **/ -if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE) { - if(empty($_POST['number']) || empty($_POST['antibot']) ) - {$error[] = "Vous êtes un bot ?";} - elseif(! check_antibot($_POST['number'], $_POST['antibot'])) - {$error[] = "Antibot : Ce n'est pas le bon nombre.";} - - if( empty( $error)) { - if (is_uploaded_file($_FILES['file']['tmp_name'])) { - $opml = null; - if( ($opml = simplexml_load_file( $_FILES['file']['tmp_name'])) !== false ) { - create_from_opml($opml); - } - else - $error[] = "Impossible de lire le contenu du fichier OPML."; - unlink($_FILES['file']['tmp_name']); - } else { - $error[] = "Le fichier n'a pas été envoyé."; - } - } -} - -/** - * ADD BY OPML Link - **/ - if( !empty($_POST['opml_link']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK) { - if(empty($_POST['number']) || empty($_POST['antibot']) ) - {$error[] = "Vous êtes un bot ?";} - elseif(! check_antibot($_POST['number'], $_POST['antibot'])) - {$error[] = "Antibot : Ce n'est pas le bon nombre.";} - if( empty( $_POST['opml_url'] )) - {$error[] = 'Le lien est incorrect.';} - - if( empty( $error)) { - $opml_url = escape($_POST['opml_url']); - if(parse_url($opml_url, PHP_URL_HOST)==FALSE) { - $error[] = "URL du fichier OPML non valide."; - } else { - if ( ($opml = simplexml_load_file( $opml_url )) !== false ) { - create_from_opml($opml); - } else { - $error[] = "Impossible de lire le contenu du fichier OPML ou d'accéder à l'URL donnée."; - } - } - - } -} - -?> - - - - - Projet Autoblog<?php if(strlen(HEAD_TITLE)>0) echo " | " . HEAD_TITLE; ?> - - - '; - } - ?> - - -

- PROJET AUTOBLOG - 0) echo " | " . HEAD_TITLE; ?> -

- -
- '; - ?> -

Présentation

- -

- Le Projet Autoblog a pour objectif de répliquer les articles d'un blog ou d'un site site web.
- Si l'article source est supprimé, et même si le site d'origine disparaît, les articles restent lisibles sur l'autoblog.
- L'objectif premier de ce projet est de lutter contre la censure et toute sorte de pression... -

- -

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

-
- - -
-

Mise à jour

-

- Une mise à jour du Projet Autoblog est disponible !
- → Télécharger la dernière version
- → Important : Consulter la documentation - mise à jour -

-
- - - -
- -

Ajouter un autoblog

- - Message'. (count($error) ? 's' : '') .' :

    '; - foreach ( $error AS $value ) { - echo '
  • '. $value .'
  • '; - } - foreach ( $success AS $value ) { - echo '
  • '. $value .'
  • '; - } - echo '
'; - } - - $button_list = '

Ajouter un autoblog via : '; - if(ALLOW_NEW_AUTOBLOGS_BY_LINKS) - $button_list .= 'Flux RSS '; - if(ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) { - $button_list .= 'Compte réseau social '; - $button_list .= 'Shaarli '; - } - if(ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE) - $button_list .= 'Fichier OPML '; - if(ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK) - $button_list .= 'Lien vers OPML '; - if(ALLOW_NEW_AUTOBLOGS_BY_BUTTON) - $button_list .= 'Marque page '; - $button_list .= '

'; - echo $button_list; - - if(ALLOW_NEW_AUTOBLOGS_BY_LINKS == TRUE) { ?> -
-

Ajouter un site web

-

- Si vous souhaitez que héberge un autoblog d'un site,
- remplissez le formulaire suivant: -

- - -
- -
-

Ajouter un compte social

- -
-
- Twitter
'; - else echo 'Twitter
'; ?> - Identica
- -
-
- - -
-
- -
-

Ajouter un Shaarli

- -
- -
-
- - -
-
- -
-

Ajouter par fichier OPML

- -
- -
-
- - -
-
- - - - - - - -
- - - '. substr($unit, (strrpos($unit, '/')) + 1 ) .''; - } - } - } - if(!empty( $docs )) { - echo '

Autres documents

    '; - foreach( $docs as $value ) - echo '
  • '. $value .'
  • '; - echo '
'; - } - ?> - -
-

Autoblogs hébergés rss

-

- Autres fermes - → Rechercher -

- - -
- $value) - { - $key = strtolower($key); - $config->$key = $value; - } - $autoblogs[$unit] = $config; - unset($ini); - } - } - } - } - } - - uasort($autoblogs, "objectCmp"); - $autoblogs_display = ''; - - if(!empty($autoblogs)){ - foreach ($autoblogs as $key => $autoblog) { - $opml_link='opml'; - $autoblogs_display .= '
- -
config ini '.$opml_link.' | '.escape($autoblog->site_type).' source: '.escape($autoblog->site_url).'
-
'; - } - } - echo $autoblogs_display; - ?> -
-
- - ".count($autoblogs)." autoblogs hébergés

"; ?> -
- Propulsé par Projet Autoblog 0.3 de Mitsu, Oros et Arthur Hoaro (Domaine Public) - 0 ){ echo "
".FOOTER; } ?> - - - - - - - diff --git a/0.3/resources/autoblog.css b/0.3/resources/autoblog.css deleted file mode 100644 index 259e2e8..0000000 --- a/0.3/resources/autoblog.css +++ /dev/null @@ -1,48 +0,0 @@ -/** - * autoblog.css - * ------------ - * Please do NOT edit this file. Updating your Autoblogs farm will be easier. - * If you want to add your own CSS, use the file user.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[type="text"]{width:20em;} -input[type="radio"] {width:1em;} -input[type="submit"] {width:8em;} -div.form {padding:0.2em;border:1px solid #fff;} -div.form:hover {background-color:#FAF4DA;border:1px dotted;} -#contentVignette {text-align: center;} -.vignette {width:27%;height:2em;display: inline-block;text-align:justify;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;} -.success {color: green;} -.error {color: red;} -.button_list{display:none;} -.button{-moz-box-shadow:inset 0 1px 0 0 #d9fbbe;-webkit-box-shadow:inset 0 1px 0 0 #d9fbbe;box-shadow:inset 0 1px 0 0 #d9fbbe;background:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#b8e356',endColorstr='#a5cc52');background-color:#b8e356;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border:1px solid #83c41a;display:inline-block;color:#fff;font-family:arial;font-size:14px;font-weight:700;text-decoration:none;text-shadow:1px 1px 0 #86ae47;padding:6px 24px;} -.button:hover{background:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#a5cc52',endColorstr='#b8e356');background-color:#a5cc52;} -.button:active{position:relative;top:1px;} -.buttonactive{background-color:#aaa;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border:1px solid #83c41a;display:inline-block;color:#fff;font-family:arial;font-size:14px;font-weight:700;text-decoration:none;text-shadow:1px 1px 0 #86ae47;padding:6px 24px;} -@media screen and (max-width:1024px) { - .vignette { width: 40%; } -} -@media screen and (max-width:640px) { - h1 { font-size:20pt; } - .button, .button:hover, .button:active, .buttonactive { display: block; margin: auto; text-align:center; } - .vignette { width: 80%; } -} -@media screen and (max-width:480px) { - #logo { max-width: 250px; } - input[type="text"]{width:15em;} -} \ No newline at end of file diff --git a/0.3/resources/icon-logo.svg b/0.3/resources/icon-logo.svg deleted file mode 100644 index e3045dd..0000000 --- a/0.3/resources/icon-logo.svg +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/0.3/resources/rss.png b/0.3/resources/rss.png deleted file mode 100644 index 315c4f4fa62cb720326ba3f54259666ba3999e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 691 zcmV;k0!;mhP)bpQb1=l6TxbDZwj&S={?7%qx-u`rsG(Zp`-rh=e^=%((1yvsuf5d=&62Zj)Y zH&JviNS_F4_Hj|T(1j4$p-!}kixP9&dB4uv^MveG?dGf%sUCoc2!IFxD6wHRA2^dX zXRVk!-qSfk(jcaUKn#RP48(whfPlJUpApdrA!TQi_4D+fVoM;3I0gZ8{=Xv~Po;geVA+Em9@0Wq2 zr>OTZEGR05L=gf1T;ucCxq6Q6EgJiH@@-lVaAlQyw`jIF^c=&IVnj|95hHbE_cnt| zTzZQ?F4Ne@(bH(~&3nM%m)I@ID{@jJ2qZPjr)jhpe9hViOwH5k&|T#EmmL3(vHeUQ zq^!t^Al6JD;=mHq^Bg?J-8-zG2Od7gZbknG;K9czYjPqG*xjPo0k(c4%lPXTpw(qq z@aGMnxtFS(np+2kC} z7P02O874ZkJH$v#nCUVx$({yDN`IX@o2wyvTD#e`qN`_w5<}$3F+_ $expire) { - echo "too early"; - die; -} -else { - if( file_exists($lockfile) ) - unlink($lockfile); - - if( file_put_contents($lockfile, date(DATE_RFC822)) ===FALSE) { - echo "Merci d'ajouter des droits d'écriture sur le dossier."; - die; - } -} - -define('ROOT_DIR', __DIR__); -if(file_exists("functions.php")){ - include "functions.php"; -}else{ - echo "functions.php not found !"; - die; -} - -if(file_exists("config.php")){ - include "config.php"; -}else{ - echo "config.php not found !"; - die; -} - -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; -} - -libxml_use_internal_errors(true); - -// $max_exec_time = temps max d'exécution en seconde -function xsafimport($xsafremote, $max_exec_time) { - if( DEBUG ) - 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; - } - - $get_remote_db = ($json_import['meta']['xsaf-db_transfer'] == "true") ? true : false; - $get_remote_media = ($json_import['meta']['xsaf-media_transfer'] == "true") ? true : false; - - if(!empty($json_import['autoblogs'])) { - foreach ($json_import['autoblogs'] as $value) { - - if(count($value)==4 && !empty($value['SITE_TYPE']) && !empty($value['SITE_TITLE']) && !empty($value['SITE_URL']) && !empty($value['FEED_URL'])) { - $sitetype = escape($value['SITE_TYPE']); - $sitename = escape($value['SITE_TITLE']); - $siteurl = escape($value['SITE_URL']); - // Do not use DetectRedirect because it's slow and it has been used when the feed was added - //$rssurl = DetectRedirect(escape($value['FEED_URL'])); - $rssurl = escape($value['FEED_URL']); - } - - - /* TOO SLOW - $xml = simplexml_load_file($rssurl); // quick feed check - // ATOM feed && RSS 1.0 /RDF && RSS 2.0 - $result = (!isset($xml->entry) && !isset($xml->item) && !isset($xml->channel->item)) ? false : true; */ - $result = true; - - /* autoblog */ - if( $result === true ) { - $foldername = urlToFolderSlash($siteurl); - - $errors = createAutoblog($sitetype, $sitename, $siteurl, $rssurl); - foreach( $errors AS $value) { - if( DEBUG ) - echo '

'. $value .'

'; - } - if( empty($errors) && DEBUG ) { - echo '

autoblog '. $sitename .' crée avec succès (DL DB : '. var_dump($get_remote_db) .' - DL media : '. var_dump($get_remote_media) .') : '. $foldername .'

'; - if( !ALLOW_REMOTE_DB_DL && !ALLOW_REMOTE_MEDIA_DL ) - echo ''; - } - - /* ============================================================================================================================================================================== */ - /* récupération de la DB distante */ - if($get_remote_db == true && ALLOW_REMOTE_DB_DL ) { - $remote_db = str_replace("?export", $foldername."/articles.db", $xsafremote); - copy($remote_db, './'. $foldername .'/articles.db'); - } - - if($get_remote_media == true && ALLOW_REMOTE_MEDIA_DL ) { - $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 - //$to_update[] = serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog - } - - if( DEBUG ) - echo '

time : '.($max_exec_time - time()) .'

'; - if(time() >= $max_exec_time) { - if( DEBUG ) - echo "

Time out !

"; - break; - } - } - } - else { - if( DEBUG ) - echo "Format JSON incorrect."; - return false; - } - } - return; -} - -if( DEBUG ) echo ''; -if( ALLOW_NEW_AUTOBLOGS and ALLOW_NEW_AUTOBLOGS_BY_XSAF && !empty($friends_autoblog_farm) ) { - foreach( $friends_autoblog_farm AS $value ) { - if( !empty($value) ) - xsafimport($value, EXEC_TIME); - } - if(DEBUG) echo "

XSAF import finished

"; -} -elseif( DEBUG ) - echo "

XSAF désactivé. Positionnez les variables ALLOW_NEW_AUTOBLOGS et ALLOW_NEW_AUTOBLOGS_BY_XSAF à TRUE dans le fichier config.php pour l'activer.

"; - -if( DEBUG ) echo ''; -?> diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 87eb396..1a0fa83 --- a/README.md +++ b/README.md @@ -1,27 +1,18 @@ -Projet Autoblog -=============== +Projet Autoblog serie 0.3 +============== -Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ) +- version VroumVroumBlog 0.3.0 BETA -Branche MASTER: +Auteurs: Mitsu (https://www.suumitsu.eu/), Oros (https://www.ecirtam.net/) et Arthur Hoaro (http://hoa.ro) -- script de migration 0.2 to 0.3 par Arthur Hoaro +Licence: Domaine Public -- Autoblog Project serie 0.3 par Mitsu, Oros, Arthur Hoaro +- À propos du Projet Autoblog -Nouveautés majeures -=================== +lire: http://sebsauvage.net/streisand.me/fr/ -- "ferme" d'autoblogs avec ajout facile par différents formulaires (générique, microblogging, OPML, marque-pages) -- échange de références entre fermes avec XSAF (Cross-Site Autoblog Farming) -- vérification du statut des sites distants, et flux de suivi des changements -- export facile des références, articles et médias -- contrôle de version et alerte de mise à jour -- apparence de l'autoblog selon son type -- CSS utilisateur personnalisable -- hébergement de documents spécifiques +Instructions -Pré-requis techniques -===================== +- uploader les fichiers sur un serveur avec PHP 5.3+ -- serveur web avec PHP 5.3 et son support SQLite +- ..c'est tout. Hackez le code pour apprendre comment ça marche et comment le personnaliser :) From 732c7d5f6c811f1053f1f92301f5abc625956a04 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Mon, 22 Apr 2013 12:00:26 +0200 Subject: [PATCH 10/28] ?? --- autoblogs/autoblog.php | 908 ++++++++++++++++++++++++++++++++++++ class_rssfeed.php | 277 +++++++++++ config.php | 43 ++ docs/docs.txt | 4 + functions.php | 302 ++++++++++++ index.php | 926 +++++++++++++++++++++++++++++++++++++ resources/autoblog.css | 48 ++ resources/icon-logo.svg | 218 +++++++++ resources/rss.png | Bin 0 -> 691 bytes resources/user.css.example | 10 + version | 1 + xsaf3.php | 169 +++++++ 12 files changed, 2906 insertions(+) create mode 100644 autoblogs/autoblog.php create mode 100755 class_rssfeed.php create mode 100755 config.php create mode 100644 docs/docs.txt create mode 100755 functions.php create mode 100755 index.php create mode 100644 resources/autoblog.css create mode 100644 resources/icon-logo.svg create mode 100644 resources/rss.png create mode 100644 resources/user.css.example create mode 100644 version create mode 100755 xsaf3.php diff --git a/autoblogs/autoblog.php b/autoblogs/autoblog.php new file mode 100644 index 0000000..87a8b28 --- /dev/null +++ b/autoblogs/autoblog.php @@ -0,0 +1,908 @@ +=')) + 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'; +} +//else die("Configuration file not found."); + +if (file_exists(__DIR__ . '/../functions.php')){ + require_once __DIR__ . '/../functions.php'; +} +else die("Functions file not found."); + +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 + define('LOCAL_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '')."://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); +} + +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: Mozilla/5.0 (X11; Linux x86_64; rv:20.0; Autoblogs; +https://github.com/mitsukarenai/Projet-Autoblog/) Gecko/20100101 Firefox/20.0\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); + if( isset($from['path']) ) { // not exist if http://exemple.com + $from['path'] = preg_replace('![^/]*$!', '', $from['path']); + }else{ + $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/atom+xml; charset=UTF-8'); + echo ' + + '.escape($config->site_title).' + '.escape(html_entity_decode(strip_tags($config->site_description), ENT_COMPAT, 'UTF-8')).' + '.date(DATE_ATOM, filemtime(ARTICLES_DB_FILE)).' + + '.LOCAL_URL.' + + Projet Autoblog'; + + foreach($vvb->listLastArticles() as $art) + { + echo ' + + + '.escape($config->site_title).' + '.escape($config->site_url).' + + <![CDATA['.escape($art['title']).']]> + + '.str_replace('?feed', '?', LOCAL_URL).urlencode(str_replace('./?', '', $vvb->getLocalURL($art))).' + '.date(DATE_ATOM, $art['date']).' + + + source)
'.escape_content($art['content']).']]> +
+
'; + } + + echo ' +
'; + exit; +} + +if (isset($_GET['opml'])) // OPML +{ + //header('Content-Type: application/octet-stream'); + header('Content-type: text/xml'); + header('Content-Disposition: attachment; filename="'.escape($config->site_title).'.xml"'); + $opmlfile = new SimpleXMLElement(''); + $opmlfile->addAttribute('version', '1.0'); + $opmlhead = $opmlfile->addChild('head'); + $opmlhead->addChild('title', escape($config->site_title)); + $opmlhead->addChild('dateCreated', date('r', time())); + $opmlbody = $opmlfile->addChild('body'); + $outline = $opmlbody->addChild('outline'); + $outline->addAttribute('title', escape($config->site_title)); + $outline->addAttribute('text', escape($config->site_type)); + $outline->addAttribute('htmlUrl', escape($config->site_url)); + $outline->addAttribute('xmlUrl', escape($config->feed_url)); + + echo $opmlfile->asXML(); + exit; +} + +if (isset($_GET['media'])) // MEDIA +{ + header('Content-Type: application/json'); + if(is_dir(MEDIA_DIR)) + { + $url = str_replace('?media', 'media/', LOCAL_URL); + $files = scandir(MEDIA_DIR); + unset($files[0]); // . + unset($files[1]); // .. + echo json_encode(array("url"=> $url, "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' || $site_type == 'twitter' || $site_type == 'identica') // 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).' + + + + + +
+

PROJET AUTOBLOG'. (strlen(HEAD_TITLE) > 0 ? ' ~ '. HEAD_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 ' + +'; + + +function escape_content($str) +{ + $str = preg_replace('!<\s*(style|script|link)!', '<\\1', $str); + $str = str_replace('="media/', '="./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/class_rssfeed.php b/class_rssfeed.php new file mode 100755 index 0000000..59fd431 --- /dev/null +++ b/class_rssfeed.php @@ -0,0 +1,277 @@ + + * + * + 03/2013 + * Few changes, AutoblogRSS and FileRSSFeed + * @author Arthur Hoaro + */ +class RSSFeed { + protected $xml; + + /** + * Construct a RSS feed + */ + public function __construct() { + $template = << + + + + +END; + + $this->xml = new SimpleXMLElement($template); + } + + /** + * Set RSS Feed headers + * @param $title the title of the feed + * @param $link link to the website where you can find the RSS feed + * @param $description a description of the RSS feed + * @param $rsslink the link to this RSS feed + */ + public function setHeaders($title, $link, $description, $rsslink) { + $atomlink = $this->xml->channel->addChild("atom:link","","http://www.w3.org/2005/Atom"); + $atomlink->addAttribute("href",$rsslink); + $atomlink->addAttribute("rel","self"); + $atomlink->addAttribute("type","application/rss+xml"); + + $this->xml->channel->title = $title; + $this->xml->channel->link = $link; + $this->xml->channel->description = $description; + } + + /** + * Set the language of the RSS feed + * @param $lang the language of the RSS feed + */ + public function setLanguage($lang) { + $this->xml->channel->addChild("language",$lang); + } + /** + * Adds a picture to the RSS feed + * @param $url URL to the image + * @param $title The image title. Usually same as the RSS feed's title + * @param $link Where the image should link to. Usually same as the RSS feed's link + */ + public function setImage($url, $title, $link) { + $image = $this->xml->channel->addChild("image"); + $image->url = $url; + $image->title = $title; + $image->link = $link; + } + /** + * Add a item to the RSS feed + * @param $title The title of the RSS feed + * @param $link Link to the item's url + * @param $description The description of the item + * @param $author The author who wrote this item + * @param $guid Unique ID for this post + * @param $timestamp Unix timestamp for making a date + */ + public function addItem($title, $link, $description, $author, $guid, $timestamp) { + $item = $this->xml->channel->addChild("item"); + $item->title = $title; + $item->description = $description; + $item->link = $link; + $item->guid = $guid; + if( isset($guid['isPermaLink'])) + $item->guid['isPermaLink'] = $guid['isPermaLink']; + if( !empty( $author) ) + $item->author = $author; + $item->pubDate = date(DATE_RSS,intval($timestamp)); + } + /** + * Displays the RSS feed + */ + public function displayXML() { + header('Content-type: application/rss+xml; charset=utf-8'); + echo $this->xml->asXML(); + exit; + } + + public function getXML() { + return $this->xml; + } +} + +class RSSMerger { + private $feeds = array(); + + /** + * Constructs a RSSmerger object + */ + function __construct() { + + } + + /** + * Populates the feeds array from the given url which is a rss feed + * @param $url + */ + function add($xml) { + + foreach($xml->channel->item as $item) { + $item->sitetitle = $xml->channel->title; + $item->sitelink = $xml->channel->link; + + preg_match("/^[A-Za-z]{3}, ([0-9]{2}) ([A-Za-z]{3}) ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([\+|\-]?[0-9]{4})$/", $item->pubDate, $match); + $item->time = time($match[4]+($match[6]/100),$match[5],$match[6],date("m",strtotime($match[2])),$match[1],$match[3]); + + $this->feeds[] = $item; + } + } + /** + * Comparing function for sorting the feeds + * @param $value1 + * @param $value2 + */ + function feeds_cmp($value1,$value2) { + if(intval($value1->time) == intval($value2->time)) + return 0; + + return (intval($value1->time) < intval($value2->time)) ? +1 : -1; + } + + /** + * Sorts the feeds array using the Compare function feeds_cmp + */ + function sort() { + usort($this->feeds,Array("RssMerger","feeds_cmp")); + } + + /** + * This function return the feed items. + * @param $limit how many feed items that should be returned + * @return the feeds array + */ + function getFeeds($limit) { + return array_slice($this->feeds,0,$limit); + } +} + +class FileRSSFeed extends RSSFeed { + protected $filename; + + public function __construct($filename) { + parent::__construct(); + $this->filename = $filename; + + $this->load(); + } + + public function load() { + if ( file_exists( $this->filename )) { + $this->xml = simplexml_load_file($this->filename); + } + } + + public function create($title, $link, $description, $rsslink) { + parent::setHeaders($title, $link, $description, $rsslink); + $this->write(); + } + + public function addItem($title, $link, $description, $author, $guid, $timestamp) { + parent::addItem($title, $link, $description, $author, $guid, $timestamp); + $this->write(); + } + + private function write() { + if ( file_exists( $this->filename )) { + unlink($this->filename); + } + + $outputXML = new RSSFeed(); + foreach($this->xml->channel->item as $f) { + $item = $outputXML->addItem($f->title,$f->link,$f->description,$f->author,$f->guid, strtotime($f->pubDate)); + } + + $merger = new RssMerger(); + $merger->add($outputXML->getXML()); + $merger->sort(); + + unset($this->xml->channel->item); + foreach($merger->getFeeds(20) as $f) { + parent::addItem($f->title,$f->link,$f->description,$f->author,$f->guid,$f->time); + } + + file_put_contents( $this->filename, $this->xml->asXML(), LOCK_EX ); + } +} + +class AutoblogRSS extends FileRSSFeed { + public function __construct($filename) { + parent::__construct($filename); + } + + public function addUnavailable($title, $folder, $siteurl, $rssurl) { + $path = pathinfo( $_SERVER['PHP_SELF'] ); + $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. + $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; + + parent::addItem( 'L\'autoblog "'. $title.'" est indisponible', $autobHref, + 'Autoblog: '.$title.'
+ Site: '. $siteurl .'
+ RSS: '.$rssurl.'
+ Folder: '. $folder , + 'admin@'.$_SERVER['SERVER_NAME'], + $autobHref, + time() + ); + } + + public function addAvailable($title, $folder, $siteurl, $rssurl) { + $path = pathinfo( $_SERVER['PHP_SELF'] ); + $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. + $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; + + parent::addItem( 'L\'autoblog "'. $title.'" est de nouveau disponible', $autobHref, + 'Autoblog : '.$title.'
+ Site: '. $siteurl .'
+ RSS: '.$rssurl.'
+ Folder: '. $folder , + 'admin@'.$_SERVER['SERVER_NAME'], + $autobHref, + time() + ); + } + + public function addCodeChanged($title, $folder, $siteurl, $rssurl, $code) { + $path = pathinfo( $_SERVER['PHP_SELF'] ); + $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. + $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; + + parent::addItem( 'L\'autoblog "'. $title.'" a renvoyé un code imprévu', $autobHref, + 'Code: '. $code .'
+ Autoblog : '.$title.'
+ Site: '. $siteurl .'
+ RSS: '.$rssurl.'
+ Folder: '. $folder , + 'admin@'.$_SERVER['SERVER_NAME'], + $autobHref, + time() + ); + } + + public function addNewAutoblog($title, $folder, $siteurl, $rssurl) { + $path = pathinfo( $_SERVER['PHP_SELF'] ); + $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. + $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; + + parent::addItem( 'L\'autoblog "'. $title.'" a été ajouté à la ferme', $autobHref, + 'Autoblog : '.$title.'
+ Site: '. $siteurl .'
+ RSS: '.$rssurl.'
+ Folder: '. $folder , + 'admin@'.$_SERVER['SERVER_NAME'], + $autobHref, + time() + ); + } +} + +?> diff --git a/config.php b/config.php new file mode 100755 index 0000000..8f98017 --- /dev/null +++ b/config.php @@ -0,0 +1,43 @@ +SebSauvage et Bohwaz.'); + +// define( 'ALLOW_FULL_UPDATE', TRUE ); +// define( 'ALLOW_CHECK_UPDATE', TRUE ); + +/** + * If you set ALLOW_NEW_AUTOBLOGS to FALSE, the following options do not matter. + **/ +// define( 'ALLOW_NEW_AUTOBLOGS', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_LINKS', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_SOCIAL', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_BUTTON', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK', TRUE ); +// define( 'ALLOW_NEW_AUTOBLOGS_BY_XSAF', TRUE ); + +/** + * More about TwitterBridge : https://github.com/mitsukarenai/twitterbridge + **/ +// define( 'API_TWITTER', FALSE ); + +/** + * Import autoblogs from friend's autoblog farm - Add a link to the JSON export + **/ +$friends_autoblog_farm = array( + 'https://raw.github.com/mitsukarenai/xsaf-bootstrap/master/3.json', + // 'https://www.ecirtam.net/autoblogs/?export', + // 'https://autoblog.suumitsu.eu/?export', + // 'http://streisand.hoa.ro/?export', +); +?> diff --git a/docs/docs.txt b/docs/docs.txt new file mode 100644 index 0000000..a4c763e --- /dev/null +++ b/docs/docs.txt @@ -0,0 +1,4 @@ +You can manually add files in the /docs/ directory, such as PDF, docs, images, etc. +You can also add subfolders in /docs/ for website mirroring. Be sure that your subfolder contains a file named index.html. + +Delete this file to hide the 'Autres documents' block in your autoblogs homepage. diff --git a/functions.php b/functions.php new file mode 100755 index 0000000..b1f68d1 --- /dev/null +++ b/functions.php @@ -0,0 +1,302 @@ +SebSauvage et Bohwaz.'); + +// Functions +function NoProtocolSiteURL($url) { + $protocols = array("http://", "https://"); + $siteurlnoproto = str_replace($protocols, "", $url); + + // Remove the / at the end of string + if ( $siteurlnoproto[strlen($siteurlnoproto) - 1] == '/' ) + $siteurlnoproto = substr($siteurlnoproto, 0, -1); + + // Remove index.php/html at the end of string + if( strpos($url, 'index.php') || strpos($url, 'index.html') ) { + $siteurlnoproto = preg_replace('#(.*)/index\.(html|php)$#', '$1', $siteurlnoproto); + } + + return $siteurlnoproto; +} + + +function DetectRedirect($url) +{ + if(parse_url($url, PHP_URL_HOST)==FALSE) { + //die('Not a URL'); + throw new Exception('Not a URL: '. escape ($url) ); + } + $response = get_headers($url, 1); + if(!empty($response['Location'])) { + $response2 = get_headers($response['Location'], 1); + if(!empty($response2['Location'])) { + //die('too much redirection'); + throw new Exception('too much redirection: '. escape ($url) ); + } + else { return $response['Location']; } + } + else { + return $url; + } +} + +function urlToFolder($url) { + return sha1(NoProtocolSiteURL($url)); +} + +function urlToFolderSlash($url) { + return sha1(NoProtocolSiteURL($url).'/'); +} + +function folderExists($url) { + return file_exists(AUTOBLOGS_FOLDER . urlToFolder($url)) || file_exists(AUTOBLOGS_FOLDER . urlToFolderSlash($url)); +} + +function escape($str) { + return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false); +} + +function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { + if( $type == 'generic' || empty( $type )) { + $var = updateType( $siteurl ); + $type = $var['type']; + if( !empty( $var['name']) ) { + if( !stripos($siteurl, $var['name'] === false) ) + $sitename = ucfirst($var['name']) . ' - ' . $sitename; + } + } + + if(folderExists($siteurl)) { + $error[] = 'Erreur : l\'autoblog '. $sitename .' existe déjà.'; + return $error; + } + + $foldername = AUTOBLOGS_FOLDER . urlToFolderSlash($siteurl); + + if ( mkdir($foldername, 0755, false) ) { + + /** + * RSS + **/ + try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->addNewAutoblog($sitename, $foldername, $siteurl, $rssurl); + } + catch (Exception $e) { + ; + } + + $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="'. $type .'" +SITE_TITLE="'. $sitename .'" +SITE_DESCRIPTION="Site original : '. $sitename .'" +SITE_URL="'. $siteurl .'" +FEED_URL="'. $rssurl .'" +ARTICLES_PER_PAGE="'. getArticlesPerPage( $type ) .'" +UPDATE_INTERVAL="'. getInterval( $type ) .'" +UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) + $error[] = "Impossible d'écrire le fichier vvb.ini"; + fclose($fp); + } + else + $error[] = "Impossible de créer le répertoire."; + updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); /* éventuellement une conditionnelle ici: if(empty($error)) ? */ + return $error; +} + +function getArticlesPerPage( $type ) { + switch( $type ) { + case 'microblog': + return 20; + case 'shaarli': + return 20; + default: + return 5; + } +} + +function getInterval( $type ) { + switch( $type ) { + case 'microblog': + return 300; + case 'shaarli': + return 1800; + default: + return 3600; + } +} + +function getTimeout( $type ) { + switch( $type ) { + case 'microblog': + return 30; + case 'shaarli': + return 30; + default: + return 30; + } +} + +function updateType($siteurl) { + if( strpos($siteurl, 'twitter.com') !== FALSE ) { + return array('type' => 'twitter', 'name' => 'twitter'); + } + elseif ( strpos( $siteurl, 'identi.ca') !== FALSE ) { + return array('type' => 'identica', 'name' => 'identica'); + } + elseif( strpos( $siteurl, 'shaarli' ) !== FALSE ) { + return array('type' => 'shaarli', 'name' => 'shaarli'); + } + else + return array('type' => 'generic', 'name' => ''); +} + +function debug($data) +{ + echo '
';
+	var_dump($data);
+	echo '
'; +} + +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 '%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 'ATOM Feed': + return 'Flux ATOM'; + 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; + } +} + +function updateXML($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) +{ +$json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); +$json[] = array( + 'timestamp'=>time(), + 'autoblog_url'=>$autoblog_url, + 'autoblog_title'=>$autoblog_title, + 'autoblog_sourceurl'=>$autoblog_sourceurl, + 'autoblog_sourcefeed'=>$autoblog_sourcefeed, + 'status'=>$status, + 'response_code'=>$response_code + ); +file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX); +} + +function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { + switch ($status) + { + case 'unavailable': + return 'Autoblog "'.$autoblog_title.'": site distant inaccessible (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'moved': + return 'Autoblog "'.$autoblog_title.'": site distant redirigé (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'not_found': + return 'Autoblog "'.$autoblog_title.'": site distant introuvable (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'remote_error': + return 'Autoblog "'.$autoblog_title.'": site distant a problème serveur (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'available': + return 'Autoblog "'.$autoblog_title.'": site distant à nouveau opérationnel (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + case 'new_autoblog_added': + return 'Autoblog "'.$autoblog_title.'" ajouté (code '.$response_code.')
Autoblog: '.$autoblog_title.'
Site: '. $autoblog_sourceurl .'
RSS: '.$autoblog_sourcefeed.''; + } +} + +function displayXML_tmp() { +header('Content-type: application/rss+xml; charset=utf-8'); +echo ' +'.serverUrl(true).''; +echo 'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; +if(file_exists(RESOURCES_FOLDER.'rss.json')) +{ + $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); + foreach ($json as $item) + { + $description = displayXMLstatus_tmp($item['status'],$item['response_code'],$item['autoblog_url'],$item['autoblog_title'],$item['autoblog_sourceurl'],$item['autoblog_sourcefeed']); + $link = serverUrl(true).AUTOBLOGS_FOLDER.$item['autoblog_url']; + $date = date("r", $item['timestamp']); + print << + {$item['autoblog_title']} + + {$link} + {$item['timestamp']} + admin@{$_SERVER['SERVER_NAME']} + {$date} + +EOT; + } +} +echo ''; +} +?> diff --git a/index.php b/index.php new file mode 100755 index 0000000..be3c7e4 --- /dev/null +++ b/index.php @@ -0,0 +1,926 @@ +loadXML($data) or die('xml malformé'); + $title = $dom->getElementsByTagName('title'); + return $title->item(0)->nodeValue; +} + +function get_link_from_feed($url) { + return get_link_from_datafeed(file_get_contents($url)); +} + +function get_link_from_datafeed($data) { + if($data === false) { return 'url inaccessible'; } + $xml = simplexml_load_string($data); // quick feed check + + // ATOM feed && RSS 1.0 /RDF && RSS 2.0 + if (!isset($xml->entry) && !isset($xml->item) && !isset($xml->channel->item)) + 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($return_subfolder = false) +{ + $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"]); + if($return_subfolder === true) { + $path = pathinfo( $_SERVER['PHP_SELF'] ); + $subfolder = $path['dirname'] .'/'; + } else $subfolder = ''; + return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport.$subfolder; +} + +function objectCmp($a, $b) { + return strcasecmp ($a->site_title, $b->site_title); +} + +function generate_antibot() { + $letters = array('zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt'); + return $letters[mt_rand(1, 20)]; +} + +function check_antibot($number, $text_number) { + $letters = array('zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt'); + return ( array_search( $text_number, $letters ) === intval($number) ) ? true : false; +} + +function create_from_opml($opml) { + global $error, $success; + + foreach( $opml->body->outline as $outline ) { + if ( !empty( $outline['title'] ) && !empty( $outline['text'] ) && !empty( $outline['xmlUrl']) && !empty( $outline['htmlUrl'] )) { + try { + $rssurl = DetectRedirect(escape( $outline['xmlUrl'])); + + $sitename = escape( $outline['title'] ); + $siteurl = escape($outline['htmlUrl']); + $sitetype = escape($outline['text']); if ( $sitetype == 'generic' or $sitetype == 'microblog' or $sitetype == 'shaarli') { } else { $sitetype = 'generic'; } + + $error = array_merge( $error, createAutoblog( $sitetype, $sitename, $siteurl, $rssurl, $error ) ); + + if( empty ( $error )) + $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; + } + catch (Exception $e) { + $error[] = $e->getMessage(); + } + } + } +} + +/** + * Simple version check + **/ +function versionCheck() { + $versionfile = 'version'; + $lastestUrl = 'https://raw.github.com/mitsukarenai/Projet-Autoblog/master/0.3/version'; + + $expire = time() - 84600 ; // 23h30 en secondes + $lockfile = '.versionlock'; + + if (file_exists($lockfile) && filemtime($lockfile) > $expire) { + if( file_get_contents($lockfile) == 'NEW' ) { + // No new version installed + if( filemtime( $lockfile ) > filemtime( $versionfile ) ) + return true; + else unlink($lockfile); + } + else return false; + } + + if (file_exists($lockfile) && filemtime($lockfile) < $expire) { unlink($lockfile); } + + if( file_get_contents($versionfile) != file_get_contents($lastestUrl) ) { + file_put_contents($lockfile, 'NEW'); + return true; + } + file_put_contents($lockfile, '.'); + return false; + } + $update_available = (ALLOW_CHECK_UPDATE) ? versionCheck() : false; + +/** +* RSS Feed +**/ +if( !file_exists(RSS_FILE)) { + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->create('Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : ''), serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.", serverUrl(true) . RSS_FILE); +} +if (isset($_GET['rss'])) { + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->displayXML(); + die; +} + +if( !file_exists(RESOURCES_FOLDER.'rss.json')) { + file_put_contents(RESOURCES_FOLDER.'rss.json', '', LOCK_EX); +} + +if (isset($_GET['rss_tmp'])) { + displayXML_tmp(); + die; +} + +/** + * SVG + **/ +if (isset($_GET['check'])) +{ + //echo "1"; + header('Content-type: image/svg+xml'); + $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="./".escape( $_GET['check'] ) ."/error.log"; + + $oldvalue = null; + if(file_exists($errorlog)) { $oldvalue = file_get_contents($errorlog); }; + 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 */ + { + 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("./". escape( $_GET['check'] ) ."/vvb.ini") or die; + + if(strpos(strtolower($ini['SITE_TITLE']), 'twitter') !== FALSE) { die($svg_twitter); } /* Twitter */ + if(strpos(strtolower($ini['SITE_TITLE']), 'identica') !== FALSE) { die($svg_identica); } /* Identica */ + if(strpos(strtolower($ini['SITE_TYPE']), 'microblog') !== FALSE) { die($svg_statusnet); } /* Statusnet */ + + $headers = get_headers($ini['FEED_URL']); + /* le flux est indisponible (typiquement: erreur DNS ou possible censure) - à vérifier */ + if(empty($headers) || $headers === FALSE ) { + if( $oldvalue !== null && $oldvalue != '..' ) { + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->addUnavailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); + updateXML('unavailable', 'nxdomain', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); + } + file_put_contents($errorlog, '..'); + die($svg_rouge); + } + $code=explode(" ", $headers[0]); + /* code retour 200: flux disponible */ + if($code[1] == "200") { + if( $oldvalue !== null && $oldvalue != '' ) { + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->addAvailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); + updateXML('available', '200', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); + } + file_put_contents($errorlog, ''); + die($svg_vert); + } + /* autre code retour: un truc a changé (redirection, changement de CMS, .. bref vvb.ini doit être corrigé) */ + else { + if( $oldvalue !== null && $oldvalue != '.' ) { + require_once('class_rssfeed.php'); + $rss = new AutoblogRSS(RSS_FILE); + $rss->addCodeChanged($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL'], $code[1]); + updateXML('moved', '3xx', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); + } + file_put_contents($errorlog, '.'); + die($svg_jaune); + } + } +} + +/** + * JSON Export + **/ +if (isset($_GET['export'])) { + header('Content-Type: application/json'); + $subdirs = glob(AUTOBLOGS_FOLDER . "*"); + + 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; + $type=$config->site_type; + $title=$config->site_title; + $url=$config->site_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; +} + +/** + * JSON Allowed Twitter accounts export + **/ +if (isset($_GET['export_twitter'])) { + header('Content-Type: application/json'); + $subdirs = glob(AUTOBLOGS_FOLDER . "*"); + $response = array(); + + foreach($subdirs as $unit) { + if(is_dir($unit)) { + $unit=substr($unit, 2); + $ini = parse_ini_file($unit.'/vvb.ini'); + if( $ini['SITE_TYPE'] == 'twitter' ) { + preg_match('#twitter\.com/(.+)#', $ini['SITE_URL'], $username); + $response[] = $username[1]; + } + unset($ini); + } + } + echo json_encode( $response ); + die; +} + +/** + * OPML Full Export + **/ +if (isset($_GET['exportopml'])) // OPML +{ + //header('Content-Type: application/octet-stream'); + header('Content-type: text/xml'); + header('Content-Disposition: attachment; filename="autoblogs-'. $_SERVER['SERVER_NAME'] .'.xml"'); + + $opmlfile = new SimpleXMLElement(''); + $opmlfile->addAttribute('version', '1.0'); + $opmlhead = $opmlfile->addChild('head'); + $opmlhead->addChild('title', 'Autoblog OPML export from '. $_SERVER['SERVER_NAME'] ); + $opmlhead->addChild('dateCreated', date('r', time())); + $opmlbody = $opmlfile->addChild('body'); + + $subdirs = glob(AUTOBLOGS_FOLDER . "*"); + + 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); + + $outline = $opmlbody->addChild('outline'); + $outline->addAttribute('title', escape($config->site_title)); + $outline->addAttribute('text', escape($config->site_type)); + $outline->addAttribute('htmlUrl', escape($config->site_url)); + $outline->addAttribute('xmlUrl', escape($config->feed_url)); + } + } + echo $opmlfile->asXML(); + exit; +} + +/** + * Site map + * NEW AUTOBLOG FOLDER - Need update + **/ +if (isset($_GET['sitemap'])) +{ + header('Content-Type: application/xml'); + $proto=(!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS'])=='on')?"https://":"http://"; + echo ''; + echo ''.$proto."{$_SERVER['HTTP_HOST']}".str_replace('?sitemap', '', $_SERVER['REQUEST_URI'])."\n"; + echo ''.date('c', time())."\n"; + echo 'daily'; + $subdirs = glob(AUTOBLOGS_FOLDER . "*"); + foreach($subdirs as $unit) { + if(is_dir($unit)) { + $unit=substr($unit, 2); + echo ''.$proto.$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, -9)."$unit/"."\n"; + echo ''.date('c', filemtime($unit))."\n"; + echo 'hourly'; + } + } + echo ''; + die; +} + +/** + * Update ALL autblogs (except .disabled) + * This action can be very slow and consume CPU if you have a lot of autoblogs + **/ +if( isset($_GET['updateall']) && ALLOW_FULL_UPDATE) { + + $expire = time() - 84600 ; // 23h30 en secondes + $lockfile = ".updatealllock"; + if (file_exists($lockfile) && filemtime($lockfile) > $expire) { + echo "too early"; + die; + } + else { + if( file_exists($lockfile) ) + unlink($lockfile); + + if( file_put_contents($lockfile, date(DATE_RFC822)) ===FALSE) { + echo "Merci d'ajouter des droits d'écriture sur le fichier."; + die; + } + } + + $subdirs = glob(AUTOBLOGS_FOLDER . "*"); + foreach($subdirs as $unit) { + if(is_dir($unit)) { + if( !file_exists(ROOT_DIR . '/' . $unit . '/.disabled')) { + file_get_contents(serverUrl() . substr($_SERVER['PHP_SELF'], 0, -9) . $unit . '/index.php'); + } + } + } +} + +$antibot = generate_antibot(); +$form = '
+
+
+ + +
'; + +/** + * ADD BY BOOKMARK BUTTON + **/ +if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_BUTTON ) +{ + $form = ''; + + if( empty($_GET['rssurl']) ) { + $form .= '

URL du flux RSS incorrect.
Fermer la fenêtre.

'; + } + else { + if(isset($_GET['add']) && $_GET['add'] === '1' && !empty($_GET['siteurl']) && !empty($_GET['sitename'])) { + try { + $rssurl = DetectRedirect(escape($_GET['rssurl'])); + + $siteurl = escape($_GET['siteurl']); + $sitename = escape($_GET['sitename']); + $sitetype = updateType($siteurl); // Disabled input doesn't send POST data + $sitetype = $sitetype['type']; + + $error = array_merge( $error, createAutoblog($sitetype, $sitename, $siteurl, $rssurl, $error)); + if( empty($error)) { + $form .= ''; + $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; + } + else { + $form .= '

    '; + foreach ( $error AS $value ) + $form .= '
  • '. $value .'
  • '; + $form .= '
'; + } + } + catch (Exception $e) { + $form .= $e->getMessage(); + } + $form .= 'Fermer la fenêtre.

'; + } + else { + try { + $rssurl = DetectRedirect(escape($_GET['rssurl'])); + $datafeed = file_get_contents($rssurl); + if( $datafeed !== false ) { + $siteurl = get_link_from_datafeed($datafeed); + $sitename = get_title_from_datafeed($datafeed); + $sitetype = updateType($siteurl); + $sitetype = $sitetype['type']; + + $form .= 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
+
+ +
+
+
+
+
'; + } + else { + $form .= '

URL du flux RSS incorrecte.
Fermer la fenêtre.

'; + } + } + catch (Exception $e) { + $form .= $e->getMessage() .'
Fermer la fenêtre.

'; + } + } + } + $form .= ''; + echo $form; die; +} + +/** + * ADD BY SOCIAL / SHAARLI + **/ +if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) +{ + if( !empty($_POST['number']) && !empty($_POST['antibot']) && check_antibot($_POST['number'], $_POST['antibot']) ) { + + $socialaccount = strtolower(escape($_POST['socialaccount'])); + $socialinstance = strtolower(escape($_POST['socialinstance'])); + + if($socialinstance === 'twitter') { + if( API_TWITTER !== FALSE ) { + $sitetype = 'twitter'; + $siteurl = "http://twitter.com/$socialaccount"; + $rssurl = API_TWITTER.$socialaccount; + } + else + $error[] = "Twitter veut mettre à mort son API ouverte. Du coup on peut plus faire ça comme ça."; + } + elseif($socialinstance === 'identica') { + $sitetype = 'identica'; + $siteurl = "http://identi.ca/$socialaccount"; + $rssurl = "http://identi.ca/api/statuses/user_timeline/$socialaccount.rss"; + } + elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { + $sitetype = 'microblog'; + $siteurl= NoProtocolSiteURL(escape($_POST['statusneturl'])); + try { + $rssurl = DetectRedirect("http://".$siteurl."/api/statuses/user_timeline/$socialaccount.rss"); + $siteurl = DetectRedirect("http://".$siteurl."/$socialaccount"); + } + catch (Exception $e) { + echo $error[] = $e->getMessage(); + } + } + elseif($socialinstance === 'shaarli' && !empty($_POST['shaarliurl'])) { + $sitetype = 'shaarli'; + $siteurl = NoProtocolSiteURL(escape($_POST['shaarliurl'])); + try { + $siteurl = DetectRedirect("http://".$siteurl."/"); + } + catch (Exception $e) { + echo $error[] = $e->getMessage(); + } + $rssurl = $siteurl."?do=rss"; + $socialaccount = get_title_from_feed($rssurl); + } + + if( empty($error) ) { + // Twitterbridge do NOT allow this user yet => No check + if( $sitetype != 'twitter' ) { + $headers = get_headers($rssurl, 1); + if (strpos($headers[0], '200') == FALSE) { + $error[] = "Flux inaccessible (compte inexistant ?)"; + } + } + if( empty($error) ) { + $error = array_merge( $error, createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl, $error)); + if( empty($error)) + $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; + } + } + } + else + $error[] = 'Antibot : Chiffres incorrects.'; +} + +/** + * ADD BY GENERIC LINK + **/ +if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_LINKS) { + if(empty($_POST['rssurl'])) + {$error[] = "Veuillez entrer l'adresse du flux.";} + if(empty($_POST['number']) || empty($_POST['antibot']) ) + {$error[] = "Vous êtes un bot ?";} + elseif(! check_antibot($_POST['number'], $_POST['antibot'])) + {$error[] = "Antibot : Ce n'est pas le bon nombre.";} + + if(empty($error)) { + try { + $rssurl = DetectRedirect(escape($_POST['rssurl'])); + + if(!empty($_POST['siteurl'])) { + + $siteurl = escape($_POST['siteurl']); + $sitename = get_title_from_feed($rssurl); + + $error = array_merge( $error, createAutoblog('generic', $sitename, $siteurl, $rssurl, $error)); + + if( empty($error)) + $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; + } + else { + // checking procedure + + $datafeed = file_get_contents($rssurl); + if( $datafeed === false ) { + $error[] = 'URL "'. $rssurl .'" inaccessible.'; + } + $sitetype = 'generic'; + $siteurl = get_link_from_datafeed($datafeed); + $sitename = get_title_from_datafeed($datafeed); + + $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
+
+
+
+
+
+
+
'; + + } + } + catch (Exception $e) { + echo $error[] = $e->getMessage(); + } + } +} + +/** + * ADD BY OPML File + **/ +if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE) { + if(empty($_POST['number']) || empty($_POST['antibot']) ) + {$error[] = "Vous êtes un bot ?";} + elseif(! check_antibot($_POST['number'], $_POST['antibot'])) + {$error[] = "Antibot : Ce n'est pas le bon nombre.";} + + if( empty( $error)) { + if (is_uploaded_file($_FILES['file']['tmp_name'])) { + $opml = null; + if( ($opml = simplexml_load_file( $_FILES['file']['tmp_name'])) !== false ) { + create_from_opml($opml); + } + else + $error[] = "Impossible de lire le contenu du fichier OPML."; + unlink($_FILES['file']['tmp_name']); + } else { + $error[] = "Le fichier n'a pas été envoyé."; + } + } +} + +/** + * ADD BY OPML Link + **/ + if( !empty($_POST['opml_link']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK) { + if(empty($_POST['number']) || empty($_POST['antibot']) ) + {$error[] = "Vous êtes un bot ?";} + elseif(! check_antibot($_POST['number'], $_POST['antibot'])) + {$error[] = "Antibot : Ce n'est pas le bon nombre.";} + if( empty( $_POST['opml_url'] )) + {$error[] = 'Le lien est incorrect.';} + + if( empty( $error)) { + $opml_url = escape($_POST['opml_url']); + if(parse_url($opml_url, PHP_URL_HOST)==FALSE) { + $error[] = "URL du fichier OPML non valide."; + } else { + if ( ($opml = simplexml_load_file( $opml_url )) !== false ) { + create_from_opml($opml); + } else { + $error[] = "Impossible de lire le contenu du fichier OPML ou d'accéder à l'URL donnée."; + } + } + + } +} + +?> + + + + + Projet Autoblog<?php if(strlen(HEAD_TITLE)>0) echo " | " . HEAD_TITLE; ?> + + + '; + } + ?> + + +

+ PROJET AUTOBLOG + 0) echo " | " . HEAD_TITLE; ?> +

+ +
+ '; + ?> +

Présentation

+ +

+ Le Projet Autoblog a pour objectif de répliquer les articles d'un blog ou d'un site site web.
+ Si l'article source est supprimé, et même si le site d'origine disparaît, les articles restent lisibles sur l'autoblog.
+ L'objectif premier de ce projet est de lutter contre la censure et toute sorte de pression... +

+ +

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

+
+ + +
+

Mise à jour

+

+ Une mise à jour du Projet Autoblog est disponible !
+ → Télécharger la dernière version
+ → Important : Consulter la documentation - mise à jour +

+
+ + + +
+ +

Ajouter un autoblog

+ + Message'. (count($error) ? 's' : '') .' :

    '; + foreach ( $error AS $value ) { + echo '
  • '. $value .'
  • '; + } + foreach ( $success AS $value ) { + echo '
  • '. $value .'
  • '; + } + echo '
'; + } + + $button_list = '

Ajouter un autoblog via : '; + if(ALLOW_NEW_AUTOBLOGS_BY_LINKS) + $button_list .= 'Flux RSS '; + if(ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) { + $button_list .= 'Compte réseau social '; + $button_list .= 'Shaarli '; + } + if(ALLOW_NEW_AUTOBLOGS_BY_OPML_FILE) + $button_list .= 'Fichier OPML '; + if(ALLOW_NEW_AUTOBLOGS_BY_OPML_LINK) + $button_list .= 'Lien vers OPML '; + if(ALLOW_NEW_AUTOBLOGS_BY_BUTTON) + $button_list .= 'Marque page '; + $button_list .= '

'; + echo $button_list; + + if(ALLOW_NEW_AUTOBLOGS_BY_LINKS == TRUE) { ?> +
+

Ajouter un site web

+

+ Si vous souhaitez que héberge un autoblog d'un site,
+ remplissez le formulaire suivant: +

+ + +
+ +
+

Ajouter un compte social

+ +
+
+ Twitter
'; + else echo 'Twitter
'; ?> + Identica
+ +
+
+ + +
+
+ +
+

Ajouter un Shaarli

+ +
+ +
+
+ + +
+
+ +
+

Ajouter par fichier OPML

+ +
+ +
+
+ + +
+
+ + + + + + + +
+ + + '. substr($unit, (strrpos($unit, '/')) + 1 ) .''; + } + } + } + if(!empty( $docs )) { + echo '

Autres documents

    '; + foreach( $docs as $value ) + echo '
  • '. $value .'
  • '; + echo '
'; + } + ?> + +
+

Autoblogs hébergés rss

+

+ Autres fermes + → Rechercher +

+ + +
+ $value) + { + $key = strtolower($key); + $config->$key = $value; + } + $autoblogs[$unit] = $config; + unset($ini); + } + } + } + } + } + + uasort($autoblogs, "objectCmp"); + $autoblogs_display = ''; + + if(!empty($autoblogs)){ + foreach ($autoblogs as $key => $autoblog) { + $opml_link='opml'; + $autoblogs_display .= '
+ +
config ini '.$opml_link.' | '.escape($autoblog->site_type).' source: '.escape($autoblog->site_url).'
+
'; + } + } + echo $autoblogs_display; + ?> +
+
+ + ".count($autoblogs)." autoblogs hébergés

"; ?> +
+ Propulsé par Projet Autoblog 0.3 de Mitsu, Oros et Arthur Hoaro (Domaine Public) + 0 ){ echo "
".FOOTER; } ?> + + + + + + + diff --git a/resources/autoblog.css b/resources/autoblog.css new file mode 100644 index 0000000..259e2e8 --- /dev/null +++ b/resources/autoblog.css @@ -0,0 +1,48 @@ +/** + * autoblog.css + * ------------ + * Please do NOT edit this file. Updating your Autoblogs farm will be easier. + * If you want to add your own CSS, use the file user.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[type="text"]{width:20em;} +input[type="radio"] {width:1em;} +input[type="submit"] {width:8em;} +div.form {padding:0.2em;border:1px solid #fff;} +div.form:hover {background-color:#FAF4DA;border:1px dotted;} +#contentVignette {text-align: center;} +.vignette {width:27%;height:2em;display: inline-block;text-align:justify;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;} +.success {color: green;} +.error {color: red;} +.button_list{display:none;} +.button{-moz-box-shadow:inset 0 1px 0 0 #d9fbbe;-webkit-box-shadow:inset 0 1px 0 0 #d9fbbe;box-shadow:inset 0 1px 0 0 #d9fbbe;background:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#b8e356',endColorstr='#a5cc52');background-color:#b8e356;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border:1px solid #83c41a;display:inline-block;color:#fff;font-family:arial;font-size:14px;font-weight:700;text-decoration:none;text-shadow:1px 1px 0 #86ae47;padding:6px 24px;} +.button:hover{background:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#a5cc52',endColorstr='#b8e356');background-color:#a5cc52;} +.button:active{position:relative;top:1px;} +.buttonactive{background-color:#aaa;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border:1px solid #83c41a;display:inline-block;color:#fff;font-family:arial;font-size:14px;font-weight:700;text-decoration:none;text-shadow:1px 1px 0 #86ae47;padding:6px 24px;} +@media screen and (max-width:1024px) { + .vignette { width: 40%; } +} +@media screen and (max-width:640px) { + h1 { font-size:20pt; } + .button, .button:hover, .button:active, .buttonactive { display: block; margin: auto; text-align:center; } + .vignette { width: 80%; } +} +@media screen and (max-width:480px) { + #logo { max-width: 250px; } + input[type="text"]{width:15em;} +} \ No newline at end of file diff --git a/resources/icon-logo.svg b/resources/icon-logo.svg new file mode 100644 index 0000000..e3045dd --- /dev/null +++ b/resources/icon-logo.svg @@ -0,0 +1,218 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/rss.png b/resources/rss.png new file mode 100644 index 0000000000000000000000000000000000000000..315c4f4fa62cb720326ba3f54259666ba3999e42 GIT binary patch literal 691 zcmV;k0!;mhP)bpQb1=l6TxbDZwj&S={?7%qx-u`rsG(Zp`-rh=e^=%((1yvsuf5d=&62Zj)Y zH&JviNS_F4_Hj|T(1j4$p-!}kixP9&dB4uv^MveG?dGf%sUCoc2!IFxD6wHRA2^dX zXRVk!-qSfk(jcaUKn#RP48(whfPlJUpApdrA!TQi_4D+fVoM;3I0gZ8{=Xv~Po;geVA+Em9@0Wq2 zr>OTZEGR05L=gf1T;ucCxq6Q6EgJiH@@-lVaAlQyw`jIF^c=&IVnj|95hHbE_cnt| zTzZQ?F4Ne@(bH(~&3nM%m)I@ID{@jJ2qZPjr)jhpe9hViOwH5k&|T#EmmL3(vHeUQ zq^!t^Al6JD;=mHq^Bg?J-8-zG2Od7gZbknG;K9czYjPqG*xjPo0k(c4%lPXTpw(qq z@aGMnxtFS(np+2kC} z7P02O874ZkJH$v#nCUVx$({yDN`IX@o2wyvTD#e`qN`_w5<}$3F+_ $expire) { + echo "too early"; + die; +} +else { + if( file_exists($lockfile) ) + unlink($lockfile); + + if( file_put_contents($lockfile, date(DATE_RFC822)) ===FALSE) { + echo "Merci d'ajouter des droits d'écriture sur le dossier."; + die; + } +} + +define('ROOT_DIR', __DIR__); +if(file_exists("functions.php")){ + include "functions.php"; +}else{ + echo "functions.php not found !"; + die; +} + +if(file_exists("config.php")){ + include "config.php"; +}else{ + echo "config.php not found !"; + die; +} + +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; +} + +libxml_use_internal_errors(true); + +// $max_exec_time = temps max d'exécution en seconde +function xsafimport($xsafremote, $max_exec_time) { + if( DEBUG ) + 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; + } + + $get_remote_db = ($json_import['meta']['xsaf-db_transfer'] == "true") ? true : false; + $get_remote_media = ($json_import['meta']['xsaf-media_transfer'] == "true") ? true : false; + + if(!empty($json_import['autoblogs'])) { + foreach ($json_import['autoblogs'] as $value) { + + if(count($value)==4 && !empty($value['SITE_TYPE']) && !empty($value['SITE_TITLE']) && !empty($value['SITE_URL']) && !empty($value['FEED_URL'])) { + $sitetype = escape($value['SITE_TYPE']); + $sitename = escape($value['SITE_TITLE']); + $siteurl = escape($value['SITE_URL']); + // Do not use DetectRedirect because it's slow and it has been used when the feed was added + //$rssurl = DetectRedirect(escape($value['FEED_URL'])); + $rssurl = escape($value['FEED_URL']); + } + + + /* TOO SLOW + $xml = simplexml_load_file($rssurl); // quick feed check + // ATOM feed && RSS 1.0 /RDF && RSS 2.0 + $result = (!isset($xml->entry) && !isset($xml->item) && !isset($xml->channel->item)) ? false : true; */ + $result = true; + + /* autoblog */ + if( $result === true ) { + $foldername = urlToFolderSlash($siteurl); + + $errors = createAutoblog($sitetype, $sitename, $siteurl, $rssurl); + foreach( $errors AS $value) { + if( DEBUG ) + echo '

'. $value .'

'; + } + if( empty($errors) && DEBUG ) { + echo '

autoblog '. $sitename .' crée avec succès (DL DB : '. var_dump($get_remote_db) .' - DL media : '. var_dump($get_remote_media) .') : '. $foldername .'

'; + if( !ALLOW_REMOTE_DB_DL && !ALLOW_REMOTE_MEDIA_DL ) + echo ''; + } + + /* ============================================================================================================================================================================== */ + /* récupération de la DB distante */ + if($get_remote_db == true && ALLOW_REMOTE_DB_DL ) { + $remote_db = str_replace("?export", $foldername."/articles.db", $xsafremote); + copy($remote_db, './'. $foldername .'/articles.db'); + } + + if($get_remote_media == true && ALLOW_REMOTE_MEDIA_DL ) { + $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 + //$to_update[] = serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog + } + + if( DEBUG ) + echo '

time : '.($max_exec_time - time()) .'

'; + if(time() >= $max_exec_time) { + if( DEBUG ) + echo "

Time out !

"; + break; + } + } + } + else { + if( DEBUG ) + echo "Format JSON incorrect."; + return false; + } + } + return; +} + +if( DEBUG ) echo ''; +if( ALLOW_NEW_AUTOBLOGS and ALLOW_NEW_AUTOBLOGS_BY_XSAF && !empty($friends_autoblog_farm) ) { + foreach( $friends_autoblog_farm AS $value ) { + if( !empty($value) ) + xsafimport($value, EXEC_TIME); + } + if(DEBUG) echo "

XSAF import finished

"; +} +elseif( DEBUG ) + echo "

XSAF désactivé. Positionnez les variables ALLOW_NEW_AUTOBLOGS et ALLOW_NEW_AUTOBLOGS_BY_XSAF à TRUE dans le fichier config.php pour l'activer.

"; + +if( DEBUG ) echo ''; +?> From d654fb912830ebbc399ec31090fe7e4f99823a92 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 22 Apr 2013 11:18:53 +0200 Subject: [PATCH 11/28] IMPORTANT: Restructuration dans commit precedent - conserver ses donnees : https://github.com/mitsukarenai/Projet-Autoblog/wiki/Mettre-%C3%A0-jour#dev-restructuration-durant-le-dveloppement-03 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a0fa83..53f467d 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ Projet Autoblog serie 0.3 -============== +============== - version VroumVroumBlog 0.3.0 BETA From 0075de55fc5eb26c340dab67885b8deef122b222 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 22 Apr 2013 11:37:07 +0200 Subject: [PATCH 12/28] Version file URL --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index be3c7e4..69a41c1 100755 --- a/index.php +++ b/index.php @@ -132,7 +132,7 @@ function create_from_opml($opml) { **/ function versionCheck() { $versionfile = 'version'; - $lastestUrl = 'https://raw.github.com/mitsukarenai/Projet-Autoblog/master/0.3/version'; + $lastestUrl = 'https://raw.github.com/mitsukarenai/Projet-Autoblog/master/version'; $expire = time() - 84600 ; // 23h30 en secondes $lockfile = '.versionlock'; From c691f224a24849d1545d8bae5b246a9add0e29d8 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 22 Apr 2013 13:30:42 +0300 Subject: [PATCH 13/28] Update README.md --- README.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 53f467d..a4c1d46 100755 --- a/README.md +++ b/README.md @@ -1,18 +1,27 @@ -Projet Autoblog serie 0.3 -============== +Projet Autoblog +=============== -- version VroumVroumBlog 0.3.0 BETA +Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ) -Auteurs: Mitsu (https://www.suumitsu.eu/), Oros (https://www.ecirtam.net/) et Arthur Hoaro (http://hoa.ro) +Branches : + - master (_développement_) : Autoblog Project serie 0.3 par Mitsu, Oros, Arthur Hoaro + - legacy-0.2 : version VroumVroumBlog 0.2.11 par BohwaZ (VVB) & Arthur Hoaro, Mitsukarenai, Oros (index ferme d'autoblogs) + - legacy-0.1 : version VroumVroumBlog 0.1.32 par Sebastien Sauvage + - legacy-0.2to0.3 : script de migration 0.2 to 0.3 par Oros et Arthur Hoaro -Licence: Domaine Public +Nouveautés majeures +=================== -- À propos du Projet Autoblog +- "ferme" d'autoblogs avec ajout facile par différents formulaires (générique, microblogging, OPML, marque-pages) +- échange de références entre fermes avec XSAF (Cross-Site Autoblog Farming) +- vérification du statut des sites distants, et flux de suivi des changements +- export facile des références, articles et médias +- contrôle de version et alerte de mise à jour +- apparence de l'autoblog selon son type +- CSS utilisateur personnalisable +- hébergement de documents spécifiques -lire: http://sebsauvage.net/streisand.me/fr/ +Pré-requis techniques +===================== -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 :) +- serveur web avec PHP 5.3 et son support SQLite From e35e593f749302ec1b1160e37e5a32d2fe77e75b Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 22 Apr 2013 13:33:35 +0300 Subject: [PATCH 14/28] Update README.md --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a4c1d46..90fe2ab 100755 --- a/README.md +++ b/README.md @@ -1,13 +1,9 @@ Projet Autoblog =============== -Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ) +Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ). -Branches : - - master (_développement_) : Autoblog Project serie 0.3 par Mitsu, Oros, Arthur Hoaro - - legacy-0.2 : version VroumVroumBlog 0.2.11 par BohwaZ (VVB) & Arthur Hoaro, Mitsukarenai, Oros (index ferme d'autoblogs) - - legacy-0.1 : version VroumVroumBlog 0.1.32 par Sebastien Sauvage - - legacy-0.2to0.3 : script de migration 0.2 to 0.3 par Oros et Arthur Hoaro +Serie 0.3 par Mitsu, Oros, Arthur Hoaro Nouveautés majeures =================== @@ -21,6 +17,14 @@ Nouveautés majeures - CSS utilisateur personnalisable - hébergement de documents spécifiques +Branches : +=================== + + - [master](https://github.com/mitsukarenai/Projet-Autoblog/tree/master/) _(développement)_ : Autoblog Project serie 0.3 par Mitsu, Oros, Arthur Hoaro + - [legacy-0.2](https://github.com/mitsukarenai/Projet-Autoblog/tree/legacy-0.2) : version VroumVroumBlog 0.2.11 par BohwaZ (VVB) & Arthur Hoaro, Mitsukarenai, Oros (index ferme d'autoblogs) + - [legacy-0.1](https://github.com/mitsukarenai/Projet-Autoblog/tree/legacy-0.1) : version VroumVroumBlog 0.1.32 par Sebastien Sauvage + - [legacy-0.2to0.3](https://github.com/mitsukarenai/Projet-Autoblog/tree/legacy-0.2to0.3) : script de migration 0.2 to 0.3 par Oros et Arthur Hoaro + Pré-requis techniques ===================== From ad27d9a02e9ee3dfb3d521a0d952d35e0ea700af Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 22 Apr 2013 15:57:24 +0200 Subject: [PATCH 15/28] Fixes #23, handle errors, few bugfixes and optimization --- functions.php | 36 ++++++++++--------- index.php | 97 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/functions.php b/functions.php index b1f68d1..735c442 100755 --- a/functions.php +++ b/functions.php @@ -35,7 +35,9 @@ if( !defined('LOGO')) define( 'LOGO', 'icon-logo.svg' ); if( !defined('HEAD_TITLE')) define( 'HEAD_TITLE', ''); if( !defined('FOOTER')) define( 'FOOTER', 'D\'après les premières versions de SebSauvage et Bohwaz.'); -// Functions +/** + * Functions + **/ function NoProtocolSiteURL($url) { $protocols = array("http://", "https://"); $siteurlnoproto = str_replace($protocols, "", $url); @@ -56,15 +58,17 @@ function NoProtocolSiteURL($url) { function DetectRedirect($url) { if(parse_url($url, PHP_URL_HOST)==FALSE) { - //die('Not a URL'); throw new Exception('Not a URL: '. escape ($url) ); } - $response = get_headers($url, 1); + + try { $response = get_headers($url, 1); } + catch (Exception $e) { throw new Exception('RSS URL unreachable: '. escape($url) ); } if(!empty($response['Location'])) { - $response2 = get_headers($response['Location'], 1); + try { $response2 = get_headers($response['Location'], 1); } + catch (Exception $e) { throw new Exception('RSS URL unreachable: '. escape($url) ); } + if(!empty($response2['Location'])) { - //die('too much redirection'); - throw new Exception('too much redirection: '. escape ($url) ); + throw new Exception('Too much redirection: '. escape ($url) ); } else { return $response['Location']; } } @@ -89,7 +93,7 @@ function escape($str) { return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false); } -function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { +function createAutoblog($type, $sitename, $siteurl, $rssurl) { if( $type == 'generic' || empty( $type )) { $var = updateType( $siteurl ); $type = $var['type']; @@ -100,8 +104,7 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { } if(folderExists($siteurl)) { - $error[] = 'Erreur : l\'autoblog '. $sitename .' existe déjà.'; - return $error; + throw new Exception('Erreur : l\'autoblog '. $sitename .' existe déjà.'); } $foldername = AUTOBLOGS_FOLDER . urlToFolderSlash($siteurl); @@ -110,7 +113,7 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { /** * RSS - **/ + * try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); @@ -118,11 +121,11 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { } catch (Exception $e) { ; - } + }*/ $fp = fopen($foldername .'/index.php', 'w+'); if( !fwrite($fp, "") ) - $error[] = "Impossible d'écrire le fichier index.php"; + throw new Exception('Impossible d\'écrire le fichier index.php'); fclose($fp); $fp = fopen($foldername .'/vvb.ini', 'w+'); @@ -135,13 +138,14 @@ FEED_URL="'. $rssurl .'" ARTICLES_PER_PAGE="'. getArticlesPerPage( $type ) .'" UPDATE_INTERVAL="'. getInterval( $type ) .'" UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) - $error[] = "Impossible d'écrire le fichier vvb.ini"; + throw new Exception('Impossible d\'écrire le fichier vvb.ini'); fclose($fp); } else - $error[] = "Impossible de créer le répertoire."; - updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); /* éventuellement une conditionnelle ici: if(empty($error)) ? */ - return $error; + throw new Exception('Impossible de créer le répertoire.'); + + /* @Mitsu: Il faudrait remonter les erreurs d'I/O */ + updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); } function getArticlesPerPage( $type ) { diff --git a/index.php b/index.php index 69a41c1..a9d42ab 100755 --- a/index.php +++ b/index.php @@ -36,6 +36,21 @@ if(file_exists("functions.php")){ die; } +/** + * gets the data from a URL + * http://davidwalsh.name/curl-download + **/ +function get_data($url) { + $ch = curl_init(); + $timeout = 5; + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + $data = curl_exec($ch); + curl_close($ch); + return $data; +} + function get_title_from_feed($url) { return get_title_from_datafeed(file_get_contents($url)); } @@ -105,19 +120,28 @@ function check_antibot($number, $text_number) { function create_from_opml($opml) { global $error, $success; - + $cpt = 0; foreach( $opml->body->outline as $outline ) { if ( !empty( $outline['title'] ) && !empty( $outline['text'] ) && !empty( $outline['xmlUrl']) && !empty( $outline['htmlUrl'] )) { try { - $rssurl = DetectRedirect(escape( $outline['xmlUrl'])); - $sitename = escape( $outline['title'] ); $siteurl = escape($outline['htmlUrl']); - $sitetype = escape($outline['text']); if ( $sitetype == 'generic' or $sitetype == 'microblog' or $sitetype == 'shaarli') { } else { $sitetype = 'generic'; } + + // Lighten process by checking folderExists first + // A CHANGER SELON ISSUE #20 + if(folderExists($siteurl)) + throw new Exception('Erreur : l\'autoblog '. $sitename .' existe déjà.'); + + $sitetype = escape($outline['text']); + if ( $sitetype != 'microblog' && $sitetype != 'shaarli' && $sitetype != 'twitter' && $sitetype != 'identica' ) + $sitetype = 'generic'; + + $rssurl = DetectRedirect(escape($outline['xmlUrl'])); - $error = array_merge( $error, createAutoblog( $sitetype, $sitename, $siteurl, $rssurl, $error ) ); - - if( empty ( $error )) + createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); + + // Do not print iframe on big import (=> heavy and useless) + if( ++$cpt < 10 ) $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; } catch (Exception $e) { @@ -438,7 +462,8 @@ if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOG $sitetype = updateType($siteurl); // Disabled input doesn't send POST data $sitetype = $sitetype['type']; - $error = array_merge( $error, createAutoblog($sitetype, $sitename, $siteurl, $rssurl, $error)); + createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); + if( empty($error)) { $form .= ''; $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; @@ -500,16 +525,16 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ if($socialinstance === 'twitter') { if( API_TWITTER !== FALSE ) { $sitetype = 'twitter'; - $siteurl = "http://twitter.com/$socialaccount"; + $siteurl = 'http://twitter.com/$socialaccount'; $rssurl = API_TWITTER.$socialaccount; } else - $error[] = "Twitter veut mettre à mort son API ouverte. Du coup on peut plus faire ça comme ça."; + $error[] = 'Vous devez définir une API Twitter -> RSS dans votre fichier de configuration (see TwitterBridge).'; } elseif($socialinstance === 'identica') { $sitetype = 'identica'; - $siteurl = "http://identi.ca/$socialaccount"; - $rssurl = "http://identi.ca/api/statuses/user_timeline/$socialaccount.rss"; + $siteurl = 'http://identi.ca/$socialaccount'; + $rssurl = 'http://identi.ca/api/statuses/user_timeline/$socialaccount.rss'; } elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { $sitetype = 'microblog'; @@ -535,18 +560,22 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ $socialaccount = get_title_from_feed($rssurl); } + if( empty($error) ) { - // Twitterbridge do NOT allow this user yet => No check - if( $sitetype != 'twitter' ) { - $headers = get_headers($rssurl, 1); - if (strpos($headers[0], '200') == FALSE) { - $error[] = "Flux inaccessible (compte inexistant ?)"; + try { + // TwitterBridge user will be allowed after Autoblog creation + // TODO: Twitter user does not exist ? + if($sitetype != 'twitter') { + $headers = get_headers($rssurl, 1); + if (strpos($headers[0], '200') === FALSE) + throw new Exception('Flux inaccessible (compte inexistant ?)'); } + + createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl); + $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; } - if( empty($error) ) { - $error = array_merge( $error, createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl, $error)); - if( empty($error)) - $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; + catch (Exception $e) { + echo $error[] = $e->getMessage(); } } } @@ -574,10 +603,9 @@ if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_L $siteurl = escape($_POST['siteurl']); $sitename = get_title_from_feed($rssurl); - $error = array_merge( $error, createAutoblog('generic', $sitename, $siteurl, $rssurl, $error)); + createAutoblog('generic', $sitename, $siteurl, $rssurl); - if( empty($error)) - $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; + $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; } else { // checking procedure @@ -647,7 +675,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY if(parse_url($opml_url, PHP_URL_HOST)==FALSE) { $error[] = "URL du fichier OPML non valide."; } else { - if ( ($opml = simplexml_load_file( $opml_url )) !== false ) { + if ( ($opml = simplexml_load_string( get_data($opml_url) )) !== false ) { create_from_opml($opml); } else { $error[] = "Impossible de lire le contenu du fichier OPML ou d'accéder à l'URL donnée."; @@ -678,10 +706,10 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY

- '; - ?> + '; + ?>

Présentation

@@ -694,6 +722,11 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY Voici une liste d'autoblogs hébergés sur (plus d'infos sur le projet).

+ +

+ Autres fermes + → Rechercher +

@@ -849,11 +882,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY

Autoblogs hébergés rss

-

- Autres fermes - → Rechercher -

- +
Date: Mon, 22 Apr 2013 15:59:55 +0200 Subject: [PATCH 16/28] Restore RSS feed until JSON RSS --- functions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions.php b/functions.php index 735c442..262fde7 100755 --- a/functions.php +++ b/functions.php @@ -113,15 +113,15 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl) { /** * RSS - * + */ try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? require_once('class_rssfeed.php'); $rss = new AutoblogRSS(RSS_FILE); $rss->addNewAutoblog($sitename, $foldername, $siteurl, $rssurl); } catch (Exception $e) { - ; - }*/ + ; // DO NOTHING + } $fp = fopen($foldername .'/index.php', 'w+'); if( !fwrite($fp, "") ) From e220d1760db2b4236ddbe3b0928fbfdadb023a32 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 22 Apr 2013 16:09:49 +0200 Subject: [PATCH 17/28] Bugfix --- index.php | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/index.php b/index.php index a9d42ab..9b82113 100755 --- a/index.php +++ b/index.php @@ -36,21 +36,6 @@ if(file_exists("functions.php")){ die; } -/** - * gets the data from a URL - * http://davidwalsh.name/curl-download - **/ -function get_data($url) { - $ch = curl_init(); - $timeout = 5; - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); - $data = curl_exec($ch); - curl_close($ch); - return $data; -} - function get_title_from_feed($url) { return get_title_from_datafeed(file_get_contents($url)); } @@ -140,9 +125,11 @@ function create_from_opml($opml) { createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); + $message = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; // Do not print iframe on big import (=> heavy and useless) if( ++$cpt < 10 ) - $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; + $message .= '' + $success[] = $message; } catch (Exception $e) { $error[] = $e->getMessage(); @@ -675,7 +662,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY if(parse_url($opml_url, PHP_URL_HOST)==FALSE) { $error[] = "URL du fichier OPML non valide."; } else { - if ( ($opml = simplexml_load_string( get_data($opml_url) )) !== false ) { + if ( ($opml = simplexml_load_file( $opml_url )) !== false ) { create_from_opml($opml); } else { $error[] = "Impossible de lire le contenu du fichier OPML ou d'accéder à l'URL donnée."; From 43d9a5dd9d6775e5254338a9d33f630bc6801c93 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 22 Apr 2013 16:11:58 +0200 Subject: [PATCH 18/28] -_-; --- index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 9b82113..bfceded 100755 --- a/index.php +++ b/index.php @@ -128,8 +128,8 @@ function create_from_opml($opml) { $message = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; // Do not print iframe on big import (=> heavy and useless) if( ++$cpt < 10 ) - $message .= '' - $success[] = $message; + $message .= ''; + $success[] = $message; } catch (Exception $e) { $error[] = $e->getMessage(); From e982da76b7f439d38d704e6cd6aa4b7ec7b8feb6 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Thu, 25 Apr 2013 11:34:34 +0200 Subject: [PATCH 19/28] =?UTF-8?q?catch=20exception=20=C3=A9criture=20rss.j?= =?UTF-8?q?son?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/functions.php b/functions.php index 262fde7..d3c601a 100755 --- a/functions.php +++ b/functions.php @@ -145,7 +145,9 @@ UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) throw new Exception('Impossible de créer le répertoire.'); /* @Mitsu: Il faudrait remonter les erreurs d'I/O */ - updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); + /* Comme ça ? :) */ + if(updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl) === FALSE) + { throw new Exception('Impossible d\'écrire le fichier rss.json'); } } function getArticlesPerPage( $type ) { @@ -254,7 +256,9 @@ $json[] = array( 'status'=>$status, 'response_code'=>$response_code ); -file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX); +if(file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX) === FALSE) + { return FALSE; } + else { return TRUE; } } function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { From d7675c0edbb82aad820b12106fb827697e34d5ce Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Thu, 25 Apr 2013 13:02:33 +0200 Subject: [PATCH 20/28] fix issue #24 en attendant mieux regex --- autoblogs/autoblog.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autoblogs/autoblog.php b/autoblogs/autoblog.php index 87a8b28..16b8063 100644 --- a/autoblogs/autoblog.php +++ b/autoblogs/autoblog.php @@ -498,11 +498,11 @@ class VroumVroum_Blog $from['path'] = ''; } - preg_match_all('!(src|href)\s*=\s*[\'"]?([^"\'<>\s]+\.(?:'.$extensions.'))[\'"]?!i', $content, $match, PREG_SET_ORDER); + preg_match_all('!(src|href)\s*=\s*[\'"]?([^"\'<>\s]+\.(?:'.$extensions.')[\'"])[\'"]?!i', $content, $match, PREG_SET_ORDER); foreach ($match as $m) { - $url = parse_url($m[2]); + $url = parse_url(substr($m[2], 0, -1)); if (empty($url['scheme'])) $url['scheme'] = $from['scheme']; From c7741165f488b7fe07c24923e2f68003e62fadc2 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 26 Apr 2013 22:42:51 +0200 Subject: [PATCH 21/28] =?UTF-8?q?Euh...=20j'avais=20oubli=C3=A9=20de=20com?= =?UTF-8?q?mit=20quelque=20chose=20=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions.php | 18 ++++++++---------- index.php | 39 +++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/functions.php b/functions.php index b1f68d1..ec49743 100755 --- a/functions.php +++ b/functions.php @@ -56,14 +56,12 @@ function NoProtocolSiteURL($url) { function DetectRedirect($url) { if(parse_url($url, PHP_URL_HOST)==FALSE) { - //die('Not a URL'); throw new Exception('Not a URL: '. escape ($url) ); } $response = get_headers($url, 1); if(!empty($response['Location'])) { $response2 = get_headers($response['Location'], 1); if(!empty($response2['Location'])) { - //die('too much redirection'); throw new Exception('too much redirection: '. escape ($url) ); } else { return $response['Location']; } @@ -89,7 +87,7 @@ function escape($str) { return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false); } -function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { +function createAutoblog($type, $sitename, $siteurl, $rssurl) { if( $type == 'generic' || empty( $type )) { $var = updateType( $siteurl ); $type = $var['type']; @@ -100,8 +98,7 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { } if(folderExists($siteurl)) { - $error[] = 'Erreur : l\'autoblog '. $sitename .' existe déjà.'; - return $error; + throw new Exception('Erreur : l\'autoblog '. $sitename .' existe déjà.'); } $foldername = AUTOBLOGS_FOLDER . urlToFolderSlash($siteurl); @@ -122,7 +119,7 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl, $error = array()) { $fp = fopen($foldername .'/index.php', 'w+'); if( !fwrite($fp, "") ) - $error[] = "Impossible d'écrire le fichier index.php"; + throw new Exception('Impossible d\'écrire le fichier index.php'); fclose($fp); $fp = fopen($foldername .'/vvb.ini', 'w+'); @@ -135,13 +132,14 @@ FEED_URL="'. $rssurl .'" ARTICLES_PER_PAGE="'. getArticlesPerPage( $type ) .'" UPDATE_INTERVAL="'. getInterval( $type ) .'" UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) - $error[] = "Impossible d'écrire le fichier vvb.ini"; + throw new Exception('Impossible d\'écrire le fichier vvb.ini'); fclose($fp); } else - $error[] = "Impossible de créer le répertoire."; - updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); /* éventuellement une conditionnelle ici: if(empty($error)) ? */ - return $error; + throw new Exception('Impossible de créer le répertoire.'); + + /* @Mitsu: Il faudrait remonter les erreurs d'I/O */ + updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); } function getArticlesPerPage( $type ) { diff --git a/index.php b/index.php index 69a41c1..788fcbb 100755 --- a/index.php +++ b/index.php @@ -113,9 +113,11 @@ function create_from_opml($opml) { $sitename = escape( $outline['title'] ); $siteurl = escape($outline['htmlUrl']); - $sitetype = escape($outline['text']); if ( $sitetype == 'generic' or $sitetype == 'microblog' or $sitetype == 'shaarli') { } else { $sitetype = 'generic'; } + $sitetype = escape($outline['text']); + if ( $sitetype != 'microblog' && $sitetype != 'shaarli' && $sitetype != 'twitter' && $sitetype != 'identica' ) + $sitetype = 'generic'; - $error = array_merge( $error, createAutoblog( $sitetype, $sitename, $siteurl, $rssurl, $error ) ); + createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); if( empty ( $error )) $success[] = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; @@ -438,7 +440,8 @@ if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOG $sitetype = updateType($siteurl); // Disabled input doesn't send POST data $sitetype = $sitetype['type']; - $error = array_merge( $error, createAutoblog($sitetype, $sitename, $siteurl, $rssurl, $error)); + createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); + if( empty($error)) { $form .= ''; $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; @@ -500,16 +503,16 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ if($socialinstance === 'twitter') { if( API_TWITTER !== FALSE ) { $sitetype = 'twitter'; - $siteurl = "http://twitter.com/$socialaccount"; + $siteurl = 'http://twitter.com/$socialaccount'; $rssurl = API_TWITTER.$socialaccount; } else - $error[] = "Twitter veut mettre à mort son API ouverte. Du coup on peut plus faire ça comme ça."; + $error[] = 'Vous devez définir une API Twitter -> RSS dans votre fichier de configuration (see TwitterBridge).'; } elseif($socialinstance === 'identica') { $sitetype = 'identica'; - $siteurl = "http://identi.ca/$socialaccount"; - $rssurl = "http://identi.ca/api/statuses/user_timeline/$socialaccount.rss"; + $siteurl = 'http://identi.ca/$socialaccount'; + $rssurl = 'http://identi.ca/api/statuses/user_timeline/$socialaccount.rss'; } elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { $sitetype = 'microblog'; @@ -535,18 +538,19 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ $socialaccount = get_title_from_feed($rssurl); } + if( empty($error) ) { - // Twitterbridge do NOT allow this user yet => No check - if( $sitetype != 'twitter' ) { + try { $headers = get_headers($rssurl, 1); - if (strpos($headers[0], '200') == FALSE) { - $error[] = "Flux inaccessible (compte inexistant ?)"; + if (strpos($headers[0], '200') === FALSE) { + throw new Exception('Flux inaccessible (compte inexistant ?)'); } + + createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl); + $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; } - if( empty($error) ) { - $error = array_merge( $error, createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl, $error)); - if( empty($error)) - $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; + catch (Exception $e) { + echo $error[] = $e->getMessage(); } } } @@ -574,10 +578,9 @@ if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_L $siteurl = escape($_POST['siteurl']); $sitename = get_title_from_feed($rssurl); - $error = array_merge( $error, createAutoblog('generic', $sitename, $siteurl, $rssurl, $error)); + createAutoblog('generic', $sitename, $siteurl, $rssurl); - if( empty($error)) - $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; + $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; } else { // checking procedure From d9e6c5bcf8eb86d6de6aa3b621b22743bffa973e Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 29 Apr 2013 14:21:17 +0300 Subject: [PATCH 22/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90fe2ab..02d5b2e 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Projet Autoblog Création, gestion et échange de blogs automatiques contre la censure (à propos: http://sebsauvage.net/streisand.me/fr/ ). -Serie 0.3 par Mitsu, Oros, Arthur Hoaro +Serie 0.3 par [Mitsu](https://github.com/mitsukarenai/), [Oros](https://github.com/Oros42), [Arthur Hoaro](https://github.com/ArthurHoaro). Nouveautés majeures =================== From d47dd18f3aaacfc3cb3ec8ff46b2acd74441898e Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 29 Apr 2013 22:06:31 +0200 Subject: [PATCH 23/28] fixes #20 (foldername) and begin change to rss.json WARNING: You really need to take a look at https://github.com/mitsukarenai/Projet-Autoblog/wiki/Mettre-%C3%A0-jour before updating --- .gitignore | 1 + functions.php | 35 ++++++++++----------------- index.php | 33 +++++++++---------------- version | 2 +- xsaf3.php | 67 +++++++++++++++++++++++++++------------------------ 5 files changed, 62 insertions(+), 76 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 version diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index bba9c93..79c93a2 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ config.php .versionlock .xsaflock resources/rss.xml +resources/rss.json .project resources/user.css autoblogs/* diff --git a/functions.php b/functions.php index d3c601a..8d4ffec 100755 --- a/functions.php +++ b/functions.php @@ -13,6 +13,7 @@ if (!defined('AUTOBLOGS_FOLDER')) define('AUTOBLOGS_FOLDER', './autoblogs/'); if (!defined('DOC_FOLDER')) define('DOC_FOLDER', './docs/'); if (!defined('RESOURCES_FOLDER')) define('RESOURCES_FOLDER', './resources/'); if (!defined('RSS_FILE')) define('RSS_FILE', RESOURCES_FOLDER.'rss.xml'); +if (!defined('FOLDER_MAX_LENGTH')) define('FOLDER_MAX_LENGTH', 80); date_default_timezone_set('Europe/Paris'); setlocale(LC_TIME, 'fr_FR.UTF-8', 'fr_FR', 'fr'); @@ -77,16 +78,16 @@ function DetectRedirect($url) } } -function urlToFolder($url) { - return sha1(NoProtocolSiteURL($url)); +function urlHash($rssurl) { + return sha1(NoProtocolSiteURL($rssurl)); } -function urlToFolderSlash($url) { - return sha1(NoProtocolSiteURL($url).'/'); +function urlToFolder($siteurl, $rssurl) { + return AUTOBLOGS_FOLDER . substr(preg_replace("/[^a-z0-9]/", '', strtolower(NoProtocolSiteURL($siteurl))), 0, FOLDER_MAX_LENGTH) .'_'. urlHash($rssurl) .'/'; } -function folderExists($url) { - return file_exists(AUTOBLOGS_FOLDER . urlToFolder($url)) || file_exists(AUTOBLOGS_FOLDER . urlToFolderSlash($url)); +function folderExists($siteurl, $rssurl) { + return file_exists(urlToFolder($siteurl, $rssurl)); } function escape($str) { @@ -103,25 +104,13 @@ function createAutoblog($type, $sitename, $siteurl, $rssurl) { } } - if(folderExists($siteurl)) { + if(folderExists($siteurl, $rssurl)) { throw new Exception('Erreur : l\'autoblog '. $sitename .' existe déjà.'); } - $foldername = AUTOBLOGS_FOLDER . urlToFolderSlash($siteurl); + $foldername = urlToFolder($siteurl, $rssurl); if ( mkdir($foldername, 0755, false) ) { - - /** - * RSS - */ - try { // à déplacer après la tentative de création de l'autoblog crée avec succès ? - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addNewAutoblog($sitename, $foldername, $siteurl, $rssurl); - } - catch (Exception $e) { - ; // DO NOTHING - } $fp = fopen($foldername .'/index.php', 'w+'); if( !fwrite($fp, "") ) @@ -146,8 +135,10 @@ UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) /* @Mitsu: Il faudrait remonter les erreurs d'I/O */ /* Comme ça ? :) */ - if(updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl) === FALSE) - { throw new Exception('Impossible d\'écrire le fichier rss.json'); } + /* Arthur 29/04/13 : En fait c'était une mauvaise idée : on rend de nouveau bloquant l'écrire du flux RSS, qui est une feature mineure */ + // if(updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl) === FALSE) + // { throw new Exception('Impossible d\'écrire le fichier rss.json'); } + updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); } function getArticlesPerPage( $type ) { diff --git a/index.php b/index.php index bfceded..f963cb4 100755 --- a/index.php +++ b/index.php @@ -125,10 +125,10 @@ function create_from_opml($opml) { createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); - $message = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; + $message = 'Autoblog "'. $sitename .'" crée avec succès. → afficher l\'autoblog.'; // Do not print iframe on big import (=> heavy and useless) if( ++$cpt < 10 ) - $message .= ''; + $message .= ''; $success[] = $message; } catch (Exception $e) { @@ -171,24 +171,13 @@ function versionCheck() { /** * RSS Feed +* **/ -if( !file_exists(RSS_FILE)) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->create('Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : ''), serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.", serverUrl(true) . RSS_FILE); -} -if (isset($_GET['rss'])) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->displayXML(); - die; -} - if( !file_exists(RESOURCES_FOLDER.'rss.json')) { file_put_contents(RESOURCES_FOLDER.'rss.json', '', LOCK_EX); } -if (isset($_GET['rss_tmp'])) { +if (isset($_GET['rss'])) { displayXML_tmp(); die; } @@ -452,8 +441,8 @@ if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOG createAutoblog( $sitetype, $sitename, $siteurl, $rssurl ); if( empty($error)) { - $form .= ''; - $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; + $form .= ''; + $form .= '

Autoblog '. $sitename .' ajouté avec succès.
'; } else { $form .= '

    '; @@ -559,7 +548,8 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ } createAutoblog($sitetype, ucfirst($socialinstance) .' - '. $socialaccount, $siteurl, $rssurl); - $success[] = ''.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; + $success[] = ' + '.ucfirst($socialinstance) .' - '. $socialaccount.' ajouté avec succès.'; } catch (Exception $e) { echo $error[] = $e->getMessage(); @@ -592,7 +582,8 @@ if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_L createAutoblog('generic', $sitename, $siteurl, $rssurl); - $success[] = 'Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; + $success[] = ' + Autoblog '. $sitename .' crée avec succès.afficher l\'autoblog'; } else { // checking procedure @@ -605,7 +596,7 @@ if( !empty($_POST['generic']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_L $siteurl = get_link_from_datafeed($datafeed); $sitename = get_title_from_datafeed($datafeed); - $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire.
    + $form = 'Merci de vérifier les informations suivantes, corrigez si nécessaire. Tous les champs doivent être renseignés.


    @@ -678,7 +669,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY Projet Autoblog<?php if(strlen(HEAD_TITLE)>0) echo " | " . HEAD_TITLE; ?> - + '. $value .'

    '; - } - if( empty($errors) && DEBUG ) { - echo '

    autoblog '. $sitename .' crée avec succès (DL DB : '. var_dump($get_remote_db) .' - DL media : '. var_dump($get_remote_media) .') : '. $foldername .'

    '; - if( !ALLOW_REMOTE_DB_DL && !ALLOW_REMOTE_MEDIA_DL ) - echo ''; - } + try { + createAutoblog($sitetype, $sitename, $siteurl, $rssurl); - /* ============================================================================================================================================================================== */ - /* récupération de la DB distante */ - if($get_remote_db == true && ALLOW_REMOTE_DB_DL ) { - $remote_db = str_replace("?export", $foldername."/articles.db", $xsafremote); - copy($remote_db, './'. $foldername .'/articles.db'); - } + if( DEBUG ) { + echo '

    autoblog '. $sitename .' crée avec succès (DL DB : '. var_dump($get_remote_db) .' - DL media : '. var_dump($get_remote_media) .') : '. $foldername .'

    '; + if( !ALLOW_REMOTE_DB_DL && !ALLOW_REMOTE_MEDIA_DL ) + echo ''; + } - if($get_remote_media == true && ALLOW_REMOTE_MEDIA_DL ) { - $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); + /* ============================================================================================================================================================================== */ + /* récupération de la DB distante */ + if($get_remote_db == true && ALLOW_REMOTE_DB_DL ) { + $remote_db = str_replace("?export", $foldername."/articles.db", $xsafremote); + copy($remote_db, './'. $foldername .'/articles.db'); + } + + if($get_remote_media == true && ALLOW_REMOTE_MEDIA_DL ) { + $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 - //$to_update[] = serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog + /* ============================================================================================================================================================================== */ + //TODO : tester si articles.db est une DB valide + //$to_update[] = serverUrl().preg_replace("/(.*)\/(.*)$/i","$1/".$foldername , $_SERVER['SCRIPT_NAME']); // url of the new autoblog + } + catch (Exception $e) { + if( DEBUG ) + echo $e->getMessage(); + } } if( DEBUG ) From 21bdae95cf742ce3d64fe86cb6fa8b28e9b1102f Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Mon, 29 Apr 2013 22:32:03 +0200 Subject: [PATCH 24/28] (cassera ? cassera pas ?) --- class_rssfeed.php | 277 ---------------------------------------------- functions.php | 14 +-- index.php | 15 +-- 3 files changed, 7 insertions(+), 299 deletions(-) delete mode 100755 class_rssfeed.php diff --git a/class_rssfeed.php b/class_rssfeed.php deleted file mode 100755 index 59fd431..0000000 --- a/class_rssfeed.php +++ /dev/null @@ -1,277 +0,0 @@ - - * - * + 03/2013 - * Few changes, AutoblogRSS and FileRSSFeed - * @author Arthur Hoaro - */ -class RSSFeed { - protected $xml; - - /** - * Construct a RSS feed - */ - public function __construct() { - $template = << - - - - -END; - - $this->xml = new SimpleXMLElement($template); - } - - /** - * Set RSS Feed headers - * @param $title the title of the feed - * @param $link link to the website where you can find the RSS feed - * @param $description a description of the RSS feed - * @param $rsslink the link to this RSS feed - */ - public function setHeaders($title, $link, $description, $rsslink) { - $atomlink = $this->xml->channel->addChild("atom:link","","http://www.w3.org/2005/Atom"); - $atomlink->addAttribute("href",$rsslink); - $atomlink->addAttribute("rel","self"); - $atomlink->addAttribute("type","application/rss+xml"); - - $this->xml->channel->title = $title; - $this->xml->channel->link = $link; - $this->xml->channel->description = $description; - } - - /** - * Set the language of the RSS feed - * @param $lang the language of the RSS feed - */ - public function setLanguage($lang) { - $this->xml->channel->addChild("language",$lang); - } - /** - * Adds a picture to the RSS feed - * @param $url URL to the image - * @param $title The image title. Usually same as the RSS feed's title - * @param $link Where the image should link to. Usually same as the RSS feed's link - */ - public function setImage($url, $title, $link) { - $image = $this->xml->channel->addChild("image"); - $image->url = $url; - $image->title = $title; - $image->link = $link; - } - /** - * Add a item to the RSS feed - * @param $title The title of the RSS feed - * @param $link Link to the item's url - * @param $description The description of the item - * @param $author The author who wrote this item - * @param $guid Unique ID for this post - * @param $timestamp Unix timestamp for making a date - */ - public function addItem($title, $link, $description, $author, $guid, $timestamp) { - $item = $this->xml->channel->addChild("item"); - $item->title = $title; - $item->description = $description; - $item->link = $link; - $item->guid = $guid; - if( isset($guid['isPermaLink'])) - $item->guid['isPermaLink'] = $guid['isPermaLink']; - if( !empty( $author) ) - $item->author = $author; - $item->pubDate = date(DATE_RSS,intval($timestamp)); - } - /** - * Displays the RSS feed - */ - public function displayXML() { - header('Content-type: application/rss+xml; charset=utf-8'); - echo $this->xml->asXML(); - exit; - } - - public function getXML() { - return $this->xml; - } -} - -class RSSMerger { - private $feeds = array(); - - /** - * Constructs a RSSmerger object - */ - function __construct() { - - } - - /** - * Populates the feeds array from the given url which is a rss feed - * @param $url - */ - function add($xml) { - - foreach($xml->channel->item as $item) { - $item->sitetitle = $xml->channel->title; - $item->sitelink = $xml->channel->link; - - preg_match("/^[A-Za-z]{3}, ([0-9]{2}) ([A-Za-z]{3}) ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([\+|\-]?[0-9]{4})$/", $item->pubDate, $match); - $item->time = time($match[4]+($match[6]/100),$match[5],$match[6],date("m",strtotime($match[2])),$match[1],$match[3]); - - $this->feeds[] = $item; - } - } - /** - * Comparing function for sorting the feeds - * @param $value1 - * @param $value2 - */ - function feeds_cmp($value1,$value2) { - if(intval($value1->time) == intval($value2->time)) - return 0; - - return (intval($value1->time) < intval($value2->time)) ? +1 : -1; - } - - /** - * Sorts the feeds array using the Compare function feeds_cmp - */ - function sort() { - usort($this->feeds,Array("RssMerger","feeds_cmp")); - } - - /** - * This function return the feed items. - * @param $limit how many feed items that should be returned - * @return the feeds array - */ - function getFeeds($limit) { - return array_slice($this->feeds,0,$limit); - } -} - -class FileRSSFeed extends RSSFeed { - protected $filename; - - public function __construct($filename) { - parent::__construct(); - $this->filename = $filename; - - $this->load(); - } - - public function load() { - if ( file_exists( $this->filename )) { - $this->xml = simplexml_load_file($this->filename); - } - } - - public function create($title, $link, $description, $rsslink) { - parent::setHeaders($title, $link, $description, $rsslink); - $this->write(); - } - - public function addItem($title, $link, $description, $author, $guid, $timestamp) { - parent::addItem($title, $link, $description, $author, $guid, $timestamp); - $this->write(); - } - - private function write() { - if ( file_exists( $this->filename )) { - unlink($this->filename); - } - - $outputXML = new RSSFeed(); - foreach($this->xml->channel->item as $f) { - $item = $outputXML->addItem($f->title,$f->link,$f->description,$f->author,$f->guid, strtotime($f->pubDate)); - } - - $merger = new RssMerger(); - $merger->add($outputXML->getXML()); - $merger->sort(); - - unset($this->xml->channel->item); - foreach($merger->getFeeds(20) as $f) { - parent::addItem($f->title,$f->link,$f->description,$f->author,$f->guid,$f->time); - } - - file_put_contents( $this->filename, $this->xml->asXML(), LOCK_EX ); - } -} - -class AutoblogRSS extends FileRSSFeed { - public function __construct($filename) { - parent::__construct($filename); - } - - public function addUnavailable($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" est indisponible', $autobHref, - 'Autoblog: '.$title.'
    - Site: '. $siteurl .'
    - RSS: '.$rssurl.'
    - Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addAvailable($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" est de nouveau disponible', $autobHref, - 'Autoblog : '.$title.'
    - Site: '. $siteurl .'
    - RSS: '.$rssurl.'
    - Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addCodeChanged($title, $folder, $siteurl, $rssurl, $code) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" a renvoyé un code imprévu', $autobHref, - 'Code: '. $code .'
    - Autoblog : '.$title.'
    - Site: '. $siteurl .'
    - RSS: '.$rssurl.'
    - Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } - - public function addNewAutoblog($title, $folder, $siteurl, $rssurl) { - $path = pathinfo( $_SERVER['PHP_SELF'] ); - $autobHref = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'. - $_SERVER["SERVER_NAME"].':'.$_SERVER["SERVER_PORT"]. $path['dirname'].'/'.$folder; - - parent::addItem( 'L\'autoblog "'. $title.'" a été ajouté à la ferme', $autobHref, - 'Autoblog : '.$title.'
    - Site: '. $siteurl .'
    - RSS: '.$rssurl.'
    - Folder: '. $folder , - 'admin@'.$_SERVER['SERVER_NAME'], - $autobHref, - time() - ); - } -} - -?> diff --git a/functions.php b/functions.php index 8d4ffec..2e3496f 100755 --- a/functions.php +++ b/functions.php @@ -12,7 +12,6 @@ define('LOCAL_URI', ''); if (!defined('AUTOBLOGS_FOLDER')) define('AUTOBLOGS_FOLDER', './autoblogs/'); if (!defined('DOC_FOLDER')) define('DOC_FOLDER', './docs/'); if (!defined('RESOURCES_FOLDER')) define('RESOURCES_FOLDER', './resources/'); -if (!defined('RSS_FILE')) define('RSS_FILE', RESOURCES_FOLDER.'rss.xml'); if (!defined('FOLDER_MAX_LENGTH')) define('FOLDER_MAX_LENGTH', 80); date_default_timezone_set('Europe/Paris'); setlocale(LC_TIME, 'fr_FR.UTF-8', 'fr_FR', 'fr'); @@ -133,11 +132,6 @@ UPDATE_TIMEOUT="'. getTimeout( $type ) .'"') ) else throw new Exception('Impossible de créer le répertoire.'); - /* @Mitsu: Il faudrait remonter les erreurs d'I/O */ - /* Comme ça ? :) */ - /* Arthur 29/04/13 : En fait c'était une mauvaise idée : on rend de nouveau bloquant l'écrire du flux RSS, qui est une feature mineure */ - // if(updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl) === FALSE) - // { throw new Exception('Impossible d\'écrire le fichier rss.json'); } updateXML('new_autoblog_added', 'new', $foldername, $sitename, $siteurl, $rssurl); } @@ -252,7 +246,7 @@ if(file_put_contents(RESOURCES_FOLDER.'rss.json', json_encode($json), LOCK_EX) = else { return TRUE; } } -function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { +function displayXMLstatus($status, $response_code, $autoblog_url, $autoblog_title, $autoblog_sourceurl, $autoblog_sourcefeed) { switch ($status) { case 'unavailable': @@ -270,17 +264,17 @@ function displayXMLstatus_tmp($status, $response_code, $autoblog_url, $autoblog_ } } -function displayXML_tmp() { +function displayXML() { header('Content-type: application/rss+xml; charset=utf-8'); echo ' '.serverUrl(true).''; -echo 'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; +echo 'Projet Autoblog'. ((strlen(HEAD_TITLE)>0) ? ' | '. HEAD_TITLE : '').''.serverUrl(true),"Projet Autoblog - RSS : Ajouts et changements de disponibilité.".''; if(file_exists(RESOURCES_FOLDER.'rss.json')) { $json = json_decode(file_get_contents(RESOURCES_FOLDER.'rss.json'), true); foreach ($json as $item) { - $description = displayXMLstatus_tmp($item['status'],$item['response_code'],$item['autoblog_url'],$item['autoblog_title'],$item['autoblog_sourceurl'],$item['autoblog_sourcefeed']); + $description = displayXMLstatus($item['status'],$item['response_code'],$item['autoblog_url'],$item['autoblog_title'],$item['autoblog_sourceurl'],$item['autoblog_sourcefeed']); $link = serverUrl(true).AUTOBLOGS_FOLDER.$item['autoblog_url']; $date = date("r", $item['timestamp']); print <<addUnavailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); updateXML('unavailable', 'nxdomain', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, '..'); @@ -235,9 +232,6 @@ if (isset($_GET['check'])) /* code retour 200: flux disponible */ if($code[1] == "200") { if( $oldvalue !== null && $oldvalue != '' ) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addAvailable($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL']); updateXML('available', '200', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, ''); @@ -246,9 +240,6 @@ if (isset($_GET['check'])) /* autre code retour: un truc a changé (redirection, changement de CMS, .. bref vvb.ini doit être corrigé) */ else { if( $oldvalue !== null && $oldvalue != '.' ) { - require_once('class_rssfeed.php'); - $rss = new AutoblogRSS(RSS_FILE); - $rss->addCodeChanged($ini['SITE_TITLE'], escape($_GET['check']), $ini['SITE_URL'], $ini['FEED_URL'], $code[1]); updateXML('moved', '3xx', escape($_GET['check']), $ini['SITE_TITLE'], $ini['SITE_URL'], $ini['FEED_URL']); } file_put_contents($errorlog, '.'); @@ -355,7 +346,6 @@ if (isset($_GET['exportopml'])) // OPML /** * Site map - * NEW AUTOBLOG FOLDER - Need update **/ if (isset($_GET['sitemap'])) { @@ -541,6 +531,7 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ try { // TwitterBridge user will be allowed after Autoblog creation // TODO: Twitter user does not exist ? + // TODO: get remote like http://wwz.suumitsu.eu/twitter/whitelist.json, decode, check if is in array, return error or continue if($sitetype != 'twitter') { $headers = get_headers($rssurl, 1); if (strpos($headers[0], '200') === FALSE) @@ -669,7 +660,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY Projet Autoblog<?php if(strlen(HEAD_TITLE)>0) echo " | " . HEAD_TITLE; ?> - + Date: Mon, 29 Apr 2013 23:32:39 +0200 Subject: [PATCH 25/28] #20 socialinstace --- index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.php b/index.php index f963cb4..738f3cf 100755 --- a/index.php +++ b/index.php @@ -501,7 +501,7 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ if($socialinstance === 'twitter') { if( API_TWITTER !== FALSE ) { $sitetype = 'twitter'; - $siteurl = 'http://twitter.com/$socialaccount'; + $siteurl = 'http://twitter.com/'. $socialaccount; $rssurl = API_TWITTER.$socialaccount; } else @@ -509,8 +509,8 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ } elseif($socialinstance === 'identica') { $sitetype = 'identica'; - $siteurl = 'http://identi.ca/$socialaccount'; - $rssurl = 'http://identi.ca/api/statuses/user_timeline/$socialaccount.rss'; + $siteurl = 'http://identi.ca/'.$socialaccount; + $rssurl = 'http://identi.ca/api/statuses/user_timeline/'.$socialaccount.rss; } elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { $sitetype = 'microblog'; From 3252d44c8bfe2c28e0ab3138e9d850e06fe8c2b7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 29 Apr 2013 23:36:53 +0200 Subject: [PATCH 26/28] =?UTF-8?q?Qui=20fait=20des=20commit=20=C3=A0=20la?= =?UTF-8?q?=20va=20vite=20=3F=20fixes=20#26?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 8812cb3..844391a 100755 --- a/index.php +++ b/index.php @@ -500,7 +500,7 @@ if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_ elseif($socialinstance === 'identica') { $sitetype = 'identica'; $siteurl = 'http://identi.ca/'.$socialaccount; - $rssurl = 'http://identi.ca/api/statuses/user_timeline/'.$socialaccount.rss; + $rssurl = 'http://identi.ca/api/statuses/user_timeline/'.$socialaccount.'.rss'; } elseif($socialinstance === 'statusnet' && !empty($_POST['statusneturl'])) { $sitetype = 'microblog'; From 9d03dd69aa925d29c78f08a90cc1faa7ad4032da Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 30 Apr 2013 00:13:20 +0200 Subject: [PATCH 27/28] fixes 28 --- index.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/index.php b/index.php index 844391a..04fed13 100755 --- a/index.php +++ b/index.php @@ -481,15 +481,17 @@ if(!empty($_GET['via_button']) && $_GET['number'] === '17' && ALLOW_NEW_AUTOBLOG /** * ADD BY SOCIAL / SHAARLI **/ -if(!empty($_POST['socialaccount']) && !empty($_POST['socialinstance']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) -{ - if( !empty($_POST['number']) && !empty($_POST['antibot']) && check_antibot($_POST['number'], $_POST['antibot']) ) { +if( !empty($_POST['socialinstance']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY_SOCIAL) +{; + $socialinstance = strtolower(escape($_POST['socialinstance'])); + $socialaccount = (!empty($_POST['socialaccount'])) ? strtolower(escape($_POST['socialaccount'])) : false; + if( $socialaccount === false && $socialinstance !== 'shaarli') + $error[] = 'Le compte social doit être renseigné.'; - $socialaccount = strtolower(escape($_POST['socialaccount'])); - $socialinstance = strtolower(escape($_POST['socialinstance'])); + if( !empty($_POST['number']) && !empty($_POST['antibot']) && check_antibot($_POST['number'], $_POST['antibot']) && empty($error)) { if($socialinstance === 'twitter') { - if( API_TWITTER !== FALSE ) { + if( API_TWITTER !== FALSE ) { $sitetype = 'twitter'; $siteurl = 'http://twitter.com/'. $socialaccount; $rssurl = API_TWITTER.$socialaccount; @@ -777,7 +779,7 @@ if( !empty($_POST['opml_file']) && ALLOW_NEW_AUTOBLOGS && ALLOW_NEW_AUTOBLOGS_BY

    Ajouter un Shaarli

    - +

    From af2b3ef44c6415b48a4348b3ec64f3b9f066da58 Mon Sep 17 00:00:00 2001 From: Mitsukarenai Date: Tue, 30 Apr 2013 00:22:40 +0200 Subject: [PATCH 28/28] RSS: newest first --- functions.php | 1 + 1 file changed, 1 insertion(+) diff --git a/functions.php b/functions.php index 2e3496f..c296c8c 100755 --- a/functions.php +++ b/functions.php @@ -272,6 +272,7 @@ echo '