From 878e96202e8a22e4857b98e29b0a1fce68eccbc9 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 15 Dec 2013 03:30:24 +0100 Subject: Grosse refactorisation pour permettre le chargement automatique des classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C'est parti de changements pour https://github.com/marienfressinaud/FreshRSS/issues/255 et finalement j'ai continué la refactorisation... Ajout de préfixes FreshRSS_ et Minz_ sur le modèle de SimplePie_. Toutes les classes sont maintenant en chargement automatique (devrait améliorer les performances en évitant de charger plein de classes inutilisées, et faciliter la maintenance). Suppression de set_include_path(). Si souhaité, certaines classes de Minz pourraient être déplacées dans un sous-répertoire, par exemple les exceptions. Tests et relecture nécessaires. --- app/views/javascript/actualize.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/views/javascript') diff --git a/app/views/javascript/actualize.phtml b/app/views/javascript/actualize.phtml index f39540a9a..69689133c 100644 --- a/app/views/javascript/actualize.phtml +++ b/app/views/javascript/actualize.phtml @@ -1,12 +1,12 @@ var feeds = new Array (); feeds as $feed) { ?> -feeds.push (" 'feed', 'a' => 'actualize', 'params' => array ('id' => $feed->id (), 'ajax' => '1')), 'php'); ?>"); +feeds.push (" 'feed', 'a' => 'actualize', 'params' => array ('id' => $feed->id (), 'ajax' => '1')), 'php'); ?>"); function initProgressBar (init) { if (init) { $("body").after ("\
\ - 0 / " + feeds.length + "
\ + 0 / " + feeds.length + "
\ \
"); } else { -- cgit v1.2.3 From b48b7939d78ffbd35a7efca792e2cb9897e8f160 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 2 Jan 2014 19:08:21 +0100 Subject: JavaScript : Bug actualize quand il n'y a aucun flux + un peu de JSLint. --- app/views/javascript/actualize.phtml | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'app/views/javascript') diff --git a/app/views/javascript/actualize.phtml b/app/views/javascript/actualize.phtml index 69689133c..1f6072c29 100644 --- a/app/views/javascript/actualize.phtml +++ b/app/views/javascript/actualize.phtml @@ -1,37 +1,41 @@ -var feeds = new Array (); +"use strict"; +var feeds = []; feeds as $feed) { ?> -feeds.push (" 'feed', 'a' => 'actualize', 'params' => array ('id' => $feed->id (), 'ajax' => '1')), 'php'); ?>"); +feeds.push(" 'feed', 'a' => 'actualize', 'params' => array ('id' => $feed->id (), 'ajax' => '1')), 'php'); ?>"); -function initProgressBar (init) { +function initProgressBar(init) { if (init) { - $("body").after ("\
\ + $("body").after("\
\ 0 / " + feeds.length + "
\ \
"); } else { - window.location.reload (); + window.location.reload(); } } -function updateProgressBar (i) { +function updateProgressBar(i) { $("#actualizeProgressBar").val(i); - $("#actualizeProgress .progress").html (i + " / " + feeds.length); + $("#actualizeProgress .progress").html(i + " / " + feeds.length); } -function updateFeeds () { - initProgressBar (true); +function updateFeeds() { + if (feeds.length === 0) { + return; + } + initProgressBar(true); var i = 0; for (var f in feeds) { - $.ajax ({ + $.ajax({ type: 'POST', url: feeds[f], - }).done (function (data) { + }).done(function (data) { i++; - updateProgressBar (i); + updateProgressBar(i); - if (i == feeds.length) { - initProgressBar (false); + if (i === feeds.length) { + initProgressBar(false); } }); } -- cgit v1.2.3 From 3d876091e1268e3ccd5036449a4deb5134936206 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 9 Jan 2014 23:17:35 +0100 Subject: Nouveau rafraîchissement automatique du nombre d'articles non lus + session Persona MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Devrait aussi résoudre https://github.com/marienfressinaud/FreshRSS/issues/358 À tester --- CHANGELOG | 2 + app/Controllers/javascriptController.php | 8 ++- app/views/javascript/nbUnreadsPerFeed.phtml | 8 +++ p/i/index.php | 1 + p/scripts/main.js | 96 +++++++++++++++++------------ 5 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 app/views/javascript/nbUnreadsPerFeed.phtml (limited to 'app/views/javascript') diff --git a/CHANGELOG b/CHANGELOG index 45936ac03..fe856fe4a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,8 @@ (voir réorganisation ci-dessous) * Pour les versions suivantes, juste garder “./data/config.php” et “./data/*_user.php”, éventuellement “./data/persona/*” +* Rafraîchissement automatique du nombre d’articles non lus toutes les minutes (utilise le cache HTTP à bon escient) + * Permet aussi de conserver la session valide, surtout dans le cas de Persona * Importation OPML instantanée et plus tolérante * Nouvelle gestion des favicons avec téléchargement en parallèle * Nouvelles options diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index e7e25f656..2d0ff4984 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -3,11 +3,17 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { public function firstAction () { $this->view->_useLayout (false); - header('Content-type: text/javascript'); } public function actualizeAction () { + header('Content-Type: text/javascript; charset=UTF-8'); $feedDAO = new FreshRSS_FeedDAO (); $this->view->feeds = $feedDAO->listFeeds (); } + + public function nbUnreadsPerFeedAction() { + header('Content-Type: application/json; charset=UTF-8'); + $catDAO = new FreshRSS_CategoryDAO(); + $this->view->categories = $catDAO->listCategories(true, false); + } } diff --git a/app/views/javascript/nbUnreadsPerFeed.phtml b/app/views/javascript/nbUnreadsPerFeed.phtml new file mode 100644 index 000000000..68f98ce9e --- /dev/null +++ b/app/views/javascript/nbUnreadsPerFeed.phtml @@ -0,0 +1,8 @@ +categories as $cat) { + foreach ($cat->feeds() as $feed) { + $result[$feed->id()] = $feed->nbNotRead(); + } +} +echo json_encode($result); diff --git a/p/i/index.php b/p/i/index.php index 3dcf659c9..187bbabe8 100755 --- a/p/i/index.php +++ b/p/i/index.php @@ -26,6 +26,7 @@ if (file_exists ('install.php')) { session_cache_limiter(''); Minz_Session::init('FreshRSS'); + Minz_Session::_param('keepAlive', 1); //For Persona if (!file_exists(DATA_PATH . '/no-cache.txt')) { require(LIB_PATH . '/http-conditional.php'); diff --git a/p/scripts/main.js b/p/scripts/main.js index 8646d9b72..24fdfd3f3 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -25,6 +25,46 @@ function incLabel(p, inc) { return i > 0 ? ' (' + i + ')' : ''; } +function incUnreadsFeed(article, feed_id, nb) { + //Update unread: feed + var elem = $('#' + feed_id + '>.feed').get(0), + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0, + feed_priority = elem ? (parseInt(elem.getAttribute('data-priority'), 10) || 0) : 0; + if (elem) { + elem.setAttribute('data-unread', Math.max(0, feed_unreads + nb)); + } + + //Update unread: category + elem = $('#' + feed_id).parent().prevAll('.category').children(':first').get(0); + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; + if (elem) { + elem.setAttribute('data-unread', Math.max(0, feed_unreads + nb)); + } + + //Update unread: all + if (feed_priority > 0) { + elem = $('#aside_flux .all').children(':first').get(0); + if (elem) { + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; + elem.setAttribute('data-unread', Math.max(0, feed_unreads + nb)); + } + } + + //Update unread: favourites + if (article && article.closest('div').hasClass('favorite')) { + elem = $('#aside_flux .favorites').children(':first').get(0); + if (elem) { + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; + elem.setAttribute('data-unread', Math.max(0, feed_unreads + nb)); + } + } + + //Update unread: title + document.title = document.title.replace(/((?: \(\d+\))?)( · .*?)((?: \(\d+\))?)$/, function (m, p1, p2, p3) { + return incLabel(p1, nb) + p2 + incLabel(p3, feed_priority > 0 ? nb : 0); + }); +} + function mark_read(active, only_not_read) { if (active[0] === undefined || (only_not_read === true && !active.hasClass("not_read"))) { return false; @@ -51,45 +91,9 @@ function mark_read(active, only_not_read) { } $r.find('.icon').replaceWith(data.icon); - //Update unread: feed var feed_url = active.find(".website>a").attr("href"), - feed_id = feed_url.substr(feed_url.lastIndexOf('f_')), - elem = $('#' + feed_id + ' .feed').get(0), - feed_unread = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0, - feed_priority = elem ? (parseInt(elem.getAttribute('data-priority'), 10) || 0) : 0; - if (elem) { - elem.setAttribute('data-unread', Math.max(0, feed_unread + inc)); - } - - //Update unread: category - elem = $('#' + feed_id).parent().prevAll('.category').children(':first').get(0); - feed_unread = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; - if (elem) { - elem.setAttribute('data-unread', Math.max(0, feed_unread + inc)); - } - - //Update unread: all - if (feed_priority > 0) { - elem = $('#aside_flux .all').children(':first').get(0); - if (elem) { - feed_unread = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; - elem.setAttribute('data-unread', Math.max(0, feed_unread + inc)); - } - } - - //Update unread: favourites - if (active.closest('div').hasClass('favorite')) { - elem = $('#aside_flux .favorites').children(':first').get(0); - if (elem) { - feed_unread = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; - elem.setAttribute('data-unread', Math.max(0, feed_unread + inc)); - } - } - - //Update unread: title - document.title = document.title.replace(/((?: \(\d+\))?)( · .*?)((?: \(\d+\))?)$/, function (m, p1, p2, p3) { - return incLabel(p1, inc) + p2 + incLabel(p3, feed_priority > 0 ? inc : 0); - }); + feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); + incUnreadsFeed(active, feed_id, inc); }); } @@ -128,8 +132,8 @@ function mark_favorite(active) { if (active.closest('div').hasClass('not_read')) { var elem = $('#aside_flux .favorites').children(':first').get(0), - feed_unread = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; - elem.setAttribute('data-unread', Math.max(0, feed_unread + inc)); + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; + elem.setAttribute('data-unread', Math.max(0, feed_unreads + inc)); } }); } @@ -514,6 +518,17 @@ function init_notifications() { } } +function refreshUnreads() { + $.getJSON('./?c=javascript&a=nbUnreadsPerFeed').done(function (data) { + $.each(data, function(feed_id, nbUnreads) { + feed_id = 'f_' + feed_id; + var elem = $('#' + feed_id + '>.feed').get(0), + feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0; + incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads); + }); + }); +} + // var url_load_more = "", load_more = false, @@ -685,6 +700,7 @@ function init_all() { } init_confirm_action(); init_print_action(); + window.setInterval(refreshUnreads, 60000); if (window.console) { console.log('FreshRSS init done.'); } -- cgit v1.2.3 From eb50ab3b61ee2280dac2696598a58803e246fe22 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 11 Jan 2014 16:48:10 +0100 Subject: Mot de passe + nonce serveur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Début de https://github.com/marienfressinaud/FreshRSS/issues/104 --- README.md | 7 ++----- app/Controllers/javascriptController.php | 27 +++++++++++++++++++++++++++ app/Models/Configuration.php | 4 ++++ app/views/javascript/nonce.phtml | 2 ++ 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 app/views/javascript/nonce.phtml (limited to 'app/views/javascript') diff --git a/README.md b/README.md index 96e25f4df..4100a8638 100644 --- a/README.md +++ b/README.md @@ -74,17 +74,14 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ``` - ---- - # Bibliothèques incluses -* [SimplePie](https://github.com/simplepie/simplepie) +* [SimplePie](http://simplepie.org/) * [MINZ](https://github.com/marienfressinaud/MINZ) * [php-http-304](http://alexandre.alapetite.fr/doc-alex/php-http-304/) * [jQuery](http://jquery.com/) * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/) -## Uniquement dans certaines configurations +## Uniquement pour certaines options * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](http://code.google.com/p/phpquery/) * [Lazy Load](http://www.appelsiini.net/projects/lazyload) diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index 2d0ff4984..e29f439d8 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -16,4 +16,31 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { $catDAO = new FreshRSS_CategoryDAO(); $this->view->categories = $catDAO->listCategories(true, false); } + + // For Web-form login + public function nonceAction() { + header('Content-Type: application/json; charset=UTF-8'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T')); + header('Expires: 0'); + header('Cache-Control: private, no-cache, no-store, must-revalidate'); + header('Pragma: no-cache'); + + $user = isset($_GET['user']) ? $_GET['user'] : ''; + if (ctype_alnum($user)) { + try { + $conf = new FreshRSS_Configuration($user); + $hash = $conf->passwordHash; //CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". + if (strlen($hash) >= 60) { + $this->view->salt1 = substr($hash, 0, 29); + $this->view->nonce = sha1(Minz_Configuration::salt() . uniqid(mt_rand(), true)); + Minz_Session::_param ('nonce', $this->view->nonce); + return; //Success + } + } catch (Minz_Exception $me) { + Minz_Log::record ('Login failure: ' . $me->getMessage(), Minz_Log::WARNING); + } + } + $this->view->nonce = ''; //Failure + $this->view->salt1 = ''; + } } diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index c29e74603..8f394737a 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -9,6 +9,7 @@ class FreshRSS_Configuration { 'keep_history_default' => 0, 'mail_login' => '', 'token' => '', + 'passwordHash' => '', //CRYPT_BLOWFISH 'posts_per_page' => 20, 'view_mode' => 'normal', 'default_view' => 'not_read', @@ -162,6 +163,9 @@ class FreshRSS_Configuration { } } } + public function _passwordHash ($value) { + $this->data['passwordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : ''; + } public function _mail_login ($value) { $value = filter_var($value, FILTER_VALIDATE_EMAIL); if ($value) { diff --git a/app/views/javascript/nonce.phtml b/app/views/javascript/nonce.phtml new file mode 100644 index 000000000..4ac46c8fc --- /dev/null +++ b/app/views/javascript/nonce.phtml @@ -0,0 +1,2 @@ + $this->salt1, 'nonce' => $this->nonce)); -- cgit v1.2.3