Merge branch 'dev' into beta

pull/491/merge
Marien Fressinaud 11 years ago
commit 7f51bf0d02
  1. 8
      CHANGELOG
  2. 8
      README.md
  3. 2
      app/Controllers/configureController.php
  4. 40
      app/Controllers/indexController.php
  5. 2
      app/Controllers/javascriptController.php
  6. 1
      app/Controllers/usersController.php
  7. 4
      app/FreshRSS.php
  8. 4
      app/Models/Configuration.php
  9. 44
      app/Models/Feed.php
  10. 205
      app/Models/StatsDAO.php
  11. 31
      app/i18n/en.php
  12. 29
      app/i18n/fr.php
  13. 2
      app/i18n/install.en.php
  14. 1
      app/i18n/install.fr.php
  15. 7
      app/layout/aside_configure.phtml
  16. 4
      app/layout/aside_feed.phtml
  17. 2
      app/layout/aside_flux.phtml
  18. 6
      app/layout/header.phtml
  19. 2
      app/layout/layout.phtml
  20. 11
      app/layout/nav_menu.phtml
  21. 2
      app/views/configure/archiving.phtml
  22. 19
      app/views/configure/display.phtml
  23. 18
      app/views/configure/feed.phtml
  24. 12
      app/views/configure/sharing.phtml
  25. 8
      app/views/configure/users.phtml
  26. 16
      app/views/helpers/view/normal_view.phtml
  27. 31
      app/views/index/formLogin.phtml
  28. 2
      app/views/index/index.phtml
  29. 125
      app/views/index/stats.phtml
  30. 39
      lib/Minz/Configuration.php
  31. 2
      lib/Minz/Error.php
  32. 61
      lib/lib_rss.php
  33. BIN
      p/favicon.ico
  34. 100
      p/i/install.php
  35. 27
      p/scripts/flotr2.min.js
  36. 1
      p/scripts/jquery-2.0.3.min.map
  37. 10
      p/scripts/jquery.min.js
  38. 32
      p/scripts/main.js
  39. 101
      p/themes/Dark/freshrss.css
  40. 39
      p/themes/Dark/global.css
  41. 92
      p/themes/Flat/freshrss.css
  42. 28
      p/themes/Flat/global.css
  43. 31
      p/themes/Flat/icons/category.svg
  44. 93
      p/themes/Origine/freshrss.css
  45. 35
      p/themes/Origine/global.css
  46. BIN
      p/themes/icons/favicon-128.png
  47. BIN
      p/themes/icons/favicon-16-32-48-64.ico
  48. BIN
      p/themes/icons/favicon-16.png
  49. BIN
      p/themes/icons/favicon-256.png
  50. BIN
      p/themes/icons/favicon-32.png
  51. BIN
      p/themes/icons/favicon-48.png
  52. BIN
      p/themes/icons/favicon-512.png
  53. BIN
      p/themes/icons/favicon-64.png
  54. 17
      p/themes/icons/favicon.svg
  55. 224
      p/themes/icons/icon.svg

@ -1,6 +1,6 @@
# Journal des modifications
## 2014-01-xx FreshRSS 0.7
## 2014-01-29 FreshRSS 0.7
* Nouveau mode multi-utilisateur
* L’utilisateur par défaut (administrateur) peut créer et supprimer d’autres utilisateurs
@ -14,10 +14,10 @@
* Installateur supportant les mises à jour :
* Depuis une v0.6, placer application.ini et Configuration.array.php dans le nouveau répertoire “./data/”
(voir réorganisation ci-dessous)
* Pour les versions suivantes, juste garder “./data/config.php” et “./data/*_user.php”,
éventuellement “./data/persona/*”
* Rafraîchissement automatique du nombre d’articles non lus toutes les minutes (utilise le cache HTTP à bon escient)
* Pour les versions suivantes, juste garder le répertoire “./data/”
* Rafraîchissement automatique du nombre d’articles non lus toutes les deux minutes (utilise le cache HTTP à bon escient)
* Permet aussi de conserver la session valide, surtout dans le cas de Persona
* Nouvelle page de statistiques (nombres d’articles par jour / catégorie)
* Importation OPML instantanée et plus tolérante
* Nouvelle gestion des favicons avec téléchargement en parallèle
* Nouvelles options

@ -6,10 +6,10 @@ Il se veut léger et facile à prendre en main tout en étant un outil puissant
Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture anonyme.
* Site officiel : http://freshrss.org
* Démo : http://marienfressinaud.fr/projets/freshrss/
* Démo : http://demo.freshrss.org/
* Développeur : Marien Fressinaud <dev@marienfressinaud.fr>
* Version actuelle : 0.7-RC1
* Date de publication 2014-01-xx
* Version actuelle : 0.7
* Date de publication 2014-01-29
* 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)
@ -29,7 +29,7 @@ Privilégiez pour cela des demandes sur GitHub
* 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)
* MySQL 5.0.3+ (ou SQLite 3.7.4+ à venir)
* Un navigateur Web récent tel Firefox, Chrome, Opera, Safari, Internet Explorer 9+
* Un navigateur Web récent tel Firefox 4+, Chrome, Opera, Safari, Internet Explorer 9+
* Fonctionne aussi sur mobile
![Capture d’écran de FreshRSS](http://marienfressinaud.fr/data/images/freshrss/freshrss_default-design.png)

@ -196,7 +196,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
if (Minz_Request::isPost ()) {
$this->view->conf->_sharing (array(
'shaarli' => Minz_Request::param ('shaarli', false),
'poche' => Minz_Request::param ('poche', false),
'wallabag' => Minz_Request::param ('wallabag', false),
'diaspora' => Minz_Request::param ('diaspora', false),
'twitter' => Minz_Request::param ('twitter', false),
'g+' => Minz_Request::param ('g+', false),

@ -1,18 +1,7 @@
<?php
class FreshRSS_index_Controller extends Minz_ActionController {
private $get = false;
private $nb_not_read_cat = 0;
private $entryDAO;
private $feedDAO;
private $catDAO;
function __construct($router) {
parent::__construct($router);
$this->entryDAO = new FreshRSS_EntryDAO ();
$this->feedDAO = new FreshRSS_FeedDAO ();
$this->catDAO = new FreshRSS_CategoryDAO ();
}
public function indexAction () {
$output = Minz_Request::param ('output');
@ -50,8 +39,11 @@ class FreshRSS_index_Controller extends Minz_ActionController {
Minz_View::appendScript (Minz_Url::display ('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js')));
}
$this->view->cat_aside = $this->catDAO->listCategories ();
$this->view->nb_favorites = $this->entryDAO->countUnreadReadFavorites ();
$catDAO = new FreshRSS_CategoryDAO();
$entryDAO = new FreshRSS_EntryDAO();
$this->view->cat_aside = $catDAO->listCategories ();
$this->view->nb_favorites = $entryDAO->countUnreadReadFavorites ();
$this->view->currentName = '';
$this->view->get_c = '';
@ -125,14 +117,14 @@ class FreshRSS_index_Controller extends Minz_ActionController {
$keepHistoryDefault = $this->view->conf->keep_history_default;
try {
$entries = $this->entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min, $keepHistoryDefault);
$entries = $entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min, $keepHistoryDefault);
// Si on a récupéré aucun article "non lus"
// on essaye de récupérer tous les articles
if ($state === 'not_read' && empty($entries)) {
Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG);
$this->view->state = 'all';
$entries = $this->entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, $keepHistoryDefault);
$entries = $entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, $keepHistoryDefault);
}
if (count($entries) <= $nb) {
@ -170,7 +162,8 @@ class FreshRSS_index_Controller extends Minz_ActionController {
case 'c':
$cat = isset($this->view->cat_aside[$getId]) ? $this->view->cat_aside[$getId] : null;
if ($cat === null) {
$cat = $this->catDAO->searchById ($getId);
$catDAO = new FreshRSS_CategoryDAO();
$cat = $catDAO->searchById($getId);
}
if ($cat) {
$this->view->currentName = $cat->name ();
@ -183,7 +176,8 @@ class FreshRSS_index_Controller extends Minz_ActionController {
case 'f':
$feed = FreshRSS_CategoryDAO::findFeed($this->view->cat_aside, $getId);
if (empty($feed)) {
$feed = $this->feedDAO->searchById ($getId);
$feedDAO = new FreshRSS_FeedDAO();
$feed = $feedDAO->searchById($getId);
}
if ($feed) {
$this->view->currentName = $feed->name ();
@ -198,6 +192,16 @@ class FreshRSS_index_Controller extends Minz_ActionController {
return false;
}
}
public function statsAction () {
$statsDAO = new FreshRSS_StatsDAO ();
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->feedByCategory = $statsDAO->calculateFeedByCategory();
$this->view->entryByCategory = $statsDAO->calculateEntryByCategory();
$this->view->topFeed = $statsDAO->calculateTopFeed();
}
public function aboutAction () {
Minz_View::prependTitle (Minz_Translate::t ('about') . ' · ');
@ -316,6 +320,8 @@ class FreshRSS_index_Controller extends Minz_ActionController {
} catch (Minz_Exception $me) {
Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING);
}
} else {
Minz_Log::record('Invalid credential parameters: user=' . $username . ' challenge=' . $c . ' nonce=' . $nonce, Minz_Log::DEBUG);
}
if (!$ok) {
$notif = array(

@ -37,7 +37,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController {
return; //Success
}
} catch (Minz_Exception $me) {
Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING);
Minz_Log::record('Nonce failure: ' . $me->getMessage(), Minz_Log::WARNING);
}
}
$this->view->nonce = ''; //Failure

@ -106,6 +106,7 @@ class FreshRSS_users_Controller extends Minz_ActionController {
}
$passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST));
$passwordPlain = '';
$passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js
$ok &= ($passwordHash != '');
}
if (empty($passwordHash)) {

@ -106,8 +106,8 @@ class FreshRSS extends Minz_FrontController {
private function loadParamsView () {
Minz_Session::_param ('language', $this->conf->language);
Minz_Translate::init();
$output = Minz_Request::param ('output');
if (!$output) {
$output = Minz_Request::param ('output', '');
if (($output === '') || ($output !== 'normal' && $output !== 'rss' && $output !== 'reader' && $output !== 'global')) {
$output = $this->conf->view_mode;
Minz_Request::_param ('output', $output);
}

@ -48,7 +48,7 @@ class FreshRSS_Configuration {
'bottomline_link' => true,
'sharing' => array(
'shaarli' => '',
'poche' => '',
'wallabag' => '',
'diaspora' => '',
'twitter' => true,
'g+' => true,
@ -185,7 +185,7 @@ class FreshRSS_Configuration {
}
}
public function _sharing ($values) {
$are_url = array ('shaarli', 'poche', 'diaspora');
$are_url = array ('shaarli', 'wallabag', 'diaspora');
foreach ($values as $key => $value) {
if (in_array($key, $are_url)) {
$is_url = (

@ -187,54 +187,12 @@ class FreshRSS_Feed extends Minz_Model {
Minz_Exception::ERROR
);
} else {
$feed = new SimplePie ();
$feed->set_useragent(Minz_Translate::t ('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION);
$url = htmlspecialchars_decode ($this->url, ENT_QUOTES);
if ($this->httpAuth != '') {
$url = preg_replace ('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url);
}
$feed = customSimplePie();
$feed->set_feed_url ($url);
$feed->set_cache_location (CACHE_PATH);
$feed->set_cache_duration(1500);
$feed->strip_htmltags (array (
'base', 'blink', 'body', 'doctype', 'embed',
'font', 'form', 'frame', 'frameset', 'html',
'input', 'marquee', 'meta', 'noscript',
'object', 'param', 'plaintext', 'script', 'style',
));
$feed->strip_attributes(array_merge($feed->strip_attributes, array(
'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup',
'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur',
'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless')));
$feed->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'),
));
$feed->set_url_replacements(array(
'a' => 'href',
'area' => 'href',
'audio' => 'src',
'blockquote' => 'cite',
'del' => 'cite',
'form' => 'action',
'iframe' => 'src',
'img' => array(
'longdesc',
'src'
),
'input' => 'src',
'ins' => 'cite',
'q' => 'cite',
'source' => 'src',
'track' => 'src',
'video' => array(
'poster',
'src',
),
));
$feed->init ();
if ($feed->error ()) {

@ -0,0 +1,205 @@
<?php
class FreshRSS_StatsDAO extends Minz_ModelPdo {
/**
* Calculates entry repartition for all feeds and for main stream.
* The repartition includes:
* - total entries
* - read entries
* - unread entries
* - favorite entries
*
* @return type
*/
public function calculateEntryRepartition() {
$repartition = array();
// Generates the repartition for the main stream of entry
$sql = <<<SQL
SELECT COUNT(1) AS `total`,
COUNT(1) - SUM(e.is_read) AS `unread`,
SUM(e.is_read) AS `read`,
SUM(e.is_favorite) AS `favorite`
FROM {$this->prefix}entry AS e
, {$this->prefix}feed AS f
WHERE e.id_feed = f.id
AND f.priority = 10
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
$repartition['main_stream'] = $res[0];
// Generates the repartition for all entries
$sql = <<<SQL
SELECT COUNT(1) AS `total`,
COUNT(1) - SUM(e.is_read) AS `unread`,
SUM(e.is_read) AS `read`,
SUM(e.is_favorite) AS `favorite`
FROM {$this->prefix}entry AS e
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
$repartition['all_feeds'] = $res[0];
return $repartition;
}
/**
* Calculates entry count per day on a 30 days period.
* Returns the result as a JSON string.
*
* @return string
*/
public function calculateEntryCount() {
$count = array();
// Generates a list of 30 last day to be sure we always have 30 days.
// If we do not do that kind of thing, we'll end up with holes in the
// days if the user do not have a lot of feeds.
$sql = <<<SQL
SELECT - (tens.val + units.val + 1) AS day
FROM (
SELECT 0 AS val
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
) AS units
CROSS JOIN (
SELECT 0 AS val
UNION ALL SELECT 10
UNION ALL SELECT 20
) AS tens
ORDER BY day ASC
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
foreach ($res as $value) {
$count[$value['day']] = 0;
}
// Get stats per day for the last 30 days and applies the result on
// the array created with the last query.
$sql = <<<SQL
SELECT DATEDIFF(FROM_UNIXTIME(e.date), NOW()) AS day,
COUNT(1) AS count
FROM {$this->prefix}entry AS e
WHERE FROM_UNIXTIME(e.date, '%Y%m%d') BETWEEN DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -30 DAY), '%Y%m%d') AND DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -1 DAY), '%Y%m%d')
GROUP BY day
ORDER BY day ASC
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
foreach ($res as $value) {
$count[$value['day']] = (int) $value['count'];
}
return $this->convertToSerie($count);
}
/**
* Calculates feed count per category.
* Returns the result as a JSON string.
*
* @return string
*/
public function calculateFeedByCategory() {
$sql = <<<SQL
SELECT c.name AS label
, COUNT(f.id) AS data
FROM {$this->prefix}category AS c,
{$this->prefix}feed AS f
WHERE c.id = f.category
GROUP BY label
ORDER BY data DESC
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
return $this->convertToPieSerie($res);
}
/**
* Calculates entry count per category.
* Returns the result as a JSON string.
*
* @return string
*/
public function calculateEntryByCategory() {
$sql = <<<SQL
SELECT c.name AS label
, COUNT(e.id) AS data
FROM {$this->prefix}category AS c,
{$this->prefix}feed AS f,
{$this->prefix}entry AS e
WHERE c.id = f.category
AND f.id = e.id_feed
GROUP BY label
ORDER BY data DESC
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
return $this->convertToPieSerie($res);
}
/**
* Calculates the 10 top feeds based on their number of entries
*
* @return array
*/
public function calculateTopFeed() {
$sql = <<<SQL
SELECT f.id AS id
, MAX(f.name) AS name
, MAX(c.name) AS category
, COUNT(e.id) AS count
FROM {$this->prefix}category AS c,
{$this->prefix}feed AS f,
{$this->prefix}entry AS e
WHERE c.id = f.category
AND f.id = e.id_feed
GROUP BY id
ORDER BY count DESC
LIMIT 10
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
return $stm->fetchAll(PDO::FETCH_ASSOC);
}
private function convertToSerie($data) {
$serie = array();
foreach ($data as $key => $value) {
$serie[] = array($key, $value);
}
return json_encode($serie);
}
private function convertToPieSerie($data) {
$serie = array();
foreach ($data as $value) {
$value['data'] = array(array(0, (int) $value['data']));
$serie[] = $value;
}
return json_encode($serie);
}
}

@ -11,8 +11,11 @@ return array (
'users' => 'Users',
'categories' => 'Categories',
'category' => 'Category',
'feed' => 'Feed',
'feeds' => 'Feeds',
'shortcuts' => 'Shortcuts',
'about' => 'About',
'stats' => 'Statistics',
'your_rss_feeds' => 'Your RSS feeds',
'add_rss_feed' => 'Add a RSS feed',
@ -20,7 +23,8 @@ return array (
'import_export_opml' => 'Import / export (OPML)',
'subscription_management' => 'Subscriptions management',
'all_feeds' => 'Main stream',
'main_stream' => 'Main stream',
'all_feeds' => 'All feeds',
'favorite_feeds' => 'Favourites (%d)',
'not_read' => '%d unread',
'not_reads' => '%d unread',
@ -157,7 +161,7 @@ return array (
'not_yet_implemented' => 'Not yet implemented',
'access_protected_feeds' => 'Connection allows to access HTTP protected RSS feeds',
'no_selected_feed' => 'No feed selected.',
'think_to_add' => '<a href="./?c=configure&amp;a=feed">Remember to add some RSS feeds!</a>',
'think_to_add' => '<a href="./?c=configure&amp;a=feed">You may add some feeds</a>.',
'current_user' => 'Current user',
'default_user' => 'Username of the default user <small>(maximum 16 alphanumeric characters)</small>',
@ -206,7 +210,7 @@ return array (
'scroll' => 'during page scrolls',
'upon_reception' => 'upon reception of the article',
'your_shaarli' => 'Your Shaarli',
'your_poche' => 'Your Poche',
'your_wallabag' => 'Your wallabag',
'your_diaspora_pod' => 'Your Diaspora* pod',
'sharing' => 'Sharing',
'share' => 'Share',
@ -217,7 +221,7 @@ return array (
'more_information' => 'More information',
'activate_sharing' => 'Activate sharing',
'shaarli' => 'Shaarli',
'poche' => 'Poche',
'wallabag' => 'wallabag',
'diaspora' => 'Diaspora*',
'twitter' => 'Twitter',
'g+' => 'Google+',
@ -232,7 +236,7 @@ return array (
'by' => 'by',
'load_more' => 'Load more articles',
'nothing_to_load' => 'There is no more articles',
'nothing_to_load' => 'There are no more articles',
'rss_feeds_of' => 'RSS feed of %s',
@ -241,9 +245,10 @@ return array (
'today' => 'Today',
'yesterday' => 'Yesterday',
'before_yesterday' => 'Before yesterday',
'new_article' => 'There are new available articles, click to refresh the page.',
'by_author' => 'By <em>%s</em>',
'related_tags' => 'Related tags',
'no_feed_to_display' => 'There is no feed to show yet.',
'no_feed_to_display' => 'There is no article to show.',
'about_freshrss' => 'About FreshRSS',
'project_website' => 'Project website',
@ -295,5 +300,17 @@ return array (
'Dec' => '\D\e\c\e\m\b\e\r',
// format for date() function, %s allows to indicate month in letter
'format_date' => '%s j\<\s\u\p\>S\<\/\s\u\p\> Y',
'format_date_hour' => '%s j\<\s\u\p\>S\<\/\s\u\p\> Y \a\t H\.i',
'format_date_hour' => '%s j\<\s\u\p\>S\<\/\s\u\p\> Y \a\t H\:i',
'status_favorites' => 'Favourites',
'status_read' => 'Read',
'status_unread' => 'Unread',
'status_total' => 'Total',
'stats_entry_repartition' => 'Entries repartition',
'stats_entry_per_day' => 'Entries per day (last 30 days)',
'stats_feed_per_category' => 'Feeds per category',
'stats_entry_per_category' => 'Entries per category',
'stats_top_feed' => 'Top ten feeds',
'stats_entry_count' => 'Entry count',
);

@ -11,8 +11,11 @@ return array (
'users' => 'Utilisateurs',
'categories' => 'Catégories',
'category' => 'Catégorie',
'feed' => 'Flux',
'feeds' => 'Flux',
'shortcuts' => 'Raccourcis',
'about' => 'À propos',
'stats' => 'Statistiques',
'your_rss_feeds' => 'Vos flux RSS',
'add_rss_feed' => 'Ajouter un flux RSS',
@ -20,7 +23,8 @@ return array (
'import_export_opml' => 'Importer / exporter (OPML)',
'subscription_management' => 'Gestion des abonnements',
'all_feeds' => 'Flux principal',
'main_stream' => 'Flux principal',
'all_feeds' => 'Tous les flux',
'favorite_feeds' => 'Favoris (%d)',
'not_read' => '%d non lu',
'not_reads' => '%d non lus',
@ -157,7 +161,7 @@ return array (
'not_yet_implemented' => 'Pas encore implémenté',
'access_protected_feeds' => 'La connexion permet d’accéder aux flux protégés par une authentification HTTP',
'no_selected_feed' => 'Aucun flux sélectionné.',
'think_to_add' => '<a href="./?c=configure&amp;a=feed">Pensez à en ajouter !</a>',
'think_to_add' => '<a href="./?c=configure&amp;a=feed">Vous pouvez ajouter des flux</a>.',
'current_user' => 'Utilisateur actuel',
'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
@ -206,7 +210,7 @@ return array (
'scroll' => 'au défilement de la page',
'upon_reception' => 'dès la réception du nouvel article',
'your_shaarli' => 'Votre Shaarli',
'your_poche' => 'Votre Poche',
'your_wallabag' => 'Votre wallabag',
'your_diaspora_pod' => 'Votre pod Diaspora*',
'sharing' => 'Partage',
'share' => 'Partager',
@ -217,7 +221,7 @@ return array (
'more_information' => 'Plus d’informations',
'activate_sharing' => 'Activer le partage',
'shaarli' => 'Shaarli',
'poche' => 'Poche',
'wallabag' => 'wallabag',
'diaspora' => 'Diaspora*',
'twitter' => 'Twitter',
'g+' => 'Google+',
@ -241,9 +245,10 @@ return array (
'today' => 'Aujourd’hui',
'yesterday' => 'Hier',
'before_yesterday' => 'À partir d’avant-hier',
'new_article' => 'Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.',
'by_author' => 'Par <em>%s</em>',
'related_tags' => 'Tags associés',
'no_feed_to_display' => 'Il n’y a aucun flux à afficher pour l’instant.',
'no_feed_to_display' => 'Il n’y a aucun article à afficher.',
'about_freshrss' => 'À propos de FreshRSS',
'project_website' => 'Site du projet',
@ -295,5 +300,17 @@ return array (
'Dec' => '\d\é\c\e\m\b\r\e',
// format pour la fonction date(), %s permet d'indiquer le mois en toutes lettres
'format_date' => 'j %s Y',
'format_date_hour' => '\l\e j %s Y \à H\:i',
'format_date_hour' => 'j %s Y \à H\:i',
'status_favorites' => 'favoris',
'status_read' => 'lus',
'status_unread' => 'non lus',
'status_total' => 'total',
'stats_entry_repartition' => 'Répartition des articles',
'stats_entry_per_day' => 'Nombre d’articles par jour (30 derniers jours)',
'stats_feed_per_category' => 'Flux par catégorie',
'stats_entry_per_category' => 'Articles par catégorie',
'stats_top_feed' => 'Les dix plus gros flux',
'stats_entry_count' => 'Nombre d’articles',
);

@ -58,6 +58,8 @@ return array (
'update_start' => 'Start update process',
'update_long' => 'This can take a long time, depending on the size of your database. You may have to wait for this page to time out (~5 minutes) and then refresh this page.',
'update_end' => 'Update process is completed, now you can go to the final step.',
'installation_is_ok' => 'The installation process was successful.<br />The final step will now attempt to delete the <kbd>./p/i/install.php</kbd> file and any database backup created during the update process.<br />You may choose to skip this step and delete <kbd>./p/i/install.php</kbd> manually.',
'finish_installation' => 'Complete installation',

@ -58,6 +58,7 @@ return array (
'update_start' => 'Lancer la mise à jour',
'update_long' => 'Ce processus peut prendre longtemps, selon la taille de votre base de données. Vous aurez peut-être à attendre que cette page dépasse son temps maximum d’exécution (~5 minutes) puis à la recharger.',
'update_end' => 'La mise à jour est terminée, vous pouvez maintenant passer à l’étape finale.',
'installation_is_ok' => 'L’installation s’est bien passée.<br />La dernière étape va maintenant tenter de supprimer le fichier <kbd>./p/i/install.php</kbd>, ainsi que d’éventuelles copies de base de données créées durant le processus de mise à jour.<br />Vous pouvez choisir de sauter cette étape et de supprimer <kbd>./p/i/install.php</kbd> manuellement.',
'finish_installation' => 'Terminer l’installation',

@ -1,8 +1,5 @@
<ul class="nav nav-list aside">
<li class="nav-header"><?php echo Minz_Translate::t ('configuration'); ?></li>
<li class="item<?php echo Minz_Request::actionName () == 'users' ? ' active' : ''; ?>">
<a href="<?php echo _url ('configure', 'users'); ?>"><?php echo Minz_Translate::t ('users'); ?></a>
</li>
<li class="item<?php echo Minz_Request::actionName () == 'display' ? ' active' : ''; ?>">
<a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a>
</li>
@ -15,4 +12,8 @@
<li class="item<?php echo Minz_Request::actionName () == 'shortcut' ? ' active' : ''; ?>">
<a href="<?php echo _url ('configure', 'shortcut'); ?>"><?php echo Minz_Translate::t ('shortcuts'); ?></a>
</li>
<li class="separator"></li>
<li class="item<?php echo Minz_Request::actionName () == 'users' ? ' active' : ''; ?>">
<a href="<?php echo _url ('configure', 'users'); ?>"><?php echo Minz_Translate::t ('users'); ?></a>
</li>
</ul>

@ -27,10 +27,10 @@
<li class="dropdown-header"><?php echo Minz_Translate::t ('http_authentication'); ?></li>
<li class="input">
<input type="text" name="http_user" id="http_user" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('username'); ?>" />
<input type="text" name="http_user" id="http_user_add" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('username'); ?>" />
</li>
<li class="input">
<input type="password" name="http_pass" id="http_pass" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('password'); ?>" />
<input type="password" name="http_pass" id="http_pass_add" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('password'); ?>" />
</li>
</ul>
</div>

@ -23,7 +23,7 @@
<div class="category all">
<a data-unread="<?php echo $this->nb_not_read; ?>" class="btn<?php echo $this->get_c == 'a' ? ' active' : ''; ?>" href="<?php echo Minz_Url::display($arUrl); ?>">
<?php echo FreshRSS_Themes::icon('all'); ?>
<?php echo Minz_Translate::t ('all_feeds'); ?>
<?php echo Minz_Translate::t ('main_stream'); ?>
</a>
</div>
</li>

@ -36,7 +36,7 @@ if (Minz_Configuration::canLogIn()) {
<form action="<?php echo _url ('index', 'index'); ?>" method="get">
<div class="stick">
<?php $search = Minz_Request::param ('search', ''); ?>
<input type="search" name="search" id="search" value="<?php echo $search; ?>" placeholder="<?php echo Minz_Translate::t ('search'); ?>" />
<input type="search" name="search" id="search" class="extend" value="<?php echo $search; ?>" placeholder="<?php echo Minz_Translate::t ('search'); ?>" />
<?php $get = Minz_Request::param ('get', ''); ?>
<?php if($get != '') { ?>
@ -67,12 +67,14 @@ if (Minz_Configuration::canLogIn()) {
<ul class="dropdown-menu">
<li class="dropdown-close"><a href="#close"></a></li>
<li class="dropdown-header"><?php echo Minz_Translate::t ('configuration'); ?></li>
<li class="item"><a href="<?php echo _url ('configure', 'users'); ?>"><?php echo Minz_Translate::t ('users'); ?></a></li>
<li class="item"><a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a></li>
<li class="item"><a href="<?php echo _url ('configure', 'archiving'); ?>"><?php echo Minz_Translate::t ('archiving_configuration'); ?></a></li>
<li class="item"><a href="<?php echo _url ('configure', 'sharing'); ?>"><?php echo Minz_Translate::t ('sharing'); ?></a></li>
<li class="item"><a href="<?php echo _url ('configure', 'shortcut'); ?>"><?php echo Minz_Translate::t ('shortcuts'); ?></a></li>
<li class="separator"></li>
<li class="item"><a href="<?php echo _url ('configure', 'users'); ?>"><?php echo Minz_Translate::t ('users'); ?></a></li>
<li class="separator"></li>
<li class="item"><a href="<?php echo _url ('index', 'stats'); ?>"><?php echo Minz_Translate::t ('stats'); ?></a></li>
<li class="item"><a href="<?php echo _url ('index', 'about'); ?>"><?php echo Minz_Translate::t ('about'); ?></a></li>
<li class="item"><a href="<?php echo _url ('index', 'logs'); ?>"><?php echo Minz_Translate::t ('logs'); ?></a></li>
<?php

@ -28,7 +28,7 @@
<meta name="msapplication-TileColor" content="#FFF" />
<meta name="robots" content="noindex,nofollow" />
</head>
<body>
<body class="<?php echo Minz_Request::param('output', 'normal'); ?>">
<?php $this->partial ('header'); ?>
<div id="global">

@ -1,5 +1,10 @@
<?php
$actual_view = Minz_Request::param('output', 'normal');
?>
<div class="nav_menu">
<?php if ($actual_view === 'normal') { ?>
<a class="btn toggle_aside" href="#aside_flux"><?php echo FreshRSS_Themes::icon('category'); ?></a>
<?php } ?>
<?php if ($this->loginOk) { ?>
<a id="actualize" class="btn" href="<?php echo _url ('feed', 'actualize'); ?>"><?php echo FreshRSS_Themes::icon('refresh'); ?></a>
@ -107,9 +112,7 @@
<?php
$url_output = $url;
$actual_view = Minz_Request::param('output', 'normal');
?>
<?php if($actual_view !== 'normal') { ?>
if ($actual_view !== 'normal') { ?>
<li class="item">
<?php $url_output['params']['output'] = 'normal'; ?>
<a class="view_normal" href="<?php echo Minz_Url::display ($url_output); ?>">
@ -202,7 +205,7 @@
<div class="item search">
<form action="<?php echo _url ('index', 'index'); ?>" method="get">
<?php $search = Minz_Request::param ('search', ''); ?>
<input type="search" name="search" value="<?php echo $search; ?>" placeholder="<?php echo Minz_Translate::t ('search_short'); ?>" />
<input type="search" name="search" class="extend" value="<?php echo $search; ?>" placeholder="<?php echo Minz_Translate::t ('search_short'); ?>" />
<?php $get = Minz_Request::param ('get', ''); ?>
<?php if($get != '') { ?>

@ -39,7 +39,7 @@
<div class="form-group">
<p class="group-name"><?php echo Minz_Translate::t('current_user'); ?></p>
<div class="group-controls">
<p><?php echo $this->nb_total, ' ', Minz_Translate::t('articles'), ', ', formatBytes($this->size_user); ?></p>
<p><?php echo formatNumber($this->nb_total), ' ', Minz_Translate::t('articles'), ', ', formatBytes($this->size_user); ?></p>
<input type="hidden" name="optimiseDatabase" value="1" />
<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('optimize_bdd'); ?></button>
<?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('optimize_todo_sometimes'); ?>

@ -21,14 +21,17 @@
<div class="form-group">
<label class="group-name" for="theme"><?php echo Minz_Translate::t ('theme'); ?></label>
<div class="group-controls">
<select name="theme" id="theme" required="">
<option></option>
<?php foreach ($this->themes as $theme) { ?>
<option value="<?php echo $theme['id']; ?>"<?php echo $this->conf->theme === $theme['id'] ? ' selected="selected"' : ''; ?>>
<?php echo $theme['name'] . ' — ' . Minz_Translate::t ('by') . ' ' . $theme['author']; ?>
</option>
<?php } ?>
</select>
<select name="theme" id="theme" required=""><?php
$found = false;
foreach ($this->themes as $theme) {
?><option value="<?php echo $theme['id']; ?>"<?php if ($this->conf->theme === $theme['id']) { echo ' selected="selected"'; $found = true; } ?>><?php
echo $theme['name'] . ' — ' . Minz_Translate::t ('by') . ' ' . $theme['author'];
?></option><?php
}
if (!$found) {
?><option selected="selected"></option><?php
}
?></select>
</div>
</div>

@ -16,26 +16,26 @@
<div class="form-group">
<label class="group-name" for="name"><?php echo Minz_Translate::t ('title'); ?></label>
<div class="group-controls">
<input type="text" name="name" id="name" value="<?php echo $this->flux->name () ; ?>" />
<input type="text" name="name" id="name" class="extend" value="<?php echo $this->flux->name () ; ?>" />
</div>
</div>
<div class="form-group">
<label class="group-name"><?php echo Minz_Translate::t ('feed_description'); ?></label>
<label class="group-name" for="description"><?php echo Minz_Translate::t ('feed_description'); ?></label>
<div class="group-controls">
<textarea name="description" id="description"><?php echo htmlspecialchars($this->flux->description(), ENT_NOQUOTES, 'UTF-8'); ?></textarea>
</div>
</div>
<div class="form-group">
<label class="group-name"><?php echo Minz_Translate::t ('website_url'); ?></label>
<label class="group-name" for="website"><?php echo Minz_Translate::t ('website_url'); ?></label>
<div class="group-controls">
<input type="text" name="website" id="website" value="<?php echo $this->flux->website (); ?>" />
<input type="text" name="website" id="website" class="extend" value="<?php echo $this->flux->website (); ?>" />
<a target="_blank" href="<?php echo $this->flux->website (); ?>"><?php echo FreshRSS_Themes::icon('link'); ?></a>
</div>
</div>
<div class="form-group">
<label class="group-name"><?php echo Minz_Translate::t ('feed_url'); ?></label>
<label class="group-name" for="url"><?php echo Minz_Translate::t ('feed_url'); ?></label>
<div class="group-controls">
<input type="text" name="url" id="url" value="<?php echo $this->flux->url (); ?>" />
<input type="text" name="url" id="url" class="extend" value="<?php echo $this->flux->url (); ?>" />
<a target="_blank" href="<?php echo $this->flux->url (); ?>"><?php echo FreshRSS_Themes::icon('link'); ?></a>
  <a class="btn" target="_blank" href="http://validator.w3.org/feed/check.cgi?url=<?php echo $this->flux->url (); ?>"><?php echo Minz_Translate::t ('feed_validator'); ?></a>
</div>
@ -106,13 +106,13 @@
<div class="form-group">
<label class="group-name" for="http_user"><?php echo Minz_Translate::t ('http_username'); ?></label>
<div class="group-controls">
<input type="text" name="http_user" id="http_user" value="<?php echo $auth['username']; ?>" autocomplete="off" />
<input type="text" name="http_user" id="http_user" class="extend" value="<?php echo $auth['username']; ?>" autocomplete="off" />
<?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t ('access_protected_feeds'); ?>
</div>
<label class="group-name" for="http_pass"><?php echo Minz_Translate::t ('http_password'); ?></label>
<div class="group-controls">
<input type="password" name="http_pass" id="http_pass" value="<?php echo $auth['password']; ?>" autocomplete="off" />
<input type="password" name="http_pass" id="http_pass" class="extend" value="<?php echo $auth['password']; ?>" autocomplete="off" />
</div>
</div>
@ -127,7 +127,7 @@
<div class="form-group">
<label class="group-name" for="path_entries"><?php echo Minz_Translate::t ('css_path_on_website'); ?></label>
<div class="group-controls">
<input type="text" name="path_entries" id="path_entries" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" />
<input type="text" name="path_entries" id="path_entries" class="extend" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" />
<?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t ('retrieve_truncated_feeds'); ?>
</div>
</div>

@ -10,20 +10,20 @@
<?php echo Minz_Translate::t ('your_shaarli'); ?>
</label>
<div class="group-controls">
<input type="url" id="shaarli" name="shaarli" value="<?php echo $this->conf->sharing ('shaarli'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<input type="url" id="shaarli" name="shaarli" class="extend" value="<?php echo $this->conf->sharing ('shaarli'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<?php echo FreshRSS_Themes::icon('help'); ?> <a target="_blank" href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli"><?php echo Minz_Translate::t ('more_information'); ?></a>
</div>
</div>
<div class="form-group">
<label class="group-name" for="poche">
<?php echo Minz_Translate::t ('your_poche'); ?>
<label class="group-name" for="wallabag">
<?php echo Minz_Translate::t ('your_wallabag'); ?>
</label>
<div class="group-controls">
<input type="url" id="poche" name="poche" value="<?php echo $this->conf->sharing ('poche'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<input type="url" id="wallabag" name="wallabag" class="extend" value="<?php echo $this->conf->sharing ('wallabag'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<?php echo FreshRSS_Themes::icon('help'); ?> <a target="_blank" href="http://www.inthepoche.com/"><?php echo Minz_Translate::t ('more_information'); ?></a>
<?php echo FreshRSS_Themes::icon('help'); ?> <a target="_blank" href="http://www.wallabag.org"><?php echo Minz_Translate::t ('more_information'); ?></a>
</div>
</div>
@ -32,7 +32,7 @@
<?php echo Minz_Translate::t ('your_diaspora_pod'); ?>
</label>
<div class="group-controls">
<input type="url" id="diaspora" name="diaspora" value="<?php echo $this->conf->sharing ('diaspora'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<input type="url" id="diaspora" name="diaspora" class="extend" value="<?php echo $this->conf->sharing ('diaspora'); ?>" placeholder="<?php echo Minz_Translate::t ('blank_to_disable'); ?>" size="64" />
<?php echo FreshRSS_Themes::icon('help'); ?> <a target="_blank" href="https://diasporafoundation.org/"><?php echo Minz_Translate::t ('more_information'); ?></a>
</div>

@ -29,7 +29,7 @@
<label class="group-name" for="mail_login"><?php echo Minz_Translate::t('persona_connection_email'); ?></label>
<?php $mail = $this->conf->mail_login; ?>
<div class="group-controls">
<input type="email" id="mail_login" name="mail_login" value="<?php echo $mail; ?>" <?php echo Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_')) ? '' : 'disabled="disabled"'; ?> placeholder="alice@example.net" />
<input type="email" id="mail_login" name="mail_login" class="extend" value="<?php echo $mail; ?>" <?php echo Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_')) ? '' : 'disabled="disabled"'; ?> placeholder="alice@example.net" />
<noscript><b><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></b></noscript>
</div>
</div>
@ -49,7 +49,9 @@
<label class="group-name" for="auth_type"><?php echo Minz_Translate::t('auth_type'); ?></label>
<div class="group-controls">
<select id="auth_type" name="auth_type" required="required">
<option value=""></option>
<?php if (!in_array(Minz_Configuration::authType(), array('form', 'persona', 'http_auth', 'none'))) { ?>
<option selected="selected"></option>
<?php } ?>
<option value="form"<?php echo Minz_Configuration::authType() === 'form' ? ' selected="selected"' : '', version_compare(PHP_VERSION, '5.3', '<') ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('auth_form'); ?></option>
<option value="persona"<?php echo Minz_Configuration::authType() === 'persona' ? ' selected="selected"' : '', $this->conf->mail_login == '' ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('auth_persona'); ?></option>
<option value="http_auth"<?php echo Minz_Configuration::authType() === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('http_auth'); ?> (REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
@ -143,7 +145,7 @@
<label class="group-name" for="new_user_email"><?php echo Minz_Translate::t('persona_connection_email'); ?></label>
<?php $mail = $this->conf->mail_login; ?>
<div class="group-controls">
<input type="email" id="new_user_email" name="new_user_email" placeholder="alice@example.net" />
<input type="email" id="new_user_email" name="new_user_email" class="extend" placeholder="alice@example.net" />
</div>
</div>

@ -9,11 +9,11 @@ if (!empty($this->entries)) {
$display_others = true;
if ($this->loginOk) {
$shaarli = $this->conf->sharing ('shaarli');
$poche = $this->conf->sharing ('poche');
$wallabag = $this->conf->sharing ('wallabag');
$diaspora = $this->conf->sharing ('diaspora');
} else {
$shaarli = '';
$poche = '';
$wallabag = '';
$diaspora = '';
}
$twitter = $this->conf->sharing ('twitter');
@ -30,7 +30,7 @@ if (!empty($this->entries)) {
$bottomline_read = $this->conf->bottomline_read;
$bottomline_favorite = $this->conf->bottomline_favorite;
$bottomline_sharing = $this->conf->bottomline_sharing && (
$shaarli || $poche || $diaspora || $twitter ||
$shaarli || $wallabag || $diaspora || $twitter ||
$google_plus || $facebook || $email || $print);
$bottomline_tags = $this->conf->bottomline_tags;
$bottomline_date = $this->conf->bottomline_date;
@ -38,6 +38,9 @@ if (!empty($this->entries)) {
?>
<div id="stream" class="normal<?php echo $hidePosts ? ' hide_posts' : ''; ?>"><?php
?><div id="new-article">
<a href="<?php echo _url('index', 'index'); ?>"><?php echo Minz_Translate::t ('new_article'); ?></a>
</div><?php
foreach ($this->entries as $item) {
if ($display_today && $item->isDay (FreshRSS_Days::TODAY, $this->today)) {
?><div class="day" id="day_today"><?php
@ -62,7 +65,6 @@ if (!empty($this->entries)) {
?></div><?php
$display_others = false;
}
?><div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>">
<ul class="horizontal-list flux_header"><?php
if ($this->loginOk) {
@ -150,10 +152,10 @@ if (!empty($this->entries)) {
<?php echo Minz_Translate::t ('shaarli'); ?>
</a>
</li>
<?php } if ($poche) { ?>
<?php } if ($wallabag) { ?>
<li class="item">
<a target="_blank" href="<?php echo $poche . '?action=add&amp;url=' . base64_encode (urldecode($link)); ?>">
<?php echo Minz_Translate::t ('poche'); ?>
<a target="_blank" href="<?php echo $wallabag . '?action=add&amp;url=' . base64_encode (urldecode($link)); ?>">
<?php echo Minz_Translate::t ('wallabag'); ?>
</a>
</li>
<?php } if ($diaspora) { ?>

@ -1,5 +1,4 @@
<div class="post content">
<div class="prompt">
<?php
if (Minz_Configuration::canLogIn()) {
?><h1><?php echo Minz_Translate::t('login'); ?></h1><?php
@ -7,25 +6,17 @@ if (Minz_Configuration::canLogIn()) {
case 'form':
?><form id="loginForm" method="post" action="<?php echo _url('index', 'formLogin'); ?>">
<div class="form-group">
<label class="group-name" for="username"><?php echo Minz_Translate::t('username'); ?></label>
<div class="group-controls">
<input type="text" id="username" name="username" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" autofocus="autofocus" />
</div>
</div>
<div class="form-group">
<label class="group-name" for="passwordPlain"><?php echo Minz_Translate::t('password'); ?></label>
<div class="group-controls">
<p>
<label for="username"><?php echo Minz_Translate::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" />
</p><p>
<label for="passwordPlain"><?php echo Minz_Translate::t('password'); ?></label>
<input type="password" id="passwordPlain" required="required" />
<input type="hidden" id="challenge" name="challenge" />
<input type="hidden" id="challenge" name="challenge" /><br />
<noscript><strong><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></strong></noscript>
</div>
</div>
<div class="form-group form-actions">
<div class="group-controls">
<button id="loginButton" type="submit" class="btn btn-important"><?php echo Minz_Translate::t('login'); ?></button>
</div>
</div>
</p><p>
<button id="loginButton" type="submit" class="btn btn-important"><?php echo Minz_Translate::t('login'); ?></button>
</p>
</form><?php
break;
@ -39,5 +30,5 @@ if (Minz_Configuration::canLogIn()) {
}
?>
<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 Minz_Translate::t('about_freshrss'); ?></a></p>
</div>

@ -12,6 +12,8 @@ if ($this->loginOk || Minz_Configuration::allowAnonymous()) {
} elseif ($output === 'global') {
$this->renderHelper ('view/global_view');
} else {
Minz_Request::_param ('output', 'normal');
$output = 'normal';
$this->renderHelper ('view/normal_view');
}
} elseif ($output === 'rss') {

@ -0,0 +1,125 @@
<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'); ?></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 $this->repartition['main_stream']['total']?></td>
<td class="numeric"><?php echo $this->repartition['all_feeds']['total']?></td>
</tr>
<tr>
<th><?php echo Minz_Translate::t ('status_read')?></th>
<td class="numeric"><?php echo $this->repartition['main_stream']['read']?></td>
<td class="numeric"><?php echo $this->repartition['all_feeds']['read']?></td>
</tr>
<tr>
<th><?php echo Minz_Translate::t ('status_unread')?></th>
<td class="numeric"><?php echo $this->repartition['main_stream']['unread']?></td>
<td class="numeric"><?php echo $this->repartition['all_feeds']['unread']?></td>
</tr>
<tr>
<th><?php echo Minz_Translate::t ('status_favorites')?></th>
<td class="numeric"><?php echo $this->repartition['main_stream']['favorite']?></td>
<td class="numeric"><?php echo $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 $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 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 + ' - '+ 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 + ' - '+ obj.y + ' ('+ (obj.fraction * 100).toFixed(1) + '%)';}},
legend: {container: document.getElementById('statsEntryPerCategoryLegend'), noColumns: 3}
});
}
initStats();
</script>

@ -69,8 +69,24 @@ class Minz_Configuration {
public static function salt () {
return self::$salt;
}
public static function environment () {
return self::$environment;
public static function environment ($str = false) {
$env = self::$environment;
if ($str) {
switch (self::$environment) {
case self::SILENT:
$env = 'silent';
break;
case self::DEVELOPMENT:
$env = 'development';
break;
case self::PRODUCTION:
default:
$env = 'production';
}
}
return $env;
}
public static function baseUrl () {
return self::$base_url;
@ -147,7 +163,7 @@ class Minz_Configuration {
public static function writeFile() {
$ini_array = array(
'general' => array(
'environment' => self::$environment,
'environment' => self::environment(true),
'use_url_rewriting' => self::$use_url_rewriting,
'salt' => self::$salt,
'base_url' => self::$base_url,
@ -205,23 +221,26 @@ class Minz_Configuration {
if (isset ($general['environment'])) {
switch ($general['environment']) {
case Minz_Configuration::SILENT:
case 'silent':
self::$environment = Minz_Configuration::SILENT;
break;
case Minz_Configuration::DEVELOPMENT:
case 'development':
self::$environment = Minz_Configuration::DEVELOPMENT;
break;
case Minz_Configuration::PRODUCTION:
case 'production':
self::$environment = Minz_Configuration::PRODUCTION;
break;
default:
throw new Minz_BadConfigurationException (
'environment',
Minz_Exception::ERROR
);
if ($general['environment'] >= 0 &&
$general['environment'] <= 2) {
// fallback 0.7-beta
self::$environment = $general['environment'];
} else {
throw new Minz_BadConfigurationException (
'environment',
Minz_Exception::ERROR
);
}
}
}

@ -21,7 +21,7 @@ class Minz_Error {
*/
public static function error ($code = 404, $logs = array (), $redirect = false) {
$logs = self::processLogs ($logs);
$error_filename = APP_PATH . '/Controllers/ErrorController.php';
$error_filename = APP_PATH . '/Controllers/errorController.php';
if (file_exists ($error_filename)) {
$params = array (

@ -62,6 +62,11 @@ function small_hash ($txt) {
return strtr ($t, '+/', '-_');
}
function formatNumber($n, $precision = 0) {
return str_replace(' ', '&#8239;', //Espace fine insécable
number_format($n, $precision, '.', ' ')); //number_format does not seem to be Unicode-compatible
}
function formatBytes($bytes, $precision = 2, $system = 'IEC') {
if ($system === 'IEC') {
$base = 1024;
@ -74,7 +79,7 @@ function formatBytes($bytes, $precision = 2, $system = 'IEC') {
$pow = $bytes === 0 ? 0 : floor(log($bytes) / log($base));
$pow = min($pow, count($units) - 1);
$bytes /= pow($base, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
return formatNumber($bytes, $precision) . ' ' . $units[$pow];
}
function timestamptodate ($t, $hour = true) {
@ -106,13 +111,59 @@ function html_only_entity_decode($text) {
return strtr($text, $htmlEntitiesOnly);
}
function sanitizeHTML($data) {
function customSimplePie() {
$simplePie = new SimplePie();
$simplePie->set_useragent(Minz_Translate::t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION);
$simplePie->set_cache_location(CACHE_PATH);
$simplePie->set_cache_duration(1500);
$simplePie->strip_htmltags(array(
'base', 'blink', 'body', 'doctype', 'embed',
'font', 'form', 'frame', 'frameset', 'html',
'link', 'input', 'marquee', 'meta', 'noscript',
'object', 'param', 'plaintext', 'script', 'style',
));
$simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array(
'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup',
'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'),
));
$simplePie->set_url_replacements(array(
'a' => 'href',
'area' => 'href',
'audio' => 'src',
'blockquote' => 'cite',
'del' => 'cite',
'form' => 'action',
'iframe' => 'src',
'img' => array(
'longdesc',
'src'
),
'input' => 'src',
'ins' => 'cite',
'q' => 'cite',
'source' => 'src',
'track' => 'src',
'video' => array(
'poster',
'src',
),
));
return $simplePie;
}
function sanitizeHTML($data, $base = '') {
static $simplePie = null;
if ($simplePie == null) {
$simplePie = new SimplePie();
$simplePie = customSimplePie();
$simplePie->init();
}
return html_only_entity_decode($simplePie->sanitize->sanitize($data, SIMPLEPIE_CONSTRUCT_MAYBE_HTML));
return html_only_entity_decode($simplePie->sanitize->sanitize($data, SIMPLEPIE_CONSTRUCT_HTML, $base));
}
/* permet de récupérer le contenu d'un article pour un flux qui n'est pas complet */
@ -125,7 +176,7 @@ function get_content_by_parsing ($url, $path) {
if ($html) {
$doc = phpQuery::newDocument ($html);
$content = $doc->find ($path);
return sanitizeHTML($content->__toString());
return sanitizeHTML($content->__toString(), $url);
} else {
throw new Exception ();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 18 KiB

@ -4,7 +4,7 @@ if (function_exists('opcache_reset')) {
}
require('../../constants.php');
const BCRYPT_COST = 9;
define('BCRYPT_COST', 9);
include(LIB_PATH . '/lib_rss.php');
@ -87,6 +87,8 @@ SET f.cache_nbEntries=x.nbEntries, f.cache_nbUnreads=x.nbUnreads
');
define('SQL_UPDATE_HISTORYv007b', 'UPDATE `%1$sfeed` SET keep_history = CASE WHEN keep_history = 0 THEN -2 WHEN keep_history = 1 THEN -1 ELSE keep_history END;');
define('SQL_GET_FEEDS', 'SELECT id, url, website FROM `%1$sfeed`;');
//</updates>
// gestion internationalisation
@ -170,6 +172,9 @@ function saveStep2 () {
$_SESSION['default_user'] = substr(preg_replace('/[^a-zA-Z0-9]/', '', $_POST['default_user']), 0, 16);
$_SESSION['auth_type'] = $_POST['auth_type'];
if (!empty($_POST['passwordPlain'])) {
if (!function_exists('password_hash')) {
include_once(LIB_PATH . '/password_compat.php');
}
$passwordHash = password_hash($_POST['passwordPlain'], PASSWORD_BCRYPT, array('cost' => BCRYPT_COST));
$passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js
$_SESSION['passwordHash'] = $passwordHash;
@ -307,14 +312,6 @@ function updateDatabase($perform = false) {
$stm->execute();
}
$sql = sprintf(SQL_UPDATE_HISTORYv007b, $_SESSION['bd_prefix_user']);
$stm = $c->prepare($sql);
$stm->execute();
$sql = sprintf(SQL_UPDATE_CACHED_VALUES, $_SESSION['bd_prefix_user']);
$stm = $c->prepare($sql);
$stm->execute();
$sql = sprintf(SQL_CONVERT_SELECTv006, $_SESSION['bd_prefix'], $_SESSION['bd_prefix_user']);
if (!$perform) {
$sql .= ' LIMIT 1';
@ -336,6 +333,7 @@ function updateDatabase($perform = false) {
$content = unserialize(gzinflate(base64_decode($row['content'])));
$stm2->execute(array($content, $id));
}
return true;
} catch (PDOException $e) {
return false;
@ -343,6 +341,51 @@ function updateDatabase($perform = false) {
return false;
}
function newPdo() {
switch ($_SESSION['bd_type']) {
case 'mysql':
$str = 'mysql:host=' . $_SESSION['bd_host'] . ';dbname=' . $_SESSION['bd_base'];
$driver_options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
break;
case 'sqlite':
$str = 'sqlite:' . DATA_PATH . $_SESSION['bd_base'] . '.sqlite';
$driver_options = null;
break;
default:
return false;
}
return new PDO($str, $_SESSION['bd_user'], $_SESSION['bd_password'], $driver_options);
}
function postUpdate() {
$c = newPdo();
$sql = sprintf(SQL_UPDATE_HISTORYv007b, $_SESSION['bd_prefix_user']);
$stm = $c->prepare($sql);
$stm->execute();
$sql = sprintf(SQL_UPDATE_CACHED_VALUES, $_SESSION['bd_prefix_user']);
$stm = $c->prepare($sql);
$stm->execute();
//<favicons>
$sql = sprintf(SQL_GET_FEEDS, $_SESSION['bd_prefix_user']);
$stm = $c->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
foreach ($res as $feed) {
if (empty($feed['url'])) {
continue;
}
$hash = hash('crc32b', $_SESSION['salt'] . $feed['url']);
@file_put_contents(DATA_PATH . '/favicons/' . $hash . '.txt',
empty($feed['website']) ? $feed['url'] : $feed['website']);
}
//</favicons>
}
function deleteInstall () {
$res = unlink (INDEX_PATH . '/install.php');
if ($res) {
@ -357,22 +400,7 @@ function deleteInstall () {
}
try {
switch ($_SESSION['bd_type']) {
case 'mysql':
$str = 'mysql:host=' . $_SESSION['bd_host'] . ';dbname=' . $_SESSION['bd_base'];
$driver_options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
break;
case 'sqlite':
$str = 'sqlite:' . DATA_PATH . $_SESSION['bd_base'] . '.sqlite';
$driver_options = null;
break;
default:
return false;
}
$c = new PDO($str, $_SESSION['bd_user'], $_SESSION['bd_password'], $driver_options);
$c = newPdo();
$sql = sprintf(SQL_DROP_BACKUPv006, $_SESSION['bd_prefix']);
$stm = $c->prepare($sql);
$stm->execute();
@ -805,7 +833,9 @@ function printStep2 () {
<label class="group-name" for="auth_type"><?php echo _t('auth_type'); ?></label>
<div class="group-controls">
<select id="auth_type" name="auth_type" required="required">
<option value=""></option>
<?php if (!in_array($_SESSION['auth_type'], array('form', 'persona', 'http_auth', 'none'))) { ?>
<option selected="selected"></option>
<?php } ?>
<option value="form"<?php echo $_SESSION['auth_type'] === 'form' ? ' selected="selected"' : '', version_compare(PHP_VERSION, '5.3', '<') ? ' disabled="disabled"' : ''; ?>><?php echo _t('auth_form'); ?></option>
<option value="persona"<?php echo $_SESSION['auth_type'] === 'persona' ? ' selected="selected"' : ''; ?>><?php echo _t('auth_persona'); ?></option>
<option value="http_auth"<?php echo $_SESSION['auth_type'] === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('http_auth'); ?> (REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
@ -922,17 +952,26 @@ function printStep4 () {
?>
<form action="index.php?step=4" method="post">
<legend><?php echo _t ('version_update'); ?></legend>
<?php if (updateDatabase(false)) { ?>
<p class="alert"><?php echo _t ('update_long'); ?></p>
<div class="form-group form-actions">
<div class="group-controls">
<?php if (updateDatabase(false)) { ?>
<input type="hidden" name="updateDatabase" value="1" />
<button type="submit" class="btn btn-important"><?php echo _t ('update_start'); ?></button>
<p><?php echo _t ('update_long'); ?></p>
<?php } else { ?>
</div>
</div>
<?php } else { ?>
<p class="alert"><?php echo _t ('update_end'); ?></p>
<div class="form-group form-actions">
<div class="group-controls">
<a class="btn btn-important next-step" href="?step=5"><?php echo _t ('next_step'); ?></a>
<?php } ?>
</div>
</div>
<?php } ?>
</form>
<?php
}
@ -973,6 +1012,7 @@ case 4:
}
break;
case 5:
postUpdate();
break;
case 6:
deleteInstall ();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -59,14 +59,18 @@ function incUnreadsFeed(article, feed_id, nb) {
}
}
var isCurrentView = false;
//Update unread: title
document.title = document.title.replace(/((?: \(\d+\))?)( · .*?)((?: \(\d+\))?)$/, function (m, p1, p2, p3) {
if (article || ($('#' + feed_id).closest('.active').length > 0)) {
var $feed = $('#' + feed_id);
if (article || ($feed.closest('.active').length > 0 && $feed.siblings('.active').length === 0)) {
isCurrentView = true;
return incLabel(p1, nb) + p2 + incLabel(p3, feed_priority > 0 ? nb : 0);
} else {
return p1 + p2 + incLabel(p3, feed_priority > 0 ? nb : 0);
}
});
return isCurrentView;
}
function mark_read(active, only_not_read) {
@ -519,11 +523,15 @@ function init_notifications() {
function refreshUnreads() {
$.getJSON('./?c=javascript&a=nbUnreadsPerFeed').done(function (data) {
var isAll = $('.category.all > .active').length > 0;
$.each(data, function(feed_id, nbUnreads) {
feed_id = 'f_' + feed_id;
var elem = $('#' + feed_id + '>.feed').get(0),
feed_unreads = elem ? (parseInt(elem.getAttribute('data-unread'), 10) || 0) : 0;
incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads);
if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && //Update of current view?
(nbUnreads - feed_unreads > 0)) {
$('#new-article').show();
};
});
});
}
@ -618,14 +626,18 @@ function init_loginForm() {
if (data.salt1 == '' || data.nonce == '') {
alert('Invalid user!');
} else {
var strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'),
s = dcodeIO.bcrypt.hashSync($('#passwordPlain').val(), data.salt1),
c = dcodeIO.bcrypt.hashSync(data.nonce + s, strong ? 4 : poormanSalt());
$('#challenge').val(c);
if (s == '' || c == '') {
alert('Crypto error!');
} else {
success = true;
try {
var strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'),
s = dcodeIO.bcrypt.hashSync($('#passwordPlain').val(), data.salt1),
c = dcodeIO.bcrypt.hashSync(data.nonce + s, strong ? 4 : poormanSalt());
$('#challenge').val(c);
if (s == '' || c == '') {
alert('Crypto error!');
} else {
success = true;
}
} catch (e) {
alert('Crypto exception! ' + e);
}
}
}).fail(function() {

@ -31,7 +31,6 @@
}
.header > .item.search input {
width: 230px;
transition: width 200ms linear;
}
.header .item.search input:focus {
width: 330px;
@ -201,10 +200,9 @@
font-weight: bold;
line-height: 50px;
background: #1c1c1c;
border-top: 1px solid #888;
border-bottom: 1px solid #888;
border-top: 1px solid #2f2f2f;
}
.day:first-child {
#new-article + .day {
border-top: none;
}
.day .name {
@ -224,8 +222,27 @@
text-align: right;
}
#new-article {
display: none;
min-height: 40px;
background: #26303F;
text-align: center;
}
#new-article:hover {
background: #4A5D7A;
}
#new-article > a {
display: block;
line-height: 40px;
color: #fff;
font-weight: bold;
}
#new-article > a:hover {
text-decoration: none;
}
.flux {
border-left: 3px solid #aaa;
border-left: 3px solid #2f2f2f;
background: #1c1c1c;
}
.flux.not_read {
@ -241,6 +258,10 @@
background: #1a1a1a;
}
.horizontal-list > .item:not(.title):not(.website) > a {
display: block;
}
.flux_header {
background: inherit;
height: 25px;
@ -268,11 +289,6 @@
}
.flux .item.title {
background: inherit;
}
.flux:hover .item.title {
border-right: 2px solid rgba(127, 127, 127, 0.1);
padding-right: 1em;
position: absolute;
}
.flux .item.title a {
color: #888;
@ -283,7 +299,7 @@
font-weight: bold;
}
.flux .item.date {
width: 200px;
width: 145px;
padding:0 5px 0 0;
text-align: right;
font-size: 10px;
@ -652,6 +668,14 @@ select.number option {
text-align:right;
}
@media(min-width: 841px) {
.flux:not(.current):hover .item.title {
max-width: calc(100% - 580px);
padding-right: 1.5em;
position: absolute;
}
}
@media(max-width: 840px) {
.header,
.aside .btn-important,
@ -672,11 +696,6 @@ select.number option {
display: block;
}
.content {
font-size: 120%;
padding: 0;
}
.pagination {
margin: 0 0 40px;
}
@ -801,16 +820,12 @@ select.number option {
}
.nav-head {
background: #fff;
background: -moz-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: -webkit-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: -o-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: -ms-linear-gradient(top, #fff 0%, #f0f0f0 100%);
background: #1c1c1c;
}
.header > .item.search input {
input.extend {
-moz-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
}
@ -860,3 +875,43 @@ select.number option {
text-decoration: underline;
}
}
.stat {
border:1px solid #2f2f2f;
border-radius:10px;
margin:10px 0;
padding:0 5px;
}
.stat > h2 {
border-bottom:1px solid #2f2f2f;
margin:0 -5px;
padding-left:5px;
}
.stat > div {
margin:5px 0;
}
.stat > table {
border-collapse:collapse;
margin:5px 0;
width:100%;
}
.stat > table > thead > tr {
border-bottom:2px solid #2f2f2f;
}
.stat > table > tbody > tr {
border-bottom:1px solid #2f2f2f;
}
.stat > table > tbody > tr:last-child {
border-bottom:0;
}
.stat > table th, .stat > table td {
border-left:2px solid #2f2f2f;
padding:5px;
}
.stat > table th:first-child, .stat > table td:first-child {
border-left:0;
}
.stat > table td.numeric{
margin:5px 0;
text-align:center;
}

@ -87,6 +87,13 @@ label {
line-height: 25px;
cursor: pointer;
}
input {
width: 180px;
}
textarea {
width: 360px;
height: 100px;
}
input, select, textarea {
display: inline-block;
max-width: 100%;
@ -116,6 +123,10 @@ input, select, textarea {
border-color: red;
box-shadow: 0 0 2px 1px red;
}
input:focus.extend {
width: 300px;
transition: width 200ms linear;
}
.form-group {
margin: 0;
@ -179,8 +190,13 @@ input, select, textarea {
}
.stick .btn + .btn,
.stick .btn + input,
.stick .btn + .dropdown > .btn,
.stick input + .btn,
.stick input + input {
.stick input + input,
.stick input + .dropdown > .btn,
.stick .dropdown + .btn,
.stick .dropdown + input,
.stick .dropdown + .dropdown > .btn {
border-left: none;
}
.stick .btn + .dropdown > .btn {
@ -305,7 +321,7 @@ input, select, textarea {
display: block;
height: 0;
margin: 5px 0;
border-bottom: 1px solid #ddd;
border-bottom: 1px solid #2f2f2f;
}
.nav-list .nav-form {
@ -317,7 +333,7 @@ input, select, textarea {
display: block;
margin: 0;
background: linear-gradient(to bottom, #fff, #f0f0f0);
border-bottom: 1px solid #ddd;
border-bottom: 1px solid #2f2f2f;
text-align: right;
}
.nav-head .item {
@ -489,3 +505,20 @@ input, select, textarea {
vertical-align: middle;
line-height: 16px;
}
/* Prompt (centré) */
.prompt > h1, .prompt > p {
text-align:center;
}
.prompt > form {
margin:1em auto 2.5em auto;
width:10em;
}
.prompt .btn {
display:block;
margin:.5em auto;
}
.prompt input {
margin:.4em auto 1.1em auto;
width:99%;
}

@ -34,7 +34,6 @@ body {
}
.header > .item.search input {
width: 230px;
transition: width 200ms linear;
}
.header .item.search input:focus {
width: 330px;
@ -217,6 +216,25 @@ body {
z-index: -10;
}
#new-article {
display: none;
min-height: 40px;
background: #3498db;
text-align: center;
}
#new-article:hover {
background: #2980b9;
}
#new-article > a {
display: block;
line-height: 40px;
color: #fff;
font-weight: bold;
}
#new-article > a:hover {
text-decoration: none;
}
.flux {
border-left: 3px solid #ecf0f1;
}
@ -236,6 +254,10 @@ body {
background: #fff;
}
.horizontal-list > .item:not(.title):not(.website) > a {
display: block;
}
.flux_header {
background: inherit;
height: 25px;
@ -263,11 +285,6 @@ body {
}
.flux .item.title {
background: inherit;
}
.flux:hover .item.title {
border-right: 2px solid rgba(127, 127, 127, 0.1);
padding-right: 1em;
position: absolute;
}
.flux .item.title a {
color: #333;
@ -278,7 +295,7 @@ body {
font-weight: bold;
}
.flux .item.date {
width: 200px;
width: 145px;
padding:0 5px 0 0;
text-align: right;
font-size: 10px;
@ -656,6 +673,14 @@ select.number option {
text-align:right;
}
@media(min-width: 841px) {
.flux:not(.current):hover .item.title {
max-width: calc(100% - 580px);
padding-right: 1.5em;
position: absolute;
}
}
@media(max-width: 840px) {
.header,
.aside .btn-important,
@ -676,11 +701,6 @@ select.number option {
display: block;
}
.content {
font-size: 120%;
padding: 0;
}
.pagination {
margin: 0 0 40px;
}
@ -779,6 +799,13 @@ select.number option {
-ms-transform: rotate(45deg);
}
input.extend {
-moz-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
}
@media print {
.header,
.aside,
@ -815,3 +842,44 @@ select.number option {
text-decoration: underline;
}
}
.stat {
border:1px solid #aaa;
border-radius:10px;
box-shadow:2px 2px 5px #aaa;
margin:10px 0;
padding:0 5px;
}
.stat > h2 {
border-bottom:1px solid #aaa;
margin:0 -5px;
padding-left:5px;
}
.stat > div {
margin:5px 0;
}
.stat > table {
border-collapse:collapse;
margin:5px 0;
width:100%;
}
.stat > table > thead > tr {
border-bottom:2px solid #aaa;
}
.stat > table > tbody > tr {
border-bottom:1px solid #aaa;
}
.stat > table > tbody > tr:last-child {
border-bottom:0;
}
.stat > table th, .stat > table td {
border-left:2px solid #aaa;
padding:5px;
}
.stat > table th:first-child, .stat > table td:first-child {
border-left:0;
}
.stat > table td.numeric{
margin:5px 0;
text-align:center;
}

@ -88,6 +88,13 @@ label {
font-weight: bold;
color: #444;
}
input {
width: 180px;
}
textarea {
width: 360px;
height: 100px;
}
input, select, textarea {
display: inline-block;
max-width: 100%;
@ -117,6 +124,10 @@ input, select, textarea {
border-color: red;
box-shadow: 0 0 2px 1px red;
}
input:focus.extend {
width: 300px;
transition: width 200ms linear;
}
.form-group {
margin: 5px 0;
@ -497,3 +508,20 @@ input, select, textarea {
vertical-align: middle;
line-height: 16px;
}
/* Prompt (centré) */
.prompt > h1, .prompt > p {
text-align:center;
}
.prompt > form {
margin:1em auto 2.5em auto;
width:10em;
}
.prompt .btn {
display:block;
margin:.5em auto;
}
.prompt input {
margin:.4em auto 1.1em auto;
width:99%;
}

@ -0,0 +1,31 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:svg='http://www.w3.org/2000/svg' id='svg7384' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' sodipodi:docname='folder-symbolic.svg' version='1.1' inkscape:version='0.48.0 r9654' height='16' 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:cy='-173.07332' pagecolor='#555753' borderopacity='1' showborder='false' inkscape:bbox-paths='false' guidetolerance='10' inkscape:window-width='1310' showguides='true' inkscape:object-nodes='true' inkscape:snap-bbox='true' inkscape:pageshadow='2' inkscape:guide-bbox='true' inkscape:snap-nodes='true' bordercolor='#FFFFFF' objecttolerance='10' id='namedview88' showgrid='false' inkscape:window-maximized='0' inkscape:window-x='52' inkscape:snap-global='true' inkscape:window-y='24' gridtolerance='10' inkscape:window-height='690' inkscape:snap-to-guides='true' inkscape:current-layer='layer13' inkscape:zoom='1' inkscape:cx='-157.67647' inkscape:snap-grids='true' inkscape:pageopacity='1'>
<inkscape:grid spacingx='1px' spacingy='1px' id='grid4866' empspacing='2' enabled='true' type='xygrid' snapvisiblegridlinesonly='true' visible='true'/>
</sodipodi:namedview>
<title id='title9167'>Gnome Symbolic Icon Theme</title>
<defs id='defs7386'/>
<g inkscape:label='status' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer9' style='display:inline'/>
<g inkscape:label='devices' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer10'/>
<g inkscape:label='apps' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer11'/>
<g inkscape:label='actions' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer12'/>
<g inkscape:label='places' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer13'>
<g transform='translate(234.0002,-820)' id='g14154'>
<path inkscape:connector-curvature='0' d='m 208.53105,997 c -0.28913,0 -0.53125,0.24212 -0.53125,0.53125 l 0,13.93755 c 0,0.2985 0.23264,0.5312 0.53125,0.5312 l 14.9375,0 c 0.2986,0 0.53125,-0.2326 0.53125,-0.5312 l 0,-8.9376 c 0,-0.2891 -0.24212,-0.5312 -0.53125,-0.5312 l -12.46875,0 0,7.5 c 0,0.277 -0.223,0.5 -0.5,0.5 -0.277,0 -0.5,-0.223 -0.5,-0.5 l 0,-8 c 0,-0.277 0.223,-0.5 0.5,-0.5 l 2.96875,0 8.53125,0 0,-1.4062 c 0,-0.3272 -0.26666,-0.5938 -0.59375,-0.5938 l -7.40625,0 0,-1.46875 C 213.9998,997.2421 213.75768,997 213.46855,997 z' id='rect3845' sodipodi:nodetypes='ccccccccccsccccccccccc' style='fill:#FFFFFF;fill-opacity:1;stroke:none;display:inline'/>
</g>
</g>
<g inkscape:label='mimetypes' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer14'/>
<g inkscape:label='emblems' transform='translate(-442,-176)' inkscape:groupmode='layer' id='layer15' style='display:inline'/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -32,7 +32,6 @@
}
.header > .item.search input {
width: 230px;
transition: width 200ms linear;
}
.header .item.search input:focus {
width: 330px;
@ -210,7 +209,7 @@
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.day:first-child {
#new-article + .day {
border-top: none;
}
.day .name {
@ -230,6 +229,25 @@
text-align: right;
}
#new-article {
display: none;
min-height: 40px;
background: #0084CC;
text-align: center;
}
#new-article:hover {
background: #0066CC;
}
#new-article > a {
display: block;
line-height: 40px;
color: #fff;
font-weight: bold;
}
#new-article > a:hover {
text-decoration: none;
}
.flux {
border-left: 3px solid #aaa;
background: #fafafa;
@ -250,6 +268,10 @@
background: #fff;
}
.horizontal-list > .item:not(.title):not(.website) > a {
display: block;
}
.flux_header {
background: inherit;
height: 25px;
@ -277,11 +299,6 @@
}
.flux .item.title {
background: inherit;
}
.flux:hover .item.title {
border-right: 2px solid rgba(127, 127, 127, 0.1);
padding-right: 1em;
position: absolute;
}
.flux .item.title a {
color: #000;
@ -292,7 +309,7 @@
font-weight: bold;
}
.flux .item.date {
width: 200px;
width: 145px;
padding:0 5px 0 0;
text-align: right;
font-size: 10px;
@ -657,6 +674,14 @@ select.number option {
text-align:right;
}
@media(min-width: 841px) {
.flux:not(.current):hover .item.title {
max-width: calc(100% - 580px);
padding-right: 1.5em;
position: absolute;
}
}
@media(max-width: 840px) {
.header,
.aside .btn-important,
@ -677,11 +702,6 @@ select.number option {
display: block;
}
.content {
font-size: 120%;
padding: 0;
}
.pagination {
margin: 0 0 40px;
}
@ -826,9 +846,9 @@ select.number option {
background: -ms-linear-gradient(top, #fff 0%, #f0f0f0 100%);
}
.header > .item.search input {
input.extend {
-moz-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
}
@ -836,7 +856,7 @@ select.number option {
@media(max-width: 840px) {
.aside {
-moz-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-webkit-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
}
@ -878,3 +898,44 @@ select.number option {
text-decoration: underline;
}
}
.stat {
border:1px solid #aaa;
border-radius:10px;
box-shadow:2px 2px 5px #aaa;
margin:10px 0;
padding:0 5px;
}
.stat > h2 {
border-bottom:1px solid #aaa;
margin:0 -5px;
padding-left:5px;
}
.stat > div {
margin:5px 0;
}
.stat > table {
border-collapse:collapse;
margin:5px 0;
width:100%;
}
.stat > table > thead > tr {
border-bottom:2px solid #aaa;
}
.stat > table > tbody > tr {
border-bottom:1px solid #aaa;
}
.stat > table > tbody > tr:last-child {
border-bottom:0;
}
.stat > table th, .stat > table td {
border-left:2px solid #aaa;
padding:5px;
}
.stat > table th:first-child, .stat > table td:first-child {
border-left:0;
}
.stat > table td.numeric{
margin:5px 0;
text-align:center;
}

@ -86,6 +86,13 @@ label {
line-height: 25px;
cursor: pointer;
}
input {
width: 180px;
}
textarea {
width: 360px;
height: 100px;
}
input, select, textarea {
display: inline-block;
max-width: 100%;
@ -116,6 +123,10 @@ input, select, textarea {
border-color: red;
box-shadow: 0 0 2px 1px red;
}
input:focus.extend {
width: 300px;
transition: width 200ms linear;
}
.form-group {
margin: 0;
@ -179,8 +190,13 @@ input, select, textarea {
}
.stick .btn + .btn,
.stick .btn + input,
.stick .btn + .dropdown > .btn,
.stick input + .btn,
.stick input + input {
.stick input + input,
.stick input + .dropdown > .btn,
.stick .dropdown + .btn,
.stick .dropdown + input,
.stick .dropdown + .dropdown > .btn {
border-left: none;
}
.stick input + .btn {
@ -505,3 +521,20 @@ input, select, textarea {
vertical-align: middle;
line-height: 16px;
}
/* Prompt (centré) */
.prompt > h1, .prompt > p {
text-align:center;
}
.prompt > form {
margin:1em auto 2.5em auto;
width:10em;
}
.prompt .btn {
display:block;
margin:.5em auto;
}
.prompt input {
margin:.4em auto 1.1em auto;
width:99%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<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: 512 B

@ -1,213 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<title>Logo FreshRSS</title>
<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"
width="256"
height="256"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/cyp/Bureau/FreshRSS.png"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197">
<title
id="title2991">Logo FreshRSS</title>
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.0000001"
inkscape:cx="211.05579"
inkscape:cy="58.65406"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="711"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:snap-global="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="false" />
<metadata
id="metadata7">
<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>Logo FreshRSS</dc:title>
<dc:date>2013-08-20</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Cyprien POUZENC</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:rights>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(27,-823.3622)">
<path
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 101,823.3622 0,23.704 c 57.60125,0 104.2963,46.6944 104.2963,104.296 l 23.7037,0 c 0,-70.6912 -57.30755,-128 -128,-128 z"
id="path2990-22"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-64"
inkscape:transform-center-y="-63.999956"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 101,866.0294 0,23.704 c 34.0371,0 61.62963,27.592 61.62963,61.6288 l 23.7037,0 c 0,-47.128 -38.20503,-85.3328 -85.33333,-85.3328 z"
id="path2990-3"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-42.666665"
inkscape:transform-center-y="-42.666356"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2990"
sodipodi:cx="-0.088388346"
sodipodi:cy="50"
sodipodi:rx="3.9774756"
sodipodi:ry="3.9774756"
d="M -0.08838827,46.022524 A 3.9774756,3.9774756 0 0 1 3.8890873,50 l -3.97747565,0 z"
transform="matrix(8.3432784,0,0,8.3432808,101.73744,534.199)"
sodipodi:start="4.712389"
sodipodi:end="6.2831853"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197"
inkscape:transform-center-x="-16.592584"
inkscape:transform-center-y="-16.591714" />
<path
style="color:#000000;fill:#0062be;fill-opacity:0.29591836;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 229,951.3622 -23.7037,0 c 0,57.6016 -46.69488,104.296 -104.2963,104.296 l 0,23.704 c 70.6925,0 128,-57.3072 128,-128 z"
id="path2990-22-9"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-64"
inkscape:transform-center-y="64.000044"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
style="color:#000000;fill:#0062be;fill-opacity:0.29591836;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 186.33333,951.3622 -23.7037,0 c 0,34.0368 -27.59253,61.6304 -61.62963,61.6304 l 0,23.704 c 47.12818,0 85.33333,-38.2064 85.33333,-85.3344 z"
id="path2990-3-6"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-42.666665"
inkscape:transform-center-y="42.667244"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
style="color:#000000;fill:#0062be;fill-opacity:0.29591836;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -27,951.3622 23.703712,0 c 0,-57.6016 46.694864,-104.296 104.296288,-104.296 l 0,-23.704 c -70.692496,0 -128,57.3088 -128,128 z"
id="path2990-22-93"
inkscape:connector-curvature="0"
inkscape:transform-center-x="64"
inkscape:transform-center-y="-63.999956"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
style="color:#000000;fill:#0062be;fill-opacity:0.29591836;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 15.666656,951.3622 23.703712,0 c 0,-34.0368 27.592544,-61.6288 61.629632,-61.6288 l 0,-23.704 c -47.128176,0 -85.333344,38.2048 -85.333344,85.3328 z"
id="path2990-3-9"
inkscape:connector-curvature="0"
inkscape:transform-center-x="42.666672"
inkscape:transform-center-y="-42.666356"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2990-1"
sodipodi:cx="-0.088388346"
sodipodi:cy="50"
sodipodi:rx="3.9774756"
sodipodi:ry="3.9774756"
d="M -0.08838827,46.022524 A 3.9774756,3.9774756 0 0 1 3.8890873,50 l -3.97747565,0 z"
transform="matrix(0,-8.3432784,8.3432808,0,-315.97884,950.62475)"
sodipodi:start="4.712389"
sodipodi:end="6.2831853"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197"
inkscape:transform-center-x="16.591713"
inkscape:transform-center-y="-16.592581" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2990-6"
sodipodi:cx="-0.088388346"
sodipodi:cy="50"
sodipodi:rx="3.9774756"
sodipodi:ry="3.9774756"
d="M -0.08838827,46.022524 A 3.9774756,3.9774756 0 0 1 3.8890873,50 l -3.97747565,0 z"
transform="matrix(-8.3432784,0,0,-8.3432808,100.44774,1368.3403)"
sodipodi:start="4.712389"
sodipodi:end="6.2831853"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197"
inkscape:transform-center-x="16.592584"
inkscape:transform-center-y="16.591761" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#0062be;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2990-1-6"
sodipodi:cx="-0.088388346"
sodipodi:cy="50"
sodipodi:rx="3.9774756"
sodipodi:ry="3.9774756"
d="M -0.08838827,46.022524 A 3.9774756,3.9774756 0 0 1 3.8890873,50 l -3.97747565,0 z"
transform="matrix(0,8.3432784,-8.3432808,0,518.16402,951.91446)"
sodipodi:start="4.712389"
sodipodi:end="6.2831853"
inkscape:export-xdpi="197"
inkscape:export-ydpi="197"
inkscape:transform-center-x="-16.591713"
inkscape:transform-center-y="16.592578" />
</g>
<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>

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 462 B

Loading…
Cancel
Save