From f59de4e2b679efb1ba4bbfd576a5ea07422cc169 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 15 Nov 2016 20:43:06 +0100 Subject: Stream JSON export Avoid large in-memory copies https://github.com/FreshRSS/FreshRSS/issues/1372 --- app/views/helpers/export/articles.phtml | 92 ++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 41 deletions(-) (limited to 'app/views') diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index ffdca1daa..2ad4a3abf 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -1,47 +1,57 @@ 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, - 'title' => $this->list_title, - 'author' => $username, - 'items' => array() - ); + $options = 0; + if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; + } - foreach ($this->entries as $entry) { - if (!isset($this->feed)) { - $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed ()); - } else { - $feed = $this->feed; - } + $articles = array( + 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, + 'title' => $this->list_title, + 'author' => $username, + 'items' => array(), + ); - $articles['items'][] = array( - 'id' => $entry->guid(), - 'categories' => array_values($entry->tags()), - 'title' => $entry->title(), - 'author' => $entry->author(), - 'published' => $entry->date(true), - 'updated' => $entry->date(true), - 'alternate' => array(array( - 'href' => $entry->link(), - 'type' => 'text/html' - )), - 'content' => array( - 'content' => $entry->content() - ), - 'origin' => array( - 'streamId' => $feed->id(), - 'title' => $feed->name(), - 'htmlUrl' => $feed->website(), - 'feedUrl' => $feed->url() - ) - ); - } + echo rtrim(json_encode($articles, $options), " ]}\n\r\t"); + $first = true; - $options = 0; - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - } + foreach ($this->entriesRaw as $entryRaw) { + $entry = FreshRSS_EntryDAO::daoToEntry($entryRaw); + if (!isset($this->feed)) { + $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed ()); + } else { + $feed = $this->feed; + } - echo json_encode($articles, $options); -?> + $article = array( + 'id' => $entry->guid(), + 'categories' => array_values($entry->tags()), + 'title' => $entry->title(), + 'author' => $entry->author(), + 'published' => $entry->date(true), + 'updated' => $entry->date(true), + 'alternate' => array(array( + 'href' => $entry->link(), + 'type' => 'text/html', + )), + 'content' => array( + 'content' => $entry->content(), + ), + 'origin' => array( + 'streamId' => $feed->id(), + 'title' => $feed->name(), + 'htmlUrl' => $feed->website(), + 'feedUrl' => $feed->url(), + ) + ); + + if ($first) { + $first = false; + } else { + echo ",\n"; + } + echo json_encode($article, $options); + } + + echo "\n]}\n"; -- cgit v1.2.3 From 8d3d2a7d7fc7d623e998b6dd97b7f4419cf0d60c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 15 Nov 2016 20:54:56 +0100 Subject: Minor code formatting of export helper --- app/views/helpers/export/articles.phtml | 96 ++++++++++++++++----------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'app/views') diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index 2ad4a3abf..9acf3cc83 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -1,57 +1,57 @@ = 0) { - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - } +$options = 0; +if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; +} - $articles = array( - 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, - 'title' => $this->list_title, - 'author' => $username, - 'items' => array(), - ); +$articles = array( + 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, + 'title' => $this->list_title, + 'author' => $username, + 'items' => array(), +); - echo rtrim(json_encode($articles, $options), " ]}\n\r\t"); - $first = true; +echo rtrim(json_encode($articles, $options), " ]}\n\r\t"), "\n"; +$first = true; - foreach ($this->entriesRaw as $entryRaw) { - $entry = FreshRSS_EntryDAO::daoToEntry($entryRaw); - if (!isset($this->feed)) { - $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed ()); - } else { - $feed = $this->feed; - } +foreach ($this->entriesRaw as $entryRaw) { + $entry = FreshRSS_EntryDAO::daoToEntry($entryRaw); + if (!isset($this->feed)) { + $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed()); + } else { + $feed = $this->feed; + } - $article = array( - 'id' => $entry->guid(), - 'categories' => array_values($entry->tags()), - 'title' => $entry->title(), - 'author' => $entry->author(), - 'published' => $entry->date(true), - 'updated' => $entry->date(true), - 'alternate' => array(array( - 'href' => $entry->link(), - 'type' => 'text/html', - )), - 'content' => array( - 'content' => $entry->content(), - ), - 'origin' => array( - 'streamId' => $feed->id(), - 'title' => $feed->name(), - 'htmlUrl' => $feed->website(), - 'feedUrl' => $feed->url(), - ) - ); + $article = array( + 'id' => $entry->guid(), + 'categories' => array_values($entry->tags()), + 'title' => $entry->title(), + 'author' => $entry->author(), + 'published' => $entry->date(true), + 'updated' => $entry->date(true), + 'alternate' => array(array( + 'href' => $entry->link(), + 'type' => 'text/html', + )), + 'content' => array( + 'content' => $entry->content(), + ), + 'origin' => array( + 'streamId' => $feed->id(), + 'title' => $feed->name(), + 'htmlUrl' => $feed->website(), + 'feedUrl' => $feed->url(), + ) + ); - if ($first) { - $first = false; - } else { - echo ",\n"; - } - echo json_encode($article, $options); + if ($first) { + $first = false; + } else { + echo ",\n"; } + echo json_encode($article, $options); +} - echo "\n]}\n"; +echo "\n]}\n"; -- cgit v1.2.3 From 1d5006d83fc84a0c653d8e2db42a4cfbdebdc5bb Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 16 Nov 2016 17:49:20 +0100 Subject: Error edge cases for JSON export --- app/views/helpers/export/articles.phtml | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'app/views') diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index 9acf3cc83..49c370023 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -17,9 +17,15 @@ echo rtrim(json_encode($articles, $options), " ]}\n\r\t"), "\n"; $first = true; foreach ($this->entriesRaw as $entryRaw) { + if (empty($entryRaw)) { + continue; + } $entry = FreshRSS_EntryDAO::daoToEntry($entryRaw); if (!isset($this->feed)) { $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed()); + if ($feed == null) { + $feed = $entry->feed(true); + } } else { $feed = $this->feed; } @@ -39,19 +45,22 @@ foreach ($this->entriesRaw as $entryRaw) { 'content' => $entry->content(), ), 'origin' => array( - 'streamId' => $feed->id(), - 'title' => $feed->name(), - 'htmlUrl' => $feed->website(), - 'feedUrl' => $feed->url(), + 'streamId' => $feed == null ? '' : $feed->id(), + 'title' => $feed == null ? '' : $feed->name(), + 'htmlUrl' => $feed == null ? '' : $feed->website(), + 'feedUrl' => $feed == null ? '' : $feed->url(), ) ); - if ($first) { - $first = false; - } else { - echo ",\n"; + $line = json_encode($article, $options); + if ($line != '') { + if ($first) { + $first = false; + } else { + echo ",\n"; + } + echo $line; } - echo json_encode($article, $options); } echo "\n]}\n"; -- cgit v1.2.3 From 332a4dec8690b658bcb878a20056aea33c673f69 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 24 Dec 2016 16:33:28 +0100 Subject: Option for cookie duration https://github.com/FreshRSS/FreshRSS/issues/1384 --- app/Controllers/authController.php | 4 ++++ app/Models/Auth.php | 11 ++++++++--- app/i18n/cz/gen.php | 2 +- app/i18n/de/gen.php | 2 +- app/i18n/en/gen.php | 2 +- app/i18n/fr/gen.php | 2 +- app/i18n/it/gen.php | 2 +- app/i18n/nl/gen.php | 2 +- app/i18n/ru/gen.php | 2 +- app/i18n/tr/gen.php | 2 +- app/views/auth/formLogin.phtml | 2 +- data/config.default.php | 3 +++ 12 files changed, 24 insertions(+), 12 deletions(-) (limited to 'app/views') diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index 9decba431..1398e4e49 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -113,6 +113,10 @@ class FreshRSS_auth_Controller extends Minz_ActionController { $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js'); Minz_View::appendScript(Minz_Url::display('/scripts/bcrypt.min.js?' . $file_mtime)); + $conf = Minz_Configuration::get('system'); + $limits = $conf->limits; + $this->view->cookie_days = round($limits['cookie_duration'] / 86400, 1); + if (Minz_Request::isPost()) { $nonce = Minz_Session::param('nonce'); $username = Minz_Request::param('username', ''); diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 3313fdf3f..042210eaf 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -219,8 +219,8 @@ class FreshRSS_FormAuth { } public static function makeCookie($username, $password_hash) { + $conf = Minz_Configuration::get('system'); do { - $conf = Minz_Configuration::get('system'); $token = sha1($conf->salt . $username . uniqid(mt_rand(), true)); $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; } while (file_exists($token_file)); @@ -229,7 +229,9 @@ class FreshRSS_FormAuth { return false; } - $expire = time() + 2629744; //1 month //TODO: Use a configuration instead + $limits = $conf->limits; + $cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration']; + $expire = time() + $cookie_duration; Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); return $token; } @@ -247,7 +249,10 @@ class FreshRSS_FormAuth { } public static function purgeTokens() { - $oldest = time() - 2629744; // 1 month // TODO: Use a configuration instead + $conf = Minz_Configuration::get('system'); + $limits = $conf->limits; + $cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration']; + $oldest = time() - $cookie_duration; foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php index e73325c55..6722a02e5 100644 --- a/app/i18n/cz/gen.php +++ b/app/i18n/cz/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email', - 'keep_logged_in' => 'Zapamatovat přihlášení (1 měsíc)', + 'keep_logged_in' => 'Zapamatovat přihlášení (%s dny)', 'login' => 'Login', 'logout' => 'Odhlášení', 'password' => array( diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php index c6e7f1ef3..3f1238edc 100644 --- a/app/i18n/de/gen.php +++ b/app/i18n/de/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'E-Mail-Adresse', - 'keep_logged_in' => 'Eingeloggt bleiben (1 Monat)', + 'keep_logged_in' => 'Eingeloggt bleiben (%s Tage)', 'login' => 'Anmelden', 'logout' => 'Abmelden', 'password' => array( diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 17b47ba2f..c68a0f07b 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email address', - 'keep_logged_in' => 'Keep me logged in (1 month)', + 'keep_logged_in' => 'Keep me logged in (%s days)', 'login' => 'Login', 'logout' => 'Logout', 'password' => array( diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index d61a716a7..b5dc098ae 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Adresse courriel', - 'keep_logged_in' => 'Rester connecté (1 mois)', + 'keep_logged_in' => 'Rester connecté (%s jours)', 'login' => 'Connexion', 'logout' => 'Déconnexion', 'password' => array( diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php index c02ddd13a..01c0afba8 100644 --- a/app/i18n/it/gen.php +++ b/app/i18n/it/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Indirizzo email', - 'keep_logged_in' => 'Ricorda i dati (1 mese)', + 'keep_logged_in' => 'Ricorda i dati (%s giorni)', 'login' => 'Accedi', 'logout' => 'Esci', 'password' => array( diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index 7e03229c9..a156697d5 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email adres', - 'keep_logged_in' => 'Ingelogd blijven voor (1 maand)', + 'keep_logged_in' => 'Ingelogd blijven voor (%s dagen)', 'login' => 'Log in', 'logout' => 'Log uit', 'password' => array( diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php index eecd72749..130fac4ed 100644 --- a/app/i18n/ru/gen.php +++ b/app/i18n/ru/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email address', - 'keep_logged_in' => 'Keep me logged in (1 month)', + 'keep_logged_in' => 'Keep me logged in (%s дней)', 'login' => 'Login', 'logout' => 'Logout', 'password' => array( diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php index 865dbd4e2..7f9d3d8e0 100644 --- a/app/i18n/tr/gen.php +++ b/app/i18n/tr/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email adresleri', - 'keep_logged_in' => '(1 ay) oturumu açık tut', + 'keep_logged_in' => '(%s günler) oturumu açık tut', 'login' => 'Giriş', 'logout' => 'Çıkış', 'password' => array( diff --git a/app/views/auth/formLogin.phtml b/app/views/auth/formLogin.phtml index 4bbc8ed55..a8213b7ae 100644 --- a/app/views/auth/formLogin.phtml +++ b/app/views/auth/formLogin.phtml @@ -20,7 +20,7 @@

diff --git a/data/config.default.php b/data/config.default.php index 8b07b85cd..433207a9c 100644 --- a/data/config.default.php +++ b/data/config.default.php @@ -74,6 +74,9 @@ return array( 'limits' => array( + # Duration in seconds of the login cookie. + 'cookie_duration' => 2592000, + # Duration in seconds of the SimplePie cache, # during which a query to the RSS feed will return the local cached version. # Especially important for multi-user setups. -- cgit v1.2.3