Upgrade sources to 0.7.4
|
@ -1,5 +1,25 @@
|
|||
# Journal des modifications
|
||||
|
||||
## 2014-08-xx FreshRSS 0.7.4
|
||||
|
||||
* UI
|
||||
* Hide categories/feeds with unread articles when showing only unread articles
|
||||
* Dynamic favicon showing the number of unread articles
|
||||
* New theme: Screwdriver by Mister aiR
|
||||
* Statistics
|
||||
* New page with article repartition
|
||||
* Improvements
|
||||
* Security
|
||||
* Basic protection against XSRF (Cross-Site Request Forgery) based on HTTP Referer (POST requests only)
|
||||
* API
|
||||
* Compatible with lighttpd
|
||||
* Misc.
|
||||
* Changed lazyload implementation
|
||||
* Support of HTML5 notifications for new upcoming articles
|
||||
* Add option to stay logged in
|
||||
* Bux fixes in export function, add/remove users, keyboard shortcuts, etc.
|
||||
|
||||
|
||||
## 2014-07-21 FreshRSS 0.7.3
|
||||
|
||||
* New options
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
* [English version](README.md)
|
||||
|
||||
# FreshRSS
|
||||
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/).
|
||||
|
||||
|
@ -8,8 +10,8 @@ Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture an
|
|||
* Site officiel : http://freshrss.org
|
||||
* Démo : http://demo.freshrss.org/
|
||||
* Développeur : Marien Fressinaud <dev@marienfressinaud.fr>
|
||||
* Version actuelle : 0.7.3
|
||||
* Date de publication 2014-07-21
|
||||
* Version actuelle : 0.7.4
|
||||
* Date de publication 2014-08-24
|
||||
* License [GNU AGPL 3](http://www.gnu.org/licenses/agpl-3.0.html)
|
||||
|
||||
![Logo de FreshRSS](http://marienfressinaud.fr/data/images/freshrss/freshrss_title.png)
|
||||
|
@ -31,11 +33,11 @@ Privilégiez pour cela des demandes sur GitHub
|
|||
# Pré-requis
|
||||
* Serveur modeste, par exemple sous Linux ou Windows
|
||||
* Fonctionne même sur un Raspberry Pi avec des temps de réponse < 1s (testé sur 150 flux, 22k articles, soit 32Mo de données partiellement compressées)
|
||||
* Serveur Web Apache2 ou Nginx (non testé sur les autres)
|
||||
* Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres)
|
||||
* PHP 5.2.1+ (PHP 5.3.7+ recommandé)
|
||||
* Requis : [PDO_MySQL](http://php.net/pdo-mysql), [cURL](http://php.net/curl), [LibXML](http://php.net/xml), [PCRE](http://php.net/pcre), [ctype](http://php.net/ctype)
|
||||
* Recommandés : [JSON](http://php.net/json), [zlib](http://php.net/zlib), [mbstring](http://php.net/mbstring), [iconv](http://php.net/iconv), [Zip](http://php.net/zip)
|
||||
* MySQL 5.0.3+ (recommandé) ou SQLite 3.7.4+ (en bêta)
|
||||
* Requis : [PDO_MySQL](http://php.net/pdo-mysql) ou [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (seulement pour accès API sur platformes < 64 bits)
|
||||
* Recommandés : [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [zlib](http://php.net/zlib), [Zip](http://php.net/zip)
|
||||
* MySQL 5.0.3+ (recommandé) ou SQLite 3.7.4+
|
||||
* Un navigateur Web récent tel Firefox 4+, Chrome, Opera, Safari, Internet Explorer 9+
|
||||
* Fonctionne aussi sur mobile
|
||||
|
||||
|
@ -93,7 +95,6 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql
|
|||
## 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)
|
||||
|
||||
## Si les fonctions natives ne sont pas disponibles
|
||||
* [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198)
|
|
@ -184,6 +184,8 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
|
|||
$this->view->conf->_default_view((int)Minz_Request::param('default_view', FreshRSS_Entry::STATE_ALL));
|
||||
$this->view->conf->_auto_load_more(Minz_Request::param('auto_load_more', false));
|
||||
$this->view->conf->_display_posts(Minz_Request::param('display_posts', false));
|
||||
$this->view->conf->_display_categories(Minz_Request::param('display_categories', false));
|
||||
$this->view->conf->_hide_read_feeds(Minz_Request::param('hide_read_feeds', false));
|
||||
$this->view->conf->_onread_jump_next(Minz_Request::param('onread_jump_next', false));
|
||||
$this->view->conf->_lazyload(Minz_Request::param('lazyload', false));
|
||||
$this->view->conf->_sticky_post(Minz_Request::param('sticky_post', false));
|
||||
|
|
|
@ -1,26 +1,38 @@
|
|||
<?php
|
||||
|
||||
class FreshRSS_error_Controller extends Minz_ActionController {
|
||||
public function indexAction () {
|
||||
switch (Minz_Request::param ('code')) {
|
||||
case 403:
|
||||
$this->view->code = 'Error 403 - Forbidden';
|
||||
break;
|
||||
case 404:
|
||||
$this->view->code = 'Error 404 - Not found';
|
||||
break;
|
||||
case 500:
|
||||
$this->view->code = 'Error 500 - Internal Server Error';
|
||||
break;
|
||||
case 503:
|
||||
$this->view->code = 'Error 503 - Service Unavailable';
|
||||
break;
|
||||
default:
|
||||
$this->view->code = 'Error 404 - Not found';
|
||||
public function indexAction() {
|
||||
switch (Minz_Request::param('code')) {
|
||||
case 403:
|
||||
$this->view->code = 'Error 403 - Forbidden';
|
||||
break;
|
||||
case 404:
|
||||
$this->view->code = 'Error 404 - Not found';
|
||||
break;
|
||||
case 500:
|
||||
$this->view->code = 'Error 500 - Internal Server Error';
|
||||
break;
|
||||
case 503:
|
||||
$this->view->code = 'Error 503 - Service Unavailable';
|
||||
break;
|
||||
default:
|
||||
$this->view->code = 'Error 404 - Not found';
|
||||
}
|
||||
|
||||
$this->view->logs = Minz_Request::param ('logs');
|
||||
|
||||
Minz_View::prependTitle ($this->view->code . ' · ');
|
||||
|
||||
$errors = Minz_Request::param('logs', array());
|
||||
$this->view->errorMessage = trim(implode($errors));
|
||||
if ($this->view->errorMessage == '') {
|
||||
switch(Minz_Request::param('code')) {
|
||||
case 403:
|
||||
$this->view->errorMessage = Minz_Translate::t('forbidden_access');
|
||||
break;
|
||||
case 404:
|
||||
default:
|
||||
$this->view->errorMessage = Minz_Translate::t('page_not_found');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Minz_View::prependTitle($this->view->code . ' · ');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
if (!$this->view->loginOk) {
|
||||
Minz_Error::error(
|
||||
403,
|
||||
array('error' => array(Minz_Translate::t('access_denied')))
|
||||
array('error' => array(_t('access_denied')))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -20,33 +20,51 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
$this->view->categories = $this->catDAO->listCategories();
|
||||
$this->view->feeds = $this->feedDAO->listFeeds();
|
||||
|
||||
Minz_View::prependTitle(Minz_Translate::t('import_export') . ' · ');
|
||||
Minz_View::prependTitle(_t('import_export') . ' · ');
|
||||
}
|
||||
|
||||
public function importAction() {
|
||||
if (Minz_Request::isPost() && $_FILES['file']['error'] == 0) {
|
||||
@set_time_limit(300);
|
||||
if (!Minz_Request::isPost()) {
|
||||
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
|
||||
}
|
||||
|
||||
$file = $_FILES['file'];
|
||||
$type_file = $this->guessFileType($file['name']);
|
||||
$file = $_FILES['file'];
|
||||
$status_file = $file['error'];
|
||||
|
||||
$list_files = array(
|
||||
'opml' => array(),
|
||||
'json_starred' => array(),
|
||||
'json_feed' => array()
|
||||
);
|
||||
if ($status_file !== 0) {
|
||||
Minz_Log::error('File cannot be uploaded. Error code: ' . $status_file);
|
||||
Minz_Request::bad(_t('file_cannot_be_uploaded'),
|
||||
array('c' => 'importExport', 'a' => 'index'));
|
||||
}
|
||||
|
||||
// We try to list all files according to their type
|
||||
// A zip file is first opened and then its files are listed
|
||||
$list = array();
|
||||
if ($type_file === 'zip') {
|
||||
$zip = zip_open($file['tmp_name']);
|
||||
@set_time_limit(300);
|
||||
|
||||
while (($zipfile = zip_read($zip)) !== false) {
|
||||
$type_zipfile = $this->guessFileType(
|
||||
zip_entry_name($zipfile)
|
||||
);
|
||||
$type_file = $this->guessFileType($file['name']);
|
||||
|
||||
$list_files = array(
|
||||
'opml' => array(),
|
||||
'json_starred' => array(),
|
||||
'json_feed' => array()
|
||||
);
|
||||
|
||||
// We try to list all files according to their type
|
||||
$list = array();
|
||||
if ($type_file === 'zip' && extension_loaded('zip')) {
|
||||
$zip = zip_open($file['tmp_name']);
|
||||
|
||||
if (!is_resource($zip)) {
|
||||
// zip_open cannot open file: something is wrong
|
||||
Minz_Log::error('Zip archive cannot be imported. Error code: ' . $zip);
|
||||
Minz_Request::bad(_t('zip_error'),
|
||||
array('c' => 'importExport', 'a' => 'index'));
|
||||
}
|
||||
|
||||
while (($zipfile = zip_read($zip)) !== false) {
|
||||
if (!is_resource($zipfile)) {
|
||||
// zip_entry() can also return an error code!
|
||||
Minz_Log::error('Zip file cannot be imported. Error code: ' . $zipfile);
|
||||
} else {
|
||||
$type_zipfile = $this->guessFileType(zip_entry_name($zipfile));
|
||||
if ($type_file !== 'unknown') {
|
||||
$list_files[$type_zipfile][] = zip_entry_read(
|
||||
$zipfile,
|
||||
|
@ -54,59 +72,37 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
zip_close($zip);
|
||||
} elseif ($type_file !== 'unknown') {
|
||||
$list_files[$type_file][] = file_get_contents(
|
||||
$file['tmp_name']
|
||||
);
|
||||
}
|
||||
|
||||
// Import different files.
|
||||
// OPML first(so categories and feeds are imported)
|
||||
// Starred articles then so the "favourite" status is already set
|
||||
// And finally all other files.
|
||||
$error = false;
|
||||
foreach ($list_files['opml'] as $opml_file) {
|
||||
$error = $this->importOpml($opml_file);
|
||||
}
|
||||
foreach ($list_files['json_starred'] as $article_file) {
|
||||
$error = $this->importArticles($article_file, true);
|
||||
}
|
||||
foreach ($list_files['json_feed'] as $article_file) {
|
||||
$error = $this->importArticles($article_file);
|
||||
}
|
||||
|
||||
// And finally, we get import status and redirect to the home page
|
||||
$notif = null;
|
||||
if ($error === true) {
|
||||
$content_notif = Minz_Translate::t(
|
||||
'feeds_imported_with_errors'
|
||||
);
|
||||
} else {
|
||||
$content_notif = Minz_Translate::t(
|
||||
'feeds_imported'
|
||||
);
|
||||
}
|
||||
|
||||
Minz_Session::_param('notification', array(
|
||||
'type' => 'good',
|
||||
'content' => $content_notif
|
||||
));
|
||||
Minz_Session::_param('actualize_feeds', true);
|
||||
|
||||
Minz_Request::forward(array(
|
||||
'c' => 'index',
|
||||
'a' => 'index'
|
||||
), true);
|
||||
zip_close($zip);
|
||||
} elseif ($type_file === 'zip') {
|
||||
// Zip extension is not loaded
|
||||
Minz_Request::bad(_t('no_zip_extension'),
|
||||
array('c' => 'importExport', 'a' => 'index'));
|
||||
} elseif ($type_file !== 'unknown') {
|
||||
$list_files[$type_file][] = file_get_contents($file['tmp_name']);
|
||||
}
|
||||
|
||||
// What are you doing? you have to call this controller
|
||||
// with a POST request!
|
||||
Minz_Request::forward(array(
|
||||
'c' => 'importExport',
|
||||
'a' => 'index'
|
||||
));
|
||||
// Import file contents.
|
||||
// OPML first(so categories and feeds are imported)
|
||||
// Starred articles then so the "favourite" status is already set
|
||||
// And finally all other files.
|
||||
$error = false;
|
||||
foreach ($list_files['opml'] as $opml_file) {
|
||||
$error = $this->importOpml($opml_file);
|
||||
}
|
||||
foreach ($list_files['json_starred'] as $article_file) {
|
||||
$error = $this->importArticles($article_file, true);
|
||||
}
|
||||
foreach ($list_files['json_feed'] as $article_file) {
|
||||
$error = $this->importArticles($article_file);
|
||||
}
|
||||
|
||||
// And finally, we get import status and redirect to the home page
|
||||
Minz_Session::_param('actualize_feeds', true);
|
||||
$content_notif = $error === true ? _t('feeds_imported_with_errors') :
|
||||
_t('feeds_imported');
|
||||
Minz_Request::good($content_notif);
|
||||
}
|
||||
|
||||
private function guessFileType($filename) {
|
||||
|
@ -120,7 +116,8 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
} elseif (substr_compare($filename, '.opml', -5) === 0 ||
|
||||
substr_compare($filename, '.xml', -4) === 0) {
|
||||
return 'opml';
|
||||
} elseif (strcmp($filename, 'starred.json') === 0) {
|
||||
} elseif (substr_compare($filename, '.json', -5) === 0 &&
|
||||
strpos($filename, 'starred') !== false) {
|
||||
return 'json_starred';
|
||||
} elseif (substr_compare($filename, '.json', -5) === 0 &&
|
||||
strpos($filename, 'feed_') === 0) {
|
||||
|
@ -176,15 +173,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
}
|
||||
|
||||
// We get different useful information
|
||||
$url = html_chars_utf8($feed_elt['xmlUrl']);
|
||||
$name = html_chars_utf8($feed_elt['text']);
|
||||
$url = Minz_Helper::htmlspecialchars_utf8($feed_elt['xmlUrl']);
|
||||
$name = Minz_Helper::htmlspecialchars_utf8($feed_elt['text']);
|
||||
$website = '';
|
||||
if (isset($feed_elt['htmlUrl'])) {
|
||||
$website = html_chars_utf8($feed_elt['htmlUrl']);
|
||||
$website = Minz_Helper::htmlspecialchars_utf8($feed_elt['htmlUrl']);
|
||||
}
|
||||
$description = '';
|
||||
if (isset($feed_elt['description'])) {
|
||||
$description = html_chars_utf8($feed_elt['description']);
|
||||
$description = Minz_Helper::htmlspecialchars_utf8($feed_elt['description']);
|
||||
}
|
||||
|
||||
$error = false;
|
||||
|
@ -210,7 +207,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
|
||||
private function addCategoryOpml($cat_elt, $parent_cat) {
|
||||
// Create a new Category object
|
||||
$cat = new FreshRSS_Category(html_chars_utf8($cat_elt['text']));
|
||||
$cat = new FreshRSS_Category(Minz_Helper::htmlspecialchars_utf8($cat_elt['text']));
|
||||
|
||||
$id = $this->catDAO->addCategoryObject($cat);
|
||||
$error = ($id === false);
|
||||
|
@ -287,7 +284,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
$url = $origin[$key];
|
||||
$name = $origin['title'];
|
||||
$website = $origin['htmlUrl'];
|
||||
$error = false;
|
||||
|
||||
try {
|
||||
// Create a Feed object and add it in DB
|
||||
$feed = new FreshRSS_Feed($url);
|
||||
|
@ -311,44 +308,53 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
}
|
||||
|
||||
public function exportAction() {
|
||||
if (Minz_Request::isPost()) {
|
||||
$this->view->_useLayout(false);
|
||||
if (!Minz_Request::isPost()) {
|
||||
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
|
||||
}
|
||||
|
||||
$export_opml = Minz_Request::param('export_opml', false);
|
||||
$export_starred = Minz_Request::param('export_starred', false);
|
||||
$export_feeds = Minz_Request::param('export_feeds', false);
|
||||
$this->view->_useLayout(false);
|
||||
|
||||
// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
|
||||
$file = tempnam('tmp', 'zip');
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($file, ZipArchive::OVERWRITE);
|
||||
$export_opml = Minz_Request::param('export_opml', false);
|
||||
$export_starred = Minz_Request::param('export_starred', false);
|
||||
$export_feeds = Minz_Request::param('export_feeds', array());
|
||||
|
||||
// Stuff with content
|
||||
if ($export_opml) {
|
||||
$zip->addFromString(
|
||||
'feeds.opml', $this->generateOpml()
|
||||
);
|
||||
}
|
||||
if ($export_starred) {
|
||||
$zip->addFromString(
|
||||
'starred.json', $this->generateArticles('starred')
|
||||
);
|
||||
}
|
||||
foreach ($export_feeds as $feed_id) {
|
||||
$feed = $this->feedDAO->searchById($feed_id);
|
||||
$zip->addFromString(
|
||||
'feed_' . $feed->category() . '_' . $feed->id() . '.json',
|
||||
$this->generateArticles('feed', $feed)
|
||||
$export_files = array();
|
||||
if ($export_opml) {
|
||||
$export_files['feeds.opml'] = $this->generateOpml();
|
||||
}
|
||||
|
||||
if ($export_starred) {
|
||||
$export_files['starred.json'] = $this->generateArticles('starred');
|
||||
}
|
||||
|
||||
foreach ($export_feeds as $feed_id) {
|
||||
$feed = $this->feedDAO->searchById($feed_id);
|
||||
if ($feed) {
|
||||
$filename = 'feed_' . $feed->category() . '_'
|
||||
. $feed->id() . '.json';
|
||||
$export_files[$filename] = $this->generateArticles(
|
||||
'feed', $feed
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Close and send to user
|
||||
$zip->close();
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Length: ' . filesize($file));
|
||||
header('Content-Disposition: attachment; filename="freshrss_export.zip"');
|
||||
readfile($file);
|
||||
unlink($file);
|
||||
$nb_files = count($export_files);
|
||||
if ($nb_files > 1) {
|
||||
// If there are more than 1 file to export, we need a zip archive.
|
||||
try {
|
||||
$this->exportZip($export_files);
|
||||
} catch (Exception $e) {
|
||||
# Oops, there is no Zip extension!
|
||||
Minz_Request::bad(_t('export_no_zip_extension'),
|
||||
array('c' => 'importExport', 'a' => 'index'));
|
||||
}
|
||||
} elseif ($nb_files === 1) {
|
||||
// Only one file? Guess its type and export it.
|
||||
$filename = key($export_files);
|
||||
$type = $this->guessFileType($filename);
|
||||
$this->exportFile('freshrss_' . $filename, $export_files[$filename], $type);
|
||||
} else {
|
||||
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +373,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
$this->view->categories = $this->catDAO->listCategories();
|
||||
|
||||
if ($type == 'starred') {
|
||||
$this->view->list_title = Minz_Translate::t('starred_list');
|
||||
$this->view->list_title = _t('starred_list');
|
||||
$this->view->type = 'starred';
|
||||
$unread_fav = $this->entryDAO->countUnreadReadFavorites();
|
||||
$this->view->entries = $this->entryDAO->listWhere(
|
||||
|
@ -375,9 +381,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
$unread_fav['all']
|
||||
);
|
||||
} elseif ($type == 'feed' && !is_null($feed)) {
|
||||
$this->view->list_title = Minz_Translate::t(
|
||||
'feed_list', $feed->name()
|
||||
);
|
||||
$this->view->list_title = _t('feed_list', $feed->name());
|
||||
$this->view->type = 'feed/' . $feed->id();
|
||||
$this->view->entries = $this->entryDAO->listWhere(
|
||||
'f', $feed->id(), FreshRSS_Entry::STATE_ALL, 'ASC',
|
||||
|
@ -388,4 +392,44 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
|
|||
|
||||
return $this->view->helperToString('export/articles');
|
||||
}
|
||||
|
||||
private function exportZip($files) {
|
||||
if (!extension_loaded('zip')) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
|
||||
$zip_file = tempnam('tmp', 'zip');
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($zip_file, ZipArchive::OVERWRITE);
|
||||
|
||||
foreach ($files as $filename => $content) {
|
||||
$zip->addFromString($filename, $content);
|
||||
}
|
||||
|
||||
// Close and send to user
|
||||
$zip->close();
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Length: ' . filesize($zip_file));
|
||||
header('Content-Disposition: attachment; filename="freshrss_export.zip"');
|
||||
readfile($zip_file);
|
||||
unlink($zip_file);
|
||||
}
|
||||
|
||||
private function exportFile($filename, $content, $type) {
|
||||
if ($type === 'unknown') {
|
||||
return;
|
||||
}
|
||||
|
||||
$content_type = '';
|
||||
if ($type === 'opml') {
|
||||
$content_type = "text/opml";
|
||||
} elseif ($type === 'json_feed' || $type === 'json_starred') {
|
||||
$content_type = "text/json";
|
||||
}
|
||||
|
||||
header('Content-Type: ' . $content_type . '; charset=utf-8');
|
||||
header('Content-disposition: attachment; filename=' . $filename);
|
||||
print($content);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,6 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
|
||||
// mise à jour des titres
|
||||
$this->view->rss_title = $this->view->currentName . ' | ' . Minz_View::title();
|
||||
if ($this->view->nb_not_read > 0) {
|
||||
Minz_View::prependTitle('(' . formatNumber($this->view->nb_not_read) . ') ');
|
||||
}
|
||||
Minz_View::prependTitle(
|
||||
($this->nb_not_read_cat > 0 ? '(' . formatNumber($this->nb_not_read_cat) . ') ' : '') .
|
||||
$this->view->currentName .
|
||||
|
@ -79,14 +76,14 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
);
|
||||
|
||||
// On récupère les différents éléments de filtrage
|
||||
$this->view->state = $state = Minz_Request::param ('state', $this->view->conf->default_view);
|
||||
$this->view->state = Minz_Request::param('state', $this->view->conf->default_view);
|
||||
$state_param = Minz_Request::param ('state', null);
|
||||
$filter = Minz_Request::param ('search', '');
|
||||
$this->view->order = $order = Minz_Request::param ('order', $this->view->conf->sort_order);
|
||||
$nb = Minz_Request::param ('nb', $this->view->conf->posts_per_page);
|
||||
$first = Minz_Request::param ('next', '');
|
||||
|
||||
if ($state === FreshRSS_Entry::STATE_NOT_READ) { //Any unread article in this category at all?
|
||||
if ($this->view->state === FreshRSS_Entry::STATE_NOT_READ) { //Any unread article in this category at all?
|
||||
switch ($getType) {
|
||||
case 'a':
|
||||
$hasUnread = $this->view->nb_not_read > 0;
|
||||
|
@ -107,7 +104,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
break;
|
||||
}
|
||||
if (!$hasUnread && ($state_param === null)) {
|
||||
$this->view->state = $state = FreshRSS_Entry::STATE_ALL;
|
||||
$this->view->state = FreshRSS_Entry::STATE_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,11 +117,11 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
$keepHistoryDefault = $this->view->conf->keep_history_default;
|
||||
|
||||
try {
|
||||
$entries = $entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min, true, $keepHistoryDefault);
|
||||
$entries = $entryDAO->listWhere($getType, $getId, $this->view->state, $order, $nb + 1, $first, $filter, $date_min, true, $keepHistoryDefault);
|
||||
|
||||
// Si on a récupéré aucun article "non lus"
|
||||
// on essaye de récupérer tous les articles
|
||||
if ($state === FreshRSS_Entry::STATE_NOT_READ && empty($entries) && ($state_param === null) && ($filter == '')) {
|
||||
if ($this->view->state === FreshRSS_Entry::STATE_NOT_READ && empty($entries) && ($state_param === null) && ($filter == '')) {
|
||||
Minz_Log::record('Conflicting information about nbNotRead!', Minz_Log::DEBUG);
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
try {
|
||||
|
@ -135,6 +132,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
$this->view->state = FreshRSS_Entry::STATE_ALL;
|
||||
$entries = $entryDAO->listWhere($getType, $getId, $this->view->state, $order, $nb, $first, $filter, $date_min, true, $keepHistoryDefault);
|
||||
}
|
||||
Minz_Request::_param('state', $this->view->state);
|
||||
|
||||
if (count($entries) <= $nb) {
|
||||
$this->view->nextId = '';
|
||||
|
@ -298,6 +296,41 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
Minz_Session::_param('passwordHash');
|
||||
}
|
||||
|
||||
private static function makeLongTermCookie($username, $passwordHash) {
|
||||
do {
|
||||
$token = sha1(Minz_Configuration::salt() . $username . uniqid(mt_rand(), true));
|
||||
$tokenFile = DATA_PATH . '/tokens/' . $token . '.txt';
|
||||
} while (file_exists($tokenFile));
|
||||
if (@file_put_contents($tokenFile, $username . "\t" . $passwordHash) === false) {
|
||||
return false;
|
||||
}
|
||||
$expire = time() + 2629744; //1 month //TODO: Use a configuration instead
|
||||
Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire);
|
||||
Minz_Session::_param('token', $token);
|
||||
return $token;
|
||||
}
|
||||
|
||||
private static function deleteLongTermCookie() {
|
||||
Minz_Session::deleteLongTermCookie('FreshRSS_login');
|
||||
$token = Minz_Session::param('token', null);
|
||||
if (ctype_alnum($token)) {
|
||||
@unlink(DATA_PATH . '/tokens/' . $token . '.txt');
|
||||
}
|
||||
Minz_Session::_param('token');
|
||||
if (rand(0, 10) === 1) {
|
||||
self::purgeTokens();
|
||||
}
|
||||
}
|
||||
|
||||
private static function purgeTokens() {
|
||||
$oldest = time() - 2629744; //1 month //TODO: Use a configuration instead
|
||||
foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $fileInfo) {
|
||||
if ($fileInfo->getExtension() === 'txt' && $fileInfo->getMTime() < $oldest) {
|
||||
@unlink($fileInfo->getPathname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function formLoginAction () {
|
||||
if (Minz_Request::isPost()) {
|
||||
$ok = false;
|
||||
|
@ -315,6 +348,11 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
if ($ok) {
|
||||
Minz_Session::_param('currentUser', $username);
|
||||
Minz_Session::_param('passwordHash', $s);
|
||||
if (Minz_Request::param('keep_logged_in', false)) {
|
||||
self::makeLongTermCookie($username, $s);
|
||||
} else {
|
||||
self::deleteLongTermCookie();
|
||||
}
|
||||
} else {
|
||||
Minz_Log::record('Password mismatch for user ' . $username . ', nonce=' . $nonce . ', c=' . $c, Minz_Log::WARNING);
|
||||
}
|
||||
|
@ -374,6 +412,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
|
|||
Minz_Session::_param('currentUser');
|
||||
Minz_Session::_param('mail');
|
||||
Minz_Session::_param('passwordHash');
|
||||
self::deleteLongTermCookie();
|
||||
Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ class FreshRSS_stats_Controller extends Minz_ActionController {
|
|||
|
||||
public function indexAction() {
|
||||
$statsDAO = FreshRSS_Factory::createStatsDAO();
|
||||
Minz_View::appendScript (Minz_Url::display ('/scripts/flotr2.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/flotr2.min.js')));
|
||||
Minz_View::appendScript(Minz_Url::display('/scripts/flotr2.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/flotr2.min.js')));
|
||||
$this->view->repartition = $statsDAO->calculateEntryRepartition();
|
||||
$this->view->count = ($statsDAO->calculateEntryCount());
|
||||
$this->view->count = $statsDAO->calculateEntryCount();
|
||||
$this->view->feedByCategory = $statsDAO->calculateFeedByCategory();
|
||||
$this->view->entryByCategory = $statsDAO->calculateEntryByCategory();
|
||||
$this->view->topFeed = $statsDAO->calculateTopFeed();
|
||||
|
@ -15,7 +15,13 @@ class FreshRSS_stats_Controller extends Minz_ActionController {
|
|||
public function idleAction() {
|
||||
$statsDAO = FreshRSS_Factory::createStatsDAO();
|
||||
$feeds = $statsDAO->calculateFeedLastDate();
|
||||
$idleFeeds = array();
|
||||
$idleFeeds = array(
|
||||
'last_year' => array(),
|
||||
'last_6_month' => array(),
|
||||
'last_3_month' => array(),
|
||||
'last_month' => array(),
|
||||
'last_week' => array(),
|
||||
);
|
||||
$now = new \DateTime();
|
||||
$feedDate = clone $now;
|
||||
$lastWeek = clone $now;
|
||||
|
@ -34,26 +40,37 @@ class FreshRSS_stats_Controller extends Minz_ActionController {
|
|||
if ($feedDate >= $lastWeek) {
|
||||
continue;
|
||||
}
|
||||
if ($feedDate < $lastWeek) {
|
||||
$idleFeeds['last_week'][] = $feed['name'];
|
||||
}
|
||||
if ($feedDate < $lastMonth) {
|
||||
$idleFeeds['last_month'][] = $feed['name'];
|
||||
}
|
||||
if ($feedDate < $last3Month) {
|
||||
$idleFeeds['last_3_month'][] = $feed['name'];
|
||||
}
|
||||
if ($feedDate < $last6Month) {
|
||||
$idleFeeds['last_6_month'][] = $feed['name'];
|
||||
}
|
||||
if ($feedDate < $lastYear) {
|
||||
$idleFeeds['last_year'][] = $feed['name'];
|
||||
$idleFeeds['last_year'][] = $feed;
|
||||
} elseif ($feedDate < $last6Month) {
|
||||
$idleFeeds['last_6_month'][] = $feed;
|
||||
} elseif ($feedDate < $last3Month) {
|
||||
$idleFeeds['last_3_month'][] = $feed;
|
||||
} elseif ($feedDate < $lastMonth) {
|
||||
$idleFeeds['last_month'][] = $feed;
|
||||
} elseif ($feedDate < $lastWeek) {
|
||||
$idleFeeds['last_week'][] = $feed;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->idleFeeds = array_reverse($idleFeeds);
|
||||
$this->view->idleFeeds = $idleFeeds;
|
||||
}
|
||||
|
||||
|
||||
public function repartitionAction() {
|
||||
$statsDAO = FreshRSS_Factory::createStatsDAO();
|
||||
$categoryDAO = new FreshRSS_CategoryDAO();
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
Minz_View::appendScript(Minz_Url::display('/scripts/flotr2.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/flotr2.min.js')));
|
||||
$id = Minz_Request::param ('id', null);
|
||||
$this->view->categories = $categoryDAO->listCategories();
|
||||
$this->view->feed = $feedDAO->searchById($id);
|
||||
$this->view->days = $statsDAO->getDays();
|
||||
$this->view->months = $statsDAO->getMonths();
|
||||
$this->view->repartitionHour = $statsDAO->calculateEntryRepartitionPerFeedPerHour($id);
|
||||
$this->view->repartitionDayOfWeek = $statsDAO->calculateEntryRepartitionPerFeedPerDayOfWeek($id);
|
||||
$this->view->repartitionMonth = $statsDAO->calculateEntryRepartitionPerFeedPerMonth($id);
|
||||
}
|
||||
|
||||
public function firstAction() {
|
||||
if (!$this->view->loginOk) {
|
||||
Minz_Error::error(
|
||||
|
|
|
@ -100,7 +100,7 @@ class FreshRSS_users_Controller extends Minz_ActionController {
|
|||
public function createAction() {
|
||||
if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
|
||||
$db = Minz_Configuration::dataBase();
|
||||
require_once(APP_PATH . '/SQL/sql.' . $db['type'] . '.php');
|
||||
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
|
||||
|
||||
$new_user_language = Minz_Request::param('new_user_language', $this->view->conf->language);
|
||||
if (!in_array($new_user_language, $this->view->conf->availableLanguages())) {
|
||||
|
@ -172,7 +172,7 @@ class FreshRSS_users_Controller extends Minz_ActionController {
|
|||
public function deleteAction() {
|
||||
if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
|
||||
$db = Minz_Configuration::dataBase();
|
||||
require_once(APP_PATH . '/SQL/sql.' . $db['type'] . '.php');
|
||||
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
|
||||
|
||||
$username = Minz_Request::param('username');
|
||||
$ok = ctype_alnum($username);
|
||||
|
|
|
@ -6,17 +6,49 @@ class FreshRSS extends Minz_FrontController {
|
|||
}
|
||||
$loginOk = $this->accessControl(Minz_Session::param('currentUser', ''));
|
||||
$this->loadParamsView();
|
||||
if (Minz_Request::isPost() && (empty($_SERVER['HTTP_REFERER']) ||
|
||||
Minz_Request::getDomainName() !== parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST))) {
|
||||
$loginOk = false; //Basic protection against XSRF attacks
|
||||
Minz_Error::error(
|
||||
403,
|
||||
array('error' => array(Minz_Translate::t('access_denied') . ' [HTTP_REFERER=' .
|
||||
htmlspecialchars(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']) . ']'))
|
||||
);
|
||||
}
|
||||
Minz_View::_param('loginOk', $loginOk);
|
||||
$this->loadStylesAndScripts($loginOk); //TODO: Do not load that when not needed, e.g. some Ajax requests
|
||||
$this->loadNotifications();
|
||||
}
|
||||
|
||||
private static function getCredentialsFromLongTermCookie() {
|
||||
$token = Minz_Session::getLongTermCookie('FreshRSS_login');
|
||||
if (!ctype_alnum($token)) {
|
||||
return array();
|
||||
}
|
||||
$tokenFile = DATA_PATH . '/tokens/' . $token . '.txt';
|
||||
$mtime = @filemtime($tokenFile);
|
||||
if ($mtime + 2629744 < time()) { //1 month //TODO: Use a configuration instead
|
||||
@unlink($tokenFile);
|
||||
return array(); //Expired or token does not exist
|
||||
}
|
||||
$credentials = @file_get_contents($tokenFile);
|
||||
return $credentials === false ? array() : explode("\t", $credentials, 2);
|
||||
}
|
||||
|
||||
private function accessControl($currentUser) {
|
||||
if ($currentUser == '') {
|
||||
switch (Minz_Configuration::authType()) {
|
||||
case 'form':
|
||||
$currentUser = Minz_Configuration::defaultUser();
|
||||
Minz_Session::_param('passwordHash');
|
||||
$loginOk = false;
|
||||
$credentials = self::getCredentialsFromLongTermCookie();
|
||||
if (isset($credentials[1])) {
|
||||
$currentUser = trim($credentials[0]);
|
||||
Minz_Session::_param('passwordHash', trim($credentials[1]));
|
||||
}
|
||||
$loginOk = $currentUser != '';
|
||||
if (!$loginOk) {
|
||||
$currentUser = Minz_Configuration::defaultUser();
|
||||
Minz_Session::_param('passwordHash');
|
||||
}
|
||||
break;
|
||||
case 'http_auth':
|
||||
$currentUser = httpAuthUser();
|
||||
|
@ -95,7 +127,6 @@ class FreshRSS extends Minz_FrontController {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Minz_View::_param ('loginOk', $loginOk);
|
||||
return $loginOk;
|
||||
}
|
||||
|
||||
|
@ -127,13 +158,9 @@ class FreshRSS extends Minz_FrontController {
|
|||
Minz_View::appendScript('https://login.persona.org/include.js');
|
||||
break;
|
||||
}
|
||||
$includeLazyLoad = $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param ('output') === 'reader');
|
||||
Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')), false, !$includeLazyLoad, !$includeLazyLoad);
|
||||
if ($includeLazyLoad) {
|
||||
Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.lazyload.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.lazyload.min.js')));
|
||||
}
|
||||
Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js')));
|
||||
Minz_View::appendScript (Minz_Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js')));
|
||||
Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')));
|
||||
Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js')));
|
||||
Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js')));
|
||||
}
|
||||
|
||||
private function loadNotifications () {
|
||||
|
|
|
@ -17,6 +17,8 @@ class FreshRSS_Configuration {
|
|||
'default_view' => FreshRSS_Entry::STATE_NOT_READ,
|
||||
'auto_load_more' => true,
|
||||
'display_posts' => false,
|
||||
'display_categories' => false,
|
||||
'hide_read_feeds' => true,
|
||||
'onread_jump_next' => true,
|
||||
'lazyload' => true,
|
||||
'sticky_post' => true,
|
||||
|
@ -141,6 +143,12 @@ class FreshRSS_Configuration {
|
|||
public function _display_posts ($value) {
|
||||
$this->data['display_posts'] = ((bool)$value) && $value !== 'no';
|
||||
}
|
||||
public function _display_categories ($value) {
|
||||
$this->data['display_categories'] = ((bool)$value) && $value !== 'no';
|
||||
}
|
||||
public function _hide_read_feeds($value) {
|
||||
$this->data['hide_read_feeds'] = (bool)$value;
|
||||
}
|
||||
public function _onread_jump_next ($value) {
|
||||
$this->data['onread_jump_next'] = ((bool)$value) && $value !== 'no';
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
|
|||
}
|
||||
|
||||
public function addEntry($valuesTmp, $preparedStatement = null) {
|
||||
$stm = $preparedStatement === null ? addEntryPrepare() : $preparedStatement;
|
||||
$stm = $preparedStatement === null ?
|
||||
FreshRSS_EntryDAO::addEntryPrepare() :
|
||||
$preparedStatement;
|
||||
|
||||
$values = array(
|
||||
$valuesTmp['id'],
|
||||
|
@ -63,7 +65,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
|
|||
}
|
||||
|
||||
if (!isset($existingGuids[$entry->guid()]) &&
|
||||
($feedHistory != 0 || $eDate >= $date_min)) {
|
||||
($feedHistory != 0 || $eDate >= $date_min || $entry->isFavorite())) {
|
||||
$values = $entry->toArray();
|
||||
|
||||
$useDeclaredDate = empty($existingGuids);
|
||||
|
@ -173,7 +175,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
|
|||
public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0) {
|
||||
if ($idMax == 0) {
|
||||
$idMax = time() . '000000';
|
||||
Minz_Log::record($nb . 'Calling markReadEntries(0) is deprecated!', Minz_Log::DEBUG);
|
||||
Minz_Log::record('Calling markReadEntries(0) is deprecated!', Minz_Log::DEBUG);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id '
|
||||
|
@ -201,7 +203,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
|
|||
public function markReadCat($id, $idMax = 0) {
|
||||
if ($idMax == 0) {
|
||||
$idMax = time() . '000000';
|
||||
Minz_Log::record($nb . 'Calling markReadCat(0) is deprecated!', Minz_Log::DEBUG);
|
||||
Minz_Log::record('Calling markReadCat(0) is deprecated!', Minz_Log::DEBUG);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id '
|
||||
|
@ -224,11 +226,11 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
|
|||
public function markReadFeed($id, $idMax = 0) {
|
||||
if ($idMax == 0) {
|
||||
$idMax = time() . '000000';
|
||||
Minz_Log::record($nb . 'Calling markReadFeed(0) is deprecated!', Minz_Log::DEBUG);
|
||||
Minz_Log::record('Calling markReadFeed(0) is deprecated!', Minz_Log::DEBUG);
|
||||
}
|
||||
$this->bd->beginTransaction();
|
||||
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` '
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` '
|
||||
. 'SET is_read=1 '
|
||||
. 'WHERE id_feed=? AND is_read=0 AND id <= ?';
|
||||
$values = array($id, $idMax);
|
||||
|
|
|
@ -72,7 +72,7 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
|
|||
public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0) {
|
||||
if ($idMax == 0) {
|
||||
$idMax = time() . '000000';
|
||||
Minz_Log::record($nb . 'Calling markReadEntries(0) is deprecated!', Minz_Log::DEBUG);
|
||||
Minz_Log::record('Calling markReadEntries(0) is deprecated!', Minz_Log::DEBUG);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` SET is_read=1 WHERE is_read=0 AND id <= ?';
|
||||
|
@ -98,7 +98,7 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
|
|||
public function markReadCat($id, $idMax = 0) {
|
||||
if ($idMax == 0) {
|
||||
$idMax = time() . '000000';
|
||||
Minz_Log::record($nb . 'Calling markReadCat(0) is deprecated!', Minz_Log::DEBUG);
|
||||
Minz_Log::record('Calling markReadCat(0) is deprecated!', Minz_Log::DEBUG);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE `' . $this->prefix . 'entry` '
|
||||
|
|
|
@ -28,6 +28,12 @@ class FreshRSS_Feed extends Minz_Model {
|
|||
}
|
||||
}
|
||||
|
||||
public static function example() {
|
||||
$f = new FreshRSS_Feed('http://example.net/', false);
|
||||
$f->faviconPrepare();
|
||||
return $f;
|
||||
}
|
||||
|
||||
public function id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
@ -277,11 +283,11 @@ class FreshRSS_Feed extends Minz_Model {
|
|||
$elinks[$elink] = '1';
|
||||
$mime = strtolower($enclosure->get_type());
|
||||
if (strpos($mime, 'image/') === 0) {
|
||||
$content .= '<br /><img src="' . $elink . '" alt="" />';
|
||||
$content .= '<br /><img lazyload="" postpone="" src="' . $elink . '" alt="" />';
|
||||
} elseif (strpos($mime, 'audio/') === 0) {
|
||||
$content .= '<br /><audio src="' . $elink . '" controls="controls" />';
|
||||
$content .= '<br /><audio lazyload="" postpone="" preload="none" src="' . $elink . '" controls="controls" />';
|
||||
} elseif (strpos($mime, 'video/') === 0) {
|
||||
$content .= '<br /><video src="' . $elink . '" controls="controls" />';
|
||||
$content .= '<br /><video lazyload="" postpone="" preload="none" src="' . $elink . '" controls="controls" />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,9 +85,83 @@ SQL;
|
|||
* @return array
|
||||
*/
|
||||
protected function initEntryCountArray() {
|
||||
return $this->initStatsArray(-self::ENTRY_COUNT_PERIOD, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of article per hour of the day per feed
|
||||
*
|
||||
* @param integer $feed id
|
||||
* @return string
|
||||
*/
|
||||
public function calculateEntryRepartitionPerFeedPerHour($feed = null) {
|
||||
return $this->calculateEntryRepartitionPerFeedPerPeriod('%H', $feed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of article per day of week per feed
|
||||
*
|
||||
* @param integer $feed id
|
||||
* @return string
|
||||
*/
|
||||
public function calculateEntryRepartitionPerFeedPerDayOfWeek($feed = null) {
|
||||
return $this->calculateEntryRepartitionPerFeedPerPeriod('%w', $feed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of article per month per feed
|
||||
*
|
||||
* @param integer $feed
|
||||
* @return string
|
||||
*/
|
||||
public function calculateEntryRepartitionPerFeedPerMonth($feed = null) {
|
||||
return $this->calculateEntryRepartitionPerFeedPerPeriod('%m', $feed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of article per period per feed
|
||||
*
|
||||
* @param string $period format string to use for grouping
|
||||
* @param integer $feed id
|
||||
* @return string
|
||||
*/
|
||||
protected function calculateEntryRepartitionPerFeedPerPeriod($period, $feed = null) {
|
||||
if ($feed) {
|
||||
$restrict = "WHERE e.id_feed = {$feed}";
|
||||
} else {
|
||||
$restrict = '';
|
||||
}
|
||||
$sql = <<<SQL
|
||||
SELECT DATE_FORMAT(FROM_UNIXTIME(e.date), '{$period}') AS period
|
||||
, COUNT(1) AS count
|
||||
FROM {$this->prefix}entry AS e
|
||||
{$restrict}
|
||||
GROUP BY period
|
||||
ORDER BY period ASC
|
||||
SQL;
|
||||
|
||||
$stm = $this->bd->prepare($sql);
|
||||
$stm->execute();
|
||||
$res = $stm->fetchAll(PDO::FETCH_NAMED);
|
||||
|
||||
foreach ($res as $value) {
|
||||
$repartition[(int) $value['period']] = (int) $value['count'];
|
||||
}
|
||||
|
||||
return $this->convertToSerie($repartition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an array for statistics depending on a range
|
||||
*
|
||||
* @param integer $min
|
||||
* @param integer $max
|
||||
* @return array
|
||||
*/
|
||||
protected function initStatsArray($min, $max) {
|
||||
return array_map(function () {
|
||||
return 0;
|
||||
}, array_flip(range(-self::ENTRY_COUNT_PERIOD, -1)));
|
||||
}, array_flip(range($min, $max)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,7 +244,8 @@ SQL;
|
|||
*/
|
||||
public function calculateFeedLastDate() {
|
||||
$sql = <<<SQL
|
||||
SELECT MAX(f.name) AS name
|
||||
SELECT MAX(f.id) as id
|
||||
, MAX(f.name) AS name
|
||||
, MAX(date) AS last_date
|
||||
FROM {$this->prefix}feed AS f,
|
||||
{$this->prefix}entry AS e
|
||||
|
@ -204,4 +279,57 @@ SQL;
|
|||
return json_encode($serie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets days ready for graphs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDays() {
|
||||
return $this->convertToTranslatedJson(array(
|
||||
'sun',
|
||||
'mon',
|
||||
'tue',
|
||||
'wed',
|
||||
'thu',
|
||||
'fri',
|
||||
'sat',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets months ready for graphs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMonths() {
|
||||
return $this->convertToTranslatedJson(array(
|
||||
'jan',
|
||||
'feb',
|
||||
'mar',
|
||||
'apr',
|
||||
'may',
|
||||
'jun',
|
||||
'jul',
|
||||
'aug',
|
||||
'sep',
|
||||
'oct',
|
||||
'nov',
|
||||
'dec',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates array content and encode it as JSON
|
||||
*
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
private function convertToTranslatedJson($data = array()) {
|
||||
$translated = array_map(function ($a) {
|
||||
return Minz_Translate::t($a);
|
||||
}, $data);
|
||||
|
||||
return json_encode($translated);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,10 +28,36 @@ SQL;
|
|||
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($res as $value) {
|
||||
$count[(int)$value['day']] = (int) $value['count'];
|
||||
$count[(int) $value['day']] = (int) $value['count'];
|
||||
}
|
||||
|
||||
return $this->convertToSerie($count);
|
||||
}
|
||||
|
||||
protected function calculateEntryRepartitionPerFeedPerPeriod($period, $feed = null) {
|
||||
if ($feed) {
|
||||
$restrict = "WHERE e.id_feed = {$feed}";
|
||||
} else {
|
||||
$restrict = '';
|
||||
}
|
||||
$sql = <<<SQL
|
||||
SELECT strftime('{$period}', e.date, 'unixepoch') AS period
|
||||
, COUNT(1) AS count
|
||||
FROM {$this->prefix}entry AS e
|
||||
{$restrict}
|
||||
GROUP BY period
|
||||
ORDER BY period ASC
|
||||
SQL;
|
||||
|
||||
$stm = $this->bd->prepare($sql);
|
||||
$stm->execute();
|
||||
$res = $stm->fetchAll(PDO::FETCH_NAMED);
|
||||
|
||||
foreach ($res as $value) {
|
||||
$repartition[(int) $value['period']] = (int) $value['count'];
|
||||
}
|
||||
|
||||
return $this->convertToSerie($repartition);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,19 +3,22 @@
|
|||
class FreshRSS_UserDAO extends Minz_ModelPdo {
|
||||
public function createUser($username) {
|
||||
$db = Minz_Configuration::dataBase();
|
||||
require_once(APP_PATH . '/SQL/sql.' . $db['type'] . '.php');
|
||||
|
||||
if (defined('SQL_CREATE_TABLES')) {
|
||||
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
|
||||
|
||||
$userPDO = new Minz_ModelPdo($username);
|
||||
|
||||
$ok = false;
|
||||
if (defined('SQL_CREATE_TABLES')) { //E.g. MySQL
|
||||
$sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_', Minz_Translate::t('default_category'));
|
||||
$stm = $c->prepare($sql);
|
||||
$stm = $userPDO->bd->prepare($sql);
|
||||
$ok = $stm && $stm->execute();
|
||||
} else {
|
||||
} else { //E.g. SQLite
|
||||
global $SQL_CREATE_TABLES;
|
||||
if (is_array($SQL_CREATE_TABLES)) {
|
||||
$ok = true;
|
||||
foreach ($SQL_CREATE_TABLES as $instruction) {
|
||||
$sql = sprintf($instruction, '', Minz_Translate::t('default_category'));
|
||||
$stm = $c->prepare($sql);
|
||||
$stm = $userPDO->bd->prepare($sql);
|
||||
$ok &= ($stm && $stm->execute());
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +27,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
|
|||
if ($ok) {
|
||||
return true;
|
||||
} else {
|
||||
$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
|
||||
$info = empty($stm) ? array(2 => 'syntax error') : $stm->errorInfo();
|
||||
Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
@ -32,16 +35,22 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
|
|||
|
||||
public function deleteUser($username) {
|
||||
$db = Minz_Configuration::dataBase();
|
||||
require_once(APP_PATH . '/SQL/sql.' . $db['type'] . '.php');
|
||||
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
|
||||
|
||||
$sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
|
||||
$stm = $this->bd->prepare($sql);
|
||||
if ($stm && $stm->execute()) {
|
||||
return true;
|
||||
if ($db['type'] === 'sqlite') {
|
||||
return unlink(DATA_PATH . '/' . $username . '.sqlite');
|
||||
} else {
|
||||
$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
|
||||
Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
|
||||
return false;
|
||||
$userPDO = new Minz_ModelPdo($username);
|
||||
|
||||
$sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
|
||||
$stm = $userPDO->bd->prepare($sql);
|
||||
if ($stm && $stm->execute()) {
|
||||
return true;
|
||||
} else {
|
||||
$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
|
||||
Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
global $SQL_CREATE_TABLES;
|
||||
$SQL_CREATE_TABLES = array(
|
||||
'CREATE TABLE IF NOT EXISTS `%1$scategory` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
return array (
|
||||
// LAYOUT
|
||||
'login' => 'Login',
|
||||
'keep_logged_in' => 'Keep me logged in <small>(1 month)</small>',
|
||||
'login_with_persona' => 'Login with Persona',
|
||||
'logout' => 'Logout',
|
||||
'search' => 'Search words or #tags',
|
||||
|
@ -48,6 +49,10 @@ return array (
|
|||
'stats' => 'Statistics',
|
||||
'stats_idle' => 'Idle feeds',
|
||||
'stats_main' => 'Main statistics',
|
||||
'stats_repartition' => 'Articles repartition',
|
||||
'stats_entry_per_hour' => 'Per hour',
|
||||
'stats_entry_per_day_of_week' => 'Per day of week',
|
||||
'stats_entry_per_month' => 'Per month',
|
||||
|
||||
'last_week' => 'Last week',
|
||||
'last_month' => 'Last month',
|
||||
|
@ -177,10 +182,15 @@ return array (
|
|||
'focus_search' => 'Access search box',
|
||||
|
||||
'file_to_import' => 'File to import<br />(OPML, Json or Zip)',
|
||||
'file_to_import_no_zip' => 'File to import<br />(OPML or Json)',
|
||||
'import' => 'Import',
|
||||
'file_cannot_be_uploaded' => 'File cannot be uploaded!',
|
||||
'zip_error' => 'An error occured during Zip import.',
|
||||
'no_zip_extension' => 'Zip extension is not present on your server.',
|
||||
'export' => 'Export',
|
||||
'export_opml' => 'Export list of feeds (OPML)',
|
||||
'export_starred' => 'Export your favourites',
|
||||
'export_no_zip_extension' => 'Zip extension is not present on your server. Please try to export files one by one.',
|
||||
'starred_list' => 'List of favourite articles',
|
||||
'feed_list' => 'List of %s articles',
|
||||
'or' => 'or',
|
||||
|
@ -257,6 +267,8 @@ return array (
|
|||
'sort_order' => 'Sort order',
|
||||
'auto_load_more' => 'Load next articles at the page bottom',
|
||||
'display_articles_unfolded' => 'Show articles unfolded by default',
|
||||
'display_categories_unfolded' => 'Show categories folded by default',
|
||||
'hide_read_feeds' => 'Hide categories & feeds with no unread article (only in “unread articles” display mode)',
|
||||
'after_onread' => 'After “mark all as read”,',
|
||||
'jump_next' => 'jump to next unread sibling (feed or category)',
|
||||
'article_icons' => 'Article icons',
|
||||
|
@ -339,20 +351,41 @@ return array (
|
|||
'login_required' => 'Login required:',
|
||||
|
||||
'confirm_action' => 'Are you sure you want to perform this action? It cannot be cancelled!',
|
||||
'notif_title_new_articles' => 'FreshRSS: new articles!',
|
||||
'notif_body_new_articles' => 'There are \d new articles to read on FreshRSS.',
|
||||
|
||||
// DATE
|
||||
'january' => 'january',
|
||||
'february' => 'february',
|
||||
'march' => 'march',
|
||||
'april' => 'april',
|
||||
'may' => 'may',
|
||||
'june' => 'june',
|
||||
'july' => 'july',
|
||||
'august' => 'august',
|
||||
'september' => 'september',
|
||||
'october' => 'october',
|
||||
'november' => 'november',
|
||||
'december' => 'december',
|
||||
'january' => 'January',
|
||||
'february' => 'February',
|
||||
'march' => 'March',
|
||||
'april' => 'April',
|
||||
'may' => 'May',
|
||||
'june' => 'June',
|
||||
'july' => 'July',
|
||||
'august' => 'August',
|
||||
'september' => 'September',
|
||||
'october' => 'October',
|
||||
'november' => 'November',
|
||||
'december' => 'December',
|
||||
'january' => 'Jan',
|
||||
'february' => 'Feb',
|
||||
'march' => 'Mar',
|
||||
'april' => 'Apr',
|
||||
'may' => 'May',
|
||||
'june' => 'Jun',
|
||||
'july' => 'Jul',
|
||||
'august' => 'Aug',
|
||||
'september' => 'Sep',
|
||||
'october' => 'Oct',
|
||||
'november' => 'Nov',
|
||||
'december' => 'Dec',
|
||||
'sun' => 'Sun',
|
||||
'mon' => 'Mon',
|
||||
'tue' => 'Tue',
|
||||
'wed' => 'Wed',
|
||||
'thu' => 'Thu',
|
||||
'fri' => 'Fri',
|
||||
'sat' => 'Sat',
|
||||
// special format for date() function
|
||||
'Jan' => '\J\a\n\u\a\r\y',
|
||||
'Feb' => '\F\e\b\r\u\a\r\y',
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
return array (
|
||||
// LAYOUT
|
||||
'login' => 'Connexion',
|
||||
'keep_logged_in' => 'Rester connecté <small>(1 mois)</small>',
|
||||
'login_with_persona' => 'Connexion avec Persona',
|
||||
'logout' => 'Déconnexion',
|
||||
'search' => 'Rechercher des mots ou des #tags',
|
||||
|
@ -48,6 +49,10 @@ return array (
|
|||
'stats' => 'Statistiques',
|
||||
'stats_idle' => 'Flux inactifs',
|
||||
'stats_main' => 'Statistiques principales',
|
||||
'stats_repartition' => 'Répartition des articles',
|
||||
'stats_entry_per_hour' => 'Par heure',
|
||||
'stats_entry_per_day_of_week' => 'Par jour de la semaine',
|
||||
'stats_entry_per_month' => 'Par mois',
|
||||
|
||||
'last_week' => 'La dernière semaine',
|
||||
'last_month' => 'Le dernier mois',
|
||||
|
@ -177,10 +182,15 @@ return array (
|
|||
'focus_search' => 'Accéder à la recherche',
|
||||
|
||||
'file_to_import' => 'Fichier à importer<br />(OPML, Json ou Zip)',
|
||||
'file_to_import_no_zip' => 'Fichier à importer<br />(OPML ou Json)',
|
||||
'import' => 'Importer',
|
||||
'file_cannot_be_uploaded' => 'Le fichier ne peut pas être téléchargé!',
|
||||
'zip_error' => 'Une erreur est survenue durant l’import du fichier Zip.',
|
||||
'no_zip_extension' => 'L’extension Zip n’est pas présente sur votre serveur.',
|
||||
'export' => 'Exporter',
|
||||
'export_opml' => 'Exporter la liste des flux (OPML)',
|
||||
'export_starred' => 'Exporter les favoris',
|
||||
'export_no_zip_extension' => 'L’extension Zip n’est pas présente sur votre serveur. Veuillez essayer d’exporter les fichiers un par un.',
|
||||
'starred_list' => 'Liste des articles favoris',
|
||||
'feed_list' => 'Liste des articles de %s',
|
||||
'or' => 'ou',
|
||||
|
@ -224,7 +234,7 @@ return array (
|
|||
'persona_connection_email' => 'Adresse courriel de connexion<br /><small>(pour <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>',
|
||||
'allow_anonymous' => 'Autoriser la lecture anonyme des articles de l’utilisateur par défaut (%s)',
|
||||
'allow_anonymous_refresh' => 'Autoriser le rafraîchissement anonyme des flux',
|
||||
'unsafe_autologin' => 'Autoriser les connexion automatiques non-sûres au format : ',
|
||||
'unsafe_autologin' => 'Autoriser les connexions automatiques non-sûres au format : ',
|
||||
'api_enabled' => 'Autoriser l’accès par <abbr>API</abbr> <small>(nécessaire pour les applis mobiles)</small>',
|
||||
'auth_token' => 'Jeton d’identification',
|
||||
'explain_token' => 'Permet d’accéder à la sortie RSS de l’utilisateur par défaut sans besoin de s’authentifier.<br /><kbd>%s?output=rss&token=%s</kbd>',
|
||||
|
@ -257,6 +267,8 @@ return array (
|
|||
'sort_order' => 'Ordre de tri',
|
||||
'auto_load_more' => 'Charger les articles suivants en bas de page',
|
||||
'display_articles_unfolded' => 'Afficher les articles dépliés par défaut',
|
||||
'display_categories_unfolded' => 'Afficher les catégories pliées par défaut',
|
||||
'hide_read_feeds' => 'Cacher les catégories & flux sans article non-lu (uniquement en affichage “articles non lus”)',
|
||||
'after_onread' => 'Après “marquer tout comme lu”,',
|
||||
'jump_next' => 'sauter au prochain voisin non lu (flux ou catégorie)',
|
||||
'article_icons' => 'Icônes d’article',
|
||||
|
@ -339,6 +351,8 @@ return array (
|
|||
'login_required' => 'Accès protégé par mot de passe :',
|
||||
|
||||
'confirm_action' => 'Êtes-vous sûr(e) de vouloir continuer ? Cette action ne peut être annulée !',
|
||||
'notif_title_new_articles' => 'FreshRSS : nouveaux articles !',
|
||||
'notif_body_new_articles' => 'Il y a \d nouveaux articles à lire sur FreshRSS.',
|
||||
|
||||
// DATE
|
||||
'january' => 'janvier',
|
||||
|
@ -353,6 +367,25 @@ return array (
|
|||
'october' => 'octobre',
|
||||
'november' => 'novembre',
|
||||
'december' => 'décembre',
|
||||
'jan' => 'jan.',
|
||||
'feb' => 'fév.',
|
||||
'mar' => 'mar.',
|
||||
'apr' => 'avr.',
|
||||
'may' => 'mai.',
|
||||
'jun' => 'juin',
|
||||
'jul' => 'jui.',
|
||||
'aug' => 'août',
|
||||
'sep' => 'sep.',
|
||||
'oct' => 'oct.',
|
||||
'nov' => 'nov.',
|
||||
'dec' => 'déc.',
|
||||
'sun' => 'dim.',
|
||||
'mon' => 'lun.',
|
||||
'tue' => 'mar.',
|
||||
'wed' => 'mer.',
|
||||
'thu' => 'jeu.',
|
||||
'fri' => 'ven.',
|
||||
'sat' => 'sam.',
|
||||
// format spécial pour la fonction date()
|
||||
'Jan' => '\j\a\n\v\i\e\r',
|
||||
'Feb' => '\f\é\v\r\i\e\r',
|
||||
|
|
|
@ -28,8 +28,8 @@ return array (
|
|||
'minz_is_nok' => 'You lack the Minz framework. You should execute <em>build.sh</em> script or <a href="https://github.com/marienfressinaud/MINZ">download it on Github</a> and install in <em>%s</em> directory the content of its <em>/lib</em> directory.',
|
||||
'curl_is_ok' => 'You have version %s of cURL',
|
||||
'curl_is_nok' => 'You lack cURL (php5-curl package)',
|
||||
'pdomysql_is_ok' => 'You have PDO and its driver for MySQL',
|
||||
'pdomysql_is_nok' => 'You lack PDO or its driver for MySQL (php5-mysql package)',
|
||||
'pdo_is_ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite)',
|
||||
'pdo_is_nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite)',
|
||||
'dom_is_ok' => 'You have the required library to browse the DOM',
|
||||
'dom_is_nok' => 'You lack a required library to browse the DOM (php-xml package)',
|
||||
'pcre_is_ok' => 'You have the required library for regular expressions (PCRE)',
|
||||
|
|
|
@ -28,8 +28,8 @@ return array (
|
|||
'minz_is_nok' => 'Vous ne disposez pas de la librairie Minz. Vous devriez exécuter le script <em>build.sh</em> ou bien <a href="https://github.com/marienfressinaud/MINZ">la télécharger sur Github</a> et installer dans le répertoire <em>%s</em> le contenu de son répertoire <em>/lib</em>.',
|
||||
'curl_is_ok' => 'Vous disposez de cURL dans sa version %s',
|
||||
'curl_is_nok' => 'Vous ne disposez pas de cURL (paquet php5-curl)',
|
||||
'pdomysql_is_ok' => 'Vous disposez de PDO et de son driver pour MySQL (paquet php5-mysql)',
|
||||
'pdomysql_is_nok' => 'Vous ne disposez pas de PDO ou de son driver pour MySQL',
|
||||
'pdo_is_ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite)',
|
||||
'pdo_is_nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite)',
|
||||
'dom_is_ok' => 'Vous disposez du nécessaire pour parcourir le DOM',
|
||||
'dom_is_nok' => 'Il manque une librairie pour parcourir le DOM (paquet php-xml)',
|
||||
'pcre_is_ok' => 'Vous disposez du nécessaire pour les expressions régulières (PCRE)',
|
||||
|
|
|
@ -249,11 +249,11 @@ function saveStep3 () {
|
|||
'base_url' => '',
|
||||
'title' => $_SESSION['title'],
|
||||
'default_user' => $_SESSION['default_user'],
|
||||
'auth_type' => $_SESSION['auth_type'],
|
||||
'allow_anonymous' => isset($_SESSION['allow_anonymous']) ? $_SESSION['allow_anonymous'] : false,
|
||||
'allow_anonymous_refresh' => false,
|
||||
'unsafe_autologin_enabled' => false,
|
||||
'api_enabled' => false,
|
||||
'allow_anonymous_refresh' => isset($_SESSION['allow_anonymous_refresh']) ? $_SESSION['allow_anonymous_refresh'] : false,
|
||||
'auth_type' => $_SESSION['auth_type'],
|
||||
'api_enabled' => isset($_SESSION['api_enabled']) ? $_SESSION['api_enabled'] : false,
|
||||
'unsafe_autologin_enabled' => isset($_SESSION['unsafe_autologin_enabled']) ? $_SESSION['unsafe_autologin_enabled'] : false,
|
||||
),
|
||||
'db' => array(
|
||||
'type' => $_SESSION['bd_type'],
|
||||
|
@ -499,7 +499,7 @@ function checkStep0 () {
|
|||
if ($ini_array) {
|
||||
$ini_general = isset($ini_array['general']) ? $ini_array['general'] : null;
|
||||
if ($ini_general) {
|
||||
$keys = array('environment', 'salt', 'title', 'default_user', 'allow_anonymous', 'auth_type');
|
||||
$keys = array('environment', 'salt', 'title', 'default_user', 'allow_anonymous', 'allow_anonymous_refresh', 'auth_type', 'api_enabled', 'unsafe_autologin_enabled');
|
||||
foreach ($keys as $key) {
|
||||
if ((empty($_SESSION[$key])) && isset($ini_general[$key])) {
|
||||
$_SESSION[$key] = $ini_general[$key];
|
||||
|
@ -574,7 +574,9 @@ function checkStep1 () {
|
|||
$php = version_compare (PHP_VERSION, '5.2.1') >= 0;
|
||||
$minz = file_exists (LIB_PATH . '/Minz');
|
||||
$curl = extension_loaded ('curl');
|
||||
$pdo = extension_loaded ('pdo_mysql');
|
||||
$pdo_mysql = extension_loaded ('pdo_mysql');
|
||||
$pdo_sqlite = extension_loaded ('pdo_sqlite');
|
||||
$pdo = $pdo_mysql || $pdo_sqlite;
|
||||
$pcre = extension_loaded ('pcre');
|
||||
$ctype = extension_loaded ('ctype');
|
||||
$dom = class_exists('DOMDocument');
|
||||
|
@ -588,7 +590,9 @@ function checkStep1 () {
|
|||
'php' => $php ? 'ok' : 'ko',
|
||||
'minz' => $minz ? 'ok' : 'ko',
|
||||
'curl' => $curl ? 'ok' : 'ko',
|
||||
'pdo-mysql' => $pdo ? 'ok' : 'ko',
|
||||
'pdo-mysql' => $pdo_mysql ? 'ok' : 'ko',
|
||||
'pdo-sqlite' => $pdo_sqlite ? 'ok' : 'ko',
|
||||
'pdo' => $pdo ? 'ok' : 'ko',
|
||||
'pcre' => $pcre ? 'ok' : 'ko',
|
||||
'ctype' => $ctype ? 'ok' : 'ko',
|
||||
'dom' => $dom ? 'ok' : 'ko',
|
||||
|
@ -766,10 +770,10 @@ function printStep1 () {
|
|||
<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('minz_is_nok', LIB_PATH . '/Minz'); ?></p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($res['pdo-mysql'] == 'ok') { ?>
|
||||
<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('pdomysql_is_ok'); ?></p>
|
||||
<?php if ($res['pdo'] == 'ok') { ?>
|
||||
<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('pdo_is_ok'); ?></p>
|
||||
<?php } else { ?>
|
||||
<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('pdomysql_is_nok'); ?></p>
|
||||
<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('pdo_is_nok'); ?></p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($res['curl'] == 'ok') { ?>
|
||||
|
@ -923,14 +927,18 @@ function printStep3 () {
|
|||
<label class="group-name" for="type"><?php echo _t ('bdd_type'); ?></label>
|
||||
<div class="group-controls">
|
||||
<select name="type" id="type" onchange="mySqlShowHide()">
|
||||
<?php if (extension_loaded('pdo_mysql')) {?>
|
||||
<option value="mysql"
|
||||
<?php echo (isset($_SESSION['bd_type']) && $_SESSION['bd_type'] === 'mysql') ? 'selected="selected"' : ''; ?>>
|
||||
MySQL
|
||||
</option>
|
||||
<?php }?>
|
||||
<?php if (extension_loaded('pdo_sqlite')) {?>
|
||||
<option value="sqlite"
|
||||
<?php echo (isset($_SESSION['bd_type']) && $_SESSION['bd_type'] === 'sqlite') ? 'selected="selected"' : ''; ?>>
|
||||
SQLite
|
||||
</option>
|
||||
<?php }?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="aside aside_flux" id="aside_flux">
|
||||
<div class="aside aside_flux<?php if ($this->conf->hide_read_feeds && ($this->state & FreshRSS_Entry::STATE_NOT_READ) && !($this->state & FreshRSS_Entry::STATE_READ)) echo ' state_unread'; ?>" id="aside_flux">
|
||||
<a class="toggle_aside" href="#close"><?php echo FreshRSS_Themes::icon('close'); ?></a>
|
||||
|
||||
<ul class="categories">
|
||||
|
@ -41,11 +41,17 @@
|
|||
foreach ($this->cat_aside as $cat) {
|
||||
$feeds = $cat->feeds ();
|
||||
if (!empty ($feeds)) {
|
||||
?><li><?php
|
||||
$c_active = false;
|
||||
if ($this->get_c == $cat->id ()) {
|
||||
$c_active = true;
|
||||
if ($this->conf->display_categories) {
|
||||
if ($this->get_c == $cat->id () && $this->get_f) {
|
||||
$c_active = true;
|
||||
}
|
||||
} else {
|
||||
if ($this->get_c == $cat->id ()) {
|
||||
$c_active = true;
|
||||
}
|
||||
}
|
||||
?><li data-unread="<?php echo $cat->nbNotRead(); ?>"<?php if ($c_active) echo ' class="active"'; ?>><?php
|
||||
?><div class="category stick<?php echo $c_active ? ' active' : ''; ?>"><?php
|
||||
?><a data-unread="<?php echo formatNumber($cat->nbNotRead()); ?>" class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php $arUrl['params']['get'] = 'c_' . $cat->id(); echo Minz_Url::display($arUrl); ?>"><?php echo $cat->name (); ?></a><?php
|
||||
?><a class="btn dropdown-toggle" href="#"><?php echo FreshRSS_Themes::icon($c_active ? 'up' : 'down'); ?></a><?php
|
||||
|
@ -55,7 +61,7 @@
|
|||
$feed_id = $feed->id ();
|
||||
$nbEntries = $feed->nbEntries ();
|
||||
$f_active = ($this->get_f == $feed_id);
|
||||
?><li id="f_<?php echo $feed_id; ?>" class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError () ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>"><?php
|
||||
?><li id="f_<?php echo $feed_id; ?>" class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError () ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>"><?php
|
||||
?><div class="dropdown"><?php
|
||||
?><div class="dropdown-target"></div><?php
|
||||
?><a class="dropdown-toggle" data-fweb="<?php echo $feed->website (); ?>"><?php echo FreshRSS_Themes::icon('configure'); ?></a><?php
|
||||
|
@ -77,6 +83,7 @@
|
|||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-close"><a href="#close">❌</a></li>
|
||||
<li class="item"><a href="<?php echo _url ('index', 'index', 'get', 'f_!!!!!!'); ?>"><?php echo Minz_Translate::t ('filter'); ?></a></li>
|
||||
<li class="item"><a href="<?php echo _url ('stats', 'repartition', 'id', '!!!!!!'); ?>"><?php echo Minz_Translate::t ('stats'); ?></a></li>
|
||||
<li class="item"><a target="_blank" href="http://example.net/"><?php echo Minz_Translate::t ('see_website'); ?></a></li>
|
||||
<?php if ($this->loginOk) { ?>
|
||||
<li class="separator"></li>
|
||||
|
|
|
@ -6,4 +6,7 @@
|
|||
<li class="item<?php echo Minz_Request::actionName () == 'idle' ? ' active' : ''; ?>">
|
||||
<a href="<?php echo _url ('stats', 'idle'); ?>"><?php echo Minz_Translate::t ('stats_idle'); ?></a>
|
||||
</li>
|
||||
<li class="item<?php echo Minz_Request::actionName () == 'repartition' ? ' active' : ''; ?>">
|
||||
<a href="<?php echo _url ('stats', 'repartition'); ?>"><?php echo Minz_Translate::t ('stats_repartition'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
?>
|
||||
<link id="prefetch" rel="next prefetch" href="<?php echo Minz_Url::display(array('c' => Minz_Request::controllerName(), 'a' => Minz_Request::actionName(), 'params' => $params)); ?>" />
|
||||
<?php } ?>
|
||||
<link rel="shortcut icon" type="image/x-icon" sizes="16x16 64x64" href="<?php echo Minz_Url::display('/favicon.ico'); ?>" />
|
||||
<link rel="shortcut icon" id="favicon" type="image/x-icon" sizes="16x16 64x64" href="<?php echo Minz_Url::display('/favicon.ico'); ?>" />
|
||||
<link rel="icon msapplication-TileImage apple-touch-icon" type="image/png" sizes="256x256" href="<?php echo Minz_Url::display('/themes/icons/favicon-256.png'); ?>" />
|
||||
<?php
|
||||
if (isset($this->url)) {
|
||||
|
|
|
@ -164,11 +164,15 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ($this->order === 'ASC') {
|
||||
$idMax = 0;
|
||||
} else {
|
||||
$p = isset($this->entries[0]) ? $this->entries[0] : null;
|
||||
$idMax = $p === null ? '0' : $p->id();
|
||||
|
||||
$p = isset($this->entries[0]) ? $this->entries[0] : null;
|
||||
$idMax = $p === null ? (time() - 1) . '000000' : $p->id();
|
||||
|
||||
if ($this->order === 'ASC') { //In this case we do not know but we guess idMax
|
||||
$idMax2 = (time() - 1) . '000000';
|
||||
if (strcmp($idMax2, $idMax) > 0) {
|
||||
$idMax = $idMax2;
|
||||
}
|
||||
}
|
||||
|
||||
$arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('get' => $get, 'nextGet' => $nextGet, 'idMax' => $idMax));
|
||||
|
@ -221,7 +225,9 @@
|
|||
|
||||
<?php
|
||||
$url_output['params']['output'] = 'rss';
|
||||
$url_output['params']['token'] = $this->conf->token;
|
||||
if ($this->conf->token) {
|
||||
$url_output['params']['token'] = $this->conf->token;
|
||||
}
|
||||
?>
|
||||
<a class="view_rss btn" target="_blank" title="<?php echo Minz_Translate::t ('rss_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
|
||||
<?php echo FreshRSS_Themes::icon('rss'); ?>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<div class="form-group">
|
||||
<label class="group-name" for="posts_per_page"><?php echo Minz_Translate::t ('articles_per_page'); ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" />
|
||||
<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" min="5" max="50" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -44,10 +44,9 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="auto_load_more">
|
||||
<input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo $this->conf->auto_load_more ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t ('auto_load_more'); ?>
|
||||
<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
|
||||
<label class="checkbox" for="hide_read_feeds">
|
||||
<input type="checkbox" name="hide_read_feeds" id="hide_read_feeds" value="1"<?php echo $this->conf->hide_read_feeds ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t('hide_read_feeds'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -64,9 +63,9 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="lazyload">
|
||||
<input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo $this->conf->lazyload ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t ('img_with_lazyload'); ?>
|
||||
<label class="checkbox" for="display_categories">
|
||||
<input type="checkbox" name="display_categories" id="display_categories" value="1"<?php echo $this->conf->display_categories ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t ('display_categories_unfolded'); ?>
|
||||
<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -82,6 +81,26 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="auto_load_more">
|
||||
<input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo $this->conf->auto_load_more ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t ('auto_load_more'); ?>
|
||||
<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="lazyload">
|
||||
<input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo $this->conf->lazyload ? ' checked="checked"' : ''; ?> />
|
||||
<?php echo Minz_Translate::t ('img_with_lazyload'); ?>
|
||||
<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="reading_confirm">
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
<div class="post">
|
||||
<div class="alert alert-error">
|
||||
<h1 class="alert-head"><?php echo $this->code; ?></h1>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
switch(Minz_Request::param ('code')) {
|
||||
case 403:
|
||||
echo Minz_Translate::t ('forbidden_access');
|
||||
break;
|
||||
case 404:
|
||||
default:
|
||||
echo Minz_Translate::t ('page_not_found');
|
||||
} ?><br />
|
||||
<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Minz_Translate::t ('back_to_rss_feeds'); ?></a>
|
||||
<?php echo $this->errorMessage; ?><br />
|
||||
<a href="<?php echo _url('index', 'index'); ?>"><?php echo Minz_Translate::t('back_to_rss_feeds'); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,9 +18,9 @@ foreach ($this->categories as $key => $cat) {
|
|||
$opml_array['body'][$key]['@outlines'][] = array(
|
||||
'text' => htmlspecialchars_decode($feed->name()),
|
||||
'type' => 'rss',
|
||||
'xmlUrl' => $feed->url(),
|
||||
'htmlUrl' => $feed->website(),
|
||||
'description' => $feed->description()
|
||||
'xmlUrl' => htmlspecialchars_decode($feed->url()),
|
||||
'htmlUrl' => htmlspecialchars_decode($feed->website()),
|
||||
'description' => htmlspecialchars_decode($feed->description()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ echo 'var ',
|
|||
',auto_mark_site=', $mark['site'] ? 'true' : 'false',
|
||||
',auto_mark_scroll=', $mark['scroll'] ? 'true' : 'false',
|
||||
',auto_load_more=', $this->conf->auto_load_more ? 'true' : 'false',
|
||||
',full_lazyload=', $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'true' : 'false',
|
||||
',does_lazyload=', $this->conf->lazyload ? 'true' : 'false',
|
||||
',sticky_post=', $this->conf->sticky_post ? 'true' : 'false';
|
||||
|
||||
|
@ -50,6 +49,8 @@ echo 'authType="', $authType, '",',
|
|||
'url_logout="', _url ('index', 'logout'), '",';
|
||||
|
||||
echo 'str_confirmation="', Minz_Translate::t('confirm_action'), '"', ",\n";
|
||||
echo 'str_notif_title_articles="', Minz_Translate::t('notif_title_new_articles'), '"', ",\n";
|
||||
echo 'str_notif_body_articles="', Minz_Translate::t('notif_body_new_articles'), '"', ",\n";
|
||||
|
||||
$autoActualise = Minz_Session::param('actualize_feeds', false);
|
||||
echo 'auto_actualize_feeds=', $autoActualise ? 'true' : 'false', ";\n";
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<?php } elseif ($markReadUrl) { ?>
|
||||
<a id="bigMarkAsRead" href="<?php echo $markReadUrl; ?>"<?php if ($this->conf->reading_confirm) { echo ' class="confirm"';} ?>>
|
||||
<?php echo Minz_Translate::t ('nothing_to_load'); ?><br />
|
||||
<span class="bigTick">✔</span><br />
|
||||
<span class="bigTick">✓</span><br />
|
||||
<?php echo Minz_Translate::t ('mark_all_read'); ?>
|
||||
</a>
|
||||
<?php } else { ?>
|
||||
|
|
|
@ -81,7 +81,12 @@ if (!empty($this->entries)) {
|
|||
}
|
||||
}
|
||||
$feed = FreshRSS_CategoryDAO::findFeed($this->cat_aside, $item->feed ()); //We most likely already have the feed object in cache
|
||||
if (empty($feed)) $feed = $item->feed (true);
|
||||
if ($feed == null) {
|
||||
$feed = $item->feed(true);
|
||||
if ($feed == null) {
|
||||
$feed = FreshRSS_Feed::example();
|
||||
}
|
||||
}
|
||||
?><li class="item website"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> <span><?php echo $feed->name(); ?></span></a></li>
|
||||
<li class="item title"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo $item->title (); ?></a></li>
|
||||
<?php if ($topline_date) { ?><li class="item date"><?php echo $item->date (); ?> </li><?php } ?>
|
||||
|
@ -92,13 +97,9 @@ if (!empty($this->entries)) {
|
|||
<div class="content <?php echo $content_width; ?>">
|
||||
<h1 class="title"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo $item->title (); ?></a></h1>
|
||||
<?php
|
||||
$author = $item->author ();
|
||||
echo $author != '' ? '<div class="author">' . Minz_Translate::t ('by_author', $author) . '</div>' : '';
|
||||
if ($lazyload) {
|
||||
echo $hidePosts ? lazyIframe(lazyimg($item->content())) : lazyimg($item->content());
|
||||
} else {
|
||||
echo $item->content();
|
||||
}
|
||||
$author = $item->author();
|
||||
echo $author != '' ? '<div class="author">' . Minz_Translate::t('by_author', $author) . '</div>' : '',
|
||||
$lazyload && $hidePosts ? lazyimg($item->content()) : $item->content();
|
||||
?>
|
||||
</div>
|
||||
<ul class="horizontal-list bottom"><?php
|
||||
|
|
|
@ -21,19 +21,13 @@ if (!empty($this->entries)) {
|
|||
</a>
|
||||
<h1 class="title"><?php echo $item->title (); ?></h1>
|
||||
|
||||
<div class="author">
|
||||
<?php $author = $item->author (); ?>
|
||||
<?php echo $author != '' ? Minz_Translate::t ('by_author', $author) . ' — ' : ''; ?>
|
||||
<?php echo $item->date (); ?>
|
||||
</div>
|
||||
<div class="author"><?php
|
||||
$author = $item->author();
|
||||
echo $author != '' ? Minz_Translate::t('by_author', $author) . ' — ' : '',
|
||||
$item->date();
|
||||
?></div>
|
||||
|
||||
<?php
|
||||
if ($lazyload) {
|
||||
echo lazyimg($item->content ());
|
||||
} else {
|
||||
echo $item->content();
|
||||
}
|
||||
?>
|
||||
<?php echo $item->content(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
0
sources/app/views/importExport/export.phtml
Executable file
|
@ -1,12 +1,14 @@
|
|||
<?php $this->partial ('aside_feed'); ?>
|
||||
<?php $this->partial('aside_feed'); ?>
|
||||
|
||||
<div class="post ">
|
||||
<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Minz_Translate::t ('back_to_rss_feeds'); ?></a>
|
||||
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('back_to_rss_feeds'); ?></a>
|
||||
|
||||
<form method="post" action="<?php echo _url('importExport', 'import'); ?>" enctype="multipart/form-data">
|
||||
<legend><?php echo Minz_Translate::t ('import'); ?></legend>
|
||||
<legend><?php echo _t('import'); ?></legend>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="file"><?php echo Minz_Translate::t ('file_to_import'); ?></label>
|
||||
<label class="group-name" for="file">
|
||||
<?php echo extension_loaded('zip') ? _t('file_to_import') : _t('file_to_import_no_zip'); ?>
|
||||
</label>
|
||||
<div class="group-controls">
|
||||
<input type="file" name="file" id="file" />
|
||||
</div>
|
||||
|
@ -14,27 +16,34 @@
|
|||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('import'); ?></button>
|
||||
<button type="submit" class="btn btn-important"><?php echo _t('import'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if (count($this->feeds) > 0) { ?>
|
||||
<form method="post" action="<?php echo _url('importExport', 'export'); ?>">
|
||||
<legend><?php echo Minz_Translate::t ('export'); ?></legend>
|
||||
<legend><?php echo _t('export'); ?></legend>
|
||||
<div class="form-group">
|
||||
<div class="group-controls">
|
||||
<label class="checkbox" for="export_opml">
|
||||
<input type="checkbox" name="export_opml" id="export_opml" value="1" checked="checked" />
|
||||
<?php echo Minz_Translate::t ('export_opml'); ?>
|
||||
<?php echo _t('export_opml'); ?>
|
||||
</label>
|
||||
|
||||
<label class="checkbox" for="export_starred">
|
||||
<input type="checkbox" name="export_starred" id="export_starred" value="1" checked="checked" />
|
||||
<?php echo Minz_Translate::t ('export_starred'); ?>
|
||||
<input type="checkbox" name="export_starred" id="export_starred" value="1" <?php echo extension_loaded('zip') ? 'checked="checked"' : ''; ?> />
|
||||
<?php echo _t('export_starred'); ?>
|
||||
</label>
|
||||
|
||||
<select name="export_feeds[]" size="<?php echo min(10, count($this->feeds)); ?>" multiple="multiple">
|
||||
<?php
|
||||
$select_args = '';
|
||||
if (extension_loaded('zip')) {
|
||||
$select_args = ' size="' . min(10, count($this->feeds)) .'" multiple="multiple"';
|
||||
}
|
||||
?>
|
||||
<select name="export_feeds[]"<?php echo $select_args; ?>>
|
||||
<?php echo extension_loaded('zip') ? '' : '<option></option>'; ?>
|
||||
<?php foreach ($this->feeds as $feed) { ?>
|
||||
<option value="<?php echo $feed->id(); ?>"><?php echo $feed->name(); ?></option>
|
||||
<?php } ?>
|
||||
|
@ -44,7 +53,7 @@
|
|||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('export'); ?></button>
|
||||
<button type="submit" class="btn btn-important"><?php echo _t('export'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,32 +1,39 @@
|
|||
<div class="prompt">
|
||||
<h1><?php echo Minz_Translate::t('login'); ?></h1><?php
|
||||
<h1><?php echo _t('login'); ?></h1><?php
|
||||
|
||||
switch (Minz_Configuration::authType()) {
|
||||
case 'form':
|
||||
?><form id="loginForm" method="post" action="<?php echo _url('index', 'formLogin'); ?>">
|
||||
<div>
|
||||
<label for="username"><?php echo Minz_Translate::t('username'); ?></label>
|
||||
<label for="username"><?php echo _t('username'); ?></label>
|
||||
<input type="text" id="username" name="username" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" autofocus="autofocus" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="passwordPlain"><?php echo Minz_Translate::t('password'); ?></label>
|
||||
<label for="passwordPlain"><?php echo _t('password'); ?></label>
|
||||
<input type="password" id="passwordPlain" required="required" />
|
||||
<input type="hidden" id="challenge" name="challenge" /><br />
|
||||
<noscript><strong><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></strong></noscript>
|
||||
<noscript><strong><?php echo _t('javascript_should_be_activated'); ?></strong></noscript>
|
||||
</div>
|
||||
<div>
|
||||
<button id="loginButton" type="submit" class="btn btn-important"><?php echo Minz_Translate::t('login'); ?></button>
|
||||
<label class="checkbox" for="keep_logged_in">
|
||||
<input type="checkbox" name="keep_logged_in" id="keep_logged_in" value="1" />
|
||||
<?php echo _t('keep_logged_in'); ?>
|
||||
</label>
|
||||
<br />
|
||||
</div>
|
||||
<div>
|
||||
<button id="loginButton" type="submit" class="btn btn-important"><?php echo _t('login'); ?></button>
|
||||
</div>
|
||||
</form><?php
|
||||
break;
|
||||
|
||||
case 'persona':
|
||||
?><p>
|
||||
<?php echo FreshRSS_Themes::icon('login'); ?>
|
||||
<a class="signin" href="#"><?php echo Minz_Translate::t('login_with_persona'); ?></a>
|
||||
<?php echo _i('login'); ?>
|
||||
<a class="signin" href="#"><?php echo _t('login_with_persona'); ?></a>
|
||||
</p><?php
|
||||
break;
|
||||
} ?>
|
||||
|
||||
<p><a href="<?php echo _url('index', 'about'); ?>"><?php echo Minz_Translate::t('about_freshrss'); ?></a></p>
|
||||
<p><a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('about_freshrss'); ?></a></p>
|
||||
</div>
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
"use strict";
|
||||
var feeds = [<?php
|
||||
foreach ($this->feeds as $feed) {
|
||||
echo "'", Minz_Url::display(array('c' => 'feed', 'a' => 'actualize', 'params' => array('id' => $feed->id(), 'ajax' => '1')), 'php'), "',\n";
|
||||
}
|
||||
?>],
|
||||
var feeds = [<?php foreach ($this->feeds as $feed) { ?>{<?php
|
||||
?>url: "<?php echo Minz_Url::display(array('c' => 'feed', 'a' => 'actualize', 'params' => array('id' => $feed->id(), 'ajax' => '1')), 'php'); ?>",<?php
|
||||
?>title: "<?php echo $feed->name(); ?>"<?php
|
||||
?>},<?php } ?>],
|
||||
feed_processed = 0,
|
||||
feed_count = feeds.length;
|
||||
|
||||
function initProgressBar(init) {
|
||||
if (init) {
|
||||
$("body").after("\<div id=\"actualizeProgress\" class=\"notification good\">\
|
||||
<?php echo _t('refresh'); ?> <span class=\"progress\">0 / " + feed_count + "</span><br />\
|
||||
<progress id=\"actualizeProgressBar\" value=\"0\" max=\"" + feed_count + "\"></progress>\
|
||||
<?php echo _t('refresh'); ?><br /><span class=\"title\">/</span><br />\
|
||||
<span class=\"progress\">0 / " + feed_count + "</span>\
|
||||
</div>");
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
function updateProgressBar(i) {
|
||||
$("#actualizeProgressBar").val(i);
|
||||
function updateProgressBar(i, title_feed) {
|
||||
$("#actualizeProgress .progress").html(i + " / " + feed_count);
|
||||
$("#actualizeProgress .title").html(title_feed);
|
||||
}
|
||||
|
||||
function updateFeeds() {
|
||||
|
@ -43,10 +42,10 @@ function updateFeed() {
|
|||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: feed,
|
||||
url: feed['url'],
|
||||
}).complete(function (data) {
|
||||
feed_processed++;
|
||||
updateProgressBar(feed_processed);
|
||||
updateProgressBar(feed_processed, feed['title']);
|
||||
|
||||
if (feed_processed === feed_count) {
|
||||
initProgressBar(false);
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
<?php $this->partial('aside_stats'); ?>
|
||||
|
||||
<div class="post content">
|
||||
<a href="<?php echo _url ('index', 'index'); ?>"><?php echo _t ('back_to_rss_feeds'); ?></a>
|
||||
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('back_to_rss_feeds'); ?></a>
|
||||
|
||||
<h1><?php echo _t ('stats_idle'); ?></h1>
|
||||
<h1><?php echo _t('stats_idle'); ?></h1>
|
||||
|
||||
<?php foreach ($this->idleFeeds as $period => $feeds){ ?>
|
||||
<?php
|
||||
foreach ($this->idleFeeds as $period => $feeds) {
|
||||
if (!empty($feeds)) {
|
||||
?>
|
||||
<div class="stat">
|
||||
<h2><?php echo _t ($period); ?></h2>
|
||||
<h2><?php echo _t($period); ?></h2>
|
||||
|
||||
<ul>
|
||||
<?php foreach ($feeds as $feed){ ?>
|
||||
<li><?php echo $feed; ?></li>
|
||||
<?php foreach ($feeds as $feed) { ?>
|
||||
<li><a href="<?php echo _url('configure', 'feed', 'id', $feed['id']); ?>" title="<?php echo date('Y-m-d', $feed['last_date']); ?>"><?php echo $feed['name']; ?></a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
<?php $this->partial('aside_stats'); ?>
|
||||
|
||||
<div class="post content">
|
||||
<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Minz_Translate::t ('back_to_rss_feeds'); ?></a>
|
||||
|
||||
<h1><?php echo Minz_Translate::t ('stats_main'); ?></h1>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo Minz_Translate::t ('stats_entry_repartition'); ?></h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th><?php echo Minz_Translate::t ('main_stream'); ?></th>
|
||||
<th><?php echo Minz_Translate::t ('all_feeds'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo Minz_Translate::t ('status_total'); ?></th>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['main_stream']['total']); ?></td>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['all_feeds']['total']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo Minz_Translate::t ('status_read'); ?></th>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['main_stream']['read']); ?></td>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['all_feeds']['read']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo Minz_Translate::t ('status_unread'); ?></th>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['main_stream']['unread']); ?></td>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['all_feeds']['unread']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo Minz_Translate::t ('status_favorites'); ?></th>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['main_stream']['favorite']); ?></td>
|
||||
<td class="numeric"><?php echo formatNumber($this->repartition['all_feeds']['favorite']); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo Minz_Translate::t ('stats_entry_per_day'); ?></h2>
|
||||
<div id="statsEntryPerDay" style="height: 300px"></div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo Minz_Translate::t ('stats_feed_per_category'); ?></h2>
|
||||
<div id="statsFeedPerCategory" style="height: 300px"></div>
|
||||
<div id="statsFeedPerCategoryLegend"></div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo Minz_Translate::t ('stats_entry_per_category'); ?></h2>
|
||||
<div id="statsEntryPerCategory" style="height: 300px"></div>
|
||||
<div id="statsEntryPerCategoryLegend"></div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo Minz_Translate::t ('stats_top_feed'); ?></h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo Minz_Translate::t ('feed'); ?></th>
|
||||
<th><?php echo Minz_Translate::t ('category'); ?></th>
|
||||
<th><?php echo Minz_Translate::t ('stats_entry_count'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->topFeed as $feed): ?>
|
||||
<tr>
|
||||
<td><?php echo $feed['name']; ?></td>
|
||||
<td><?php echo $feed['category']; ?></td>
|
||||
<td class="numeric"><?php echo formatNumber($feed['count']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
function initStats() {
|
||||
if (!window.Flotr) {
|
||||
if (window.console) {
|
||||
console.log('FreshRSS waiting for Flotr…');
|
||||
}
|
||||
window.setTimeout(initStats, 50);
|
||||
return;
|
||||
}
|
||||
// Entry per day
|
||||
Flotr.draw(document.getElementById('statsEntryPerDay'),
|
||||
[<?php echo $this->count ?>],
|
||||
{
|
||||
grid: {verticalLines: false},
|
||||
bars: {horizontal: false, show: true},
|
||||
xaxis: {noTicks: 6, showLabels: false, tickDecimals: 0},
|
||||
yaxis: {min: 0},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return numberFormat(obj.y);}}
|
||||
});
|
||||
// Feed per category
|
||||
Flotr.draw(document.getElementById('statsFeedPerCategory'),
|
||||
<?php echo $this->feedByCategory ?>,
|
||||
{
|
||||
grid: {verticalLines: false, horizontalLines: false},
|
||||
pie: {explode: 10, show: true, labelFormatter: function(){return '';}},
|
||||
xaxis: {showLabels: false},
|
||||
yaxis: {showLabels: false},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return obj.series.label + ' - '+ numberFormat(obj.y) + ' ('+ (obj.fraction * 100).toFixed(1) + '%)';}},
|
||||
legend: {container: document.getElementById('statsFeedPerCategoryLegend'), noColumns: 3}
|
||||
});
|
||||
// Entry per category
|
||||
Flotr.draw(document.getElementById('statsEntryPerCategory'),
|
||||
<?php echo $this->entryByCategory ?>,
|
||||
{
|
||||
grid: {verticalLines: false, horizontalLines: false},
|
||||
pie: {explode: 10, show: true, labelFormatter: function(){return '';}},
|
||||
xaxis: {showLabels: false},
|
||||
yaxis: {showLabels: false},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return obj.series.label + ' - '+ numberFormat(obj.y) + ' ('+ (obj.fraction * 100).toFixed(1) + '%)';}},
|
||||
legend: {container: document.getElementById('statsEntryPerCategoryLegend'), noColumns: 3}
|
||||
});
|
||||
}
|
||||
initStats();
|
||||
</script>
|
114
sources/app/views/stats/repartition.phtml
Executable file
|
@ -0,0 +1,114 @@
|
|||
<?php $this->partial('aside_stats'); ?>
|
||||
|
||||
<div class="post content">
|
||||
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('back_to_rss_feeds'); ?></a>
|
||||
|
||||
<h1><?php echo _t('stats_repartition'); ?></h1>
|
||||
|
||||
<select id="feed_select">
|
||||
<option data-url="<?php echo _url('stats', 'repartition')?>"><?php echo _t('all_feeds')?></option>
|
||||
<?php foreach ($this->categories as $category) {
|
||||
$feeds = $category->feeds();
|
||||
if (!empty($feeds)) {
|
||||
echo '<optgroup label=', $category->name(), '>';
|
||||
foreach ($feeds as $feed) {
|
||||
if ($this->feed && $feed->id() == $this->feed->id()){
|
||||
echo '<option value ="', $feed->id(), '" selected data-url="', _url('stats', 'repartition', 'id', $feed->id()), '">', $feed->name(), '</option>';
|
||||
} else {
|
||||
echo '<option value ="', $feed->id(), '" data-url="', _url('stats', 'repartition', 'id', $feed->id()), '">', $feed->name(), '</option>';
|
||||
}
|
||||
}
|
||||
echo '</optgroup>';
|
||||
}
|
||||
}?>
|
||||
</select>
|
||||
|
||||
<?php if ($this->feed) {?>
|
||||
<a href="<?php echo _url('configure', 'feed', 'id', $this->feed->id()); ?>">
|
||||
<?php echo _t('administration'); ?>
|
||||
</a>
|
||||
<?php }?>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo _t('stats_entry_per_hour'); ?></h2>
|
||||
<div id="statsEntryPerHour" style="height: 300px"></div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo _t('stats_entry_per_day_of_week'); ?></h2>
|
||||
<div id="statsEntryPerDayOfWeek" style="height: 300px"></div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<h2><?php echo _t('stats_entry_per_month'); ?></h2>
|
||||
<div id="statsEntryPerMonth" style="height: 300px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
function initStats() {
|
||||
if (!window.Flotr) {
|
||||
if (window.console) {
|
||||
console.log('FreshRSS waiting for Flotr…');
|
||||
}
|
||||
window.setTimeout(initStats, 50);
|
||||
return;
|
||||
}
|
||||
// Entry per hour
|
||||
Flotr.draw(document.getElementById('statsEntryPerHour'),
|
||||
[<?php echo $this->repartitionHour ?>],
|
||||
{
|
||||
grid: {verticalLines: false},
|
||||
bars: {horizontal: false, show: true},
|
||||
xaxis: {noTicks: 23,
|
||||
tickFormatter: function(x) {
|
||||
var x = parseInt(x);
|
||||
return x + 1;
|
||||
},
|
||||
min: -0.9,
|
||||
max: 23.9,
|
||||
tickDecimals: 0},
|
||||
yaxis: {min: 0},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return numberFormat(obj.y);}}
|
||||
});
|
||||
// Entry per day of week
|
||||
Flotr.draw(document.getElementById('statsEntryPerDayOfWeek'),
|
||||
[<?php echo $this->repartitionDayOfWeek ?>],
|
||||
{
|
||||
grid: {verticalLines: false},
|
||||
bars: {horizontal: false, show: true},
|
||||
xaxis: {noTicks: 6,
|
||||
tickFormatter: function(x) {
|
||||
var x = parseInt(x),
|
||||
days = <?php echo $this->days?>;
|
||||
return days[x];
|
||||
},
|
||||
min: -0.9,
|
||||
max: 6.9,
|
||||
tickDecimals: 0},
|
||||
yaxis: {min: 0},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return numberFormat(obj.y);}}
|
||||
});
|
||||
// Entry per month
|
||||
Flotr.draw(document.getElementById('statsEntryPerMonth'),
|
||||
[<?php echo $this->repartitionMonth ?>],
|
||||
{
|
||||
grid: {verticalLines: false},
|
||||
bars: {horizontal: false, show: true},
|
||||
xaxis: {noTicks: 12,
|
||||
tickFormatter: function(x) {
|
||||
var x = parseInt(x),
|
||||
months = <?php echo $this->months?>;
|
||||
return months[(x - 1)];
|
||||
},
|
||||
min: 0.1,
|
||||
max: 12.9,
|
||||
tickDecimals: 0},
|
||||
yaxis: {min: 0},
|
||||
mouse: {relative: true, track: true, trackDecimals: 0, trackFormatter: function(obj) {return numberFormat(obj.y);}}
|
||||
});
|
||||
|
||||
}
|
||||
initStats();
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
define('FRESHRSS_VERSION', '0.7.3');
|
||||
define('FRESHRSS_VERSION', '0.7.4');
|
||||
define('FRESHRSS_WEBSITE', 'http://freshrss.org');
|
||||
|
||||
// PHP text output compression http://php.net/ob_gzhandler (better to do it at Web server level)
|
||||
|
|
1
sources/data/tokens/.gitignore
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
*.txt
|
13
sources/data/tokens/index.html
Executable file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="Refresh" content="0; url=/" />
|
||||
<title>Redirection</title>
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p><a href="/">Redirection</a></p>
|
||||
</body>
|
||||
</html>
|
|
@ -12,11 +12,22 @@ class Minz_Helper {
|
|||
* Annule les effets des magic_quotes pour une variable donnée
|
||||
* @param $var variable à traiter (tableau ou simple variable)
|
||||
*/
|
||||
public static function stripslashes_r ($var) {
|
||||
if (is_array ($var)){
|
||||
return array_map (array ('Helper', 'stripslashes_r'), $var);
|
||||
public static function stripslashes_r($var) {
|
||||
if (is_array($var)){
|
||||
return array_map(array('Minz_Helper', 'stripslashes_r'), $var);
|
||||
} else {
|
||||
return stripslashes($var);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for htmlspecialchars.
|
||||
* Force UTf-8 value and can be used on array too.
|
||||
*/
|
||||
public static function htmlspecialchars_utf8($var) {
|
||||
if (is_array($var)) {
|
||||
return array_map(array('Minz_Helper', 'htmlspecialchars_utf8'), $var);
|
||||
}
|
||||
return htmlspecialchars($var, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ class Minz_ModelPdo {
|
|||
* Créé la connexion à la base de données à l'aide des variables
|
||||
* HOST, BASE, USER et PASS définies dans le fichier de configuration
|
||||
*/
|
||||
public function __construct() {
|
||||
if (self::$useSharedBd && self::$sharedBd != null) {
|
||||
public function __construct($currentUser = null) {
|
||||
if (self::$useSharedBd && self::$sharedBd != null && $currentUser === null) {
|
||||
$this->bd = self::$sharedBd;
|
||||
$this->prefix = self::$sharedPrefix;
|
||||
return;
|
||||
|
@ -42,6 +42,10 @@ class Minz_ModelPdo {
|
|||
|
||||
$db = Minz_Configuration::dataBase();
|
||||
|
||||
if ($currentUser === null) {
|
||||
$currentUser = Minz_Session::param('currentUser', '_');
|
||||
}
|
||||
|
||||
try {
|
||||
$type = $db['type'];
|
||||
if ($type === 'mysql') {
|
||||
|
@ -51,9 +55,9 @@ class Minz_ModelPdo {
|
|||
$driver_options = array(
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
|
||||
);
|
||||
$this->prefix = $db['prefix'] . Minz_Session::param('currentUser', '_') . '_';
|
||||
$this->prefix = $db['prefix'] . $currentUser . '_';
|
||||
} elseif ($type === 'sqlite') {
|
||||
$string = 'sqlite:' . DATA_PATH . '/' . Minz_Session::param('currentUser', '_') . '.sqlite';
|
||||
$string = 'sqlite:' . DATA_PATH . '/' . $currentUser . '.sqlite';
|
||||
$driver_options = array(
|
||||
//PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
);
|
||||
|
@ -67,7 +71,7 @@ class Minz_ModelPdo {
|
|||
self::$sharedDbType = $type;
|
||||
self::$sharedPrefix = $this->prefix;
|
||||
|
||||
$this->bd = new FreshPDO(
|
||||
$this->bd = new MinzPDO(
|
||||
$string,
|
||||
$db['user'],
|
||||
$db['password'],
|
||||
|
@ -98,7 +102,7 @@ class Minz_ModelPdo {
|
|||
}
|
||||
}
|
||||
|
||||
class FreshPDO extends PDO {
|
||||
class MinzPDO extends PDO {
|
||||
private static function check($statement) {
|
||||
if (preg_match('/^(?:UPDATE|INSERT|DELETE)/i', $statement)) {
|
||||
invalidateHttpCache();
|
||||
|
@ -106,12 +110,12 @@ class FreshPDO extends PDO {
|
|||
}
|
||||
|
||||
public function prepare($statement, $driver_options = array()) {
|
||||
FreshPDO::check($statement);
|
||||
MinzPDO::check($statement);
|
||||
return parent::prepare($statement, $driver_options);
|
||||
}
|
||||
|
||||
public function exec($statement) {
|
||||
FreshPDO::check($statement);
|
||||
MinzPDO::check($statement);
|
||||
return parent::exec($statement);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
class Minz_Request {
|
||||
private static $controller_name = '';
|
||||
private static $action_name = '';
|
||||
private static $params = array ();
|
||||
private static $params = array();
|
||||
|
||||
private static $default_controller_name = 'index';
|
||||
private static $default_action_name = 'index';
|
||||
|
@ -18,59 +18,53 @@ class Minz_Request {
|
|||
/**
|
||||
* Getteurs
|
||||
*/
|
||||
public static function controllerName () {
|
||||
public static function controllerName() {
|
||||
return self::$controller_name;
|
||||
}
|
||||
public static function actionName () {
|
||||
public static function actionName() {
|
||||
return self::$action_name;
|
||||
}
|
||||
public static function params () {
|
||||
public static function params() {
|
||||
return self::$params;
|
||||
}
|
||||
static function htmlspecialchars_utf8 ($p) {
|
||||
if (is_array($p)) {
|
||||
return array_map('self::htmlspecialchars_utf8', $p);
|
||||
}
|
||||
return htmlspecialchars($p, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
public static function param ($key, $default = false, $specialchars = false) {
|
||||
if (isset (self::$params[$key])) {
|
||||
public static function param($key, $default = false, $specialchars = false) {
|
||||
if (isset(self::$params[$key])) {
|
||||
$p = self::$params[$key];
|
||||
if(is_object($p) || $specialchars) {
|
||||
if (is_object($p) || $specialchars) {
|
||||
return $p;
|
||||
} else {
|
||||
return self::htmlspecialchars_utf8($p);
|
||||
return Minz_Helper::htmlspecialchars_utf8($p);
|
||||
}
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
public static function defaultControllerName () {
|
||||
public static function defaultControllerName() {
|
||||
return self::$default_controller_name;
|
||||
}
|
||||
public static function defaultActionName () {
|
||||
public static function defaultActionName() {
|
||||
return self::$default_action_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setteurs
|
||||
*/
|
||||
public static function _controllerName ($controller_name) {
|
||||
public static function _controllerName($controller_name) {
|
||||
self::$controller_name = $controller_name;
|
||||
}
|
||||
public static function _actionName ($action_name) {
|
||||
public static function _actionName($action_name) {
|
||||
self::$action_name = $action_name;
|
||||
}
|
||||
public static function _params ($params) {
|
||||
public static function _params($params) {
|
||||
if (!is_array($params)) {
|
||||
$params = array ($params);
|
||||
$params = array($params);
|
||||
}
|
||||
|
||||
self::$params = $params;
|
||||
}
|
||||
public static function _param ($key, $value = false) {
|
||||
public static function _param($key, $value = false) {
|
||||
if ($value === false) {
|
||||
unset (self::$params[$key]);
|
||||
unset(self::$params[$key]);
|
||||
} else {
|
||||
self::$params[$key] = $value;
|
||||
}
|
||||
|
@ -79,14 +73,14 @@ class Minz_Request {
|
|||
/**
|
||||
* Initialise la Request
|
||||
*/
|
||||
public static function init () {
|
||||
self::magicQuotesOff ();
|
||||
public static function init() {
|
||||
self::magicQuotesOff();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourn le nom de domaine du site
|
||||
*/
|
||||
public static function getDomainName () {
|
||||
public static function getDomainName() {
|
||||
return $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
|
||||
|
@ -94,7 +88,7 @@ class Minz_Request {
|
|||
* Détermine la base de l'url
|
||||
* @return la base de l'url
|
||||
*/
|
||||
public static function getBaseUrl () {
|
||||
public static function getBaseUrl() {
|
||||
$defaultBaseUrl = Minz_Configuration::baseUrl();
|
||||
if (!empty($defaultBaseUrl)) {
|
||||
return $defaultBaseUrl;
|
||||
|
@ -109,13 +103,13 @@ class Minz_Request {
|
|||
* Récupère l'URI de la requête
|
||||
* @return l'URI
|
||||
*/
|
||||
public static function getURI () {
|
||||
if (isset ($_SERVER['REQUEST_URI'])) {
|
||||
$base_url = self::getBaseUrl ();
|
||||
public static function getURI() {
|
||||
if (isset($_SERVER['REQUEST_URI'])) {
|
||||
$base_url = self::getBaseUrl();
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
|
||||
$len_base_url = strlen ($base_url);
|
||||
$real_uri = substr ($uri, $len_base_url);
|
||||
$len_base_url = strlen($base_url);
|
||||
$real_uri = substr($uri, $len_base_url);
|
||||
} else {
|
||||
$real_uri = '';
|
||||
}
|
||||
|
@ -129,16 +123,16 @@ class Minz_Request {
|
|||
* @param $redirect si vrai, force la redirection http
|
||||
* > sinon, le dispatcher recharge en interne
|
||||
*/
|
||||
public static function forward ($url = array (), $redirect = false) {
|
||||
$url = Minz_Url::checkUrl ($url);
|
||||
public static function forward($url = array(), $redirect = false) {
|
||||
$url = Minz_Url::checkUrl($url);
|
||||
|
||||
if ($redirect) {
|
||||
header ('Location: ' . Minz_Url::display ($url, 'php'));
|
||||
exit ();
|
||||
header('Location: ' . Minz_Url::display($url, 'php'));
|
||||
exit();
|
||||
} else {
|
||||
self::_controllerName ($url['c']);
|
||||
self::_actionName ($url['a']);
|
||||
self::_params (array_merge (
|
||||
self::_controllerName($url['c']);
|
||||
self::_actionName($url['a']);
|
||||
self::_params(array_merge(
|
||||
self::$params,
|
||||
$url['params']
|
||||
));
|
||||
|
@ -146,6 +140,31 @@ class Minz_Request {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrappers good notifications + redirection
|
||||
* @param $msg notification content
|
||||
* @param $url url array to where we should be forwarded
|
||||
*/
|
||||
public static function good($msg, $url = array()) {
|
||||
Minz_Session::_param('notification', array(
|
||||
'type' => 'good',
|
||||
'content' => $msg
|
||||
));
|
||||
|
||||
Minz_Request::forward($url, true);
|
||||
}
|
||||
|
||||
public static function bad($msg, $url = array()) {
|
||||
Minz_Session::_param('notification', array(
|
||||
'type' => 'bad',
|
||||
'content' => $msg
|
||||
));
|
||||
|
||||
Minz_Request::forward($url, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Permet de récupérer une variable de type $_GET
|
||||
* @param $param nom de la variable
|
||||
|
@ -154,10 +173,10 @@ class Minz_Request {
|
|||
* $_GET si $param = false
|
||||
* $default si $_GET[$param] n'existe pas
|
||||
*/
|
||||
public static function fetchGET ($param = false, $default = false) {
|
||||
public static function fetchGET($param = false, $default = false) {
|
||||
if ($param === false) {
|
||||
return $_GET;
|
||||
} elseif (isset ($_GET[$param])) {
|
||||
} elseif (isset($_GET[$param])) {
|
||||
return $_GET[$param];
|
||||
} else {
|
||||
return $default;
|
||||
|
@ -172,10 +191,10 @@ class Minz_Request {
|
|||
* $_POST si $param = false
|
||||
* $default si $_POST[$param] n'existe pas
|
||||
*/
|
||||
public static function fetchPOST ($param = false, $default = false) {
|
||||
public static function fetchPOST($param = false, $default = false) {
|
||||
if ($param === false) {
|
||||
return $_POST;
|
||||
} elseif (isset ($_POST[$param])) {
|
||||
} elseif (isset($_POST[$param])) {
|
||||
return $_POST[$param];
|
||||
} else {
|
||||
return $default;
|
||||
|
@ -188,15 +207,16 @@ class Minz_Request {
|
|||
* $_POST
|
||||
* $_COOKIE
|
||||
*/
|
||||
private static function magicQuotesOff () {
|
||||
if (get_magic_quotes_gpc ()) {
|
||||
$_GET = Minz_Helper::stripslashes_r ($_GET);
|
||||
$_POST = Minz_Helper::stripslashes_r ($_POST);
|
||||
$_COOKIE = Minz_Helper::stripslashes_r ($_COOKIE);
|
||||
private static function magicQuotesOff() {
|
||||
if (get_magic_quotes_gpc()) {
|
||||
$_GET = Minz_Helper::stripslashes_r($_GET);
|
||||
$_POST = Minz_Helper::stripslashes_r($_POST);
|
||||
$_COOKIE = Minz_Helper::stripslashes_r($_COOKIE);
|
||||
}
|
||||
}
|
||||
|
||||
public static function isPost () {
|
||||
return $_SERVER['REQUEST_METHOD'] === 'POST';
|
||||
public static function isPost() {
|
||||
return isset($_SERVER['REQUEST_METHOD']) &&
|
||||
$_SERVER['REQUEST_METHOD'] === 'POST';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,28 +2,20 @@
|
|||
|
||||
/**
|
||||
* La classe Session gère la session utilisateur
|
||||
* C'est un singleton
|
||||
*/
|
||||
class Minz_Session {
|
||||
/**
|
||||
* $session stocke les variables de session
|
||||
*/
|
||||
private static $session = array (); //TODO: Try to avoid having another local copy
|
||||
|
||||
/**
|
||||
* Initialise la session, avec un nom
|
||||
* Le nom de session est utilisé comme nom pour les cookies et les URLs (i.e. PHPSESSID).
|
||||
* Le nom de session est utilisé comme nom pour les cookies et les URLs(i.e. PHPSESSID).
|
||||
* Il ne doit contenir que des caractères alphanumériques ; il doit être court et descriptif
|
||||
*/
|
||||
public static function init ($name) {
|
||||
// démarre la session
|
||||
session_name ($name);
|
||||
session_set_cookie_params (0, dirname(empty($_SERVER['REQUEST_URI']) ? '/' : dirname($_SERVER['REQUEST_URI'])), null, false, true);
|
||||
session_start ();
|
||||
public static function init($name) {
|
||||
$cookie = session_get_cookie_params();
|
||||
self::keepCookie($cookie['lifetime']);
|
||||
|
||||
if (isset ($_SESSION)) {
|
||||
self::$session = $_SESSION;
|
||||
}
|
||||
// démarre la session
|
||||
session_name($name);
|
||||
session_start();
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,8 +24,8 @@ class Minz_Session {
|
|||
* @param $p le paramètre à récupérer
|
||||
* @return la valeur de la variable de session, false si n'existe pas
|
||||
*/
|
||||
public static function param ($p, $default = false) {
|
||||
return isset(self::$session[$p]) ? self::$session[$p] : $default;
|
||||
public static function param($p, $default = false) {
|
||||
return isset($_SESSION[$p]) ? $_SESSION[$p] : $default;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,13 +34,11 @@ class Minz_Session {
|
|||
* @param $p le paramètre à créer ou modifier
|
||||
* @param $v la valeur à attribuer, false pour supprimer
|
||||
*/
|
||||
public static function _param ($p, $v = false) {
|
||||
public static function _param($p, $v = false) {
|
||||
if ($v === false) {
|
||||
unset ($_SESSION[$p]);
|
||||
unset (self::$session[$p]);
|
||||
unset($_SESSION[$p]);
|
||||
} else {
|
||||
$_SESSION[$p] = $v;
|
||||
self::$session[$p] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,15 +47,47 @@ class Minz_Session {
|
|||
* Permet d'effacer une session
|
||||
* @param $force si à false, n'efface pas le paramètre de langue
|
||||
*/
|
||||
public static function unset_session ($force = false) {
|
||||
$language = self::param ('language');
|
||||
public static function unset_session($force = false) {
|
||||
$language = self::param('language');
|
||||
|
||||
session_destroy();
|
||||
self::$session = array ();
|
||||
$_SESSION = array();
|
||||
|
||||
if (!$force) {
|
||||
self::_param ('language', $language);
|
||||
Minz_Translate::reset ();
|
||||
self::_param('language', $language);
|
||||
Minz_Translate::reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Spécifie la durée de vie des cookies
|
||||
* @param $l la durée de vie
|
||||
*/
|
||||
public static function keepCookie($l) {
|
||||
$cookie_dir = empty($_SERVER['REQUEST_URI']) ? '' : $_SERVER['REQUEST_URI'];
|
||||
session_set_cookie_params($l, $cookie_dir, '', false, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Régénère un id de session.
|
||||
* Utile pour appeler session_set_cookie_params après session_start()
|
||||
*/
|
||||
public static function regenerateID() {
|
||||
session_regenerate_id(true);
|
||||
}
|
||||
|
||||
public static function deleteLongTermCookie($name) {
|
||||
setcookie($name, '', 1, '', '', false, true);
|
||||
}
|
||||
|
||||
public static function setLongTermCookie($name, $value, $expire) {
|
||||
setcookie($name, $value, $expire, '', '', false, true);
|
||||
}
|
||||
|
||||
public static function getLongTermCookie($name) {
|
||||
return isset($_COOKIE[$name]) ? $_COOKIE[$name] : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -75,5 +75,5 @@ function _t($key) {
|
|||
unset($args[0]);
|
||||
array_unshift($args, $key);
|
||||
|
||||
return call_user_func_array("Minz_Translate::t", $args);
|
||||
return call_user_func_array('Minz_Translate::t', $args);
|
||||
}
|
||||
|
|
|
@ -121,10 +121,10 @@ function customSimplePie() {
|
|||
'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur',
|
||||
'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless')));
|
||||
$simplePie->add_attributes(array(
|
||||
'img' => array('lazyload' => ''), //http://www.w3.org/TR/resource-priorities/
|
||||
'audio' => array('preload' => 'none'),
|
||||
'iframe' => array('postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'),
|
||||
'video' => array('postpone' => '', 'preload' => 'none'),
|
||||
'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/
|
||||
'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'),
|
||||
'iframe' => array('lazyload' => '', 'postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'),
|
||||
'video' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'),
|
||||
));
|
||||
$simplePie->set_url_replacements(array(
|
||||
'a' => 'href',
|
||||
|
@ -183,16 +183,8 @@ function get_content_by_parsing ($url, $path) {
|
|||
*/
|
||||
function lazyimg($content) {
|
||||
return preg_replace(
|
||||
'/<img([^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
|
||||
'<img$1src="' . Minz_Url::display('/themes/icons/grey.gif') . '" data-original="$2"$3>',
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
function lazyIframe($content) {
|
||||
return preg_replace(
|
||||
'/<iframe([^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
|
||||
'<iframe$1src="about:blank" data-original="$2"$3>',
|
||||
'/<((?:img|iframe)[^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i',
|
||||
'<$1src="' . Minz_Url::display('/themes/icons/grey.gif') . '" data-original="$2"$3>',
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
@ -238,7 +230,3 @@ function cryptAvailable() {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function html_chars_utf8($str) {
|
||||
return htmlspecialchars($str, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ function checkCompatibility() {
|
|||
}
|
||||
if ((!array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) && //Apache mod_rewrite trick should be fine
|
||||
(empty($_SERVER['SERVER_SOFTWARE']) || (stripos($_SERVER['SERVER_SOFTWARE'], 'nginx') === false)) && //nginx should be fine
|
||||
(empty($_SERVER['SERVER_SOFTWARE']) || (stripos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') === false)) && //lighttpd should be fine
|
||||
((!function_exists('getallheaders')) || (stripos(php_sapi_name(), 'cgi') !== false))) { //Main problem is Apache/CGI mode
|
||||
die('FAIL getallheaders! (probably)');
|
||||
}
|
||||
|
|
1
sources/p/i/.gitignore
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
.htaccess
|
15
sources/p/scripts/jquery.lazyload.min.js
vendored
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Lazy Load - jQuery plugin for lazy loading images
|
||||
*
|
||||
* Copyright (c) 2007-2013 Mika Tuupola
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/lazyload
|
||||
*
|
||||
* Version: 1.9.0
|
||||
*
|
||||
*/
|
||||
!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.data(j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.data(j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/iphone|ipod|ipad.*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document);
|
|
@ -69,6 +69,10 @@ function incUnreadsFeed(article, feed_id, nb) {
|
|||
feed_priority = elem ? str2int(elem.getAttribute('data-priority')) : 0;
|
||||
if (elem) {
|
||||
elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
|
||||
elem = $(elem).closest('li').get(0);
|
||||
if (elem) {
|
||||
elem.setAttribute('data-unread', feed_unreads + nb);
|
||||
}
|
||||
}
|
||||
|
||||
//Update unread: category
|
||||
|
@ -76,6 +80,10 @@ function incUnreadsFeed(article, feed_id, nb) {
|
|||
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
|
||||
if (elem) {
|
||||
elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
|
||||
elem = $(elem).closest('li').get(0);
|
||||
if (elem) {
|
||||
elem.setAttribute('data-unread', feed_unreads + nb);
|
||||
}
|
||||
}
|
||||
|
||||
//Update unread: all
|
||||
|
@ -98,16 +106,16 @@ function incUnreadsFeed(article, feed_id, nb) {
|
|||
|
||||
var isCurrentView = false;
|
||||
//Update unread: title
|
||||
document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)(.*? · )((?:\([ 0-9]+\) )?)/, function (m, p1, p2, p3) {
|
||||
document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)/, function (m, p1) {
|
||||
var $feed = $('#' + feed_id);
|
||||
if (article || ($feed.closest('.active').length > 0 && $feed.siblings('.active').length === 0)) {
|
||||
isCurrentView = true;
|
||||
return incLabel(p1, nb, true) + p2 + incLabel(p3, feed_priority > 0 ? nb : 0, true);
|
||||
return incLabel(p1, nb, true);
|
||||
} else if ($('.all.active').length > 0) {
|
||||
isCurrentView = feed_priority > 0;
|
||||
return incLabel(p1, feed_priority > 0 ? nb : 0, true) + p2 + incLabel(p3, feed_priority > 0 ? nb : 0, true);
|
||||
return incLabel(p1, feed_priority > 0 ? nb : 0, true);
|
||||
} else {
|
||||
return p1 + p2 + incLabel(p3, feed_priority > 0 ? nb : 0, true);
|
||||
return p1;
|
||||
}
|
||||
});
|
||||
return isCurrentView;
|
||||
|
@ -152,6 +160,7 @@ function mark_read(active, only_not_read) {
|
|||
$r.find('.icon').replaceWith(data.icon);
|
||||
|
||||
incUnreadsFeed(active, feed_id, inc);
|
||||
faviconNbUnread();
|
||||
|
||||
pending_feeds.splice(index_pending, 1);
|
||||
});
|
||||
|
@ -361,7 +370,12 @@ function last_category() {
|
|||
|
||||
function collapse_entry() {
|
||||
isCollapsed = !isCollapsed;
|
||||
$(".flux.current").toggleClass("active");
|
||||
|
||||
var flux_current = $(".flux.current");
|
||||
flux_current.toggleClass("active");
|
||||
if (isCollapsed) {
|
||||
mark_read(flux_current, true);
|
||||
}
|
||||
}
|
||||
|
||||
function auto_share(key) {
|
||||
|
@ -407,21 +421,7 @@ function inMarkViewport(flux, box_to_follow, relative_follow) {
|
|||
return (windowBot >= begin && bot >= windowBot);
|
||||
}
|
||||
|
||||
function init_lazyload() {
|
||||
if ($.fn.lazyload) {
|
||||
if (is_global_mode()) {
|
||||
$(".flux_content img").lazyload({
|
||||
container: $("#panel")
|
||||
});
|
||||
} else {
|
||||
$(".flux_content img").lazyload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init_posts() {
|
||||
init_lazyload();
|
||||
|
||||
var box_to_follow = $(window),
|
||||
relative_follow = false;
|
||||
if (is_global_mode()) {
|
||||
|
@ -663,7 +663,7 @@ function init_stream(divStream) {
|
|||
|
||||
if (auto_mark_site) {
|
||||
divStream.on('click', '.flux .link > a', function () {
|
||||
mark_read($(this).parent().parent().parent(), true);
|
||||
mark_read($(this).parents(".flux"), true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -768,18 +768,66 @@ function init_notifications() {
|
|||
}
|
||||
// </notification>
|
||||
|
||||
// <notifs html5>
|
||||
var notifs_html5_permission = 'denied';
|
||||
|
||||
function notifs_html5_is_supported() {
|
||||
return window.Notification !== undefined;
|
||||
}
|
||||
|
||||
function notifs_html5_ask_permission() {
|
||||
window.Notification.requestPermission(function () {
|
||||
notifs_html5_permission = window.Notification.permission;
|
||||
});
|
||||
}
|
||||
|
||||
function notifs_html5_show(nb) {
|
||||
if (notifs_html5_permission !== "granted") {
|
||||
return
|
||||
}
|
||||
|
||||
var notification = new window.Notification(str_notif_title_articles, {
|
||||
icon: "../themes/icons/favicon-256.png",
|
||||
body: str_notif_body_articles.replace("\d", nb)
|
||||
});
|
||||
|
||||
notification.onclick = function() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
function init_notifs_html5() {
|
||||
if (!notifs_html5_is_supported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifs_html5_permission = notifs_html5_ask_permission();
|
||||
}
|
||||
// </notifs html5>
|
||||
|
||||
function refreshUnreads() {
|
||||
$.getJSON('./?c=javascript&a=nbUnreadsPerFeed').done(function (data) {
|
||||
var isAll = $('.category.all > .active').length > 0;
|
||||
var isAll = $('.category.all > .active').length > 0,
|
||||
new_articles = false;
|
||||
|
||||
$.each(data, function(feed_id, nbUnreads) {
|
||||
feed_id = 'f_' + feed_id;
|
||||
var elem = $('#' + feed_id + '>.feed').get(0),
|
||||
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
|
||||
|
||||
if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && //Update of current view?
|
||||
(nbUnreads - feed_unreads > 0)) {
|
||||
$('#new-article').show();
|
||||
new_articles = true;
|
||||
};
|
||||
});
|
||||
|
||||
var nb_unreads = str2int($('.category.all>a').attr('data-unread'));
|
||||
|
||||
if (nb_unreads > 0 && new_articles) {
|
||||
faviconNbUnread(nb_unreads);
|
||||
notifs_html5_show(nb_unreads);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -812,7 +860,6 @@ function load_more_posts() {
|
|||
});
|
||||
|
||||
init_load_more(box_load_more);
|
||||
init_lazyload();
|
||||
|
||||
$('#load_more').removeClass('loading');
|
||||
load_more = false;
|
||||
|
@ -826,6 +873,12 @@ function focus_search() {
|
|||
function init_load_more(box) {
|
||||
box_load_more = box;
|
||||
|
||||
if (!does_lazyload) {
|
||||
$('img[postpone], audio[postpone], iframe[postpone], video[postpone]').each(function () {
|
||||
this.removeAttribute('postpone');
|
||||
});
|
||||
}
|
||||
|
||||
var $next_link = $("#load_more");
|
||||
if (!$next_link.length) {
|
||||
// no more article to load
|
||||
|
@ -967,7 +1020,7 @@ function init_persona() {
|
|||
//</persona>
|
||||
|
||||
function init_confirm_action() {
|
||||
$('.confirm').click(function () {
|
||||
$('body').on('click', '.confirm', function () {
|
||||
return confirm(str_confirmation);
|
||||
});
|
||||
}
|
||||
|
@ -1010,6 +1063,12 @@ function init_share_observers() {
|
|||
});
|
||||
}
|
||||
|
||||
function init_stats_observers() {
|
||||
$('#feed_select').on('change', function(e) {
|
||||
redirect($(this).find(':selected').data('url'));
|
||||
});
|
||||
}
|
||||
|
||||
function init_remove_observers() {
|
||||
$('.post').on('click', 'a.remove', function(e) {
|
||||
var remove_what = $(this).attr('data-remove');
|
||||
|
@ -1052,8 +1111,44 @@ function init_password_observers() {
|
|||
});
|
||||
}
|
||||
|
||||
function faviconNbUnread(n) {
|
||||
if (typeof n === 'undefined') {
|
||||
n = str2int($('.category.all>a').attr('data-unread'));
|
||||
}
|
||||
//http://remysharp.com/2010/08/24/dynamic-favicons/
|
||||
var canvas = document.createElement('canvas'),
|
||||
link = document.getElementById('favicon').cloneNode(true);
|
||||
if (canvas.getContext && link) {
|
||||
canvas.height = canvas.width = 16;
|
||||
var img = document.createElement('img');
|
||||
img.onload = function () {
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
|
||||
if (n > 0) {
|
||||
var text = '';
|
||||
if (n < 1000) {
|
||||
text = n;
|
||||
} else if (n < 100000) {
|
||||
text = Math.floor(n / 1000) + 'k';
|
||||
} else {
|
||||
text = 'E' + Math.floor(Math.log10(n));
|
||||
}
|
||||
ctx.font = 'bold 9px "Arial", sans-serif';
|
||||
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
|
||||
ctx.fillRect(0, 7, ctx.measureText(text).width, 9);
|
||||
ctx.fillStyle = '#F00';
|
||||
ctx.fillText(text, 0, canvas.height - 1);
|
||||
}
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
$('link[rel~=icon]').remove();
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
img.src = '../favicon.ico';
|
||||
}
|
||||
}
|
||||
|
||||
function init_all() {
|
||||
if (!(window.$ && window.url_freshrss && ((!full_lazyload) || $.fn.lazyload))) {
|
||||
if (!(window.$ && window.url_freshrss)) {
|
||||
if (window.console) {
|
||||
console.log('FreshRSS waiting for JS…');
|
||||
}
|
||||
|
@ -1079,13 +1174,16 @@ function init_all() {
|
|||
init_stream($stream);
|
||||
init_nav_entries();
|
||||
init_shortcuts();
|
||||
faviconNbUnread();
|
||||
init_print_action();
|
||||
init_notifs_html5();
|
||||
window.setInterval(refreshUnreads, 120000);
|
||||
} else {
|
||||
init_share_observers();
|
||||
init_remove_observers();
|
||||
init_feed_observers();
|
||||
init_password_observers();
|
||||
init_stats_observers();
|
||||
}
|
||||
|
||||
if (window.console) {
|
||||
|
|
|
@ -515,15 +515,13 @@ a.btn {
|
|||
.categories .feeds .item.empty.active {
|
||||
background: #c95;
|
||||
}
|
||||
.categories .feeds .item.empty.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
.categories .feeds .item.error .feed {
|
||||
color: #a44;
|
||||
}
|
||||
.categories .feeds .item.error.active {
|
||||
background: #a44;
|
||||
}
|
||||
.categories .feeds .item.empty.active .feed,
|
||||
.categories .feeds .item.error.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -570,7 +568,7 @@ a.btn {
|
|||
}
|
||||
.prompt form {
|
||||
margin: 10px auto 20px auto;
|
||||
width: 180px;
|
||||
width: 200px;
|
||||
}
|
||||
.prompt input {
|
||||
margin: 5px auto;
|
||||
|
|
|
@ -309,6 +309,9 @@ a.btn {
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
.state_unread li:not(.active)[data-unread="0"] {
|
||||
display: none;
|
||||
}
|
||||
.category {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -492,10 +492,6 @@ a.btn {
|
|||
.categories .feeds .item.active {
|
||||
background: #2980b9;
|
||||
}
|
||||
.categories .feeds .item.active .feed,
|
||||
.categories .feeds .item.empty.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
.categories .feeds .item.empty.active {
|
||||
background: #f39c12;
|
||||
}
|
||||
|
@ -508,6 +504,11 @@ a.btn {
|
|||
.categories .feeds .item.error .feed {
|
||||
color: #bd362f;
|
||||
}
|
||||
.categories .feeds .item.active .feed,
|
||||
.categories .feeds .item.empty.active .feed,
|
||||
.categories .feeds .item.error.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
.categories .feeds .item .feed {
|
||||
margin: 0;
|
||||
width: 165px;
|
||||
|
@ -551,7 +552,7 @@ a.btn {
|
|||
}
|
||||
.prompt form {
|
||||
margin: 10px auto 20px auto;
|
||||
width: 180px;
|
||||
width: 200px;
|
||||
}
|
||||
.prompt input {
|
||||
margin: 5px auto;
|
||||
|
|
|
@ -309,6 +309,9 @@ a.btn {
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
.state_unread li:not(.active)[data-unread="0"] {
|
||||
display: none;
|
||||
}
|
||||
.category {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -540,21 +540,23 @@ a.btn {
|
|||
.categories .feeds .item.active {
|
||||
background: #0062BE;
|
||||
}
|
||||
.categories .feeds .item.active .feed {
|
||||
color: #fff;
|
||||
.categories .feeds .item.empty.active {
|
||||
background: #e67e22;
|
||||
}
|
||||
.categories .feeds .item.error.active {
|
||||
background: #BD362F;
|
||||
}
|
||||
.categories .feeds .item.empty .feed {
|
||||
color: #e67e22;
|
||||
}
|
||||
.categories .feeds .item.empty.active {
|
||||
background: #e67e22;
|
||||
}
|
||||
.categories .feeds .item.empty.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
.categories .feeds .item.error .feed {
|
||||
color: #BD362F;
|
||||
}
|
||||
.categories .feeds .item.active .feed,
|
||||
.categories .feeds .item.empty.active .feed,
|
||||
.categories .feeds .item.error.active .feed {
|
||||
color: #fff;
|
||||
}
|
||||
.categories .feeds .item .feed {
|
||||
margin: 0;
|
||||
width: 165px;
|
||||
|
@ -598,7 +600,7 @@ a.btn {
|
|||
}
|
||||
.prompt form {
|
||||
margin: 10px auto 20px auto;
|
||||
width: 180px;
|
||||
width: 200px;
|
||||
}
|
||||
.prompt input {
|
||||
margin: 5px auto;
|
||||
|
|
|
@ -309,6 +309,9 @@ a.btn {
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
.state_unread li:not(.active)[data-unread="0"] {
|
||||
display: none;
|
||||
}
|
||||
.category {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
|
36
sources/p/themes/Screwdriver/README.md
Executable file
|
@ -0,0 +1,36 @@
|
|||
Screwdriver
|
||||
=======
|
||||
|
||||
**C'est un cocktail! C'est chaud mais "fresh" à la fois. C'est... c'est... un thème pour l'agrégateur de flux RSS<a href="https://github.com/marienfressinaud/FreshRSS/" target="blank">FreshRSS</a>!!**
|
||||
En toute modestie, ce thème tue du chaton.
|
||||
|
||||
![screenshot](https://github.com/misterair/Screwdriver/blob/master/screenshot.png)
|
||||
|
||||
|
||||
Installation
|
||||
-----------------
|
||||
1. Placez le dossier du thème dans ledossier /FreshRSS/p/themes/Screwdriver de votre FreshRSS;
|
||||
2. Allez dans les paramètres d'Affichage et changez de thème;
|
||||
3. Profitez de votre Screwdriver!
|
||||
4. Remontez les problèmes sur Github (facultatif mais fortement apprécié)
|
||||
|
||||
|
||||
|
||||
Screwdriver est distribué sous license BeerWare:
|
||||
-----------------
|
||||
|
||||
« LICENCE BEERWARE » (Révision 42):
|
||||
|
||||
mister.air@gmail.com a créé ce fichier. Tant que vous conservez cet avertissement,
|
||||
|
||||
vous pouvez faire ce que vous voulez de ce truc. Si on se rencontre un jour et
|
||||
|
||||
que vous pensez que ce truc vaut le coup, vous pouvez me payer une bière en retour.
|
||||
|
||||
*Mister aiR*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
5
sources/p/themes/Screwdriver/icons/add.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-60.0002,-726)">
|
||||
<path style="color:#666666;" fill="#666" d="m67,729,0,4-4,0,0,2,4,0,0,4,2,0,0-4,4,0,0-2-4,0,0-4-2,0z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 220 B |
7
sources/p/themes/Screwdriver/icons/all.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-40.0002,-746)" fill="#bebebe">
|
||||
<rect style="color:#bebebe;" height="2.0002" width="9.9996" y="749" x="43"/>
|
||||
<rect style="color:#bebebe;" height="2.0002" width="9.9996" y="753" x="43"/>
|
||||
<rect style="color:#bebebe;" height="2.0002" width="9.9996" y="757" x="43"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 362 B |
BIN
sources/p/themes/Screwdriver/icons/apple-touch-icon.png
Executable file
After Width: | Height: | Size: 5.5 KiB |
6
sources/p/themes/Screwdriver/icons/bookmark-add.svg
Executable file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-141.0002,-807)" fill="#bebebe">
|
||||
<path d="m143,807,0,13,4-4,4,4,0-4,0-1-2,0,0-4,2,0,0-4z"/>
|
||||
<path d="m152,810,0,2-2,0,0,2,2,0,0,2,2,0,0-2,2,0,0-2-2,0,0-2-2,0z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 261 B |
60
sources/p/themes/Screwdriver/icons/bookmark.svg
Executable file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="16"
|
||||
width="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="bookmark.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="745"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-2.2033898"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
transform="translate(-41.000202,-397)"
|
||||
id="g4">
|
||||
<path
|
||||
style="enable-background:accumulate;color:#000000;fill:#d18104;fill-opacity:1"
|
||||
d="m530.95,186.71c-0.77941,0.55189-3.1576-1.906-4.1125-1.9179-0.95532-0.0119-3.3949,2.3858-4.161,1.8149-0.76573-0.57072,0.83698-3.592,0.55319-4.5039-0.2839-0.91223-3.3182-2.4915-3.0119-3.3965,0.30617-0.90461,3.6749-0.31399,4.4544-0.86567,0.77986-0.5519,1.3442-3.9257,2.2995-3.914,0.95494,0.0116,1.4342,3.398,2.1998,3.9689,0.76588,0.57114,4.1489,0.0653,4.4331,0.97746,0.28402,0.9118-2.7885,2.414-3.0949,3.3186-0.30652,0.90489,1.22,3.966,0.44027,4.5182z"
|
||||
fill-rule="nonzero"
|
||||
transform="matrix(1.0472113,-0.00871584,0.00871584,1.0472113,-504.35434,220.15425)"
|
||||
fill="#f1c40f"
|
||||
id="path6" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
7
sources/p/themes/Screwdriver/icons/category-white.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-442,-176)">
|
||||
<g transform="translate(234.0002,-820)">
|
||||
<path d="m208.53,997c-0.28913,0-0.53125,0.24212-0.53125,0.53125v13.938c0,0.2985,0.23264,0.5312,0.53125,0.5312h14.938c0.2986,0,0.53125-0.2326,0.53125-0.5312v-8.9376c0-0.2891-0.24212-0.5312-0.53125-0.5312h-12.469v7.5c0,0.277-0.223,0.5-0.5,0.5s-0.5-0.223-0.5-0.5v-8c0-0.277,0.223-0.5,0.5-0.5h2.9688,8.5312v-1.4062c0-0.3272-0.26666-0.5938-0.59375-0.5938h-7.4062v-1.4688c0-0.39-0.24-0.63-0.53-0.63z" fill="#FFF"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 567 B |
7
sources/p/themes/Screwdriver/icons/category.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-442,-176)">
|
||||
<g transform="translate(234.0002,-820)">
|
||||
<path d="m208.53,997c-0.28913,0-0.53125,0.24212-0.53125,0.53125v13.938c0,0.2985,0.23264,0.5312,0.53125,0.5312h14.938c0.2986,0,0.53125-0.2326,0.53125-0.5312v-8.9376c0-0.2891-0.24212-0.5312-0.53125-0.5312h-12.469v7.5c0,0.277-0.223,0.5-0.5,0.5s-0.5-0.223-0.5-0.5v-8c0-0.277,0.223-0.5,0.5-0.5h2.9688,8.5312v-1.4062c0-0.3272-0.26666-0.5938-0.59375-0.5938h-7.4062v-1.4688c0-0.39-0.24-0.63-0.53-0.63z" fill="#666"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 567 B |
7
sources/p/themes/Screwdriver/icons/close.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-60,-518)">
|
||||
<g transform="translate(19,-242)">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m45,764,1,0c0.01037-0.00012,0.02079-0.00046,0.03125,0,0.25495,0.0112,0.50987,0.12858,0.6875,0.3125l2.282,2.28,2.312-2.28c0.266-0.23,0.447-0.3,0.688-0.31h1v1c0,0.28647-0.03434,0.55065-0.25,0.75l-2.2812,2.2812,2.25,2.25c0.188,0.19,0.281,0.45,0.281,0.72v1h-1c-0.2653-0.00001-0.53059-0.0931-0.71875-0.28125l-2.281-2.28-2.281,2.28c-0.188,0.19-0.454,0.28-0.719,0.28h-1v-1c-0.000003-0.26529,0.09306-0.53058,0.28125-0.71875l2.2812-2.25-2.281-2.28c-0.21-0.19-0.303-0.47-0.281-0.75v-1z" fill-rule="nonzero" fill="#bebebe"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 805 B |
5
sources/p/themes/Screwdriver/icons/configure.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-441.0002,-400.99999)">
|
||||
<path style="color:#666666;enable-background:accumulate;" d="m449,402c-0.22065,0-0.44081,0.0113-0.65625,0.0312l-0.40625,2.0938c-0.33446,0.0733-0.66305,0.17589-0.96875,0.3125l-1.5312-1.4688c-0.38863,0.23011-0.72695,0.51408-1.0625,0.8125l0.90625,1.9062c-0.22242,0.24899-0.42425,0.5225-0.59375,0.8125l-2.0938-0.28125c-0.17772,0.40877-0.30872,0.83637-0.40625,1.2812l1.8438,1c-0.0171,0.16809-0.0312,0.3274-0.0312,0.5s0.0142,0.33191,0.0312,0.5l-1.8438,1c0.0975,0.44488,0.22853,0.87248,0.40625,1.2812l2.0938-0.28125c0.1695,0.29,0.37133,0.56351,0.59375,0.8125l-0.90625,1.9062c0.33555,0.29842,0.67387,0.58239,1.0625,0.8125l1.5312-1.4688c0.3057,0.13661,0.63429,0.23916,0.96875,0.3125l0.40625,2.0938c0.21544,0.02,0.4356,0.0312,0.65625,0.0312s0.44081-0.0113,0.65625-0.0312l0.40625-2.0938c0.33446-0.0733,0.66305-0.17589,0.96875-0.3125l1.5312,1.4688c0.38863-0.23011,0.72695-0.51408,1.0625-0.8125l-0.90625-1.9062c0.22242-0.24899,0.42425-0.5225,0.59375-0.8125l2.0938,0.28125c0.17772-0.40877,0.30872-0.83637,0.40625-1.2812l-1.8438-1c0.0171-0.16809,0.0312-0.3274,0.0312-0.5s-0.0142-0.33191-0.0312-0.5l1.8438-1c-0.0975-0.44488-0.22853-0.87248-0.40625-1.2812l-2.0938,0.28125c-0.1695-0.29-0.37133-0.56351-0.59375-0.8125l0.90625-1.9062c-0.33555-0.29842-0.67387-0.58239-1.0625-0.8125l-1.5312,1.4688c-0.3057-0.13661-0.63429-0.23916-0.96875-0.3125l-0.40625-2.0938c-0.21544-0.02-0.4356-0.0312-0.65625-0.0312zm0,4c1.6568,0,3,1.3432,3,3s-1.3432,3-3,3-3-1.3432-3-3,1.3432-3,3-3z" fill-rule="nonzero" fill="#666"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
5
sources/p/themes/Screwdriver/icons/down.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-181.0002,-747)">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m195.03,751,0,1c-0.00091,0.0111,0.00059,0.021-0.00009,0.0312-0.0112,0.25496-0.12835,0.50994-0.31251,0.6875l-5.7188,6.2977-5.7188-6.2977c-0.18821-0.1881-0.28121-0.45346-0.28122-0.71875v-1h1c0.26531,0.00007,0.53059,0.0931,0.71873,0.28131l4.2812,4.829,4.2813-4.829c0.19464-0.21073,0.46925-0.30315,0.74998-0.2813z" fill-rule="nonzero" fill="#bebebe"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 605 B |
BIN
sources/p/themes/Screwdriver/icons/favicon-16-32-48-64.ico
Executable file
After Width: | Height: | Size: 31 KiB |
BIN
sources/p/themes/Screwdriver/icons/favicon-256.png
Executable file
After Width: | Height: | Size: 17 KiB |
13
sources/p/themes/Screwdriver/icons/favicon.svg
Executable file
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
|
||||
<title>Logo FreshRSS</title>
|
||||
<circle fill="#FFF" cx="128" cy="128" r="128"/>
|
||||
<circle fill="#0062BE" cx="128" cy="128" r="33"/>
|
||||
<g fill="none" stroke="#0062BE" stroke-width="24">
|
||||
<g stroke-opacity="0.3">
|
||||
<path d="M12,128 A116,116 0 1,1 128,244"/>
|
||||
<path d="M54,128 A74,74 0 1,1 128,202"/>
|
||||
</g>
|
||||
<path d="M128,12 A116,116 0 0,1 244,128"/>
|
||||
<path d="M128,54 A74,74 0 0,1 202,128"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 470 B |
BIN
sources/p/themes/Screwdriver/icons/grey.gif
Executable file
After Width: | Height: | Size: 56 B |
7
sources/p/themes/Screwdriver/icons/help.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-182,-490)" fill="#bebebe">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="m190,490c-4.4147,0-8,3.5853-8,8s3.5853,8,8,8,8-3.5853,8-8-3.5853-8-8-8zm0,2c3.3413,0,6,2.6587,6,6s-2.6587,6-6,6-6-2.6587-6-6,2.6587-6,6-6z"/>
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="M189.34,495c-1.28,0-2.34,1.06-2.34,2.34v1.3125c0,1.2861,1.0576,2.3438,2.3438,2.3438h1.3125c1.29,0.01,2.35-1.05,2.35-2.33v-1.3125c0-1.29-1.06-2.35-2.34-2.35h-1.3125zm0,1,1.3125,0c0.74942,0,1.3438,0.59433,1.3438,1.3438v1.3125c0.01,0.76-0.58,1.35-1.33,1.35h-1.3125c-0.76,0-1.35-0.59-1.35-1.34v-1.3125c0-0.76,0.59-1.35,1.34-1.35z"/>
|
||||
<path d="m186.72,491.44c-1.5103,0.6073-2.6811,1.7985-3.2812,3.3125l3.75,1.875c0.25196-0.64029,0.74249-1.1706,1.375-1.4375l-1.8438-3.75zm6.5625,0-1.8438,3.75c0.63251,0.26694,1.123,0.79721,1.375,1.4375l3.75-1.875c-0.60015-1.514-1.7709-2.7052-3.2812-3.3125zm-6.0938,8-3.75,1.875c0.60709,1.4886,1.789,2.65,3.2812,3.25l1.875-3.75c-0.62682-0.25556-1.1433-0.75203-1.4062-1.375zm5.625,0c-0.26291,0.62297-0.77943,1.1194-1.4062,1.375l1.875,3.75c1.4923-0.60005,2.6742-1.7614,3.2812-3.25l-3.75-1.875z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -1,7 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
|
||||
<title>Logo FreshRSS</title>
|
||||
<circle fill="#2980b9" cx="128" cy="128" r="33"/>
|
||||
<g fill="none" stroke="#2980b9" stroke-width="24">
|
||||
<circle fill="#0062BE" cx="128" cy="128" r="33"/>
|
||||
<g fill="none" stroke="#0062BE" stroke-width="24">
|
||||
<g stroke-opacity="0.3">
|
||||
<path d="M12,128 A116,116 0 1,1 128,244"/>
|
||||
<path d="M54,128 A74,74 0 1,1 128,202"/>
|
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
|
@ -1,5 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(-340.99994,-257)" fill="#ffffff">
|
||||
<g transform="translate(-340.99994,-257)" fill="#666666">
|
||||
<path style="block-progression:tb;color:#000000;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="m346,260c-2.7496,0-5,2.2504-5,5s2.2504,5,5,5c1.5862,0,2.9034-0.84459,3.8125-2h4.8438,0.75l0.21875-0.75,1.0312-4,0.3125-1.25h-1.2812-5.875c-0.90914-1.1554-2.2263-2-3.8125-2zm0,2c1.1158,0,2.0379,0.59507,2.5625,1.5l0.3125,0.5h0.5625,4.9688l-0.53125,2h-4.4375-0.5625l-0.3125,0.5c-0.52462,0.90493-1.4466,1.5-2.5625,1.5-1.6687,0-3-1.3313-3-3s1.3313-3,3-3z"/>
|
||||
<path opacity="0.35" style="enable-background:accumulate;color:#000000;" d="M355.5,265,350,265,349.44,267,355,267z" fill-rule="nonzero"/>
|
||||
<path style="enable-background:accumulate;color:#000000;" d="m346,265c0,0.55228-0.44772,1-1,1s-1-0.44772-1-1,0.44772-1,1-1,1,0.44772,1,1z" fill-rule="nonzero"/>
|
Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 910 B |
7
sources/p/themes/Screwdriver/icons/link.svg
Executable file
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16.004" width="16">
|
||||
<g fill="#bebebe" transform="translate(-183,-529)">
|
||||
<path style="enable-background:accumulate;color:#000000;" d="m191,533.85,0,10.38-2.344-2.2882-1.3394,2.7346c-0.32808,0.73962-2.0337,0.14492-1.5487-0.84412l1.3255-2.8393h-2.9579l6.8645-7.1436z" fill-rule="nonzero" display="block"/>
|
||||
<path d="m190.16,530.06c-3.8266,0.46006-6.5788,3.9578-6.0938,7.7812,0.13127,1.0347,0.29377,1.3818,0.29377,1.3818l1.675-1.6318c-0.33104-2.7534,1.6216-5.2315,4.375-5.5625,2.7534-0.33104,5.2315,1.6216,5.5625,4.375,0.31355,2.608-1.3913,5.0249-3.9688,5.5312l0.0312,2s0.52086-0.1059,0.62354-0.13097c3.4156-0.83385,5.7063-4.1273,5.2827-7.6503-0.46006-3.8266-3.9547-6.5538-7.7812-6.0938z" style="baseline-shift:baseline;block-progression:tb;color:#000000;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;"/>
|
||||
<path opacity="0.3" style="enable-background:accumulate;color:#000000;" d="m187.11,536.81,0-0.20574-0.19826,0.0186c0.0165-0.13095,0.0329-0.26167,0.0496-0.3926h-0.11578l-0.11556,0.14959-0.11578,0.0559-0.1653-0.0932-0.0165-0.20575,0.0331-0.22438,0.24798-0.18688h0.19826l0.0329-0.11229,0.24786,0.0559,0.18183,0.2246,0.0331-0.37419,0.31401-0.26167,0.11567-0.28055,0.23133-0.0934,0.1322-0.18688,0.29738-0.0564,0.14885-0.22415h-0.44623l0.28094-0.13095h0.19814l0.28106-0.0937,0.0331-0.11186-0.0992-0.0937-0.11567-0.0375,0.0331-0.11208-0.0826-0.16822-0.19837,0.0746,0.0331-0.14947-0.23134-0.13096-0.18171,0.3177,0.0165,0.11229-0.18171,0.075-0.11578,0.24302-0.0495-0.22438-0.31402-0.13095-0.0496-0.16822,0.41315-0.24325,0.18182-0.16822,0.0165-0.20563-0.0991-0.0562-0.13219-0.0188-0.0826,0.20575s-0.1382,0.0271-0.17373,0.0358c-0.45378,0.41804-1.3707,1.3204-1.5837,3.024,0.008,0.0395,0.15441,0.26854,0.15441,0.26854l0.347,0.20552,0.347,0.0937m3.9661-4.3003-0.4298-0.16833-0.49552,0.0561-0.61161,0.16822-0.11567,0.11229,0.38008,0.26167,0,0.14959-0.14875,0.14959,0.19846,0.39294,0.13188-0.075,0.16561-0.26168c0.2553-0.0789,0.4842-0.16833,0.72686-0.28053l0.19846-0.5048m2.5292,0.34192-0.375,0.0937-0.21875,0.15625,0,0.125-0.375,0.25,0.0937,0.34375,0.21875-0.15625,0.125,0.15625,0.15625,0.0937,0.0937-0.28125-0.0625-0.15625,0.0625-0.0937,0.21875-0.1875,0.0937,0-0.0937,0.21875,0,0.1875c0.0892-0.0242,0.1588-0.051,0.25-0.0625l-0.25,0.1875v0.125l-0.3125,0.21875-0.28125-0.0625v-0.15625l-0.125,0.0625,0.0625,0.15625h-0.21875l-0.125,0.21875-0.15625,0.15625-0.0937,0.0312v0.1875l0.0312,0.15625h-0.0312v0.53125l0.0625-0.0312,0.0937-0.21875,0.1875-0.125,0.0312-0.0937,0.28125-0.0625,0.15625,0.1875,0.1875,0.0937-0.0937,0.1875,0.15625-0.0312,0.0625-0.21875-0.1875-0.21875h0.0625l0.21875,0.15625,0.0312,0.21875,0.15625,0.21875,0.0625-0.3125,0.0937-0.0312c0.0959,0.0996,0.1692,0.23163,0.25,0.34375h0.28125l0.1875,0.125-0.0937,0.0937-0.15625,0.15625h-0.25l-0.34375-0.0937h-0.1875l-0.125,0.15625-0.34375-0.375-0.25-0.0625-0.375,0.0625-0.15625,0.0937v2.4062l0.0312,0.0312,0.25-0.15625,0.0937,0.0937h0.28125l0.125,0.15625-0.0937,0.3125,0.1875,0.1875v0.375l0.125,0.25-0.0937,0.25c-0.009,0.16159,0,0.30714,0,0.46875,0.0795,0.21894,0.14355,0.43575,0.21875,0.65625l0.0625,0.34375v0.1875h0.125l0.21875-0.125h0.25l0.375-0.4375-0.0312-0.15625,0.25-0.21875-0.1875-0.1875,0.21875-0.1875,0.21875-0.125,0.0937-0.125-0.0625-0.25v-0.59375l0.1875-0.375,0.1875-0.25,0.25-0.5625v-0.15625c-0.11654,0.0146-0.22972,0.0231-0.34375,0.0312-0.0722,0.005-0.14446,0-0.21875,0-0.12359-0.25961-0.2183-0.50966-0.3125-0.78125l-0.15625-0.1875-0.0937-0.3125,0.0625-0.0625,0.21875,0.25,0.25,0.5625,0.15625,0.15625-0.0625,0.21875,0.15625,0.15625,0.25-0.25,0.3125-0.21875,0.15625-0.1875v-0.21875c-0.0389-0.0732-0.0547-0.14545-0.0937-0.21875l-0.15625,0.1875-0.125-0.15625-0.1875-0.125v-0.28125l0.21875,0.21875,0.21875-0.0312c0.10166,0.0923,0.19205,0.20751,0.28125,0.3125l0.15625-0.1875c0-0.17463-0.19976-1.0204-0.625-1.75-0.42526-0.72932-1.1562-1.4062-1.1562-1.4062l-0.0625,0.0937-0.21875,0.21875-0.25-0.25h0.25l0.125-0.125-0.46875-0.0937-0.25-0.0937z" fill-rule="nonzero"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
6
sources/p/themes/Screwdriver/icons/login.svg
Executable file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-181.0002,-237)" fill="#bebebe">
|
||||
<path style="color:#bebebe;" d="m184,244c-0.554,0-1,0.446-1,1v0.53125,5.4688h12v-5.4688-0.53c0-0.554-0.446-1-1-1h-10z" fill-rule="nonzero"/>
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="m188,238c-1.6447,0-3,1.3553-3,3v7c0,1.6447,1.3553,3,3,3h2c1.6447,0,3-1.3553,3-3v-7c0-1.6447-1.3553-3-3-3h-2zm0,2,2,0c0.5713,0,1,0.4287,1,1v7c0,0.5713-0.4287,1-1,1h-2c-0.5713,0-1-0.4287-1-1v-7c0-0.5713,0.4287-1,1-1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 662 B |
6
sources/p/themes/Screwdriver/icons/logout.svg
Executable file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-201.0002,-237)" fill="#bebebe">
|
||||
<path style="color:#bebebe;" d="m204,246c-0.554,0-1,0.446-1,1v0.53125,5.4688h12v-5.4688-0.53c0-0.554-0.446-1-1-1h-10z" fill-rule="nonzero"/>
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="m208,237c-1.6447,0-3,1.3553-3,3v3h2v-3c0-0.57129,0.42873-1,1-1h2c0.57127,0,1,0.42871,1,1v7h2v-7c0-1.6447-1.3553-3-3-3h-2z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 569 B |
5
sources/p/themes/Screwdriver/icons/next.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-121.0002,-747)">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m125,749,1,0c0.0104-0.00012,0.0208-0.00046,0.0313,0,0.25495,0.0112,0.50987,0.12858,0.6875,0.3125l6.2977,5.7188-6.2977,5.7188c-0.18816,0.18819-0.45346,0.28125-0.71875,0.28125h-1v-1c0-0.26529,0.0931-0.53058,0.28125-0.71875l4.829-4.2812-4.829-4.2812c-0.21074-0.19463-0.30316-0.46925-0.28125-0.75z" fill-rule="nonzero" fill="#bebebe"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 589 B |
5
sources/p/themes/Screwdriver/icons/non-starred.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-61.000202,-397)">
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#000000;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" fill="#bebebe" d="m69.003,398.01c-0.2659-0.00099-0.49859,0.1006-0.6647,0.2393-0.16611,0.13869-0.27742,0.32137-0.38968,0.50028-0.22453,0.35782-0.39269,0.76873-0.56546,1.2036-0.17277,0.43483-0.34713,0.88766-0.5046,1.2323-0.15747,0.34465-0.3456,0.57871-0.35862,0.58776-0.01287,0.009-0.30722,0.117-0.69576,0.15181-0.38855,0.0348-0.88122,0.0492-1.3632,0.0694-0.48202,0.0202-0.9703,0.0362-1.393,0.12817-0.21138,0.046-0.4154,0.10148-0.60434,0.20956s-0.36689,0.28631-0.45004,0.53002-0.04901,0.50627,0.03636,0.70157c0.08537,0.19531,0.22656,0.36514,0.3682,0.52344,0.2833,0.31663,0.6327,0.60557,1.0079,0.89849s0.77671,0.55926,1.0678,0.81027c0.29104,0.25101,0.45422,0.50796,0.45912,0.52271,0.0048,0.0146,0.03119,0.33498-0.05456,0.70231-0.08575,0.36732-0.2238,0.81174-0.35282,1.2603-0.12902,0.44861-0.25176,0.90196-0.2917,1.3184-0.01997,0.20819-0.04285,0.40729,0.0053,0.61409,0.04814,0.20679,0.1845,0.43007,0.39902,0.58168,0.21451,0.15161,0.44936,0.1881,0.66823,0.1701s0.43535-0.0703,0.63515-0.15132c0.39961-0.16214,0.80177-0.42851,1.2064-0.68231,0.40465-0.2538,0.80822-0.52155,1.1456-0.71107,0.33734-0.18952,0.6484-0.2686,0.66445-0.26854,0.01586,0.00006,0.30338,0.0951,0.63894,0.28732,0.33556,0.19221,0.72532,0.46503,1.1276,0.72205,0.40229,0.25702,0.81996,0.49752,1.218,0.66284,0.19903,0.0827,0.38893,0.15086,0.60762,0.17059,0.2187,0.0197,0.47978-0.031,0.69551-0.18105,0.21572-0.15001,0.33928-0.35235,0.38918-0.55877s0.04291-0.43517,0.02476-0.64358c-0.03632-0.41683-0.15899-0.86394-0.2841-1.3137-0.12511-0.44978-0.26165-0.88661-0.34421-1.2548-0.08256-0.36813-0.07169-0.68662-0.06666-0.70133,0.005-0.0145,0.18746-0.25247,0.4806-0.50101,0.29313-0.24854,0.67599-0.53755,1.0536-0.82731,0.37764-0.28976,0.76716-0.57158,1.0531-0.88579,0.14298-0.1571,0.2418-0.33444,0.32882-0.52904s0.136-0.42874,0.05481-0.67306-0.27108-0.41314-0.45912-0.52272-0.36679-0.18158-0.57782-0.22931c-0.42206-0.0955-0.91359-0.14009-1.3956-0.16426-0.48198-0.0242-0.94584-0.039-1.3342-0.077s-0.71565-0.13122-0.72859-0.14037c-0.01279-0.009-0.18402-0.23636-0.3384-0.58217s-0.32658-0.78819-0.49548-1.2243c-0.1689-0.4361-0.33477-0.86429-0.55609-1.2238-0.11067-0.17977-0.23335-0.35397-0.39826-0.49396s-0.40309-0.25684-0.66899-0.25783zm0.0086,0.99424c0.0422,0.0358,0.10671,0.13602,0.1841,0.26173,0.15477,0.25141,0.33068,0.6272,0.49397,1.0488,0.16329,0.42163,0.31905,0.88645,0.49598,1.2828,0.17693,0.39633,0.31456,0.73379,0.6753,0.98889,0.36072,0.25509,0.77019,0.29763,1.2152,0.34118,0.44506,0.0435,0.92882,0.0532,1.3948,0.0765,0.46599,0.0234,0.91824,0.0697,1.2135,0.13647,0.14763,0.0334,0.25558,0.0572,0.30381,0.0853-0.02227,0.0498-0.07958,0.15478-0.17956,0.26464-0.19997,0.21973-0.53749,0.48746-0.90261,0.7676-0.36511,0.28015-0.77804,0.57219-1.114,0.85704-0.33595,0.28485-0.63992,0.53221-0.77987,0.94209-0.13995,0.40986-0.05396,0.77681,0.04065,1.1987s0.25406,0.87813,0.37502,1.313c0.12096,0.43486,0.22688,0.84692,0.25228,1.1385,0.01156,0.13264-0.01699,0.23485-0.02778,0.29267-0.05993-0.008-0.1764-0.0324-0.30381-0.0853-0.27836-0.11561-0.64649-0.32808-1.0354-0.57657-0.38894-0.24849-0.8039-0.53053-1.1885-0.75081-0.38457-0.22028-0.70791-0.39837-1.1551-0.40015-0.44722-0.002-0.79205,0.17245-1.1786,0.38965-0.38659,0.21719-0.78438,0.49517-1.1756,0.74055-0.39123,0.24538-0.77636,0.4507-1.0559,0.56412-0.13977,0.0567-0.24616,0.0856-0.3023,0.0902-0.01026-0.0578-0.01522-0.16008-0.0025-0.29243,0.02793-0.29118,0.13818-0.70893,0.26291-1.1426,0.12473-0.43372,0.25404-0.89785,0.35232-1.3188,0.09828-0.42099,0.18672-0.78846,0.05027-1.1994-0.13644-0.41097-0.43218-0.64202-0.76571-0.92967-0.33353-0.28766-0.70551-0.58555-1.0683-0.86876-0.36275-0.2832-0.7178-0.56075-0.91597-0.78224-0.09908-0.11075-0.16221-0.21163-0.1841-0.26173,0.04834-0.0276,0.15448-0.058,0.3023-0.0902,0.29562-0.0643,0.74518-0.10714,1.2112-0.1267,0.46603-0.0196,0.94824-0.0298,1.3935-0.0697,0.44531-0.0399,0.84679-0.0499,1.2097-0.30216,0.36289-0.25221,0.5383-0.60511,0.71876-1.0001,0.18046-0.39497,0.33731-0.84115,0.50435-1.2616,0.16704-0.42041,0.31848-0.83556,0.47556-1.0859,0.07853-0.12515,0.16751-0.20007,0.21012-0.23565z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
5
sources/p/themes/Screwdriver/icons/prev.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-301.0002,-747)">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m313.01,749-1,0c-0.0104-0.00012-0.0208-0.00046-0.0313,0-0.25495,0.0112-0.50987,0.12858-0.6875,0.3125l-6.2977,5.7188,6.2977,5.7188c0.18816,0.18819,0.45346,0.28125,0.71875,0.28125h1v-1c0-0.26529-0.0931-0.53058-0.28125-0.71875l-4.829-4.2812,4.829-4.2812c0.21074-0.19463,0.30316-0.46925,0.28125-0.75z" fill-rule="nonzero" fill="#bebebe"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 592 B |
57
sources/p/themes/Screwdriver/icons/read.svg
Executable file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="16.001"
|
||||
width="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="read.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="745"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.749079"
|
||||
inkscape:cx="-2.2040272"
|
||||
inkscape:cy="8.0004997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
transform="translate(-60.99995,-296.9989)"
|
||||
id="g4" />
|
||||
<path
|
||||
style="fill:#cccccc;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.0004996,3.2833392 c -3.433907,0 -6.410294,1.9996259 -7.87290101,4.9205634 1.46260701,2.9209364 4.43899401,4.9205624 7.87290101,4.9205624 3.4338474,0 6.4102344,-1.999626 7.8729014,-4.9205624 C 14.410824,5.2829651 11.434347,3.2833392 8.0004996,3.2833392 z m 3.8818634,2.6094965 c 0.925096,0.590068 1.709004,1.3804357 2.29781,2.3110669 -0.588806,0.9306312 -1.372744,1.7209988 -2.29784,2.3110964 -1.162392,0.741404 -2.5047194,1.133295 -3.8818334,1.133295 -1.377143,0 -2.719472,-0.391891 -3.881863,-1.133326 -0.925066,-0.5900366 -1.708974,-1.3804016 -2.29781,-2.3110654 0.588806,-0.9306638 1.372744,-1.7210288 2.29781,-2.3110669 0.06025,-0.038442 0.121108,-0.075682 0.182338,-0.1122479 -0.153123,0.4202145 -0.236925,0.873738 -0.236925,1.3469419 0,2.1740274 1.762423,3.9364493 3.93645,3.9364493 2.1740274,0 3.9364514,-1.7624219 3.9364514,-3.9364493 0,-0.4732039 -0.0838,-0.9267274 -0.236925,-1.3469745 0.0612,0.036566 0.122061,0.073839 0.182337,0.1122805 z M 8.0004996,6.6354719 c 0,0.8152761 -0.660894,1.4761705 -1.476168,1.4761705 -0.815275,0 -1.476169,-0.6608944 -1.476169,-1.4761705 0,-0.8152759 0.660894,-1.4761676 1.476169,-1.4761676 0.815274,0 1.476168,0.6608917 1.476168,1.4761676 z"
|
||||
id="path3167" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
5
sources/p/themes/Screwdriver/icons/refresh.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-241.0002,-627)">
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#666666;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" fill="#666" d="m253.91,628.97a1.0001,1.0001,0,0,0,-0.125,0.0312,1.0001,1.0001,0,0,0,-0.78125,1v1.6875c-0.38225-0.57796-0.84927-1.0822-1.4062-1.5-1.1556-0.86677-2.532-1.2523-3.875-1.1875-0.19186,0.009-0.37223,0.0353-0.5625,0.0625-1.5222,0.21741-2.9782,1.023-3.9688,2.3438-1.9812,2.6414-1.4227,6.425,1.2188,8.4062s6.425,1.4227,8.4062-1.2188a1.0063,1.0063,0,0,0,0.18,-0.59,1.0063,1.0063,0,0,0,0,-0.15625v-0.84375h-0.8125-0.0937a1.0063,1.0063,0,0,0,-0.0937,0,1.0063,1.0063,0,0,0,-0.8125,0.40625c-1.3326,1.7767-3.817,2.1139-5.5938,0.78125-1.7767-1.3326-2.1139-3.817-0.78125-5.5938,1.3326-1.7767,3.817-2.1139,5.5938-0.78125,0.42946,0.32212,0.76954,0.73295,1.0312,1.1875h-1.4375a1.0001,1.0001,0,0,0,-1,1,1.0001,1.0001,0,0,0,0,0.21875v0.78125h0.84375,0.15625,4,1v-1-4a1.0001,1.0001,0,0,0,0,-0.1875v-0.8125h-0.8125a1.0001,1.0001,0,0,0,-0.28125,-0.0312z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -1,5 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g fill-rule="nonzero" transform="translate(-561,-301.00012)" fill="#fff">
|
||||
<g fill-rule="nonzero" transform="translate(-561,-301.00012)" fill="#666">
|
||||
<path style="enable-background:new;color:#000000;" d="m325.06,97.188c0,1.7872-0.89543,3.2361-2,3.2361s-2-1.4488-2-3.2361c0-1.7872,0.89543-3.2361,2-3.2361s2,1.4488,2,3.2361z" transform="matrix(1.0000007,0,0,0.61803426,241.93747,252.93479)"/>
|
||||
<path style="enable-background:new;color:#000000;" d="m563,303,0,1c0,0.55016,0.45347,1,1,1,4.9706,0,9,4.0294,9,9,0,0.55016,0.45347,1,1,1h1v-1c0-6.0751-4.9249-11-11-11h-1zm0,4,0,1c0,0.55016,0.45347,1,1,1,2.7614,0,5,2.2386,5,5,0,0.55016,0.45347,1,1,1h1v-1c0-3.866-3.134-7-7-7h-1z"/>
|
||||
</g>
|
Before Width: | Height: | Size: 672 B After Width: | Height: | Size: 672 B |
6
sources/p/themes/Screwdriver/icons/search.svg
Executable file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g fill="#666" transform="translate(-441.0004,-195)">
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#666666;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m447.51,196c-3.0289,0-5.5107,2.479-5.5107,5.5045,0,3.0254,2.4819,5.5045,5.5107,5.5045s5.5107-2.479,5.5107-5.5045c0-3.0254-2.4819-5.5045-5.5107-5.5045zm0,2.0089c1.9474,0,3.4995,1.5504,3.4995,3.4955s-1.5522,3.4955-3.4995,3.4955c-1.9474,0-3.4995-1.5504-3.4995-3.4955,0-1.9452,1.5522-3.4955,3.4995-3.4955z"/>
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#666666;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m450.81,204a1.0001,1.0001,0,0,0,-0.5,1.7188l4,4a1.0055,1.0055,0,1,0,1.4062,-1.4375l-4-4a1.0001,1.0001,0,0,0,-0.91,-0.28z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 886 B |
8
sources/p/themes/Screwdriver/icons/share.svg
Executable file
|
@ -0,0 +1,8 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g fill="#bebebe" transform="translate(-581.0002,-196)">
|
||||
<path style="enable-background:new;color:#000000;" d="m291,178.03c0,1.0873-0.88144,1.9688-1.9688,1.9688-1.0873,0-1.9688-0.88144-1.9688-1.9688,0-1.0873,0.88144-1.9688,1.9688-1.9688,1.0873,0,1.9688,0.88144,1.9688,1.9688z" fill-rule="nonzero" transform="matrix(1.5079365,0,0,1.5079365,148.15963,-64.49107)"/>
|
||||
<path style="enable-background:new;color:#000000;" d="m291,178.03c0,1.0873-0.88144,1.9688-1.9688,1.9688-1.0873,0-1.9688-0.88144-1.9688-1.9688,0-1.0873,0.88144-1.9688,1.9688-1.9688,1.0873,0,1.9688,0.88144,1.9688,1.9688z" fill-rule="nonzero" transform="matrix(1.5079365,0,0,1.5079365,158.12818,-59.49107)"/>
|
||||
<path style="enable-background:new;color:#000000;" d="m291,178.03c0,1.0873-0.88144,1.9688-1.9688,1.9688-1.0873,0-1.9688-0.88144-1.9688-1.9688,0-1.0873,0.88144-1.9688,1.9688-1.9688,1.0873,0,1.9688,0.88144,1.9688,1.9688z" fill-rule="nonzero" transform="matrix(1.5079365,0,0,1.5079365,158.12818,-69.49107)"/>
|
||||
<path style="baseline-shift:baseline;block-progression:tb;color:#000000;direction:ltr;text-indent:0;text-align:start;enable-background:accumulate;text-transform:none;" d="m593.62,198.16-10.062,4.875-1.8125,0.90625,1.8125,0.90625,10.031,5.0625,0.90625-1.8125-8.2188-4.1562,8.2188-4-0.875-1.7812z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
60
sources/p/themes/Screwdriver/icons/starred.svg
Executable file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="16"
|
||||
width="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="starred.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="685"
|
||||
inkscape:window-height="480"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="8"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
transform="translate(-41.000202,-397)"
|
||||
id="g4">
|
||||
<path
|
||||
style="enable-background:accumulate;color:#000000;fill:#eaa904;fill-opacity:1"
|
||||
d="m530.95,186.71c-0.77941,0.55189-3.1576-1.906-4.1125-1.9179-0.95532-0.0119-3.3949,2.3858-4.161,1.8149-0.76573-0.57072,0.83698-3.592,0.55319-4.5039-0.2839-0.91223-3.3182-2.4915-3.0119-3.3965,0.30617-0.90461,3.6749-0.31399,4.4544-0.86567,0.77986-0.5519,1.3442-3.9257,2.2995-3.914,0.95494,0.0116,1.4342,3.398,2.1998,3.9689,0.76588,0.57114,4.1489,0.0653,4.4331,0.97746,0.28402,0.9118-2.7885,2.414-3.0949,3.3186-0.30652,0.90489,1.22,3.966,0.44027,4.5182z"
|
||||
fill-rule="nonzero"
|
||||
transform="matrix(1.0472113,-0.00871584,0.00871584,1.0472113,-504.35434,220.15425)"
|
||||
fill="#f1c40f"
|
||||
id="path6" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
5
sources/p/themes/Screwdriver/icons/tag.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-141.0002,-807)">
|
||||
<path d="m149,809,0,13,4-4,4,4c0.0525-6.8494-0.0285-10.584,0-13z" fill="#bebebe"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 200 B |
65
sources/p/themes/Screwdriver/icons/unread.svg
Executable file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="16"
|
||||
width="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="unread.svg">
|
||||
<metadata
|
||||
id="metadata14">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs12" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="745"
|
||||
id="namedview10"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:zoom="20.85965"
|
||||
inkscape:cx="3.2842788"
|
||||
inkscape:cy="5.738225"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2">
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="18.02523,13.039528"
|
||||
id="guide4011" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="10.738435,2.1093355"
|
||||
id="guide4013" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
style="fill:#666666;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.9824408,3.5290339 c -3.4339072,0 -6.4102945,1.9996258 -7.87290106,4.9205633 C 1.5721463,11.370534 4.5485336,13.37016 7.9824408,13.37016 c 3.4338472,0 6.4102342,-1.999626 7.8729012,-4.9205628 C 14.392765,5.5286597 11.416288,3.5290339 7.9824408,3.5290339 z m 3.8818632,2.6094964 c 0.925096,0.590068 1.709004,1.3804357 2.29781,2.3110669 -0.588806,0.9306312 -1.372744,1.7209988 -2.29784,2.3110968 -1.162392,0.741404 -2.5047196,1.133295 -3.8818332,1.133295 -1.377143,0 -2.7194718,-0.391891 -3.8818628,-1.133326 C 3.1755118,10.170626 2.3916036,9.380261 1.8027674,8.4495972 2.3915738,7.5189334 3.1755118,6.7285684 4.100578,6.1385303 4.160827,6.1000883 4.221686,6.0628483 4.2829153,6.0262824 c -0.1531228,0.4202145 -0.236925,0.873738 -0.236925,1.3469419 0,2.1740274 1.7624231,3.9364497 3.9364505,3.9364497 2.1740272,0 3.9364512,-1.7624223 3.9364512,-3.9364497 0,-0.4732039 -0.0838,-0.9267274 -0.236925,-1.3469745 0.0612,0.036566 0.122061,0.073839 0.182337,0.1122805 z M 7.9824408,6.8811665 c 0,0.8152761 -0.660894,1.4761705 -1.476168,1.4761705 -0.8152757,0 -1.4761697,-0.6608944 -1.4761697,-1.4761705 0,-0.8152759 0.660894,-1.4761676 1.4761697,-1.4761676 0.815274,0 1.476168,0.6608917 1.476168,1.4761676 z"
|
||||
id="path3167" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
5
sources/p/themes/Screwdriver/icons/up.svg
Executable file
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<g transform="translate(-201.0002,-747)">
|
||||
<path style="block-progression:tb;color:#bebebe;direction:ltr;text-indent:0;text-align:start;enable-background:new;text-transform:none;" d="m215.03,759,0-1c-0.00091-0.0111,0.00059-0.021-0.00009-0.0312-0.0112-0.25496-0.12835-0.50994-0.31251-0.6875l-5.7188-6.2977-5.7188,6.2977c-0.18821,0.1881-0.28121,0.45346-0.28122,0.71875v1h1c0.26531-0.00007,0.53059-0.0931,0.71873-0.28131l4.2812-4.829,4.2813,4.829c0.19464,0.21073,0.46925,0.30315,0.74998,0.2813z" fill-rule="nonzero" fill="#bebebe"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 604 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-61-867)" fill="#fff" color="#000"><rect height="2" rx=".385" ry=".379" width="2" x="64" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="64" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="64" y="878"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="878"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="878"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-61-867)" fill="#666" color="#000"><rect height="2" rx=".385" ry=".379" width="2" x="64" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="870"/><rect height="2" rx=".385" ry=".379" width="2" x="64" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="874.02"/><rect height="2" rx=".385" ry=".379" width="2" x="64" y="878"/><rect height="2" rx=".385" ry=".379" width="2" x="68" y="878"/><rect height="2" rx=".385" ry=".379" width="2" x="72" y="878"/></g></svg>
|
Before Width: | Height: | Size: 705 B After Width: | Height: | Size: 705 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-40-746)" fill="#fff" color="#fff"><path d="m43 749h10v2h-10z"/><path d="m43 753h10v2h-10z"/><path d="m43 757h10v2h-10z"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-40-746)" fill="#666" color="#666"><path d="m43 749h10v2h-10z"/><path d="m43 753h10v2h-10z"/><path d="m43 757h10v2h-10z"/></g></svg>
|
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-181-867)" fill="#fff" color="#fff"><path d="m 181,868 0,1 0,11 0,1 1,0 5,0 c 0.1754,0 0.52538,0.15166 0.8125,0.34375 0.28712,0.19209 0.46875,0.375 0.46875,0.375 L 189,882.4375 l 0.71875,-0.75 c 0,0 0.8963,-0.6875 1.28125,-0.6875 l 5,0 1,0 0,-1 0,-11 0,-1 -1,0 -5,0 c -0.87652,0 -1.56017,0.34756 -2.03125,0.6875 -0.0301,-0.0207 -0.031,-0.0105 -0.0625,-0.0312 C 188.44557,868.35254 187.82811,868 187,868 l -5,0 -1,0 z m 2,2 4,0 c 0.13821,0 0.51476,0.14746 0.8125,0.34375 0.29774,0.19629 0.5,0.375 0.5,0.375 l 0.71875,0.6875 0.6875,-0.71875 c 0,0 0.89975,-0.6875 1.28125,-0.6875 l 4,0 0,9 -4,0 c -0.87693,0 -1.56008,0.34735 -2.03125,0.6875 -0.0196,-0.0135 -0.011,-0.0177 -0.0312,-0.0312 C 188.47725,879.34834 187.83512,879 187,879 l -4,0 0,-9 z"/><g transform="scale(-1 1)"><rect height="2" rx=".375" width="3" x="-187" y="872"/><rect height="2" rx=".375" width="3" x="-187" y="875"/><rect height="2" rx=".375" width="3" x="-194" y="872"/><rect height="2" rx=".375" width="3" x="-194" y="875"/></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g transform="translate(-181-867)" fill="#666" color="#666"><path d="m 181,868 0,1 0,11 0,1 1,0 5,0 c 0.1754,0 0.52538,0.15166 0.8125,0.34375 0.28712,0.19209 0.46875,0.375 0.46875,0.375 L 189,882.4375 l 0.71875,-0.75 c 0,0 0.8963,-0.6875 1.28125,-0.6875 l 5,0 1,0 0,-1 0,-11 0,-1 -1,0 -5,0 c -0.87652,0 -1.56017,0.34756 -2.03125,0.6875 -0.0301,-0.0207 -0.031,-0.0105 -0.0625,-0.0312 C 188.44557,868.35254 187.82811,868 187,868 l -5,0 -1,0 z m 2,2 4,0 c 0.13821,0 0.51476,0.14746 0.8125,0.34375 0.29774,0.19629 0.5,0.375 0.5,0.375 l 0.71875,0.6875 0.6875,-0.71875 c 0,0 0.89975,-0.6875 1.28125,-0.6875 l 4,0 0,9 -4,0 c -0.87693,0 -1.56008,0.34735 -2.03125,0.6875 -0.0196,-0.0135 -0.011,-0.0177 -0.0312,-0.0312 C 188.47725,879.34834 187.83512,879 187,879 l -4,0 0,-9 z"/><g transform="scale(-1 1)"><rect height="2" rx=".375" width="3" x="-187" y="872"/><rect height="2" rx=".375" width="3" x="-187" y="875"/><rect height="2" rx=".375" width="3" x="-194" y="872"/><rect height="2" rx=".375" width="3" x="-194" y="875"/></g></g></svg>
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
sources/p/themes/Screwdriver/loader.gif
Executable file
After Width: | Height: | Size: 4.1 KiB |
7
sources/p/themes/Screwdriver/metadata.json
Executable file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "Screwdriver",
|
||||
"author": "Mister aiR",
|
||||
"description": "C'est un cocktail ! C'est chaud mais « fresh » à la fois. Ce thème tue du chaton.",
|
||||
"version": 1.1,
|
||||
"files": ["template.css","screwdriver.css"]
|
||||
}
|
695
sources/p/themes/YunoHost/yunohost.css → sources/p/themes/Screwdriver/screwdriver.css
Normal file → Executable file
4
sources/p/themes/YunoHost/template.css → sources/p/themes/Screwdriver/template.css
Normal file → Executable file
|
@ -2,10 +2,10 @@
|
|||
|
||||
/*=== GENERAL */
|
||||
/*============*/
|
||||
html, body {
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 100%;
|
||||
font-size: 92%;
|
||||
}
|
||||
|
||||
/*=== Links */
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:svg='http://www.w3.org/2000/svg' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' id='svg7384' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' version='1.1' inkscape:version='0.47 r22583' height='16' sodipodi:docname='list-add-symbolic.svg' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns='http://www.w3.org/2000/svg' width='16'>
|
||||
<metadata id='metadata90'>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about=''>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview inkscape:object-paths='true' inkscape:cy='17.83946' inkscape:current-layer='layer12' inkscape:window-width='1920' pagecolor='#555753' showborder='false' showguides='true' inkscape:snap-nodes='false' objecttolerance='10' showgrid='true' inkscape:object-nodes='true' inkscape:pageshadow='2' inkscape:guide-bbox='true' inkscape:window-x='0' inkscape:snap-bbox='true' bordercolor='#FFFFFF' id='namedview88' inkscape:window-maximized='1' inkscape:snap-global='true' inkscape:window-y='26' gridtolerance='10' inkscape:zoom='1' inkscape:window-height='1021' borderopacity='1' guidetolerance='10' inkscape:snap-bbox-midpoints='false' inkscape:cx='-2.56708' inkscape:bbox-paths='false' inkscape:snap-grids='true' inkscape:pageopacity='1' inkscape:snap-to-guides='true'>
|
||||
<inkscape:grid visible='true' spacingx='1px' type='xygrid' spacingy='1px' id='grid4866' empspacing='2' enabled='true' snapvisiblegridlinesonly='true'/>
|
||||
</sodipodi:namedview>
|
||||
<title id='title9167'>Gnome Symbolic Icon Theme</title>
|
||||
<defs id='defs7386'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer10' inkscape:label='devices'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer11' inkscape:label='apps'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer12' inkscape:label='actions'>
|
||||
|
||||
<path d='m 67.0002,729 0,4 -4,0 0,2 4,0 0,4 2,0 0,-4 4,0 0,-2 -4,0 0,-4 -2,0 z' id='rect31992' style='color:#FFFFFF;fill:#FFFFFF;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible'/>
|
||||
</g>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer13' inkscape:label='places'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline'/>
|
||||
<g transform='translate(-60.0002,-726)' inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline'/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3 KiB |