diff options
author | Thomas Citharel <tcit@tcit.fr> | 2015-02-01 11:27:10 +0100 |
---|---|---|
committer | Thomas Citharel <tcit@tcit.fr> | 2015-02-01 11:27:10 +0100 |
commit | b05f482dd219acd5f5c7e9669ad8bd168ba224c6 (patch) | |
tree | 4c89e1dc27201b34e35a8d9e3e8e461531978443 | |
parent | 3dcd85c075998ecdf2d54c5661c42e24080067d5 (diff) | |
parent | bc6f5a8086b331bf21cdfcac799788264d8cd3b2 (diff) | |
download | wallabag-b05f482dd219acd5f5c7e9669ad8bd168ba224c6.tar.gz wallabag-b05f482dd219acd5f5c7e9669ad8bd168ba224c6.tar.zst wallabag-b05f482dd219acd5f5c7e9669ad8bd168ba224c6.zip |
Merge branch 'dev' into reloadarticle
21 files changed, 1070 insertions, 2255 deletions
@@ -8,9 +8,10 @@ wallabag is based on : | |||
8 | * Twig http://twig.sensiolabs.org | 8 | * Twig http://twig.sensiolabs.org |
9 | * Flash messages https://github.com/plasticbrain/PHP-Flash-Messages | 9 | * Flash messages https://github.com/plasticbrain/PHP-Flash-Messages |
10 | * Pagination https://github.com/daveismyname/pagination | 10 | * Pagination https://github.com/daveismyname/pagination |
11 | * PHPePub https://github.com/Grandt/PHPePub/ | ||
11 | 12 | ||
12 | wallabag is mainly developed by Nicolas LÅ“uillet under the MIT License | 13 | wallabag is mainly developed by Nicolas LÅ“uillet under the MIT License |
13 | 14 | ||
14 | Thank you so much to @tcitworld and @mariroz. | 15 | Thank you so much to @tcitworld and @mariroz. |
15 | 16 | ||
16 | Contributors : https://github.com/wallabag/wallabag/graphs/contributors \ No newline at end of file | 17 | Contributors : https://github.com/wallabag/wallabag/graphs/contributors |
diff --git a/composer.json b/composer.json index 6c69e48d..a63f2893 100644 --- a/composer.json +++ b/composer.json | |||
@@ -1,4 +1,27 @@ | |||
1 | { | 1 | { |
2 | "name": "wallabag/wallabag", | ||
3 | "type": "project", | ||
4 | "description": "open source self hostable read-it-later web application", | ||
5 | "keywords": ["read-it-later","read it later"], | ||
6 | "homepage": "https://github.com/wallabag/wallabag", | ||
7 | "license": "MIT", | ||
8 | "authors": [ | ||
9 | { | ||
10 | "name": "Nicolas LÅ“uillet", | ||
11 | "email": "nicolas@loeuillet.org", | ||
12 | "homepage": "http://www.cdetc.fr", | ||
13 | "role": "Developer" | ||
14 | }, | ||
15 | { | ||
16 | "name": "Thomas Citharel", | ||
17 | "homepage": "http://tcit.fr", | ||
18 | "role": "Developer" | ||
19 | } | ||
20 | ], | ||
21 | "support": { | ||
22 | "email": "hello@wallabag.org", | ||
23 | "issues": "https://github.com/wallabag/wallabag/issues" | ||
24 | }, | ||
2 | "require": { | 25 | "require": { |
3 | "twig/twig": "1.*", | 26 | "twig/twig": "1.*", |
4 | "twig/extensions": "1.0.*", | 27 | "twig/extensions": "1.0.*", |
diff --git a/inc/3rdparty/libraries/MOBIClass/MOBI.php b/inc/3rdparty/libraries/MOBIClass/MOBI.php index 17e718c1..df4826b0 100644 --- a/inc/3rdparty/libraries/MOBIClass/MOBI.php +++ b/inc/3rdparty/libraries/MOBIClass/MOBI.php | |||
@@ -1,5 +1,5 @@ | |||
1 | <?php | 1 | <?php |
2 | require_once(dirname(__FILE__)."/readability/Readability.php"); | 2 | require_once(dirname(__FILE__)."/../readability/Readability.php"); |
3 | require_once(dirname(__FILE__).'/CharacterEntities.php'); | 3 | require_once(dirname(__FILE__).'/CharacterEntities.php'); |
4 | require_once(dirname(__FILE__).'/constants.php'); | 4 | require_once(dirname(__FILE__).'/constants.php'); |
5 | require_once(dirname(__FILE__).'/ContentProvider.php'); | 5 | require_once(dirname(__FILE__).'/ContentProvider.php'); |
@@ -189,4 +189,4 @@ class MOBI { | |||
189 | } | 189 | } |
190 | 190 | ||
191 | } | 191 | } |
192 | ?> \ No newline at end of file | 192 | ?> |
diff --git a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php b/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php deleted file mode 100644 index 1a8ec88c..00000000 --- a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * JavaScript-like HTML DOM Element | ||
4 | * | ||
5 | * This class extends PHP's DOMElement to allow | ||
6 | * users to get and set the innerHTML property of | ||
7 | * HTML elements in the same way it's done in | ||
8 | * JavaScript. | ||
9 | * | ||
10 | * Example usage: | ||
11 | * @code | ||
12 | * require_once 'JSLikeHTMLElement.php'; | ||
13 | * header('Content-Type: text/plain'); | ||
14 | * $doc = new DOMDocument(); | ||
15 | * $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement'); | ||
16 | * $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>'); | ||
17 | * $elem = $doc->getElementsByTagName('div')->item(0); | ||
18 | * | ||
19 | * // print innerHTML | ||
20 | * echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>' | ||
21 | * echo "\n\n"; | ||
22 | * | ||
23 | * // set innerHTML | ||
24 | * $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>'; | ||
25 | * echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>' | ||
26 | * echo "\n\n"; | ||
27 | * | ||
28 | * // print document (with our changes) | ||
29 | * echo $doc->saveXML(); | ||
30 | * @endcode | ||
31 | * | ||
32 | * @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net | ||
33 | * @see http://fivefilters.org (the project this was written for) | ||
34 | */ | ||
35 | class JSLikeHTMLElement extends DOMElement | ||
36 | { | ||
37 | /** | ||
38 | * Used for setting innerHTML like it's done in JavaScript: | ||
39 | * @code | ||
40 | * $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>'; | ||
41 | * @endcode | ||
42 | */ | ||
43 | public function __set($name, $value) { | ||
44 | if ($name == 'innerHTML') { | ||
45 | // first, empty the element | ||
46 | for ($x=$this->childNodes->length-1; $x>=0; $x--) { | ||
47 | $this->removeChild($this->childNodes->item($x)); | ||
48 | } | ||
49 | // $value holds our new inner HTML | ||
50 | if ($value != '') { | ||
51 | $f = $this->ownerDocument->createDocumentFragment(); | ||
52 | // appendXML() expects well-formed markup (XHTML) | ||
53 | $result = @$f->appendXML($value); // @ to suppress PHP warnings | ||
54 | if ($result) { | ||
55 | if ($f->hasChildNodes()) $this->appendChild($f); | ||
56 | } else { | ||
57 | // $value is probably ill-formed | ||
58 | $f = new DOMDocument(); | ||
59 | $value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8'); | ||
60 | // Using <htmlfragment> will generate a warning, but so will bad HTML | ||
61 | // (and by this point, bad HTML is what we've got). | ||
62 | // We use it (and suppress the warning) because an HTML fragment will | ||
63 | // be wrapped around <html><body> tags which we don't really want to keep. | ||
64 | // Note: despite the warning, if loadHTML succeeds it will return true. | ||
65 | $result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>'); | ||
66 | if ($result) { | ||
67 | $import = $f->getElementsByTagName('htmlfragment')->item(0); | ||
68 | foreach ($import->childNodes as $child) { | ||
69 | $importedNode = $this->ownerDocument->importNode($child, true); | ||
70 | $this->appendChild($importedNode); | ||
71 | } | ||
72 | } else { | ||
73 | // oh well, we tried, we really did. :( | ||
74 | // this element is now empty | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | } else { | ||
79 | $trace = debug_backtrace(); | ||
80 | trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * Used for getting innerHTML like it's done in JavaScript: | ||
86 | * @code | ||
87 | * $string = $div->innerHTML; | ||
88 | * @endcode | ||
89 | */ | ||
90 | public function __get($name) | ||
91 | { | ||
92 | if ($name == 'innerHTML') { | ||
93 | $inner = ''; | ||
94 | foreach ($this->childNodes as $child) { | ||
95 | $inner .= $this->ownerDocument->saveXML($child); | ||
96 | } | ||
97 | return $inner; | ||
98 | } | ||
99 | |||
100 | $trace = debug_backtrace(); | ||
101 | trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); | ||
102 | return null; | ||
103 | } | ||
104 | |||
105 | public function __toString() | ||
106 | { | ||
107 | return '['.$this->tagName.']'; | ||
108 | } | ||
109 | } | ||
110 | ?> \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/MOBIClass/readability/Readability.php b/inc/3rdparty/libraries/MOBIClass/readability/Readability.php deleted file mode 100644 index 91554243..00000000 --- a/inc/3rdparty/libraries/MOBIClass/readability/Readability.php +++ /dev/null | |||
@@ -1,1069 +0,0 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * Arc90's Readability ported to PHP for FiveFilters.org | ||
4 | * Based on readability.js version 1.7.1 (without multi-page support) | ||
5 | * ------------------------------------------------------ | ||
6 | * Original URL: http://lab.arc90.com/experiments/readability/js/readability.js | ||
7 | * Arc90's project URL: http://lab.arc90.com/experiments/readability/ | ||
8 | * JS Source: http://code.google.com/p/arc90labs-readability | ||
9 | * Ported by: Keyvan Minoukadeh, http://www.keyvan.net | ||
10 | * More information: http://fivefilters.org/content-only/ | ||
11 | * License: Apache License, Version 2.0 | ||
12 | * Requires: PHP5 | ||
13 | * Date: 2010-10-29 | ||
14 | * | ||
15 | * Differences between the PHP port and the original | ||
16 | * ------------------------------------------------------ | ||
17 | * Arc90's Readability is designed to run in the browser. It works on the DOM | ||
18 | * tree (the parsed HTML) after the page's CSS styles have been applied and | ||
19 | * Javascript code executed. This PHP port does not run inside a browser. | ||
20 | * We use PHP's ability to parse HTML to build our DOM tree, but we cannot | ||
21 | * rely on CSS or Javascript support. As such, the results will not always | ||
22 | * match Arc90's Readability. (For example, if a web page contains CSS style | ||
23 | * rules or Javascript code which hide certain HTML elements from display, | ||
24 | * Arc90's Readability will dismiss those from consideration but our PHP port, | ||
25 | * unable to understand CSS or Javascript, will not know any better.) | ||
26 | * | ||
27 | * Another significant difference is that the aim of Arc90's Readability is | ||
28 | * to re-present the main content block of a given web page so users can | ||
29 | * read it more easily in their browsers. Correct identification, clean up, | ||
30 | * and separation of the content block is only a part of this process. | ||
31 | * This PHP port is only concerned with this part, it does not include code | ||
32 | * that relates to presentation in the browser - Arc90 already do | ||
33 | * that extremely well, and for PDF output there's FiveFilters.org's | ||
34 | * PDF Newspaper: http://fivefilters.org/pdf-newspaper/. | ||
35 | * | ||
36 | * Finally, this class contains methods that might be useful for developers | ||
37 | * working on HTML document fragments. So without deviating too much from | ||
38 | * the original code (which I don't want to do because it makes debugging | ||
39 | * and updating more difficult), I've tried to make it a little more | ||
40 | * developer friendly. You should be able to use the methods here on | ||
41 | * existing DOMElement objects without passing an entire HTML document to | ||
42 | * be parsed. | ||
43 | */ | ||
44 | |||
45 | // This class allows us to do JavaScript like assignements to innerHTML | ||
46 | require_once(dirname(__FILE__).'/JSLikeHTMLElement.php'); | ||
47 | |||
48 | // Alternative usage (for testing only!) | ||
49 | // uncomment the lins below and call Readability.php in your browser | ||
50 | // passing it the URL of the page you'd like content from, e.g.: | ||
51 | // Readability.php?url=http://medialens.org/alerts/09/090615_the_guardian_climate.php | ||
52 | |||
53 | /* | ||
54 | if (!isset($_GET['url']) || $_GET['url'] == '') { | ||
55 | die('Please pass a URL to the script. E.g. Readability.php?url=bla.com/story.html'); | ||
56 | } | ||
57 | $url = $_GET['url']; | ||
58 | if (!preg_match('!^https?://!i', $url)) $url = 'http://'.$url; | ||
59 | $html = file_get_contents($url); | ||
60 | $r = new Readability($html, $url); | ||
61 | $r->init(); | ||
62 | echo $r->articleContent->innerHTML; | ||
63 | */ | ||
64 | |||
65 | class Readability | ||
66 | { | ||
67 | public $version = '1.7.1-without-multi-page'; | ||
68 | public $convertLinksToFootnotes = false; | ||
69 | public $revertForcedParagraphElements = true; | ||
70 | public $articleTitle; | ||
71 | public $articleContent; | ||
72 | public $dom; | ||
73 | public $url = null; // optional - URL where HTML was retrieved | ||
74 | public $debug = false; | ||
75 | protected $body = null; // | ||
76 | protected $bodyCache = null; // Cache the body HTML in case we need to re-use it later | ||
77 | protected $flags = 7; // 1 | 2 | 4; // Start with all flags set. | ||
78 | protected $success = false; // indicates whether we were able to extract or not | ||
79 | |||
80 | /** | ||
81 | * All of the regular expressions in use within readability. | ||
82 | * Defined up here so we don't instantiate them repeatedly in loops. | ||
83 | **/ | ||
84 | public $regexps = array( | ||
85 | 'unlikelyCandidates' => '/combx|comment|community|disqus|extra|foot|header|menu|remark|rss|shoutbox|sidebar|sponsor|ad-break|agegate|pagination|pager|popup|tweet|twitter/i', | ||
86 | 'okMaybeItsACandidate' => '/and|article|body|column|main|shadow/i', | ||
87 | 'positive' => '/article|body|content|entry|hentry|main|page|pagination|post|text|blog|story/i', | ||
88 | 'negative' => '/combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget/i', | ||
89 | 'divToPElements' => '/<(a|blockquote|dl|div|img|ol|p|pre|table|ul)/i', | ||
90 | 'replaceBrs' => '/(<br[^>]*>[ \n\r\t]*){2,}/i', | ||
91 | 'replaceFonts' => '/<(\/?)font[^>]*>/i', | ||
92 | // 'trimRe' => '/^\s+|\s+$/g', // PHP has trim() | ||
93 | 'normalize' => '/\s{2,}/', | ||
94 | 'killBreaks' => '/(<br\s*\/?>(\s| ?)*){1,}/', | ||
95 | 'video' => '/http:\/\/(www\.)?(youtube|vimeo)\.com/i', | ||
96 | 'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i' | ||
97 | ); | ||
98 | |||
99 | /* constants */ | ||
100 | const FLAG_STRIP_UNLIKELYS = 1; | ||
101 | const FLAG_WEIGHT_CLASSES = 2; | ||
102 | const FLAG_CLEAN_CONDITIONALLY = 4; | ||
103 | |||
104 | /** | ||
105 | * Create instance of Readability | ||
106 | * @param string UTF-8 encoded string | ||
107 | * @param string (optional) URL associated with HTML (used for footnotes) | ||
108 | */ | ||
109 | function __construct($html, $url=null) | ||
110 | { | ||
111 | /* Turn all double br's into p's */ | ||
112 | /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */ | ||
113 | $html = preg_replace($this->regexps['replaceBrs'], '</p><p>', $html); | ||
114 | $html = preg_replace($this->regexps['replaceFonts'], '<$1span>', $html); | ||
115 | $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8"); | ||
116 | $this->dom = new DOMDocument(); | ||
117 | $this->dom->preserveWhiteSpace = false; | ||
118 | $this->dom->registerNodeClass('DOMElement', 'JSLikeHTMLElement'); | ||
119 | @$this->dom->loadHTML($html); | ||
120 | $this->url = $url; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * Get article title element | ||
125 | * @return DOMElement | ||
126 | */ | ||
127 | public function getTitle() { | ||
128 | return $this->articleTitle; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Get article content element | ||
133 | * @return DOMElement | ||
134 | */ | ||
135 | public function getContent() { | ||
136 | return $this->articleContent; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * Runs readability. | ||
141 | * | ||
142 | * Workflow: | ||
143 | * 1. Prep the document by removing script tags, css, etc. | ||
144 | * 2. Build readability's DOM tree. | ||
145 | * 3. Grab the article content from the current dom tree. | ||
146 | * 4. Replace the current DOM tree with the new one. | ||
147 | * 5. Read peacefully. | ||
148 | * | ||
149 | * @return boolean true if we found content, false otherwise | ||
150 | **/ | ||
151 | public function init() | ||
152 | { | ||
153 | $this->removeScripts($this->dom); | ||
154 | |||
155 | // Assume successful outcome | ||
156 | $this->success = true; | ||
157 | |||
158 | $bodyElems = $this->dom->getElementsByTagName('body'); | ||
159 | if ($bodyElems->length > 0) { | ||
160 | if ($this->bodyCache == null) { | ||
161 | $this->bodyCache = $bodyElems->item(0)->innerHTML; | ||
162 | } | ||
163 | if ($this->body == null) { | ||
164 | $this->body = $bodyElems->item(0); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | $this->prepDocument(); | ||
169 | |||
170 | //die($this->dom->documentElement->parentNode->nodeType); | ||
171 | //$this->setInnerHTML($this->dom->documentElement, $this->getInnerHTML($this->dom->documentElement)); | ||
172 | //die($this->getInnerHTML($this->dom->documentElement)); | ||
173 | |||
174 | /* Build readability's DOM tree */ | ||
175 | $overlay = $this->dom->createElement('div'); | ||
176 | $innerDiv = $this->dom->createElement('div'); | ||
177 | $articleTitle = $this->getArticleTitle(); | ||
178 | $articleContent = $this->grabArticle(); | ||
179 | |||
180 | if (!$articleContent) { | ||
181 | $this->success = false; | ||
182 | $articleContent = $this->dom->createElement('div'); | ||
183 | $articleContent->setAttribute('id', 'readability-content'); | ||
184 | $articleContent->innerHTML = '<p>Sorry, Readability was unable to parse this page for content.</p>'; | ||
185 | } | ||
186 | |||
187 | $overlay->setAttribute('id', 'readOverlay'); | ||
188 | $innerDiv->setAttribute('id', 'readInner'); | ||
189 | |||
190 | /* Glue the structure of our document together. */ | ||
191 | $innerDiv->appendChild($articleTitle); | ||
192 | $innerDiv->appendChild($articleContent); | ||
193 | $overlay->appendChild($innerDiv); | ||
194 | |||
195 | /* Clear the old HTML, insert the new content. */ | ||
196 | $this->body->innerHTML = ''; | ||
197 | $this->body->appendChild($overlay); | ||
198 | //document.body.insertBefore(overlay, document.body.firstChild); | ||
199 | $this->body->removeAttribute('style'); | ||
200 | |||
201 | $this->postProcessContent($articleContent); | ||
202 | |||
203 | // Set title and content instance variables | ||
204 | $this->articleTitle = $articleTitle; | ||
205 | $this->articleContent = $articleContent; | ||
206 | |||
207 | return $this->success; | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Debug | ||
212 | */ | ||
213 | protected function dbg($msg) { | ||
214 | if ($this->debug) echo '* ',$msg, '<br />', "\n"; | ||
215 | } | ||
216 | |||
217 | /** | ||
218 | * Run any post-process modifications to article content as necessary. | ||
219 | * | ||
220 | * @param DOMElement | ||
221 | * @return void | ||
222 | */ | ||
223 | public function postProcessContent($articleContent) { | ||
224 | if ($this->convertLinksToFootnotes && !preg_match('/wikipedia\.org/', @$this->url)) { | ||
225 | $this->addFootnotes($articleContent); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * Get the article title as an H1. | ||
231 | * | ||
232 | * @return DOMElement | ||
233 | */ | ||
234 | protected function getArticleTitle() { | ||
235 | $curTitle = ''; | ||
236 | $origTitle = ''; | ||
237 | |||
238 | try { | ||
239 | $curTitle = $origTitle = $this->getInnerText($this->dom->getElementsByTagName('title')->item(0)); | ||
240 | } catch(Exception $e) {} | ||
241 | |||
242 | if (preg_match('/ [\|\-] /', $curTitle)) | ||
243 | { | ||
244 | $curTitle = preg_replace('/(.*)[\|\-] .*/i', '$1', $origTitle); | ||
245 | |||
246 | if (count(explode(' ', $curTitle)) < 3) { | ||
247 | $curTitle = preg_replace('/[^\|\-]*[\|\-](.*)/i', '$1', $origTitle); | ||
248 | } | ||
249 | } | ||
250 | else if (strpos($curTitle, ': ') !== false) | ||
251 | { | ||
252 | $curTitle = preg_replace('/.*:(.*)/i', '$1', $origTitle); | ||
253 | |||
254 | if (count(explode(' ', $curTitle)) < 3) { | ||
255 | $curTitle = preg_replace('/[^:]*[:](.*)/i','$1', $origTitle); | ||
256 | } | ||
257 | } | ||
258 | else if(strlen($curTitle) > 150 || strlen($curTitle) < 15) | ||
259 | { | ||
260 | $hOnes = $this->dom->getElementsByTagName('h1'); | ||
261 | if($hOnes->length == 1) | ||
262 | { | ||
263 | $curTitle = $this->getInnerText($hOnes->item(0)); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | $curTitle = trim($curTitle); | ||
268 | |||
269 | if (count(explode(' ', $curTitle)) <= 4) { | ||
270 | $curTitle = $origTitle; | ||
271 | } | ||
272 | |||
273 | $articleTitle = $this->dom->createElement('h1'); | ||
274 | $articleTitle->innerHTML = $curTitle; | ||
275 | |||
276 | return $articleTitle; | ||
277 | } | ||
278 | |||
279 | /** | ||
280 | * Prepare the HTML document for readability to scrape it. | ||
281 | * This includes things like stripping javascript, CSS, and handling terrible markup. | ||
282 | * | ||
283 | * @return void | ||
284 | **/ | ||
285 | protected function prepDocument() { | ||
286 | /** | ||
287 | * In some cases a body element can't be found (if the HTML is totally hosed for example) | ||
288 | * so we create a new body node and append it to the document. | ||
289 | */ | ||
290 | if($this->dom->documentElement == null){ | ||
291 | throw new Exception("No document element"); | ||
292 | } | ||
293 | if ($this->body == null) | ||
294 | { | ||
295 | $this->body = $this->dom->createElement('body'); | ||
296 | $this->dom->documentElement->appendChild($this->body); | ||
297 | } | ||
298 | |||
299 | $this->body->setAttribute('id', 'readabilityBody'); | ||
300 | |||
301 | /* Remove all style tags in head */ | ||
302 | $styleTags = $this->dom->getElementsByTagName('style'); | ||
303 | for ($i = $styleTags->length-1; $i >= 0; $i--) | ||
304 | { | ||
305 | $styleTags->item($i)->parentNode->removeChild($styleTags->item($i)); | ||
306 | } | ||
307 | |||
308 | /* Turn all double br's into p's */ | ||
309 | /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */ | ||
310 | //document.body.innerHTML = document.body.innerHTML.replace(readability.regexps.replaceBrs, '</p><p>').replace(readability.regexps.replaceFonts, '<$1span>'); | ||
311 | // We do this in the constructor for PHP as that's when we have raw HTML - before parsing it into a DOM tree. | ||
312 | // Manipulating innerHTML as it's done in JS is not possible in PHP. | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * For easier reading, convert this document to have footnotes at the bottom rather than inline links. | ||
317 | * @see http://www.roughtype.com/archives/2010/05/experiments_in.php | ||
318 | * | ||
319 | * @return void | ||
320 | **/ | ||
321 | public function addFootnotes($articleContent) { | ||
322 | $footnotesWrapper = $this->dom->createElement('div'); | ||
323 | $footnotesWrapper->setAttribute('id', 'readability-footnotes'); | ||
324 | $footnotesWrapper->innerHTML = '<h3>References</h3>'; | ||
325 | |||
326 | $articleFootnotes = $this->dom->createElement('ol'); | ||
327 | $articleFootnotes->setAttribute('id', 'readability-footnotes-list'); | ||
328 | $footnotesWrapper->appendChild($articleFootnotes); | ||
329 | |||
330 | $articleLinks = $articleContent->getElementsByTagName('a'); | ||
331 | |||
332 | $linkCount = 0; | ||
333 | for ($i = 0; $i < $articleLinks->length; $i++) | ||
334 | { | ||
335 | $articleLink = $articleLinks->item($i); | ||
336 | $footnoteLink = $articleLink->cloneNode(true); | ||
337 | $refLink = $this->dom->createElement('a'); | ||
338 | $footnote = $this->dom->createElement('li'); | ||
339 | $linkDomain = @parse_url($footnoteLink->getAttribute('href'), PHP_URL_HOST); | ||
340 | if (!$linkDomain && isset($this->url)) $linkDomain = @parse_url($this->url, PHP_URL_HOST); | ||
341 | //linkDomain = footnoteLink.host ? footnoteLink.host : document.location.host, | ||
342 | $linkText = $this->getInnerText($articleLink); | ||
343 | |||
344 | if ((strpos($articleLink->getAttribute('class'), 'readability-DoNotFootnote') !== false) || preg_match($this->regexps['skipFootnoteLink'], $linkText)) { | ||
345 | continue; | ||
346 | } | ||
347 | |||
348 | $linkCount++; | ||
349 | |||
350 | /** Add a superscript reference after the article link */ | ||
351 | $refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount); | ||
352 | $refLink->innerHTML = '<small><sup>[' . $linkCount . ']</sup></small>'; | ||
353 | $refLink->setAttribute('class', 'readability-DoNotFootnote'); | ||
354 | $refLink->setAttribute('style', 'color: inherit;'); | ||
355 | |||
356 | //TODO: does this work or should we use DOMNode.isSameNode()? | ||
357 | if ($articleLink->parentNode->lastChild == $articleLink) { | ||
358 | $articleLink->parentNode->appendChild($refLink); | ||
359 | } else { | ||
360 | $articleLink->parentNode->insertBefore($refLink, $articleLink->nextSibling); | ||
361 | } | ||
362 | |||
363 | $articleLink->setAttribute('style', 'color: inherit; text-decoration: none;'); | ||
364 | $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount); | ||
365 | |||
366 | $footnote->innerHTML = '<small><sup><a href="#readabilityLink-' . $linkCount . '" title="Jump to Link in Article">^</a></sup></small> '; | ||
367 | |||
368 | $footnoteLink->innerHTML = ($footnoteLink->getAttribute('title') != '' ? $footnoteLink->getAttribute('title') : $linkText); | ||
369 | $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount); | ||
370 | |||
371 | $footnote->appendChild($footnoteLink); | ||
372 | if ($linkDomain) $footnote->innerHTML = $footnote->innerHTML . '<small> (' . $linkDomain . ')</small>'; | ||
373 | |||
374 | $articleFootnotes->appendChild($footnote); | ||
375 | } | ||
376 | |||
377 | if ($linkCount > 0) { | ||
378 | $articleContent->appendChild($footnotesWrapper); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Reverts P elements with class 'readability-styled' | ||
384 | * to text nodes - which is what they were before. | ||
385 | * | ||
386 | * @param DOMElement | ||
387 | * @return void | ||
388 | */ | ||
389 | function revertReadabilityStyledElements($articleContent) { | ||
390 | $xpath = new DOMXPath($articleContent->ownerDocument); | ||
391 | $elems = $xpath->query('.//p[@class="readability-styled"]', $articleContent); | ||
392 | //$elems = $articleContent->getElementsByTagName('p'); | ||
393 | for ($i = $elems->length-1; $i >= 0; $i--) { | ||
394 | $e = $elems->item($i); | ||
395 | $e->parentNode->replaceChild($articleContent->ownerDocument->createTextNode($e->textContent), $e); | ||
396 | //if ($e->hasAttribute('class') && $e->getAttribute('class') == 'readability-styled') { | ||
397 | // $e->parentNode->replaceChild($this->dom->createTextNode($e->textContent), $e); | ||
398 | //} | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * Prepare the article node for display. Clean out any inline styles, | ||
404 | * iframes, forms, strip extraneous <p> tags, etc. | ||
405 | * | ||
406 | * @param DOMElement | ||
407 | * @return void | ||
408 | */ | ||
409 | function prepArticle($articleContent) { | ||
410 | $this->cleanStyles($articleContent); | ||
411 | $this->killBreaks($articleContent); | ||
412 | if ($this->revertForcedParagraphElements) { | ||
413 | $this->revertReadabilityStyledElements($articleContent); | ||
414 | } | ||
415 | |||
416 | /* Clean out junk from the article content */ | ||
417 | $this->cleanConditionally($articleContent, 'form'); | ||
418 | $this->clean($articleContent, 'object'); | ||
419 | $this->clean($articleContent, 'h1'); | ||
420 | |||
421 | /** | ||
422 | * If there is only one h2, they are probably using it | ||
423 | * as a header and not a subheader, so remove it since we already have a header. | ||
424 | ***/ | ||
425 | if ($articleContent->getElementsByTagName('h2')->length == 1) { | ||
426 | $this->clean($articleContent, 'h2'); | ||
427 | } | ||
428 | $this->clean($articleContent, 'iframe'); | ||
429 | |||
430 | $this->cleanHeaders($articleContent); | ||
431 | |||
432 | /* Do these last as the previous stuff may have removed junk that will affect these */ | ||
433 | $this->cleanConditionally($articleContent, 'table'); | ||
434 | $this->cleanConditionally($articleContent, 'ul'); | ||
435 | $this->cleanConditionally($articleContent, 'div'); | ||
436 | |||
437 | /* Remove extra paragraphs */ | ||
438 | $articleParagraphs = $articleContent->getElementsByTagName('p'); | ||
439 | for ($i = $articleParagraphs->length-1; $i >= 0; $i--) | ||
440 | { | ||
441 | $imgCount = $articleParagraphs->item($i)->getElementsByTagName('img')->length; | ||
442 | $embedCount = $articleParagraphs->item($i)->getElementsByTagName('embed')->length; | ||
443 | $objectCount = $articleParagraphs->item($i)->getElementsByTagName('object')->length; | ||
444 | |||
445 | if ($imgCount === 0 && $embedCount === 0 && $objectCount === 0 && $this->getInnerText($articleParagraphs->item($i), false) == '') | ||
446 | { | ||
447 | $articleParagraphs->item($i)->parentNode->removeChild($articleParagraphs->item($i)); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | try { | ||
452 | $articleContent->innerHTML = preg_replace('/<br[^>]*>\s*<p/i', '<p', $articleContent->innerHTML); | ||
453 | //articleContent.innerHTML = articleContent.innerHTML.replace(/<br[^>]*>\s*<p/gi, '<p'); | ||
454 | } | ||
455 | catch (Exception $e) { | ||
456 | $this->dbg("Cleaning innerHTML of breaks failed. This is an IE strict-block-elements bug. Ignoring.: " . $e); | ||
457 | } | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * Initialize a node with the readability object. Also checks the | ||
462 | * className/id for special names to add to its score. | ||
463 | * | ||
464 | * @param Element | ||
465 | * @return void | ||
466 | **/ | ||
467 | protected function initializeNode($node) { | ||
468 | $readability = $this->dom->createAttribute('readability'); | ||
469 | $readability->value = 0; // this is our contentScore | ||
470 | $node->setAttributeNode($readability); | ||
471 | |||
472 | switch (strtoupper($node->tagName)) { // unsure if strtoupper is needed, but using it just in case | ||
473 | case 'DIV': | ||
474 | $readability->value += 5; | ||
475 | break; | ||
476 | |||
477 | case 'PRE': | ||
478 | case 'TD': | ||
479 | case 'BLOCKQUOTE': | ||
480 | $readability->value += 3; | ||
481 | break; | ||
482 | |||
483 | case 'ADDRESS': | ||
484 | case 'OL': | ||
485 | case 'UL': | ||
486 | case 'DL': | ||
487 | case 'DD': | ||
488 | case 'DT': | ||
489 | case 'LI': | ||
490 | case 'FORM': | ||
491 | $readability->value -= 3; | ||
492 | break; | ||
493 | |||
494 | case 'H1': | ||
495 | case 'H2': | ||
496 | case 'H3': | ||
497 | case 'H4': | ||
498 | case 'H5': | ||
499 | case 'H6': | ||
500 | case 'TH': | ||
501 | $readability->value -= 5; | ||
502 | break; | ||
503 | } | ||
504 | $readability->value += $this->getClassWeight($node); | ||
505 | } | ||
506 | |||
507 | /*** | ||
508 | * grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is | ||
509 | * most likely to be the stuff a user wants to read. Then return it wrapped up in a div. | ||
510 | * | ||
511 | * @return DOMElement | ||
512 | **/ | ||
513 | protected function grabArticle($page=null) { | ||
514 | $stripUnlikelyCandidates = $this->flagIsActive(self::FLAG_STRIP_UNLIKELYS); | ||
515 | if (!$page) $page = $this->dom; | ||
516 | $allElements = $page->getElementsByTagName('*'); | ||
517 | /** | ||
518 | * First, node prepping. Trash nodes that look cruddy (like ones with the class name "comment", etc), and turn divs | ||
519 | * into P tags where they have been used inappropriately (as in, where they contain no other block level elements.) | ||
520 | * | ||
521 | * Note: Assignment from index for performance. See http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5 | ||
522 | * TODO: Shouldn't this be a reverse traversal? | ||
523 | **/ | ||
524 | $node = null; | ||
525 | $nodesToScore = array(); | ||
526 | for ($nodeIndex = 0; ($node = $allElements->item($nodeIndex)); $nodeIndex++) { | ||
527 | //for ($nodeIndex=$targetList->length-1; $nodeIndex >= 0; $nodeIndex--) { | ||
528 | //$node = $targetList->item($nodeIndex); | ||
529 | $tagName = strtoupper($node->tagName); | ||
530 | /* Remove unlikely candidates */ | ||
531 | if ($stripUnlikelyCandidates) { | ||
532 | $unlikelyMatchString = $node->getAttribute('class') . $node->getAttribute('id'); | ||
533 | if ( | ||
534 | preg_match($this->regexps['unlikelyCandidates'], $unlikelyMatchString) && | ||
535 | !preg_match($this->regexps['okMaybeItsACandidate'], $unlikelyMatchString) && | ||
536 | $tagName != 'BODY' | ||
537 | ) | ||
538 | { | ||
539 | $this->dbg('Removing unlikely candidate - ' . $unlikelyMatchString); | ||
540 | //$nodesToRemove[] = $node; | ||
541 | $node->parentNode->removeChild($node); | ||
542 | $nodeIndex--; | ||
543 | continue; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | if ($tagName == 'P' || $tagName == 'TD' || $tagName == 'PRE') { | ||
548 | $nodesToScore[] = $node; | ||
549 | } | ||
550 | |||
551 | /* Turn all divs that don't have children block level elements into p's */ | ||
552 | if ($tagName == 'DIV') { | ||
553 | if (!preg_match($this->regexps['divToPElements'], $node->innerHTML)) { | ||
554 | //$this->dbg('Altering div to p'); | ||
555 | $newNode = $this->dom->createElement('p'); | ||
556 | try { | ||
557 | $newNode->innerHTML = $node->innerHTML; | ||
558 | //$nodesToReplace[] = array('new'=>$newNode, 'old'=>$node); | ||
559 | $node->parentNode->replaceChild($newNode, $node); | ||
560 | $nodeIndex--; | ||
561 | $nodesToScore[] = $node; // or $newNode? | ||
562 | } | ||
563 | catch(Exception $e) { | ||
564 | $this->dbg('Could not alter div to p, reverting back to div.: ' . $e); | ||
565 | } | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | /* EXPERIMENTAL */ | ||
570 | // TODO: change these p elements back to text nodes after processing | ||
571 | for ($i = 0, $il = $node->childNodes->length; $i < $il; $i++) { | ||
572 | $childNode = $node->childNodes->item($i); | ||
573 | if ($childNode->nodeType == 3) { // XML_TEXT_NODE | ||
574 | //$this->dbg('replacing text node with a p tag with the same content.'); | ||
575 | $p = $this->dom->createElement('p'); | ||
576 | $p->innerHTML = $childNode->nodeValue; | ||
577 | $p->setAttribute('style', 'display: inline;'); | ||
578 | $p->setAttribute('class', 'readability-styled'); | ||
579 | $childNode->parentNode->replaceChild($p, $childNode); | ||
580 | } | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | /** | ||
587 | * Loop through all paragraphs, and assign a score to them based on how content-y they look. | ||
588 | * Then add their score to their parent node. | ||
589 | * | ||
590 | * A score is determined by things like number of commas, class names, etc. Maybe eventually link density. | ||
591 | **/ | ||
592 | $candidates = array(); | ||
593 | for ($pt=0; $pt < count($nodesToScore); $pt++) { | ||
594 | $parentNode = $nodesToScore[$pt]->parentNode; | ||
595 | // $grandParentNode = $parentNode ? $parentNode->parentNode : null; | ||
596 | $grandParentNode = !$parentNode ? null : (($parentNode->parentNode instanceof DOMElement) ? $parentNode->parentNode : null); | ||
597 | $innerText = $this->getInnerText($nodesToScore[$pt]); | ||
598 | |||
599 | if (!$parentNode || !isset($parentNode->tagName)) { | ||
600 | continue; | ||
601 | } | ||
602 | |||
603 | /* If this paragraph is less than 25 characters, don't even count it. */ | ||
604 | if(strlen($innerText) < 25) { | ||
605 | continue; | ||
606 | } | ||
607 | |||
608 | /* Initialize readability data for the parent. */ | ||
609 | if (!$parentNode->hasAttribute('readability')) | ||
610 | { | ||
611 | $this->initializeNode($parentNode); | ||
612 | $candidates[] = $parentNode; | ||
613 | } | ||
614 | |||
615 | /* Initialize readability data for the grandparent. */ | ||
616 | if ($grandParentNode && !$grandParentNode->hasAttribute('readability') && isset($grandParentNode->tagName)) | ||
617 | { | ||
618 | $this->initializeNode($grandParentNode); | ||
619 | $candidates[] = $grandParentNode; | ||
620 | } | ||
621 | |||
622 | $contentScore = 0; | ||
623 | |||
624 | /* Add a point for the paragraph itself as a base. */ | ||
625 | $contentScore++; | ||
626 | |||
627 | /* Add points for any commas within this paragraph */ | ||
628 | $contentScore += count(explode(',', $innerText)); | ||
629 | |||
630 | /* For every 100 characters in this paragraph, add another point. Up to 3 points. */ | ||
631 | $contentScore += min(floor(strlen($innerText) / 100), 3); | ||
632 | |||
633 | /* Add the score to the parent. The grandparent gets half. */ | ||
634 | $parentNode->getAttributeNode('readability')->value += $contentScore; | ||
635 | |||
636 | if ($grandParentNode) { | ||
637 | $grandParentNode->getAttributeNode('readability')->value += $contentScore/2; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | /** | ||
642 | * After we've calculated scores, loop through all of the possible candidate nodes we found | ||
643 | * and find the one with the highest score. | ||
644 | **/ | ||
645 | $topCandidate = null; | ||
646 | for ($c=0, $cl=count($candidates); $c < $cl; $c++) | ||
647 | { | ||
648 | /** | ||
649 | * Scale the final candidates score based on link density. Good content should have a | ||
650 | * relatively small link density (5% or less) and be mostly unaffected by this operation. | ||
651 | **/ | ||
652 | $readability = $candidates[$c]->getAttributeNode('readability'); | ||
653 | $readability->value = $readability->value * (1-$this->getLinkDensity($candidates[$c])); | ||
654 | |||
655 | $this->dbg('Candidate: ' . $candidates[$c]->tagName . ' (' . $candidates[$c]->getAttribute('class') . ':' . $candidates[$c]->getAttribute('id') . ') with score ' . $readability->value); | ||
656 | |||
657 | if (!$topCandidate || $readability->value > (int)$topCandidate->getAttribute('readability')) { | ||
658 | $topCandidate = $candidates[$c]; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * If we still have no top candidate, just use the body as a last resort. | ||
664 | * We also have to copy the body node so it is something we can modify. | ||
665 | **/ | ||
666 | if ($topCandidate === null || strtoupper($topCandidate->tagName) == 'BODY') | ||
667 | { | ||
668 | $topCandidate = $this->dom->createElement('div'); | ||
669 | $topCandidate->innerHTML = ($page instanceof DOMDocument) ? $page->saveXML($page->documentElement) : $page->innerHTML; | ||
670 | $page->innerHTML = ''; | ||
671 | $page->appendChild($topCandidate); | ||
672 | $this->initializeNode($topCandidate); | ||
673 | } | ||
674 | |||
675 | /** | ||
676 | * Now that we have the top candidate, look through its siblings for content that might also be related. | ||
677 | * Things like preambles, content split by ads that we removed, etc. | ||
678 | **/ | ||
679 | $articleContent = $this->dom->createElement('div'); | ||
680 | $articleContent->setAttribute('id', 'readability-content'); | ||
681 | $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2); | ||
682 | $siblingNodes = $topCandidate->parentNode->childNodes; | ||
683 | |||
684 | for ($s=0, $sl=$siblingNodes->length; $s < $sl; $s++) | ||
685 | { | ||
686 | $siblingNode = $siblingNodes->item($s); | ||
687 | $append = false; | ||
688 | |||
689 | $this->dbg('Looking at sibling node: ' . $siblingNode->nodeName . (($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability')) ? (' with score ' . $siblingNode->getAttribute('readability')) : '')); | ||
690 | |||
691 | //dbg('Sibling has score ' . ($siblingNode->readability ? siblingNode.readability.contentScore : 'Unknown')); | ||
692 | |||
693 | if ($siblingNode === $topCandidate) | ||
694 | // or if ($siblingNode->isSameNode($topCandidate)) | ||
695 | { | ||
696 | $append = true; | ||
697 | } | ||
698 | |||
699 | $contentBonus = 0; | ||
700 | /* Give a bonus if sibling nodes and top candidates have the example same classname */ | ||
701 | if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->getAttribute('class') == $topCandidate->getAttribute('class') && $topCandidate->getAttribute('class') != '') { | ||
702 | $contentBonus += ((int)$topCandidate->getAttribute('readability')) * 0.2; | ||
703 | } | ||
704 | |||
705 | if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability') && (((int)$siblingNode->getAttribute('readability')) + $contentBonus) >= $siblingScoreThreshold) | ||
706 | { | ||
707 | $append = true; | ||
708 | } | ||
709 | |||
710 | if (strtoupper($siblingNode->nodeName) == 'P') { | ||
711 | $linkDensity = $this->getLinkDensity($siblingNode); | ||
712 | $nodeContent = $this->getInnerText($siblingNode); | ||
713 | $nodeLength = strlen($nodeContent); | ||
714 | |||
715 | if ($nodeLength > 80 && $linkDensity < 0.25) | ||
716 | { | ||
717 | $append = true; | ||
718 | } | ||
719 | else if ($nodeLength < 80 && $linkDensity === 0 && preg_match('/\.( |$)/', $nodeContent)) | ||
720 | { | ||
721 | $append = true; | ||
722 | } | ||
723 | } | ||
724 | |||
725 | if ($append) | ||
726 | { | ||
727 | $this->dbg('Appending node: ' . $siblingNode->nodeName); | ||
728 | |||
729 | $nodeToAppend = null; | ||
730 | $sibNodeName = strtoupper($siblingNode->nodeName); | ||
731 | if ($sibNodeName != 'DIV' && $sibNodeName != 'P') { | ||
732 | /* We have a node that isn't a common block level element, like a form or td tag. Turn it into a div so it doesn't get filtered out later by accident. */ | ||
733 | |||
734 | $this->dbg('Altering siblingNode of ' . $sibNodeName . ' to div.'); | ||
735 | $nodeToAppend = $this->dom->createElement('div'); | ||
736 | try { | ||
737 | $nodeToAppend->setAttribute('id', $siblingNode->getAttribute('id')); | ||
738 | $nodeToAppend->innerHTML = $siblingNode->innerHTML; | ||
739 | } | ||
740 | catch(Exception $e) | ||
741 | { | ||
742 | $this->dbg('Could not alter siblingNode to div, reverting back to original.'); | ||
743 | $nodeToAppend = $siblingNode; | ||
744 | $s--; | ||
745 | $sl--; | ||
746 | } | ||
747 | } else { | ||
748 | $nodeToAppend = $siblingNode; | ||
749 | $s--; | ||
750 | $sl--; | ||
751 | } | ||
752 | |||
753 | /* To ensure a node does not interfere with readability styles, remove its classnames */ | ||
754 | $nodeToAppend->removeAttribute('class'); | ||
755 | |||
756 | /* Append sibling and subtract from our list because it removes the node when you append to another node */ | ||
757 | $articleContent->appendChild($nodeToAppend); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | /** | ||
762 | * So we have all of the content that we need. Now we clean it up for presentation. | ||
763 | **/ | ||
764 | $this->prepArticle($articleContent); | ||
765 | |||
766 | /** | ||
767 | * Now that we've gone through the full algorithm, check to see if we got any meaningful content. | ||
768 | * If we didn't, we may need to re-run grabArticle with different flags set. This gives us a higher | ||
769 | * likelihood of finding the content, and the sieve approach gives us a higher likelihood of | ||
770 | * finding the -right- content. | ||
771 | **/ | ||
772 | if (strlen($this->getInnerText($articleContent, false)) < 250) | ||
773 | { | ||
774 | $this->body->innerHTML = $this->bodyCache; | ||
775 | |||
776 | if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS)) { | ||
777 | $this->removeFlag(self::FLAG_STRIP_UNLIKELYS); | ||
778 | return $this->grabArticle($this->body); | ||
779 | } | ||
780 | else if ($this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) { | ||
781 | $this->removeFlag(self::FLAG_WEIGHT_CLASSES); | ||
782 | return $this->grabArticle($this->body); | ||
783 | } | ||
784 | else if ($this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) { | ||
785 | $this->removeFlag(self::FLAG_CLEAN_CONDITIONALLY); | ||
786 | return $this->grabArticle($this->body); | ||
787 | } | ||
788 | else { | ||
789 | return false; | ||
790 | } | ||
791 | } | ||
792 | return $articleContent; | ||
793 | } | ||
794 | |||
795 | /** | ||
796 | * Remove script tags from document | ||
797 | * | ||
798 | * @param DOMElement | ||
799 | * @return void | ||
800 | */ | ||
801 | public function removeScripts($doc) { | ||
802 | $scripts = $doc->getElementsByTagName('script'); | ||
803 | for($i = $scripts->length-1; $i >= 0; $i--) | ||
804 | { | ||
805 | $scripts->item($i)->parentNode->removeChild($scripts->item($i)); | ||
806 | } | ||
807 | } | ||
808 | |||
809 | /** | ||
810 | * Get the inner text of a node. | ||
811 | * This also strips out any excess whitespace to be found. | ||
812 | * | ||
813 | * @param DOMElement $ | ||
814 | * @param boolean $normalizeSpaces (default: true) | ||
815 | * @return string | ||
816 | **/ | ||
817 | public function getInnerText($e, $normalizeSpaces=true) { | ||
818 | $textContent = ''; | ||
819 | |||
820 | if (!isset($e->textContent) || $e->textContent == '') { | ||
821 | return ''; | ||
822 | } | ||
823 | |||
824 | $textContent = trim($e->textContent); | ||
825 | |||
826 | if ($normalizeSpaces) { | ||
827 | return preg_replace($this->regexps['normalize'], ' ', $textContent); | ||
828 | } else { | ||
829 | return $textContent; | ||
830 | } | ||
831 | } | ||
832 | |||
833 | /** | ||
834 | * Get the number of times a string $s appears in the node $e. | ||
835 | * | ||
836 | * @param DOMElement $e | ||
837 | * @param string - what to count. Default is "," | ||
838 | * @return number (integer) | ||
839 | **/ | ||
840 | public function getCharCount($e, $s=',') { | ||
841 | return substr_count($this->getInnerText($e), $s); | ||
842 | } | ||
843 | |||
844 | /** | ||
845 | * Remove the style attribute on every $e and under. | ||
846 | * | ||
847 | * @param DOMElement $e | ||
848 | * @return void | ||
849 | */ | ||
850 | public function cleanStyles($e) { | ||
851 | $elems = $e->getElementsByTagName('*'); | ||
852 | foreach ($elems as $elem) { | ||
853 | $elem->removeAttribute('style'); | ||
854 | } | ||
855 | } | ||
856 | |||
857 | /** | ||
858 | * Get the density of links as a percentage of the content | ||
859 | * This is the amount of text that is inside a link divided by the total text in the node. | ||
860 | * | ||
861 | * @param DOMElement $e | ||
862 | * @return number (float) | ||
863 | */ | ||
864 | public function getLinkDensity($e) { | ||
865 | $links = $e->getElementsByTagName('a'); | ||
866 | $textLength = strlen($this->getInnerText($e)); | ||
867 | $linkLength = 0; | ||
868 | for ($i=0, $il=$links->length; $i < $il; $i++) | ||
869 | { | ||
870 | $linkLength += strlen($this->getInnerText($links->item($i))); | ||
871 | } | ||
872 | if ($textLength > 0) { | ||
873 | return $linkLength / $textLength; | ||
874 | } else { | ||
875 | return 0; | ||
876 | } | ||
877 | } | ||
878 | |||
879 | /** | ||
880 | * Get an elements class/id weight. Uses regular expressions to tell if this | ||
881 | * element looks good or bad. | ||
882 | * | ||
883 | * @param DOMElement $e | ||
884 | * @return number (Integer) | ||
885 | */ | ||
886 | public function getClassWeight($e) { | ||
887 | if(!$this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) { | ||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | $weight = 0; | ||
892 | |||
893 | /* Look for a special classname */ | ||
894 | if ($e->hasAttribute('class') && $e->getAttribute('class') != '') | ||
895 | { | ||
896 | if (preg_match($this->regexps['negative'], $e->getAttribute('class'))) { | ||
897 | $weight -= 25; | ||
898 | } | ||
899 | if (preg_match($this->regexps['positive'], $e->getAttribute('class'))) { | ||
900 | $weight += 25; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | /* Look for a special ID */ | ||
905 | if ($e->hasAttribute('id') && $e->getAttribute('id') != '') | ||
906 | { | ||
907 | if (preg_match($this->regexps['negative'], $e->getAttribute('id'))) { | ||
908 | $weight -= 25; | ||
909 | } | ||
910 | if (preg_match($this->regexps['positive'], $e->getAttribute('id'))) { | ||
911 | $weight += 25; | ||
912 | } | ||
913 | } | ||
914 | return $weight; | ||
915 | } | ||
916 | |||
917 | /** | ||
918 | * Remove extraneous break tags from a node. | ||
919 | * | ||
920 | * @param DOMElement $node | ||
921 | * @return void | ||
922 | */ | ||
923 | public function killBreaks($node) { | ||
924 | $html = $node->innerHTML; | ||
925 | $html = preg_replace($this->regexps['killBreaks'], '<br />', $html); | ||
926 | $node->innerHTML = $html; | ||
927 | } | ||
928 | |||
929 | /** | ||
930 | * Clean a node of all elements of type "tag". | ||
931 | * (Unless it's a youtube/vimeo video. People love movies.) | ||
932 | * | ||
933 | * @param DOMElement $e | ||
934 | * @param string $tag | ||
935 | * @return void | ||
936 | */ | ||
937 | public function clean($e, $tag) { | ||
938 | $targetList = $e->getElementsByTagName($tag); | ||
939 | $isEmbed = ($tag == 'object' || $tag == 'embed'); | ||
940 | |||
941 | for ($y=$targetList->length-1; $y >= 0; $y--) { | ||
942 | /* Allow youtube and vimeo videos through as people usually want to see those. */ | ||
943 | if ($isEmbed) { | ||
944 | $attributeValues = ''; | ||
945 | for ($i=0, $il=$targetList->item($y)->attributes->length; $i < $il; $i++) { | ||
946 | $attributeValues .= $targetList->item($y)->attributes->item($i)->value . '|'; // DOMAttr? (TODO: test) | ||
947 | } | ||
948 | |||
949 | /* First, check the elements attributes to see if any of them contain youtube or vimeo */ | ||
950 | if (preg_match($this->regexps['video'], $attributeValues)) { | ||
951 | continue; | ||
952 | } | ||
953 | |||
954 | /* Then check the elements inside this element for the same. */ | ||
955 | if (preg_match($this->regexps['video'], $targetList->item($y)->innerHTML)) { | ||
956 | continue; | ||
957 | } | ||
958 | } | ||
959 | $targetList->item($y)->parentNode->removeChild($targetList->item($y)); | ||
960 | } | ||
961 | } | ||
962 | |||
963 | /** | ||
964 | * Clean an element of all tags of type "tag" if they look fishy. | ||
965 | * "Fishy" is an algorithm based on content length, classnames, | ||
966 | * link density, number of images & embeds, etc. | ||
967 | * | ||
968 | * @param DOMElement $e | ||
969 | * @param string $tag | ||
970 | * @return void | ||
971 | */ | ||
972 | public function cleanConditionally($e, $tag) { | ||
973 | if (!$this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) { | ||
974 | return; | ||
975 | } | ||
976 | |||
977 | $tagsList = $e->getElementsByTagName($tag); | ||
978 | $curTagsLength = $tagsList->length; | ||
979 | |||
980 | /** | ||
981 | * Gather counts for other typical elements embedded within. | ||
982 | * Traverse backwards so we can remove nodes at the same time without effecting the traversal. | ||
983 | * | ||
984 | * TODO: Consider taking into account original contentScore here. | ||
985 | */ | ||
986 | for ($i=$curTagsLength-1; $i >= 0; $i--) { | ||
987 | $weight = $this->getClassWeight($tagsList->item($i)); | ||
988 | $contentScore = ($tagsList->item($i)->hasAttribute('readability')) ? (int)$tagsList->item($i)->getAttribute('readability') : 0; | ||
989 | |||
990 | $this->dbg('Cleaning Conditionally ' . $tagsList->item($i)->tagName . ' (' . $tagsList->item($i)->getAttribute('class') . ':' . $tagsList->item($i)->getAttribute('id') . ')' . (($tagsList->item($i)->hasAttribute('readability')) ? (' with score ' . $tagsList->item($i)->getAttribute('readability')) : '')); | ||
991 | |||
992 | if ($weight + $contentScore < 0) { | ||
993 | $tagsList->item($i)->parentNode->removeChild($tagsList->item($i)); | ||
994 | } | ||
995 | else if ( $this->getCharCount($tagsList->item($i), ',') < 10) { | ||
996 | /** | ||
997 | * If there are not very many commas, and the number of | ||
998 | * non-paragraph elements is more than paragraphs or other ominous signs, remove the element. | ||
999 | **/ | ||
1000 | $p = $tagsList->item($i)->getElementsByTagName('p')->length; | ||
1001 | $img = $tagsList->item($i)->getElementsByTagName('img')->length; | ||
1002 | $li = $tagsList->item($i)->getElementsByTagName('li')->length-100; | ||
1003 | $input = $tagsList->item($i)->getElementsByTagName('input')->length; | ||
1004 | |||
1005 | $embedCount = 0; | ||
1006 | $embeds = $tagsList->item($i)->getElementsByTagName('embed'); | ||
1007 | for ($ei=0, $il=$embeds->length; $ei < $il; $ei++) { | ||
1008 | if (preg_match($this->regexps['video'], $embeds->item($ei)->getAttribute('src'))) { | ||
1009 | $embedCount++; | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | $linkDensity = $this->getLinkDensity($tagsList->item($i)); | ||
1014 | $contentLength = strlen($this->getInnerText($tagsList->item($i))); | ||
1015 | $toRemove = false; | ||
1016 | |||
1017 | if ( $img > $p ) { | ||
1018 | $toRemove = true; | ||
1019 | } else if ($li > $p && $tag != 'ul' && $tag != 'ol') { | ||
1020 | $toRemove = true; | ||
1021 | } else if ( $input > floor($p/3) ) { | ||
1022 | $toRemove = true; | ||
1023 | } else if ($contentLength < 25 && ($img === 0 || $img > 2) ) { | ||
1024 | $toRemove = true; | ||
1025 | } else if($weight < 25 && $linkDensity > 0.2) { | ||
1026 | $toRemove = true; | ||
1027 | } else if($weight >= 25 && $linkDensity > 0.5) { | ||
1028 | $toRemove = true; | ||
1029 | } else if(($embedCount == 1 && $contentLength < 75) || $embedCount > 1) { | ||
1030 | $toRemove = true; | ||
1031 | } | ||
1032 | |||
1033 | if ($toRemove) { | ||
1034 | $tagsList->item($i)->parentNode->removeChild($tagsList->item($i)); | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | /** | ||
1041 | * Clean out spurious headers from an Element. Checks things like classnames and link density. | ||
1042 | * | ||
1043 | * @param DOMElement $e | ||
1044 | * @return void | ||
1045 | */ | ||
1046 | public function cleanHeaders($e) { | ||
1047 | for ($headerIndex = 1; $headerIndex < 3; $headerIndex++) { | ||
1048 | $headers = $e->getElementsByTagName('h' . $headerIndex); | ||
1049 | for ($i=$headers->length-1; $i >=0; $i--) { | ||
1050 | if ($this->getClassWeight($headers->item($i)) < 0 || $this->getLinkDensity($headers->item($i)) > 0.33) { | ||
1051 | $headers->item($i)->parentNode->removeChild($headers->item($i)); | ||
1052 | } | ||
1053 | } | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | public function flagIsActive($flag) { | ||
1058 | return ($this->flags & $flag) > 0; | ||
1059 | } | ||
1060 | |||
1061 | public function addFlag($flag) { | ||
1062 | $this->flags = $this->flags | $flag; | ||
1063 | } | ||
1064 | |||
1065 | public function removeFlag($flag) { | ||
1066 | $this->flags = $this->flags & ~$flag; | ||
1067 | } | ||
1068 | } | ||
1069 | ?> \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/readability/Readability.php b/inc/3rdparty/libraries/readability/Readability.php index 4fa3ba63..a30012ce 100755 --- a/inc/3rdparty/libraries/readability/Readability.php +++ b/inc/3rdparty/libraries/readability/Readability.php | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | // This class allows us to do JavaScript like assignements to innerHTML | 47 | // This class allows us to do JavaScript like assignements to innerHTML |
48 | require_once(dirname(__FILE__).'/JSLikeHTMLElement.php'); | 48 | require_once(dirname(__FILE__).'/JSLikeHTMLElement.php'); |
49 | libxml_use_internal_errors(true); | ||
49 | 50 | ||
50 | // Alternative usage (for testing only!) | 51 | // Alternative usage (for testing only!) |
51 | // uncomment the lines below and call Readability.php in your browser | 52 | // uncomment the lines below and call Readability.php in your browser |
@@ -697,7 +698,7 @@ class Readability | |||
697 | $articleContent = $this->dom->createElement('div'); | 698 | $articleContent = $this->dom->createElement('div'); |
698 | $articleContent->setAttribute('id', 'readability-content'); | 699 | $articleContent->setAttribute('id', 'readability-content'); |
699 | $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2); | 700 | $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2); |
700 | $siblingNodes = $topCandidate->parentNode->childNodes; | 701 | $siblingNodes = @$topCandidate->parentNode->childNodes; |
701 | if (!isset($siblingNodes)) { | 702 | if (!isset($siblingNodes)) { |
702 | $siblingNodes = new stdClass; | 703 | $siblingNodes = new stdClass; |
703 | $siblingNodes->length = 0; | 704 | $siblingNodes->length = 0; |
@@ -1148,4 +1149,4 @@ class Readability | |||
1148 | } | 1149 | } |
1149 | 1150 | ||
1150 | } | 1151 | } |
1151 | ?> \ No newline at end of file | 1152 | ?> |
diff --git a/inc/3rdparty/libraries/tcpdf/tcpdf.php b/inc/3rdparty/libraries/tcpdf/tcpdf.php index 78694a0e..70c1747a 100644 --- a/inc/3rdparty/libraries/tcpdf/tcpdf.php +++ b/inc/3rdparty/libraries/tcpdf/tcpdf.php | |||
@@ -2927,11 +2927,17 @@ class TCPDF { | |||
2927 | public function Error($msg) { | 2927 | public function Error($msg) { |
2928 | // unset all class variables | 2928 | // unset all class variables |
2929 | $this->_destroy(true); | 2929 | $this->_destroy(true); |
2930 | throw new Exception('TCPDF ERROR: '.$msg); | ||
2931 | /* | ||
2932 | |||
2933 | I had problems with the constants for some reason, so here we force | ||
2934 | |||
2935 | $this->_destroy(true); | ||
2930 | if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) { | 2936 | if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) { |
2931 | die('<strong>TCPDF ERROR: </strong>'.$msg); | 2937 | die('<strong>TCPDF ERROR: </strong>'.$msg); |
2932 | } else { | 2938 | } else { |
2933 | throw new Exception('TCPDF ERROR: '.$msg); | 2939 | throw new Exception('TCPDF ERROR: '.$msg); |
2934 | } | 2940 | }*/ |
2935 | } | 2941 | } |
2936 | 2942 | ||
2937 | /** | 2943 | /** |
@@ -6915,7 +6921,7 @@ class TCPDF { | |||
6915 | $ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k; | 6921 | $ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k; |
6916 | $imsize = array($pw, $ph); | 6922 | $imsize = array($pw, $ph); |
6917 | } else { | 6923 | } else { |
6918 | $this->Error('[Image] Unable to get the size of the image: '.$file); | 6924 | $this->Error('[Image] Unable to fetch image: '.$file); |
6919 | } | 6925 | } |
6920 | } | 6926 | } |
6921 | // file hash | 6927 | // file hash |
diff --git a/inc/3rdparty/makefulltextfeed.php b/inc/3rdparty/makefulltextfeed.php index a081f88b..27a62d73 100755 --- a/inc/3rdparty/makefulltextfeed.php +++ b/inc/3rdparty/makefulltextfeed.php | |||
@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
31 | //error_reporting(E_ALL ^ E_NOTICE); | 31 | //error_reporting(E_ALL ^ E_NOTICE); |
32 | ini_set("display_errors", 1); | 32 | ini_set("display_errors", 1); |
33 | @set_time_limit(120); | 33 | @set_time_limit(120); |
34 | libxml_use_internal_errors(true); | ||
35 | |||
34 | 36 | ||
35 | // Deal with magic quotes | 37 | // Deal with magic quotes |
36 | if (get_magic_quotes_gpc()) { | 38 | if (get_magic_quotes_gpc()) { |
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index f5262a8e..a164ed47 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php | |||
@@ -180,6 +180,13 @@ class Poche | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | // if there are tags, add them to the new article | ||
184 | if (isset($_GET['tags'])) { | ||
185 | $_POST['value'] = $_GET['tags']; | ||
186 | $_POST['entry_id'] = $last_id; | ||
187 | $this->action('add_tag', $url); | ||
188 | } | ||
189 | |||
183 | $this->messages->add('s', _('the link has been added successfully')); | 190 | $this->messages->add('s', _('the link has been added successfully')); |
184 | } | 191 | } |
185 | else { | 192 | else { |
@@ -192,20 +199,34 @@ class Poche | |||
192 | } else { | 199 | } else { |
193 | Tools::redirect('?view=home&closewin=true'); | 200 | Tools::redirect('?view=home&closewin=true'); |
194 | } | 201 | } |
202 | return $last_id; | ||
195 | break; | 203 | break; |
196 | case 'delete': | 204 | case 'delete': |
197 | $msg = 'delete link #' . $id; | 205 | if (isset($_GET['search'])) { |
198 | if ($this->store->deleteById($id, $this->user->getId())) { | 206 | //when we want to apply a delete to a search |
199 | if (DOWNLOAD_PICTURES) { | 207 | $tags = array($_GET['search']); |
200 | Picture::removeDirectory(ABS_PATH . $id); | 208 | $allentry_ids = $this->store->search($tags[0], $this->user->getId()); |
209 | $entry_ids = array(); | ||
210 | foreach ($allentry_ids as $eachentry) { | ||
211 | $entry_ids[] = $eachentry[0]; | ||
201 | } | 212 | } |
202 | $this->messages->add('s', _('the link has been deleted successfully')); | 213 | } else { // delete a single article |
214 | $entry_ids = array($id); | ||
203 | } | 215 | } |
204 | else { | 216 | foreach($entry_ids as $id) { |
205 | $this->messages->add('e', _('the link wasn\'t deleted')); | 217 | $msg = 'delete link #' . $id; |
206 | $msg = 'error : can\'t delete link #' . $id; | 218 | if ($this->store->deleteById($id, $this->user->getId())) { |
219 | if (DOWNLOAD_PICTURES) { | ||
220 | Picture::removeDirectory(ABS_PATH . $id); | ||
221 | } | ||
222 | $this->messages->add('s', _('the link has been deleted successfully')); | ||
223 | } | ||
224 | else { | ||
225 | $this->messages->add('e', _('the link wasn\'t deleted')); | ||
226 | $msg = 'error : can\'t delete link #' . $id; | ||
227 | } | ||
228 | Tools::logm($msg); | ||
207 | } | 229 | } |
208 | Tools::logm($msg); | ||
209 | Tools::redirect('?'); | 230 | Tools::redirect('?'); |
210 | break; | 231 | break; |
211 | case 'toggle_fav' : | 232 | case 'toggle_fav' : |
@@ -220,8 +241,21 @@ class Poche | |||
220 | } | 241 | } |
221 | break; | 242 | break; |
222 | case 'toggle_archive' : | 243 | case 'toggle_archive' : |
223 | $this->store->archiveById($id, $this->user->getId()); | 244 | if (isset($_GET['tag_id'])) { |
224 | Tools::logm('archive link #' . $id); | 245 | //when we want to archive a whole tag |
246 | $tag_id = $_GET['tag_id']; | ||
247 | $allentry_ids = $this->store->retrieveEntriesByTag($tag_id, $this->user->getId()); | ||
248 | $entry_ids = array(); | ||
249 | foreach ($allentry_ids as $eachentry) { | ||
250 | $entry_ids[] = $eachentry[0]; | ||
251 | } | ||
252 | } else { //archive a single article | ||
253 | $entry_ids = array($id); | ||
254 | } | ||
255 | foreach($entry_ids as $id) { | ||
256 | $this->store->archiveById($id, $this->user->getId()); | ||
257 | Tools::logm('archive link #' . $id); | ||
258 | } | ||
225 | if ( Tools::isAjaxRequest() ) { | 259 | if ( Tools::isAjaxRequest() ) { |
226 | echo 1; | 260 | echo 1; |
227 | exit; | 261 | exit; |
@@ -414,9 +448,12 @@ class Poche | |||
414 | } | 448 | } |
415 | 449 | ||
416 | # flattr checking | 450 | # flattr checking |
417 | $flattr = new FlattrItem(); | 451 | $flattr = NULL; |
418 | $flattr->checkItem($entry['url'], $entry['id']); | 452 | if (FLATTR) { |
419 | 453 | $flattr = new FlattrItem(); | |
454 | $flattr->checkItem($entry['url'], $entry['id']); | ||
455 | } | ||
456 | |||
420 | # tags | 457 | # tags |
421 | $tags = $this->store->retrieveTagsByEntry($entry['id']); | 458 | $tags = $this->store->retrieveTagsByEntry($entry['id']); |
422 | 459 | ||
@@ -549,6 +586,8 @@ class Poche | |||
549 | Tools::redirect($referer); | 586 | Tools::redirect($referer); |
550 | } | 587 | } |
551 | $this->messages->add('e', _('login failed: bad login or password')); | 588 | $this->messages->add('e', _('login failed: bad login or password')); |
589 | // log login failure in web server log to allow fail2ban usage | ||
590 | error_log('user '.$login.' authentication failure'); | ||
552 | Tools::logm('login failed'); | 591 | Tools::logm('login failed'); |
553 | Tools::redirect(); | 592 | Tools::redirect(); |
554 | } | 593 | } |
@@ -634,7 +673,18 @@ class Poche | |||
634 | $urlsInserted[] = $url; //add | 673 | $urlsInserted[] = $url; //add |
635 | if (isset($record['tags']) && trim($record['tags'])) { | 674 | if (isset($record['tags']) && trim($record['tags'])) { |
636 | 675 | ||
637 | // @TODO: set tags | 676 | $tags = explode(',', $record['tags']); |
677 | foreach($tags as $tag) { | ||
678 | $entry_id = $id; | ||
679 | $tag_id = $this->store->retrieveTagByValue($tag); | ||
680 | if ($tag_id) { | ||
681 | $this->store->setTagToEntry($tag_id['id'], $entry_id); | ||
682 | } else { | ||
683 | $this->store->createTag($tag); | ||
684 | $tag_id = $this->store->retrieveTagByValue($tag); | ||
685 | $this->store->setTagToEntry($tag_id['id'], $entry_id); | ||
686 | } | ||
687 | } | ||
638 | 688 | ||
639 | } | 689 | } |
640 | } | 690 | } |
@@ -757,10 +807,11 @@ class Poche | |||
757 | * | 807 | * |
758 | * @param $token | 808 | * @param $token |
759 | * @param $user_id | 809 | * @param $user_id |
760 | * @param $tag_id | 810 | * @param $tag_id if $type is 'tag', the id of the tag to generate feed for |
761 | * @param string $type | 811 | * @param string $type the type of feed to generate |
812 | * @param int $limit the maximum number of items (0 means all) | ||
762 | */ | 813 | */ |
763 | public function generateFeeds($token, $user_id, $tag_id, $type = 'home') | 814 | public function generateFeeds($token, $user_id, $tag_id, $type = 'home', $limit = 0) |
764 | { | 815 | { |
765 | $allowed_types = array('home', 'fav', 'archive', 'tag'); | 816 | $allowed_types = array('home', 'fav', 'archive', 'tag'); |
766 | $config = $this->store->getConfigUser($user_id); | 817 | $config = $this->store->getConfigUser($user_id); |
@@ -787,8 +838,13 @@ class Poche | |||
787 | $entries = $this->store->getEntriesByView($type, $user_id); | 838 | $entries = $this->store->getEntriesByView($type, $user_id); |
788 | } | 839 | } |
789 | 840 | ||
841 | // if $limit is set to zero, use all entries | ||
842 | if (0 == $limit) { | ||
843 | $limit = count($entries); | ||
844 | } | ||
790 | if (count($entries) > 0) { | 845 | if (count($entries) > 0) { |
791 | foreach ($entries as $entry) { | 846 | for ($i = 0; $i < min(count($entries), $limit); $i++) { |
847 | $entry = $entries[$i]; | ||
792 | $newItem = $feed->createNewItem(); | 848 | $newItem = $feed->createNewItem(); |
793 | $newItem->setTitle($entry['title']); | 849 | $newItem->setTitle($entry['title']); |
794 | $newItem->setSource(Tools::getPocheUrl() . '?view=view&id=' . $entry['id']); | 850 | $newItem->setSource(Tools::getPocheUrl() . '?view=view&id=' . $entry['id']); |
diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php index 5acd08ba..a8d00b89 100755 --- a/inc/poche/Routing.class.php +++ b/inc/poche/Routing.class.php | |||
@@ -102,7 +102,8 @@ class Routing | |||
102 | $this->wallabag->login($this->referer); | 102 | $this->wallabag->login($this->referer); |
103 | } elseif (isset($_GET['feed']) && isset($_GET['user_id'])) { | 103 | } elseif (isset($_GET['feed']) && isset($_GET['user_id'])) { |
104 | $tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0); | 104 | $tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0); |
105 | $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type']); | 105 | $limit = (isset($_GET['limit']) ? intval($_GET['limit']) : 0); |
106 | $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type'], $limit); | ||
106 | } | 107 | } |
107 | 108 | ||
108 | //allowed ONLY to logged in user | 109 | //allowed ONLY to logged in user |
@@ -115,7 +116,7 @@ class Routing | |||
115 | // update password | 116 | // update password |
116 | $this->wallabag->updatePassword($_POST['password'], $_POST['password_repeat']); | 117 | $this->wallabag->updatePassword($_POST['password'], $_POST['password_repeat']); |
117 | } elseif (isset($_GET['newuser'])) { | 118 | } elseif (isset($_GET['newuser'])) { |
118 | $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser']); | 119 | $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser'], $_POST['newuseremail']); |
119 | } elseif (isset($_GET['deluser'])) { | 120 | } elseif (isset($_GET['deluser'])) { |
120 | $this->wallabag->deleteUser($_POST['password4deletinguser']); | 121 | $this->wallabag->deleteUser($_POST['password4deletinguser']); |
121 | } elseif (isset($_GET['epub'])) { | 122 | } elseif (isset($_GET['epub'])) { |
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php index f803e3b5..7ccfc069 100755 --- a/inc/poche/Tools.class.php +++ b/inc/poche/Tools.class.php | |||
@@ -342,7 +342,10 @@ final class Tools | |||
342 | return $json; | 342 | return $json; |
343 | }; | 343 | }; |
344 | 344 | ||
345 | $json = $scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url)); | 345 | // Silence $scope function to avoid |
346 | // issues with FTRSS when error_reporting is to high | ||
347 | // FTRSS generates PHP warnings which break output | ||
348 | $json = @$scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url)); | ||
346 | 349 | ||
347 | // Clearing and restoring context | 350 | // Clearing and restoring context |
348 | foreach ($GLOBALS as $key => $value) { | 351 | foreach ($GLOBALS as $key => $value) { |
diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php index bc40990b..55831571 100644 --- a/inc/poche/WallabagEBooks.class.php +++ b/inc/poche/WallabagEBooks.class.php | |||
@@ -33,7 +33,7 @@ class WallabagEBooks | |||
33 | $entry = $this->wallabag->store->retrieveOneById($entryID, $this->wallabag->user->getId()); | 33 | $entry = $this->wallabag->store->retrieveOneById($entryID, $this->wallabag->user->getId()); |
34 | $this->entries = array($entry); | 34 | $this->entries = array($entry); |
35 | $this->bookTitle = $entry['title']; | 35 | $this->bookTitle = $entry['title']; |
36 | $this->bookFileName = substr($this->bookTitle, 0, 200); | 36 | $this->bookFileName = str_replace('/', '_', substr($this->bookTitle, 0, 200)); |
37 | $this->author = preg_replace('#^w{3}.#', '', Tools::getdomain($entry["url"])); # if only one article, set author to domain name (we strip the eventual www part) | 37 | $this->author = preg_replace('#^w{3}.#', '', Tools::getdomain($entry["url"])); # if only one article, set author to domain name (we strip the eventual www part) |
38 | Tools::logm('Producing ebook from article ' . $this->bookTitle); | 38 | Tools::logm('Producing ebook from article ' . $this->bookTitle); |
39 | break; | 39 | break; |
@@ -81,6 +81,9 @@ class WallabagEpub extends WallabagEBooks | |||
81 | public function produceEpub() | 81 | public function produceEpub() |
82 | { | 82 | { |
83 | Tools::logm('Starting to produce ePub 3 file'); | 83 | Tools::logm('Starting to produce ePub 3 file'); |
84 | |||
85 | try { | ||
86 | |||
84 | $content_start = | 87 | $content_start = |
85 | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | 88 | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
86 | . "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n" | 89 | . "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n" |
@@ -155,6 +158,11 @@ class WallabagEpub extends WallabagEBooks | |||
155 | $book->finalize(); | 158 | $book->finalize(); |
156 | $zipData = $book->sendBook($this->bookFileName); | 159 | $zipData = $book->sendBook($this->bookFileName); |
157 | Tools::logm('Ebook produced'); | 160 | Tools::logm('Ebook produced'); |
161 | } | ||
162 | catch (Exception $e) { | ||
163 | Tools::logm('PHPePub has encountered an error : '.$e->getMessage()); | ||
164 | $this->wallabag->messages->add('e', $e->getMessage()); | ||
165 | } | ||
158 | } | 166 | } |
159 | } | 167 | } |
160 | 168 | ||
@@ -167,7 +175,7 @@ class WallabagMobi extends WallabagEBooks | |||
167 | 175 | ||
168 | public function produceMobi() | 176 | public function produceMobi() |
169 | { | 177 | { |
170 | 178 | try { | |
171 | Tools::logm('Starting to produce Mobi file'); | 179 | Tools::logm('Starting to produce Mobi file'); |
172 | $mobi = new MOBI(); | 180 | $mobi = new MOBI(); |
173 | $content = new MOBIFile(); | 181 | $content = new MOBIFile(); |
@@ -194,9 +202,17 @@ class WallabagMobi extends WallabagEBooks | |||
194 | } | 202 | } |
195 | $mobi->setContentProvider($content); | 203 | $mobi->setContentProvider($content); |
196 | 204 | ||
205 | // the browser inside Kindle Devices doesn't likes special caracters either, we limit to A-z/0-9 | ||
206 | $this->bookFileName = preg_replace('/[^A-Za-z0-9\-]/', '', $this->bookFileName); | ||
207 | |||
197 | // we offer file to download | 208 | // we offer file to download |
198 | $mobi->download($this->bookFileName.'.mobi'); | 209 | $mobi->download($this->bookFileName.'.mobi'); |
199 | Tools::logm('Mobi file produced'); | 210 | Tools::logm('Mobi file produced'); |
211 | } | ||
212 | catch (Exception $e) { | ||
213 | Tools::logm('PHPMobi has encountered an error : '.$e->getMessage()); | ||
214 | $this->wallabag->messages->add('e', $e->getMessage()); | ||
215 | } | ||
200 | } | 216 | } |
201 | } | 217 | } |
202 | 218 | ||
@@ -206,15 +222,16 @@ class WallabagPDF extends WallabagEbooks | |||
206 | { | 222 | { |
207 | 223 | ||
208 | Tools::logm('Starting to produce PDF file'); | 224 | Tools::logm('Starting to produce PDF file'); |
209 | 225 | @define ('K_TCPDF_THROW_EXCEPTION_ERROR', TRUE); | |
226 | try { | ||
210 | $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); | 227 | $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); |
211 | 228 | ||
212 | Tools::logm('Filling metadata for PDF...'); | 229 | Tools::logm('Filling metadata for PDF...'); |
213 | $pdf->SetCreator(PDF_CREATOR); | 230 | $pdf->SetCreator(PDF_CREATOR); |
214 | $pdf->SetAuthor(''); | 231 | $pdf->SetAuthor('wallabag'); |
215 | $pdf->SetTitle($this->bookTitle); | 232 | $pdf->SetTitle($this->bookTitle); |
216 | $pdf->SetSubject('TCPDF Tutorial'); | 233 | $pdf->SetSubject('Articles via wallabag'); |
217 | $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); | 234 | $pdf->SetKeywords('wallabag'); |
218 | 235 | ||
219 | Tools::logm('Adding introduction...'); | 236 | Tools::logm('Adding introduction...'); |
220 | $pdf->AddPage(); | 237 | $pdf->AddPage(); |
@@ -229,18 +246,26 @@ class WallabagPDF extends WallabagEbooks | |||
229 | $i = 1; | 246 | $i = 1; |
230 | Tools::logm('Adding actual content...'); | 247 | Tools::logm('Adding actual content...'); |
231 | foreach ($this->entries as $item) { | 248 | foreach ($this->entries as $item) { |
249 | $tags = $this->wallabag->store->retrieveTagsByEntry($entry['id']); | ||
250 | foreach ($tags as $tag) { | ||
251 | $pdf->SetKeywords($tag['value']); | ||
252 | } | ||
232 | $pdf->AddPage(); | 253 | $pdf->AddPage(); |
233 | $html = '<h1>' . $item['title'] . '</h1>'; | 254 | $html = '<h1>' . $item['title'] . '</h1>'; |
234 | $html .= $item['content']; | 255 | $html .= $item['content']; |
235 | $pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true); | 256 | $pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true); |
236 | $i = $i+1; | ||
237 | } | 257 | } |
238 | 258 | ||
239 | // set image scale factor | 259 | // set image scale factor |
240 | $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); | 260 | $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); |
241 | 261 | ||
242 | 262 | ||
243 | $pdf->Output($this->bookFileName . '.pdf', 'FD'); | 263 | $pdf->Output($this->bookFileName . '.pdf', 'FD'); |
264 | } | ||
265 | catch (Exception $e) { | ||
266 | Tools::logm('TCPDF has encountered an error : '.$e->getMessage()); | ||
267 | $this->wallabag->messages->add('e', $e->getMessage()); | ||
268 | } | ||
244 | 269 | ||
245 | } | 270 | } |
246 | } | 271 | } |
diff --git a/install/index.php b/install/index.php index 06d1a419..892af241 100755 --- a/install/index.php +++ b/install/index.php | |||
@@ -11,18 +11,7 @@ | |||
11 | $errors = array(); | 11 | $errors = array(); |
12 | $successes = array(); | 12 | $successes = array(); |
13 | 13 | ||
14 | /* Function taken from at http://php.net/manual/en/function.rmdir.php#110489 | 14 | require_once('wallabag_compatibility_test.php'); |
15 | * Idea : nbari at dalmp dot com | ||
16 | * Rights unknown | ||
17 | * Here in case of .gitignore files | ||
18 | */ | ||
19 | function delTree($dir) { | ||
20 | $files = array_diff(scandir($dir), array('.','..')); | ||
21 | foreach ($files as $file) { | ||
22 | (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); | ||
23 | } | ||
24 | return rmdir($dir); | ||
25 | } | ||
26 | 15 | ||
27 | if (isset($_GET['clean'])) { | 16 | if (isset($_GET['clean'])) { |
28 | if (is_dir('install')){ | 17 | if (is_dir('install')){ |
@@ -58,136 +47,109 @@ if (isset($_POST['download'])) { | |||
58 | else if (isset($_POST['install'])) { | 47 | else if (isset($_POST['install'])) { |
59 | if (!is_dir('vendor')) { | 48 | if (!is_dir('vendor')) { |
60 | $errors[] = 'You must install twig before.'; | 49 | $errors[] = 'You must install twig before.'; |
61 | } | 50 | } else { |
62 | else { | ||
63 | $continue = true; | 51 | $continue = true; |
64 | // Create config.inc.php | 52 | $salt = generate_salt(); |
65 | if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) { | 53 | $content = file_get_contents('inc/poche/config.inc.default.php'); |
66 | $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.'; | ||
67 | $continue = false; | ||
68 | } | ||
69 | else { | ||
70 | function generate_salt() { | ||
71 | mt_srand(microtime(true)*100000 + memory_get_usage(true)); | ||
72 | return md5(uniqid(mt_rand(), true)); | ||
73 | } | ||
74 | 54 | ||
75 | $content = file_get_contents('inc/poche/config.inc.php'); | 55 | // User informations |
76 | $salt = generate_salt(); | 56 | $username = trim($_POST['username']); |
77 | $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content); | 57 | $password = trim($_POST['password']); |
78 | file_put_contents('inc/poche/config.inc.php', $content); | 58 | $salted_password = sha1($password . $username . $salt); |
79 | } | ||
80 | 59 | ||
81 | if ($continue) { | 60 | // Database informations |
82 | 61 | $moreQueries = array(); | |
83 | // User informations | 62 | |
84 | $username = trim($_POST['username']); | 63 | if ($_POST['db_engine'] == 'sqlite') { |
85 | $password = trim($_POST['password']); | 64 | if (!copy('install/poche.sqlite', 'db/poche.sqlite')) { |
86 | $salted_password = sha1($password . $username . $salt); | 65 | $errors[] = 'Impossible to create the SQLite database file.'; |
87 | |||
88 | // Database informations | ||
89 | $moreQueries = array(); | ||
90 | if ($_POST['db_engine'] == 'sqlite') { | ||
91 | if (!copy('install/poche.sqlite', 'db/poche.sqlite')) { | ||
92 | $errors[] = 'Impossible to create inc/poche/config.inc.php file.'; | ||
93 | $continue = false; | ||
94 | } | ||
95 | else { | ||
96 | $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite'; | ||
97 | $handle = new PDO($db_path); | ||
98 | $sql_structure = ""; | ||
99 | } | ||
100 | } | 66 | } |
101 | else { | 67 | else { |
102 | $content = file_get_contents('inc/poche/config.inc.php'); | 68 | $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite'; |
103 | 69 | $handle = new PDO($db_path); | |
104 | if ($_POST['db_engine'] == 'mysql') { | 70 | $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
105 | $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4'; | 71 | $sql_structure = ""; |
106 | $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content); | 72 | } |
107 | $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content); | 73 | } else { |
108 | $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content); | 74 | // MySQL and Postgre |
109 | $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content); | 75 | try { |
110 | $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array( | 76 | |
111 | PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', | 77 | if ($_POST['db_engine'] == 'mysql') { |
112 | )); | 78 | $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4'; |
113 | 79 | $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content); | |
114 | $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES | 80 | $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content); |
81 | $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content); | ||
82 | $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content); | ||
83 | $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array( | ||
84 | PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', | ||
85 | )); | ||
86 | |||
87 | $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES | ||
115 | (1, 'Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', 0, 0, 0x0a3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a, 1), | 88 | (1, 'Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', 0, 0, 0x0a3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a, 1), |
116 | (2, 'wallabag/wallabag', 'https://github.com/wallabag/wallabag', 0, 0, 0x3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a, 1), | 89 | (2, 'wallabag/wallabag', 'https://github.com/wallabag/wallabag', 0, 0, 0x3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a, 1), |
117 | (3, 'a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', 0, 1, 0x0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a, 1);"; | 90 | (3, 'a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', 0, 1, 0x0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a, 1);"; |
118 | $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');"; | 91 | $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');"; |
119 | $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);"; | 92 | $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);"; |
120 | 93 | ||
121 | $sql_structure = file_get_contents('install/mysql.sql'); | 94 | $sql_structure = file_get_contents('install/mysql.sql'); |
122 | } | 95 | } |
123 | else if ($_POST['db_engine'] == 'postgres') { | 96 | else if ($_POST['db_engine'] == 'postgres') { |
124 | $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database']; | 97 | $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database']; |
125 | $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content); | 98 | $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content); |
126 | $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content); | 99 | $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content); |
127 | $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content); | 100 | $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content); |
128 | $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content); | 101 | $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content); |
129 | $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']); | 102 | $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']); |
130 | 103 | ||
131 | $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES | 104 | $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES |
132 | ('Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', false, false, convert_from(decode('3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a', 'hex'), 'UTF8'), 1), | 105 | ('Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', false, false, convert_from(decode('3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a', 'hex'), 'UTF8'), 1), |
133 | ('wallabag/wallabag', 'https://github.com/wallabag/wallabag', false, false, convert_from(decode('3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a', 'hex'), 'UTF8'), 1), | 106 | ('wallabag/wallabag', 'https://github.com/wallabag/wallabag', false, false, convert_from(decode('3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a', 'hex'), 'UTF8'), 1), |
134 | ('a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', false, true, convert_from(decode('3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a', 'hex'), 'UTF8'), 1)"; | 107 | ('a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', false, true, convert_from(decode('3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a', 'hex'), 'UTF8'), 1)"; |
135 | $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')"; | 108 | $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')"; |
136 | $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)"; | 109 | $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)"; |
137 | |||
138 | $sql_structure = file_get_contents('install/postgres.sql'); | ||
139 | } | ||
140 | 110 | ||
141 | $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content); | 111 | $sql_structure = file_get_contents('install/postgres.sql'); |
142 | file_put_contents('inc/poche/config.inc.php', $content); | ||
143 | } | 112 | } |
113 | // create database structure | ||
114 | $query = $handle->exec($sql_structure); | ||
115 | } catch (PDOException $e) { | ||
116 | $errors[] = $e->getMessage(); | ||
117 | $continue = false; | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | if ($continue) { | ||
122 | $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')"; | ||
123 | $params = array($username, $salted_password, $username); | ||
124 | $query = executeQuery($handle, $sql, $params); | ||
144 | 125 | ||
145 | if ($continue) { | 126 | $id_user = (int)$handle->lastInsertId('users_id_seq'); |
146 | |||
147 | function executeQuery($handle, $sql, $params) { | ||
148 | try | ||
149 | { | ||
150 | $query = $handle->prepare($sql); | ||
151 | $query->execute($params); | ||
152 | return $query->fetchAll(); | ||
153 | } | ||
154 | catch (Exception $e) | ||
155 | { | ||
156 | return FALSE; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | if ($_POST['db_engine'] != "sqlite") { | ||
161 | // create database structure | ||
162 | $query = $handle->exec($sql_structure); | ||
163 | } | ||
164 | |||
165 | // Create user | ||
166 | $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
167 | |||
168 | $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')"; | ||
169 | $params = array($username, $salted_password, $username); | ||
170 | $query = executeQuery($handle, $sql, $params); | ||
171 | |||
172 | $id_user = (int)$handle->lastInsertId('users_id_seq'); | ||
173 | 127 | ||
174 | $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; | 128 | $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; |
175 | $params = array($id_user, 'pager', '10'); | 129 | $params = array($id_user, 'pager', '10'); |
176 | $query = executeQuery($handle, $sql, $params); | 130 | $query = executeQuery($handle, $sql, $params); |
177 | 131 | ||
178 | $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; | 132 | $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; |
179 | $params = array($id_user, 'language', 'en_EN.UTF8'); | 133 | $params = array($id_user, 'language', 'en_EN.UTF8'); |
180 | $query = executeQuery($handle, $sql, $params); | 134 | $query = executeQuery($handle, $sql, $params); |
181 | 135 | ||
182 | foreach ($moreQueries as $query) { | 136 | foreach ($moreQueries as $query) { |
183 | executeQuery($handle, $query, array()); | 137 | executeQuery($handle, $query, array()); |
184 | } | 138 | } |
139 | $successes[] = 'wallabag is now installed. You can now <a href="index.php?clean=0">access it !</a>'; | ||
185 | 140 | ||
186 | $successes[] = 'wallabag is now installed. You can now <a href="index.php?clean=0">access it !</a>'; | 141 | if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) { |
187 | } | 142 | $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.'; |
143 | } else { | ||
144 | if ($_POST['db_engine'] != 'sqlite') { | ||
145 | $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content); | ||
146 | file_put_contents('inc/poche/config.inc.php', $content); | ||
188 | } | 147 | } |
148 | $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content); | ||
149 | file_put_contents('inc/poche/config.inc.php', $content); | ||
189 | } | 150 | } |
190 | } | 151 | } |
152 | } | ||
191 | ?> | 153 | ?> |
192 | <!DOCTYPE html> | 154 | <!DOCTYPE html> |
193 | <html> | 155 | <html> |
@@ -208,8 +170,162 @@ else if (isset($_POST['install'])) { | |||
208 | <link rel="stylesheet" href="themes/baggy/css/main.css" media="all"> | 170 | <link rel="stylesheet" href="themes/baggy/css/main.css" media="all"> |
209 | <link rel="stylesheet" href="themes/baggy/css/messages.css" media="all"> | 171 | <link rel="stylesheet" href="themes/baggy/css/messages.css" media="all"> |
210 | <link rel="stylesheet" href="themes/baggy/css/print.css" media="print"> | 172 | <link rel="stylesheet" href="themes/baggy/css/print.css" media="print"> |
211 | <script src="themes/default/js/jquery-2.0.3.min.js"></script> | 173 | <script src="themes/_global/js/jquery-2.0.3.min.js"></script> |
212 | <script src="themes/baggy/js/init.js"></script> | 174 | <script src="themes/baggy/js/init.js"></script> |
175 | |||
176 | |||
177 | <style type="text/css"> | ||
178 | a { | ||
179 | color:#000; | ||
180 | text-decoration:underline; | ||
181 | padding:0 1px; | ||
182 | } | ||
183 | a:hover { | ||
184 | color:#fff; | ||
185 | background-color:#333; | ||
186 | text-decoration:none; | ||
187 | padding:0 1px; | ||
188 | } | ||
189 | p { | ||
190 | margin:0; | ||
191 | padding:5px 0; | ||
192 | } | ||
193 | em { | ||
194 | font-style:normal; | ||
195 | background-color:#ffc; | ||
196 | padding: 0.1em 0; | ||
197 | } | ||
198 | ul, ol { | ||
199 | margin:10px 0 10px 20px; | ||
200 | padding:0 0 0 15px; | ||
201 | } | ||
202 | ul li, ol li { | ||
203 | margin:0 0 7px 0; | ||
204 | padding:0 0 0 3px; | ||
205 | } | ||
206 | h2 { | ||
207 | font-size:18px; | ||
208 | padding:0; | ||
209 | } | ||
210 | h3 { | ||
211 | font-size:16px; | ||
212 | padding:0; | ||
213 | margin:20px 0 5px 0; | ||
214 | } | ||
215 | h4 { | ||
216 | font-size:14px; | ||
217 | padding:0; | ||
218 | margin:15px 0 5px 0; | ||
219 | } | ||
220 | code { | ||
221 | font-size:1.1em; | ||
222 | background-color:#f3f3ff; | ||
223 | color:#000; | ||
224 | } | ||
225 | em strong { | ||
226 | text-transform: uppercase; | ||
227 | } | ||
228 | table#chart { | ||
229 | border-collapse:collapse; | ||
230 | } | ||
231 | table#chart th { | ||
232 | background-color:#eee; | ||
233 | padding:2px 3px; | ||
234 | border:1px solid #fff; | ||
235 | } | ||
236 | table#chart td { | ||
237 | text-align:center; | ||
238 | padding:2px 3px; | ||
239 | border:1px solid #eee; | ||
240 | } | ||
241 | table#chart tr.enabled td { | ||
242 | /* Leave this alone */ | ||
243 | } | ||
244 | table#chart tr.disabled td, | ||
245 | table#chart tr.disabled td a { | ||
246 | } | ||
247 | table#chart tr.disabled td a { | ||
248 | text-decoration:underline; | ||
249 | } | ||
250 | div.chunk { | ||
251 | margin:20px 0 0 0; | ||
252 | padding:0 0 10px 0; | ||
253 | border-bottom:1px solid #ccc; | ||
254 | } | ||
255 | .footnote, | ||
256 | .footnote a { | ||
257 | font:10px/12px verdana, sans-serif; | ||
258 | color:#aaa; | ||
259 | } | ||
260 | .footnote em { | ||
261 | background-color:transparent; | ||
262 | font-style:italic; | ||
263 | } | ||
264 | .good{ | ||
265 | background-color:#52CC5B; | ||
266 | } | ||
267 | .bad{ | ||
268 | background-color:#F74343; | ||
269 | font-style:italic; | ||
270 | font-weight: bold; | ||
271 | } | ||
272 | .pass{ | ||
273 | background-color:#FF9500; | ||
274 | } | ||
275 | .detail { | ||
276 | cursor: pointer; | ||
277 | } | ||
278 | .descriptions { | ||
279 | margin-left: 10%; | ||
280 | position: relative; | ||
281 | top: 50%; | ||
282 | } | ||
283 | .database_inputs { | ||
284 | float: left; | ||
285 | width: 50% | ||
286 | } | ||
287 | .database_info { | ||
288 | width: 100%; | ||
289 | overflow: auto; | ||
290 | } | ||
291 | .compatibity_result { | ||
292 | margin: auto; | ||
293 | max-width: 300px; | ||
294 | min-height: 50px; | ||
295 | line-height: 50px; | ||
296 | text-align: center; | ||
297 | margin-bottom: 30px; | ||
298 | border-radius: 3px; | ||
299 | } | ||
300 | |||
301 | h2, legend { | ||
302 | font-size: 30px; | ||
303 | text-transform: uppercase; | ||
304 | font-family: "PT Sans",sans-serif; | ||
305 | } | ||
306 | |||
307 | legend:after { | ||
308 | content: ""; | ||
309 | height: 4px; | ||
310 | width: 70px; | ||
311 | background-color: #000; | ||
312 | display: block; | ||
313 | } | ||
314 | #reloadpage { | ||
315 | cursor: pointer; | ||
316 | background-color: #000; | ||
317 | color: #FFF; | ||
318 | padding: 0.5em 1em; | ||
319 | display: inline-block; | ||
320 | border: 1px solid #000; | ||
321 | } | ||
322 | #reloadpage:hover { | ||
323 | background-color: #FFF; | ||
324 | color: #000; | ||
325 | } | ||
326 | |||
327 | </style> | ||
328 | |||
213 | </head> | 329 | </head> |
214 | <body> | 330 | <body> |
215 | <header class="w600p center mbm"> | 331 | <header class="w600p center mbm"> |
@@ -259,24 +375,192 @@ else if (isset($_POST['install'])) { | |||
259 | <?php endif; ?> | 375 | <?php endif; ?> |
260 | <p>To install wallabag, you just have to fill the following fields. That's all.</p> | 376 | <p>To install wallabag, you just have to fill the following fields. That's all.</p> |
261 | <p>If you need help, you can read the doc: <a href="docs/" target="_blank">offline documentation</a> and <a href="http://doc.wallabag.org" target="_blank">online one</a> (already up-to-date).</p> | 377 | <p>If you need help, you can read the doc: <a href="docs/" target="_blank">offline documentation</a> and <a href="http://doc.wallabag.org" target="_blank">online one</a> (already up-to-date).</p> |
262 | <p>Don't forget to check your server compatibility <a href="install/wallabag_compatibility_test.php?from=install">here</a>.</p> | 378 | |
263 | <form method="post"> | 379 | <div> |
264 | <fieldset> | 380 | <h2>Server compatibility test</h2> |
265 | <legend><strong>Technical settings</strong></legend> | 381 | <?php if (isOkay()) { ?> |
266 | <?php if (!is_dir('vendor')) : ?> | 382 | <div class="compatibity_result detail good">All good</div> |
267 | <div class='messages notice install'>wallabag needs twig, a template engine (<a href="http://twig.sensiolabs.org/">?</a>). Two ways to install it:<br /> | 383 | <?php } elseif (isPassing()) { ?> |
268 | <ul> | 384 | <div class="compatibity_result detail pass">Some problems, but it's OK !</div> |
269 | <li>automatically download and extract vendor.zip into your wallabag folder. | 385 | <?php } else { ?> |
270 | <p><input type="submit" name="download" value="Download vendor.zip" /></p> | 386 | <div class="compatibity_result detail bad">Bad news : you can't run wallabag</div> |
271 | <?php if (!extension_loaded('zip')) : ?> | 387 | <?php } $status = status(); ?> |
272 | <b>Be careful, zip extension is not enabled in your PHP configuration. You'll have to unzip vendor.zip manually.</b> | 388 | </div> |
273 | <?php endif; ?> | 389 | |
274 | <em>This method is mainly recommended if you don't have a dedicated server.</em></li> | 390 | <div class="details"> |
275 | <li>use <a href="http://getcomposer.org/">Composer</a> :<pre><code>curl -s http://getcomposer.org/installer | php | 391 | <div> |
276 | php composer.phar install</code></pre></li> | 392 | <hr> |
277 | </ul> | 393 | <h2 style="text-align:center;"><?php echo $status['app_name']; ?>: Compatibility Test</h2> |
278 | </div> | 394 | <table cellpadding="0" cellspacing="0" border="0" width="100%" id="chart"> |
279 | <?php endif; ?> | 395 | <thead> |
396 | <tr> | ||
397 | <th>Test</th> | ||
398 | <th>Should Be</th> | ||
399 | <th>What You Have</th> | ||
400 | <th>What it means</th> | ||
401 | </tr> | ||
402 | </thead> | ||
403 | <tbody> | ||
404 | <tr class="<?php echo ($status['php']) ? 'enabled' : 'disabled'; ?>"> | ||
405 | <td>PHP</td> | ||
406 | <td>5.3.3 or higher</td> | ||
407 | <td class="<?php echo ($status['php']) ? 'good' : 'disabled'; ?>"><?php echo phpversion(); ?></td> | ||
408 | <td><?php echo ($status['php']) ? '<strong>PHP:</strong> You are running a supported version of PHP.' : '<strong>PHP:</strong> You are running an unsupported version of PHP. <strong>' . $status['app_name'] . ' will not work here.</strong>' ;?></td> | ||
409 | </tr> | ||
410 | <tr class="<?php echo ($status['pdo']) ? 'enabled' : 'disabled'; ?>"> | ||
411 | <td><a href="http://php.net/manual/en/book.pdo.php">PDO</a></td> | ||
412 | <td>Enabled</td> | ||
413 | <?php echo ($status['pdo']) ? '<td class="good">Enabled</span>' : '<td class="bad">Disabled'; ?></td> | ||
414 | <td><?php echo ($status['pdo']) ? '<strong>PDO:</strong> You have PDO support enabled.' : '<strong>PDO:</strong> Your PHP installation doesn\'t support PHP PDO. <strong>' . $status['app_name'] . ' will not work here.</strong>' ?></td> | ||
415 | </tr> | ||
416 | <tr class="<?php echo ($status['pdo_drivers_passing']) ? 'enabled' : 'disabled'; ?>"> | ||
417 | <td>PDO Drivers</td> | ||
418 | <td>One of the PDO drivers must be installed</td> | ||
419 | <?php echo ($status['pdo_drivers_passing']) ? '<td class="good">One driver is enabled</span>' : '<td class="bad">No driver available'; ?></td> | ||
420 | <td><?php echo ($status['pdo_drivers_passing']) ? '<strong>PDO:</strong> You have at least one PDO driver installed.' : '<strong>PDO Drivers:</strong> Your PHP installation doesn\'t have any PDO driver installed. <strong>' . $status['app_name'] . ' will not work here.</strong>' ?></td> | ||
421 | </tr> | ||
422 | <tr class="<?php echo ($status['xml']) ? 'enabled' : 'disabled'; ?>"> | ||
423 | <td><a href="http://php.net/xml">XML</a></td> | ||
424 | <td>Enabled</td> | ||
425 | <?php echo ($status['xml']) ? '<td class="good">Enabled, and sane</span>' : '<td class="bad">Disabled, or broken'; ?></td> | ||
426 | <td><?php echo ($status['xml']) ? '<strong>XML:</strong> You have XMLReader support or a version of XML support that isn\'t broken installed.' : '<strong>XML:</strong> Your PHP installation doesn\'t support XML parsing. <strong>' . $status['app_name'] . ' will not work here.</strong>' ?></td> | ||
427 | </tr> | ||
428 | <tr class="<?php echo ($status['pcre']) ? 'enabled' : 'disabled'; ?>"> | ||
429 | <td><a href="http://php.net/pcre">PCRE</a></td> | ||
430 | <td>Enabled</td> | ||
431 | <?php echo ($status['pcre']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
432 | <td><?php echo ($status['pcre']) ? '<strong>PCRE:</strong> You have PCRE support installed.' : '<strong>PCRE:</strong> Your PHP installation doesn\'t support Perl-Compatible Regular Expressions. <strong>' . $status['app_name'] .' will not work here.</strong>' ?></td> | ||
433 | </tr> | ||
434 | <tr class="<?php echo ($status['zlib']) ? 'enabled' : 'disabled'; ?>"> | ||
435 | <td><a href="http://php.net/zlib">Zlib</a></td> | ||
436 | <td>Enabled</td> | ||
437 | <?php echo ($status['zlib']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
438 | <td><?php echo ($status['zlib']) ? '<strong>Zlib:</strong> You have <code>Zlib</code> enabled. This allows SimplePie to support GZIP-encoded pages.' : '<strong>Zlib:</strong> The <code>Zlib</code> extension is not available. SimplePie will ignore any GZIP-encoding, and instead handle pages as uncompressed text.' ?></td> | ||
439 | </tr> | ||
440 | <tr class="<?php echo ($status['mbstring']) ? 'enabled' : 'disabled'; ?>"> | ||
441 | <td><a href="http://php.net/mbstring">mbstring</a></td> | ||
442 | <td>Enabled</td> | ||
443 | <?php echo ($status['mbstring']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
444 | <td rowspan="2"><?php if(($status['mbstring']) && ($status['iconv'])) { ?><strong>mbstring and iconv:</strong> You have both <code>mbstring</code> and <code>iconv</code> installed! This will allow <?php echo $status['app_name']; ?> to handle the greatest number of languages. | ||
445 | <?php } elseif ($status['mbstring']) { ?><strong>mbstring:</strong> <code>mbstring</code> is installed, but <code>iconv</code> is not. | ||
446 | <?php } elseif ($status['iconv']) { ?><strong>iconv:</strong> <code>iconv</code> is installed, but <code>mbstring</code> is not. | ||
447 | <?php } else { ?><strong>mbstring and iconv:</strong> <em>You do not have either of the extensions installed.</em> This will significantly impair your ability to read non-English pages, as well as even some English ones. | ||
448 | <?php } ?> | ||
449 | </td> | ||
450 | </tr> | ||
451 | <tr class="<?php echo ($status['iconv']) ? 'enabled' : 'disabled'; ?>"> | ||
452 | <td><a href="http://php.net/iconv">iconv</a></td> | ||
453 | <td>Enabled</td> | ||
454 | <?php echo ($status['iconv']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
455 | </tr> | ||
456 | <tr class="<?php echo ($status['dom']) ? 'enabled' : 'disabled'; ?>"> | ||
457 | <td><a href="http://php.net/manual/en/book.dom.php">DOM / XML extension</a></td> | ||
458 | <td>Enabled</td> | ||
459 | <?php echo ($status['dom']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
460 | <td><?php echo ($status['dom']) ? '<strong>DOM/XML:</strong> You can parse <em>ini</em> files.' : '<strong>DOM/XML:</strong> Your PHP configuration isn\'t standard, you\'re missing PHP-DOM. You may try to install a package or recompile PHP. <strong>' . $status['app_name'] . ' will not work here.</strong>'; ?></td> | ||
461 | </tr> | ||
462 | <tr class="<?php echo ($status['filter']) ? 'enabled' : 'disabled'; ?>"> | ||
463 | <td><a href="http://uk.php.net/manual/en/book.filter.php">Data filtering</a></td> | ||
464 | <td>Enabled</td> | ||
465 | <?php echo ($status['filter']) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
466 | <td><?php echo ($status['filter']) ? '<strong>Data filtering:</strong> You can use the PHP build-in DOM to operate on XML documents.' : '<strong>Data filtering:</strong> Your PHP configuration has the filter extension disabled. <strong>' . $status['app_name'] . ' will not work here.</strong>' ?></td> | ||
467 | </tr> | ||
468 | <tr class="<?php echo ($status['gd']) ? 'enabled' : 'disabled'; ?>"> | ||
469 | <td><a href="http://php.net/manual/en/book.image.php">GD</a></td> | ||
470 | <td>Enabled</td> | ||
471 | <?php echo ($status['gd']) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
472 | <td><?php echo($status['gd']) ? '<strong>GD:</strong> You have <code>GD</code> support installed.' : '<strong>GD:</strong> The <code>GD</code> extension is not available. ' . $status['app_name'] . ' will not be able to download pictures locally on your server.' ?></td> | ||
473 | </tr> | ||
474 | <tr class="<?php echo ($status['tidy']) ? 'enabled' : 'disabled'; ?>"> | ||
475 | <td><a href="http://php.net/tidy">Tidy</a></td> | ||
476 | <td>Enabled</td> | ||
477 | <?php echo ($status['tidy']) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
478 | <td><?php echo ($status['tidy']) ? '<strong>Tidy:</strong> You have <code>Tidy</code> support installed.' : '<strong>Tidy:</strong> The <code>Tidy</code> extension is not available.' . $status['app_name'] . ' should still work with most pages, but you may experience problems with some. You can install it with <code>sudo apt-get install php5-tidy</code> and then reload Apache <code>sudo service apache2 reload</code>.' ; ?></td> | ||
479 | </tr> | ||
480 | <tr class="<?php echo ($status['curl']) ? 'enabled' : 'disabled'; ?>"> | ||
481 | <td><a href="http://php.net/curl">cURL</a></td> | ||
482 | <td>Enabled</td> | ||
483 | <?php echo (extension_loaded('curl')) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
484 | <td><?php echo ($status['curl']) ? '<strong>cURL:</strong> You have <code>cURL</code> support installed.' : '<strong>cURL:</strong> The <code>cURL</code> extension is not available. SimplePie will use <code>fsockopen()</code> instead.' ?></td> | ||
485 | </tr> | ||
486 | <tr class="<?php echo ($status['parse_ini']) ? 'enabled' : 'disabled'; ?>"> | ||
487 | <td><a href="http://uk.php.net/manual/en/function.parse-ini-file.php">Parse ini file</td> | ||
488 | <td>Enabled</td> | ||
489 | <?php echo ($status['parse_ini']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
490 | <td><?php echo ($status['parse_ini']) ? '<strong>Parse ini:</strong> You can parse <em>ini</em> files.' : '<strong>Parse ini files function :</strong> Bad luck : your webhost has decided to block the use of the <em>parse_ini_file</em> function. <strong>' . $status['app_name'] . ' will not work here.' ?></td> | ||
491 | </tr> | ||
492 | <tr class="<?php echo ($status['parallel']) ? 'enabled' : 'disabled'; ?>"> | ||
493 | <td>Parallel URL fetching</td> | ||
494 | <td>Enabled</td> | ||
495 | <?php echo ($status['parallel']) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
496 | <td><?php echo ($status['parallel']) ? '<strong>Parallel URL fetching:</strong> You have <code>HttpRequestPool</code> or <code>curl_multi</code> support installed.' : '<strong>Parallel URL fetching:</strong> <code>HttpRequestPool</code> or <code>curl_multi</code> support is not available. ' . $status['app_name'] . ' will use <code>file_get_contents()</code> instead to fetch URLs sequentially rather than in parallel.' ?></td> | ||
497 | </tr> | ||
498 | <tr class="<?php echo ($status['allow_url_fopen']) ? 'enabled' : 'disabled'; ?>"> | ||
499 | <td><a href="http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a></td> | ||
500 | <td>Enabled</td> | ||
501 | <?php echo ($status['allow_url_fopen']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
502 | <td><?php echo ($status['allow_url_fopen']) ? '<strong>allow_url_fopen:</strong> You have allow_url_fopen enabled.' : '<strong>allow_url_fopen:</strong> Your PHP configuration has allow_url_fopen disabled. <strong>' . $status['app_name'] . ' will not work here.</strong>' ?></td> | ||
503 | </tr> | ||
504 | <tr class="<?php echo ($status['gettext']) ? 'enabled' : 'disabled'; ?>"> | ||
505 | <td><a href="http://php.net/manual/en/book.gettext.php">gettext</a></td> | ||
506 | <td>Enabled</td> | ||
507 | <?php echo ($status['gettext']) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
508 | <td><?php echo ($status['gettext']) ? '<strong>Gettext:</strong> You have <code>gettext</code> enabled.</em>' : '<strong>GetText:</strong> The <code>gettext</code> extension is not available. The system we use to display wallabag in various languages is not available. <strong>' . $status['app_name'] .' will not work here.</strong>' ?></td> | ||
509 | </tr> | ||
510 | </tbody> | ||
511 | </table> | ||
512 | <hr> | ||
513 | </div> | ||
514 | <div class="details"> | ||
515 | <?php //if ($status['php'] && $status['xml'] && $status['pcre'] && $status['mbstring'] && $status['iconv'] && $status['filter'] && $status['allow_url_fopen']) { ?> | ||
516 | <?php if (isOkay()) { ?> | ||
517 | <h3>Bottom Line: Yes, you can run <?php echo $status['app_name']; ?> !</h3> | ||
518 | <p><em>Your webhost has its act together!</em></p> | ||
519 | <p><strong>Note</strong>: Passing this test does not guarantee that <?php echo $status['app_name']; ?> will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.</p> | ||
520 | <?php //} else if ($status['php'] && $status['xml'] && $status['pcre'] && $status['mbstring'] && $status['allow_url_fopen'] && $status['filter']) { ?> | ||
521 | <?php } else if (!isOkay() && isPassing()) { ?> | ||
522 | <h3>Bottom Line: Yes, you can run <?php echo $status['app_name']; ?> !</h3> | ||
523 | <p><em>For most pages, it'll run with no problems.</em> There are certain languages that you might have a hard time with though.</p> | ||
524 | <p><strong>Note</strong>: Passing this test does not guarantee that <?php echo $status['app_name']; ?> will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.</p> | ||
525 | <?php } else { ?> | ||
526 | <h3>Bottom Line: We're sorry…</h3> | ||
527 | <p><em>Your webhost does not support the minimum requirements for <?php echo $status['app_name']; ?>.</em> It may be a good idea to contact your webhost and point them to the results of this test. They may be able to enable/install the required components.</p> | ||
528 | <p>If this is your own server and you think you have all the requirements installed, please get in touch with us.</p> | ||
529 | <?php } ?> | ||
530 | </div> | ||
531 | |||
532 | <div class="chunk"> | ||
533 | <p class="footnote">This compatibility test has been borrowed (and slightly adapted by <a href="http://fivefilters.org/content-only/">fivefilters.org</a>) from the one supplied by <a href="http://simplepie.org/">SimplePie.org</a>.</a></p> | ||
534 | </div> | ||
535 | </div> | ||
536 | <form method="post" class="technical"> | ||
537 | <hr> | ||
538 | <div class='twig'> | ||
539 | <h2>Twig installation</h2> | ||
540 | <?php if (!is_dir('vendor')) : ?> | ||
541 | |||
542 | <p>wallabag needs twig, a template engine (<a href="http://twig.sensiolabs.org/">?</a>). Two ways to install it:</p> | ||
543 | <ul> | ||
544 | <li>automatically download and extract vendor.zip into your wallabag folder. | ||
545 | <p><input type="submit" name="download" value="Download vendor.zip" /></p> | ||
546 | <?php if (!extension_loaded('zip')) : ?> | ||
547 | <b>Be careful, zip extension is not enabled in your PHP configuration. You'll have to unzip vendor.zip manually.</b> | ||
548 | <?php endif; ?> | ||
549 | <em>This method is mainly recommended if you don't have a dedicated server.</em></li> | ||
550 | <li>use <a href="http://getcomposer.org/">Composer</a> in your wallabag folder :<pre><code>curl -s http://getcomposer.org/installer | php | ||
551 | php composer.phar install</code></pre> | ||
552 | <span id="reloadpage">Reload to check</span> | ||
553 | </li> | ||
554 | </ul> | ||
555 | |||
556 | <?php else : ?> | ||
557 | Twig is properly installed. | ||
558 | <?php endif; ?> | ||
559 | </div> | ||
560 | <div class="database_info"> | ||
561 | <hr> | ||
562 | <fieldset class="database_inputs"> | ||
563 | <legend><strong>Database settings</strong></legend> | ||
280 | <p> | 564 | <p> |
281 | Database engine: | 565 | Database engine: |
282 | <ul> | 566 | <ul> |
@@ -287,6 +571,9 @@ php composer.phar install</code></pre></li> | |||
287 | </li> | 571 | </li> |
288 | <li> | 572 | <li> |
289 | <label for="mysql">MySQL</label> <input name="db_engine" type="radio" id="mysql" value="mysql" /> | 573 | <label for="mysql">MySQL</label> <input name="db_engine" type="radio" id="mysql" value="mysql" /> |
574 | <div id="pdo_mysql" class='messages notice install'> | ||
575 | <p>All fields have to be filled.</p> | ||
576 | </div> | ||
290 | <ul id="mysql_infos"> | 577 | <ul id="mysql_infos"> |
291 | <li><label for="mysql_server">Server</label> <input type="text" placeholder="localhost" id="mysql_server" name="mysql_server" /></li> | 578 | <li><label for="mysql_server">Server</label> <input type="text" placeholder="localhost" id="mysql_server" name="mysql_server" /></li> |
292 | <li><label for="mysql_database">Database</label> <input type="text" placeholder="wallabag" id="mysql_database" name="mysql_database" /></li> | 579 | <li><label for="mysql_database">Database</label> <input type="text" placeholder="wallabag" id="mysql_database" name="mysql_database" /></li> |
@@ -296,6 +583,9 @@ php composer.phar install</code></pre></li> | |||
296 | </li> | 583 | </li> |
297 | <li> | 584 | <li> |
298 | <label for="postgres">PostgreSQL</label> <input name="db_engine" type="radio" id="postgres" value="postgres" /> | 585 | <label for="postgres">PostgreSQL</label> <input name="db_engine" type="radio" id="postgres" value="postgres" /> |
586 | <div id="pdo_postgres" class='messages notice install'> | ||
587 | <p>All fields have to be filled.</p> | ||
588 | </div> | ||
299 | <ul id="pg_infos"> | 589 | <ul id="pg_infos"> |
300 | <li><label for="pg_server">Server</label> <input type="text" placeholder="localhost" id="pg_server" name="pg_server" /></li> | 590 | <li><label for="pg_server">Server</label> <input type="text" placeholder="localhost" id="pg_server" name="pg_server" /></li> |
301 | <li><label for="pg_database">Database</label> <input type="text" placeholder="wallabag" id="pg_database" name="pg_database" /></li> | 591 | <li><label for="pg_database">Database</label> <input type="text" placeholder="wallabag" id="pg_database" name="pg_database" /></li> |
@@ -306,8 +596,21 @@ php composer.phar install</code></pre></li> | |||
306 | </ul> | 596 | </ul> |
307 | </p> | 597 | </p> |
308 | </fieldset> | 598 | </fieldset> |
309 | 599 | <div class="descriptions"> | |
310 | <fieldset> | 600 | <div id="sqlite_description"> |
601 | SQLite is the most simple database system of all three. It is therefore recommended for people who don't want or know how to configure other database systems. | ||
602 | </div> | ||
603 | <div id="mysql_description"> | ||
604 | MySQL is one of the most popular database systems. It comes with most shared hosting plans. | ||
605 | </div> | ||
606 | <div id="postgres_description"> | ||
607 | PostgreSQL. Because some people prefer it to MySQL. | ||
608 | </div> | ||
609 | </div> | ||
610 | </div> | ||
611 | <hr> | ||
612 | <div class="usersettings"> | ||
613 | <fieldset style="clear: both"> | ||
311 | <legend><strong>User settings</strong></legend> | 614 | <legend><strong>User settings</strong></legend> |
312 | <p> | 615 | <p> |
313 | <label for="username">Username</label> | 616 | <label for="username">Username</label> |
@@ -323,13 +626,42 @@ php composer.phar install</code></pre></li> | |||
323 | <input type="email" id="email" name="email" /> | 626 | <input type="email" id="email" name="email" /> |
324 | </p> | 627 | </p> |
325 | </fieldset> | 628 | </fieldset> |
326 | |||
327 | <input type="submit" id="install_button" value="Install wallabag" name="install" /> | 629 | <input type="submit" id="install_button" value="Install wallabag" name="install" /> |
630 | </div> | ||
328 | </form> | 631 | </form> |
329 | </div> | 632 | </div> |
330 | <script> | 633 | <script> |
634 | <?php if (!is_dir('vendor')) : ?> | ||
635 | $(".database_info").hide(); | ||
636 | $(".usersettings").hide(); | ||
637 | <?php endif ?> | ||
638 | /* | ||
639 | * Database showing/hiding | ||
640 | */ | ||
331 | $("#mysql_infos").hide(); | 641 | $("#mysql_infos").hide(); |
642 | $("#mysql_description").hide(); | ||
332 | $("#pg_infos").hide(); | 643 | $("#pg_infos").hide(); |
644 | $("#postgres_description").hide(); | ||
645 | $("#sqlite_description").show(); | ||
646 | $("#pdo_postgres").hide(); | ||
647 | $("#pdo_mysql").hide(); | ||
648 | |||
649 | /* | ||
650 | * Details hiding | ||
651 | */ | ||
652 | |||
653 | $(".details").hide(); | ||
654 | |||
655 | <?php | ||
656 | if (!isPassing()) : ?> | ||
657 | $('.technical').hide(); | ||
658 | <?php | ||
659 | else : | ||
660 | ?> | ||
661 | $('.technical').show(); | ||
662 | <?php | ||
663 | endif; | ||
664 | ?> | ||
333 | 665 | ||
334 | <?php | 666 | <?php |
335 | if (!extension_loaded('pdo_sqlite')) : ?> | 667 | if (!extension_loaded('pdo_sqlite')) : ?> |
@@ -346,20 +678,35 @@ php composer.phar install</code></pre></li> | |||
346 | { | 678 | { |
347 | if ( $("#mysql").prop('checked')) { | 679 | if ( $("#mysql").prop('checked')) { |
348 | $("#mysql_infos").show(); | 680 | $("#mysql_infos").show(); |
681 | $("#pdo_mysql").show(); | ||
349 | $("#pg_infos").hide(); | 682 | $("#pg_infos").hide(); |
683 | $("#pdo_postgres").hide(); | ||
350 | $("#pdo_sqlite").hide(); | 684 | $("#pdo_sqlite").hide(); |
351 | $("#install_button").show(); | 685 | $("#sqlite_description").hide(); |
686 | $("#postgres_description").hide(); | ||
687 | $("#mysql_description").show(); | ||
688 | $("#install_button").show(); | ||
352 | } | 689 | } |
353 | else { | 690 | else { |
354 | if ( $("#postgres").prop('checked')) { | 691 | if ( $("#postgres").prop('checked')) { |
355 | $("#mysql_infos").hide(); | 692 | $("#mysql_infos").hide(); |
693 | $("#pdo_mysql").hide(); | ||
356 | $("#pg_infos").show(); | 694 | $("#pg_infos").show(); |
695 | $("#pdo_postgres").show(); | ||
357 | $("#pdo_sqlite").hide(); | 696 | $("#pdo_sqlite").hide(); |
697 | $("#sqlite_description").hide(); | ||
698 | $("#mysql_description").hide(); | ||
699 | $("#postgres_description").show(); | ||
358 | $("#install_button").show(); | 700 | $("#install_button").show(); |
359 | } | 701 | } |
360 | else { | 702 | else { |
361 | $("#mysql_infos").hide(); | 703 | $("#mysql_infos").hide(); |
362 | $("#pg_infos").hide(); | 704 | $("#pg_infos").hide(); |
705 | $("#pdo_postgres").hide(); | ||
706 | $("#pdo_mysql").hide(); | ||
707 | $("#sqlite_description").show(); | ||
708 | $("#mysql_description").hide(); | ||
709 | $("#postgres_description").hide(); | ||
363 | <?php | 710 | <?php |
364 | if (!extension_loaded('pdo_sqlite')) : ?> | 711 | if (!extension_loaded('pdo_sqlite')) : ?> |
365 | $("#pdo_sqlite").show(); | 712 | $("#pdo_sqlite").show(); |
@@ -370,6 +717,16 @@ php composer.phar install</code></pre></li> | |||
370 | } | 717 | } |
371 | } | 718 | } |
372 | }); | 719 | }); |
720 | |||
721 | $(".detail").click(function() | ||
722 | { | ||
723 | $('.details').toggle(); | ||
724 | }); | ||
725 | $("#reloadpage").click(function() | ||
726 | { | ||
727 | location.reload(); | ||
728 | }); | ||
729 | |||
373 | </script> | 730 | </script> |
374 | </body> | 731 | </body> |
375 | </html> | 732 | </html> |
diff --git a/install/wallabag_compatibility_test.php b/install/wallabag_compatibility_test.php index 61a8e99f..3b465851 100644 --- a/install/wallabag_compatibility_test.php +++ b/install/wallabag_compatibility_test.php | |||
@@ -8,9 +8,11 @@ | |||
8 | * @license http://opensource.org/licenses/MIT see COPYING file | 8 | * @license http://opensource.org/licenses/MIT see COPYING file |
9 | */ | 9 | */ |
10 | 10 | ||
11 | function status() { | ||
11 | $app_name = 'wallabag'; | 12 | $app_name = 'wallabag'; |
12 | 13 | ||
13 | $php_ok = (function_exists('version_compare') && version_compare(phpversion(), '5.3.3', '>=')); | 14 | $php_ok = (function_exists('version_compare') && version_compare(phpversion(), '5.3.3', '>=')); |
15 | $pdo_ok = class_exists('PDO'); | ||
14 | $pcre_ok = extension_loaded('pcre'); | 16 | $pcre_ok = extension_loaded('pcre'); |
15 | $zlib_ok = extension_loaded('zlib'); | 17 | $zlib_ok = extension_loaded('zlib'); |
16 | $mbstring_ok = extension_loaded('mbstring'); | 18 | $mbstring_ok = extension_loaded('mbstring'); |
@@ -24,7 +26,7 @@ $allow_url_fopen_ok = (bool)ini_get('allow_url_fopen'); | |||
24 | $filter_ok = extension_loaded('filter'); | 26 | $filter_ok = extension_loaded('filter'); |
25 | $gettext_ok = function_exists("gettext"); | 27 | $gettext_ok = function_exists("gettext"); |
26 | $gd_ok = extension_loaded('gd'); | 28 | $gd_ok = extension_loaded('gd'); |
27 | 29 | $pdo_drivers_passing = extension_loaded('pdo_sqlite') || extension_loaded('pdo_mysql') || extension_loaded('pdo_pgsql'); | |
28 | 30 | ||
29 | if (extension_loaded('xmlreader')) { | 31 | if (extension_loaded('xmlreader')) { |
30 | $xml_ok = true; | 32 | $xml_ok = true; |
@@ -37,391 +39,50 @@ if (extension_loaded('xmlreader')) { | |||
37 | $xml_ok = false; | 39 | $xml_ok = false; |
38 | } | 40 | } |
39 | 41 | ||
40 | header('Content-type: text/html; charset=UTF-8'); | 42 | $status = array('app_name' => $app_name, 'php' => $php_ok, 'pdo' => $pdo_ok, 'pdo_drivers_passing' => $pdo_drivers_passing, 'xml' => $xml_ok, 'pcre' => $pcre_ok, 'zlib' => $zlib_ok, 'mbstring' => $mbstring_ok, 'dom' => $dom_ok, 'iconv' => $iconv_ok, 'tidy' => $tidy_ok, 'curl' => $curl_ok, 'parse_ini' => $parse_ini_ok, 'parallel' => $parallel_ok, 'allow_url_fopen' => $allow_url_fopen_ok, 'filter' => $filter_ok, 'gettext' => $gettext_ok, 'gd' => $gd_ok); |
41 | |||
42 | ?><!DOCTYPE html> | ||
43 | |||
44 | <html lang="en"> | ||
45 | <head> | ||
46 | <title><?php echo $app_name; ?>: Server Compatibility Test</title> | ||
47 | |||
48 | <style type="text/css"> | ||
49 | body { | ||
50 | font:14px/1.4em "Lucida Grande", Verdana, Arial, Helvetica, Clean, Sans, sans-serif; | ||
51 | letter-spacing:0px; | ||
52 | color:#333; | ||
53 | margin:0; | ||
54 | padding:0; | ||
55 | background:#fff; | ||
56 | } | ||
57 | |||
58 | div#site { | ||
59 | width:550px; | ||
60 | margin:20px auto 0 auto; | ||
61 | } | ||
62 | |||
63 | a { | ||
64 | color:#000; | ||
65 | text-decoration:underline; | ||
66 | padding:0 1px; | ||
67 | } | ||
68 | |||
69 | a:hover { | ||
70 | color:#fff; | ||
71 | background-color:#333; | ||
72 | text-decoration:none; | ||
73 | padding:0 1px; | ||
74 | } | ||
75 | |||
76 | p { | ||
77 | margin:0; | ||
78 | padding:5px 0; | ||
79 | } | ||
80 | |||
81 | em { | ||
82 | font-style:normal; | ||
83 | background-color:#ffc; | ||
84 | padding: 0.1em 0; | ||
85 | } | ||
86 | |||
87 | ul, ol { | ||
88 | margin:10px 0 10px 20px; | ||
89 | padding:0 0 0 15px; | ||
90 | } | ||
91 | |||
92 | ul li, ol li { | ||
93 | margin:0 0 7px 0; | ||
94 | padding:0 0 0 3px; | ||
95 | } | ||
96 | |||
97 | h2 { | ||
98 | font-size:18px; | ||
99 | padding:0; | ||
100 | margin:30px 0 20px 0; | ||
101 | } | ||
102 | |||
103 | h3 { | ||
104 | font-size:16px; | ||
105 | padding:0; | ||
106 | margin:20px 0 5px 0; | ||
107 | } | ||
108 | |||
109 | h4 { | ||
110 | font-size:14px; | ||
111 | padding:0; | ||
112 | margin:15px 0 5px 0; | ||
113 | } | ||
114 | |||
115 | code { | ||
116 | font-size:1.1em; | ||
117 | background-color:#f3f3ff; | ||
118 | color:#000; | ||
119 | } | ||
120 | |||
121 | em strong { | ||
122 | text-transform: uppercase; | ||
123 | } | ||
124 | |||
125 | table#chart { | ||
126 | border-collapse:collapse; | ||
127 | } | ||
128 | |||
129 | table#chart th { | ||
130 | background-color:#eee; | ||
131 | padding:2px 3px; | ||
132 | border:1px solid #fff; | ||
133 | } | ||
134 | |||
135 | table#chart td { | ||
136 | text-align:center; | ||
137 | padding:2px 3px; | ||
138 | border:1px solid #eee; | ||
139 | } | ||
140 | |||
141 | table#chart tr.enabled td { | ||
142 | /* Leave this alone */ | ||
143 | } | ||
144 | |||
145 | table#chart tr.disabled td, | ||
146 | table#chart tr.disabled td a { | ||
147 | } | ||
148 | |||
149 | table#chart tr.disabled td a { | ||
150 | text-decoration:underline; | ||
151 | } | ||
152 | |||
153 | div.chunk { | ||
154 | margin:20px 0 0 0; | ||
155 | padding:0 0 10px 0; | ||
156 | border-bottom:1px solid #ccc; | ||
157 | } | ||
158 | 43 | ||
159 | .footnote, | 44 | return $status; |
160 | .footnote a { | ||
161 | font:10px/12px verdana, sans-serif; | ||
162 | color:#aaa; | ||
163 | } | 45 | } |
164 | 46 | function isOkay() { | |
165 | .footnote em { | 47 | return !in_array(false, status()); |
166 | background-color:transparent; | ||
167 | font-style:italic; | ||
168 | } | 48 | } |
169 | 49 | ||
170 | .good{ | 50 | function isPassing() { |
171 | background-color:#52CC5B; | 51 | $status = status(); |
172 | } | 52 | unset($status['curl'], $status['parallel'], $status['tidy'], $status['gd'], $status['filter']); |
173 | .bad{ | 53 | return !in_array(false, $status); |
174 | background-color:#F74343; | ||
175 | font-style:italic; | ||
176 | font-weight: bold; | ||
177 | } | 54 | } |
178 | .pass{ | ||
179 | background-color:#FF9500; | ||
180 | } | ||
181 | |||
182 | </style> | ||
183 | 55 | ||
184 | </head> | 56 | /* Function taken from at http://php.net/manual/en/function.rmdir.php#110489 |
185 | 57 | * Idea : nbari at dalmp dot com | |
186 | <body> | 58 | * Rights unknown |
187 | <?php | 59 | * Here in case of .gitignore files |
188 | $frominstall = false; | 60 | */ |
189 | if (isset($_GET['from'])){ | ||
190 | if ($_GET['from'] == 'install'){ | ||
191 | $frominstall = true; | ||
192 | }} | ||
193 | ?> | ||
194 | <div id="site"> | ||
195 | <div id="content"> | ||
196 | |||
197 | <div class="chunk"> | ||
198 | <h2 style="text-align:center;"><?php echo $app_name; ?>: Compatibility Test</h2> | ||
199 | <table cellpadding="0" cellspacing="0" border="0" width="100%" id="chart"> | ||
200 | <thead> | ||
201 | <tr> | ||
202 | <th>Test</th> | ||
203 | <th>Should Be</th> | ||
204 | <th>What You Have</th> | ||
205 | </tr> | ||
206 | </thead> | ||
207 | <tbody> | ||
208 | <tr class="<?php echo ($php_ok) ? 'enabled' : 'disabled'; ?>"> | ||
209 | <td>PHP</td> | ||
210 | <td>5.3.3 or higher</td> | ||
211 | <td class="<?php echo ($php_ok) ? 'good' : 'disabled'; ?>"><?php echo phpversion(); ?></td> | ||
212 | </tr> | ||
213 | <tr class="<?php echo ($xml_ok) ? 'enabled' : 'disabled'; ?>"> | ||
214 | <td><a href="http://php.net/xml">XML</a></td> | ||
215 | <td>Enabled</td> | ||
216 | <?php echo ($xml_ok) ? '<td class="good">Enabled, and sane</span>' : '<td class="bad">Disabled, or broken'; ?></td> | ||
217 | </tr> | ||
218 | <tr class="<?php echo ($pcre_ok) ? 'enabled' : 'disabled'; ?>"> | ||
219 | <td><a href="http://php.net/pcre">PCRE</a></td> | ||
220 | <td>Enabled</td> | ||
221 | <?php echo ($pcre_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
222 | </tr> | ||
223 | <!-- <tr class="<?php echo ($zlib_ok) ? 'enabled' : 'disabled'; ?>"> | ||
224 | <td><a href="http://php.net/zlib">Zlib</a></td> | ||
225 | <td>Enabled</td> | ||
226 | <?php echo ($zlib_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
227 | </tr> --> | ||
228 | <!-- <tr class="<?php echo ($mbstring_ok) ? 'enabled' : 'disabled'; ?>"> | ||
229 | <td><a href="http://php.net/mbstring">mbstring</a></td> | ||
230 | <td>Enabled</td> | ||
231 | <?php echo ($mbstring_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
232 | </tr> --> | ||
233 | <!-- <tr class="<?php echo ($iconv_ok) ? 'enabled' : 'disabled'; ?>"> | ||
234 | <td><a href="http://php.net/iconv">iconv</a></td> | ||
235 | <td>Enabled</td> | ||
236 | <?php echo ($iconv_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
237 | </tr> --> | ||
238 | <tr class="<?php echo ($dom_ok) ? 'enabled' : 'disabled'; ?>"> | ||
239 | <td><a href="http://php.net/manual/en/book.dom.php">DOM / XML extension</a></td> | ||
240 | <td>Enabled</td> | ||
241 | <?php echo ($dom_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
242 | </tr> | ||
243 | <tr class="<?php echo ($filter_ok) ? 'enabled' : 'disabled'; ?>"> | ||
244 | <td><a href="http://uk.php.net/manual/en/book.filter.php">Data filtering</a></td> | ||
245 | <td>Enabled</td> | ||
246 | <?php echo ($filter_ok) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
247 | </tr> | ||
248 | <tr class="<?php echo ($gd_ok) ? 'enabled' : 'disabled'; ?>"> | ||
249 | <td><a href="http://php.net/manual/en/book.image.php">GD</a></td> | ||
250 | <td>Enabled</td> | ||
251 | <?php echo ($gd_ok) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
252 | </tr> | ||
253 | <tr class="<?php echo ($tidy_ok) ? 'enabled' : 'disabled'; ?>"> | ||
254 | <td><a href="http://php.net/tidy">Tidy</a></td> | ||
255 | <td>Enabled</td> | ||
256 | <?php echo ($tidy_ok) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
257 | </tr> | ||
258 | <tr class="<?php echo ($curl_ok) ? 'enabled' : 'disabled'; ?>"> | ||
259 | <td><a href="http://php.net/curl">cURL</a></td> | ||
260 | <td>Enabled</td> | ||
261 | <?php echo (extension_loaded('curl')) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
262 | </tr> | ||
263 | <tr class="<?php echo ($parse_ini_ok) ? 'enabled' : 'disabled'; ?>"> | ||
264 | <td><a href="http://uk.php.net/manual/en/function.parse-ini-file.php">Parse ini file</td> | ||
265 | <td>Enabled</td> | ||
266 | <?php echo ($parse_ini_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
267 | </tr> | ||
268 | <tr class="<?php echo ($parallel_ok) ? 'enabled' : 'disabled'; ?>"> | ||
269 | <td>Parallel URL fetching</td> | ||
270 | <td>Enabled</td> | ||
271 | <?php echo ($parallel_ok) ? '<td class="good">Enabled' : '<td class="pass">Disabled'; ?></td> | ||
272 | </tr> | ||
273 | <tr class="<?php echo ($allow_url_fopen_ok) ? 'enabled' : 'disabled'; ?>"> | ||
274 | <td><a href="http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a></td> | ||
275 | <td>Enabled</td> | ||
276 | <?php echo ($allow_url_fopen_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
277 | </tr> | ||
278 | <tr class="<?php echo ($gettext_ok) ? 'enabled' : 'disabled'; ?>"> | ||
279 | <td><a href="http://php.net/manual/en/book.gettext.php">gettext</a></td> | ||
280 | <td>Enabled</td> | ||
281 | <?php echo ($gettext_ok) ? '<td class="good">Enabled' : '<td class="bad">Disabled'; ?></td> | ||
282 | </tr> | ||
283 | </tbody> | ||
284 | </table> | ||
285 | </div> | ||
286 | |||
287 | <div class="chunk"> | ||
288 | <h3>What does this mean?</h3> | ||
289 | <ol> | ||
290 | <?php //if ($php_ok && $xml_ok && $pcre_ok && $mbstring_ok && $iconv_ok && $filter_ok && $zlib_ok && $tidy_ok && $curl_ok && $parallel_ok && $allow_url_fopen_ok): ?> | ||
291 | <?php if ($php_ok && $xml_ok && $pcre_ok && $dom_ok && $filter_ok && $gd_ok && $tidy_ok && $curl_ok && $parallel_ok && $allow_url_fopen_ok && $gettext_ok && $parse_ini_ok): ?> | ||
292 | <li><em>You have everything you need to run <?php echo $app_name; ?> properly! Congratulations!</em></li> | ||
293 | <?php else: ?> | ||
294 | <?php if ($php_ok): ?> | ||
295 | <li><strong>PHP:</strong> You are running a supported version of PHP. <em>No problems here.</em></li> | ||
296 | <?php if ($xml_ok): ?> | ||
297 | <li><strong>XML:</strong> You have XMLReader support or a version of XML support that isn't broken installed. <em>No problems here.</em></li> | ||
298 | <?php if ($pcre_ok): ?> | ||
299 | <li><strong>PCRE:</strong> You have PCRE support installed. <em>No problems here.</em></li> | ||
300 | |||
301 | <?php if ($allow_url_fopen_ok): ?> | ||
302 | <li><strong>allow_url_fopen:</strong> You have allow_url_fopen enabled. <em>No problems here.</em></li> | ||
303 | |||
304 | <?php if ($gettext_ok): ?> | ||
305 | <li><strong>Gettext:</strong> You have <code>gettext</code> enabled. <em>No problems here.</em></li> | ||
306 | |||
307 | <?php if ($parse_ini_ok): ?> | ||
308 | <li><strong>Parse ini:</strong> You can parse <em>ini</em> files. <em>No problems here.</em></li> | ||
309 | |||
310 | <?php if ($dom_ok): ?> | ||
311 | <li><strong>DOM/XML:</strong> You can parse <em>ini</em> files. <em>No problems here.</em></li> | ||
312 | |||
313 | <?php if ($filter_ok): ?> | ||
314 | <li><strong>Data filtering:</strong> You can use the PHP build-in DOM to operate on XML documents. <em>No problems here.</em></li> | ||
315 | |||
316 | <?php if ($zlib_ok): ?> | ||
317 | <li><strong>Zlib:</strong> You have <code>Zlib</code> enabled. This allows SimplePie to support GZIP-encoded feeds. <em>No problems here.</em></li> | ||
318 | <?php else: ?> | ||
319 | <li><strong>Zlib:</strong> The <code>Zlib</code> extension is not available. SimplePie will ignore any GZIP-encoding, and instead handle feeds as uncompressed text.</li> | ||
320 | <?php endif; ?> | ||
321 | |||
322 | <?php if ($mbstring_ok && $iconv_ok): ?> | ||
323 | <li><strong>mbstring and iconv:</strong> You have both <code>mbstring</code> and <code>iconv</code> installed! This will allow <?php echo $app_name; ?> to handle the greatest number of languages. <em>No problems here.</em></li> | ||
324 | <?php elseif ($mbstring_ok): ?> | ||
325 | <li><strong>mbstring:</strong> <code>mbstring</code> is installed, but <code>iconv</code> is not.</li> | ||
326 | <?php elseif ($iconv_ok): ?> | ||
327 | <li><strong>iconv:</strong> <code>iconv</code> is installed, but <code>mbstring</code> is not.</li> | ||
328 | <?php else: ?> | ||
329 | <li><strong>mbstring and iconv:</strong> <em>You do not have either of the extensions installed.</em> This will significantly impair your ability to read non-English feeds, as well as even some English ones.</li> | ||
330 | <?php endif; ?> | ||
331 | |||
332 | <?php if ($gd_ok): ?> | ||
333 | <li><strong>GD:</strong> You have <code>GD</code> support installed. <em>No problems here.</em></li> | ||
334 | <?php else: ?> | ||
335 | <li><strong>GD:</strong> The <code>GD</code> extension is not available. <?php echo $app_name; ?> will not be able to download pictures locally on your server.</li> | ||
336 | <?php endif; ?> | ||
337 | |||
338 | <?php if ($tidy_ok): ?> | ||
339 | <li><strong>Tidy:</strong> You have <code>Tidy</code> support installed. <em>No problems here.</em></li> | ||
340 | <?php else: ?> | ||
341 | <li><strong>Tidy:</strong> The <code>Tidy</code> extension is not available. <?php echo $app_name; ?> should still work with most feeds, but you may experience problems with some. You can install it with <code>sudo apt-get install php5-tidy</code> and then reload Apache <code>sudo service apache2 reload</code>.</li> | ||
342 | <?php endif; ?> | ||
343 | |||
344 | <?php if ($curl_ok): ?> | ||
345 | <li><strong>cURL:</strong> You have <code>cURL</code> support installed. <em>No problems here.</em></li> | ||
346 | <?php else: ?> | ||
347 | <li><strong>cURL:</strong> The <code>cURL</code> extension is not available. SimplePie will use <code>fsockopen()</code> instead.</li> | ||
348 | <?php endif; ?> | ||
349 | |||
350 | <?php if ($parallel_ok): ?> | ||
351 | <li><strong>Parallel URL fetching:</strong> You have <code>HttpRequestPool</code> or <code>curl_multi</code> support installed. <em>No problems here.</em></li> | ||
352 | <?php else: ?> | ||
353 | <li><strong>Parallel URL fetching:</strong> <code>HttpRequestPool</code> or <code>curl_multi</code> support is not available. <?php echo $app_name; ?> will use <code>file_get_contents()</code> instead to fetch URLs sequentially rather than in parallel.</li> | ||
354 | <?php endif; ?> | ||
355 | |||
356 | <?php else: ?> | ||
357 | <li><strong>Data filtering:</strong> Your PHP configuration has the filter extension disabled. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
358 | <?php endif; ?> | ||
359 | |||
360 | <?php else: ?> | ||
361 | <li><strong>DOM/XML:</strong> Your PHP configuration isn't standard, you're missing PHP-DOM. You may try to install a package or recompile PHP. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
362 | <?php endif; ?> | ||
363 | |||
364 | <?php else : ?> | ||
365 | <li><strong>Parse ini files function :</strong> Bad luck : your webhost has decided to block the use of the <em>parse_ini_file</em> function. <strong><?php echo $app_name; ?> will not work here.</strong> | ||
366 | <?php endif; ?> | ||
367 | |||
368 | <?php else: ?> | ||
369 | <li><strong>GetText:</strong> The <code>gettext</code> extension is not available. The system we use to display wallabag in various languages is not available. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
370 | <?php endif; ?> | ||
371 | |||
372 | <?php else: ?> | ||
373 | <li><strong>allow_url_fopen:</strong> Your PHP configuration has allow_url_fopen disabled. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
374 | <?php endif; ?> | ||
375 | |||
376 | <?php else: ?> | ||
377 | <li><strong>PCRE:</strong> Your PHP installation doesn't support Perl-Compatible Regular Expressions. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
378 | <?php endif; ?> | ||
379 | <?php else: ?> | ||
380 | <li><strong>XML:</strong> Your PHP installation doesn't support XML parsing. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
381 | <?php endif; ?> | ||
382 | <?php else: ?> | ||
383 | <li><strong>PHP:</strong> You are running an unsupported version of PHP. <strong><?php echo $app_name; ?> will not work here.</strong></li> | ||
384 | <?php endif; ?> | ||
385 | <?php endif; ?> | ||
386 | </ol> | ||
387 | </div> | ||
388 | |||
389 | <div class="chunk"> | ||
390 | <?php //if ($php_ok && $xml_ok && $pcre_ok && $mbstring_ok && $iconv_ok && $filter_ok && $allow_url_fopen_ok) { ?> | ||
391 | <?php if ($php_ok && $xml_ok && $pcre_ok && $filter_ok && $allow_url_fopen_ok && $gettext_ok && $parse_ini_ok) { ?> | ||
392 | <h3>Bottom Line: Yes, you can!</h3> | ||
393 | <p><em>Your webhost has its act together!</em></p> | ||
394 | <?php if (!$frominstall) { ?> | ||
395 | <p>You can download the latest version of <?php echo $app_name; ?> from <a href="http://wallabag.org/download">wallabag.org</a>.</p> | ||
396 | <p>If you already have done that, you should access <a href="index.php">the index.php file</a> of your installation to configure and/or start using wallabag</p> | ||
397 | <?php } else { ?> | ||
398 | <p>You can now <a href="../index.php">return to the installation section</a>.</p> | ||
399 | <?php } ?> | ||
400 | <p><strong>Note</strong>: Passing this test does not guarantee that <?php echo $app_name; ?> will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.</p> | ||
401 | <?php //} else if ($php_ok && $xml_ok && $pcre_ok && $mbstring_ok && $allow_url_fopen_ok && $filter_ok) { ?> | ||
402 | <?php } else if ($php_ok && $xml_ok && $pcre_ok && $allow_url_fopen_ok && $filter_ok && $gettext_ok && $parse_ini_ok) { ?> | ||
403 | <h3>Bottom Line: Yes, you can!</h3> | ||
404 | <p><em>For most feeds, it'll run with no problems.</em> There are certain languages that you might have a hard time with though.</p> | ||
405 | <?php if (!$frominstall) { ?> | ||
406 | <p>You can download the latest version of <?php echo $app_name; ?> from <a href="http://wallabag.org/download">wallabag.org</a>.</p> | ||
407 | <p>If you already have done that, you should access <a href="index.php">the index.php file</a> of your installation to configure and/or start using wallabag</p> | ||
408 | <?php } else { ?> | ||
409 | <p>You can now <a href="../index.php">return to the installation section</a>.</p> | ||
410 | <?php } ?> | ||
411 | <p><strong>Note</strong>: Passing this test does not guarantee that <?php echo $app_name; ?> will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.</p> | ||
412 | <?php } else { ?> | ||
413 | <h3>Bottom Line: We're sorry…</h3> | ||
414 | <p><em>Your webhost does not support the minimum requirements for <?php echo $app_name; ?>.</em> It may be a good idea to contact your webhost and point them to the results of this test. They may be able to enable/install the required components.</p> | ||
415 | <?php } ?> | ||
416 | </div> | ||
417 | |||
418 | <div class="chunk"> | ||
419 | <p class="footnote">This compatibility test has been borrowed (and slightly adapted by <a href="http://fivefilters.org/content-only/">fivefilters.org</a>) from the one supplied by <a href="http://simplepie.org/">SimplePie.org</a>.</a></p> | ||
420 | </div> | ||
421 | |||
422 | </div> | ||
423 | |||
424 | </div> | ||
425 | 61 | ||
426 | </body> | 62 | function delTree($dir) { |
427 | </html> | 63 | $files = array_diff(scandir($dir), array('.','..')); |
64 | foreach ($files as $file) { | ||
65 | (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); | ||
66 | } | ||
67 | return rmdir($dir); | ||
68 | } | ||
69 | |||
70 | function generate_salt() { | ||
71 | mt_srand(microtime(true)*100000 + memory_get_usage(true)); | ||
72 | return md5(uniqid(mt_rand(), true)); | ||
73 | } | ||
74 | |||
75 | function executeQuery($handle, $sql, $params) { | ||
76 | try | ||
77 | { | ||
78 | $query = $handle->prepare($sql); | ||
79 | $query->execute($params); | ||
80 | return $query->fetchAll(); | ||
81 | } | ||
82 | catch (Exception $e) | ||
83 | { | ||
84 | return FALSE; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | ?> \ No newline at end of file | ||
diff --git a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo index bd18817f..3add116c 100644 --- a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo +++ b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo | |||
Binary files differ | |||
diff --git a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po index 8b82721d..47801007 100644 --- a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po +++ b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po | |||
@@ -1,18 +1,26 @@ | |||
1 | msgid "" | 1 | msgid "" |
2 | msgstr "" | 2 | msgstr "" |
3 | "Project-Id-Version: Wallabag\n" | 3 | "Project-Id-Version: wallabag\n" |
4 | "Report-Msgid-Bugs-To: \n" | 4 | "Report-Msgid-Bugs-To: \n" |
5 | "POT-Creation-Date: 2014-03-27 13:41+0100\n" | 5 | "POT-Creation-Date: 2014-02-25 15:17+0300\n" |
6 | "PO-Revision-Date: \n" | 6 | "PO-Revision-Date: \n" |
7 | "Last-Translator: Kevin Meyer <wallabag@kevin-meyer.de>\n" | 7 | "Last-Translator: Julian Oster <wallabag@jlnostr.de>\n" |
8 | "Language-Team: \n" | 8 | "Language-Team: \n" |
9 | "Language: de\n" | 9 | "Language: de_DE\n" |
10 | "MIME-Version: 1.0\n" | 10 | "MIME-Version: 1.0\n" |
11 | "Content-Type: text/plain; charset=UTF-8\n" | 11 | "Content-Type: text/plain; charset=UTF-8\n" |
12 | "Content-Transfer-Encoding: 8bit\n" | 12 | "Content-Transfer-Encoding: 8bit\n" |
13 | "X-Generator: Poedit 1.6.4\n" | 13 | "X-Generator: Poedit 1.7.3\n" |
14 | "X-Poedit-Basepath: .\n" | 14 | "X-Poedit-Basepath: .\n" |
15 | "X-Poedit-SearchPath-0: /Users/kevinmeyer/Dropbox/dev_web/wallabag-dev\n" | 15 | |
16 | msgid "wallabag, a read it later open source system" | ||
17 | msgstr "wallabag, ein \"Read-it-later\"-Open-Source-System" | ||
18 | |||
19 | msgid "login failed: user doesn't exist" | ||
20 | msgstr "Anmeldung fehlgeschlagen: Benutzer existiert nicht" | ||
21 | |||
22 | msgid "return home" | ||
23 | msgstr "Auf Startseite zurückkehren" | ||
16 | 24 | ||
17 | msgid "config" | 25 | msgid "config" |
18 | msgstr "Konfiguration" | 26 | msgstr "Konfiguration" |
@@ -21,13 +29,19 @@ msgid "Saving articles" | |||
21 | msgstr "Artikel speichern" | 29 | msgstr "Artikel speichern" |
22 | 30 | ||
23 | msgid "There are several ways to save an article:" | 31 | msgid "There are several ways to save an article:" |
24 | msgstr "Es gibt viele Methoden um Artikel zu speichern:" | 32 | msgstr "Es gibt mehrere Wege, um einen Artikel zu speichern:" |
25 | 33 | ||
26 | msgid "read the documentation" | 34 | msgid "read the documentation" |
27 | msgstr "Die Dokumentation lesen" | 35 | msgstr "Dokumentation lesen" |
28 | 36 | ||
29 | msgid "download the extension" | 37 | msgid "download the extension" |
30 | msgstr "installiere die Erweiterung" | 38 | msgstr "Erweiterung herunterladen" |
39 | |||
40 | msgid "Firefox Add-On" | ||
41 | msgstr "Firefox-Addon" | ||
42 | |||
43 | msgid "Chrome Extension" | ||
44 | msgstr "Chrome-Erweiterung" | ||
31 | 45 | ||
32 | msgid "via F-Droid" | 46 | msgid "via F-Droid" |
33 | msgstr "via F-Droid" | 47 | msgstr "via F-Droid" |
@@ -39,16 +53,16 @@ msgid "via Google Play" | |||
39 | msgstr "via Google Play" | 53 | msgstr "via Google Play" |
40 | 54 | ||
41 | msgid "download the application" | 55 | msgid "download the application" |
42 | msgstr "lade die App" | 56 | msgstr "App herunterladen" |
43 | 57 | ||
44 | msgid "By filling this field" | 58 | msgid "By filling this field" |
45 | msgstr "Durch Ausfüllen dieses Feldes" | 59 | msgstr "Durch das Ausfüllen dieses Feldes" |
46 | 60 | ||
47 | msgid "bag it!" | 61 | msgid "bag it!" |
48 | msgstr "bag it!" | 62 | msgstr "bag it!" |
49 | 63 | ||
50 | msgid "Bookmarklet: drag & drop this link to your bookmarks bar" | 64 | msgid "Bookmarklet: drag & drop this link to your bookmarks bar" |
51 | msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen-Leiste" | 65 | msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen" |
52 | 66 | ||
53 | msgid "Upgrading wallabag" | 67 | msgid "Upgrading wallabag" |
54 | msgstr "wallabag aktualisieren" | 68 | msgstr "wallabag aktualisieren" |
@@ -57,58 +71,46 @@ msgid "Installed version" | |||
57 | msgstr "Installierte Version" | 71 | msgstr "Installierte Version" |
58 | 72 | ||
59 | msgid "Latest stable version" | 73 | msgid "Latest stable version" |
60 | msgstr "Neuste stabile Version" | 74 | msgstr "Letzte stabile Version" |
61 | 75 | ||
62 | msgid "A more recent stable version is available." | 76 | msgid "A more recent stable version is available." |
63 | msgstr "Eine neuere stabile Version ist verfügbar." | 77 | msgstr "Eine neuere Version ist verfügbar." |
64 | 78 | ||
65 | msgid "You are up to date." | 79 | msgid "You are up to date." |
66 | msgstr "Du bist auf den neuesten Stand." | 80 | msgstr "Du bist auf dem aktuellsten Stand." |
67 | |||
68 | msgid "Last check:" | ||
69 | msgstr "Zuletzt geprüft:" | ||
70 | 81 | ||
71 | msgid "Latest dev version" | 82 | msgid "Latest dev version" |
72 | msgstr "Neuste Entwicklungsversion" | 83 | msgstr "Letzte Entwickler-Version" |
73 | 84 | ||
74 | msgid "A more recent development version is available." | 85 | msgid "A more recent development version is available." |
75 | msgstr "Eine neuere Entwicklungsversion ist verfügbar." | 86 | msgstr "Eine neuere Entwickler-Version ist verfügbar." |
76 | 87 | ||
77 | msgid "You can clear cache to check the latest release." | 88 | msgid "You can clear cache to check the latest release." |
78 | msgstr "Leere den Cache um die neueste Version zu prüfen." | 89 | msgstr "Du kannst den <a href=\"#cache\">Cache leeren</a>, um nach neueren Versionen zu suchen." |
79 | 90 | ||
80 | msgid "Feeds" | 91 | msgid "Feeds" |
81 | msgstr "Feeds" | 92 | msgstr "Feeds" |
82 | 93 | ||
83 | msgid "" | 94 | msgid "Your feed token is currently empty and must first be generated to enable feeds. Click <a href='?feed&action=generate'>here to generate it</a>." |
84 | "Your feed token is currently empty and must first be generated to enable " | 95 | msgstr "Dein Feed-Token ist momentan leer und muss generiert werden, um die Feeds zu aktivieren. Klicke <a href='?feed&action=generate'>hier, um ihn zu erstellen</a>." |
85 | "feeds. Click <a href='?feed&action=generate'>here to generate it</a>." | ||
86 | msgstr "" | ||
87 | "Dein Feed Token ist noch nicht vorhanden und muss zunächst generiert werden, " | ||
88 | "um deine Feeds zu aktivieren. Klicke <a href='?feed&" | ||
89 | "action=generate'>hier um ihn zu generieren</a>." | ||
90 | 96 | ||
91 | msgid "Unread feed" | 97 | msgid "Unread feed" |
92 | msgstr "Ungelesen Feed" | 98 | msgstr "Feed für Ungelesenes" |
93 | 99 | ||
94 | msgid "Favorites feed" | 100 | msgid "Favorites feed" |
95 | msgstr "Favoriten Feed" | 101 | msgstr "Feed für Favoriten" |
96 | 102 | ||
97 | msgid "Archive feed" | 103 | msgid "Archive feed" |
98 | msgstr "Archiv Feed" | 104 | msgstr "Archiv-Feed" |
99 | 105 | ||
100 | msgid "Your token:" | 106 | msgid "Your token:" |
101 | msgstr "Dein Token:" | 107 | msgstr "Dein Token:" |
102 | 108 | ||
103 | msgid "Your user id:" | 109 | msgid "Your user id:" |
104 | msgstr "Deine User ID:" | 110 | msgstr "Deine Benutzer-ID:" |
105 | 111 | ||
106 | msgid "" | 112 | msgid "You can regenerate your token: <a href='?feed&action=generate'>generate!</a>." |
107 | "You can regenerate your token: <a href='?feed&action=generate'>generate!" | 113 | msgstr "Du kannst deinen Token regenerieren: <a href='?feed&action=generate'>generieren!</a>." |
108 | "</a>." | ||
109 | msgstr "" | ||
110 | "Hier kannst du dein Token erzeugen: <a href='?feed&" | ||
111 | "action=generate'>Generieren!</a>." | ||
112 | 114 | ||
113 | msgid "Change your theme" | 115 | msgid "Change your theme" |
114 | msgstr "Theme ändern" | 116 | msgstr "Theme ändern" |
@@ -138,76 +140,58 @@ msgid "Repeat your new password:" | |||
138 | msgstr "Neues Passwort wiederholen:" | 140 | msgstr "Neues Passwort wiederholen:" |
139 | 141 | ||
140 | msgid "Import" | 142 | msgid "Import" |
141 | msgstr "Import" | 143 | msgstr "Importieren" |
142 | 144 | ||
143 | msgid "" | 145 | msgid "You can import your Pocket, Readability, Instapaper, Wallabag or any data in appropriate json or html format." |
144 | "Importing from other services can be quite long, and webservers default " | 146 | msgstr "Du kannst aus Pocket, Readability, Instapaper, wallabag oder einer beliebigen Datei in angebrachtem JSON- oder HTML-Format importieren." |
145 | "configuration often prevents long scripts execution time, so it must be done " | 147 | |
146 | "in multiple parts." | 148 | msgid "Please execute the import script locally as it can take a very long time." |
147 | msgstr "" | 149 | msgstr "Führe das Import-Skript lokal aus, da der Import sehr lange dauern kann." |
148 | "Der Import von anderen Diensten kann sehr lange dauern. Deswegen bricht der " | ||
149 | "Webserver diesen in vielen Konfigurationen ab. Daher muss der Import in " | ||
150 | "mehrere Teile aufgeteilt werden." | ||
151 | 150 | ||
152 | msgid "First, select the export file on your computer and upload it." | 151 | msgid "Please select export file on your computer and press \"Import\" button below. Wallabag will parse your file, insert all URLs and start fetching of articles if required." |
153 | msgstr "Wähle eine Datei von deinem Computer aus und lade sie hoch." | 152 | msgstr "" |
153 | "Wähle die Export-Datei auf deinem Computer aus und drücke den \"Import\"-Button unten. Wallabag wird deine Datei durchsuchen, alle URLs in der Datenbank speichern und die Artikel " | ||
154 | "herunterladen, sofern dies erforderlich ist." | ||
154 | 155 | ||
155 | msgid "File:" | 156 | msgid "You can click here to fetch content for articles with no content." |
156 | msgstr "Datei:" | 157 | msgstr "Du kannst hier klicken, um den Inhalt für Artikel ohne Inhalt herunterzuladen." |
157 | 158 | ||
158 | msgid "Upload" | 159 | msgid "More info in the official documentation:" |
159 | msgstr "Hochladen" | 160 | msgstr "Mehr Infos in der offiziellen Dokumentation:" |
160 | 161 | ||
161 | msgid "Then, click on the right link below." | 162 | msgid "(<a href=\"http://doc.wallabag.org/en/User_documentation/Save_your_first_article\" target=\"_blank\" title=\"Documentation\">?</a>)" |
162 | msgstr "Klicke dann unten auf den entsprechenden Link." | 163 | msgstr "(<a href=\"http://doc.wallabag.org/de/Anwender/Den_ersten_Artikel_speichern\" target=\"_blank\" title=\"Dokumentation\">?</a>)" |
163 | 164 | ||
164 | msgid "Import from Pocket" | 165 | msgid "Import from Pocket" |
165 | msgstr "Import aus Pocket" | 166 | msgstr "Aus Pocket importieren" |
166 | 167 | ||
167 | #, php-format | 168 | #, php-format |
168 | msgid "(after uploaded %s file)" | 169 | msgid "(you must have a %s file on your server)" |
169 | msgstr "(nach Upload der Datei %s)" | 170 | msgstr "(du solltest eine %s Datei auf deinem Server haben)" |
170 | 171 | ||
171 | msgid "Import from Readability" | 172 | msgid "Import from Readability" |
172 | msgstr "Import aus Readability" | 173 | msgstr "Aus Readability importieren" |
173 | 174 | ||
174 | msgid "Import from Instapaper" | 175 | msgid "Import from Instapaper" |
175 | msgstr "Import aus Instapaper" | 176 | msgstr "Aus Instapaper importieren" |
176 | 177 | ||
177 | msgid "Import from wallabag" | 178 | msgid "Import from wallabag" |
178 | msgstr "Import aus Readability" | 179 | msgstr "Aus wallabag importieren" |
179 | 180 | ||
180 | msgid "" | 181 | msgid "Export your wallabag data" |
181 | "3. Your feed token is currently empty and must first be generated to fetch " | 182 | msgstr "Deine wallabag-Daten exportieren" |
182 | "content. Click <a href='?feed&action=generate'>here to generate it</a>." | ||
183 | msgstr "" | ||
184 | "3. Dein Feed Token ist noch nicht vorhanden und muss zunächst generiert " | ||
185 | "werden, um Inhalt abrufen zu können. Klicke <a href='?feed&" | ||
186 | "action=generate'>hier um ihn zu generieren</a>." | ||
187 | |||
188 | msgid "Finally, you have to fetch content for imported items." | ||
189 | msgstr "Jetzt musst du den Inhalt der importierten Artikel abrufen." | ||
190 | 183 | ||
191 | msgid "Click here" | 184 | msgid "Click here" |
192 | msgstr "Klicke hier" | 185 | msgstr "Hier klicken, " |
193 | |||
194 | msgid "to fetch content for 10 articles" | ||
195 | msgstr "um den Inhalt von 10 Artikeln abzurufen" | ||
196 | |||
197 | msgid "" | ||
198 | "If you have console access to your server, you can also create a cron task:" | ||
199 | msgstr "" | ||
200 | "Wenn du Konsolenzugang zu deinem Server hast kannst du auch einen cron " | ||
201 | "erstellen:" | ||
202 | |||
203 | msgid "Export your wallabag data" | ||
204 | msgstr "Exportieren deine wallabag Daten" | ||
205 | 186 | ||
206 | msgid "to download your database." | 187 | msgid "to download your database." |
207 | msgstr "um deine Datenbank herunterzuladen" | 188 | msgstr "um die Datenbank herunterzuladen." |
208 | 189 | ||
209 | msgid "to export your wallabag data." | 190 | msgid "to export your wallabag data." |
210 | msgstr "um deine Daten aus wallabag zu exportieren." | 191 | msgstr "um die wallabag-Daten zu exportieren." |
192 | |||
193 | msgid "Export JSON" | ||
194 | msgstr "JSON exportieren" | ||
211 | 195 | ||
212 | msgid "Cache" | 196 | msgid "Cache" |
213 | msgstr "Cache" | 197 | msgstr "Cache" |
@@ -215,444 +199,437 @@ msgstr "Cache" | |||
215 | msgid "to delete cache." | 199 | msgid "to delete cache." |
216 | msgstr "um den Cache zu löschen." | 200 | msgstr "um den Cache zu löschen." |
217 | 201 | ||
218 | msgid "Tags" | 202 | msgid "Delete Cache" |
219 | msgstr "Tags" | 203 | msgstr "Cache löschen, " |
204 | |||
205 | msgid "You can enter multiple tags, separated by commas." | ||
206 | msgstr "Du kannst mehrere Schlagworte, getrennt von einem Komma, hinzufügen." | ||
207 | |||
208 | msgid "Add tags:" | ||
209 | msgstr "Schlagworte hinzufügen:" | ||
210 | |||
211 | msgid "no tags" | ||
212 | msgstr "keine schlagworte" | ||
213 | |||
214 | msgid "The tag has been applied successfully" | ||
215 | msgstr "Das Schlagwort wurde erfolgreich übernommen." | ||
216 | |||
217 | msgid "interview" | ||
218 | msgstr "interview" | ||
219 | |||
220 | msgid "editorial" | ||
221 | msgstr "editorial" | ||
222 | |||
223 | msgid "video" | ||
224 | msgstr "video" | ||
225 | |||
226 | msgid "return to article" | ||
227 | msgstr "zum artikel zurückkehren" | ||
228 | |||
229 | msgid "plop" | ||
230 | msgstr "plop" | ||
231 | |||
232 | msgid "You can <a href='wallabag_compatibility_test.php'>check your configuration here</a>." | ||
233 | msgstr "Du kannst deine <a href='wallabag_compatibility_test.php'>Konfiguration hier überprüfen</a>." | ||
234 | |||
235 | msgid "favoris" | ||
236 | msgstr "Favoriten" | ||
237 | |||
238 | msgid "archive" | ||
239 | msgstr "archiv" | ||
240 | |||
241 | msgid "unread" | ||
242 | msgstr "ungelesen" | ||
220 | 243 | ||
221 | msgid "by date asc" | 244 | msgid "by date asc" |
222 | msgstr "nach Datum aufsteigend" | 245 | msgstr "nach Datum, aufsteigend" |
223 | 246 | ||
224 | msgid "by date" | 247 | msgid "by date" |
225 | msgstr "nach Datum" | 248 | msgstr "nach Datum" |
226 | 249 | ||
227 | msgid "by date desc" | 250 | msgid "by date desc" |
228 | msgstr "nach Datum absteigend" | 251 | msgstr "nach Datum, absteigend" |
229 | 252 | ||
230 | msgid "by title asc" | 253 | msgid "by title asc" |
231 | msgstr "nach Titel aufsteigend" | 254 | msgstr "nach Titel, aufsteigend" |
232 | 255 | ||
233 | msgid "by title" | 256 | msgid "by title" |
234 | msgstr "nach Titel" | 257 | msgstr "nach Titel" |
235 | 258 | ||
236 | msgid "by title desc" | 259 | msgid "by title desc" |
237 | msgstr "nach Titel absteigend" | 260 | msgstr "nach Titel, absteigend" |
238 | |||
239 | #, fuzzy | ||
240 | msgid "toggle view mode" | ||
241 | msgstr "Favorit" | ||
242 | 261 | ||
243 | msgid "home" | 262 | msgid "Tag" |
244 | msgstr "Start" | 263 | msgstr "Schlagwort" |
245 | 264 | ||
246 | msgid "favorites" | 265 | msgid "No articles found." |
247 | msgstr "Favoriten" | 266 | msgstr "Keine Artikel gefunden." |
248 | 267 | ||
249 | msgid "archive" | 268 | msgid "Toggle mark as read" |
250 | msgstr "Archiv" | 269 | msgstr "Als gelesen/ungelesen markieren" |
251 | 270 | ||
252 | msgid "tags" | 271 | msgid "toggle favorite" |
253 | msgstr "Tags" | 272 | msgstr "favorisieren" |
254 | 273 | ||
255 | msgid "save a link" | 274 | msgid "delete" |
256 | msgstr "Speichere einen Link" | 275 | msgstr "löschen" |
257 | 276 | ||
258 | msgid "search" | 277 | msgid "original" |
259 | msgstr "Suche" | 278 | msgstr "original" |
260 | 279 | ||
261 | msgid "logout" | 280 | msgid "estimated reading time:" |
262 | msgstr "Logout" | 281 | msgstr "Geschätzte Lesezeit:" |
263 | 282 | ||
264 | msgid "return home" | 283 | msgid "mark all the entries as read" |
265 | msgstr "Zurück zum Start" | 284 | msgstr "Alle Einträge als gelesen markieren" |
266 | 285 | ||
267 | #, fuzzy | 286 | msgid "results" |
268 | msgid "Search" | 287 | msgstr "Ergebnisse" |
269 | msgstr "Archiv" | ||
270 | 288 | ||
271 | msgid "powered by" | 289 | msgid "installation" |
272 | msgstr "bereitgestellt von" | 290 | msgstr "installation" |
273 | 291 | ||
274 | msgid "debug mode is on so cache is off." | 292 | msgid "install your wallabag" |
275 | msgstr "Debug Modus ist aktiviert, das Caching ist somit deaktiviert" | 293 | msgstr "deine wallabag installieren" |
276 | 294 | ||
277 | msgid "your wallabag version:" | 295 | msgid "wallabag is still not installed. Please fill the below form to install it. Don't hesitate to <a href='http://doc.wallabag.org/'>read the documentation on wallabag website</a>." |
278 | msgstr "Deine wallabag Version" | 296 | msgstr "" |
297 | "wallabag ist noch nicht installiert. Fülle das untenstehende Formular aus, um wallabag zu installieren. Scheue dich nicht davor, die <a href='http://doc.wallabag.org/de'>Dokumentation " | ||
298 | "auf der wallabag-Webseite</a> zur Hilfe zu ziehen." | ||
279 | 299 | ||
280 | msgid "storage:" | 300 | msgid "Login" |
281 | msgstr "Speicher:" | 301 | msgstr "Anmelden" |
282 | 302 | ||
283 | msgid "Save a link" | 303 | msgid "Repeat your password" |
284 | msgstr "Speichere einen Link" | 304 | msgstr "Passwort wiederholen" |
285 | 305 | ||
286 | msgid "save link!" | 306 | msgid "Install" |
287 | msgstr "Link speichern!" | 307 | msgstr "Installieren" |
288 | 308 | ||
289 | msgid "unread" | 309 | msgid "login to your wallabag" |
290 | msgstr "ungelesen" | 310 | msgstr "Melde dich in deiner wallabag an" |
291 | 311 | ||
292 | msgid "Tag" | 312 | msgid "Login to wallabag" |
293 | msgstr "Tag" | 313 | msgstr "In wallabag anmelden" |
294 | 314 | ||
295 | msgid "No articles found." | 315 | msgid "you are in demo mode, some features may be disabled." |
296 | msgstr "Keine Artikel gefunden." | 316 | msgstr "Du bist im Demo-Modus, einige Features sind möglicherweise deaktiviert." |
297 | 317 | ||
298 | msgid "estimated reading time:" | 318 | msgid "Username" |
299 | msgstr "geschätzte Lesezeit:" | 319 | msgstr "Benutzername" |
300 | 320 | ||
301 | msgid "estimated reading time :" | 321 | msgid "Stay signed in" |
302 | msgstr "geschätzte Lesezeit:" | 322 | msgstr "Angemeldet bleiben" |
303 | 323 | ||
304 | msgid "Toggle mark as read" | 324 | msgid "(Do not check on public computers)" |
305 | msgstr "Als gelesen markieren" | 325 | msgstr "(nicht auf öffentlichen Computern ankreuzen)" |
306 | 326 | ||
307 | msgid "toggle favorite" | 327 | msgid "Sign in" |
308 | msgstr "Favorit" | 328 | msgstr "Anmelden" |
309 | 329 | ||
310 | msgid "delete" | 330 | msgid "favorites" |
311 | msgstr "Löschen" | 331 | msgstr "favoriten" |
312 | 332 | ||
313 | msgid "original" | 333 | msgid "estimated reading time :" |
314 | msgstr "Original" | 334 | msgstr "Geschätzte Lesezeit:" |
315 | 335 | ||
316 | msgid "Mark all the entries as read" | 336 | msgid "Mark all the entries as read" |
317 | msgstr "Markiere alle als gelesen" | 337 | msgstr "Alle Einträge als gelesen markieren" |
318 | 338 | ||
319 | msgid "results" | 339 | msgid "Return home" |
320 | msgstr "Ergebnisse" | 340 | msgstr "Zur Startseite zurückkehren" |
321 | 341 | ||
322 | msgid "Uh, there is a problem with the cron." | 342 | msgid "Back to top" |
323 | msgstr "Oh, es gab ein Problem mit dem cron." | 343 | msgstr "Nach oben scrollen" |
324 | 344 | ||
325 | msgid "Untitled" | 345 | msgid "Mark as read" |
326 | msgstr "Ohne Titel" | 346 | msgstr "Als gelesen markieren" |
327 | |||
328 | msgid "the link has been added successfully" | ||
329 | msgstr "Speichern des Links erfolgreich" | ||
330 | |||
331 | msgid "error during insertion : the link wasn't added" | ||
332 | msgstr "Fehler beim Einfügen: Der Link wurde nicht hinzugefügt" | ||
333 | |||
334 | msgid "the link has been deleted successfully" | ||
335 | msgstr "Löschen des Links erfolgreich" | ||
336 | |||
337 | msgid "the link wasn't deleted" | ||
338 | msgstr "Der Link wurde nicht entfernt" | ||
339 | 347 | ||
340 | msgid "Article not found!" | 348 | msgid "Favorite" |
341 | msgstr "Artikel nicht gefunden!" | 349 | msgstr "Favorisieren" |
342 | 350 | ||
343 | msgid "previous" | 351 | msgid "Toggle favorite" |
344 | msgstr "vorherige" | 352 | msgstr "favorisieren" |
345 | 353 | ||
346 | msgid "next" | 354 | msgid "Delete" |
347 | msgstr "nächste" | 355 | msgstr "Löschen" |
348 | 356 | ||
349 | msgid "in demo mode, you can't update your password" | 357 | msgid "Tweet" |
350 | msgstr "im Demo-Modus kann das Passwort nicht geändert werden" | 358 | msgstr "Twittern" |
351 | 359 | ||
352 | msgid "your password has been updated" | 360 | msgid "Email" |
353 | msgstr "Dein Passwort wurde geändert" | 361 | msgstr "Email" |
354 | 362 | ||
355 | msgid "" | 363 | msgid "shaarli" |
356 | "the two fields have to be filled & the password must be the same in the two " | 364 | msgstr "shaarli" |
357 | "fields" | ||
358 | msgstr "Beide Felder müssen mit selbem Inhalt ausgefüllt sein" | ||
359 | 365 | ||
360 | msgid "still using the \"" | 366 | msgid "flattr" |
361 | msgstr "nutze immernoch die \"" | 367 | msgstr "flattr" |
362 | 368 | ||
363 | msgid "that theme does not seem to be installed" | 369 | msgid "Does this article appear wrong?" |
364 | msgstr "dieses Theme scheint nicht installiert zu sein" | 370 | msgstr "Erscheint dieser Artikel nicht richtig?" |
365 | 371 | ||
366 | msgid "you have changed your theme preferences" | 372 | msgid "tags:" |
367 | msgstr "Du hast deine Theme Einstellungen geändert" | 373 | msgstr "schlagworte:" |
368 | 374 | ||
369 | msgid "that language does not seem to be installed" | 375 | msgid "Edit tags" |
370 | msgstr "Diese Sprache scheint nicht installiert zu sein" | 376 | msgstr "Schlagworte bearbeiten" |
371 | 377 | ||
372 | msgid "you have changed your language preferences" | 378 | msgid "save link!" |
373 | msgstr "Du hast deine Spracheinstellungen geändert" | 379 | msgstr "link speichern!" |
374 | 380 | ||
375 | msgid "login failed: you have to fill all fields" | 381 | msgid "home" |
376 | msgstr "Anmeldung fehlgeschlagen: Alle Felder müssen ausgefüllt werden" | 382 | msgstr "start" |
377 | 383 | ||
378 | msgid "welcome to your wallabag" | 384 | msgid "tags" |
379 | msgstr "Willkommen bei deiner wallabag" | 385 | msgstr "schlagworte" |
380 | 386 | ||
381 | msgid "login failed: bad login or password" | 387 | msgid "logout" |
382 | msgstr "Anmeldung fehlgeschlagen: Falscher Benutzername oder Passwort" | 388 | msgstr "abmelden" |
383 | 389 | ||
384 | msgid "" | 390 | msgid "powered by" |
385 | "import from instapaper completed. You have to execute the cron to fetch " | 391 | msgstr "Angetrieben von" |
386 | "content." | ||
387 | msgstr "" | ||
388 | "Import aus Instapaper vollständig. Führe den cronjob aus um den Inhalt " | ||
389 | "abzurufen." | ||
390 | 392 | ||
391 | msgid "" | 393 | msgid "debug mode is on so cache is off." |
392 | "import from pocket completed. You have to execute the cron to fetch content." | 394 | msgstr "Der Debug-Modus ist aktiviert, also ist der Cache deaktiviert." |
393 | msgstr "" | ||
394 | "Import aus Pocket vollständig. Führe den cronjob aus um den Inhalt abzurufen." | ||
395 | 395 | ||
396 | msgid "" | 396 | msgid "your wallabag version:" |
397 | "import from Readability completed. You have to execute the cron to fetch " | 397 | msgstr "Deine wallabag-Version:" |
398 | "content." | ||
399 | msgstr "" | ||
400 | "Import aus Readability vollständig. Führe den cronjob aus um den Inhalt " | ||
401 | "abzurufen." | ||
402 | 398 | ||
403 | msgid "" | 399 | msgid "storage:" |
404 | "import from Poche completed. You have to execute the cron to fetch content." | 400 | msgstr "speicher:" |
405 | msgstr "" | ||
406 | "Import aus Poche vollständig. Führe den cronjob aus um den Inhalt abzurufen." | ||
407 | 401 | ||
408 | msgid "Unknown import provider." | 402 | msgid "save a link" |
409 | msgstr "Unbekannter Import Anbieter." | 403 | msgstr "einen link speichern" |
410 | 404 | ||
411 | msgid "Could not find required \"" | 405 | msgid "back to home" |
412 | msgstr "Nicht gefunden: \"" | 406 | msgstr "zurück zur startseite" |
413 | 407 | ||
414 | msgid "File uploaded. You can now execute import." | 408 | msgid "toggle mark as read" |
415 | msgstr "Datei hochgeladen. Du kannst nun importieren." | 409 | msgstr "als gelesen/ungelesen markieren" |
416 | 410 | ||
417 | msgid "Error while importing file. Do you have access to upload it?" | 411 | msgid "tweet" |
418 | msgstr "Fehler beim Importieren. Hast du das Recht zum Hochladen?" | 412 | msgstr "tweet" |
419 | 413 | ||
420 | msgid "User with this id (" | 414 | msgid "email" |
421 | msgstr "Nutzer mit dieser id (" | 415 | msgstr "email" |
422 | 416 | ||
423 | msgid "Uh, there is a problem while generating feeds." | 417 | msgid "this article appears wrong?" |
424 | msgstr "Oh, es gab ein Problem beim Erstellen des Feeds." | 418 | msgstr "dieser artikel erscheint falsch?" |
425 | 419 | ||
426 | msgid "Cache deleted." | 420 | msgid "No link available here!" |
427 | msgstr "Cache gelöscht" | 421 | msgstr "Kein Link verfügbar!" |
428 | 422 | ||
429 | msgid "Oops, it seems you don't have PHP 5." | 423 | msgid "Poching a link" |
430 | msgstr "Oops, es scheint als würde PHP 5 fehlen." | 424 | msgstr "Link speichern" |
431 | 425 | ||
432 | msgid "wallabag, a read it later open source system" | 426 | msgid "by filling this field" |
433 | msgstr "wallabag, ein Später-Lesen Open Source System" | 427 | msgstr "mit dem Ausfüllen dieses Feldes" |
434 | 428 | ||
435 | msgid "login failed: user doesn't exist" | 429 | msgid "bookmarklet: drag & drop this link to your bookmarks bar" |
436 | msgstr "Anmeldung fehlgeschlagen: Benutzer existiert nicht" | 430 | msgstr "Bookmarklet: Drag & drop diesen Link in deine Lesezeichen" |
437 | 431 | ||
438 | #~ msgid "You can enter multiple tags, separated by commas." | 432 | msgid "Drag & drop this link to your bookmarks bar:" |
439 | #~ msgstr "Du kannst mehrere Tags, durch Kommata getrennt, eingeben." | 433 | msgstr "Drag & drop diesen Link in deine Lesezeichen:" |
440 | 434 | ||
441 | #~ msgid "return to article" | 435 | msgid "your version" |
442 | #~ msgstr "zurück zum Artikel" | 436 | msgstr "deine Version" |
443 | 437 | ||
444 | #, fuzzy | 438 | msgid "latest stable version" |
445 | #~ msgid "favoris" | 439 | msgstr "letzte stabile Version" |
446 | #~ msgstr "Favoriten" | ||
447 | 440 | ||
448 | #~ msgid "mark all the entries as read" | 441 | msgid "a more recent stable version is available." |
449 | #~ msgstr "Markiere alle als gelesen" | 442 | msgstr "Eine aktuellere Version ist verfügbar." |
450 | 443 | ||
451 | #~ msgid "Back to top" | 444 | msgid "you are up to date." |
452 | #~ msgstr "Nach Oben" | 445 | msgstr "Du bist auf dem aktuellsten Stand." |
453 | 446 | ||
454 | #~ msgid "Mark as read" | 447 | msgid "latest dev version" |
455 | #~ msgstr "Als gelesen markieren" | 448 | msgstr "Letzte Entwickler-Version" |
456 | 449 | ||
457 | #~ msgid "Favorite" | 450 | msgid "a more recent development version is available." |
458 | #~ msgstr "Favoriten" | 451 | msgstr "Eine neuere Entwickler-Version ist verfügbar." |
459 | 452 | ||
460 | #~ msgid "Toggle favorite" | 453 | msgid "Please execute the import script locally, it can take a very long time." |
461 | #~ msgstr "Favorit" | 454 | msgstr "Führe das Import-Skript lokal aus, da der Import sehr lange dauern kann." |
462 | 455 | ||
463 | #~ msgid "Delete" | 456 | msgid "More infos in the official doc:" |
464 | #~ msgstr "Löschen" | 457 | msgstr "Mehr Informationen in der offiziellen Dokumentation:" |
465 | 458 | ||
466 | #~ msgid "Tweet" | 459 | msgid "import from Pocket" |
467 | #~ msgstr "Twittern" | 460 | msgstr "Aus Pocket importieren" |
468 | 461 | ||
469 | #~ msgid "Email" | 462 | msgid "import from Readability" |
470 | #~ msgstr "per E-Mail senden" | 463 | msgstr "Aus Readability importieren" |
471 | 464 | ||
472 | #~ msgid "shaarli" | 465 | msgid "import from Instapaper" |
473 | #~ msgstr "Shaarli" | 466 | msgstr "Aus Instapaper importieren" |
474 | 467 | ||
475 | #~ msgid "flattr" | 468 | msgid "Tags" |
476 | #~ msgstr "flattr" | 469 | msgstr "Schlagworte" |
477 | 470 | ||
478 | #~ msgid "Does this article appear wrong?" | 471 | msgid "Untitled" |
479 | #~ msgstr "Erscheint dieser Artikel falsch?" | 472 | msgstr "Untitled" |
480 | 473 | ||
481 | #~ msgid "Edit tags" | 474 | msgid "the link has been added successfully" |
482 | #~ msgstr "Tags bearbeiten" | 475 | msgstr "Der Link wurde erfolgreich hinzugefügt" |
483 | 476 | ||
484 | #~ msgid "Start typing for auto complete." | 477 | msgid "error during insertion : the link wasn't added" |
485 | #~ msgstr "Beginne zu tippen für die Autovervollständigung." | 478 | msgstr "Fehler während des Imports: Der Link wurde nicht hinzugefügt." |
486 | 479 | ||
487 | #~ msgid "Return home" | 480 | msgid "the link has been deleted successfully" |
488 | #~ msgstr "Zurück zum Start" | 481 | msgstr "Der Link wurde erfolgreich gelöscht" |
489 | 482 | ||
490 | #~ msgid "tags:" | 483 | msgid "the link wasn't deleted" |
491 | #~ msgstr "Tags:" | 484 | msgstr "Der Link wurde nicht gelöscht." |
492 | 485 | ||
493 | #~ msgid "login to your wallabag" | 486 | msgid "Article not found!" |
494 | #~ msgstr "Bei wallabag anmelden" | 487 | msgstr "Artikel nicht gefunden!" |
495 | 488 | ||
496 | #~ msgid "you are in demo mode, some features may be disabled." | 489 | msgid "previous" |
497 | #~ msgstr "" | 490 | msgstr "vorherige" |
498 | #~ "Du befindest dich im Demomodus, einige Funktionen könnten deaktiviert " | ||
499 | #~ "sein." | ||
500 | 491 | ||
501 | #~ msgid "Login" | 492 | msgid "next" |
502 | #~ msgstr "Benutzername" | 493 | msgstr "nächste" |
503 | 494 | ||
504 | #~ msgid "Stay signed in" | 495 | msgid "in demo mode, you can't update your password" |
505 | #~ msgstr "Angemeldet bleiben" | 496 | msgstr "Im Demo-Modus kannst du as Kennwort nicht aktualisieren." |
506 | 497 | ||
507 | #~ msgid "(Do not check on public computers)" | 498 | msgid "your password has been updated" |
508 | #~ msgstr "(nicht auf einem öffentlichen Computer anhaken)" | 499 | msgstr "Dein Passwort wurde aktualisiert" |
509 | 500 | ||
510 | #~ msgid "plop" | 501 | msgid "the two fields have to be filled & the password must be the same in the two fields" |
511 | #~ msgstr "plop" | 502 | msgstr "Beide Felder müssen ausgefüllt sein und das gleiche Passwort beinhalten" |
512 | 503 | ||
513 | #~ msgid "Login to wallabag" | 504 | msgid "still using the \"" |
514 | #~ msgstr "Bei wallabag anmelden" | 505 | msgstr "nutze immernoch die \"" |
515 | 506 | ||
516 | #~ msgid "Username" | 507 | msgid "that theme does not seem to be installed" |
517 | #~ msgstr "Benutzername" | 508 | msgstr "Dieses Theme scheint nicht installiert zu sein." |
518 | 509 | ||
519 | #~ msgid "Sign in" | 510 | msgid "you have changed your theme preferences" |
520 | #~ msgstr "Einloggen" | 511 | msgstr "Du hast deine Theme-Einstellungen geändert" |
521 | 512 | ||
522 | #~ msgid "Enter your search here" | 513 | msgid "that language does not seem to be installed" |
523 | #~ msgstr "Gib hier deine Suchanfrage ein" | 514 | msgstr "Diese Sprache scheint nicht installiert zu sein" |
524 | 515 | ||
525 | #~ msgid "installation" | 516 | msgid "you have changed your language preferences" |
526 | #~ msgstr "Installieren" | 517 | msgstr "Du hast deine Spracheinstellungen geändert" |
527 | 518 | ||
528 | #~ msgid "install your wallabag" | 519 | msgid "login failed: you have to fill all fields" |
529 | #~ msgstr "Installiere deine wallabag" | 520 | msgstr "Anmeldung fehlgeschlagen: Du musst alle Felder ausfüllen" |
530 | 521 | ||
531 | #~ msgid "" | 522 | msgid "welcome to your wallabag" |
532 | #~ "wallabag is still not installed. Please fill the below form to install " | 523 | msgstr "Willkommen in deiner wallabag" |
533 | #~ "it. Don't hesitate to <a href='http://doc.wallabag.org/'>read the " | ||
534 | #~ "documentation on wallabag website</a>." | ||
535 | #~ msgstr "" | ||
536 | #~ "wallabag ist noch nicht installiert. Bitte fülle die Felder unten aus, um " | ||
537 | #~ "die Installation durchzuführen. Zögere nicht, <a href='http://doc." | ||
538 | #~ "wallabag.org/'>die Dokumentation auf der Website von wallabag zu lesen, " | ||
539 | #~ "falls du Probleme haben solltest." | ||
540 | 524 | ||
541 | #~ msgid "Repeat your password" | 525 | msgid "login failed: bad login or password" |
542 | #~ msgstr "Wiederhole dein Passwort" | 526 | msgstr "Anmeldung fehlgeschlagen: Falscher Benutzername oder falsches Passwort" |
543 | 527 | ||
544 | #~ msgid "Install" | 528 | msgid "import from instapaper completed" |
545 | #~ msgstr "Installieren" | 529 | msgstr "Import aus Instapaper abgeschlossen" |
546 | 530 | ||
547 | #~ msgid "No link available here!" | 531 | msgid "import from pocket completed" |
548 | #~ msgstr "Kein Link verfügbar!" | 532 | msgstr "Import aus Pocket abgeschlossen" |
549 | 533 | ||
550 | #~ msgid "toggle mark as read" | 534 | msgid "import from Readability completed. " |
551 | #~ msgstr "Als gelesen markieren" | 535 | msgstr "Import aus Readability abgeschlossen." |
552 | 536 | ||
553 | #~ msgid "" | 537 | msgid "import from Poche completed. " |
554 | #~ "You can <a href='wallabag_compatibility_test.php'>check your " | 538 | msgstr "Import aus wallabag abgeschlossen." |
555 | #~ "configuration here</a>." | ||
556 | #~ msgstr "" | ||
557 | #~ "Du kannst deine Konfiguration <a href='wallabag_compatibility_test." | ||
558 | #~ "php'>hier testen</a>." | ||
559 | 539 | ||
560 | #~ msgid "back to home" | 540 | msgid "Unknown import provider." |
561 | #~ msgstr "züruck zur Hauptseite" | 541 | msgstr "Unbekannter Import-Provider." |
562 | 542 | ||
563 | #~ msgid "tweet" | 543 | msgid "Incomplete inc/poche/define.inc.php file, please define \"" |
564 | #~ msgstr "Twittern" | 544 | msgstr "Die Datei /inc/poche/define.inc.php ist unvollständig, bitte definiere \"" |
565 | 545 | ||
566 | #~ msgid "email" | 546 | msgid "Could not find required \"" |
567 | #~ msgstr "senden per E-Mail" | 547 | msgstr "Nicht gefunden: \"" |
568 | 548 | ||
569 | #~ msgid "this article appears wrong?" | 549 | msgid "Uh, there is a problem while generating feeds." |
570 | #~ msgstr "dieser Artikel erscheint falsch?" | 550 | msgstr "Oh, es gibt ein Problem bei dem Generieren der Feeds." |
571 | 551 | ||
572 | #~ msgid "Poching a link" | 552 | msgid "Cache deleted." |
573 | #~ msgstr "Poche einen Link" | 553 | msgstr "Cache geleert." |
574 | 554 | ||
575 | #~ msgid "by filling this field" | 555 | msgid "Oops, it seems you don't have PHP 5." |
576 | #~ msgstr "durch das ausfüllen dieses Feldes:" | 556 | msgstr "Ups, es sieht so aus, als ob du nicht PHP 5 hast." |
577 | 557 | ||
578 | #~ msgid "bookmarklet: drag & drop this link to your bookmarks bar" | 558 | msgid "Add user" |
579 | #~ msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen-Leiste" | 559 | msgstr "Benutzer hinzufügen" |
580 | 560 | ||
581 | #~ msgid "your version" | 561 | msgid "Add a new user :" |
582 | #~ msgstr "Deine Version" | 562 | msgstr "Neuen Benutzer hinzufügen:" |
583 | 563 | ||
584 | #~ msgid "latest stable version" | 564 | msgid "Login for new user" |
585 | #~ msgstr "Neuste stabile Version" | 565 | msgstr "Benutzername des neuen Benutzers" |
586 | 566 | ||
587 | #~ msgid "a more recent stable version is available." | 567 | msgid "Password for new user" |
588 | #~ msgstr "Eine neuere stabile Version ist verfügbar." | 568 | msgstr "Passwort des neuen Benutzers" |
589 | 569 | ||
590 | #~ msgid "you are up to date." | 570 | msgid "Email for new user (not required)" |
591 | #~ msgstr "Du bist auf den neuesten Stand." | 571 | msgstr "E-Mail-Adresse des neuen Benutzers (nicht erforderlich)" |
592 | 572 | ||
593 | #~ msgid "latest dev version" | 573 | msgid "Send" |
594 | #~ msgstr "Neuste Entwicklungsversion" | 574 | msgstr "Senden" |
595 | 575 | ||
596 | #~ msgid "a more recent development version is available." | 576 | msgid "Delete account" |
597 | #~ msgstr "Eine neuere Entwicklungsversion ist verfügbar." | 577 | msgstr "Account löschen" |
598 | 578 | ||
599 | #~ msgid "" | 579 | msgid "You can delete your account by entering your password and validating." |
600 | #~ "Please execute the import script locally, it can take a very long time." | 580 | msgstr "Du kannst deinen Account löschen, indem du dein Kennwort eintippst und validierst." |
601 | #~ msgstr "" | ||
602 | #~ "Bitte führe das Import Script lokal aus, dies kann eine Weile dauern." | ||
603 | 581 | ||
604 | #~ msgid "More infos in the official doc:" | 582 | msgid "Be careful, data will be erased forever (that is a very long time)." |
605 | #~ msgstr "Mehr Informationen in der offiziellen Dokumentation:" | 583 | msgstr "Pass auf, die Daten werden für immer gelöscht werden (eine sehr lange Zeit)." |
606 | 584 | ||
607 | #~ msgid "import from Pocket" | 585 | msgid "Type here your password" |
608 | #~ msgstr "Import aus Pocket" | 586 | msgstr "Kennwort hier eintippen" |
609 | 587 | ||
610 | #~ msgid "(you must have a %s file on your server)" | 588 | msgid "You are the only user, you cannot delete your own account." |
611 | #~ msgstr "(du brauchst eine %s Datei auf deinem Server)" | 589 | msgstr "Du kannst deinen Account nicht löschen, weil du der einzige Benutzer bist." |
612 | 590 | ||
613 | #~ msgid "import from Readability" | 591 | msgid "To completely remove wallabag, delete the wallabag folder on your web server (and eventual databases)." |
614 | #~ msgstr "Import aus Readability" | 592 | msgstr "Um wallabag komplett zu entfernen, lösche den wallabag-Ordner und die Datenbank(en) von deinem Webserver." |
615 | 593 | ||
616 | #~ msgid "import from Instapaper" | 594 | msgid "Enter your search here" |
617 | #~ msgstr "Import aus Instapaper" | 595 | msgstr "Suchbegriff hier eintippen" |
618 | 596 | ||
619 | #~ msgid "You can also create a cron task:" | 597 | msgid "Tag these results as" |
620 | #~ msgstr "Du kannst auch einen cronjob anlegen:" | 598 | msgstr "Diese Ergebnisse verschlagworten mit" |
621 | 599 | ||
622 | #~ msgid "" | 600 | # ebook |
623 | #~ "Please execute the import script locally as it can take a very long time." | 601 | msgid "Fancy an E-Book ?" |
624 | #~ msgstr "" | 602 | msgstr "Willst du ein E-Book?" |
625 | #~ "Bitte führe das Import Script lokal aus, da dies eine Weile dauern kann." | ||
626 | 603 | ||
627 | #~ msgid "More info in the official documentation:" | 604 | msgid "Click on <a href=\"./?epub&method=all\" title=\"Generate ePub\">this link</a> to get all your articles in one ebook (ePub 3 format)." |
628 | #~ msgstr "Mehr Informationen in der offiziellen Dokumentation:" | 605 | msgstr "Klicke auf <a href=\"./?epub&method=all\" title=\"EPUB erstellen\">diesen Link</a>, um alle Artikel in ein E-Book (EPUB 3-Format) zu exportieren." |
629 | 606 | ||
630 | #~ msgid "import from instapaper completed" | 607 | msgid "This can <b>take a while</b> and can <b>even fail</b> if you have too many articles, depending on your server configuration." |
631 | #~ msgstr "Import aus Instapaper erfolgreich" | 608 | msgstr "Dies kann <b>eine Weile dauern</b> oder <b>sogar fehlschlagen</b>, wenn du zu viele Artikel hast, abhängig von deiner Server-Konfiguration." |
632 | 609 | ||
633 | #~ msgid "import from pocket completed" | 610 | msgid "Download the articles from this tag in an epub" |
634 | #~ msgstr "Import aus Pocket erfolgreich" | 611 | msgstr "Die Artikel von diesem Schlagwort als EPUB herunterladen" |
635 | 612 | ||
636 | #~ msgid "import from Poche completed. " | 613 | msgid "Download the articles from this search in an epub" |
637 | #~ msgstr "Import aus Poche erfolgreich" | 614 | msgstr "Alle Artikel aus dieser Suche als EPUB herunterladen" |
638 | 615 | ||
639 | #~ msgid "Incomplete inc/poche/define.inc.php file, please define \"" | 616 | msgid "Download the articles from this category in an epub" |
640 | #~ msgstr "Unvollständige inc/poche/define.inc.php Datei, bitte setze \"" | 617 | msgstr "Alle Artikel aus dieser Kategorie als EPUB herunterladen" |
641 | 618 | ||
642 | #~ msgid "poche it!" | 619 | #~ msgid "poche it!" |
643 | #~ msgstr "Poche es!" | 620 | #~ msgstr "poche it!" |
644 | 621 | ||
645 | #~ msgid "Updating poche" | 622 | #~ msgid "Updating poche" |
646 | #~ msgstr "Poche aktualisieren" | 623 | #~ msgstr "Updating poche" |
647 | 624 | ||
648 | #~ msgid "create an issue" | 625 | #~ msgid "create an issue" |
649 | #~ msgstr "ein Ticket erstellen" | 626 | #~ msgstr "create an issue" |
650 | 627 | ||
651 | #~ msgid "or" | 628 | #~ msgid "or" |
652 | #~ msgstr "oder" | 629 | #~ msgstr "or" |
653 | 630 | ||
654 | #~ msgid "contact us by mail" | 631 | #~ msgid "contact us by mail" |
655 | #~ msgstr "kontaktieren Sie uns per E-Mail" | 632 | #~ msgstr "contact us by mail" |
656 | 633 | ||
657 | #~ msgid "your poche version:" | 634 | #~ msgid "your poche version:" |
658 | #~ msgstr "Deine Poche Version" | 635 | #~ msgstr "your poche version:" |
diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo index eed260b2..83f397a0 100644 --- a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo +++ b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo | |||
Binary files differ | |||
diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po index 4bdb3cd5..fef31208 100644 --- a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po +++ b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po | |||
@@ -250,7 +250,7 @@ msgid "" | |||
250 | "your config file: IMPORT_LIMIT (how many articles are fetched at once) and " | 250 | "your config file: IMPORT_LIMIT (how many articles are fetched at once) and " |
251 | "IMPORT_DELAY (delay between fetch of next batch of articles)." | 251 | "IMPORT_DELAY (delay between fetch of next batch of articles)." |
252 | msgstr "" | 252 | msgstr "" |
253 | "Sélectionner le fichier à importer sur votre disque dur, et pressez la " | 253 | "Sélectionnez le fichier à importer sur votre disque dur, et pressez la " |
254 | "bouton « Importer » ci-dessous.<br />wallabag analysera votre fichier, " | 254 | "bouton « Importer » ci-dessous.<br />wallabag analysera votre fichier, " |
255 | "ajoutera toutes les URL trouvées et commencera à télécharger les contenus si " | 255 | "ajoutera toutes les URL trouvées et commencera à télécharger les contenus si " |
256 | "nécessaire.<br />Le processus de téléchargement est contrôlé par deux " | 256 | "nécessaire.<br />Le processus de téléchargement est contrôlé par deux " |
diff --git a/themes/baggy/home.twig b/themes/baggy/home.twig index abebe455..93515080 100755 --- a/themes/baggy/home.twig +++ b/themes/baggy/home.twig | |||
@@ -59,7 +59,11 @@ | |||
59 | {{ block('pager') }} | 59 | {{ block('pager') }} |
60 | {% if view == 'home' %}{% if nb_results > 1 %}<p><a title="{% trans "Mark all the entries as read" %}" href="./?action=archive_all">{% trans "Mark all the entries as read" %}</a></p>{% endif %}{% endif %} | 60 | {% if view == 'home' %}{% if nb_results > 1 %}<p><a title="{% trans "Mark all the entries as read" %}" href="./?action=archive_all">{% trans "Mark all the entries as read" %}</a></p>{% endif %}{% endif %} |
61 | {% if searchterm is defined %}<a title="{% trans "Tag these results as" %} {{ searchterm }}" href="./?action=add_tag&search={{ searchterm }}">{% trans "Tag these results as" %} {{ searchterm }}</a>{% endif %}<br /> | 61 | {% if searchterm is defined %}<a title="{% trans "Tag these results as" %} {{ searchterm }}" href="./?action=add_tag&search={{ searchterm }}">{% trans "Tag these results as" %} {{ searchterm }}</a>{% endif %}<br /> |
62 | 62 | ||
63 | {% if searchterm is defined %}<a title="{% trans "Delete results matching" %} {{ searchterm }}" href="./?action=delete&search={{ searchterm }}">{% trans "Delete results matching" %} {{ searchterm }}</a>{% endif %}<br /> | ||
64 | |||
65 | {% if tag %}<a title="{% trans "Mark all articles from this tag as read" %}" href="./?action=toggle_archive&tag_id={{ tag.id }}">{% trans "Mark all articles from this tag as read" %}</a><br />{% endif %} | ||
66 | |||
63 | {% if tag %} | 67 | {% if tag %} |
64 | {% if constant('EPUB') == 1 %}<a title="{% trans "Download the articles from this tag in an epub file" %}" href="./?epub&method=tag&value={{ tag.value }}">{% trans "Download as ePub3" %}</a>{% endif %} | 68 | {% if constant('EPUB') == 1 %}<a title="{% trans "Download the articles from this tag in an epub file" %}" href="./?epub&method=tag&value={{ tag.value }}">{% trans "Download as ePub3" %}</a>{% endif %} |
65 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this tag in a mobi file" %}" href="./?mobi&method=tag&value={{ tag.value }}">{% trans "Download as Mobi" %}</a>{% endif %} | 69 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this tag in a mobi file" %}" href="./?mobi&method=tag&value={{ tag.value }}">{% trans "Download as Mobi" %}</a>{% endif %} |
diff --git a/themes/courgette/config.twig b/themes/courgette/config.twig deleted file mode 100755 index 6b0fa308..00000000 --- a/themes/courgette/config.twig +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | {% extends "layout.twig" %} | ||
2 | |||
3 | {% block title %}{% trans "config" %}{% endblock %} | ||
4 | {% block menu %} | ||
5 | {% include '_menu.twig' %} | ||
6 | {% endblock %} | ||
7 | {% block content %} | ||
8 | <div id="config"> | ||
9 | <h2>{% trans "Poching a link" %}</h2> | ||
10 | <p>{% trans "There are several ways to save an article:" %} (<a class="special" href="http://doc.wallabag.org" title="{% trans "read the documentation" %}">?</a>)</p> | ||
11 | <ul> | ||
12 | <li>Firefox: <a href="https://addons.mozilla.org/firefox/addon/wallabag/" title="download the firefox extension">{% trans "download the extension" %}</a></li> | ||
13 | <li>Chrome: <a href="http://doc.wallabag.org/doku.php?id=users:chrome_extension" title="download the chrome extension">{% trans "download the extension" %}</a></li> | ||
14 | <li>Android: <a href="https://f-droid.org/app/fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via F-Droid" %}</a> {% trans " or " %} <a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via Google Play" %}</a></li> | ||
15 | <li>iOS: <a href="https://itunes.apple.com/app/wallabag/id828331015?mt=8" title="download the iOS application">{% trans "download the application" %}</a></li> | ||
16 | <li>Windows Phone: <a href="http://www.windowsphone.com/en-us/store/app/wallabag/ff890514-348c-4d0b-9b43-153fff3f7450" title="download the window phone application">{% trans "download the application" %}</a></li> | ||
17 | <li> | ||
18 | <form method="get" action="index.php"> | ||
19 | <label class="addurl" for="plainurl">{% trans "by filling this field" %}:</label> | ||
20 | <input required placeholder="Ex:mywebsite.com/article" class="addurl" id="plainurl" name="plainurl" type="url" /> | ||
21 | <input type="submit" value="{% trans "bag it!" %}" /> | ||
22 | </form> | ||
23 | </li> | ||
24 | <li>{% trans "bookmarklet: drag & drop this link to your bookmarks bar" %} <a id="bookmarklet" ondragend="this.click();" title="i am a bookmarklet, use me !" href="javascript:if(top['bookmarklet-url@wallabag.org']){top['bookmarklet-url@wallabag.org'];}else{(function(){var%20url%20=%20location.href%20||%20url;window.open('{{ poche_url }}?action=add&url='%20+%20btoa(url),'_self');})();void(0);}">{% trans "bag it!" %}</a></li> | ||
25 | </ul> | ||
26 | |||
27 | <h2>{% trans "Upgrading wallabag" %}</h2> | ||
28 | <ul> | ||
29 | <li>{% trans "your version" %} : <strong>{{ constant('POCHE') }}</strong></li> | ||
30 | <li>{% trans "latest stable version" %} : {{ prod }}. {% if compare_prod == -1 %}<strong><a href="http://wallabag.org/">{% trans "a more recent stable version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li> | ||
31 | {% if constant('DEBUG_POCHE') == 1 %}<li>{% trans "latest dev version" %} : {{ dev }}. {% if compare_dev == -1 %}<strong><a href="http://wallabag.org/">{% trans "a more recent development version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>{% endif %} | ||
32 | </ul> | ||
33 | |||
34 | <h2>{% trans "Change your theme" %}</h2> | ||
35 | <form method="post" action="?updatetheme" name="changethemeform"> | ||
36 | <fieldset class="w500p"> | ||
37 | <div class="row"> | ||
38 | <label class="col w150p" for="theme">{% trans "Theme:" %}</label> | ||
39 | <select class="col" id="theme" name="theme"> | ||
40 | {% for key, theme in themes %} | ||
41 | <option value="{{ key }}" {{ theme.current ? 'selected' : '' }}>{{ theme.name }}</option> | ||
42 | {% endfor %} | ||
43 | </select> | ||
44 | </div> | ||
45 | <div class="row mts txtcenter"> | ||
46 | <button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button> | ||
47 | </div> | ||
48 | </fieldset> | ||
49 | <input type="hidden" name="returnurl" value="{{ referer }}"> | ||
50 | <input type="hidden" name="token" value="{{ token }}"> | ||
51 | </form> | ||
52 | |||
53 | <h2>{% trans "Change your password" %}</h2> | ||
54 | <form method="post" action="?config" name="loginform"> | ||
55 | <fieldset class="w500p"> | ||
56 | <div class="row"> | ||
57 | <label class="col w150p" for="password">{% trans "New password:" %}</label> | ||
58 | <input class="col" type="password" id="password" name="password" placeholder="{% trans "Password" %}" tabindex="2"> | ||
59 | </div> | ||
60 | <div class="row"> | ||
61 | <label class="col w150p" for="password_repeat">{% trans "Repeat your new password:" %}</label> | ||
62 | <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="{% trans "Password" %}" tabindex="3"> | ||
63 | </div> | ||
64 | <div class="row mts txtcenter"> | ||
65 | <button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button> | ||
66 | </div> | ||
67 | </fieldset> | ||
68 | <input type="hidden" name="returnurl" value="{{ referer }}"> | ||
69 | <input type="hidden" name="token" value="{{ token }}"> | ||
70 | </form> | ||
71 | |||
72 | <h2>{% trans "Import" %}</h2> | ||
73 | <p>{% trans "Please execute the import script locally, it can take a very long time." %}</p> | ||
74 | <p>{% trans "More infos in the official doc:" %} <a href="http://doc.wallabag.org">wallabag.org</a></p> | ||
75 | <ul> | ||
76 | <li><a href="./?import&from=pocket">{% trans "import from Pocket" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('POCKET_FILE')) }}</li> | ||
77 | <li><a href="./?import&from=readability">{% trans "import from Readability" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('READABILITY_FILE')) }}</li> | ||
78 | <li><a href="./?import&from=instapaper">{% trans "import from Instapaper" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('INSTAPAPER_FILE')) }}</li> | ||
79 | </ul> | ||
80 | |||
81 | <h2>{% trans "Export your wallabag data" %}</h2> | ||
82 | <p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your wallabag data." %}</p> | ||
83 | |||
84 | <h2>{% trans "Fancy an E-Book ?" %}</h2> | ||
85 | <p>{% trans "Click to get all your articles in one ebook :" %} | ||
86 | <ul> | ||
87 | <li><a href="./?epub&method=all" title="Generate ePub file">ePub 3</a></li> | ||
88 | <li><a href="./?mobi&method=all" title="Generate Mobi file">Mobi</a></li> | ||
89 | <li><a href="./?pdf&method=all" title="Generate PDF file">PDF</a></li> | ||
90 | </ul> | ||
91 | |||
92 | <br>{% trans "This can <b>take a while</b> and can <b>even fail</b> if you have too many articles, depending on your server configuration." %}</p> | ||
93 | |||
94 | <h2>{% trans 'Add user' %}</h2> | ||
95 | <p>{% trans 'Add a new user :' %}</p> | ||
96 | <form method="post" action="?newuser"> | ||
97 | <fieldset class="w500p"> | ||
98 | <div class="row"> | ||
99 | <label class="col w150p" for="newusername">{% trans 'Login for new user' %}</label> | ||
100 | <input class="col" type="text" id="newusername" name="newusername" placeholder="{% trans 'Login' %}"> | ||
101 | </div> | ||
102 | <div class="row"> | ||
103 | <label class="col w150p" for="password4newuser">{% trans "Password for new user" %}</label> | ||
104 | <input class="col" type="password" id="password4newuser" name="password4newuser" placeholder="{% trans "Password" %}"> | ||
105 | </div> | ||
106 | <div class="row mts txtcenter"> | ||
107 | <button type="submit">{% trans "Send" %}</button> | ||
108 | </div> | ||
109 | </fieldset> | ||
110 | </form> | ||
111 | |||
112 | <h2>{% trans "Delete account" %}</h2> | ||
113 | {% if not only_user %}<form method="post" action="?deluser"> | ||
114 | <p>{% trans "You can delete your account by entering your password and validating." %}<br /><b>{% trans "Be careful, data will be erased forever (that is a very long time)." %}</b></p> | ||
115 | <fieldset class="w500p"> | ||
116 | <div class="row"> | ||
117 | <label class="col w150p" for="password4deletinguser">{% trans "Type here your password" %}</label> | ||
118 | <input class="col" type="password" id="password4deletinguser" name="password4deletinguser" placeholder="{% trans "Password" %}"> | ||
119 | </div> | ||
120 | <div class="row mts txtcenter"> | ||
121 | <button type="submit">{% trans "Send" %}</button> | ||
122 | </div> | ||
123 | </form> | ||
124 | {% else %}<p>{% trans "You are the only user, you cannot delete your own account." %}<br /> | ||
125 | {% trans "To completely remove wallabag, delete the wallabag folder on your web server." %}</p>{% endif %} | ||
126 | </div> | ||
127 | {% endblock %} | ||
diff --git a/themes/default/home.twig b/themes/default/home.twig index c5db5802..b9000559 100755 --- a/themes/default/home.twig +++ b/themes/default/home.twig | |||
@@ -59,7 +59,11 @@ | |||
59 | {{ block('pager') }} | 59 | {{ block('pager') }} |
60 | {% if view == 'home' %}{% if nb_results > 1 %}<p><a title="{% trans "Mark all the entries as read" %}" href="./?action=archive_all">{% trans "Mark all the entries as read" %}</a></p>{% endif %}{% endif %} | 60 | {% if view == 'home' %}{% if nb_results > 1 %}<p><a title="{% trans "Mark all the entries as read" %}" href="./?action=archive_all">{% trans "Mark all the entries as read" %}</a></p>{% endif %}{% endif %} |
61 | {% if searchterm is defined %}<a title="{% trans "Tag these results as" %} {{ searchterm }}" href="./?action=add_tag&search={{ searchterm }}">{% trans "Tag these results as" %} {{ searchterm }}</a>{% endif %}<br /> | 61 | {% if searchterm is defined %}<a title="{% trans "Tag these results as" %} {{ searchterm }}" href="./?action=add_tag&search={{ searchterm }}">{% trans "Tag these results as" %} {{ searchterm }}</a>{% endif %}<br /> |
62 | 62 | ||
63 | {% if searchterm is defined %}<a title="{% trans "Delete results matching" %} {{ searchterm }}" href="./?action=delete&search={{ searchterm }}">{% trans "Delete results matching" %} {{ searchterm }}</a>{% endif %}<br /> | ||
64 | |||
65 | {% if tag %}<a title="{% trans "Mark all articles from this tag as read" %}" href="./?action=toggle_archive&tag_id={{ tag.id }}">{% trans "Mark all articles from this tag as read" %}</a><br />{% endif %} | ||
66 | |||
63 | {% if tag %} | 67 | {% if tag %} |
64 | {% if constant('EPUB') == 1 %}<a title="{% trans "Download the articles from this tag in an epub file" %}" href="./?epub&method=tag&value={{ tag.value }}">{% trans "Download as ePub3" %}</a>{% endif %} | 68 | {% if constant('EPUB') == 1 %}<a title="{% trans "Download the articles from this tag in an epub file" %}" href="./?epub&method=tag&value={{ tag.value }}">{% trans "Download as ePub3" %}</a>{% endif %} |
65 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this tag in a mobi file" %}" href="./?mobi&method=tag&value={{ tag.value }}">{% trans "Download as Mobi" %}</a>{% endif %} | 69 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this tag in a mobi file" %}" href="./?mobi&method=tag&value={{ tag.value }}">{% trans "Download as Mobi" %}</a>{% endif %} |
@@ -73,6 +77,6 @@ | |||
73 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this category in a mobi file" %}" href="./?mobi&method=category&value={{ view }}">{% trans "Download as Mobi" %}</a>{% endif %} | 77 | {% if constant('MOBI') == 1 %}<a title="{% trans "Download the articles from this category in a mobi file" %}" href="./?mobi&method=category&value={{ view }}">{% trans "Download as Mobi" %}</a>{% endif %} |
74 | {% if constant('PDF') == 1 %}<a title="{% trans "Download the articles from this category in a pdf file" %}" href="./?pdf&method=category&value={{ view }}">{% trans "Download as PDF" %}</a>{% endif %} | 78 | {% if constant('PDF') == 1 %}<a title="{% trans "Download the articles from this category in a pdf file" %}" href="./?pdf&method=category&value={{ view }}">{% trans "Download as PDF" %}</a>{% endif %} |
75 | {% endif %} | 79 | {% endif %} |
76 | 80 | ||
77 | {% endif %} | 81 | {% endif %} |
78 | {% endblock %} | 82 | {% endblock %} |