diff options
| author | 2013-12-25 20:58:38 +0100 | |
|---|---|---|
| committer | 2013-12-25 20:58:38 +0100 | |
| commit | 7b4451912e2a9008a49854a2496cf9bb99b7ed10 (patch) | |
| tree | 99b6c2173bb0b8a528050aac6fab4e633f6be355 | |
| parent | 318954dfbd64f7a29203cdb25a95400dea0cec0d (diff) | |
| parent | 7eda2793bbc3210ae37aa66511fd7ad7661c2149 (diff) | |
Merge remote-tracking branch 'origin/dev' into beta
| -rw-r--r-- | CHANGELOG | 2 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rwxr-xr-x | app/Controllers/configureController.php | 10 | ||||
| -rwxr-xr-x | app/Controllers/entryController.php | 41 | ||||
| -rwxr-xr-x | app/Controllers/feedController.php | 27 | ||||
| -rwxr-xr-x | app/Controllers/indexController.php | 5 | ||||
| -rw-r--r-- | app/Models/Configuration.php | 14 | ||||
| -rw-r--r-- | app/Models/ConfigurationDAO.php | 8 | ||||
| -rw-r--r-- | app/Models/EntryDAO.php | 8 | ||||
| -rw-r--r-- | app/Models/Feed.php | 23 | ||||
| -rw-r--r-- | app/Models/FeedDAO.php | 33 | ||||
| -rw-r--r-- | app/i18n/en.php | 13 | ||||
| -rw-r--r-- | app/i18n/fr.php | 14 | ||||
| -rw-r--r-- | app/views/configure/display.phtml | 68 | ||||
| -rw-r--r-- | app/views/configure/feed.phtml | 68 | ||||
| -rw-r--r-- | constants.php | 5 | ||||
| -rw-r--r-- | lib/SimplePie/SimplePie.php | 13 | ||||
| -rw-r--r-- | lib/SimplePie/SimplePie/Parser.php | 30 | ||||
| -rw-r--r-- | public/install.php | 4 | ||||
| -rw-r--r-- | public/themes/default/freshrss.css | 4 | ||||
| -rw-r--r-- | public/themes/default/global.css | 3 | ||||
| -rw-r--r-- | public/themes/flat-design/freshrss.css | 4 | ||||
| -rw-r--r-- | public/themes/flat-design/global.css | 3 |
23 files changed, 285 insertions, 119 deletions
@@ -12,6 +12,7 @@ * Améliorations partage vers Shaarli, Poche, Diaspora*, Facebook, Twitter, Google+, courriel * Permet la suppression de tous les articles d’un flux * Option pour marquer les articles comme lus dès la réception + * Permet de configurer plus finement le nombre d’articles minimum à conserver par flux * Permet de modifier la description et l’adresse d’un flux RSS ainsi que le site Web associé * Nouveau raccourci pour ouvrir/fermer un article (‘c’ par défaut) * Bouton pour effacer les logs @@ -42,6 +43,7 @@ * PHP : * Meilleure gestion des caractères spéciaux dans différents cas * Amélioration des performances + * Encore plus tolérant pour les flux comportant des erreurs * Chargement automatique des classes * Alternative dans le cas d’absence de librairie JSON * Pour le développement, le cache HTTP peut être désactivé en créant un fichier “./no-cache.txt” @@ -2,10 +2,10 @@ FreshRSS est un agrégateur de flux RSS à auto-héberger à l’image de [Leed](http://projet.idleman.fr/leed/) ou de [Kriss Feed](http://tontof.net/kriss/feed/). Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable. -* Site officiel : http://marienfressinaud.github.io/FreshRSS/ +* Site officiel : http://freshrss.org * Démo : http://marienfressinaud.fr/projets/freshrss/ * Développeur : Marien Fressinaud <dev@marienfressinaud.fr> -* Version actuelle : 0.7-beta +* Version actuelle : 0.7-beta2 * Date de publication 2014-01-xx * License [GNU AGPL 3](http://www.gnu.org/licenses/agpl-3.0.html) diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 8d3e02d3e..762134dd0 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -97,18 +97,13 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $description = sanitizeHTML(Minz_Request::param('description', '', true)); $website = Minz_Request::param('website', ''); $url = Minz_Request::param('url', ''); - $hist = Minz_Request::param ('keep_history', 'no'); + $keep_history = intval(Minz_Request::param ('keep_history', -2)); $cat = Minz_Request::param ('category', 0); $path = Minz_Request::param ('path_entries', ''); $priority = Minz_Request::param ('priority', 0); $user = Minz_Request::param ('http_user', ''); $pass = Minz_Request::param ('http_pass', ''); - $keep_history = false; - if ($hist == 'yes') { - $keep_history = true; - } - $httpAuth = ''; if ($user != '' || $pass != '') { $httpAuth = $user . ':' . $pass; @@ -165,6 +160,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $lazyload = Minz_Request::param ('lazyload', 'no'); $sort = Minz_Request::param ('sort_order', 'DESC'); $old = Minz_Request::param ('old_entries', 3); + $keepHistoryDefault = Minz_Request::param('keep_history_default', 0); $mail = Minz_Request::param ('mail_login', false); $anon = Minz_Request::param ('anon_access', 'no'); $token = Minz_Request::param ('token', $current_token); @@ -194,6 +190,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $this->view->conf->_lazyload ($lazyload); $this->view->conf->_sortOrder ($sort); $this->view->conf->_oldEntries ($old); + $this->view->conf->_keepHistoryDefault($keepHistoryDefault); $this->view->conf->_mailLogin ($mail); $this->view->conf->_anonAccess ($anon); $this->view->conf->_token ($token); @@ -226,6 +223,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { 'lazyload' => $this->view->conf->lazyload (), 'sort_order' => $this->view->conf->sortOrder (), 'old_entries' => $this->view->conf->oldEntries (), + 'keep_history_default' => $this->view->conf->keepHistoryDefault(), 'mail_login' => $this->view->conf->mailLogin (), 'anon_access' => $this->view->conf->anonAccess (), 'token' => $this->view->conf->token (), diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index a332ca8a9..1c3c56c4d 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -109,4 +109,45 @@ class FreshRSS_entry_Controller extends Minz_ActionController { 'a' => 'display' ), true); } + + public function purgeAction() { + @set_time_limit(300); + + $nb_month_old = max($this->view->conf->oldEntries(), 1); + $date_min = time() - (3600 * 24 * 30 * $nb_month_old); + + $feedDAO = new FreshRSS_FeedDAO(); + $feeds = $feedDAO->listFeedsOrderUpdate(); + $nbTotal = 0; + + invalidateHttpCache(); + + foreach ($feeds as $feed) { + $feedHistory = $feed->keepHistory(); + if ($feedHistory == -2) { //default + $feedHistory = $this->view->conf->keepHistoryDefault(); + } + if ($feedHistory >= 0) { + $nb = $feedDAO->cleanOldEntries($feed->id(), $date_min, $feedHistory); + if ($nb > 0) { + $nbTotal += $nb; + Minz_Log::record($nb . ' old entries cleaned in feed ' . $feed->id(), Minz_Log::DEBUG); + $feedDAO->updateLastUpdate($feed->id()); + } + } + } + + invalidateHttpCache(); + + $notif = array( + 'type' => 'good', + 'content' => Minz_Translate::t('purge_completed', $nbTotal) + ); + Minz_Session::_param('notification', $notif); + + Minz_Request::forward(array( + 'c' => 'configure', + 'a' => 'display' + ), true); + } } diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 27b76dd42..04d0aa98b 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -102,14 +102,11 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->beginTransaction (); // on ajoute les articles en masse sans vérification foreach ($entries as $entry) { - if ($entry->date (true) >= $date_min || - $feed->keepHistory ()) { - $values = $entry->toArray (); - $values['id_feed'] = $feed->id (); - $values['id'] = min(time(), $entry->date (true)) . uSecString(); - $values['is_read'] = $is_read; - $entryDAO->addEntry ($values); - } + $values = $entry->toArray (); + $values['id_feed'] = $feed->id (); + $values['id'] = min(time(), $entry->date (true)) . uSecString(); + $values['is_read'] = $is_read; + $entryDAO->addEntry ($values); } $feedDAO->updateLastUpdate ($feed->id ()); $feedDAO->commit (); @@ -195,7 +192,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } // on calcule la date des articles les plus anciens qu'on accepte - $nb_month_old = $this->view->conf->oldEntries (); + $nb_month_old = max($this->view->conf->oldEntries(), 1); $date_min = time () - (3600 * 24 * 30 * $nb_month_old); $i = 0; @@ -217,8 +214,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->beginTransaction (); foreach ($entries as $entry) { if ((!isset ($existingGuids[$entry->guid ()])) && - ($entry->date (true) >= $date_min || - $feed->keepHistory ())) { + ($entry->date (true) >= $date_min)) { $values = $entry->toArray (); //Use declared date at first import, otherwise use discovery date $values['id'] = empty($existingGuids) ? min(time(), $entry->date (true)) . uSecString() : uTimeString(); @@ -227,8 +223,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } - if ((!$feed->keepHistory()) && (rand(0, 30) === 1)) { - $nb = $feedDAO->cleanOldEntries ($feed->id (), $date_min, count($entries) + 10); + $feedHistory = $feed->keepHistory(); + if ($feedHistory == -2) { //default + $feedHistory = $this->view->conf->keepHistoryDefault(); + } + + if (($feedHistory >= 0) && (rand(0, 30) === 1)) { + $nb = $feedDAO->cleanOldEntries ($feed->id (), $date_min, max($feedHistory, count($entries) + 10)); if ($nb > 0) { Minz_Log::record ($nb . ' old entries cleaned in feed ' . $feed->id (), Minz_Log::DEBUG); } diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index e3c253518..6c0ba9058 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -130,16 +130,17 @@ class FreshRSS_index_Controller extends Minz_ActionController { // on calcule la date des articles les plus anciens qu'on affiche $nb_month_old = $this->view->conf->oldEntries (); $date_min = $today - (3600 * 24 * 30 * $nb_month_old); //Do not use a fast changing value such as time() to allow SQL caching + $keepHistoryDefault = $this->view->conf->keepHistoryDefault(); try { - $entries = $this->entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min); + $entries = $this->entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min, $keepHistoryDefault); // Si on a récupéré aucun article "non lus" // on essaye de récupérer tous les articles if ($state === 'not_read' && empty($entries)) { //TODO: Remove in v0.8 Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG); $this->view->state = 'all'; - $entries = $this->entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min); + $entries = $this->entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, $keepHistoryDefault); } if (count($entries) <= $nb) { diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index d5f69601f..47509636f 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -14,6 +14,7 @@ class FreshRSS_Configuration extends Minz_Model { private $lazyload; private $sort_order; private $old_entries; + private $keep_history_default; private $shortcuts = array (); private $mail_login = ''; private $mark_when = array (); @@ -44,6 +45,7 @@ class FreshRSS_Configuration extends Minz_Model { $this->_lazyload ($confDAO->lazyload); $this->_sortOrder ($confDAO->sort_order); $this->_oldEntries ($confDAO->old_entries); + $this->_keepHistoryDefault($confDAO->keep_history_default); $this->_shortcuts ($confDAO->shortcuts); $this->_mailLogin ($confDAO->mail_login); $this->_markWhen ($confDAO->mark_when); @@ -95,6 +97,9 @@ class FreshRSS_Configuration extends Minz_Model { public function oldEntries () { return $this->old_entries; } + public function keepHistoryDefault() { + return $this->keep_history_default; + } public function shortcuts () { return $this->shortcuts; } @@ -217,11 +222,18 @@ class FreshRSS_Configuration extends Minz_Model { } public function _oldEntries ($value) { if (ctype_digit ($value) && $value > 0) { - $this->old_entries = $value; + $this->old_entries = intval($value); } else { $this->old_entries = 3; } } + public function _keepHistoryDefault($value) { + if (ctype_digit($value) && $value >= -1) { + $this->keep_history_default = intval($value); + } else { + $this->keep_history_default = 0; + } + } public function _shortcuts ($values) { foreach ($values as $key => $value) { $this->shortcuts[$key] = $value; diff --git a/app/Models/ConfigurationDAO.php b/app/Models/ConfigurationDAO.php index 0eebf2d90..91210e701 100644 --- a/app/Models/ConfigurationDAO.php +++ b/app/Models/ConfigurationDAO.php @@ -10,6 +10,7 @@ class FreshRSS_ConfigurationDAO extends Minz_ModelArray { public $lazyload = 'yes'; public $sort_order = 'DESC'; public $old_entries = 3; + public $keep_history_default = 0; public $shortcuts = array ( 'mark_read' => 'r', 'mark_favorite' => 'f', @@ -62,7 +63,7 @@ class FreshRSS_ConfigurationDAO extends Minz_ModelArray { $this->language = $this->array['language']; } if (isset ($this->array['posts_per_page'])) { - $this->posts_per_page = $this->array['posts_per_page']; + $this->posts_per_page = intval($this->array['posts_per_page']); } if (isset ($this->array['view_mode'])) { $this->view_mode = $this->array['view_mode']; @@ -83,7 +84,10 @@ class FreshRSS_ConfigurationDAO extends Minz_ModelArray { $this->sort_order = $this->array['sort_order']; } if (isset ($this->array['old_entries'])) { - $this->old_entries = $this->array['old_entries']; + $this->old_entries = intval($this->array['old_entries']); + } + if (isset ($this->array['keep_history_default'])) { + $this->keep_history_default = intval($this->array['keep_history_default']); } if (isset ($this->array['shortcuts'])) { $this->shortcuts = array_merge ( diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index c6bd5c404..99aaf3a0d 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -260,7 +260,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo { return isset ($entries[0]) ? $entries[0] : false; } - public function listWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { + public function listWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $keepHistoryDefault = 0) { $where = ''; $joinFeed = false; $values = array(); @@ -307,7 +307,11 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo { $where .= 'AND e1.id ' . ($order === 'DESC' ? '<=' : '>=') . $firstId . ' '; } if (($date_min > 0) && ($type !== 's')) { - $where .= 'AND (e1.id >= ' . $date_min . '000000 OR e1.is_favorite = 1 OR f.keep_history = 1) '; + $where .= 'AND (e1.id >= ' . $date_min . '000000 OR e1.is_read = 0 OR e1.is_favorite = 1 OR (f.keep_history <> 0'; + if (intval($keepHistoryDefault) === 0) { + $where .= ' AND f.keep_history <> -2'; //default + } + $where .= ')) '; $joinFeed = true; } $search = ''; diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 70efb0fa3..dcf97d4ec 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -15,7 +15,7 @@ class FreshRSS_Feed extends Minz_Model { private $pathEntries = ''; private $httpAuth = ''; private $error = false; - private $keep_history = false; + private $keep_history = -2; public function __construct ($url, $validate=true) { if ($validate) { @@ -163,19 +163,12 @@ class FreshRSS_Feed extends Minz_Model { $this->httpAuth = $value; } public function _error ($value) { - if ($value) { - $value = true; - } else { - $value = false; - } - $this->error = $value; + $this->error = (bool)$value; } public function _keepHistory ($value) { - if ($value) { - $value = true; - } else { - $value = false; - } + $value = intval($value); + $value = min($value, 1000000); + $value = max($value, -2); $this->keep_history = $value; } public function _nbNotRead ($value) { @@ -257,11 +250,11 @@ class FreshRSS_Feed extends Minz_Model { $this->_url ($subscribe_url); } - $title = $feed->get_title (); + $title = htmlspecialchars(html_only_entity_decode($feed->get_title()), ENT_COMPAT, 'UTF-8'); $this->_name (!is_null ($title) ? $title : $this->url); - $this->_website ($feed->get_link ()); - $this->_description ($feed->get_description ()); + $this->_website(html_only_entity_decode($feed->get_link())); + $this->_description(html_only_entity_decode($feed->get_description())); // et on charge les articles du flux $this->loadEntries ($feed); diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 9bd480544..d517f9580 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -2,7 +2,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { public function addFeed ($valuesTmp) { - $sql = 'INSERT INTO `' . $this->prefix . 'feed` (url, category, name, website, description, lastUpdate, priority, httpAuth, error, keep_history) VALUES(?, ?, ?, ?, ?, ?, 10, ?, 0, 0)'; + $sql = 'INSERT INTO `' . $this->prefix . 'feed` (url, category, name, website, description, lastUpdate, priority, httpAuth, error, keep_history) VALUES(?, ?, ?, ?, ?, ?, 10, ?, 0, -2)'; $stm = $this->bd->prepare ($sql); $values = array ( @@ -193,7 +193,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { } public function listFeedsOrderUpdate () { - $sql = 'SELECT * FROM `' . $this->prefix . 'feed` ORDER BY lastUpdate'; + $sql = 'SELECT id, name, url, pathEntries, httpAuth, keep_history FROM `' . $this->prefix . 'feed` ORDER BY lastUpdate'; $stm = $this->bd->prepare ($sql); $stm->execute (); @@ -315,20 +315,23 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { if (isset ($dao['id'])) { $key = $dao['id']; } + if ($catID === null) { + $catID = isset($dao['category']) ? $dao['category'] : 0; + } - $myFeed = new FreshRSS_Feed (isset($dao['url']) ? $dao['url'] : '', false); - $myFeed->_category ($catID === null ? $dao['category'] : $catID); - $myFeed->_name ($dao['name']); - $myFeed->_website ($dao['website'], false); - $myFeed->_description (isset($dao['description']) ? $dao['description'] : ''); - $myFeed->_lastUpdate (isset($dao['lastUpdate']) ? $dao['lastUpdate'] : 0); - $myFeed->_priority ($dao['priority']); - $myFeed->_pathEntries (isset($dao['pathEntries']) ? $dao['pathEntries'] : ''); - $myFeed->_httpAuth (isset($dao['httpAuth']) ? base64_decode ($dao['httpAuth']) : ''); - $myFeed->_error ($dao['error']); - $myFeed->_keepHistory (isset($dao['keep_history']) ? $dao['keep_history'] : ''); - $myFeed->_nbNotRead ($dao['cache_nbUnreads']); - $myFeed->_nbEntries ($dao['cache_nbEntries']); + $myFeed = new FreshRSS_Feed(isset($dao['url']) ? $dao['url'] : '', false); + $myFeed->_category(intval($catID)); + $myFeed->_name($dao['name']); + $myFeed->_website(isset($dao['website']) ? $dao['website'] : '', false); + $myFeed->_description(isset($dao['description']) ? $dao['description'] : ''); + $myFeed->_lastUpdate(isset($dao['lastUpdate']) ? $dao['lastUpdate'] : 0); + $myFeed->_priority(isset($dao['priority']) ? $dao['priority'] : 10); + $myFeed->_pathEntries(isset($dao['pathEntries']) ? $dao['pathEntries'] : ''); + $myFeed->_httpAuth(isset($dao['httpAuth']) ? base64_decode ($dao['httpAuth']) : ''); + $myFeed->_error(isset($dao['error']) ? $dao['error'] : 0); + $myFeed->_keepHistory(isset($dao['keep_history']) ? $dao['keep_history'] : -2); + $myFeed->_nbNotRead(isset($dao['cache_nbUnreads']) ? $dao['cache_nbUnreads'] : 0); + $myFeed->_nbEntries(isset($dao['cache_nbEntries']) ? $dao['cache_nbEntries'] : 0); if (isset ($dao['id'])) { $myFeed->_id ($dao['id']); } diff --git a/app/i18n/en.php b/app/i18n/en.php index 9c30573e8..498fccd14 100644 --- a/app/i18n/en.php +++ b/app/i18n/en.php @@ -137,7 +137,9 @@ return array ( 'feed_url' => 'Feed URL', 'articles' => 'articles', 'number_articles' => 'Number of articles', - 'keep_history' => 'Keep old articles?', + 'by_feed' => 'by feed', + 'by_default' => 'By default', + 'keep_history' => 'Minimum number of articles to keep', 'categorize' => 'Store in a category', 'truncate' => 'Delete all articles', 'advanced' => 'Advanced', @@ -157,14 +159,19 @@ return array ( 'general_configuration' => 'General configuration', 'language' => 'Language', - 'delete_articles_every' => 'Remove articles after', 'month' => 'months', 'default_user' => 'Username of the default user (maximum 16 alphanumeric characters)', 'persona_connection_email' => 'Login mail address (use <a href="https://persona.org/">Mozilla Persona</a>)', 'allow_anonymous' => 'Allow anonymous reading', 'auth_token' => 'Authentication token', 'explain_token' => 'Allows to access RSS output without authentication.<br />%s?token=%s', - 'reading_configuration' => 'Reading configuration', + 'login_configuration' => 'Login', + 'archiving_configuration' => 'Archiving', + 'delete_articles_every' => 'Remove articles after', + 'purge_now' => 'Purge now', + 'purge_completed' => 'Purge completed (%d articles deleted)', + 'archiving_configuration_help' => 'More options are available in the individual stream settings', + 'reading_configuration' => 'Reading', 'articles_per_page' => 'Number of articles per page', 'default_view' => 'Default view', 'sort_order' => 'Sort order', diff --git a/app/i18n/fr.php b/app/i18n/fr.php index 85bbeb4b7..c918daa44 100644 --- a/app/i18n/fr.php +++ b/app/i18n/fr.php @@ -137,7 +137,9 @@ return array ( 'feed_url' => 'URL du flux', 'articles' => 'articles', 'number_articles' => 'Nombre d’articles', - 'keep_history' => 'Garder les vieux articles ?', + 'by_feed' => 'par flux', + 'by_default' => 'Par défaut', + 'keep_history' => 'Nombre minimum d’articles à conserver', 'categorize' => 'Ranger dans une catégorie', 'truncate' => 'Supprimer tous les articles', 'advanced' => 'Avancé', @@ -157,14 +159,20 @@ return array ( 'general_configuration' => 'Configuration générale', 'language' => 'Langue', - 'delete_articles_every' => 'Supprimer les articles après', + 'month' => 'mois', 'default_user' => 'Nom de l’utilisateur par défaut (16 caractères alphanumériques maximum)', 'persona_connection_email' => 'Adresse courriel de connexion (utilise <a href="https://persona.org/">Mozilla Persona</a>)', 'allow_anonymous' => 'Autoriser la lecture anonyme', 'auth_token' => 'Jeton d’identification', 'explain_token' => 'Permet d’accéder à la sortie RSS sans besoin de s’authentifier.<br />%s?output=rss&token=%s', - 'reading_configuration' => 'Configuration de lecture', + 'login_configuration' => 'Identification', + 'archiving_configuration' => 'Archivage', + 'delete_articles_every' => 'Supprimer les articles après', + 'purge_now' => 'Purger maintenant', + 'purge_completed' => 'Purge effectuée (%d articles supprimés)', + 'archiving_configuration_help' => 'D’autres options sont disponibles dans la configuration individuelle des flux', + 'reading_configuration' => 'Lecture', 'articles_per_page' => 'Nombre d’articles par page', 'default_view' => 'Vue par défaut', 'sort_order' => 'Ordre de tri', diff --git a/app/views/configure/display.phtml b/app/views/configure/display.phtml index ad35d7c71..fca533752 100644 --- a/app/views/configure/display.phtml +++ b/app/views/configure/display.phtml @@ -31,13 +31,15 @@ </div> </div> - <div class="form-group"> - <label class="group-name" for="old_entries"><?php echo Minz_Translate::t ('delete_articles_every'); ?></label> + <div class="form-group form-actions"> <div class="group-controls"> - <input type="number" id="old_entries" name="old_entries" value="<?php echo $this->conf->oldEntries (); ?>" /> <?php echo Minz_Translate::t ('month'); ?> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> </div> </div> + <legend><?php echo Minz_Translate::t ('login_configuration'); ?></legend> + <div class="form-group"> <label class="group-name" for="mail_login"><?php echo Minz_Translate::t ('persona_connection_email'); ?></label> <?php $mail = $this->conf->mailLogin (); ?> @@ -59,7 +61,42 @@ <?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('explain_token', Minz_Url::display(null, 'html', true), $token); ?> </div> </div> - + + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> + </div> + </div> + + <legend><?php echo Minz_Translate::t ('archiving_configuration'); ?></legend> + <p><?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('archiving_configuration_help'); ?></p> + + <div class="form-group"> + <label class="group-name" for="old_entries"><?php echo Minz_Translate::t ('delete_articles_every'); ?></label> + <div class="group-controls"> + <input type="number" id="old_entries" name="old_entries" min="1" max="1200" value="<?php echo $this->conf->oldEntries (); ?>" /> <?php echo Minz_Translate::t ('month'); ?> + <a class="btn confirm" href="<?php echo _url('entry', 'purge'); ?>"><?php echo Minz_Translate::t('purge_now'); ?></a> + </div> + </div> + <div class="form-group"> + <label class="group-name" for="keep_history_default"><?php echo Minz_Translate::t('keep_history'), ' ', Minz_Translate::t('by_feed'); ?> (<?php echo Minz_Translate::t('by_default'); ?>)</label> + <div class="group-controls"> + <select class="number" name="keep_history_default" id="keep_history_default"><?php + foreach (array(-3 => '', 0 => '0', 10 => '10', 50 => '50', 100 => '100', 500 => '500', 1000 => '1 000', 5000 => '5 000', 10000 => '10 000', -1 => '∞') as $v => $t) { + echo '<option value="' . $v . ($this->conf->keepHistoryDefault() == $v ? '" selected="selected' : '') . '">' . $t . ' </option>'; + } + ?></select> + </div> + </div> + + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> + </div> + </div> + <legend><?php echo Minz_Translate::t ('reading_configuration'); ?></legend> <div class="form-group"> @@ -160,6 +197,13 @@ </div> </div> + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> + </div> + </div> + <legend><?php echo Minz_Translate::t ('reading_icons'); ?></legend> <div class="form-group"> <table> @@ -193,7 +237,14 @@ <td><input type="checkbox" name="bottomline_link" value="yes"<?php echo $this->conf->bottomlineLink () ? ' checked="checked"' : ''; ?> /></td> </tr> </tbody> - </table> + </table><br /> + </div> + + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> + </div> </div> <legend><?php echo Minz_Translate::t ('advanced'); ?></legend> @@ -207,12 +258,5 @@ <?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('optimize_todo_sometimes'); ?> </div> </div> - - <div class="form-group form-actions"> - <div class="group-controls"> - <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> - <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> - </div> - </div> </form> </div> diff --git a/app/views/configure/feed.phtml b/app/views/configure/feed.phtml index 4504b8d76..e738ab64f 100644 --- a/app/views/configure/feed.phtml +++ b/app/views/configure/feed.phtml @@ -53,6 +53,24 @@ </div> </div> <div class="form-group"> + <label class="group-name" for="priority"><?php echo Minz_Translate::t ('show_in_all_flux'); ?></label> + <div class="group-controls"> + <label class="checkbox" for="priority"> + <input type="checkbox" name="priority" id="priority" value="10"<?php echo $this->flux->priority () > 0 ? ' checked="checked"' : ''; ?> /> + <?php echo Minz_Translate::t ('yes'); ?> + </label> + </div> + </div> + <div class="form-group form-actions"> + <div class="group-controls"> + <button class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button class="btn btn-attention confirm" formmethod="post" formaction="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'delete', 'params' => array ('id' => $this->flux->id ()))); ?>"><?php echo Minz_Translate::t ('delete'); ?></button> + </div> + </div> + + <legend><?php echo Minz_Translate::t ('archiving_configuration'); ?></legend> + + <div class="form-group"> <label class="group-name"></label> <div class="group-controls"> <a class="btn" href="<?php echo _url ('feed', 'actualize', 'id', $this->flux->id ()); ?>"> @@ -64,37 +82,26 @@ <label class="group-name"><?php echo Minz_Translate::t ('number_articles'); ?></label> <div class="group-controls"> <span class="control"><?php echo $this->flux->nbEntries (); ?></span> - <label class="checkbox" for="keep_history"> - <input type="checkbox" name="keep_history" id="keep_history" value="yes"<?php echo $this->flux->keepHistory () == 'yes' ? ' checked="checked"' : ''; ?> /> - <?php echo Minz_Translate::t ('keep_history'); ?> - </label> </div> </div> <div class="form-group"> - <label class="group-name"></label> + <label class="group-name" for="keep_history"><?php echo Minz_Translate::t ('keep_history'); ?></label> <div class="group-controls"> - <button class="btn btn-attention confirm" formmethod="post" formaction="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'truncate', 'params' => array ('id' => $this->flux->id ()))); ?>"><?php echo Minz_Translate::t ('truncate'); ?></button> + <select class="number" name="keep_history" id="keep_history"><?php + foreach (array(-3 => '', -2 => Minz_Translate::t('by_default'), 0 => '0', 10 => '10', 50 => '50', 100 => '100', 500 => '500', 1000 => '1 000', 5000 => '5 000', 10000 => '10 000', -1 => '∞') as $v => $t) { + echo '<option value="' . $v . ($this->flux->keepHistory() === $v ? '" selected="selected' : '') . '">' . $t . '</option>'; + } + ?></select> </div> </div> - - <legend><?php echo Minz_Translate::t ('advanced'); ?></legend> - <div class="form-group"> - <label class="group-name" for="priority"><?php echo Minz_Translate::t ('show_in_all_flux'); ?></label> - <div class="group-controls"> - <label class="checkbox" for="priority"> - <input type="checkbox" name="priority" id="priority" value="10"<?php echo $this->flux->priority () > 0 ? ' checked="checked"' : ''; ?> /> - <?php echo Minz_Translate::t ('yes'); ?> - </label> - </div> - </div> - <div class="form-group"> - <label class="group-name" for="path_entries"><?php echo Minz_Translate::t ('css_path_on_website'); ?></label> + <div class="form-group form-actions"> <div class="group-controls"> - <input type="text" name="path_entries" id="path_entries" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" /> - <?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t ('retrieve_truncated_feeds'); ?> + <button class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button class="btn btn-attention confirm" formmethod="post" formaction="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'truncate', 'params' => array ('id' => $this->flux->id ()))); ?>"><?php echo Minz_Translate::t ('truncate'); ?></button> </div> </div> + <legend><?php echo Minz_Translate::t ('login_configuration'); ?></legend> <?php $auth = $this->flux->httpAuth (false); ?> <div class="form-group"> <label class="group-name" for="http_user"><?php echo Minz_Translate::t ('http_username'); ?></label> @@ -109,11 +116,26 @@ </div> </div> + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> + </div> + </div> + + <legend><?php echo Minz_Translate::t ('advanced'); ?></legend> + <div class="form-group"> + <label class="group-name" for="path_entries"><?php echo Minz_Translate::t ('css_path_on_website'); ?></label> + <div class="group-controls"> + <input type="text" name="path_entries" id="path_entries" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" /> + <?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t ('retrieve_truncated_feeds'); ?> + </div> + </div> <div class="form-group form-actions"> <div class="group-controls"> - <button class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> - <button class="btn btn-attention confirm" formmethod="post" formaction="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'delete', 'params' => array ('id' => $this->flux->id ()))); ?>"><?php echo Minz_Translate::t ('delete'); ?></button> + <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button> + <button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button> </div> </div> </form> diff --git a/constants.php b/constants.php index 304351823..272647947 100644 --- a/constants.php +++ b/constants.php @@ -1,9 +1,10 @@ <?php -define('FRESHRSS_VERSION', '0.7-beta'); +define('FRESHRSS_VERSION', '0.7-beta2'); define('FRESHRSS_WEBSITE', 'http://freshrss.org'); // Constantes de chemins -define ('FRESHRSS_PATH', realpath (dirname (__FILE__))); +define ('FRESHRSS_PATH', dirname(__FILE__)); + define ('PUBLIC_PATH', FRESHRSS_PATH . '/public'); define ('DATA_PATH', FRESHRSS_PATH . '/data'); define ('LIB_PATH', FRESHRSS_PATH . '/lib'); diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index d20ab5430..f02037c10 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1313,7 +1313,7 @@ class SimplePie // First check to see if input has been overridden. if ($this->input_encoding !== false) { - $encodings[] = $this->input_encoding; + $encodings[] = strtoupper($this->input_encoding); } $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); @@ -1330,18 +1330,18 @@ class SimplePie } else { - $encodings[] = ''; //Let the DOM parser decide first + $encodings[] = ''; //FreshRSS: Let the DOM parser decide first } } elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') { if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) { - $encodings[] = $charset[1]; + $encodings[] = strtoupper($charset[1]); } else { - $encodings[] = ''; + $encodings[] = ''; //FreshRSS: Let the DOM parser decide first } $encodings[] = 'US-ASCII'; } @@ -1364,13 +1364,14 @@ class SimplePie foreach ($encodings as $encoding) { // Change the encoding to UTF-8 (as we always use UTF-8 internally) - if ($utf8_data = (empty($encoding) || $encoding === 'UTF-8') ? $this->raw_data : $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8'))) + if ($utf8_data = (empty($encoding) || $encoding === 'UTF-8') ? $this->raw_data : //FreshRSS + $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8'))) { // Create new parser $parser = $this->registry->create('Parser'); // If it's parsed fine - if ($parser->parse($utf8_data, 'UTF-8')) + if ($parser->parse($utf8_data, empty($encoding) ? '' : 'UTF-8')) //FreshRSS { $this->data = $parser->get_data(); if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE)) diff --git a/lib/SimplePie/SimplePie/Parser.php b/lib/SimplePie/SimplePie/Parser.php index c4c732787..bd6c4efd8 100644 --- a/lib/SimplePie/SimplePie/Parser.php +++ b/lib/SimplePie/SimplePie/Parser.php @@ -77,6 +77,8 @@ class SimplePie_Parser public function parse(&$data, $encoding) { + $xmlEncoding = ''; + if (!empty($encoding)) { // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character @@ -121,6 +123,7 @@ class SimplePie_Parser $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5))); if ($declaration->parse()) { + $xmlEncoding = strtoupper($declaration->encoding); //FreshRSS $data = substr($data, $pos + 2); $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data; } @@ -132,17 +135,24 @@ class SimplePie_Parser } } - try //FreshRSS - { - $dom = new DOMDocument(); - $dom->recover = true; - $dom->strictErrorChecking = false; - $dom->loadXML($data); - $this->encoding = $encoding = $dom->encoding = 'UTF-8'; - $data = $dom->saveXML(); - } - catch (Exception $e) + if ($xmlEncoding === '' || $xmlEncoding === 'UTF-8') //FreshRSS: case of no explicit HTTP encoding, and lax UTF-8 { + try + { + $dom = new DOMDocument(); + $dom->recover = true; + $dom->strictErrorChecking = false; + $dom->loadXML($data); + $this->encoding = $encoding = $dom->encoding = 'UTF-8'; + $data2 = $dom->saveXML(); + if (strlen($data2) > (strlen($data) / 2.0)) + { + $data = $data2; + } + } + catch (Exception $e) + { + } } $return = true; diff --git a/public/install.php b/public/install.php index afef7e473..13abb010b 100644 --- a/public/install.php +++ b/public/install.php @@ -33,7 +33,7 @@ define ('SQL_FEED', 'CREATE TABLE IF NOT EXISTS `%1$sfeed` ( `pathEntries` varchar(511) DEFAULT NULL, `httpAuth` varchar(511) DEFAULT NULL, `error` boolean DEFAULT 0, - `keep_history` MEDIUMINT NOT NULL DEFAULT 0, + `keep_history` MEDIUMINT NOT NULL DEFAULT -2, -- v0.7, -2 = default `cache_nbEntries` int DEFAULT 0, -- v0.7 `cache_nbUnreads` int DEFAULT 0, -- v0.7 PRIMARY KEY (`id`), @@ -93,7 +93,7 @@ FROM `%1$scategory006` ORDER BY id2; INSERT IGNORE INTO `%2$sfeed` (url, category, name, website, description, priority, pathEntries, httpAuth, keep_history) -SELECT url, category2, name, website, description, priority, pathEntries, httpAuth, keep_history +SELECT url, category2, name, website, description, priority, pathEntries, httpAuth, IF(keep_history = 1, -1, -2) FROM `%1$sfeed006` ORDER BY id2; diff --git a/public/themes/default/freshrss.css b/public/themes/default/freshrss.css index e3c4c3c3b..2b157b27a 100644 --- a/public/themes/default/freshrss.css +++ b/public/themes/default/freshrss.css @@ -667,6 +667,10 @@ padding:.5em; } +select.number option { + text-align:right; +} + @media(max-width: 840px) { .header, .aside .btn-important, diff --git a/public/themes/default/global.css b/public/themes/default/global.css index 1c554d2dc..440fc6e41 100644 --- a/public/themes/default/global.css +++ b/public/themes/default/global.css @@ -99,6 +99,9 @@ input, select, textarea { vertical-align: middle; box-shadow: 0 2px 2px #eee inset; } + option { + padding:0 .5em 0 .5em; + } input[type="radio"], input[type="checkbox"] { width: 15px !important; diff --git a/public/themes/flat-design/freshrss.css b/public/themes/flat-design/freshrss.css index fa1ed13e6..7e3f4c81a 100644 --- a/public/themes/flat-design/freshrss.css +++ b/public/themes/flat-design/freshrss.css @@ -662,6 +662,10 @@ body { padding:.5em; } +select.number option { + text-align:right; +} + @media(max-width: 840px) { .header, .aside .btn-important, diff --git a/public/themes/flat-design/global.css b/public/themes/flat-design/global.css index 8cf6412b3..90b59d002 100644 --- a/public/themes/flat-design/global.css +++ b/public/themes/flat-design/global.css @@ -101,6 +101,9 @@ input, select, textarea { vertical-align: middle; border-radius: 5px; } + option { + padding:0 .5em 0 .5em; + } input[type="radio"], input[type="checkbox"] { width: 15px !important; |
