1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/freshrss_ynh.git synced 2024-09-03 18:36:33 +02:00

Upgrade sources to 0.7.4

This commit is contained in:
plopoyop 2014-09-21 12:12:35 +02:00
parent 55ea9e6e9e
commit ba9fd9941c
114 changed files with 2110 additions and 1215 deletions

View file

@ -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

View file

@ -1,3 +1,5 @@
* [English version](README.md)
# FreshRSS
FreshRSS est un agrégateur de flux RSS à auto-héberger à limage 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 dun 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)

View file

@ -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));

View file

@ -1,8 +1,8 @@
<?php
class FreshRSS_error_Controller extends Minz_ActionController {
public function indexAction () {
switch (Minz_Request::param ('code')) {
public function indexAction() {
switch (Minz_Request::param('code')) {
case 403:
$this->view->code = 'Error 403 - Forbidden';
break;
@ -19,8 +19,20 @@ class FreshRSS_error_Controller extends Minz_ActionController {
$this->view->code = 'Error 404 - Not found';
}
$this->view->logs = Minz_Request::param ('logs');
$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 . ' · ');
Minz_View::prependTitle($this->view->code . ' · ');
}
}

View file

@ -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,14 +20,25 @@ 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'];
$status_file = $file['error'];
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'));
}
@set_time_limit(300);
$type_file = $this->guessFileType($file['name']);
$list_files = array(
@ -37,16 +48,23 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
);
// 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') {
if ($type_file === 'zip' && extension_loaded('zip')) {
$zip = zip_open($file['tmp_name']);
while (($zipfile = zip_read($zip)) !== false) {
$type_zipfile = $this->guessFileType(
zip_entry_name($zipfile)
);
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,15 +72,18 @@ 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.
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']);
}
// 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.
@ -78,35 +99,10 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
// 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);
}
// What are you doing? you have to call this controller
// with a POST request!
Minz_Request::forward(array(
'c' => 'importExport',
'a' => 'index'
));
$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()) {
if (!Minz_Request::isPost()) {
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
}
$this->view->_useLayout(false);
$export_opml = Minz_Request::param('export_opml', false);
$export_starred = Minz_Request::param('export_starred', false);
$export_feeds = Minz_Request::param('export_feeds', false);
$export_feeds = Minz_Request::param('export_feeds', array());
// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
$file = tempnam('tmp', 'zip');
$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
// Stuff with content
$export_files = array();
if ($export_opml) {
$zip->addFromString(
'feeds.opml', $this->generateOpml()
);
$export_files['feeds.opml'] = $this->generateOpml();
}
if ($export_starred) {
$zip->addFromString(
'starred.json', $this->generateArticles('starred')
);
$export_files['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)
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);
}
}

View file

@ -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);
}
}

View file

@ -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,24 +40,35 @@ 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() {

View file

@ -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);

View file

@ -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':
$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');
$loginOk = false;
}
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 () {

View file

@ -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';
}

View file

@ -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,7 +226,7 @@ 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();

View file

@ -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` '

View file

@ -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" />';
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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');
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
if (defined('SQL_CREATE_TABLES')) {
$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,10 +35,15 @@ 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');
if ($db['type'] === 'sqlite') {
return unlink(DATA_PATH . '/' . $username . '.sqlite');
} else {
$userPDO = new Minz_ModelPdo($username);
$sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
$stm = $this->bd->prepare($sql);
$stm = $userPDO->bd->prepare($sql);
if ($stm && $stm->execute()) {
return true;
} else {
@ -44,4 +52,5 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
return false;
}
}
}
}

View file

@ -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,

View file

@ -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 &amp; 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',

View file

@ -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 limport du fichier Zip.',
'no_zip_extension' => 'Lextension Zip nest 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' => 'Lextension Zip nest pas présente sur votre serveur. Veuillez essayer dexporter 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 lutilisateur 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 laccès par <abbr>API</abbr> <small>(nécessaire pour les applis mobiles)</small>',
'auth_token' => 'Jeton didentification',
'explain_token' => 'Permet daccéder à la sortie RSS de lutilisateur par défaut sans besoin de sauthentifier.<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 &amp; 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 darticle',
@ -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',

View file

@ -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)',

View file

@ -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 dau moins un des drivers supportés (pdo_mysql, pdo_sqlite)',
'pdo_is_nok' => 'Vous ne disposez pas de PDO ou dun 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)',

View file

@ -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>

View file

@ -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->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>

View file

@ -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>

View file

@ -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)) {

View file

@ -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();
$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';
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'); ?>

View file

@ -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">

View file

@ -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>

View file

@ -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()),
);
}
}

View file

@ -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";

View file

@ -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 { ?>

View file

@ -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

View file

@ -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>

View file

View 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>

View file

@ -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>

View file

@ -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);

View file

@ -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>

View file

@ -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>

View 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>

View file

@ -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
View file

@ -0,0 +1 @@
*.txt

13
sources/data/tokens/index.html Executable file
View 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>

View file

@ -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');
}
}

View file

@ -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);
}
}

View file

@ -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';
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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');
}

View file

@ -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
View file

@ -0,0 +1 @@
.htaccess

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View 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*

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View 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

View 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

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

View 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

View file

@ -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

View file

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View 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"]
}

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
html, body {
margin: 0;
padding: 0;
font-size: 100%;
font-size: 92%;
}
/*=== Links */

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more