aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2013-12-25 20:58:38 +0100
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2013-12-25 20:58:38 +0100
commit7b4451912e2a9008a49854a2496cf9bb99b7ed10 (patch)
tree99b6c2173bb0b8a528050aac6fab4e633f6be355
parent318954dfbd64f7a29203cdb25a95400dea0cec0d (diff)
parent7eda2793bbc3210ae37aa66511fd7ad7661c2149 (diff)
Merge remote-tracking branch 'origin/dev' into beta
-rw-r--r--CHANGELOG2
-rw-r--r--README.md4
-rwxr-xr-xapp/Controllers/configureController.php10
-rwxr-xr-xapp/Controllers/entryController.php41
-rwxr-xr-xapp/Controllers/feedController.php27
-rwxr-xr-xapp/Controllers/indexController.php5
-rw-r--r--app/Models/Configuration.php14
-rw-r--r--app/Models/ConfigurationDAO.php8
-rw-r--r--app/Models/EntryDAO.php8
-rw-r--r--app/Models/Feed.php23
-rw-r--r--app/Models/FeedDAO.php33
-rw-r--r--app/i18n/en.php13
-rw-r--r--app/i18n/fr.php14
-rw-r--r--app/views/configure/display.phtml68
-rw-r--r--app/views/configure/feed.phtml68
-rw-r--r--constants.php5
-rw-r--r--lib/SimplePie/SimplePie.php13
-rw-r--r--lib/SimplePie/SimplePie/Parser.php30
-rw-r--r--public/install.php4
-rw-r--r--public/themes/default/freshrss.css4
-rw-r--r--public/themes/default/global.css3
-rw-r--r--public/themes/flat-design/freshrss.css4
-rw-r--r--public/themes/flat-design/global.css3
23 files changed, 285 insertions, 119 deletions
diff --git a/CHANGELOG b/CHANGELOG
index af6936204..05d3a50ec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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”
diff --git a/README.md b/README.md
index 87ed9de99..716859ccf 100644
--- a/README.md
+++ b/README.md
@@ -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;