summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexis Degrugillier <aledeg@users.noreply.github.com> 2018-01-01 20:34:06 +0100
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2018-01-01 20:34:06 +0100
commit8c2113f9e6eb86b630a4e861513229d7abf219b8 (patch)
tree6e9ca68cf291a21d573f82ff7818c66e40a7ec30
parente73fae159168b1ed9c0469e1d5bce55a3ef1f911 (diff)
Add mute strategy configuration (#1750)
-rwxr-xr-xapp/Controllers/configureController.php7
-rwxr-xr-xapp/Controllers/feedController.php15
-rw-r--r--app/Controllers/subscriptionController.php14
-rw-r--r--app/Models/CategoryDAO.php5
-rw-r--r--app/Models/EntryDAO.php40
-rw-r--r--app/Models/Feed.php23
-rw-r--r--app/Models/FeedDAO.php33
-rw-r--r--app/SQL/install.sql.mysql.php2
-rw-r--r--app/SQL/install.sql.pgsql.php2
-rw-r--r--app/SQL/install.sql.sqlite.php2
-rw-r--r--app/i18n/cz/sub.php8
-rw-r--r--app/i18n/de/sub.php8
-rw-r--r--app/i18n/en/sub.php8
-rwxr-xr-xapp/i18n/es/sub.php8
-rw-r--r--app/i18n/fr/sub.php8
-rw-r--r--app/i18n/he/sub.php8
-rw-r--r--app/i18n/it/sub.php8
-rw-r--r--app/i18n/kr/sub.php8
-rw-r--r--app/i18n/nl/sub.php8
-rw-r--r--app/i18n/pt-br/sub.php8
-rw-r--r--app/i18n/ru/sub.php8
-rw-r--r--app/i18n/tr/sub.php8
-rw-r--r--app/i18n/zh-cn/sub.php8
-rw-r--r--app/layout/aside_feed.phtml2
-rw-r--r--app/views/helpers/feed/update.phtml19
-rw-r--r--app/views/index/global.phtml2
-rw-r--r--app/views/subscription/index.phtml2
-rw-r--r--p/api/greader.php4
-rw-r--r--p/themes/base-theme/template.css3
29 files changed, 210 insertions, 69 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index de70e475b..2c7739c55 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -204,16 +204,13 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
* The options available on that page are:
* - duration to retain old article (default: 3)
* - number of article to retain per feed (default: 0)
- * - refresh frequency (default: -2)
- *
- * @todo explain why the default value is -2 but this value does not
- * exist in the drop-down list
+ * - refresh frequency (default: 0)
*/
public function archivingAction() {
if (Minz_Request::isPost()) {
FreshRSS_Context::$user_conf->old_entries = Minz_Request::param('old_entries', 3);
FreshRSS_Context::$user_conf->keep_history_default = Minz_Request::param('keep_history_default', 0);
- FreshRSS_Context::$user_conf->ttl_default = Minz_Request::param('ttl_default', -2);
+ FreshRSS_Context::$user_conf->ttl_default = Minz_Request::param('ttl_default', FreshRSS_Feed::TTL_DEFAULT);
FreshRSS_Context::$user_conf->save();
invalidateHttpCache();
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index fff20f798..2793577d5 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -24,6 +24,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
Minz_Error::error(403);
}
}
+ $this->updateTTL();
}
/**
@@ -282,11 +283,11 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$mtime = 0;
$ttl = $feed->ttl();
- if ($ttl == -1) {
+ if ($ttl < FreshRSS_Feed::TTL_DEFAULT) {
continue; //Feed refresh is disabled
}
if ((!$simplePiePush) && (!$feed_id) &&
- ($feed->lastUpdate() + 10 >= time() - ($ttl == -2 ? FreshRSS_Context::$user_conf->ttl_default : $ttl))) {
+ ($feed->lastUpdate() + 10 >= time() - ($ttl == FreshRSS_Feed::TTL_DEFAULT ? FreshRSS_Context::$user_conf->ttl_default : $ttl))) {
//Too early to refresh from source, but check whether the feed was updated by another user
$mtime = $feed->cacheModifiedTime();
if ($feed->lastUpdate() + 10 >= $mtime) {
@@ -639,4 +640,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
Minz_Request::bad(_t('feedback.sub.feed.error'), $redirect_url);
}
}
+
+ /**
+ * This method update TTL values for feeds if needed.
+ * It changes the old default value (-2) to the new default value (0).
+ * It changes the old disabled value (-1) to the default disabled value.
+ */
+ private function updateTTL() {
+ $feedDAO = FreshRSS_Factory::createFeedDao();
+ $feedDAO->updateTTL();
+ }
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index 6af048b84..b3f3df46e 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -15,8 +15,10 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
}
$catDAO = new FreshRSS_CategoryDAO();
+ $feedDAO = new FreshRSS_FeedDAO();
$catDAO->checkDefault();
+ $feedDAO->updateTTL();
$this->view->categories = $catDAO->listCategories(false);
$this->view->default_category = $catDAO->getDefault();
}
@@ -55,7 +57,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
* - display in main stream (default: 0)
* - HTTP authentication
* - number of article to retain (default: -2)
- * - refresh frequency (default: -2)
+ * - refresh frequency (default: 0)
* Default values are empty strings unless specified.
*/
public function feedAction() {
@@ -87,6 +89,12 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
$cat = intval(Minz_Request::param('category', 0));
+ $mute = Minz_Request::param('mute', false);
+ $ttl = intval(Minz_Request::param('ttl', FreshRSS_Feed::TTL_DEFAULT));
+ if ($mute && FreshRSS_Feed::TTL_DEFAULT === $ttl) {
+ $ttl = FreshRSS_Context::$user_conf->ttl_default;
+ }
+
$values = array(
'name' => Minz_Request::param('name', ''),
'description' => sanitizeHTML(Minz_Request::param('description', '', true)),
@@ -94,10 +102,10 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
'url' => checkUrl(Minz_Request::param('url', '')),
'category' => $cat,
'pathEntries' => Minz_Request::param('path_entries', ''),
- 'priority' => intval(Minz_Request::param('priority', 0)),
+ 'priority' => intval(Minz_Request::param('priority', FreshRSS_Feed::PRIORITY_MAIN_STREAM)),
'httpAuth' => $httpAuth,
'keep_history' => intval(Minz_Request::param('keep_history', -2)),
- 'ttl' => intval(Minz_Request::param('ttl', -2)),
+ 'ttl' => $ttl * ($mute ? -1 : 1),
);
invalidateHttpCache();
diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php
index f219c275f..68db17db3 100644
--- a/app/Models/CategoryDAO.php
+++ b/app/Models/CategoryDAO.php
@@ -106,13 +106,14 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable
public function listCategories($prePopulateFeeds = true, $details = false) {
if ($prePopulateFeeds) {
$sql = 'SELECT c.id AS c_id, c.name AS c_name, '
- . ($details ? 'f.* ' : 'f.id, f.name, f.url, f.website, f.priority, f.error, f.`cache_nbEntries`, f.`cache_nbUnreads` ')
+ . ($details ? 'f.* ' : 'f.id, f.name, f.url, f.website, f.priority, f.error, f.`cache_nbEntries`, f.`cache_nbUnreads`, f.ttl ')
. 'FROM `' . $this->prefix . 'category` c '
. 'LEFT OUTER JOIN `' . $this->prefix . 'feed` f ON f.category=c.id '
+ . 'WHERE f.priority >= :priority_normal '
. 'GROUP BY f.id, c_id '
. 'ORDER BY c.name, f.name';
$stm = $this->bd->prepare($sql);
- $stm->execute();
+ $stm->execute(array(':priority_normal' => FreshRSS_Feed::PRIORITY_NORMAL));
return self::daoToCategoryPrepopulated($stm->fetchAll(PDO::FETCH_ASSOC));
} else {
$sql = 'SELECT * FROM `' . $this->prefix . 'category` ORDER BY name';
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index e8b6dcdae..9e291f4ed 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -726,23 +726,23 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$values = array();
switch ($type) {
case 'a':
- $where .= 'f.priority > 0 ';
- $joinFeed = true;
+ $where .= 'f.priority > ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
break;
case 's': //Deprecated: use $state instead
- $where .= 'e.is_favorite=1 ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
+ $where .= 'AND e.is_favorite=1 ';
break;
case 'c':
- $where .= 'f.category=? ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
+ $where .= 'AND f.category=? ';
$values[] = intval($id);
- $joinFeed = true;
break;
case 'f':
$where .= 'e.id_feed=? ';
$values[] = intval($id);
break;
case 'A':
- $where .= '1=1 ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
break;
default:
throw new FreshRSS_EntriesGetter_Exception('Bad type in Entry->listByType: [' . $type . ']!');
@@ -752,7 +752,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return array(array_merge($values, $searchValues),
'SELECT e.id FROM `' . $this->prefix . 'entry` e '
- . ($joinFeed ? 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id ' : '')
+ . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id '
. 'WHERE ' . $where
. $search
. 'ORDER BY e.id ' . $order
@@ -873,12 +873,28 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
public function countUnreadReadFavorites() {
- $sql = 'SELECT c FROM ('
- . 'SELECT COUNT(id) AS c, 1 as o FROM `' . $this->prefix . 'entry` WHERE is_favorite=1 '
- . 'UNION SELECT COUNT(id) AS c, 2 AS o FROM `' . $this->prefix . 'entry` WHERE is_favorite=1 AND is_read=0'
- . ') u ORDER BY o';
+ $sql = <<<SQL
+ SELECT c
+ FROM (
+ SELECT COUNT(e1.id) AS c
+ , 1 AS o
+ FROM `{$this->prefix}entry` AS e1
+ JOIN `{$this->prefix}feed` AS f1 ON e1.id_feed = f1.id
+ WHERE e1.is_favorite = 1
+ AND f1.priority >= :priority_normal
+ UNION
+ SELECT COUNT(e2.id) AS c
+ , 2 AS o
+ FROM `{$this->prefix}entry` AS e2
+ JOIN `{$this->prefix}feed` AS f2 ON e2.id_feed = f2.id
+ WHERE e2.is_favorite = 1
+ AND e2.is_read = 0
+ AND f2.priority >= :priority_normal
+ ) u
+ORDER BY o
+SQL;
$stm = $this->bd->prepare($sql);
- $stm->execute();
+ $stm->execute(array(':priority_normal' => FreshRSS_Feed::PRIORITY_NORMAL));
$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
$all = empty($res[0]) ? 0 : $res[0];
$unread = empty($res[1]) ? 0 : $res[1];
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 560f7415d..216a26d44 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -1,6 +1,12 @@
<?php
class FreshRSS_Feed extends Minz_Model {
+ const PRIORITY_MAIN_STREAM = 10;
+ const PRIORITY_NORMAL = 0;
+ const PRIORITY_ARCHIVED = -10;
+
+ const TTL_DEFAULT = 0;
+
private $id = 0;
private $url;
private $category = 1;
@@ -11,12 +17,13 @@ class FreshRSS_Feed extends Minz_Model {
private $website = '';
private $description = '';
private $lastUpdate = 0;
- private $priority = 10;
+ private $priority = self::PRIORITY_MAIN_STREAM;
private $pathEntries = '';
private $httpAuth = '';
private $error = false;
private $keep_history = -2;
- private $ttl = -2;
+ private $ttl = self::TTL_DEFAULT;
+ private $mute = false;
private $hash = null;
private $lockPath = '';
private $hubUrl = '';
@@ -104,9 +111,12 @@ class FreshRSS_Feed extends Minz_Model {
public function ttl() {
return $this->ttl;
}
+ public function mute() {
+ return $this->mute;
+ }
// public function ttlExpire() {
// $ttl = $this->ttl;
- // if ($ttl == -2) { //Default
+ // if ($ttl == self::TTL_DEFAULT) { //Default
// $ttl = FreshRSS_Context::$user_conf->ttl_default;
// }
// if ($ttl == -1) { //Never
@@ -198,8 +208,7 @@ class FreshRSS_Feed extends Minz_Model {
$this->lastUpdate = $value;
}
public function _priority($value) {
- $value = intval($value);
- $this->priority = $value >= 0 ? $value : 10;
+ $this->priority = intval($value);
}
public function _pathEntries($value) {
$this->pathEntries = $value;
@@ -219,8 +228,8 @@ class FreshRSS_Feed extends Minz_Model {
public function _ttl($value) {
$value = intval($value);
$value = min($value, 100000000);
- $value = max($value, -2);
- $this->ttl = $value;
+ $this->ttl = abs($value);
+ $this->mute = $value < self::TTL_DEFAULT;
}
public function _nbNotRead($value) {
$this->nbNotRead = intval($value);
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index 0de6d98be..deda02c63 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -18,7 +18,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
ttl
)
VALUES
- (?, ?, ?, ?, ?, ?, 10, ?, 0, -2, -2)';
+ (?, ?, ?, ?, ?, ?, 10, ?, 0, -2, ?)';
$stm = $this->bd->prepare($sql);
$valuesTmp['url'] = safe_ascii($valuesTmp['url']);
@@ -32,6 +32,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
substr($valuesTmp['description'], 0, 1023),
$valuesTmp['lastUpdate'],
base64_encode($valuesTmp['httpAuth']),
+ FreshRSS_Feed::TTL_DEFAULT,
);
if ($stm && $stm->execute($values)) {
@@ -249,18 +250,14 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
* Use $defaultCacheDuration == -1 to return all feeds, without filtering them by TTL.
*/
public function listFeedsOrderUpdate($defaultCacheDuration = 3600) {
+ $this->updateTTL();
$sql = 'SELECT id, url, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, keep_history, ttl '
. 'FROM `' . $this->prefix . 'feed` '
- . ($defaultCacheDuration < 0 ? '' : 'WHERE ttl <> -1 AND `lastUpdate` < (' . (time() + 60) . '-(CASE WHEN ttl=-2 THEN ' . intval($defaultCacheDuration) . ' ELSE ttl END)) ')
+ . ($defaultCacheDuration < 0 ? '' : 'WHERE ttl >= ' . FreshRSS_Feed::TTL_DEFAULT
+ . ' AND `lastUpdate` < (' . (time() + 60) . '-(CASE WHEN ttl=' . FreshRSS_Feed::TTL_DEFAULT . ' THEN ' . intval($defaultCacheDuration) . ' ELSE ttl END)) ')
. 'ORDER BY `lastUpdate`';
$stm = $this->bd->prepare($sql);
- if (!($stm && $stm->execute())) {
- $sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT -2'; //v0.7.3
- $stm = $this->bd->prepare($sql2);
- $stm->execute();
- $stm = $this->bd->prepare($sql);
- $stm->execute();
- }
+ $stm->execute();
return self::daoToFeed($stm->fetchAll(PDO::FETCH_ASSOC));
}
@@ -410,7 +407,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$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->_ttl(isset($dao['ttl']) ? $dao['ttl'] : -2);
+ $myFeed->_ttl(isset($dao['ttl']) ? $dao['ttl'] : FreshRSS_Feed::TTL_DEFAULT);
$myFeed->_nbNotRead(isset($dao['cache_nbUnreads']) ? $dao['cache_nbUnreads'] : 0);
$myFeed->_nbEntries(isset($dao['cache_nbEntries']) ? $dao['cache_nbEntries'] : 0);
if (isset($dao['id'])) {
@@ -421,4 +418,20 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return $list;
}
+
+ public function updateTTL() {
+ $sql = <<<SQL
+UPDATE `{$this->prefix}feed`
+ SET ttl = :new_value
+ WHERE ttl = :old_value
+SQL;
+ $stm = $this->bd->prepare($sql);
+ if (!($stm && $stm->execute(array(':new_value' => FreshRSS_Feed::TTL_DEFAULT, ':old_value' => -2)))) {
+ $sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT ' . FreshRSS_Feed::TTL_DEFAULT; //v0.7.3
+ $stm = $this->bd->prepare($sql2);
+ $stm->execute();
+ } else {
+ $stm->execute(array(':new_value' => -3600, ':old_value' => -1));
+ }
+ }
}
diff --git a/app/SQL/install.sql.mysql.php b/app/SQL/install.sql.mysql.php
index 09defd452..b94a24298 100644
--- a/app/SQL/install.sql.mysql.php
+++ b/app/SQL/install.sql.mysql.php
@@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS `%1$sfeed` (
`httpAuth` varchar(511) DEFAULT NULL,
`error` boolean DEFAULT 0,
`keep_history` MEDIUMINT NOT NULL DEFAULT -2, -- v0.7
- `ttl` INT NOT NULL DEFAULT -2, -- v0.7.3
+ `ttl` INT NOT NULL DEFAULT 0, -- v0.7.3
`cache_nbEntries` int DEFAULT 0, -- v0.7
`cache_nbUnreads` int DEFAULT 0, -- v0.7
PRIMARY KEY (`id`),
diff --git a/app/SQL/install.sql.pgsql.php b/app/SQL/install.sql.pgsql.php
index 4cfeb2517..23afdb783 100644
--- a/app/SQL/install.sql.pgsql.php
+++ b/app/SQL/install.sql.pgsql.php
@@ -21,7 +21,7 @@ $SQL_CREATE_TABLES = array(
"httpAuth" VARCHAR(511) DEFAULT NULL,
"error" smallint DEFAULT 0,
"keep_history" INT NOT NULL DEFAULT -2,
- "ttl" INT NOT NULL DEFAULT -2,
+ "ttl" INT NOT NULL DEFAULT 0,
"cache_nbEntries" INT DEFAULT 0,
"cache_nbUnreads" INT DEFAULT 0,
FOREIGN KEY ("category") REFERENCES "%1$scategory" ("id") ON DELETE SET NULL ON UPDATE CASCADE
diff --git a/app/SQL/install.sql.sqlite.php b/app/SQL/install.sql.sqlite.php
index d485e2120..d8e670bc8 100644
--- a/app/SQL/install.sql.sqlite.php
+++ b/app/SQL/install.sql.sqlite.php
@@ -20,7 +20,7 @@ $SQL_CREATE_TABLES = array(
`httpAuth` varchar(511) DEFAULT NULL,
`error` boolean DEFAULT 0,
`keep_history` MEDIUMINT NOT NULL DEFAULT -2,
- `ttl` INT NOT NULL DEFAULT -2,
+ `ttl` INT NOT NULL DEFAULT 0,
`cache_nbEntries` int DEFAULT 0,
`cache_nbUnreads` int DEFAULT 0,
FOREIGN KEY (`category`) REFERENCES `category`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php
index 807c249d3..ec77be317 100644
--- a/app/i18n/cz/sub.php
+++ b/app/i18n/cz/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Popis',
'empty' => 'Kanál je prázdný. Ověřte prosím zda je ještě autorem udržován.',
'error' => 'Vyskytl se problém s kanálem. Ověřte že je vždy dostupný, prosím, a poté jej aktualizujte.',
- 'in_main_stream' => 'Zobrazit ve “Všechny kanály”',
'informations' => 'Informace',
'keep_history' => 'Zachovat tento minimální počet článků',
'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Nejsou označeny žádné kanály.',
'number_entries' => '%d článků',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Zobrazit ve “Všechny kanály”',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Statistika',
'think_to_add' => 'Můžete přidat kanály.',
'title' => 'Název',
diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php
index 4ffef4302..6d41d0e5a 100644
--- a/app/i18n/de/sub.php
+++ b/app/i18n/de/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Beschreibung',
'empty' => 'Dieser Feed ist leer. Bitte stellen Sie sicher, dass er noch gepflegt wird.',
'error' => 'Dieser Feed ist auf ein Problem gestoßen. Bitte stellen Sie sicher, dass er immer lesbar ist und aktualisieren Sie ihn dann.',
- 'in_main_stream' => 'In Haupt-Feeds zeigen',
'informations' => 'Information',
'keep_history' => 'Minimale Anzahl an Artikeln, die behalten wird',
'moved_category_deleted' => 'Wenn Sie eine Kategorie entfernen, werden deren Feeds automatisch in die Kategorie <em>%s</em> eingefügt.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Kein Feed ausgewählt.',
'number_entries' => '%d Artikel',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'In Haupt-Feeds zeigen',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Statistiken',
'think_to_add' => 'Sie können Feeds hinzufügen.',
'title' => 'Titel',
diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php
index 47b15ae7a..b9bae7955 100644
--- a/app/i18n/en/sub.php
+++ b/app/i18n/en/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Description',
'empty' => 'This feed is empty. Please verify that it is still maintained.',
'error' => 'This feed has encountered a problem. Please verify that it is always reachable then update it.',
- 'in_main_stream' => 'Show in main stream',
'informations' => 'Information',
'keep_history' => 'Minimum number of articles to keep',
'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',
+ 'mute' => 'mute',
'no_selected' => 'No feed selected.',
'number_entries' => '%d articles',
+ 'priority' => array(
+ '_' => 'Visibility',
+ 'archived' => 'Do not show (archived)',
+ 'main_stream' => 'Show in main stream',
+ 'normal' => 'Show in its category',
+ ),
'stats' => 'Statistics',
'think_to_add' => 'You may add some feeds.',
'title' => 'Title',
diff --git a/app/i18n/es/sub.php b/app/i18n/es/sub.php
index 72eb06eb7..091c1e3e3 100755
--- a/app/i18n/es/sub.php
+++ b/app/i18n/es/sub.php
@@ -27,12 +27,18 @@ return array(
'description' => 'Descripción',
'empty' => 'La fuente está vacía. Por favor, verifica que siga activa.',
'error' => 'Hay un problema con esta fuente. Por favor, veritica que esté disponible y prueba de nuevo.',
- 'in_main_stream' => 'Mostrar en salida principal',
'informations' => 'Información',
'keep_history' => 'Número mínimo de artículos a conservar',
'moved_category_deleted' => 'Al borrar una categoría todas sus fuentes pasan automáticamente a la categoría <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'No hay funentes seleccionadas.',
'number_entries' => '%d artículos',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Mostrar en salida principal',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Estadísticas',
'think_to_add' => 'Puedes añadir fuentes.',
'title' => 'Título',
diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php
index 607863c8f..04be55aa5 100644
--- a/app/i18n/fr/sub.php
+++ b/app/i18n/fr/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Description',
'empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.',
'error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.',
- 'in_main_stream' => 'Afficher dans le flux principal',
'informations' => 'Informations',
'keep_history' => 'Nombre minimum d’articles à conserver',
'moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
+ 'mute' => 'muet',
'no_selected' => 'Aucun flux sélectionné.',
'number_entries' => '%d articles',
+ 'priority' => array(
+ '_' => 'Visibilité',
+ 'archived' => 'Ne pas afficher (archivé)',
+ 'main_stream' => 'Afficher dans le flux principal',
+ 'normal' => 'Afficher dans sa catégorie',
+ ),
'stats' => 'Statistiques',
'think_to_add' => 'Vous pouvez ajouter des flux.',
'title' => 'Titre',
diff --git a/app/i18n/he/sub.php b/app/i18n/he/sub.php
index 333de0edf..849a1d5bd 100644
--- a/app/i18n/he/sub.php
+++ b/app/i18n/he/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'תיאור',
'empty' => 'הזנה זו ריקה. אנא ודאו שהיא עדיין מתוחזקת.',
'error' => 'הזנה זו נתקלה בשגיאה, אנא ודאו שהיא תקינה ואז נסו שנית.',
- 'in_main_stream' => 'הצגה בזרם המרכזי',
'informations' => 'מידע',
'keep_history' => 'מסםר מינימלי של מאמרים לשמור',
'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'אף הזנה לא נבחרה.',
'number_entries' => '%d מאמרים',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'הצגה בזרם המרכזי',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'סטטיסטיקות',
'think_to_add' => 'ניתן להוסיף הזנות חדשות.',
'title' => 'כותרת',
diff --git a/app/i18n/it/sub.php b/app/i18n/it/sub.php
index fe18855fb..698e64481 100644
--- a/app/i18n/it/sub.php
+++ b/app/i18n/it/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Descrizione',
'empty' => 'Questo feed non contiene articoli. Per favore verifica il sito direttamente.',
'error' => 'Questo feed ha generato un errore. Per favore verifica se ancora disponibile.',
- 'in_main_stream' => 'Mostra in homepage',
'informations' => 'Informazioni',
'keep_history' => 'Numero minimo di articoli da mantenere',
'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Nessun feed selezionato.',
'number_entries' => '%d articoli',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Mostra in homepage', // TODO
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Statistiche',
'think_to_add' => 'Aggiungi feed.',
'title' => 'Titolo',
diff --git a/app/i18n/kr/sub.php b/app/i18n/kr/sub.php
index b8f2385b3..d290dd635 100644
--- a/app/i18n/kr/sub.php
+++ b/app/i18n/kr/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => '설명',
'empty' => '이 피드는 비어있습니다. 피드가 계속 운영되고 있는지 확인하세요.',
'error' => '이 피드에 문제가 발생했습니다. 이 피드에 접근 권한이 있는지 확인하세요.',
- 'in_main_stream' => '메인 스트림에 표시하기',
'informations' => '정보',
'keep_history' => '최소 유지 글 개수',
'moved_category_deleted' => '카테고리를 삭제하면, 해당 카테고리 아래에 있던 피드들은 자동적으로 <em>%s</em> 아래로 분류됩니다.',
+ 'mute' => 'mute', // TODO
'no_selected' => '선택된 피드가 없습니다.',
'number_entries' => '%d 개의 글',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => '메인 스트림에 표시하기', // TODO
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => '통계',
'think_to_add' => '피드를 추가할 수 있습니다.',
'title' => '제목',
diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php
index ce446778c..4b699d894 100644
--- a/app/i18n/nl/sub.php
+++ b/app/i18n/nl/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Omschrijving',
'empty' => 'Deze feed is leeg. Controleer of deze nog actueel is.',
'error' => 'Deze feed heeft problemen. Verifieer a.u.b het doeladres en actualiseer het.',
- 'in_main_stream' => 'Zichtbaar in het overzicht',
'informations' => 'Informatie',
'keep_history' => 'Minimum aantal artikelen om te houden',
'moved_category_deleted' => 'Als u een categorie verwijderd, worden de feeds automatisch geclassificeerd onder <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Geen feed geselecteerd.',
'number_entries' => '%d artikelen',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Zichtbaar in het overzicht',
+ 'normal' => 'Show in its category', // TODO
+ ),
'pubsubhubbub' => 'Directe notificaties met PubSubHubbub',
'stats' => 'Statistieken',
'think_to_add' => 'Voeg wat feeds toe.',
diff --git a/app/i18n/pt-br/sub.php b/app/i18n/pt-br/sub.php
index 4249dcabf..09dde718f 100644
--- a/app/i18n/pt-br/sub.php
+++ b/app/i18n/pt-br/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Descrição',
'empty' => 'Este feed está vazio. Por favor verifique ele ainda é mantido.',
'error' => 'Este feed encontra-se com problema. Por favor verifique se ele ainda está disponível e atualize-o.',
- 'in_main_stream' => 'Mostrar na tela principal',
'informations' => 'Informações',
'keep_history' => 'Número mínimo de artigos para manter',
'moved_category_deleted' => 'Quando você deleta uma categoria, seus feeds são automaticamente classificados como <em>%s</em>.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Nenhum feed selecionado.',
'number_entries' => '%d artigos',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Mostrar na tela principal',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Estatísticas',
'think_to_add' => 'Você deve adicionar alguns feeds.',
'title' => 'Título',
diff --git a/app/i18n/ru/sub.php b/app/i18n/ru/sub.php
index 6a5530de0..9e360630a 100644
--- a/app/i18n/ru/sub.php
+++ b/app/i18n/ru/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Description',// TODO
'empty' => 'This feed is empty. Please verify that it is still maintained.',// TODO
'error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.',// TODO
- 'in_main_stream' => 'Show in main stream',// TODO
'informations' => 'Information',// TODO
'keep_history' => 'Minimum number of articles to keep',// TODO
'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',// TODO
+ 'mute' => 'mute', // TODO
'no_selected' => 'No feed selected.',// TODO
'number_entries' => '%d articles',// TODO
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Show in main stream', // TODO
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'Statistics',// TODO
'think_to_add' => 'You may add some feeds.',// TODO
'title' => 'Title',// TODO
diff --git a/app/i18n/tr/sub.php b/app/i18n/tr/sub.php
index 0bbaeec5b..871731158 100644
--- a/app/i18n/tr/sub.php
+++ b/app/i18n/tr/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => 'Tanım',
'empty' => 'Bu akış boş. Lütfen akışın aktif olduğuna emin olun.',
'error' => 'Bu akışda bir hatayla karşılaşıldı. Lütfen akışın sürekli ulaşılabilir olduğuna emin olun.',
- 'in_main_stream' => 'Ana akışda göster',
'informations' => 'Bilgi',
'keep_history' => 'En az tutulacak makale sayısı',
'moved_category_deleted' => 'Bir kategoriyi silerseniz, içerisindeki akışlar <em>%s</em> içerisine yerleşir.',
+ 'mute' => 'mute', // TODO
'no_selected' => 'Hiçbir akış seçilmedi.',
'number_entries' => '%d makale',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => 'Ana akışda göster',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => 'İstatistikler',
'think_to_add' => 'Akış ekleyebilirsiniz.',
'title' => 'Başlık',
diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php
index 026f436d7..c25875b41 100644
--- a/app/i18n/zh-cn/sub.php
+++ b/app/i18n/zh-cn/sub.php
@@ -32,12 +32,18 @@ return array(
'description' => '描述',
'empty' => '此源为空。请确认它是否正常更新。',
'error' => '此源遇到一些问题。请在确认是否能正常访问后重试。',
- 'in_main_stream' => '在首页中显示',
'informations' => '信息',
'keep_history' => '至少保存的文章数',
'moved_category_deleted' => '删除分类时,其中的 RSS 源会自动归类到 <em>%s</em>',
+ 'mute' => 'mute', // TODO
'no_selected' => '未选择 RSS 源。',
'number_entries' => '%d 篇文章',
+ 'priority' => array(
+ '_' => 'Visibility', // TODO
+ 'archived' => 'Do not show (archived)', // TODO
+ 'main_stream' => '在首页中显示',
+ 'normal' => 'Show in its category', // TODO
+ ),
'stats' => '统计',
'think_to_add' => '你可以添加一些 RSS 源。',
'title' => '标题',
diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml
index 3e1ee44dd..97c0fb0d9 100644
--- a/app/layout/aside_feed.phtml
+++ b/app/layout/aside_feed.phtml
@@ -53,7 +53,7 @@
foreach ($feeds as $feed) {
$f_active = FreshRSS_Context::isCurrentGet('f_' . $feed->id());
?>
- <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError() ? ' error' : ''; ?><?php echo $feed->nbEntries() <= 0 ? ' empty' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
+ <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $f_active ? ' active' : '', $feed->mute() ? ' mute' : ''; ?><?php echo $feed->inError() ? ' error' : ''; ?><?php echo $feed->nbEntries() <= 0 ? ' empty' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
<div class="dropdown no-mobile">
<div class="dropdown-target"></div>
<a class="dropdown-toggle" data-fweb="<?php echo $feed->website(); ?>"><?php echo _i('configure'); ?></a>
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index bf87a255a..595309f49 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -65,12 +65,13 @@
</div>
</div>
<div class="form-group">
- <label class="group-name" for="priority"><?php echo _t('sub.feed.in_main_stream'); ?></label>
+ <label class="group-name" for="priority"><?php echo _t('sub.feed.priority'); ?></label>
<div class="group-controls">
- <label class="checkbox" for="priority">
- <input type="checkbox" name="priority" id="priority" value="10"<?php echo $this->feed->priority() > 0 ? ' checked="checked"' : ''; ?> />
- <?php echo _t('gen.short.yes'); ?>
- </label>
+ <select name="priority" id="priority">
+ <option value='<?php echo FreshRSS_Feed::PRIORITY_MAIN_STREAM;?>' <?php if (FreshRSS_Feed::PRIORITY_MAIN_STREAM === $this->feed->priority()) {echo 'selected="selected"';}?>><?php echo _t('sub.feed.priority.main_stream'); ?></option>
+ <option value='<?php echo FreshRSS_Feed::PRIORITY_NORMAL;?>' <?php if (FreshRSS_Feed::PRIORITY_NORMAL === $this->feed->priority()) {echo 'selected="selected"';}?>><?php echo _t('sub.feed.priority.normal'); ?></option>
+ <option value='<?php echo FreshRSS_Feed::PRIORITY_ARCHIVED;?>' <?php if (FreshRSS_Feed::PRIORITY_ARCHIVED === $this->feed->priority()) {echo 'selected="selected"';}?>><?php echo _t('sub.feed.priority.archived'); ?></option>
+ </select>
</div>
</div>
@@ -111,11 +112,11 @@
<div class="group-controls">
<select class="number" name="ttl" id="ttl" required="required"><?php
$found = false;
- foreach (array(-2 => _t('gen.short.by_default'), 900 => '15min', 1200 => '20min', 1500 => '25min', 1800 => '30min', 2700 => '45min',
+ foreach (array(FreshRSS_Feed::TTL_DEFAULT => _t('gen.short.by_default'), 900 => '15min', 1200 => '20min', 1500 => '25min', 1800 => '30min', 2700 => '45min',
3600 => '1h', 5400 => '1.5h', 7200 => '2h', 10800 => '3h', 14400 => '4h', 18800 => '5h', 21600 => '6h', 25200 => '7h', 28800 => '8h',
36000 => '10h', 43200 => '12h', 64800 => '18h',
86400 => '1d', 129600 => '1.5d', 172800 => '2d', 259200 => '3d', 345600 => '4d', 432000 => '5d', 518400 => '6d',
- 604800 => '1wk', 1209600 => '2wk', 1814400 => '3wk', 2419200 => '4wk', 2629744 => '1mo', -1 => '∞') as $v => $t) {
+ 604800 => '1wk', 1209600 => '2wk', 1814400 => '3wk', 2419200 => '4wk', 2629744 => '1mo') as $v => $t) {
echo '<option value="' . $v . ($this->feed->ttl() === $v ? '" selected="selected' : '') . '">' . $t . '</option>';
if ($this->feed->ttl() == $v) {
$found = true;
@@ -125,6 +126,10 @@
echo '<option value="' . intval($this->feed->ttl()) . '" selected="selected">' . intval($this->feed->ttl()) . 's</option>';
}
?></select>
+ <label for="mute">
+ <input type="checkbox" name="mute" id="mute" value="1"<?php echo $this->feed->mute() ? ' checked="checked"' : ''; ?> />
+ <?php echo _t('sub.feed.mute'); ?>
+ </label>
</div>
</div>
<div class="form-group">
diff --git a/app/views/index/global.phtml b/app/views/index/global.phtml
index f35732c8f..2f25b6dc2 100644
--- a/app/views/index/global.phtml
+++ b/app/views/index/global.phtml
@@ -37,7 +37,7 @@
$empty = $feed->nbEntries() === 0 ? ' empty' : '';
$url_base['params']['get'] = 'f_' . $feed->id();
?>
- <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $error, $empty; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
+ <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $error, $empty, $feed->mute() ? ' mute' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
<img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" />
<a class="item-title" data-unread="<?php echo format_number($feed->nbNotRead()); ?>" href="<?php echo Minz_Url::display($url_base); ?>"><?php echo $feed->name(); ?></a>
</li>
diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml
index 48f760d3e..26af0bd7c 100644
--- a/app/views/subscription/index.phtml
+++ b/app/views/subscription/index.phtml
@@ -125,7 +125,7 @@
$error = $feed->inError() ? ' error' : '';
$empty = $feed->nbEntries() == 0 ? ' empty' : '';
?>
- <li class="item feed<?php echo $error, $empty; ?>"
+ <li class="item feed<?php echo $error, $empty, $feed->mute() ? ' mute': ''; ?>"
draggable="true"
data-feed-id="<?php echo $feed->id(); ?>"
dropzone="move">
diff --git a/p/api/greader.php b/p/api/greader.php
index 99304f4ec..72f886190 100644
--- a/p/api/greader.php
+++ b/p/api/greader.php
@@ -261,8 +261,8 @@ function subscriptionList() {
$pdo = new MyPDO();
$stm = $pdo->prepare('SELECT f.id, f.name, f.url, f.website, c.id as c_id, c.name as c_name FROM `%_feed` f
- INNER JOIN `%_category` c ON c.id = f.category');
- $stm->execute();
+ INNER JOIN `%_category` c ON c.id = f.category AND f.priority >= :priority_normal');
+ $stm->execute(array(':priority_normal' => FreshRSS_Feed::PRIORITY_NORMAL));
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
$salt = FreshRSS_Context::$system_conf->salt;
diff --git a/p/themes/base-theme/template.css b/p/themes/base-theme/template.css
index e5e1bca05..72487ca17 100644
--- a/p/themes/base-theme/template.css
+++ b/p/themes/base-theme/template.css
@@ -71,6 +71,9 @@ img.favicon {
width: 16px;
vertical-align: middle;
}
+.feed.mute::before {
+ content: '🔇';
+}
/*=== Videos */
iframe, embed, object, video {