= Helper\get_host_from_url($item['url']) ?> |
+ mark as read |
Date: Thu, 4 Apr 2013 23:33:29 -0400
Subject: [PATCH 16/48] Change CSP to accept iframe from Youtube and Vimeo
---
miniflux/index.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index daea32d..b9425b1 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -26,7 +26,8 @@ Router\before(function($action) {
}
Response\csp(array(
- 'img-src' => '*'
+ 'img-src' => '*',
+ 'frame-src' => 'http://www.youtube.com http://player.vimeo.com'
));
Response\xframe();
From fd2e034c017db319a0b6ce7adb9a3934b407b675 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Thu, 4 Apr 2013 23:34:07 -0400
Subject: [PATCH 17/48] Update of PicoFeed
---
miniflux/vendor/PicoFeed/Filter.php | 34 ++-
miniflux/vendor/PicoFeed/Parser.php | 251 +--------------------
miniflux/vendor/PicoFeed/Parsers/Atom.php | 83 +++++++
miniflux/vendor/PicoFeed/Parsers/Rss10.php | 81 +++++++
miniflux/vendor/PicoFeed/Parsers/Rss20.php | 93 ++++++++
miniflux/vendor/PicoFeed/Parsers/Rss91.php | 7 +
miniflux/vendor/PicoFeed/Parsers/Rss92.php | 7 +
miniflux/vendor/PicoFeed/Reader.php | 5 +
8 files changed, 317 insertions(+), 244 deletions(-)
create mode 100644 miniflux/vendor/PicoFeed/Parsers/Atom.php
create mode 100644 miniflux/vendor/PicoFeed/Parsers/Rss10.php
create mode 100644 miniflux/vendor/PicoFeed/Parsers/Rss20.php
create mode 100644 miniflux/vendor/PicoFeed/Parsers/Rss91.php
create mode 100644 miniflux/vendor/PicoFeed/Parsers/Rss92.php
diff --git a/miniflux/vendor/PicoFeed/Filter.php b/miniflux/vendor/PicoFeed/Filter.php
index 9c7dd24..f911014 100644
--- a/miniflux/vendor/PicoFeed/Filter.php
+++ b/miniflux/vendor/PicoFeed/Filter.php
@@ -45,7 +45,8 @@ class Filter
'figcaption' => array(),
'cite' => array(),
'time' => array('datetime'),
- 'abbr' => array('title')
+ 'abbr' => array('title'),
+ 'iframe' => array('width', 'height', 'frameborder', 'src')
);
public $strip_tags_content = array(
@@ -82,6 +83,11 @@ class Filter
'a' => 'rel="noreferrer" target="_blank"'
);
+ public $iframe_allowed_resources = array(
+ 'http://www.youtube.com/',
+ 'http://player.vimeo.com/'
+ );
+
public function __construct($data, $url)
{
@@ -104,7 +110,7 @@ class Filter
if (! xml_parse($parser, $this->input, true)) {
- var_dump($this->input);
+ //var_dump($this->input);
die(xml_get_current_line_number($parser).'|'.xml_error_string(xml_get_error_code($parser)));
}
@@ -130,11 +136,16 @@ class Filter
foreach ($attributes as $attribute => $value) {
- if ($this->isAllowedAttribute($name, $attribute)) {
+ if ($value != '' && $this->isAllowedAttribute($name, $attribute)) {
if ($this->isResource($attribute)) {
- if ($this->isRelativePath($value)) {
+ if ($name === 'iframe' && $this->isAllowedIframeResource($value)) {
+
+ $attr_data .= ' '.$attribute.'="'.$value.'"';
+ $used_attributes[] = $attribute;
+ }
+ else if ($this->isRelativePath($value)) {
$attr_data .= ' '.$attribute.'="'.$this->getAbsoluteUrl($value, $this->url).'"';
$used_attributes[] = $attribute;
@@ -216,7 +227,6 @@ class Filter
else {
// Relative path
-
$url_path = $components['path'];
if ($url_path{strlen($url_path) - 1} !== '/') {
@@ -258,6 +268,20 @@ class Filter
}
+ public function isAllowedIframeResource($value)
+ {
+ foreach ($this->iframe_allowed_resources as $url) {
+
+ if (strpos($value, $url) === 0) {
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
public function isAllowedProtocol($value)
{
foreach ($this->allowed_protocols as $protocol) {
diff --git a/miniflux/vendor/PicoFeed/Parser.php b/miniflux/vendor/PicoFeed/Parser.php
index 6612ebf..a494494 100644
--- a/miniflux/vendor/PicoFeed/Parser.php
+++ b/miniflux/vendor/PicoFeed/Parser.php
@@ -14,6 +14,7 @@ abstract class Parser
public $title = '';
public $updated = '';
public $items = array();
+ public $debug = false;
abstract public function execute();
@@ -37,253 +38,25 @@ abstract class Parser
return $content;
}
-}
-class Atom extends Parser
-{
- public function execute()
+ public function displayXmlErrors()
{
- try {
+ foreach(\libxml_get_errors() as $error) {
- \libxml_use_internal_errors(true);
-
- $xml = new \SimpleXMLElement($this->content);
-
- $this->url = $this->getUrl($xml);
- $this->title = (string) $xml->title;
- $this->id = (string) $xml->id;
- $this->updated = strtotime((string) $xml->updated);
- $author = (string) $xml->author->name;
-
- foreach ($xml->entry as $entry) {
-
- if (isset($entry->author->name)) {
-
- $author = $entry->author->name;
- }
-
- $item = new \StdClass;
- $item->id = (string) $entry->id;
- $item->title = (string) $entry->title;
- $item->url = $this->getUrl($entry);
- $item->updated = strtotime((string) $entry->updated);
- $item->author = $author;
- $item->content = $this->filterHtml($this->getContent($entry), $item->url);
-
- $this->items[] = $item;
- }
+ printf("Message: %s\nLine: %d\nColumn: %d\nCode: %d\n",
+ $error->message,
+ $error->line,
+ $error->column,
+ $error->code
+ );
}
- catch (\Exception $e) {
-
- }
-
- return $this;
}
- public function getContent($entry)
+ // Dirty quickfix before XML parsing
+ public function normalizeData($data)
{
- if (isset($entry->content) && ! empty($entry->content)) {
-
- if (count($entry->content->children())) {
-
- return (string) $entry->content->asXML();
- }
- else {
-
- return (string) $entry->content;
- }
- }
- else if (isset($entry->summary) && ! empty($entry->summary)) {
-
- return (string) $entry->summary;
- }
-
- return '';
- }
-
-
- public function getUrl($xml)
- {
- foreach ($xml->link as $link) {
-
- if ((string) $link['type'] === 'text/html') {
-
- return (string) $link['href'];
- }
- }
-
- return (string) $xml->link['href'];
+ return str_replace("\xc3\x20", '', $data);
}
}
-
-
-class Rss20 extends Parser
-{
- public function execute()
- {
- try {
-
- \libxml_use_internal_errors(true);
-
- $xml = new \SimpleXMLElement($this->content);
- $ns = $xml->getNamespaces(true);
-
- $this->title = (string) $xml->channel->title;
- $this->url = (string) $xml->channel->link;
- $this->id = $this->url;
- $this->updated = isset($xml->channel->pubDate) ? (string) $xml->channel->pubDate : (string) $xml->channel->lastBuildDate;
-
- if ($this->updated) {
-
- $this->updated = strtotime($this->updated);
- }
- else {
-
- $this->updated = time();
- }
-
- foreach ($xml->channel->item as $entry) {
-
- $author = '';
- $content = '';
- $pubdate = '';
- $link = '';
-
- if (isset($ns['feedburner'])) {
-
- $ns_fb = $entry->children($ns['feedburner']);
- $link = $ns_fb->origLink;
- }
-
- if (isset($ns['dc'])) {
-
- $ns_dc = $entry->children($ns['dc']);
- $author = (string) $ns_dc->creator;
- $pubdate = (string) $ns_dc->date;
- }
-
- if (isset($ns['content'])) {
-
- $ns_content = $entry->children($ns['content']);
- $content = (string) $ns_content->encoded;
- }
-
- if ($content === '' && isset($entry->description)) {
-
- $content = (string) $entry->description;
- }
-
- if ($author === '') {
-
- if (isset($entry->author)) {
-
- $author = (string) $entry->author;
- }
- else if (isset($xml->channel->webMaster)) {
-
- $author = (string) $xml->channel->webMaster;
- }
- }
-
- $item = new \StdClass;
- $item->title = (string) $entry->title;
- $item->url = $link ?: (string) $entry->link;
- $item->id = isset($entry->guid) ? (string) $entry->guid : $item->url;
- $item->updated = strtotime($pubdate ?: (string) $entry->pubDate) ?: $this->updated;
- $item->content = $this->filterHtml($content, $item->url);
- $item->author = $author;
-
- $this->items[] = $item;
- }
- }
- catch (\Exception $e) {
-
- }
-
- return $this;
- }
-}
-
-
-class Rss10 extends Parser
-{
- public function execute()
- {
- try {
-
- \libxml_use_internal_errors(true);
-
- $xml = new \SimpleXMLElement($this->content);
- $ns = $xml->getNamespaces(true);
-
- $this->title = (string) $xml->channel->title;
- $this->url = (string) $xml->channel->link;
- $this->id = $this->url;
-
- if (isset($ns['dc'])) {
-
- $ns_dc = $xml->channel->children($ns['dc']);
- $this->updated = isset($ns_dc->date) ? strtotime($ns_dc->date) : time();
- }
- else {
-
- $this->updated = time();
- }
-
- foreach ($xml->item as $entry) {
-
- $author = '';
- $content = '';
- $pubdate = '';
- $link = '';
-
- if (isset($ns['feedburner'])) {
-
- $ns_fb = $entry->children($ns['feedburner']);
- $link = $ns_fb->origLink;
- }
-
- if (isset($ns['dc'])) {
-
- $ns_dc = $entry->children($ns['dc']);
- $author = (string) $ns_dc->creator;
- $pubdate = (string) $ns_dc->date;
- }
-
- if (isset($ns['content'])) {
-
- $ns_content = $entry->children($ns['content']);
- $content = (string) $ns_content->encoded;
- }
-
- if ($content === '' && isset($entry->description)) {
-
- $content = (string) $entry->description;
- }
-
- $item = new \StdClass;
- $item->title = (string) $entry->title;
- $item->url = $link ?: (string) $entry->link;
- $item->id = $item->url;
- $item->updated = $pubdate ? strtotime($pubdate) : time();
- $item->content = $this->filterHtml($content, $item->url);
- $item->author = $author ?: (string) $xml->channel->webMaster;
-
- $this->items[] = $item;
- }
- }
- catch (\Exception $e) {
-
- }
-
- return $this;
- }
-}
-
-
-class Rss92 extends Rss20 {}
-
-
-class Rss91 extends Rss20 {}
diff --git a/miniflux/vendor/PicoFeed/Parsers/Atom.php b/miniflux/vendor/PicoFeed/Parsers/Atom.php
new file mode 100644
index 0000000..cf3f405
--- /dev/null
+++ b/miniflux/vendor/PicoFeed/Parsers/Atom.php
@@ -0,0 +1,83 @@
+content = $this->normalizeData($this->content);
+
+ \libxml_use_internal_errors(true);
+
+ $xml = \simplexml_load_string($this->content);
+
+ if ($xml === false) {
+
+ if ($this->debug) $this->displayXmlErrors();
+ return false;
+ }
+
+ $this->url = $this->getUrl($xml);
+ $this->title = (string) $xml->title;
+ $this->id = (string) $xml->id;
+ $this->updated = strtotime((string) $xml->updated);
+ $author = (string) $xml->author->name;
+
+ foreach ($xml->entry as $entry) {
+
+ if (isset($entry->author->name)) {
+
+ $author = $entry->author->name;
+ }
+
+ $item = new \StdClass;
+ $item->id = (string) $entry->id;
+ $item->title = (string) $entry->title;
+ $item->url = $this->getUrl($entry);
+ $item->updated = strtotime((string) $entry->updated);
+ $item->author = $author;
+ $item->content = $this->filterHtml($this->getContent($entry), $item->url);
+
+ $this->items[] = $item;
+ }
+
+ return $this;
+ }
+
+
+ public function getContent($entry)
+ {
+ if (isset($entry->content) && ! empty($entry->content)) {
+
+ if (count($entry->content->children())) {
+
+ return (string) $entry->content->asXML();
+ }
+ else {
+
+ return (string) $entry->content;
+ }
+ }
+ else if (isset($entry->summary) && ! empty($entry->summary)) {
+
+ return (string) $entry->summary;
+ }
+
+ return '';
+ }
+
+
+ public function getUrl($xml)
+ {
+ foreach ($xml->link as $link) {
+
+ if ((string) $link['type'] === 'text/html') {
+
+ return (string) $link['href'];
+ }
+ }
+
+ return (string) $xml->link['href'];
+ }
+}
\ No newline at end of file
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss10.php b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
new file mode 100644
index 0000000..969ab8c
--- /dev/null
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
@@ -0,0 +1,81 @@
+content = $this->normalizeData($this->content);
+
+ \libxml_use_internal_errors(true);
+
+ $xml = \simplexml_load_string($this->content);
+
+ if ($xml === false) {
+
+ if ($this->debug) $this->displayXmlErrors();
+ return false;
+ }
+
+ $ns = $xml->getNamespaces(true);
+
+ $this->title = (string) $xml->channel->title;
+ $this->url = (string) $xml->channel->link;
+ $this->id = $this->url;
+
+ if (isset($ns['dc'])) {
+
+ $ns_dc = $xml->channel->children($ns['dc']);
+ $this->updated = isset($ns_dc->date) ? strtotime($ns_dc->date) : time();
+ }
+ else {
+
+ $this->updated = time();
+ }
+
+ foreach ($xml->item as $entry) {
+
+ $author = '';
+ $content = '';
+ $pubdate = '';
+ $link = '';
+
+ if (isset($ns['feedburner'])) {
+
+ $ns_fb = $entry->children($ns['feedburner']);
+ $link = $ns_fb->origLink;
+ }
+
+ if (isset($ns['dc'])) {
+
+ $ns_dc = $entry->children($ns['dc']);
+ $author = (string) $ns_dc->creator;
+ $pubdate = (string) $ns_dc->date;
+ }
+
+ if (isset($ns['content'])) {
+
+ $ns_content = $entry->children($ns['content']);
+ $content = (string) $ns_content->encoded;
+ }
+
+ if ($content === '' && isset($entry->description)) {
+
+ $content = (string) $entry->description;
+ }
+
+ $item = new \StdClass;
+ $item->title = (string) $entry->title;
+ $item->url = $link ?: (string) $entry->link;
+ $item->id = $item->url;
+ $item->updated = $pubdate ? strtotime($pubdate) : time();
+ $item->content = $this->filterHtml($content, $item->url);
+ $item->author = $author ?: (string) $xml->channel->webMaster;
+
+ $this->items[] = $item;
+ }
+
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss20.php b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
new file mode 100644
index 0000000..7fced40
--- /dev/null
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
@@ -0,0 +1,93 @@
+content = $this->normalizeData($this->content);
+
+ \libxml_use_internal_errors(true);
+
+ $xml = \simplexml_load_string($this->content);
+
+ if ($xml === false) {
+
+ if ($this->debug) $this->displayXmlErrors();
+ return false;
+ }
+
+ $ns = $xml->getNamespaces(true);
+
+ $this->title = (string) $xml->channel->title;
+ $this->url = (string) $xml->channel->link;
+ $this->id = $this->url;
+ $this->updated = isset($xml->channel->pubDate) ? (string) $xml->channel->pubDate : (string) $xml->channel->lastBuildDate;
+
+ if ($this->updated) {
+
+ $this->updated = strtotime($this->updated);
+ }
+ else {
+
+ $this->updated = time();
+ }
+
+ foreach ($xml->channel->item as $entry) {
+
+ $author = '';
+ $content = '';
+ $pubdate = '';
+ $link = '';
+
+ if (isset($ns['feedburner'])) {
+
+ $ns_fb = $entry->children($ns['feedburner']);
+ $link = $ns_fb->origLink;
+ }
+
+ if (isset($ns['dc'])) {
+
+ $ns_dc = $entry->children($ns['dc']);
+ $author = (string) $ns_dc->creator;
+ $pubdate = (string) $ns_dc->date;
+ }
+
+ if (isset($ns['content'])) {
+
+ $ns_content = $entry->children($ns['content']);
+ $content = (string) $ns_content->encoded;
+ }
+
+ if ($content === '' && isset($entry->description)) {
+
+ $content = (string) $entry->description;
+ }
+
+ if ($author === '') {
+
+ if (isset($entry->author)) {
+
+ $author = (string) $entry->author;
+ }
+ else if (isset($xml->channel->webMaster)) {
+
+ $author = (string) $xml->channel->webMaster;
+ }
+ }
+
+ $item = new \StdClass;
+ $item->title = (string) $entry->title;
+ $item->url = $link ?: (string) $entry->link;
+ $item->id = isset($entry->guid) ? (string) $entry->guid : $item->url;
+ $item->updated = strtotime($pubdate ?: (string) $entry->pubDate) ?: $this->updated;
+ $item->content = $this->filterHtml($content, $item->url);
+ $item->author = $author;
+
+ $this->items[] = $item;
+ }
+
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss91.php b/miniflux/vendor/PicoFeed/Parsers/Rss91.php
new file mode 100644
index 0000000..08716e9
--- /dev/null
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss91.php
@@ -0,0 +1,7 @@
+content);
}
else if (strpos($first_tag, 'content);
}
else if (strpos($first_tag, 'content);
}
else if (strpos($first_tag, 'content);
}
else if (strpos($first_tag, 'content);
}
else if ($discover === true) {
From 02770f79f3ed4b4395175315200f086136b649d4 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 5 Apr 2013 21:52:58 -0400
Subject: [PATCH 18/48] Update readme
---
README.markdown | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/README.markdown b/README.markdown
index 0570f57..9faf446 100644
--- a/README.markdown
+++ b/README.markdown
@@ -14,14 +14,15 @@ Features
- Import/Export OPML feeds
- Feeds update by a cronjob or with the user interface in one click
- Protected by a login/password (only one possible user)
-- Use secure headers (only external images are allowed)
+- Use secure headers (only external images and Youtube/Vimeo videos are allowed)
- Open external links inside a new tab with a `rel="noreferrer"` attribute
- Mobile CSS (responsive design)
+- Keyboard shortcuts
-Todo
-----
+Todo and known bugs
+-------------------
-- Remove older items from the database
+- See Issues:
License
-------
@@ -33,7 +34,7 @@ Requirements
- PHP >= 5.3.7
- PHP XML extensions (SimpleXML, DOM...)
-- PHP Sqlite extensions
+- PHP Sqlite extension
Libraries used
--------------
@@ -81,6 +82,11 @@ Your life is cluttered.
Miniflux is a minimalist software. Less is more.
+### Why there is no favourites?
+
+Use the right tool for the right job.
+Your browser already have bookmarks, if you don't like it there many online tools for that.
+
### I found a bug, what next?
Report the bug to the [issues tracker](https://github.com/fguillot/miniflux/issues) and I will fix it.
From 7f8fee18690907c236ad3d585a7e90025c15f0a8 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 5 Apr 2013 21:58:17 -0400
Subject: [PATCH 19/48] Add author section to the readme
---
README.markdown | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/README.markdown b/README.markdown
index 9faf446..1d2efe8 100644
--- a/README.markdown
+++ b/README.markdown
@@ -29,6 +29,12 @@ License
- AGPL:
+Authors
+-------
+
+- Original author: [Frédéric Guillot](http://fredericguillot.com/)
+- Contributors: [Pull requesters](https://github.com/fguillot/miniflux/pulls?direction=desc&page=1&sort=created&state=closed) and [Bug reporters](https://github.com/fguillot/miniflux/issues?page=1&state=closed)
+
Requirements
------------
From 6f9c55df8afaf98316a3c2eefb5c33b69f63d3df Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 5 Apr 2013 21:59:50 -0400
Subject: [PATCH 20/48] Typo fix
---
README.markdown | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.markdown b/README.markdown
index 1d2efe8..a0e2548 100644
--- a/README.markdown
+++ b/README.markdown
@@ -91,7 +91,7 @@ Miniflux is a minimalist software. Less is more.
### Why there is no favourites?
Use the right tool for the right job.
-Your browser already have bookmarks, if you don't like it there many online tools for that.
+Your browser already have bookmarks, if you don't like it there is many online tools for that.
### I found a bug, what next?
From 402b2fe7a9da6e2bee61e1c0a0ba996dec4be4a4 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 09:19:29 -0400
Subject: [PATCH 21/48] Add UserAgent and HTTP connection timeout
---
miniflux/common.php | 2 ++
miniflux/model.php | 6 +++---
miniflux/vendor/PicoFeed/Export.php | 19 +++++++++++++++++++
miniflux/vendor/PicoFeed/Reader.php | 27 +++++++++++++++++++++++++--
4 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/miniflux/common.php b/miniflux/common.php
index b862013..6f1f988 100644
--- a/miniflux/common.php
+++ b/miniflux/common.php
@@ -11,6 +11,8 @@ require 'model.php';
const DB_VERSION = 1;
const APP_VERSION = 'master';
+const APP_USERAGENT = 'Miniflux - http://miniflux.net';
+const HTTP_TIMEOUT = 5;
// For future use...
diff --git a/miniflux/model.php b/miniflux/model.php
index dc80c85..5f83a77 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -64,7 +64,7 @@ function import_feeds($content)
function import_feed($url)
{
$reader = new Reader;
- $reader->download($url);
+ $reader->download($url, HTTP_TIMEOUT, APP_USERAGENT);
$parser = $reader->getParser();
@@ -268,7 +268,7 @@ function update_feeds()
foreach (get_feeds() as $feed) {
$reader = new Reader;
- $reader->download($feed['feed_url']);
+ $reader->download($feed['feed_url'], HTTP_TIMEOUT, APP_USERAGENT);
$parser = $reader->getParser();
if ($parser !== false) {
@@ -284,7 +284,7 @@ function update_feed($feed_id)
$feed = get_feed($feed_id);
$reader = new Reader;
- $reader->download($feed['feed_url']);
+ $reader->download($feed['feed_url'], HTTP_TIMEOUT, APP_USERAGENT);
$parser = $reader->getParser();
if ($parser !== false) {
diff --git a/miniflux/vendor/PicoFeed/Export.php b/miniflux/vendor/PicoFeed/Export.php
index 95efae2..4601f0a 100644
--- a/miniflux/vendor/PicoFeed/Export.php
+++ b/miniflux/vendor/PicoFeed/Export.php
@@ -6,6 +6,12 @@ class Export
{
private $content = array();
+ public $required_fields = array(
+ 'title',
+ 'site_url',
+ 'feed_url'
+ );
+
public function __construct(array $content)
{
@@ -24,6 +30,19 @@ class Export
foreach ($this->content as $feed) {
+ $valid = true;
+
+ foreach ($this->required_fields as $field) {
+
+ if (! isset($feed[$field])) {
+
+ $valid = false;
+ break;
+ }
+ }
+
+ if (! $valid) continue;
+
$outline = $body->addChild('outline');
$outline->addAttribute('xmlUrl', $feed['feed_url']);
$outline->addAttribute('htmlUrl', $feed['site_url']);
diff --git a/miniflux/vendor/PicoFeed/Reader.php b/miniflux/vendor/PicoFeed/Reader.php
index 015489e..13323e9 100644
--- a/miniflux/vendor/PicoFeed/Reader.php
+++ b/miniflux/vendor/PicoFeed/Reader.php
@@ -16,7 +16,7 @@ class Reader
}
- public function download($url)
+ public function download($url, $timeout = 5, $user_agent = 'PicoFeed (https://github.com/fguillot/picoFeed)')
{
if (strpos($url, 'http') !== 0) {
@@ -24,12 +24,35 @@ class Reader
}
$this->url = $url;
- $this->content = @file_get_contents($this->url);
+ $this->content = $this->fetchRemoteFile($url, $timeout, $user_agent);
return $this;
}
+ public function fetchRemoteFile($url, $timeout, $user_agent)
+ {
+ if (! \function_exists('curl_init')) {
+
+ return @file_get_contents($this->url);
+ }
+
+ $ch = \curl_init();
+
+ \curl_setopt($ch, CURLOPT_URL, $url);
+ \curl_setopt($ch, CURLOPT_HEADER, false);
+ \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+ \curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
+
+ $content = \curl_exec($ch);
+
+ \curl_close($ch);
+
+ return $content;
+ }
+
+
public function getContent()
{
return $this->content;
From 3a1050b749334f11ffce33bb20a847a280c113da Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 21:14:52 -0400
Subject: [PATCH 22/48] Update of picoFeed
---
miniflux/vendor/PicoFeed/Filter.php | 51 +++---
miniflux/vendor/PicoFeed/Reader.php | 45 ++----
miniflux/vendor/PicoFeed/RemoteResource.php | 166 ++++++++++++++++++++
3 files changed, 211 insertions(+), 51 deletions(-)
create mode 100644 miniflux/vendor/PicoFeed/RemoteResource.php
diff --git a/miniflux/vendor/PicoFeed/Filter.php b/miniflux/vendor/PicoFeed/Filter.php
index f911014..3f16272 100644
--- a/miniflux/vendor/PicoFeed/Filter.php
+++ b/miniflux/vendor/PicoFeed/Filter.php
@@ -7,11 +7,9 @@ class Filter
private $data = '';
private $url = '';
private $input = '';
- private $empty_tag = false;
+ private $empty_tags = array();
private $strip_content = false;
- public $ignored_tags = array();
-
public $allowed_tags = array(
'dt' => array(),
'dd' => array(),
@@ -68,15 +66,20 @@ class Filter
public $blacklist_media = array(
'feeds.feedburner.com',
- 'feedsportal.com',
+ 'da.feedsportal.com',
+ 'rss.feedsportal.com',
+ 'res.feedsportal.com',
+ 'pi.feedsportal.com',
'rss.nytimes.com',
'feeds.wordpress.com',
- 'stats.wordpress.com'
+ 'stats.wordpress.com',
+ 'rss.cnn.com'
);
public $required_attributes = array(
'a' => array('href'),
- 'img' => array('src')
+ 'img' => array('src'),
+ 'iframe' => array('src')
);
public $add_attributes = array(
@@ -85,13 +88,15 @@ class Filter
public $iframe_allowed_resources = array(
'http://www.youtube.com/',
- 'http://player.vimeo.com/'
+ 'https://www.youtube.com/',
+ 'http://player.vimeo.com/',
+ 'https://player.vimeo.com/'
);
- public function __construct($data, $url)
+ public function __construct($data, $site_url)
{
- $this->url = $url;
+ $this->url = $site_url;
// Convert bad formatted documents to XML
$dom = new \DOMDocument;
@@ -122,12 +127,12 @@ class Filter
public function startTag($parser, $name, $attributes)
{
- $this->empty_tag = false;
+ $empty_tag = false;
$this->strip_content = false;
if ($this->isPixelTracker($name, $attributes)) {
- $this->empty_tag = true;
+ $empty_tag = true;
}
else if ($this->isAllowedTag($name)) {
@@ -140,10 +145,13 @@ class Filter
if ($this->isResource($attribute)) {
- if ($name === 'iframe' && $this->isAllowedIframeResource($value)) {
+ if ($name === 'iframe') {
- $attr_data .= ' '.$attribute.'="'.$value.'"';
- $used_attributes[] = $attribute;
+ if ($this->isAllowedIframeResource($value)) {
+
+ $attr_data .= ' '.$attribute.'="'.$value.'"';
+ $used_attributes[] = $attribute;
+ }
}
else if ($this->isRelativePath($value)) {
@@ -164,45 +172,46 @@ class Filter
}
}
+ // Check for required attributes
if (isset($this->required_attributes[$name])) {
foreach ($this->required_attributes[$name] as $required_attribute) {
if (! in_array($required_attribute, $used_attributes)) {
- $this->empty_tag = true;
+ $empty_tag = true;
break;
}
}
}
- if (! $this->empty_tag) {
+ if (! $empty_tag) {
$this->data .= '<'.$name.$attr_data;
+ // Add custom attributes
if (isset($this->add_attributes[$name])) {
$this->data .= ' '.$this->add_attributes[$name].' ';
}
+ // If img or br, we don't close it here
if ($name !== 'img' && $name !== 'br') $this->data .= '>';
}
}
- else {
-
- $this->ignored_tags[] = $name;
- }
if (in_array($name, $this->strip_tags_content)) {
$this->strip_content = true;
}
+
+ $this->empty_tags[] = $empty_tag;
}
public function endTag($parser, $name)
{
- if (! $this->empty_tag && $this->isAllowedTag($name)) {
+ if (! array_pop($this->empty_tags) && $this->isAllowedTag($name)) {
$this->data .= $name !== 'img' && $name !== 'br' ? ''.$name.'>' : '/>';
}
diff --git a/miniflux/vendor/PicoFeed/Reader.php b/miniflux/vendor/PicoFeed/Reader.php
index 13323e9..4fdca9c 100644
--- a/miniflux/vendor/PicoFeed/Reader.php
+++ b/miniflux/vendor/PicoFeed/Reader.php
@@ -2,6 +2,9 @@
namespace PicoFeed;
+require_once __DIR__.'/Parser.php';
+require_once __DIR__.'/RemoteResource.php';
+
class Reader
{
private $url = '';
@@ -16,40 +19,22 @@ class Reader
}
- public function download($url, $timeout = 5, $user_agent = 'PicoFeed (https://github.com/fguillot/picoFeed)')
+ public function download($url, $last_modified = '', $etag = '', $timeout = 5, $user_agent = 'PicoFeed (https://github.com/fguillot/picoFeed)')
{
if (strpos($url, 'http') !== 0) {
$url = 'http://'.$url;
}
- $this->url = $url;
- $this->content = $this->fetchRemoteFile($url, $timeout, $user_agent);
+ $resource = new RemoteResource($url, $timeout, $user_agent);
+ $resource->setLastModified($last_modified);
+ $resource->setEtag($etag);
+ $resource->execute();
- return $this;
- }
+ $this->content = $resource->getContent();
+ $this->url = $resource->getUrl();
-
- public function fetchRemoteFile($url, $timeout, $user_agent)
- {
- if (! \function_exists('curl_init')) {
-
- return @file_get_contents($this->url);
- }
-
- $ch = \curl_init();
-
- \curl_setopt($ch, CURLOPT_URL, $url);
- \curl_setopt($ch, CURLOPT_HEADER, false);
- \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
- \curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
-
- $content = \curl_exec($ch);
-
- \curl_close($ch);
-
- return $content;
+ return $resource;
}
@@ -90,24 +75,24 @@ class Reader
{
$first_tag = $this->getFirstTag($this->content);
- if (strpos($first_tag, 'content);
}
- else if (strpos($first_tag, 'content);
}
- else if (strpos($first_tag, 'content);
}
- else if (strpos($first_tag, 'url = $url;
+ $this->timeout = $timeout;
+ $this->user_agent = $user_agent;
+
+ return $this;
+ }
+
+
+ public function setLastModified($last_modified)
+ {
+ $this->last_modified = $last_modified;
+ return $this;
+ }
+
+
+ public function getLastModified()
+ {
+ return $this->last_modified;
+ }
+
+
+ public function setEtag($etag)
+ {
+ $this->etag = $etag;
+ return $this;
+ }
+
+
+ public function getEtag()
+ {
+ return $this->etag;
+ }
+
+
+ public function getUrl()
+ {
+ return $this->url;
+ }
+
+
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+
+ public function isModified()
+ {
+ return $this->is_modified;
+ }
+
+
+ public function execute()
+ {
+ $response = $this->makeRequest();
+
+ $this->etag = isset($response['headers']['ETag']) ? $response['headers']['ETag'] : '';
+ $this->last_modified = isset($response['headers']['Last-Modified']) ? $response['headers']['Last-Modified'] : '';
+
+ if ($response['status'] == 304) {
+
+ $this->is_modified = false;
+ }
+ else if ($response['status'] == 301 || $response['status'] == 302) {
+
+ if (isset($response['headers']['Location'])) {
+
+ $this->url = $response['headers']['Location'];
+ }
+ else if (isset($response['headers']['location'])) {
+
+ $this->url = $response['headers']['location'];
+ }
+
+ $this->execute();
+ }
+ else {
+
+ $this->content = $response['body'];
+ }
+ }
+
+
+ public function makeRequest()
+ {
+ $http_code = 200;
+ $http_body = '';
+ $http_headers = array();
+
+ if (! function_exists('curl_init')) {
+
+ $http_body = @file_get_contents($this->url);
+ }
+ else {
+
+ $headers = array('Connection: close');
+
+ if ($this->etag) $headers[] = 'If-None-Match: '.$this->etag;
+ if ($this->last_modified) $headers[] = 'If-Modified-Since: '.$this->last_modified;
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $this->url);
+ curl_setopt($ch, CURLOPT_HEADER, true);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
+
+ $http_response = curl_exec($ch);
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $http_body = '';
+ $http_headers = array();
+
+ curl_close($ch);
+
+ $lines = explode("\r\n", $http_response);
+ $body_start = 0;
+ $i = 0;
+
+ foreach ($lines as $line) {
+
+ if ($line === '') {
+
+ $body_start = $i;
+ break;
+ }
+ else if (($p = strpos($line, ':')) !== false) {
+
+ $key = substr($line, 0, $p);
+ $value = substr($line, $p + 1);
+
+ $http_headers[trim($key)] = trim($value);
+ }
+
+ $i++;
+ }
+
+ $http_body = implode("\r\n", array_splice($lines, $i + 1));
+ }
+
+ return array(
+ 'status' => $http_code,
+ 'body' => $http_body,
+ 'headers' => $http_headers
+ );
+ }
+}
\ No newline at end of file
From f2adbeb2a41430f28a3427ddb4365c4075e9296a Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 21:15:42 -0400
Subject: [PATCH 23/48] Add support for HTTP caching with Etag and LastModified
---
miniflux/common.php | 2 +-
miniflux/model.php | 112 ++++++++++++++++++++++++++++----------------
miniflux/schema.php | 11 ++++-
3 files changed, 82 insertions(+), 43 deletions(-)
diff --git a/miniflux/common.php b/miniflux/common.php
index 6f1f988..806aab6 100644
--- a/miniflux/common.php
+++ b/miniflux/common.php
@@ -9,7 +9,7 @@ require 'schema.php';
require 'model.php';
-const DB_VERSION = 1;
+const DB_VERSION = 2;
const APP_VERSION = 'master';
const APP_USERAGENT = 'Miniflux - http://miniflux.net';
const HTTP_TIMEOUT = 5;
diff --git a/miniflux/model.php b/miniflux/model.php
index 5f83a77..8f4cecb 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -64,7 +64,7 @@ function import_feeds($content)
function import_feed($url)
{
$reader = new Reader;
- $reader->download($url, HTTP_TIMEOUT, APP_USERAGENT);
+ $resource = $reader->download($url, '', '', HTTP_TIMEOUT, APP_USERAGENT);
$parser = $reader->getParser();
@@ -72,15 +72,14 @@ function import_feed($url)
$feed = $parser->execute();
- if (! $feed->title || ! $feed->url) {
-
- return false;
- }
+ if ($feed === false) return false;
+ if (! $feed->title || ! $feed->url) return false;
$db = \PicoTools\singleton('db');
if (! $db->table('feeds')->eq('feed_url', $reader->getUrl())->count()) {
+ // Etag and LastModified are added the next update
$rs = $db->table('feeds')->save(array(
'title' => $feed->title,
'site_url' => $feed->url,
@@ -101,6 +100,62 @@ function import_feed($url)
}
+function update_feeds()
+{
+ foreach (get_feeds_id() as $feed_id) {
+
+ update_feed($feed_id);
+ }
+}
+
+
+function update_feed($feed_id)
+{
+ $feed = get_feed($feed_id);
+
+ $reader = new Reader;
+
+ $resource = $reader->download(
+ $feed['feed_url'],
+ $feed['last_modified'],
+ $feed['etag'],
+ HTTP_TIMEOUT,
+ APP_USERAGENT
+ );
+
+ if (! $resource->isModified()) {
+
+ return true;
+ }
+
+ $parser = $reader->getParser();
+
+ if ($parser !== false) {
+
+ $feed = $parser->execute();
+
+ if ($feed !== false) {
+
+ update_feed_cache_infos($feed_id, $resource->getLastModified(), $resource->getEtag());
+ update_items($feed_id, $feed->items);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+function get_feeds_id()
+{
+ return \PicoTools\singleton('db')
+ ->table('feeds')
+ ->asc('updated')
+ ->listing('id', 'id');
+}
+
+
function get_feeds()
{
return \PicoTools\singleton('db')
@@ -119,10 +174,21 @@ function get_feed($feed_id)
}
+function update_feed_cache_infos($feed_id, $last_modified, $etag)
+{
+ \PicoTools\singleton('db')
+ ->table('feeds')
+ ->eq('id', $feed_id)
+ ->save(array(
+ 'last_modified' => $last_modified,
+ 'etag' => $etag
+ ));
+}
+
+
function remove_feed($feed_id)
{
$db = \PicoTools\singleton('db');
-
$db->table('items')->eq('feed_id', $feed_id)->remove();
return $db->table('feeds')->eq('id', $feed_id)->remove();
@@ -263,40 +329,6 @@ function flush_read()
}
-function update_feeds()
-{
- foreach (get_feeds() as $feed) {
-
- $reader = new Reader;
- $reader->download($feed['feed_url'], HTTP_TIMEOUT, APP_USERAGENT);
- $parser = $reader->getParser();
-
- if ($parser !== false) {
-
- update_items($feed['id'], $parser->execute()->items);
- }
- }
-}
-
-
-function update_feed($feed_id)
-{
- $feed = get_feed($feed_id);
-
- $reader = new Reader;
- $reader->download($feed['feed_url'], HTTP_TIMEOUT, APP_USERAGENT);
- $parser = $reader->getParser();
-
- if ($parser !== false) {
-
- update_items($feed['id'], $parser->execute()->items);
- return true;
- }
-
- return false;
-}
-
-
function update_items($feed_id, array $items)
{
$db = \PicoTools\singleton('db');
diff --git a/miniflux/schema.php b/miniflux/schema.php
index c47f16d..e446af3 100644
--- a/miniflux/schema.php
+++ b/miniflux/schema.php
@@ -2,13 +2,20 @@
namespace Schema;
+
+function version_2($pdo)
+{
+ $pdo->exec('ALTER TABLE feeds ADD COLUMN last_modified TEXT');
+ $pdo->exec('ALTER TABLE feeds ADD COLUMN etag TEXT');
+}
+
+
function version_1($pdo)
{
$pdo->exec("
CREATE TABLE config (
username TEXT DEFAULT 'admin',
- password TEXT,
- history INTEGER DEFAULT '15'
+ password TEXT
)
");
From 4f9fcfe573f05d9ecf6b96f03f40e53812ed19cf Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 21:16:34 -0400
Subject: [PATCH 24/48] Add HTTPS url for Youtube and Vimeo for CSP
---
miniflux/index.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index b9425b1..9431761 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -27,7 +27,7 @@ Router\before(function($action) {
Response\csp(array(
'img-src' => '*',
- 'frame-src' => 'http://www.youtube.com http://player.vimeo.com'
+ 'frame-src' => 'http://www.youtube.com https://www.youtube.com http://player.vimeo.com https://player.vimeo.com'
));
Response\xframe();
From b854be546b949654c62b44952191babd500f6bb5 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 22:21:16 -0400
Subject: [PATCH 25/48] Add confirmation box before flush
---
miniflux/index.php | 8 ++++++++
miniflux/templates/confirm_flush.php | 10 ++++++++++
miniflux/templates/read_items.php | 2 +-
3 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 miniflux/templates/confirm_flush.php
diff --git a/miniflux/index.php b/miniflux/index.php
index 9431761..ecdd2ec 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -212,6 +212,14 @@ Router\get_action('mark-as-read', function() {
});
+Router\get_action('confirm-flush-history', function() {
+
+ Response\html(Template\layout('confirm_flush', array(
+ 'menu' => 'history'
+ )));
+});
+
+
Router\get_action('flush-history', function() {
Model\flush_read();
diff --git a/miniflux/templates/confirm_flush.php b/miniflux/templates/confirm_flush.php
new file mode 100644
index 0000000..5a15913
--- /dev/null
+++ b/miniflux/templates/confirm_flush.php
@@ -0,0 +1,10 @@
+
+
+Do you really want to remove these items from your history?
+
+
\ No newline at end of file
diff --git a/miniflux/templates/read_items.php b/miniflux/templates/read_items.php
index ada3c3d..1944e81 100644
--- a/miniflux/templates/read_items.php
+++ b/miniflux/templates/read_items.php
@@ -7,7 +7,7 @@
From 1d7f4b3f9b390c947596cbe014891c1475c74159 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 6 Apr 2013 23:29:24 -0400
Subject: [PATCH 26/48] Add favicon
---
miniflux/assets/img/favicon.png | Bin 0 -> 847 bytes
miniflux/assets/img/touch-icon-ipad-retina.png | Bin 0 -> 2181 bytes
miniflux/assets/img/touch-icon-ipad.png | Bin 0 -> 1152 bytes
.../assets/img/touch-icon-iphone-retina.png | Bin 0 -> 1801 bytes
miniflux/assets/img/touch-icon-iphone.png | Bin 0 -> 947 bytes
miniflux/favicon.ico | Bin 0 -> 16958 bytes
miniflux/templates/app_header.php | 6 ++++++
7 files changed, 6 insertions(+)
create mode 100644 miniflux/assets/img/favicon.png
create mode 100644 miniflux/assets/img/touch-icon-ipad-retina.png
create mode 100644 miniflux/assets/img/touch-icon-ipad.png
create mode 100644 miniflux/assets/img/touch-icon-iphone-retina.png
create mode 100644 miniflux/assets/img/touch-icon-iphone.png
create mode 100644 miniflux/favicon.ico
diff --git a/miniflux/assets/img/favicon.png b/miniflux/assets/img/favicon.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f96f55f614026671aff691b286e67a3fa77b2ae
GIT binary patch
literal 847
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=EX7WqAsj$Z!;#Vf4nJ
zu&IMEqi@KK<3K^l64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{O&Um^w
zhE&XXJIgvdBv7Pvzw$Bh3;`EaA(!AISq=h@jsh;xf(H+Ug>2Xo77&ob-1I}bN#dee
z>x~~Sf;?(%513Ut1p}RX)~7_?@!T`>Ov<^P{M#(j59&SJ^nF&T{kht67M@!+O^amT
z5XO=qdmu`%p_C!pmEjuW8d1gw6hU46(>E-)bKYRhS$mD=!>%ZOmEP1ZcNsz&au1Xx
z@P61B<=?QJtKvxM*1hL;+9m9L{)g4GJo_0x)AEMH4$;j!?;r48;C`ug{ep9Ena?q}
zPyfIw!CcjNdXk-q>9j2i8VViemFk#Y=exr(WA19}1GjF;Xx`U7u$O1w{6
z%D_;@q%7%l?rQOZ&3@CI54iBfGunoPS7|adtYdQGs$k!;yhujfGXKd}(Sm(C49go2
zHaT(am=_gzpXDur%-qQjO6F%bsyel+{6E27Tc{Zwhwck+{migJaJ8nj`jW9U)=wXVZnR-1*Z>hx4!V*p=w{p}1vXNUj*
literal 0
HcmV?d00001
diff --git a/miniflux/assets/img/touch-icon-ipad-retina.png b/miniflux/assets/img/touch-icon-ipad-retina.png
new file mode 100644
index 0000000000000000000000000000000000000000..92da239feb4b3bb1d8a04d754343b41557801722
GIT binary patch
literal 2181
zcmcImdsNcd7BpZ7+Zj@wxO
zXp&U_G5X8&`}v&VZmMMId|PL=>(b|HB_(p8e;`Q9u{8RN
zHkh*;yyYkYd?6RHe%*PHwzl#5_0}Me&z3Ehz<NB@pQB40>}#r&z=48FISnc3shZ)|KJkehvdK5aKv3J_pKYgA7|ON-st1?gs8
z?R9z^@{Yh@f#}APD)jyioSk5Bu)eFyZ6T|>w5%+C8MaoK3xmP#*4O9HiF$&qtgKX1
ze51j&Q8D3ITAD+Oh*NE2Yn!B5km`lQ*aVlL`}gmYzkNx`nwRKy=d5|iTn{@svK~J!
zZO01(HyZ7{GcXXOYr9g7dKm?QQ)aeNs8rhse+mU^<(Z9JoEH4Z~nqb2cx{
zn{gf2F8eEpk*ApPyBu(M1L?rU!YxSMRM$)-+?hHEpG&a2X-NZ!ZSWARpsqB)A
zy*%0r}-3wko4jz=!
z>4w6gd{?x#xrN2lqI{U-<#pkJMQwTci|`hlv1eYY@ELDWHs~m|wC3WUki5O~rrq{E
zq9O9~@^F!n_?ZU3e!3MrBO}8_hB7SR(muX*7#Z_S`}gSR!t!#)fc$Vpz0Sh7l`gU(
zbj10r3NMPz$x_ce>DJ5ly523Xz&A(rWFwcn
zuj@@qcts7Vam}&nnKwNt-xVW`sHl-3zFIjp<$Uw?>(KV`GYzSdAS8+8=;-JSg;sD(
z|L_kEmKPTnFY7~U3dWSup&@j72d<&j7uFKdc`#caa=9wa;wj)eRewI$0Z5-_7x(3?t)6?QreD1}FYKfq{C1-E<9J)g
zvuDg&x6G|-UgzXwqz84bN^GBo;DR*}JH6x?EsIV}|s9;(|<#5HHuMF3-
z*<~gsCI*2vzB%fYqL0v)QF3CAXDT
zozzdG6b_5_ec9pbQLJ4hat(BL`E%WJsOR|fG-P5n-Fuj;ATKlq*OEPN)Ya`q2L^_6
zR!#P!eIkmaEeH!|{2c((8IM*Wz7e3MP+pBjp$zI98?zdCh$Qc_Z&yf$&T#ywCT
z91su!^9-@v@L^F?I+PlR;PH5Yaw@DkP`=+9wM+3J456#53q(4FfpSJUoN5;z7Y8|~
zzh^bQ*!21)$bka^nyYm}d^jxUH)H$l1I+lV3?gP9xOJ?FcKljNN!ie@hrjalq>MW0
zY99zlfW!ZxiQVzTzi#;!m3nT_X7)*m2XgdpXa8oF)>>6}eY3M$LJ5Z)|S<=izk<^?6&{LlR$)rUyZY9Fww7
z=P?F4nJ
zu)P6cM!8Z8Q=p(^iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa~te?46s
zLn`LHon`M)lrM6;f9Ar!7rk^ZI{spw)+qGwfl`Zj4AXQr>07c{d|3rNvldTlJFqlk
z^}?vGX$oB&T8b+S7Pd{h!lb=x-u)-1SAQ#eSA4&^`tk9f2R7TxdtM`Ncd!1Dse%&I
zXLqT8U)k!cbUGSX1ve-#iMbqT;)oDn>WI+>jTzrpllg{C9-^}LBo9CoAy*WmY
z{b!9_j+u0YjT{FHlY*xZ3lrm2$yO)EZQHgz`1Va~(@mX}&5;^Yy&e=;9C%scl%KDE
zB*{=hQnIm)?O-xfw#V|zFTPf_9=mukFjsod{{6>8v|8o**%=#T4kiego0+}(Rde*{
zQC79do;jJBfm0q9SQM0%iE+0!J?gP?^!E1dI#egm&dwfcd+qx5i&w^(tO)>#kkD{x*3n6#|-bReF6-VaJ_P6eTd^!We
zx%21i=PN``E6mC9ncN$`@9F8&r&sNL`|h2V-P|dCt*x!^1x;*i*S
z9UbA};TfB6nw&S7=~Gcwwru@^j~@%qn#W0YcX!V?|NP?f&o8G5^03v{3hv^#R2;E3
zOh#7rs%?6D`tx8%`+trbBXkb^`?v3%rM9;A{By6rEyysMsUX17aQkgrdpo;@y?y)l
z@8xHUtE#FN?B6dhAPDq|!u<2AUv1vGlk;ej;F_@Puk2CtlX`o5XLv3B@bTluRqtQF
z*4ES4Uwkp+%9AM_Zi_2wYGS4a>P`Rn;e){4yzQ&zRaaO4ifcZTR(#hvSvNa7yIwav
zE9+Iic&N*f-Mg(zcE%j4wcq_TTT5fEU%e)~VBoaWEw|sUGFI{Y739~tbEoCQdz~&$
z_Kpt=X51-hbx~TVbvVN$No{iAl)~EDUbbe(74<4YD_<|Z8Jm-q=2n<%A{9DSu>W{s
zK|w%ZZhXA_ju^d#|5}|E=J^Rbu3fuUp!=xEbzst8eX8^LW2djNv9V5HcX4*PC?%N9
z7QKG`u9v8i=cItWD;7L|{(P6EFAFa(FXz?mTeotimz0$?-F_<;^|-{U_0{R8MR(_@
zHPzV757;|P`NaG0-0K~A
zR|{nkF3zjW3_dQ&DGlGIP6
literal 0
HcmV?d00001
diff --git a/miniflux/assets/img/touch-icon-iphone-retina.png b/miniflux/assets/img/touch-icon-iphone-retina.png
new file mode 100644
index 0000000000000000000000000000000000000000..71de36e3523345f78f32f4a2216ca503519c6d60
GIT binary patch
literal 1801
zcmb_diC5BT7yi}vRSvm~C4!*VAYW<@VkGWqR(y%6V{RiEY7J-%CMp-!Su@=f3y6&$;h8_qp%A=l#{+@3Z41NrWGqOU
zun3{7Kt>dceI|hlu-R-|S}dLU-I+M5Eh8biV8#sr0NXQ($2^0Q1Ro0{yaE~Uu2xM&
zRd&?NYt%_ZNMBobX?hkaeXB)QsmGV$tdgJL$GBDLI$5aZ1KyQZQ>aUOpD1zV=?hVg
zVgjk%cw66_y-+e!y-I$*LVJ8`M(V6quC}En>W?m`ju@zu8kr6|4GnV%{Ql{!5QF^z
zI{zFO>UOSUT7TGh*2Uj5ujn$+H88L+=XWUP+Z6MWAA0gCD=Y0DA`QPX)&DLs67b+^
zpU=(NndQ;6VvjFnQLaEYT!eCgq6`VNyRr}nT#i7jGm=X&-^RmX8
zr5Z{KrMRZXusWhOs$hEQqim>|&3M5n6Nu1$hvxZn53%Pw-NRA^~EJ6TS9Dl
zO(-muk(rsA&^M%@USkw>pI7|r%k(|`2vtlPEC2c4h{{$$xo7U
zKrt#od*sz34{njtZUSx06ECU;@0OQeYCr;~9Lv^o(UL;Q%gdYQ
z*(ciL@#2-0l_xMOBgjcR_#ZS!Ac#!%<#0IanH$eoIbb4`I%&dF|GS-QYm2G~?CS>l
zU^ghWPY-~?U=kh-JI=`QF;1QtcJ45?#&7)z;H-Z7pQ7}+BHkr&DtAl{_@6v!n8;>h
z&2wP3r|qaEz}3;&3awU4;yZ&`KILe9RNH?%Z3}BjUAEmMG&VNge(VpN>n%Ez>$9)I
zjDfpVZgKp|%@I8yI5=25IeAWdd3tIJ$H@s$^yJw{t_Yi&qzit5UDCQ}bs!}y44Ld^
zE`eF$ArOd_ss3(5v7(FbJFA|Eb24233%9(B`?nvQO!af~^3L?%3!Y1IgTvv6(YxB;y(^aX1As$;p8IbGR4R2Yr3H>a96|5$
zv`4&>3dZ8#CH^{LjWNX5z^4KWI-RZ@>-gCohr^W}2UR;VMsB8L3*#04|DM69IA`xt
zHv0ZOdU0u~Ph57K>9F~#!0}*_g)dBbp;-wsCMWzpv|rqj38|NTWGznhn=s7F6{72w
zl!jB%)Hj2J6V=^)eSO%g6e@ms13MwFe)urE}G
zs6zqfeik?aU=)o;6RlMV5AXdEPam+uulaJh+_&d5c?+v)PH8J~1J3>Z{krF)CKi;E
zubq(&F_9wT{Dx+^UZx96o_psR`gQ&TCfG@rc{~$@Z?xo&uN4*>ExPyM0YyYS;O<^@
zpBJ|%pWuskD=A=%#G
zVRo)?gd7)LsB&2|#&VH<%Ev~$&d)=^b!({@Qtc(oPQa>Tuot=in&$m%oKvVe&3(_4
zaBNt(r{|Wifz$B)wfF8_#`9B4oFcLhk9%YcgA6#Bc)kWI;=G31fY*94*FK!NZJm{!
zT{BL7=ARQQEWq3;+Dd`2_?
literal 0
HcmV?d00001
diff --git a/miniflux/assets/img/touch-icon-iphone.png b/miniflux/assets/img/touch-icon-iphone.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a46c5e15b3184a611865756cf52d29e50a35e4f
GIT binary patch
literal 947
zcmV;k15EshP)tGbe|80WBXSHZsp#+LUz!zAsIMlj`;8qu%
z1a%Tb?VyW`o2xiF6a*J1cNfK1aTNz~C?Zk>-F!i`$+?r>n_Jo*)7;m0zdw9K(sO<}
zza+Fx>mee7;PL+H0e(lMq$rV+qC`rH5-BN4q@*ZOe+AUCEZp7Q!7vPHng&&^?lAA~
z@3^_SfvTzq27{=ptNT*F?dX@6m)P6etJtLLIz~rFZTs^1JTjRKc6N4<%jNL)_67h@
z6a|{5A(>2KVPOHWSd2B;(a{k$H#d>ZW^sFa3)3_|Ukimo7#SHsDwV?6*cdz>Pk9*q
zkgcsP0#I>HOiXTo@iBFEb+K3gsIRY&ve|4&9uZMh
zlDS-tVzC%|ppO*{2I=hVtZ10^^>tEJ^~*e;&quqvyY5RqJUmb|8vXJ>AFH;umd?-5
zKaZVGrya8ZkfJDba&qFHWGa=SL?ThuPyi?%kCSPdl*weOW&xm%jt+Wxd2vV5>-D-a
z6abo@o~D|b8rOIm8yoIO{>`hWr>98LmCs3C*O5ph(BI#Wd_Ir;{e7ICo;v15qfrbF
z4q{+n0QdLzI5;@K;o%{x_u}FLS65fib^ZI!YOmz#>T1!Mvn-3|=jR<=iMhEsvMj5J
zxxBp0W^8Y7yLY>;t*sRe^O4urSMvFMU*at-EtTY%rb&@VgvCjx)9y%Wnnr~}q2y3R
zM8m_wY@Xlmr|0MAvb>d*6&7oJeB9RO_zU{%>?{;TDO(ed$JxBe$w}1L*O#s7?(Sx>
z9v>fV+m0n?W@akZw6wIac~etU6>C~sTUo59rzhLCBT2vCk5DMYs^iA?Zdf9LK!C+6
z6biO&N0ROB?W{VkWOH*f8X6iZ);WD-b0irKhgo%vjg73jNF>6lGYo@O_j4RcwzakK
z;9ee{d(z0^e^ZVmxx;f)>0P?o{1?CRNJ&v5B}Ivp6eUtplt@WYA|*wM?I|=I4r6F&
zsA5xRXD16D2n1NX-rimouc@iY(R?0q`jGYy<-fRHrKBj4lA=UPiV`U)N~EMH`37$~
VDbR5txDWXF
z;L-fU)?U_0*FW&@C(M=VKU`P(`47~U>}5Q<|AlKy_kWMJ(2|~i;abx3&!eUMJxk9&
zJ^#@_$af08|LgZ3z5fO7t9t*N(fjZ2{2Awak39c|d|Y-L+%t9mKWxWRR42xR5&Qpe
z5s%9b@3RQ*X5RnHu6SHF;yW4<<0!r@E*_T+-^UT$&CLIrD;}4P_)bN{C?D#zE*_T+
z-=`7W&CLI~D;}4P_%21nDESY#cw9DoW4^QPadBj}NG^$URo2&6;x`DyKNRu|;9FR{J?OY%JVciK*ZET`D=c%Cc&E@OhB2<~tA
z&dGDw@3c3PzvT1@><9BRPTpnR&w<#SZU4J)Y|QbtP%nWRuzh{?M;S*^316f6XXDCV
z^d5YUj4kW$E5E>513w$&K3|k~W`}pG`TOFZ$u_xDt;q5$DkJl+H@FT(^B^(yfwxWO
zmGK@F<(#+U7qk8Y_`hgktXCx#o;BcW6M4VG<=ywQIlwO_|9fFk`JF&To>i9}DR|fb?=XFi*nE@K>2n8E15vX1=(io*0`i%289Oe9`Yu4W~F)u7%}`BQcpvqkD-PgZtHeXcQ`^~9KY#`M&aidkk%xt>%_&sbSA
Y
+
+
+
+
+
+
miniflux
From 96f63df2a1c4ac09948fad0e02bddbbbe3df416e Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sun, 7 Apr 2013 10:57:38 -0400
Subject: [PATCH 27/48] Change a border
---
miniflux/assets/css/app.css | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/miniflux/assets/css/app.css b/miniflux/assets/css/app.css
index fdcf255..c612f66 100644
--- a/miniflux/assets/css/app.css
+++ b/miniflux/assets/css/app.css
@@ -509,7 +509,7 @@ section li {
.logo {
display: block;
float: none;
- border-bottom: 1px solid #ccc;
+ border-bottom: 1px dotted #ddd;
}
header {
@@ -528,7 +528,7 @@ section li {
display: block;
line-height: 25px;
}
-
+
nav ul {
padding-top: 5px;
}
@@ -537,7 +537,7 @@ section li {
clear: both;
padding-top: 20px;
}
-
+
.page li {
margin-left: 5px;
}
From b5dc1609a9ad8a0ca10f89c299540979af2d1b1e Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sun, 7 Apr 2013 10:57:57 -0400
Subject: [PATCH 28/48] Change error message
---
miniflux/index.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index ecdd2ec..8a72626 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -264,7 +264,7 @@ Router\post_action('add', function() {
}
else {
- Session\flash_error('Unable to find a subscription or parsing error.');
+ Session\flash_error('Unable to find a subscription.');
}
Response\html(Template\layout('add', array(
From 5f7480c52c66621c9dd515d4b51e79485c66b7dd Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sun, 7 Apr 2013 10:58:28 -0400
Subject: [PATCH 29/48] Remove useless inclusion
---
miniflux/model.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/miniflux/model.php b/miniflux/model.php
index 8f4cecb..09873c5 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -4,7 +4,6 @@ namespace Model;
require_once 'vendor/PicoFeed/Export.php';
require_once 'vendor/PicoFeed/Import.php';
-require_once 'vendor/PicoFeed/Parser.php';
require_once 'vendor/PicoFeed/Reader.php';
require_once 'vendor/SimpleValidator/Validator.php';
require_once 'vendor/SimpleValidator/Base.php';
From 6aa0aaa724c6318d598c4df4d7c6984964d434e0 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sun, 7 Apr 2013 10:58:46 -0400
Subject: [PATCH 30/48] Update of picoFeed
---
miniflux/vendor/PicoFeed/Filter.php | 11 +++-
miniflux/vendor/PicoFeed/Parsers/Rss10.php | 77 +++++++++++-----------
miniflux/vendor/PicoFeed/Parsers/Rss20.php | 76 ++++++++++-----------
3 files changed, 83 insertions(+), 81 deletions(-)
diff --git a/miniflux/vendor/PicoFeed/Filter.php b/miniflux/vendor/PicoFeed/Filter.php
index 3f16272..2c9454e 100644
--- a/miniflux/vendor/PicoFeed/Filter.php
+++ b/miniflux/vendor/PicoFeed/Filter.php
@@ -73,7 +73,16 @@ class Filter
'rss.nytimes.com',
'feeds.wordpress.com',
'stats.wordpress.com',
- 'rss.cnn.com'
+ 'rss.cnn.com',
+ 'twitter.com/home?status=',
+ 'twitter.com/share',
+ 'twitter_icon_large.png',
+ 'www.facebook.com/sharer.php',
+ 'facebook_icon_large.png',
+ 'plus.google.com/share',
+ 'www.gstatic.com/images/icons/gplus-16.png',
+ 'www.gstatic.com/images/icons/gplus-32.png',
+ 'www.gstatic.com/images/icons/gplus-64.png'
);
public $required_attributes = array(
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss10.php b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
index 969ab8c..000119c 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Rss10.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
@@ -18,15 +18,15 @@ class Rss10 extends Parser
return false;
}
- $ns = $xml->getNamespaces(true);
+ $namespaces = $xml->getNamespaces(true);
$this->title = (string) $xml->channel->title;
$this->url = (string) $xml->channel->link;
$this->id = $this->url;
- if (isset($ns['dc'])) {
+ if (isset($namespaces['dc'])) {
- $ns_dc = $xml->channel->children($ns['dc']);
+ $ns_dc = $xml->channel->children($namespaces['dc']);
$this->updated = isset($ns_dc->date) ? strtotime($ns_dc->date) : time();
}
else {
@@ -36,43 +36,46 @@ class Rss10 extends Parser
foreach ($xml->item as $entry) {
- $author = '';
- $content = '';
- $pubdate = '';
- $link = '';
-
- if (isset($ns['feedburner'])) {
-
- $ns_fb = $entry->children($ns['feedburner']);
- $link = $ns_fb->origLink;
- }
-
- if (isset($ns['dc'])) {
-
- $ns_dc = $entry->children($ns['dc']);
- $author = (string) $ns_dc->creator;
- $pubdate = (string) $ns_dc->date;
- }
-
- if (isset($ns['content'])) {
-
- $ns_content = $entry->children($ns['content']);
- $content = (string) $ns_content->encoded;
- }
-
- if ($content === '' && isset($entry->description)) {
-
- $content = (string) $entry->description;
- }
-
$item = new \StdClass;
$item->title = (string) $entry->title;
- $item->url = $link ?: (string) $entry->link;
- $item->id = $item->url;
- $item->updated = $pubdate ? strtotime($pubdate) : time();
- $item->content = $this->filterHtml($content, $item->url);
- $item->author = $author ?: (string) $xml->channel->webMaster;
+ $item->url = '';
+ $item->author= '';
+ $item->updated = '';
+ $item->content = '';
+ foreach ($namespaces as $name => $url) {
+
+ $namespace = $entry->children($namespaces[$name]);
+
+ if (! $item->url && ! empty($namespace->origLink)) $item->url = (string) $namespace->origLink;
+ if (! $item->author && ! empty($namespace->creator)) $item->author = (string) $namespace->creator;
+ if (! $item->updated && ! empty($namespace->date)) $item->updated = strtotime((string) $namespace->date);
+ if (! $item->updated && ! empty($namespace->updated)) $item->updated = strtotime((string) $namespace->updated);
+ if (! $item->content && ! empty($namespace->encoded)) $item->content = (string) $namespace->encoded;
+ }
+
+ if (empty($item->url)) $item->url = (string) $entry->link;
+ if (empty($item->updated)) $item->updated = $this->updated;
+
+ if (empty($item->content)) {
+
+ $item->content = isset($entry->description) ? (string) $entry->description : '';
+ }
+
+ if (empty($item->author)) {
+
+ if (isset($entry->author)) {
+
+ $item->author = (string) $entry->author;
+ }
+ else if (isset($xml->channel->webMaster)) {
+
+ $item->author = (string) $xml->channel->webMaster;
+ }
+ }
+
+ $item->id = $item->url;
+ $item->content = $this->filterHtml($item->content, $item->url);
$this->items[] = $item;
}
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss20.php b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
index 7fced40..7ac6595 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Rss20.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
@@ -9,7 +9,6 @@ class Rss20 extends Parser
$this->content = $this->normalizeData($this->content);
\libxml_use_internal_errors(true);
-
$xml = \simplexml_load_string($this->content);
if ($xml === false) {
@@ -18,73 +17,64 @@ class Rss20 extends Parser
return false;
}
- $ns = $xml->getNamespaces(true);
+ $namespaces = $xml->getNamespaces(true);
$this->title = (string) $xml->channel->title;
$this->url = (string) $xml->channel->link;
$this->id = $this->url;
$this->updated = isset($xml->channel->pubDate) ? (string) $xml->channel->pubDate : (string) $xml->channel->lastBuildDate;
-
- if ($this->updated) {
-
- $this->updated = strtotime($this->updated);
- }
- else {
-
- $this->updated = time();
- }
+ $this->updated = $this->updated ? strtotime($this->updated) : time();
foreach ($xml->channel->item as $entry) {
- $author = '';
- $content = '';
- $pubdate = '';
- $link = '';
+ $item = new \StdClass;
+ $item->title = (string) $entry->title;
+ $item->url = '';
+ $item->author= '';
+ $item->updated = '';
+ $item->content = '';
- if (isset($ns['feedburner'])) {
+ foreach ($namespaces as $name => $url) {
- $ns_fb = $entry->children($ns['feedburner']);
- $link = $ns_fb->origLink;
+ $namespace = $entry->children($namespaces[$name]);
+
+ if (! $item->url && ! empty($namespace->origLink)) $item->url = (string) $namespace->origLink;
+ if (! $item->author && ! empty($namespace->creator)) $item->author = (string) $namespace->creator;
+ if (! $item->updated && ! empty($namespace->date)) $item->updated = strtotime((string) $namespace->date);
+ if (! $item->updated && ! empty($namespace->updated)) $item->updated = strtotime((string) $namespace->updated);
+ if (! $item->content && ! empty($namespace->encoded)) $item->content = (string) $namespace->encoded;
}
- if (isset($ns['dc'])) {
+ if (empty($item->url)) $item->url = (string) $entry->link;
+ if (empty($item->updated)) $item->updated = strtotime((string) $entry->pubDate) ?: $this->updated;
- $ns_dc = $entry->children($ns['dc']);
- $author = (string) $ns_dc->creator;
- $pubdate = (string) $ns_dc->date;
+ if (empty($item->content)) {
+
+ $item->content = isset($entry->description) ? (string) $entry->description : '';
}
- if (isset($ns['content'])) {
-
- $ns_content = $entry->children($ns['content']);
- $content = (string) $ns_content->encoded;
- }
-
- if ($content === '' && isset($entry->description)) {
-
- $content = (string) $entry->description;
- }
-
- if ($author === '') {
+ if (empty($item->author)) {
if (isset($entry->author)) {
- $author = (string) $entry->author;
+ $item->author = (string) $entry->author;
}
else if (isset($xml->channel->webMaster)) {
- $author = (string) $xml->channel->webMaster;
+ $item->author = (string) $xml->channel->webMaster;
}
}
- $item = new \StdClass;
- $item->title = (string) $entry->title;
- $item->url = $link ?: (string) $entry->link;
- $item->id = isset($entry->guid) ? (string) $entry->guid : $item->url;
- $item->updated = strtotime($pubdate ?: (string) $entry->pubDate) ?: $this->updated;
- $item->content = $this->filterHtml($content, $item->url);
- $item->author = $author;
+ if (isset($entry->guid) && isset($entry->guid['isPermaLink']) && (string) $entry->guid['isPermaLink'] != 'false') {
+ $item->id = (string) $entry->guid;
+ }
+ else {
+
+ $item->id = $item->url;
+ }
+
+ $item->content = $this->filterHtml($item->content, $item->url);
$this->items[] = $item;
}
From 58227aa091dcf4f5f209023eeaf0644f861a4ba3 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 12 Apr 2013 15:57:54 -0400
Subject: [PATCH 31/48] Update of picoFeed for bugfix
---
miniflux/index.php | 2 +-
miniflux/vendor/PicoFeed/Filter.php | 17 +++++++++++++++--
miniflux/vendor/PicoFeed/Parsers/Rss20.php | 19 ++++++++++++++++++-
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index 8a72626..2c53592 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -22,7 +22,7 @@ Router\before(function($action) {
if ($action !== 'login' && ! isset($_SESSION['user'])) {
- PicoFarad\Response\redirect('?action=login');
+ Response\redirect('?action=login');
}
Response\csp(array(
diff --git a/miniflux/vendor/PicoFeed/Filter.php b/miniflux/vendor/PicoFeed/Filter.php
index 2c9454e..65206e4 100644
--- a/miniflux/vendor/PicoFeed/Filter.php
+++ b/miniflux/vendor/PicoFeed/Filter.php
@@ -55,8 +55,11 @@ class Filter
'http://',
'https://',
'ftp://',
- 'mailto://',
- '//'
+ 'mailto:',
+ '//',
+ 'data:image/png;base64,',
+ 'data:image/gif;base64,',
+ 'data:image/jpg;base64,'
);
public $protocol_attributes = array(
@@ -169,6 +172,14 @@ class Filter
}
else if ($this->isAllowedProtocol($value) && ! $this->isBlacklistMedia($value)) {
+ if ($attribute == 'src' &&
+ isset($attributes['data-src']) &&
+ $this->isAllowedProtocol($attributes['data-src']) &&
+ ! $this->isBlacklistMedia($attributes['data-src'])) {
+
+ $value = $attributes['data-src'];
+ }
+
$attr_data .= ' '.$attribute.'="'.$value.'"';
$used_attributes[] = $attribute;
}
@@ -264,6 +275,8 @@ class Filter
public function isRelativePath($value)
{
+ if (strpos($value, 'data:') === 0) return false;
+
return strpos($value, '://') === false && strpos($value, '//') !== 0;
}
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss20.php b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
index 7ac6595..bc04d84 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Rss20.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
@@ -19,8 +19,25 @@ class Rss20 extends Parser
$namespaces = $xml->getNamespaces(true);
+ if ($xml->channel->link->count() > 1) {
+
+ foreach ($xml->channel->link as $xml_link) {
+
+ $link = (string) $xml_link;
+
+ if ($link !== '') {
+
+ $this->url = (string) $link;
+ break;
+ }
+ }
+ }
+ else {
+
+ $this->url = (string) $xml->channel->link;
+ }
+
$this->title = (string) $xml->channel->title;
- $this->url = (string) $xml->channel->link;
$this->id = $this->url;
$this->updated = isset($xml->channel->pubDate) ? (string) $xml->channel->pubDate : (string) $xml->channel->lastBuildDate;
$this->updated = $this->updated ? strtotime($this->updated) : time();
From 222b884aad8dc8bd2a5051f9ca3fd889b61eff1c Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 12 Apr 2013 21:08:55 -0400
Subject: [PATCH 32/48] Add french locales
---
miniflux/assets/css/app.css | 14 ++--
miniflux/common.php | 4 +-
miniflux/index.php | 42 +++++++++---
miniflux/locales/fr_FR/translations.php | 87 ++++++++++++++++++++++++
miniflux/model.php | 41 +++++++----
miniflux/schema.php | 6 ++
miniflux/templates/add.php | 14 ++--
miniflux/templates/app_header.php | 10 +--
miniflux/templates/config.php | 41 +++++------
miniflux/templates/confirm_flush.php | 8 +--
miniflux/templates/confirm_remove.php | 8 +--
miniflux/templates/feeds.php | 22 +++---
miniflux/templates/import.php | 12 ++--
miniflux/templates/login.php | 8 +--
miniflux/templates/read_item.php | 20 +++---
miniflux/templates/read_items.php | 12 ++--
miniflux/templates/unread_items.php | 10 +--
miniflux/vendor/PicoTools/Translator.php | 16 ++++-
18 files changed, 258 insertions(+), 117 deletions(-)
create mode 100644 miniflux/locales/fr_FR/translations.php
diff --git a/miniflux/assets/css/app.css b/miniflux/assets/css/app.css
index c612f66..a61064d 100644
--- a/miniflux/assets/css/app.css
+++ b/miniflux/assets/css/app.css
@@ -127,8 +127,6 @@ form {
label {
cursor: pointer;
display: block;
- float: left;
- width: 10em;
}
input {
@@ -144,7 +142,8 @@ input[type="text"] {
line-height: 15px;
width: 250px;
font-size: 99%;
- margin-bottom: 15px;
+ margin-bottom: 10px;
+ margin-top: 5px;
}
input[type="email"]:focus,
@@ -196,14 +195,14 @@ textarea.form-error {
.form-errors {
color: #b94a48;
- margin-left: 10em;
+ margin-left: 15px;
list-style-type: none;
}
.form-help {
font-size: 0.9em;
color: brown;
- display: inline;
+ margin-bottom: 15px;
}
/* alerts */
@@ -346,8 +345,7 @@ nav .active a {
.page-header li {
font-size: 90%;
display: inline;
- padding-left: 10px;
- padding-right: 10px;
+ padding-right: 5px;
border-right: 1px dotted #ccc;
}
@@ -488,7 +486,7 @@ nav .active a {
/* other pages */
section li {
- margin-left: 20px;
+ margin-left: 15px;
list-style-type: square;
}
diff --git a/miniflux/common.php b/miniflux/common.php
index 806aab6..6216aeb 100644
--- a/miniflux/common.php
+++ b/miniflux/common.php
@@ -3,19 +3,19 @@
require 'check_setup.php';
require 'vendor/password.php';
require 'vendor/PicoTools/Dependency_Injection.php';
+require 'vendor/PicoTools/Translator.php';
require 'vendor/PicoDb/Database.php';
require 'vendor/PicoDb/Table.php';
require 'schema.php';
require 'model.php';
-const DB_VERSION = 2;
+const DB_VERSION = 3;
const APP_VERSION = 'master';
const APP_USERAGENT = 'Miniflux - http://miniflux.net';
const HTTP_TIMEOUT = 5;
-// For future use...
function get_db_filename()
{
return 'data/db.sqlite';
diff --git a/miniflux/index.php b/miniflux/index.php
index 2c53592..893adb0 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -25,6 +25,24 @@ Router\before(function($action) {
Response\redirect('?action=login');
}
+ $language = 'en_US';
+
+ if (isset($_SESSION['user']['language'])) {
+
+ $language = $_SESSION['user']['language'];
+ }
+ else if (isset($_COOKIE['language'])) {
+
+ $language = $_COOKIE['language'];
+ }
+
+ if ($language !== 'en_US') {
+
+ PicoTools\Translator\load($language);
+ }
+
+ setcookie('language', $language, time()+365*24*3600, dirname($_SERVER['PHP_SELF']));
+
Response\csp(array(
'img-src' => '*',
'frame-src' => 'http://www.youtube.com https://www.youtube.com http://player.vimeo.com https://player.vimeo.com'
@@ -168,11 +186,11 @@ Router\get_action('remove', function() {
if ($id && Model\remove_feed($id)) {
- Session\flash('This subscription has been removed successfully');
+ Session\flash(t('This subscription has been removed successfully.'));
}
else {
- Session\flash_error('Unable to remove this subscription');
+ Session\flash_error(t('Unable to remove this subscription.'));
}
Response\redirect('?action=feeds');
@@ -230,7 +248,7 @@ Router\get_action('flush-history', function() {
Router\get_action('refresh-all', function() {
Model\update_feeds();
- Session\flash('Your subscriptions are updated');
+ Session\flash(t('Your subscriptions are updated'));
Response\redirect('?action=unread');
});
@@ -259,17 +277,16 @@ Router\post_action('add', function() {
if (Model\import_feed($_POST['url'])) {
- Session\flash('Subscription added successfully.');
+ Session\flash(t('Subscription added successfully.'));
Response\redirect('?action=feeds');
}
else {
- Session\flash_error('Unable to find a subscription.');
+ Session\flash_error(t('Unable to find a subscription.'));
}
Response\html(Template\layout('add', array(
'values' => array('url' => $_POST['url']),
- 'errors' => array('url' => 'Unable to find a news feed.'),
'menu' => 'feeds'
)));
});
@@ -309,14 +326,14 @@ Router\post_action('import', function() {
if (Model\import_feeds(Request\file_content('file'))) {
- Session\flash('Your feeds are imported.');
+ Session\flash(t('Your feeds have been imported.'));
}
else {
- Session\flash_error('Unable to import your OPML file.');
+ Session\flash_error(t('Unable to import your OPML file.'));
}
- Response\redirect('?action=feeds');
+ Response\redirect('?action=import');
});
@@ -326,6 +343,7 @@ Router\get_action('config', function() {
'errors' => array(),
'values' => Model\get_config(),
'db_size' => filesize(get_db_filename()),
+ 'languages' => Model\get_languages(),
'menu' => 'config'
)));
});
@@ -340,11 +358,11 @@ Router\post_action('config', function() {
if (Model\save_config($values)) {
- Session\flash('Your preferences are updated.');
+ Session\flash(t('Your preferences are updated.'));
}
else {
- Session\flash_error('Unable to update your preferences.');
+ Session\flash_error(t('Unable to update your preferences.'));
}
Response\redirect('?action=config');
@@ -353,6 +371,8 @@ Router\post_action('config', function() {
Response\html(Template\layout('config', array(
'errors' => $errors,
'values' => $values,
+ 'db_size' => filesize(get_db_filename()),
+ 'languages' => Model\get_languages(),
'menu' => 'config'
)));
});
diff --git a/miniflux/locales/fr_FR/translations.php b/miniflux/locales/fr_FR/translations.php
new file mode 100644
index 0000000..c944a0d
--- /dev/null
+++ b/miniflux/locales/fr_FR/translations.php
@@ -0,0 +1,87 @@
+ 'Français',
+ 'English' => 'Anglais',
+ 'unread' => 'non lus',
+ 'history' => 'historique',
+ 'subscriptions' => 'abonnements',
+ 'Subscriptions' => 'Abonnements',
+ 'preferences' => 'préférences',
+ 'Preferences' => 'Préférences',
+ 'logout' => 'déconnexion',
+ 'Username' => 'Utilisateur',
+ 'Password' => 'Mot de passe',
+ 'Confirmation' => 'Confirmation',
+ 'Language' => 'Langue',
+ 'Update' => 'Mettre à jour',
+ 'More informations' => 'Plus d\'informations',
+ 'Database' => 'Base de données',
+ 'Database size:' => 'Taille de la base de données :',
+ 'Optimize the database' => 'Optimiser la base de données',
+ '(VACUUM command)' => '(commande SQL VACUUM)',
+ 'Download the entire database' => 'Télécharger la base de données complète',
+ '(Gzip compressed Sqlite file)' => '(Fichier Sqlite compressé en Gzip)',
+ 'Keyboard shortcuts' => 'Raccourcis clavier',
+ 'Previous item' => 'Élément précédent',
+ 'Next item' => 'Élément suivant',
+ 'Mark as read or unread' => 'Marquer comme lu ou non lu',
+ 'Open original link' => 'Ouvrir le lien original',
+ 'Open item' => 'Ouvrir un élément',
+ 'About' => 'A propos',
+ 'Miniflux version:' => 'Version de Miniflux :',
+ 'Nothing to read' => 'Rien à lire',
+ 'Unread items' => 'Éléments non lus',
+ 'mark all as read' => 'tout marquer comme lu',
+ 'original link' => 'lien original',
+ 'mark as read' => 'marquer comme lu',
+ 'No history' => 'Aucun historique',
+ 'mark as unread' => 'marquer comme non lu',
+ 'History' => 'Historique',
+ 'flush these items' => 'supprimer ces éléments',
+ 'Item not found' => 'Élément introuvable',
+ 'Unread items' => 'Éléments non lus',
+ 'Next' => 'Suivant',
+ 'Previous' => 'Précédent',
+ 'Sign in' => 'Connexion',
+ 'feeds' => 'abonnements',
+ 'add' => 'ajouter',
+ 'import' => 'importer',
+ 'export' => 'exporter',
+ 'OPML Import' => 'Importation OPML',
+ 'OPML file' => 'Fichier OPML',
+ 'Import' => 'Importer',
+ 'refresh all' => 'actualiser',
+ 'No subscription' => 'Aucun abonnement',
+ 'remove' => 'supprimer',
+ 'refresh' => 'actualiser',
+ 'feed link' => 'lien du flux',
+ 'New subscription' => 'Nouvel abonnement',
+ 'Website or Feed URL' => 'URL du site ou du flux',
+ 'Add' => 'Ajouter',
+ 'http://website/' => 'http://siteweb/',
+ 'Yes' => 'Oui',
+ 'cancel' => 'annuler',
+ 'or' => 'ou',
+ 'Official website:' => 'Site officiel :',
+ 'Bad username or password' => 'Mauvais utilisateur ou mot de passe',
+ 'Unable to update your preferences.' => 'Impossible de mettre à jour vos préférences.',
+ 'Your preferences are updated.' => 'Vos préférences ont été mises à jour.',
+ 'Unable to import your OPML file.' => 'Impossible d\'importer votre fichier OPML',
+ 'Your feeds have been imported.' => 'Vos abonnements ont été importés avec succès.',
+ 'Unable to find a subscription.' => 'Impossible de trouver un abonnement.',
+ 'Subscription added successfully.' => 'Abonnement ajouté avec succès.',
+ 'Your subscriptions are updated' => 'Vos abonnements ont été mis à jour',
+ 'Unable to remove this subscription.' => 'Impossible de supprimer cet abonnement.',
+ 'This subscription has been removed successfully.' => 'L\'abonnement a été supprimé avec succès.',
+ 'The user name is required' => 'Le nom d\'utilisateur est obligatoire',
+ 'The maximum length is 50 characters' => 'La longueur maximale est de 50 caractères',
+ 'The password is required' => 'Le mot de passe est obligatoire',
+ 'The minimum length is 6 characters' => 'La longueur minimale est de 6 caractères',
+ 'The confirmation is required' => 'La confirmation est obligatoire',
+ 'Passwords doesn\'t match' => 'Les mots de passe ne sont pas identique',
+ 'Do you really want to remove these items from your history?' => 'Voulez-vous vraiment supprimer les éléments de votre historique ?',
+ 'Do you really want to remove this subscription: "%s"?' => 'Voulez-vous vraiment supprimer cet abonnement : "%s" ?',
+ 'Nothing to read, do you want to update your subscriptions? ' =>
+ 'Il n\'y a rien à lire, voulez-vous mettre à jour vos abonnements ? '
+);
\ No newline at end of file
diff --git a/miniflux/model.php b/miniflux/model.php
index 09873c5..b633f66 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -21,6 +21,15 @@ use PicoFeed\Reader;
use PicoFeed\Export;
+function get_languages()
+{
+ return array(
+ 'en_US' => t('English'),
+ 'fr_FR' => t('French')
+ );
+}
+
+
function export_feeds()
{
$opml = new Export(get_feeds());
@@ -359,7 +368,7 @@ function get_config()
{
return \PicoTools\singleton('db')
->table('config')
- ->columns('username', 'history')
+ ->columns('username', 'language')
->findOne();
}
@@ -368,7 +377,7 @@ function get_user()
{
return \PicoTools\singleton('db')
->table('config')
- ->columns('username', 'password')
+ ->columns('username', 'password', 'language')
->findOne();
}
@@ -376,9 +385,9 @@ function get_user()
function validate_login(array $values)
{
$v = new Validator($values, array(
- new Validators\Required('username', 'The user name is required'),
- new Validators\MaxLength('username', 'The maximum length is 50 characters', 50),
- new Validators\Required('password', 'The password is required')
+ new Validators\Required('username', t('The user name is required')),
+ new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50),
+ new Validators\Required('password', t('The password is required'))
));
$result = $v->execute();
@@ -390,12 +399,13 @@ function validate_login(array $values)
if ($user && \password_verify($values['password'], $user['password'])) {
+ unset($user['password']);
$_SESSION['user'] = $user;
}
else {
$result = false;
- $errors['login'] = 'Bad username or password';
+ $errors['login'] = t('Bad username or password');
}
}
@@ -411,19 +421,19 @@ function validate_config_update(array $values)
if (! empty($values['password'])) {
$v = new Validator($values, array(
- new Validators\Required('username', 'The user name is required'),
- new Validators\MaxLength('username', 'The maximum length is 50 characters', 50),
- new Validators\Required('password', 'The password is required'),
- new Validators\MinLength('password', 'The minimum length is 6 characters', 6),
- new Validators\Required('confirmation', 'The confirmation is required'),
- new Validators\Equals('password', 'confirmation', 'Passwords doesn\'t match')
+ new Validators\Required('username', t('The user name is required')),
+ new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50),
+ new Validators\Required('password', t('The password is required')),
+ new Validators\MinLength('password', t('The minimum length is 6 characters'), 6),
+ new Validators\Required('confirmation', t('The confirmation is required')),
+ new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t match'))
));
}
else {
$v = new Validator($values, array(
- new Validators\Required('username', 'The user name is required'),
- new Validators\MaxLength('username', 'The maximum length is 50 characters', 50)
+ new Validators\Required('username', t('The user name is required')),
+ new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50)
));
}
@@ -447,5 +457,8 @@ function save_config(array $values)
unset($values['confirmation']);
+ $_SESSION['user']['language'] = $values['language'];
+ unset($_COOKIE['language']);
+
return \PicoTools\singleton('db')->table('config')->update($values);
}
diff --git a/miniflux/schema.php b/miniflux/schema.php
index e446af3..74dd7c1 100644
--- a/miniflux/schema.php
+++ b/miniflux/schema.php
@@ -3,6 +3,12 @@
namespace Schema;
+function version_3($pdo)
+{
+ $pdo->exec("ALTER TABLE config ADD COLUMN language TEXT DEFAULT 'en_US'");
+}
+
+
function version_2($pdo)
{
$pdo->exec('ALTER TABLE feeds ADD COLUMN last_modified TEXT');
diff --git a/miniflux/templates/add.php b/miniflux/templates/add.php
index 7d4c227..abd1e4f 100644
--- a/miniflux/templates/add.php
+++ b/miniflux/templates/add.php
@@ -1,16 +1,16 @@
\ No newline at end of file
diff --git a/miniflux/templates/app_header.php b/miniflux/templates/app_header.php
index 4762adf..3cfbda1 100644
--- a/miniflux/templates/app_header.php
+++ b/miniflux/templates/app_header.php
@@ -18,11 +18,11 @@
miniflux
diff --git a/miniflux/templates/config.php b/miniflux/templates/config.php
index 95c3687..048da99 100644
--- a/miniflux/templates/config.php
+++ b/miniflux/templates/config.php
@@ -1,51 +1,54 @@
-
More informations
+ = t('More informations') ?>
-
Database
+
= t('Database') ?>
-
Keyboard shortcuts
+
= t('Keyboard shortcuts') ?>
- Previous item = p
- Next item = n
- Mark as read or unread = m
- Open original link = v
- Open item = o
+ = t('Previous item') ?> = p
+ = t('Next item') ?> = n
+ = t('Mark as read or unread') ?> = m
+ = t('Open original link') ?> = v
+ = t('Open item') ?> = o
-
About
+
= t('About') ?>
- Miniflux version: = APP_VERSION ?>
+ = t('Miniflux version:') ?> = APP_VERSION ?>
+ = t('Official website:') ?> http://miniflux.net
\ No newline at end of file
diff --git a/miniflux/templates/confirm_flush.php b/miniflux/templates/confirm_flush.php
index 5a15913..44938cc 100644
--- a/miniflux/templates/confirm_flush.php
+++ b/miniflux/templates/confirm_flush.php
@@ -1,10 +1,10 @@
-Do you really want to remove these items from your history?
+= t('Do you really want to remove these items from your history?') ?>
\ No newline at end of file
diff --git a/miniflux/templates/confirm_remove.php b/miniflux/templates/confirm_remove.php
index 4c48a75..ec40551 100644
--- a/miniflux/templates/confirm_remove.php
+++ b/miniflux/templates/confirm_remove.php
@@ -1,10 +1,10 @@
-Do you really want to remove this subscription: "= Helper\escape($feed['title']) ?>"?
+= t('Do you really want to remove this subscription: "%s"?', Helper\escape($feed['title'])) ?>
\ No newline at end of file
diff --git a/miniflux/templates/feeds.php b/miniflux/templates/feeds.php
index c39d961..156b354 100644
--- a/miniflux/templates/feeds.php
+++ b/miniflux/templates/feeds.php
@@ -1,21 +1,21 @@
- No subscription.
+ = t('No subscription') ?>
- Nothing to read, do you want to update your subscriptions?
+ = t('Nothing to read, do you want to update your subscriptions? ') ?>
@@ -26,10 +26,10 @@
= Helper\escape($feed['title']) ?>
- = Helper\get_host_from_url($feed['site_url']) ?> |
- feed link |
- remove |
- refresh
+ = Helper\get_host_from_url($feed['site_url']) ?> |
+ = t('feed link') ?> |
+ = t('remove') ?> |
+ = t('refresh') ?>
diff --git a/miniflux/templates/import.php b/miniflux/templates/import.php
index a81baf3..eca99a7 100644
--- a/miniflux/templates/import.php
+++ b/miniflux/templates/import.php
@@ -1,16 +1,16 @@
\ No newline at end of file
diff --git a/miniflux/templates/login.php b/miniflux/templates/login.php
index 66b8fed..e273c79 100644
--- a/miniflux/templates/login.php
+++ b/miniflux/templates/login.php
@@ -9,7 +9,7 @@
@@ -20,14 +20,14 @@
diff --git a/miniflux/templates/read_item.php b/miniflux/templates/read_item.php
index 823c566..6af5719 100644
--- a/miniflux/templates/read_item.php
+++ b/miniflux/templates/read_item.php
@@ -1,6 +1,6 @@
- Article not found.
+ = t('Item not found') ?>
@@ -11,7 +11,7 @@
= Helper\get_host_from_url($item['url']) ?> |
- = date('l, j F Y H:i', $item['updated']) ?>
+ = dt('%A %e %B %Y %k:%M', $item['updated']) ?>
= $item['content'] ?>
@@ -20,29 +20,29 @@
- « Previous
+ « = t('Previous') ?>
- « Previous
+ « = t('Previous') ?>
- Unread items
+ = t('Unread items') ?>
- Unread items
+ = t('Unread items') ?>
- Unread items
+ = t('Unread items') ?>
- Unread items
+ = t('Unread items') ?>
- Next »
+ = t('Next') ?> »
- Next »
+ = t('Next') ?> »
diff --git a/miniflux/templates/read_items.php b/miniflux/templates/read_items.php
index 1944e81..fdbb038 100644
--- a/miniflux/templates/read_items.php
+++ b/miniflux/templates/read_items.php
@@ -1,13 +1,13 @@
- No history.
+ = t('No history') ?>
@@ -24,8 +24,8 @@
= Helper\get_host_from_url($item['url']) ?> |
- = date('l, j F Y H:i', $item['updated']) ?> |
- mark as unread |
+ = dt('%A %e %B %Y %k:%M', $item['updated']) ?> |
+ = t('mark as unread') ?> |
- direct link
+ = t('original link') ?>
diff --git a/miniflux/templates/unread_items.php b/miniflux/templates/unread_items.php
index 1e9dc23..dc50a83 100644
--- a/miniflux/templates/unread_items.php
+++ b/miniflux/templates/unread_items.php
@@ -1,13 +1,13 @@
- Nothing to read.
+ = t('Nothing to read') ?>
@@ -27,7 +27,7 @@
= Helper\get_host_from_url($item['url']) ?> |
- mark as read |
+ = t('mark as read') ?> |
- direct link
+ = t('original link') ?>
diff --git a/miniflux/vendor/PicoTools/Translator.php b/miniflux/vendor/PicoTools/Translator.php
index 40bd653..832635c 100644
--- a/miniflux/vendor/PicoTools/Translator.php
+++ b/miniflux/vendor/PicoTools/Translator.php
@@ -19,7 +19,7 @@ namespace PicoTools\Translator {
$args = \func_get_args();
\array_shift($args);
- \array_unshift($args, get($identifier));
+ \array_unshift($args, get($identifier, $identifier));
return \call_user_func_array(
'sprintf',
@@ -61,6 +61,12 @@ namespace PicoTools\Translator {
}
+ function datetime($format, $timestamp)
+ {
+ return strftime($format, $timestamp);
+ }
+
+
function get($identifier, $default = '')
{
$locales = container();
@@ -78,6 +84,8 @@ namespace PicoTools\Translator {
function load($language)
{
+ setlocale(LC_TIME, $language);
+
$path = PATH.$language;
$locales = array();
@@ -118,4 +126,10 @@ namespace {
return call_user_func_array('\PicoTools\Translator\translate', func_get_args());
}
+
+
+ function dt() {
+
+ return call_user_func_array('\PicoTools\Translator\datetime', func_get_args());
+ }
}
\ No newline at end of file
From 4f0dac1e3a592773531073142eaed556bb4e2deb Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 12 Apr 2013 21:09:05 -0400
Subject: [PATCH 33/48] Update picoFeed
---
miniflux/vendor/PicoFeed/Parsers/Atom.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/miniflux/vendor/PicoFeed/Parsers/Atom.php b/miniflux/vendor/PicoFeed/Parsers/Atom.php
index cf3f405..7478bd1 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Atom.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Atom.php
@@ -72,7 +72,7 @@ class Atom extends Parser
{
foreach ($xml->link as $link) {
- if ((string) $link['type'] === 'text/html') {
+ if ((string) $link['type'] === 'text/html' || (string) $link['type'] === 'application/xhtml+xml') {
return (string) $link['href'];
}
From 2203972e6569ba1a009744f485473c69a694d83d Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Fri, 12 Apr 2013 21:27:51 -0400
Subject: [PATCH 34/48] Reload locales after a save_config()
---
miniflux/model.php | 2 ++
miniflux/vendor/PicoTools/Translator.php | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/miniflux/model.php b/miniflux/model.php
index b633f66..e6b2fac 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -460,5 +460,7 @@ function save_config(array $values)
$_SESSION['user']['language'] = $values['language'];
unset($_COOKIE['language']);
+ \PicoTools\Translator\load($values['language']);
+
return \PicoTools\singleton('db')->table('config')->update($values);
}
diff --git a/miniflux/vendor/PicoTools/Translator.php b/miniflux/vendor/PicoTools/Translator.php
index 832635c..e2ce27d 100644
--- a/miniflux/vendor/PicoTools/Translator.php
+++ b/miniflux/vendor/PicoTools/Translator.php
@@ -110,7 +110,7 @@ namespace PicoTools\Translator {
{
static $values = array();
- if ($locales) {
+ if ($locales !== null) {
$values = $locales;
}
From 782b952920c0fa3c583510eeaa4cc2fa376e2962 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:40:21 -0400
Subject: [PATCH 35/48] Update .gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 7806308..82b8973 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
update*
+make-archive.sh
From e2076e8571a9f3bb2c9b9370e37ac4c8f77ff1eb Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:41:20 -0400
Subject: [PATCH 36/48] Add index on status column
---
miniflux/common.php | 2 +-
miniflux/schema.php | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/miniflux/common.php b/miniflux/common.php
index 6216aeb..7c0e222 100644
--- a/miniflux/common.php
+++ b/miniflux/common.php
@@ -10,7 +10,7 @@ require 'schema.php';
require 'model.php';
-const DB_VERSION = 3;
+const DB_VERSION = 4;
const APP_VERSION = 'master';
const APP_USERAGENT = 'Miniflux - http://miniflux.net';
const HTTP_TIMEOUT = 5;
diff --git a/miniflux/schema.php b/miniflux/schema.php
index 74dd7c1..4007577 100644
--- a/miniflux/schema.php
+++ b/miniflux/schema.php
@@ -3,6 +3,12 @@
namespace Schema;
+function version_4($pdo)
+{
+ $pdo->exec("CREATE INDEX idx_status ON items(status)");
+}
+
+
function version_3($pdo)
{
$pdo->exec("ALTER TABLE config ADD COLUMN language TEXT DEFAULT 'en_US'");
From f3105b5dd83ef366ead457f6ec5298dd79fba2ff Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:42:12 -0400
Subject: [PATCH 37/48] Add touch icon on login page too
---
miniflux/templates/login.php | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/miniflux/templates/login.php b/miniflux/templates/login.php
index e273c79..2a7ea80 100644
--- a/miniflux/templates/login.php
+++ b/miniflux/templates/login.php
@@ -3,8 +3,14 @@
+
+
+
+
+
+
miniflux
-
+
From 68bfc130b7cb72a3cfd6f565102413a91594dd59 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:42:39 -0400
Subject: [PATCH 38/48] Update of PicoTools
---
miniflux/vendor/PicoTools/Chrono.php | 100 -----------
miniflux/vendor/PicoTools/Crypto.php | 36 ----
miniflux/vendor/PicoTools/Helper.php | 12 ++
miniflux/vendor/PicoTools/Pixtag.php | 243 ---------------------------
4 files changed, 12 insertions(+), 379 deletions(-)
delete mode 100644 miniflux/vendor/PicoTools/Chrono.php
delete mode 100644 miniflux/vendor/PicoTools/Crypto.php
delete mode 100644 miniflux/vendor/PicoTools/Pixtag.php
diff --git a/miniflux/vendor/PicoTools/Chrono.php b/miniflux/vendor/PicoTools/Chrono.php
deleted file mode 100644
index 8a65505..0000000
--- a/miniflux/vendor/PicoTools/Chrono.php
+++ /dev/null
@@ -1,100 +0,0 @@
- microtime(true),
- 'finish' => 0
- );
- }
-
-
- /**
- * Stop a chrono
- *
- * @access public
- * @static
- * @param string $name Chrono name
- */
- public static function stop($name)
- {
- if (! isset(self::$chronos[$name])) {
-
- throw new \RuntimeException('Chrono not started!');
- }
-
- self::$chronos[$name]['finish'] = microtime(true);
- }
-
-
- /**
- * Get a duration of a chrono
- *
- * @access public
- * @static
- * @return float
- */
- public static function duration($name)
- {
- if (! isset(self::$chronos[$name])) {
-
- throw new \RuntimeException('Chrono not started!');
- }
-
- return self::$chronos[$name]['finish'] - self::$chronos[$name]['start'];
- }
-
-
- /**
- * Show all durations
- *
- * @access public
- * @static
- */
- public static function show()
- {
- foreach (self::$chronos as $name => $values) {
-
- echo $name.' = ';
- echo round($values['finish'] - $values['start'], 2).'s';
- echo PHP_EOL;
- }
- }
-}
\ No newline at end of file
diff --git a/miniflux/vendor/PicoTools/Crypto.php b/miniflux/vendor/PicoTools/Crypto.php
deleted file mode 100644
index aa48295..0000000
--- a/miniflux/vendor/PicoTools/Crypto.php
+++ /dev/null
@@ -1,36 +0,0 @@
-';
+ $html .= error_list($errors, $name);
+
+ return $html;
+}
+
+
function form_textarea($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
{
$class .= error_class($errors, $name);
diff --git a/miniflux/vendor/PicoTools/Pixtag.php b/miniflux/vendor/PicoTools/Pixtag.php
deleted file mode 100644
index a5e59d8..0000000
--- a/miniflux/vendor/PicoTools/Pixtag.php
+++ /dev/null
@@ -1,243 +0,0 @@
-filename = $filename;
- }
-
-
- /**
- * Read metadata from the picture
- *
- * @access public
- */
- public function read()
- {
- $c = new Command('exiv2 -PIEXkt '.$this->filename);
- $c->execute();
- $this->parse($c->getStdout());
- }
-
-
- /**
- * Parse metadata bloc from exiv2 output command
- *
- * @access public
- * @param string $data Raw command output of exiv2
- */
- public function parse($data)
- {
- $lines = explode("\n", trim($data));
-
- foreach ($lines as $line) {
-
- $results = preg_split('/ /', $line, -1, PREG_SPLIT_OFFSET_CAPTURE);
-
- if (isset($results[0][0])) {
-
- $key = $results[0][0];
- $value = '';
-
- for ($i = 1, $ilen = count($results); $i < $ilen; ++$i) {
-
- if ($results[$i][0] !== '') {
-
- $value = substr($line, $results[$i][1]);
- break;
- }
- }
-
- if ($value === '(Binary value suppressed)') {
-
- $value = '';
- }
-
- $this->container[$key] = $value;
- }
- }
- }
-
-
- /**
- * Write metadata to the picture
- * This method erase all keys and then add them to the picture
- *
- * @access public
- */
- public function write()
- {
- $commands = array();
-
- foreach ($this->container as $key => $value) {
-
- $commands[] = sprintf('-M "del %s"', $key);
- $commands[] = sprintf('-M "add %s %s"', $key, $value);
- }
-
- $c = new Command(sprintf(
- 'exiv2 %s %s',
- implode(' ', $commands),
- $this->filename
- ));
-
- $c->execute();
-
- if ($c->getReturnValue() !== 0) {
-
- throw new \RuntimeException('Unable to write metadata');
- }
- }
-
-
- /**
- * Set a metadata
- *
- * @access public
- * @param string $offset Key name, see exiv2 documentation for keys list
- * @param string $value Key value
- */
- public function offsetSet($offset, $value)
- {
- $this->container[$offset] = $value;
- }
-
-
- /**
- * Check if a key exists
- *
- * @access public
- * @param string $offset Key name, see exiv2 documentation for keys list
- * @return boolean True if the key exists
- */
- public function offsetExists($offset)
- {
- return isset($this->container[$offset]);
- }
-
-
- /**
- * Remove a metadata
- *
- * @access public
- * @param string $offset Key name, see exiv2 documentation for keys list
- */
- public function offsetUnset($offset)
- {
- unset($this->container[$offset]);
- }
-
-
- /**
- * Get a metadata
- *
- * @access public
- * @param string $offset Key name, see exiv2 documentation for keys list
- * @return string Key value
- */
- public function offsetGet($offset)
- {
- return isset($this->container[$offset]) ? $this->container[$offset] : null;
- }
-
-
- /**
- * Reset the position of the container
- *
- * @access public
- */
- public function rewind()
- {
- reset($this->container);
- }
-
-
- /**
- * Current
- *
- * @access public
- * @return string Current value
- */
- public function current()
- {
- return current($this->container);
- }
-
-
- /**
- * Key
- *
- * @access public
- * @return string Current key
- */
- public function key()
- {
- return key($this->container);
- }
-
-
- /**
- * Next
- *
- * @access public
- */
- public function next()
- {
- next($this->container);
- }
-
-
- /**
- * Valid
- *
- * @access public
- * @return boolean True if the current key is valid
- */
- public function valid()
- {
- return isset($this->container[key($this->container)]);
- }
-}
\ No newline at end of file
From 93d1fd40c0439bebc3f4afc6938f2e5a2467de2d Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:43:18 -0400
Subject: [PATCH 39/48] Template rename
---
miniflux/templates/{read_items.php => history.php} | 1 +
1 file changed, 1 insertion(+)
rename miniflux/templates/{read_items.php => history.php} (93%)
diff --git a/miniflux/templates/read_items.php b/miniflux/templates/history.php
similarity index 93%
rename from miniflux/templates/read_items.php
rename to miniflux/templates/history.php
index fdbb038..17db654 100644
--- a/miniflux/templates/read_items.php
+++ b/miniflux/templates/history.php
@@ -26,6 +26,7 @@
= Helper\get_host_from_url($item['url']) ?> |
= dt('%A %e %B %Y %k:%M', $item['updated']) ?> |
= t('mark as unread') ?> |
+ = t('remove') ?> |
Date: Mon, 22 Apr 2013 22:43:38 -0400
Subject: [PATCH 40/48] Update of picoDb
---
miniflux/vendor/PicoDb/Table.php | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/miniflux/vendor/PicoDb/Table.php b/miniflux/vendor/PicoDb/Table.php
index f543fd8..f05532b 100644
--- a/miniflux/vendor/PicoDb/Table.php
+++ b/miniflux/vendor/PicoDb/Table.php
@@ -63,7 +63,14 @@ class Table
$this->conditions()
);
- return false !== $this->db->execute($sql, $values);
+ $result = $this->db->execute($sql, $values);
+
+ if ($result !== false && $result->rowCount() > 0) {
+
+ return true;
+ }
+
+ return false;
}
@@ -290,6 +297,17 @@ class Table
}
break;
+ case 'notin':
+ if (is_array($arguments[1])) {
+
+ $sql = sprintf(
+ '%s NOT IN (%s)',
+ $this->db->escapeIdentifier($column),
+ implode(', ', array_fill(0, count($arguments[1]), '?'))
+ );
+ }
+ break;
+
case 'like':
$sql = sprintf('%s LIKE ?', $this->db->escapeIdentifier($column));
break;
From 5a2869e2588ff218bbd7928638704e0d93d8279b Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Mon, 22 Apr 2013 22:44:28 -0400
Subject: [PATCH 41/48] Add remove link on history page and remove old items
automatically
---
miniflux/index.php | 10 ++++++++-
miniflux/model.php | 52 ++++++++++++++++++++++++++++++++++++----------
2 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index 893adb0..6168bb4 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -133,6 +133,14 @@ Router\get_action('mark-item-unread', function() {
});
+Router\get_action('mark-item-removed', function() {
+
+ $id = Request\param('id');
+ Model\set_item_removed($id);
+ Response\Redirect('?action=history');
+});
+
+
Router\post_action('mark-item-read', function() {
$id = Request\param('id');
@@ -162,7 +170,7 @@ Router\post_action('change-item-status', function() {
Router\get_action('history', function() {
- Response\html(Template\layout('read_items', array(
+ Response\html(Template\layout('history', array(
'items' => Model\get_read_items(),
'menu' => 'history'
)));
diff --git a/miniflux/model.php b/miniflux/model.php
index e6b2fac..33f5872 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -261,6 +261,15 @@ function get_nav_item($item)
}
+function set_item_removed($id)
+{
+ \PicoTools\singleton('db')
+ ->table('items')
+ ->eq('id', $id)
+ ->save(array('status' => 'removed'));
+}
+
+
function set_item_read($id)
{
\PicoTools\singleton('db')
@@ -339,27 +348,48 @@ function flush_read()
function update_items($feed_id, array $items)
{
+ $items_in_feed = array();
$db = \PicoTools\singleton('db');
$db->startTransaction();
foreach ($items as $item) {
- if ($item->id && ! $db->table('items')->eq('id', $item->id)->count()) {
+ // Item parsed correctly?
+ if ($item->id) {
- $db->table('items')->save(array(
- 'id' => $item->id,
- 'title' => $item->title,
- 'url' => $item->url,
- 'updated' => $item->updated,
- 'author' => $item->author,
- 'content' => $item->content,
- 'status' => 'unread',
- 'feed_id' => $feed_id
- ));
+ // Insert only new item
+ if ($db->table('items')->eq('id', $item->id)->count() !== 1) {
+
+ $db->table('items')->save(array(
+ 'id' => $item->id,
+ 'title' => $item->title,
+ 'url' => $item->url,
+ 'updated' => $item->updated,
+ 'author' => $item->author,
+ 'content' => $item->content,
+ 'status' => 'unread',
+ 'feed_id' => $feed_id
+ ));
+ }
+
+ // Items inside this feed
+ $items_in_feed[] = $item->id;
}
}
+ // Remove from the database items marked as "removed"
+ // and not present inside the feed
+ if (! empty($items_in_feed)) {
+
+ \PicoTools\singleton('db')
+ ->table('items')
+ ->notin('id', $items_in_feed)
+ ->eq('status', 'removed')
+ ->eq('feed_id', $feed_id)
+ ->remove();
+ }
+
$db->closeTransaction();
}
From 4b91640cc1dae5c6ca412718f8a9a876da9a7e23 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Tue, 23 Apr 2013 21:41:04 -0400
Subject: [PATCH 42/48] Auto-vacuum when refresh feeds with the cronjob
---
miniflux/model.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/miniflux/model.php b/miniflux/model.php
index 33f5872..d14887e 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -114,6 +114,9 @@ function update_feeds()
update_feed($feed_id);
}
+
+ // Auto-vacuum for people using the cronjob
+ \PicoTools\singleton('db')->getConnection()->exec('VACUUM');
}
From 45e848b5b2bf2acbd41292189d399fe8980f5a6e Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Wed, 24 Apr 2013 20:00:02 -0400
Subject: [PATCH 43/48] Improve CSS
---
miniflux/assets/css/app.css | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/miniflux/assets/css/app.css b/miniflux/assets/css/app.css
index a61064d..040a890 100644
--- a/miniflux/assets/css/app.css
+++ b/miniflux/assets/css/app.css
@@ -63,6 +63,12 @@ blockquote {
font-family: Georgia, serif;
}
+q {
+ color: purple;
+ font-family: Georgia, serif;
+ font-style: italic;
+}
+
blockquote + p {
color: #555;
font-style: italic;
@@ -401,14 +407,17 @@ nav .active a {
/* item */
.item {
- color: #333;
+ padding-left: 5px;
+ padding-right: 5px;
padding-bottom: 50px;
+ color: #555;
}
.item p,
.item li {
font-family: Georgia, serif;
line-height: 1.6em;
+ font-size: 1.1em;
}
.item h2,
From 1c29f54c8a669a127d9cab9d1aa8de4f2ddc76f5 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Wed, 24 Apr 2013 20:00:30 -0400
Subject: [PATCH 44/48] Add tag support for "q"
---
miniflux/vendor/PicoFeed/Filter.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/miniflux/vendor/PicoFeed/Filter.php b/miniflux/vendor/PicoFeed/Filter.php
index 65206e4..f57d5e8 100644
--- a/miniflux/vendor/PicoFeed/Filter.php
+++ b/miniflux/vendor/PicoFeed/Filter.php
@@ -44,7 +44,8 @@ class Filter
'cite' => array(),
'time' => array('datetime'),
'abbr' => array('title'),
- 'iframe' => array('width', 'height', 'frameborder', 'src')
+ 'iframe' => array('width', 'height', 'frameborder', 'src'),
+ 'q' => array('cite')
);
public $strip_tags_content = array(
From 855d78bb481c0008d8410eb8712801a981e4d2da Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sat, 27 Apr 2013 08:44:30 -0400
Subject: [PATCH 45/48] Add utf-8 time locales
---
miniflux/vendor/PicoTools/Translator.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/miniflux/vendor/PicoTools/Translator.php b/miniflux/vendor/PicoTools/Translator.php
index e2ce27d..2e4dffb 100644
--- a/miniflux/vendor/PicoTools/Translator.php
+++ b/miniflux/vendor/PicoTools/Translator.php
@@ -84,7 +84,7 @@ namespace PicoTools\Translator {
function load($language)
{
- setlocale(LC_TIME, $language);
+ setlocale(LC_TIME, $language.'.UTF-8');
$path = PATH.$language;
$locales = array();
From 40f20a9bf53aeaed1e8698f3eef7cf8ee8e5ac54 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Tue, 30 Apr 2013 21:52:43 -0400
Subject: [PATCH 46/48] Fix bug #28: History original link disappear
---
miniflux/assets/js/app.js | 10 +++++++---
miniflux/templates/app_header.php | 2 +-
miniflux/templates/history.php | 1 -
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/miniflux/assets/js/app.js b/miniflux/assets/js/app.js
index 0f4ff86..3cca31c 100644
--- a/miniflux/assets/js/app.js
+++ b/miniflux/assets/js/app.js
@@ -11,7 +11,7 @@
request.onreadystatechange = function() {
- if (request.readyState === 4) {
+ if (request.readyState === 4 && is_listing()) {
var response = JSON.parse(request.responseText);
@@ -180,8 +180,12 @@
if (link) {
- mark_as_read(link.getAttribute("data-item-id"));
- find_next_item();
+ if (link.getAttribute("data-action") == "mark-read") {
+
+ mark_as_read(link.getAttribute("data-item-id"));
+ find_next_item();
+ }
+
link.click();
}
}
diff --git a/miniflux/templates/app_header.php b/miniflux/templates/app_header.php
index 3cfbda1..2ccee69 100644
--- a/miniflux/templates/app_header.php
+++ b/miniflux/templates/app_header.php
@@ -2,7 +2,7 @@
-
+
diff --git a/miniflux/templates/history.php b/miniflux/templates/history.php
index 17db654..41637b5 100644
--- a/miniflux/templates/history.php
+++ b/miniflux/templates/history.php
@@ -33,7 +33,6 @@
rel="noreferrer"
target="_blank"
data-item-id="= urlencode($item['id']) ?>"
- data-action="mark-read"
>
= t('original link') ?>
From 00644bb2b8ed29b9949018861a4ab025b65b53b4 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Tue, 30 Apr 2013 22:34:02 -0400
Subject: [PATCH 47/48] Bug fix #26: previous/next issue (items with same
updated value)
---
miniflux/index.php | 3 ++-
miniflux/model.php | 24 ++++++++++++++----------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/miniflux/index.php b/miniflux/index.php
index 6168bb4..23f2fa3 100644
--- a/miniflux/index.php
+++ b/miniflux/index.php
@@ -107,12 +107,13 @@ Router\get_action('read', function() {
$id = Request\param('id');
$item = Model\get_item($id);
+ $nav = Model\get_nav_item($item); // must be placed before set_item_read()
Model\set_item_read($id);
Response\html(Template\layout('read_item', array(
'item' => $item,
- 'item_nav' => Model\get_nav_item($item)
+ 'item_nav' => $nav
)));
});
diff --git a/miniflux/model.php b/miniflux/model.php
index d14887e..2bcf339 100644
--- a/miniflux/model.php
+++ b/miniflux/model.php
@@ -241,21 +241,25 @@ function get_item($id)
function get_nav_item($item)
{
- $next_item = \PicoTools\singleton('db')
+ $unread_items = \PicoTools\singleton('db')
->table('items')
->columns('items.id')
->eq('status', 'unread')
- ->lt('updated', $item['updated'])
->desc('updated')
- ->findOne();
+ ->findAll();
- $previous_item = \PicoTools\singleton('db')
- ->table('items')
- ->columns('items.id')
- ->eq('status', 'unread')
- ->gt('updated', $item['updated'])
- ->asc('updated')
- ->findOne();
+ $next_item = null;
+ $previous_item = null;
+
+ for ($i = 0, $ilen = count($unread_items); $i < $ilen; $i++) {
+
+ if ($unread_items[$i]['id'] == $item['id']) {
+
+ if ($i > 0) $previous_item = $unread_items[$i - 1];
+ if ($i < ($ilen - 1)) $next_item = $unread_items[$i + 1];
+ break;
+ }
+ }
return array(
'next' => $next_item,
From 5ada718357fc4edf7f60f2a35bd040ad811ba310 Mon Sep 17 00:00:00 2001
From: Frederic Guillot
Date: Sun, 5 May 2013 21:44:03 -0400
Subject: [PATCH 48/48] Blank titles are filled with the url
---
miniflux/vendor/PicoFeed/Parsers/Atom.php | 2 ++
miniflux/vendor/PicoFeed/Parsers/Rss10.php | 3 ++-
miniflux/vendor/PicoFeed/Parsers/Rss20.php | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/miniflux/vendor/PicoFeed/Parsers/Atom.php b/miniflux/vendor/PicoFeed/Parsers/Atom.php
index 7478bd1..6e925d0 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Atom.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Atom.php
@@ -39,6 +39,8 @@ class Atom extends Parser
$item->author = $author;
$item->content = $this->filterHtml($this->getContent($entry), $item->url);
+ if (empty($item->title)) $item->title = $item->url;
+
$this->items[] = $item;
}
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss10.php b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
index 000119c..d04bdd5 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Rss10.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss10.php
@@ -9,7 +9,6 @@ class Rss10 extends Parser
$this->content = $this->normalizeData($this->content);
\libxml_use_internal_errors(true);
-
$xml = \simplexml_load_string($this->content);
if ($xml === false) {
@@ -74,6 +73,8 @@ class Rss10 extends Parser
}
}
+ if (empty($item->title)) $item->title = $item->url;
+
$item->id = $item->url;
$item->content = $this->filterHtml($item->content, $item->url);
$this->items[] = $item;
diff --git a/miniflux/vendor/PicoFeed/Parsers/Rss20.php b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
index bc04d84..919b968 100644
--- a/miniflux/vendor/PicoFeed/Parsers/Rss20.php
+++ b/miniflux/vendor/PicoFeed/Parsers/Rss20.php
@@ -91,6 +91,8 @@ class Rss20 extends Parser
$item->id = $item->url;
}
+ if (empty($item->title)) $item->title = $item->url;
+
$item->content = $this->filterHtml($item->content, $item->url);
$this->items[] = $item;
}