diff --git a/CREDITS.md b/CREDITS.md
index f1e9d7af4..e76c580d3 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -8,9 +8,10 @@ wallabag is based on :
* Twig http://twig.sensiolabs.org
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
* Pagination https://github.com/daveismyname/pagination
+* PHPePub https://github.com/Grandt/PHPePub/
wallabag is mainly developed by Nicolas Lœuillet under the MIT License
Thank you so much to @tcitworld and @mariroz.
-Contributors : https://github.com/wallabag/wallabag/graphs/contributors
\ No newline at end of file
+Contributors : https://github.com/wallabag/wallabag/graphs/contributors
diff --git a/composer.json b/composer.json
index 6c69e48de..a63f2893f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,4 +1,27 @@
{
+ "name": "wallabag/wallabag",
+ "type": "project",
+ "description": "open source self hostable read-it-later web application",
+ "keywords": ["read-it-later","read it later"],
+ "homepage": "https://github.com/wallabag/wallabag",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Lœuillet",
+ "email": "nicolas@loeuillet.org",
+ "homepage": "http://www.cdetc.fr",
+ "role": "Developer"
+ },
+ {
+ "name": "Thomas Citharel",
+ "homepage": "http://tcit.fr",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "email": "hello@wallabag.org",
+ "issues": "https://github.com/wallabag/wallabag/issues"
+ },
"require": {
"twig/twig": "1.*",
"twig/extensions": "1.0.*",
diff --git a/inc/3rdparty/libraries/MOBIClass/MOBI.php b/inc/3rdparty/libraries/MOBIClass/MOBI.php
index 17e718c12..df4826b04 100644
--- a/inc/3rdparty/libraries/MOBIClass/MOBI.php
+++ b/inc/3rdparty/libraries/MOBIClass/MOBI.php
@@ -1,5 +1,5 @@
\ No newline at end of file
+?>
diff --git a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php b/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php
deleted file mode 100644
index 1a8ec88cb..000000000
--- a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php
+++ /dev/null
@@ -1,110 +0,0 @@
-registerNodeClass('DOMElement', 'JSLikeHTMLElement');
-* $doc->loadHTML('
The story begins...
';
- * @endcode
- */
- public function __set($name, $value) {
- if ($name == 'innerHTML') {
- // first, empty the element
- for ($x=$this->childNodes->length-1; $x>=0; $x--) {
- $this->removeChild($this->childNodes->item($x));
- }
- // $value holds our new inner HTML
- if ($value != '') {
- $f = $this->ownerDocument->createDocumentFragment();
- // appendXML() expects well-formed markup (XHTML)
- $result = @$f->appendXML($value); // @ to suppress PHP warnings
- if ($result) {
- if ($f->hasChildNodes()) $this->appendChild($f);
- } else {
- // $value is probably ill-formed
- $f = new DOMDocument();
- $value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');
- // Using will generate a warning, but so will bad HTML
- // (and by this point, bad HTML is what we've got).
- // We use it (and suppress the warning) because an HTML fragment will
- // be wrapped around tags which we don't really want to keep.
- // Note: despite the warning, if loadHTML succeeds it will return true.
- $result = @$f->loadHTML(''.$value.' ');
- if ($result) {
- $import = $f->getElementsByTagName('htmlfragment')->item(0);
- foreach ($import->childNodes as $child) {
- $importedNode = $this->ownerDocument->importNode($child, true);
- $this->appendChild($importedNode);
- }
- } else {
- // oh well, we tried, we really did. :(
- // this element is now empty
- }
- }
- }
- } else {
- $trace = debug_backtrace();
- trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
- }
- }
-
- /**
- * Used for getting innerHTML like it's done in JavaScript:
- * @code
- * $string = $div->innerHTML;
- * @endcode
- */
- public function __get($name)
- {
- if ($name == 'innerHTML') {
- $inner = '';
- foreach ($this->childNodes as $child) {
- $inner .= $this->ownerDocument->saveXML($child);
- }
- return $inner;
- }
-
- $trace = debug_backtrace();
- trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
- return null;
- }
-
- public function __toString()
- {
- return '['.$this->tagName.']';
- }
-}
-?>
\ 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 915542435..000000000
--- a/inc/3rdparty/libraries/MOBIClass/readability/Readability.php
+++ /dev/null
@@ -1,1069 +0,0 @@
-init();
-echo $r->articleContent->innerHTML;
-*/
-
-class Readability
-{
- public $version = '1.7.1-without-multi-page';
- public $convertLinksToFootnotes = false;
- public $revertForcedParagraphElements = true;
- public $articleTitle;
- public $articleContent;
- public $dom;
- public $url = null; // optional - URL where HTML was retrieved
- public $debug = false;
- protected $body = null; //
- protected $bodyCache = null; // Cache the body HTML in case we need to re-use it later
- protected $flags = 7; // 1 | 2 | 4; // Start with all flags set.
- protected $success = false; // indicates whether we were able to extract or not
-
- /**
- * All of the regular expressions in use within readability.
- * Defined up here so we don't instantiate them repeatedly in loops.
- **/
- public $regexps = array(
- 'unlikelyCandidates' => '/combx|comment|community|disqus|extra|foot|header|menu|remark|rss|shoutbox|sidebar|sponsor|ad-break|agegate|pagination|pager|popup|tweet|twitter/i',
- 'okMaybeItsACandidate' => '/and|article|body|column|main|shadow/i',
- 'positive' => '/article|body|content|entry|hentry|main|page|pagination|post|text|blog|story/i',
- 'negative' => '/combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget/i',
- 'divToPElements' => '/<(a|blockquote|dl|div|img|ol|p|pre|table|ul)/i',
- 'replaceBrs' => '/( ]*>[ \n\r\t]*){2,}/i',
- 'replaceFonts' => '/<(\/?)font[^>]*>/i',
- // 'trimRe' => '/^\s+|\s+$/g', // PHP has trim()
- 'normalize' => '/\s{2,}/',
- 'killBreaks' => '/( (\s| ?)*){1,}/',
- 'video' => '/http:\/\/(www\.)?(youtube|vimeo)\.com/i',
- 'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i'
- );
-
- /* constants */
- const FLAG_STRIP_UNLIKELYS = 1;
- const FLAG_WEIGHT_CLASSES = 2;
- const FLAG_CLEAN_CONDITIONALLY = 4;
-
- /**
- * Create instance of Readability
- * @param string UTF-8 encoded string
- * @param string (optional) URL associated with HTML (used for footnotes)
- */
- function __construct($html, $url=null)
- {
- /* Turn all double br's into p's */
- /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */
- $html = preg_replace($this->regexps['replaceBrs'], '', $html);
- $html = preg_replace($this->regexps['replaceFonts'], '<$1span>', $html);
- $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8");
- $this->dom = new DOMDocument();
- $this->dom->preserveWhiteSpace = false;
- $this->dom->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
- @$this->dom->loadHTML($html);
- $this->url = $url;
- }
-
- /**
- * Get article title element
- * @return DOMElement
- */
- public function getTitle() {
- return $this->articleTitle;
- }
-
- /**
- * Get article content element
- * @return DOMElement
- */
- public function getContent() {
- return $this->articleContent;
- }
-
- /**
- * Runs readability.
- *
- * Workflow:
- * 1. Prep the document by removing script tags, css, etc.
- * 2. Build readability's DOM tree.
- * 3. Grab the article content from the current dom tree.
- * 4. Replace the current DOM tree with the new one.
- * 5. Read peacefully.
- *
- * @return boolean true if we found content, false otherwise
- **/
- public function init()
- {
- $this->removeScripts($this->dom);
-
- // Assume successful outcome
- $this->success = true;
-
- $bodyElems = $this->dom->getElementsByTagName('body');
- if ($bodyElems->length > 0) {
- if ($this->bodyCache == null) {
- $this->bodyCache = $bodyElems->item(0)->innerHTML;
- }
- if ($this->body == null) {
- $this->body = $bodyElems->item(0);
- }
- }
-
- $this->prepDocument();
-
- //die($this->dom->documentElement->parentNode->nodeType);
- //$this->setInnerHTML($this->dom->documentElement, $this->getInnerHTML($this->dom->documentElement));
- //die($this->getInnerHTML($this->dom->documentElement));
-
- /* Build readability's DOM tree */
- $overlay = $this->dom->createElement('div');
- $innerDiv = $this->dom->createElement('div');
- $articleTitle = $this->getArticleTitle();
- $articleContent = $this->grabArticle();
-
- if (!$articleContent) {
- $this->success = false;
- $articleContent = $this->dom->createElement('div');
- $articleContent->setAttribute('id', 'readability-content');
- $articleContent->innerHTML = '
Sorry, Readability was unable to parse this page for content.
';
- }
-
- $overlay->setAttribute('id', 'readOverlay');
- $innerDiv->setAttribute('id', 'readInner');
-
- /* Glue the structure of our document together. */
- $innerDiv->appendChild($articleTitle);
- $innerDiv->appendChild($articleContent);
- $overlay->appendChild($innerDiv);
-
- /* Clear the old HTML, insert the new content. */
- $this->body->innerHTML = '';
- $this->body->appendChild($overlay);
- //document.body.insertBefore(overlay, document.body.firstChild);
- $this->body->removeAttribute('style');
-
- $this->postProcessContent($articleContent);
-
- // Set title and content instance variables
- $this->articleTitle = $articleTitle;
- $this->articleContent = $articleContent;
-
- return $this->success;
- }
-
- /**
- * Debug
- */
- protected function dbg($msg) {
- if ($this->debug) echo '* ',$msg, ' ', "\n";
- }
-
- /**
- * Run any post-process modifications to article content as necessary.
- *
- * @param DOMElement
- * @return void
- */
- public function postProcessContent($articleContent) {
- if ($this->convertLinksToFootnotes && !preg_match('/wikipedia\.org/', @$this->url)) {
- $this->addFootnotes($articleContent);
- }
- }
-
- /**
- * Get the article title as an H1.
- *
- * @return DOMElement
- */
- protected function getArticleTitle() {
- $curTitle = '';
- $origTitle = '';
-
- try {
- $curTitle = $origTitle = $this->getInnerText($this->dom->getElementsByTagName('title')->item(0));
- } catch(Exception $e) {}
-
- if (preg_match('/ [\|\-] /', $curTitle))
- {
- $curTitle = preg_replace('/(.*)[\|\-] .*/i', '$1', $origTitle);
-
- if (count(explode(' ', $curTitle)) < 3) {
- $curTitle = preg_replace('/[^\|\-]*[\|\-](.*)/i', '$1', $origTitle);
- }
- }
- else if (strpos($curTitle, ': ') !== false)
- {
- $curTitle = preg_replace('/.*:(.*)/i', '$1', $origTitle);
-
- if (count(explode(' ', $curTitle)) < 3) {
- $curTitle = preg_replace('/[^:]*[:](.*)/i','$1', $origTitle);
- }
- }
- else if(strlen($curTitle) > 150 || strlen($curTitle) < 15)
- {
- $hOnes = $this->dom->getElementsByTagName('h1');
- if($hOnes->length == 1)
- {
- $curTitle = $this->getInnerText($hOnes->item(0));
- }
- }
-
- $curTitle = trim($curTitle);
-
- if (count(explode(' ', $curTitle)) <= 4) {
- $curTitle = $origTitle;
- }
-
- $articleTitle = $this->dom->createElement('h1');
- $articleTitle->innerHTML = $curTitle;
-
- return $articleTitle;
- }
-
- /**
- * Prepare the HTML document for readability to scrape it.
- * This includes things like stripping javascript, CSS, and handling terrible markup.
- *
- * @return void
- **/
- protected function prepDocument() {
- /**
- * In some cases a body element can't be found (if the HTML is totally hosed for example)
- * so we create a new body node and append it to the document.
- */
- if($this->dom->documentElement == null){
- throw new Exception("No document element");
- }
- if ($this->body == null)
- {
- $this->body = $this->dom->createElement('body');
- $this->dom->documentElement->appendChild($this->body);
- }
-
- $this->body->setAttribute('id', 'readabilityBody');
-
- /* Remove all style tags in head */
- $styleTags = $this->dom->getElementsByTagName('style');
- for ($i = $styleTags->length-1; $i >= 0; $i--)
- {
- $styleTags->item($i)->parentNode->removeChild($styleTags->item($i));
- }
-
- /* Turn all double br's into p's */
- /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */
- //document.body.innerHTML = document.body.innerHTML.replace(readability.regexps.replaceBrs, '').replace(readability.regexps.replaceFonts, '<$1span>');
- // We do this in the constructor for PHP as that's when we have raw HTML - before parsing it into a DOM tree.
- // Manipulating innerHTML as it's done in JS is not possible in PHP.
- }
-
- /**
- * For easier reading, convert this document to have footnotes at the bottom rather than inline links.
- * @see http://www.roughtype.com/archives/2010/05/experiments_in.php
- *
- * @return void
- **/
- public function addFootnotes($articleContent) {
- $footnotesWrapper = $this->dom->createElement('div');
- $footnotesWrapper->setAttribute('id', 'readability-footnotes');
- $footnotesWrapper->innerHTML = '
References ';
-
- $articleFootnotes = $this->dom->createElement('ol');
- $articleFootnotes->setAttribute('id', 'readability-footnotes-list');
- $footnotesWrapper->appendChild($articleFootnotes);
-
- $articleLinks = $articleContent->getElementsByTagName('a');
-
- $linkCount = 0;
- for ($i = 0; $i < $articleLinks->length; $i++)
- {
- $articleLink = $articleLinks->item($i);
- $footnoteLink = $articleLink->cloneNode(true);
- $refLink = $this->dom->createElement('a');
- $footnote = $this->dom->createElement('li');
- $linkDomain = @parse_url($footnoteLink->getAttribute('href'), PHP_URL_HOST);
- if (!$linkDomain && isset($this->url)) $linkDomain = @parse_url($this->url, PHP_URL_HOST);
- //linkDomain = footnoteLink.host ? footnoteLink.host : document.location.host,
- $linkText = $this->getInnerText($articleLink);
-
- if ((strpos($articleLink->getAttribute('class'), 'readability-DoNotFootnote') !== false) || preg_match($this->regexps['skipFootnoteLink'], $linkText)) {
- continue;
- }
-
- $linkCount++;
-
- /** Add a superscript reference after the article link */
- $refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount);
- $refLink->innerHTML = '[' . $linkCount . '] ';
- $refLink->setAttribute('class', 'readability-DoNotFootnote');
- $refLink->setAttribute('style', 'color: inherit;');
-
- //TODO: does this work or should we use DOMNode.isSameNode()?
- if ($articleLink->parentNode->lastChild == $articleLink) {
- $articleLink->parentNode->appendChild($refLink);
- } else {
- $articleLink->parentNode->insertBefore($refLink, $articleLink->nextSibling);
- }
-
- $articleLink->setAttribute('style', 'color: inherit; text-decoration: none;');
- $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount);
-
- $footnote->innerHTML = '^ ';
-
- $footnoteLink->innerHTML = ($footnoteLink->getAttribute('title') != '' ? $footnoteLink->getAttribute('title') : $linkText);
- $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount);
-
- $footnote->appendChild($footnoteLink);
- if ($linkDomain) $footnote->innerHTML = $footnote->innerHTML . ' (' . $linkDomain . ') ';
-
- $articleFootnotes->appendChild($footnote);
- }
-
- if ($linkCount > 0) {
- $articleContent->appendChild($footnotesWrapper);
- }
- }
-
- /**
- * Reverts P elements with class 'readability-styled'
- * to text nodes - which is what they were before.
- *
- * @param DOMElement
- * @return void
- */
- function revertReadabilityStyledElements($articleContent) {
- $xpath = new DOMXPath($articleContent->ownerDocument);
- $elems = $xpath->query('.//p[@class="readability-styled"]', $articleContent);
- //$elems = $articleContent->getElementsByTagName('p');
- for ($i = $elems->length-1; $i >= 0; $i--) {
- $e = $elems->item($i);
- $e->parentNode->replaceChild($articleContent->ownerDocument->createTextNode($e->textContent), $e);
- //if ($e->hasAttribute('class') && $e->getAttribute('class') == 'readability-styled') {
- // $e->parentNode->replaceChild($this->dom->createTextNode($e->textContent), $e);
- //}
- }
- }
-
- /**
- * Prepare the article node for display. Clean out any inline styles,
- * iframes, forms, strip extraneous tags, etc.
- *
- * @param DOMElement
- * @return void
- */
- function prepArticle($articleContent) {
- $this->cleanStyles($articleContent);
- $this->killBreaks($articleContent);
- if ($this->revertForcedParagraphElements) {
- $this->revertReadabilityStyledElements($articleContent);
- }
-
- /* Clean out junk from the article content */
- $this->cleanConditionally($articleContent, 'form');
- $this->clean($articleContent, 'object');
- $this->clean($articleContent, 'h1');
-
- /**
- * If there is only one h2, they are probably using it
- * as a header and not a subheader, so remove it since we already have a header.
- ***/
- if ($articleContent->getElementsByTagName('h2')->length == 1) {
- $this->clean($articleContent, 'h2');
- }
- $this->clean($articleContent, 'iframe');
-
- $this->cleanHeaders($articleContent);
-
- /* Do these last as the previous stuff may have removed junk that will affect these */
- $this->cleanConditionally($articleContent, 'table');
- $this->cleanConditionally($articleContent, 'ul');
- $this->cleanConditionally($articleContent, 'div');
-
- /* Remove extra paragraphs */
- $articleParagraphs = $articleContent->getElementsByTagName('p');
- for ($i = $articleParagraphs->length-1; $i >= 0; $i--)
- {
- $imgCount = $articleParagraphs->item($i)->getElementsByTagName('img')->length;
- $embedCount = $articleParagraphs->item($i)->getElementsByTagName('embed')->length;
- $objectCount = $articleParagraphs->item($i)->getElementsByTagName('object')->length;
-
- if ($imgCount === 0 && $embedCount === 0 && $objectCount === 0 && $this->getInnerText($articleParagraphs->item($i), false) == '')
- {
- $articleParagraphs->item($i)->parentNode->removeChild($articleParagraphs->item($i));
- }
- }
-
- try {
- $articleContent->innerHTML = preg_replace('/ ]*>\s*
innerHTML);
- //articleContent.innerHTML = articleContent.innerHTML.replace(/ ]*>\s*
dbg("Cleaning innerHTML of breaks failed. This is an IE strict-block-elements bug. Ignoring.: " . $e);
- }
- }
-
- /**
- * Initialize a node with the readability object. Also checks the
- * className/id for special names to add to its score.
- *
- * @param Element
- * @return void
- **/
- protected function initializeNode($node) {
- $readability = $this->dom->createAttribute('readability');
- $readability->value = 0; // this is our contentScore
- $node->setAttributeNode($readability);
-
- switch (strtoupper($node->tagName)) { // unsure if strtoupper is needed, but using it just in case
- case 'DIV':
- $readability->value += 5;
- break;
-
- case 'PRE':
- case 'TD':
- case 'BLOCKQUOTE':
- $readability->value += 3;
- break;
-
- case 'ADDRESS':
- case 'OL':
- case 'UL':
- case 'DL':
- case 'DD':
- case 'DT':
- case 'LI':
- case 'FORM':
- $readability->value -= 3;
- break;
-
- case 'H1':
- case 'H2':
- case 'H3':
- case 'H4':
- case 'H5':
- case 'H6':
- case 'TH':
- $readability->value -= 5;
- break;
- }
- $readability->value += $this->getClassWeight($node);
- }
-
- /***
- * grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is
- * most likely to be the stuff a user wants to read. Then return it wrapped up in a div.
- *
- * @return DOMElement
- **/
- protected function grabArticle($page=null) {
- $stripUnlikelyCandidates = $this->flagIsActive(self::FLAG_STRIP_UNLIKELYS);
- if (!$page) $page = $this->dom;
- $allElements = $page->getElementsByTagName('*');
- /**
- * First, node prepping. Trash nodes that look cruddy (like ones with the class name "comment", etc), and turn divs
- * into P tags where they have been used inappropriately (as in, where they contain no other block level elements.)
- *
- * Note: Assignment from index for performance. See http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5
- * TODO: Shouldn't this be a reverse traversal?
- **/
- $node = null;
- $nodesToScore = array();
- for ($nodeIndex = 0; ($node = $allElements->item($nodeIndex)); $nodeIndex++) {
- //for ($nodeIndex=$targetList->length-1; $nodeIndex >= 0; $nodeIndex--) {
- //$node = $targetList->item($nodeIndex);
- $tagName = strtoupper($node->tagName);
- /* Remove unlikely candidates */
- if ($stripUnlikelyCandidates) {
- $unlikelyMatchString = $node->getAttribute('class') . $node->getAttribute('id');
- if (
- preg_match($this->regexps['unlikelyCandidates'], $unlikelyMatchString) &&
- !preg_match($this->regexps['okMaybeItsACandidate'], $unlikelyMatchString) &&
- $tagName != 'BODY'
- )
- {
- $this->dbg('Removing unlikely candidate - ' . $unlikelyMatchString);
- //$nodesToRemove[] = $node;
- $node->parentNode->removeChild($node);
- $nodeIndex--;
- continue;
- }
- }
-
- if ($tagName == 'P' || $tagName == 'TD' || $tagName == 'PRE') {
- $nodesToScore[] = $node;
- }
-
- /* Turn all divs that don't have children block level elements into p's */
- if ($tagName == 'DIV') {
- if (!preg_match($this->regexps['divToPElements'], $node->innerHTML)) {
- //$this->dbg('Altering div to p');
- $newNode = $this->dom->createElement('p');
- try {
- $newNode->innerHTML = $node->innerHTML;
- //$nodesToReplace[] = array('new'=>$newNode, 'old'=>$node);
- $node->parentNode->replaceChild($newNode, $node);
- $nodeIndex--;
- $nodesToScore[] = $node; // or $newNode?
- }
- catch(Exception $e) {
- $this->dbg('Could not alter div to p, reverting back to div.: ' . $e);
- }
- }
- else
- {
- /* EXPERIMENTAL */
- // TODO: change these p elements back to text nodes after processing
- for ($i = 0, $il = $node->childNodes->length; $i < $il; $i++) {
- $childNode = $node->childNodes->item($i);
- if ($childNode->nodeType == 3) { // XML_TEXT_NODE
- //$this->dbg('replacing text node with a p tag with the same content.');
- $p = $this->dom->createElement('p');
- $p->innerHTML = $childNode->nodeValue;
- $p->setAttribute('style', 'display: inline;');
- $p->setAttribute('class', 'readability-styled');
- $childNode->parentNode->replaceChild($p, $childNode);
- }
- }
- }
- }
- }
-
- /**
- * Loop through all paragraphs, and assign a score to them based on how content-y they look.
- * Then add their score to their parent node.
- *
- * A score is determined by things like number of commas, class names, etc. Maybe eventually link density.
- **/
- $candidates = array();
- for ($pt=0; $pt < count($nodesToScore); $pt++) {
- $parentNode = $nodesToScore[$pt]->parentNode;
- // $grandParentNode = $parentNode ? $parentNode->parentNode : null;
- $grandParentNode = !$parentNode ? null : (($parentNode->parentNode instanceof DOMElement) ? $parentNode->parentNode : null);
- $innerText = $this->getInnerText($nodesToScore[$pt]);
-
- if (!$parentNode || !isset($parentNode->tagName)) {
- continue;
- }
-
- /* If this paragraph is less than 25 characters, don't even count it. */
- if(strlen($innerText) < 25) {
- continue;
- }
-
- /* Initialize readability data for the parent. */
- if (!$parentNode->hasAttribute('readability'))
- {
- $this->initializeNode($parentNode);
- $candidates[] = $parentNode;
- }
-
- /* Initialize readability data for the grandparent. */
- if ($grandParentNode && !$grandParentNode->hasAttribute('readability') && isset($grandParentNode->tagName))
- {
- $this->initializeNode($grandParentNode);
- $candidates[] = $grandParentNode;
- }
-
- $contentScore = 0;
-
- /* Add a point for the paragraph itself as a base. */
- $contentScore++;
-
- /* Add points for any commas within this paragraph */
- $contentScore += count(explode(',', $innerText));
-
- /* For every 100 characters in this paragraph, add another point. Up to 3 points. */
- $contentScore += min(floor(strlen($innerText) / 100), 3);
-
- /* Add the score to the parent. The grandparent gets half. */
- $parentNode->getAttributeNode('readability')->value += $contentScore;
-
- if ($grandParentNode) {
- $grandParentNode->getAttributeNode('readability')->value += $contentScore/2;
- }
- }
-
- /**
- * After we've calculated scores, loop through all of the possible candidate nodes we found
- * and find the one with the highest score.
- **/
- $topCandidate = null;
- for ($c=0, $cl=count($candidates); $c < $cl; $c++)
- {
- /**
- * Scale the final candidates score based on link density. Good content should have a
- * relatively small link density (5% or less) and be mostly unaffected by this operation.
- **/
- $readability = $candidates[$c]->getAttributeNode('readability');
- $readability->value = $readability->value * (1-$this->getLinkDensity($candidates[$c]));
-
- $this->dbg('Candidate: ' . $candidates[$c]->tagName . ' (' . $candidates[$c]->getAttribute('class') . ':' . $candidates[$c]->getAttribute('id') . ') with score ' . $readability->value);
-
- if (!$topCandidate || $readability->value > (int)$topCandidate->getAttribute('readability')) {
- $topCandidate = $candidates[$c];
- }
- }
-
- /**
- * If we still have no top candidate, just use the body as a last resort.
- * We also have to copy the body node so it is something we can modify.
- **/
- if ($topCandidate === null || strtoupper($topCandidate->tagName) == 'BODY')
- {
- $topCandidate = $this->dom->createElement('div');
- $topCandidate->innerHTML = ($page instanceof DOMDocument) ? $page->saveXML($page->documentElement) : $page->innerHTML;
- $page->innerHTML = '';
- $page->appendChild($topCandidate);
- $this->initializeNode($topCandidate);
- }
-
- /**
- * Now that we have the top candidate, look through its siblings for content that might also be related.
- * Things like preambles, content split by ads that we removed, etc.
- **/
- $articleContent = $this->dom->createElement('div');
- $articleContent->setAttribute('id', 'readability-content');
- $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2);
- $siblingNodes = $topCandidate->parentNode->childNodes;
-
- for ($s=0, $sl=$siblingNodes->length; $s < $sl; $s++)
- {
- $siblingNode = $siblingNodes->item($s);
- $append = false;
-
- $this->dbg('Looking at sibling node: ' . $siblingNode->nodeName . (($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability')) ? (' with score ' . $siblingNode->getAttribute('readability')) : ''));
-
- //dbg('Sibling has score ' . ($siblingNode->readability ? siblingNode.readability.contentScore : 'Unknown'));
-
- if ($siblingNode === $topCandidate)
- // or if ($siblingNode->isSameNode($topCandidate))
- {
- $append = true;
- }
-
- $contentBonus = 0;
- /* Give a bonus if sibling nodes and top candidates have the example same classname */
- if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->getAttribute('class') == $topCandidate->getAttribute('class') && $topCandidate->getAttribute('class') != '') {
- $contentBonus += ((int)$topCandidate->getAttribute('readability')) * 0.2;
- }
-
- if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability') && (((int)$siblingNode->getAttribute('readability')) + $contentBonus) >= $siblingScoreThreshold)
- {
- $append = true;
- }
-
- if (strtoupper($siblingNode->nodeName) == 'P') {
- $linkDensity = $this->getLinkDensity($siblingNode);
- $nodeContent = $this->getInnerText($siblingNode);
- $nodeLength = strlen($nodeContent);
-
- if ($nodeLength > 80 && $linkDensity < 0.25)
- {
- $append = true;
- }
- else if ($nodeLength < 80 && $linkDensity === 0 && preg_match('/\.( |$)/', $nodeContent))
- {
- $append = true;
- }
- }
-
- if ($append)
- {
- $this->dbg('Appending node: ' . $siblingNode->nodeName);
-
- $nodeToAppend = null;
- $sibNodeName = strtoupper($siblingNode->nodeName);
- if ($sibNodeName != 'DIV' && $sibNodeName != 'P') {
- /* 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. */
-
- $this->dbg('Altering siblingNode of ' . $sibNodeName . ' to div.');
- $nodeToAppend = $this->dom->createElement('div');
- try {
- $nodeToAppend->setAttribute('id', $siblingNode->getAttribute('id'));
- $nodeToAppend->innerHTML = $siblingNode->innerHTML;
- }
- catch(Exception $e)
- {
- $this->dbg('Could not alter siblingNode to div, reverting back to original.');
- $nodeToAppend = $siblingNode;
- $s--;
- $sl--;
- }
- } else {
- $nodeToAppend = $siblingNode;
- $s--;
- $sl--;
- }
-
- /* To ensure a node does not interfere with readability styles, remove its classnames */
- $nodeToAppend->removeAttribute('class');
-
- /* Append sibling and subtract from our list because it removes the node when you append to another node */
- $articleContent->appendChild($nodeToAppend);
- }
- }
-
- /**
- * So we have all of the content that we need. Now we clean it up for presentation.
- **/
- $this->prepArticle($articleContent);
-
- /**
- * Now that we've gone through the full algorithm, check to see if we got any meaningful content.
- * If we didn't, we may need to re-run grabArticle with different flags set. This gives us a higher
- * likelihood of finding the content, and the sieve approach gives us a higher likelihood of
- * finding the -right- content.
- **/
- if (strlen($this->getInnerText($articleContent, false)) < 250)
- {
- $this->body->innerHTML = $this->bodyCache;
-
- if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS)) {
- $this->removeFlag(self::FLAG_STRIP_UNLIKELYS);
- return $this->grabArticle($this->body);
- }
- else if ($this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) {
- $this->removeFlag(self::FLAG_WEIGHT_CLASSES);
- return $this->grabArticle($this->body);
- }
- else if ($this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) {
- $this->removeFlag(self::FLAG_CLEAN_CONDITIONALLY);
- return $this->grabArticle($this->body);
- }
- else {
- return false;
- }
- }
- return $articleContent;
- }
-
- /**
- * Remove script tags from document
- *
- * @param DOMElement
- * @return void
- */
- public function removeScripts($doc) {
- $scripts = $doc->getElementsByTagName('script');
- for($i = $scripts->length-1; $i >= 0; $i--)
- {
- $scripts->item($i)->parentNode->removeChild($scripts->item($i));
- }
- }
-
- /**
- * Get the inner text of a node.
- * This also strips out any excess whitespace to be found.
- *
- * @param DOMElement $
- * @param boolean $normalizeSpaces (default: true)
- * @return string
- **/
- public function getInnerText($e, $normalizeSpaces=true) {
- $textContent = '';
-
- if (!isset($e->textContent) || $e->textContent == '') {
- return '';
- }
-
- $textContent = trim($e->textContent);
-
- if ($normalizeSpaces) {
- return preg_replace($this->regexps['normalize'], ' ', $textContent);
- } else {
- return $textContent;
- }
- }
-
- /**
- * Get the number of times a string $s appears in the node $e.
- *
- * @param DOMElement $e
- * @param string - what to count. Default is ","
- * @return number (integer)
- **/
- public function getCharCount($e, $s=',') {
- return substr_count($this->getInnerText($e), $s);
- }
-
- /**
- * Remove the style attribute on every $e and under.
- *
- * @param DOMElement $e
- * @return void
- */
- public function cleanStyles($e) {
- $elems = $e->getElementsByTagName('*');
- foreach ($elems as $elem) {
- $elem->removeAttribute('style');
- }
- }
-
- /**
- * Get the density of links as a percentage of the content
- * This is the amount of text that is inside a link divided by the total text in the node.
- *
- * @param DOMElement $e
- * @return number (float)
- */
- public function getLinkDensity($e) {
- $links = $e->getElementsByTagName('a');
- $textLength = strlen($this->getInnerText($e));
- $linkLength = 0;
- for ($i=0, $il=$links->length; $i < $il; $i++)
- {
- $linkLength += strlen($this->getInnerText($links->item($i)));
- }
- if ($textLength > 0) {
- return $linkLength / $textLength;
- } else {
- return 0;
- }
- }
-
- /**
- * Get an elements class/id weight. Uses regular expressions to tell if this
- * element looks good or bad.
- *
- * @param DOMElement $e
- * @return number (Integer)
- */
- public function getClassWeight($e) {
- if(!$this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) {
- return 0;
- }
-
- $weight = 0;
-
- /* Look for a special classname */
- if ($e->hasAttribute('class') && $e->getAttribute('class') != '')
- {
- if (preg_match($this->regexps['negative'], $e->getAttribute('class'))) {
- $weight -= 25;
- }
- if (preg_match($this->regexps['positive'], $e->getAttribute('class'))) {
- $weight += 25;
- }
- }
-
- /* Look for a special ID */
- if ($e->hasAttribute('id') && $e->getAttribute('id') != '')
- {
- if (preg_match($this->regexps['negative'], $e->getAttribute('id'))) {
- $weight -= 25;
- }
- if (preg_match($this->regexps['positive'], $e->getAttribute('id'))) {
- $weight += 25;
- }
- }
- return $weight;
- }
-
- /**
- * Remove extraneous break tags from a node.
- *
- * @param DOMElement $node
- * @return void
- */
- public function killBreaks($node) {
- $html = $node->innerHTML;
- $html = preg_replace($this->regexps['killBreaks'], ' ', $html);
- $node->innerHTML = $html;
- }
-
- /**
- * Clean a node of all elements of type "tag".
- * (Unless it's a youtube/vimeo video. People love movies.)
- *
- * @param DOMElement $e
- * @param string $tag
- * @return void
- */
- public function clean($e, $tag) {
- $targetList = $e->getElementsByTagName($tag);
- $isEmbed = ($tag == 'object' || $tag == 'embed');
-
- for ($y=$targetList->length-1; $y >= 0; $y--) {
- /* Allow youtube and vimeo videos through as people usually want to see those. */
- if ($isEmbed) {
- $attributeValues = '';
- for ($i=0, $il=$targetList->item($y)->attributes->length; $i < $il; $i++) {
- $attributeValues .= $targetList->item($y)->attributes->item($i)->value . '|'; // DOMAttr? (TODO: test)
- }
-
- /* First, check the elements attributes to see if any of them contain youtube or vimeo */
- if (preg_match($this->regexps['video'], $attributeValues)) {
- continue;
- }
-
- /* Then check the elements inside this element for the same. */
- if (preg_match($this->regexps['video'], $targetList->item($y)->innerHTML)) {
- continue;
- }
- }
- $targetList->item($y)->parentNode->removeChild($targetList->item($y));
- }
- }
-
- /**
- * Clean an element of all tags of type "tag" if they look fishy.
- * "Fishy" is an algorithm based on content length, classnames,
- * link density, number of images & embeds, etc.
- *
- * @param DOMElement $e
- * @param string $tag
- * @return void
- */
- public function cleanConditionally($e, $tag) {
- if (!$this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) {
- return;
- }
-
- $tagsList = $e->getElementsByTagName($tag);
- $curTagsLength = $tagsList->length;
-
- /**
- * Gather counts for other typical elements embedded within.
- * Traverse backwards so we can remove nodes at the same time without effecting the traversal.
- *
- * TODO: Consider taking into account original contentScore here.
- */
- for ($i=$curTagsLength-1; $i >= 0; $i--) {
- $weight = $this->getClassWeight($tagsList->item($i));
- $contentScore = ($tagsList->item($i)->hasAttribute('readability')) ? (int)$tagsList->item($i)->getAttribute('readability') : 0;
-
- $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')) : ''));
-
- if ($weight + $contentScore < 0) {
- $tagsList->item($i)->parentNode->removeChild($tagsList->item($i));
- }
- else if ( $this->getCharCount($tagsList->item($i), ',') < 10) {
- /**
- * If there are not very many commas, and the number of
- * non-paragraph elements is more than paragraphs or other ominous signs, remove the element.
- **/
- $p = $tagsList->item($i)->getElementsByTagName('p')->length;
- $img = $tagsList->item($i)->getElementsByTagName('img')->length;
- $li = $tagsList->item($i)->getElementsByTagName('li')->length-100;
- $input = $tagsList->item($i)->getElementsByTagName('input')->length;
-
- $embedCount = 0;
- $embeds = $tagsList->item($i)->getElementsByTagName('embed');
- for ($ei=0, $il=$embeds->length; $ei < $il; $ei++) {
- if (preg_match($this->regexps['video'], $embeds->item($ei)->getAttribute('src'))) {
- $embedCount++;
- }
- }
-
- $linkDensity = $this->getLinkDensity($tagsList->item($i));
- $contentLength = strlen($this->getInnerText($tagsList->item($i)));
- $toRemove = false;
-
- if ( $img > $p ) {
- $toRemove = true;
- } else if ($li > $p && $tag != 'ul' && $tag != 'ol') {
- $toRemove = true;
- } else if ( $input > floor($p/3) ) {
- $toRemove = true;
- } else if ($contentLength < 25 && ($img === 0 || $img > 2) ) {
- $toRemove = true;
- } else if($weight < 25 && $linkDensity > 0.2) {
- $toRemove = true;
- } else if($weight >= 25 && $linkDensity > 0.5) {
- $toRemove = true;
- } else if(($embedCount == 1 && $contentLength < 75) || $embedCount > 1) {
- $toRemove = true;
- }
-
- if ($toRemove) {
- $tagsList->item($i)->parentNode->removeChild($tagsList->item($i));
- }
- }
- }
- }
-
- /**
- * Clean out spurious headers from an Element. Checks things like classnames and link density.
- *
- * @param DOMElement $e
- * @return void
- */
- public function cleanHeaders($e) {
- for ($headerIndex = 1; $headerIndex < 3; $headerIndex++) {
- $headers = $e->getElementsByTagName('h' . $headerIndex);
- for ($i=$headers->length-1; $i >=0; $i--) {
- if ($this->getClassWeight($headers->item($i)) < 0 || $this->getLinkDensity($headers->item($i)) > 0.33) {
- $headers->item($i)->parentNode->removeChild($headers->item($i));
- }
- }
- }
- }
-
- public function flagIsActive($flag) {
- return ($this->flags & $flag) > 0;
- }
-
- public function addFlag($flag) {
- $this->flags = $this->flags | $flag;
- }
-
- public function removeFlag($flag) {
- $this->flags = $this->flags & ~$flag;
- }
-}
-?>
\ No newline at end of file
diff --git a/inc/3rdparty/libraries/readability/Readability.php b/inc/3rdparty/libraries/readability/Readability.php
index 4fa3ba63d..a30012ced 100755
--- a/inc/3rdparty/libraries/readability/Readability.php
+++ b/inc/3rdparty/libraries/readability/Readability.php
@@ -46,6 +46,7 @@
// This class allows us to do JavaScript like assignements to innerHTML
require_once(dirname(__FILE__).'/JSLikeHTMLElement.php');
+libxml_use_internal_errors(true);
// Alternative usage (for testing only!)
// uncomment the lines below and call Readability.php in your browser
@@ -697,7 +698,7 @@ class Readability
$articleContent = $this->dom->createElement('div');
$articleContent->setAttribute('id', 'readability-content');
$siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2);
- $siblingNodes = $topCandidate->parentNode->childNodes;
+ $siblingNodes = @$topCandidate->parentNode->childNodes;
if (!isset($siblingNodes)) {
$siblingNodes = new stdClass;
$siblingNodes->length = 0;
@@ -1148,4 +1149,4 @@ class Readability
}
}
-?>
\ No newline at end of file
+?>
diff --git a/inc/3rdparty/libraries/tcpdf/tcpdf.php b/inc/3rdparty/libraries/tcpdf/tcpdf.php
index 78694a0e4..70c1747ac 100644
--- a/inc/3rdparty/libraries/tcpdf/tcpdf.php
+++ b/inc/3rdparty/libraries/tcpdf/tcpdf.php
@@ -2926,12 +2926,18 @@ class TCPDF {
*/
public function Error($msg) {
// unset all class variables
+ $this->_destroy(true);
+ throw new Exception('TCPDF ERROR: '.$msg);
+ /*
+
+ I had problems with the constants for some reason, so here we force
+
$this->_destroy(true);
if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
die('TCPDF ERROR: '.$msg);
} else {
throw new Exception('TCPDF ERROR: '.$msg);
- }
+ }*/
}
/**
@@ -6915,7 +6921,7 @@ class TCPDF {
$ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
$imsize = array($pw, $ph);
} else {
- $this->Error('[Image] Unable to get the size of the image: '.$file);
+ $this->Error('[Image] Unable to fetch image: '.$file);
}
}
// file hash
diff --git a/inc/3rdparty/makefulltextfeed.php b/inc/3rdparty/makefulltextfeed.php
index a081f88b2..27a62d732 100755
--- a/inc/3rdparty/makefulltextfeed.php
+++ b/inc/3rdparty/makefulltextfeed.php
@@ -31,6 +31,8 @@ along with this program. If not, see .
//error_reporting(E_ALL ^ E_NOTICE);
ini_set("display_errors", 1);
@set_time_limit(120);
+libxml_use_internal_errors(true);
+
// Deal with magic quotes
if (get_magic_quotes_gpc()) {
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index 3c7a2c5a0..5b8e235f1 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -180,6 +180,13 @@ class Poche
}
}
+ // if there are tags, add them to the new article
+ if (isset($_GET['tags'])) {
+ $_POST['value'] = $_GET['tags'];
+ $_POST['entry_id'] = $last_id;
+ $this->action('add_tag', $url);
+ }
+
$this->messages->add('s', _('the link has been added successfully'));
}
else {
@@ -192,20 +199,34 @@ class Poche
} else {
Tools::redirect('?view=home&closewin=true');
}
+ return $last_id;
break;
case 'delete':
- $msg = 'delete link #' . $id;
- if ($this->store->deleteById($id, $this->user->getId())) {
- if (DOWNLOAD_PICTURES) {
- Picture::removeDirectory(ABS_PATH . $id);
+ if (isset($_GET['search'])) {
+ //when we want to apply a delete to a search
+ $tags = array($_GET['search']);
+ $allentry_ids = $this->store->search($tags[0], $this->user->getId());
+ $entry_ids = array();
+ foreach ($allentry_ids as $eachentry) {
+ $entry_ids[] = $eachentry[0];
}
- $this->messages->add('s', _('the link has been deleted successfully'));
+ } else { // delete a single article
+ $entry_ids = array($id);
}
- else {
- $this->messages->add('e', _('the link wasn\'t deleted'));
- $msg = 'error : can\'t delete link #' . $id;
+ foreach($entry_ids as $id) {
+ $msg = 'delete link #' . $id;
+ if ($this->store->deleteById($id, $this->user->getId())) {
+ if (DOWNLOAD_PICTURES) {
+ Picture::removeDirectory(ABS_PATH . $id);
+ }
+ $this->messages->add('s', _('the link has been deleted successfully'));
+ }
+ else {
+ $this->messages->add('e', _('the link wasn\'t deleted'));
+ $msg = 'error : can\'t delete link #' . $id;
+ }
+ Tools::logm($msg);
}
- Tools::logm($msg);
Tools::redirect('?');
break;
case 'toggle_fav' :
@@ -220,8 +241,21 @@ class Poche
}
break;
case 'toggle_archive' :
- $this->store->archiveById($id, $this->user->getId());
- Tools::logm('archive link #' . $id);
+ if (isset($_GET['tag_id'])) {
+ //when we want to archive a whole tag
+ $tag_id = $_GET['tag_id'];
+ $allentry_ids = $this->store->retrieveEntriesByTag($tag_id, $this->user->getId());
+ $entry_ids = array();
+ foreach ($allentry_ids as $eachentry) {
+ $entry_ids[] = $eachentry[0];
+ }
+ } else { //archive a single article
+ $entry_ids = array($id);
+ }
+ foreach($entry_ids as $id) {
+ $this->store->archiveById($id, $this->user->getId());
+ Tools::logm('archive link #' . $id);
+ }
if ( Tools::isAjaxRequest() ) {
echo 1;
exit;
@@ -413,9 +447,12 @@ class Poche
}
# flattr checking
- $flattr = new FlattrItem();
- $flattr->checkItem($entry['url'], $entry['id']);
-
+ $flattr = NULL;
+ if (FLATTR) {
+ $flattr = new FlattrItem();
+ $flattr->checkItem($entry['url'], $entry['id']);
+ }
+
# tags
$tags = $this->store->retrieveTagsByEntry($entry['id']);
@@ -548,6 +585,8 @@ class Poche
Tools::redirect($referer);
}
$this->messages->add('e', _('login failed: bad login or password'));
+ // log login failure in web server log to allow fail2ban usage
+ error_log('user '.$login.' authentication failure');
Tools::logm('login failed');
Tools::redirect();
}
@@ -633,7 +672,18 @@ class Poche
$urlsInserted[] = $url; //add
if (isset($record['tags']) && trim($record['tags'])) {
- // @TODO: set tags
+ $tags = explode(',', $record['tags']);
+ foreach($tags as $tag) {
+ $entry_id = $id;
+ $tag_id = $this->store->retrieveTagByValue($tag);
+ if ($tag_id) {
+ $this->store->setTagToEntry($tag_id['id'], $entry_id);
+ } else {
+ $this->store->createTag($tag);
+ $tag_id = $this->store->retrieveTagByValue($tag);
+ $this->store->setTagToEntry($tag_id['id'], $entry_id);
+ }
+ }
}
}
@@ -756,10 +806,11 @@ class Poche
*
* @param $token
* @param $user_id
- * @param $tag_id
- * @param string $type
+ * @param $tag_id if $type is 'tag', the id of the tag to generate feed for
+ * @param string $type the type of feed to generate
+ * @param int $limit the maximum number of items (0 means all)
*/
- public function generateFeeds($token, $user_id, $tag_id, $type = 'home')
+ public function generateFeeds($token, $user_id, $tag_id, $type = 'home', $limit = 0)
{
$allowed_types = array('home', 'fav', 'archive', 'tag');
$config = $this->store->getConfigUser($user_id);
@@ -786,8 +837,13 @@ class Poche
$entries = $this->store->getEntriesByView($type, $user_id);
}
+ // if $limit is set to zero, use all entries
+ if (0 == $limit) {
+ $limit = count($entries);
+ }
if (count($entries) > 0) {
- foreach ($entries as $entry) {
+ for ($i = 0; $i < min(count($entries), $limit); $i++) {
+ $entry = $entries[$i];
$newItem = $feed->createNewItem();
$newItem->setTitle($entry['title']);
$newItem->setSource(Tools::getPocheUrl() . '?view=view&id=' . $entry['id']);
diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php
index 5acd08ba6..a8d00b898 100755
--- a/inc/poche/Routing.class.php
+++ b/inc/poche/Routing.class.php
@@ -102,7 +102,8 @@ class Routing
$this->wallabag->login($this->referer);
} elseif (isset($_GET['feed']) && isset($_GET['user_id'])) {
$tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0);
- $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type']);
+ $limit = (isset($_GET['limit']) ? intval($_GET['limit']) : 0);
+ $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type'], $limit);
}
//allowed ONLY to logged in user
@@ -115,7 +116,7 @@ class Routing
// update password
$this->wallabag->updatePassword($_POST['password'], $_POST['password_repeat']);
} elseif (isset($_GET['newuser'])) {
- $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser']);
+ $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser'], $_POST['newuseremail']);
} elseif (isset($_GET['deluser'])) {
$this->wallabag->deleteUser($_POST['password4deletinguser']);
} elseif (isset($_GET['epub'])) {
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index f803e3b57..7ccfc069b 100755
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -342,7 +342,10 @@ final class Tools
return $json;
};
- $json = $scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url));
+ // Silence $scope function to avoid
+ // issues with FTRSS when error_reporting is to high
+ // FTRSS generates PHP warnings which break output
+ $json = @$scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url));
// Clearing and restoring context
foreach ($GLOBALS as $key => $value) {
diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php
index bc40990b1..558315719 100644
--- a/inc/poche/WallabagEBooks.class.php
+++ b/inc/poche/WallabagEBooks.class.php
@@ -33,7 +33,7 @@ class WallabagEBooks
$entry = $this->wallabag->store->retrieveOneById($entryID, $this->wallabag->user->getId());
$this->entries = array($entry);
$this->bookTitle = $entry['title'];
- $this->bookFileName = substr($this->bookTitle, 0, 200);
+ $this->bookFileName = str_replace('/', '_', substr($this->bookTitle, 0, 200));
$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)
Tools::logm('Producing ebook from article ' . $this->bookTitle);
break;
@@ -81,6 +81,9 @@ class WallabagEpub extends WallabagEBooks
public function produceEpub()
{
Tools::logm('Starting to produce ePub 3 file');
+
+ try {
+
$content_start =
"\n"
. "\n"
@@ -155,6 +158,11 @@ class WallabagEpub extends WallabagEBooks
$book->finalize();
$zipData = $book->sendBook($this->bookFileName);
Tools::logm('Ebook produced');
+ }
+ catch (Exception $e) {
+ Tools::logm('PHPePub has encountered an error : '.$e->getMessage());
+ $this->wallabag->messages->add('e', $e->getMessage());
+ }
}
}
@@ -167,7 +175,7 @@ class WallabagMobi extends WallabagEBooks
public function produceMobi()
{
-
+ try {
Tools::logm('Starting to produce Mobi file');
$mobi = new MOBI();
$content = new MOBIFile();
@@ -194,9 +202,17 @@ class WallabagMobi extends WallabagEBooks
}
$mobi->setContentProvider($content);
+ // the browser inside Kindle Devices doesn't likes special caracters either, we limit to A-z/0-9
+ $this->bookFileName = preg_replace('/[^A-Za-z0-9\-]/', '', $this->bookFileName);
+
// we offer file to download
$mobi->download($this->bookFileName.'.mobi');
Tools::logm('Mobi file produced');
+ }
+ catch (Exception $e) {
+ Tools::logm('PHPMobi has encountered an error : '.$e->getMessage());
+ $this->wallabag->messages->add('e', $e->getMessage());
+ }
}
}
@@ -206,15 +222,16 @@ class WallabagPDF extends WallabagEbooks
{
Tools::logm('Starting to produce PDF file');
-
+ @define ('K_TCPDF_THROW_EXCEPTION_ERROR', TRUE);
+ try {
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
Tools::logm('Filling metadata for PDF...');
$pdf->SetCreator(PDF_CREATOR);
- $pdf->SetAuthor('');
+ $pdf->SetAuthor('wallabag');
$pdf->SetTitle($this->bookTitle);
- $pdf->SetSubject('TCPDF Tutorial');
- $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
+ $pdf->SetSubject('Articles via wallabag');
+ $pdf->SetKeywords('wallabag');
Tools::logm('Adding introduction...');
$pdf->AddPage();
@@ -229,18 +246,26 @@ class WallabagPDF extends WallabagEbooks
$i = 1;
Tools::logm('Adding actual content...');
foreach ($this->entries as $item) {
+ $tags = $this->wallabag->store->retrieveTagsByEntry($entry['id']);
+ foreach ($tags as $tag) {
+ $pdf->SetKeywords($tag['value']);
+ }
$pdf->AddPage();
$html = '
' . $item['title'] . ' ';
$html .= $item['content'];
$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
- $i = $i+1;
}
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
-
+
$pdf->Output($this->bookFileName . '.pdf', 'FD');
+ }
+ catch (Exception $e) {
+ Tools::logm('TCPDF has encountered an error : '.$e->getMessage());
+ $this->wallabag->messages->add('e', $e->getMessage());
+ }
}
}
diff --git a/install/index.php b/install/index.php
index ec5041608..892af2416 100755
--- a/install/index.php
+++ b/install/index.php
@@ -11,18 +11,7 @@
$errors = array();
$successes = array();
-/* Function taken from at http://php.net/manual/en/function.rmdir.php#110489
- * Idea : nbari at dalmp dot com
- * Rights unknown
- * Here in case of .gitignore files
- */
-function delTree($dir) {
- $files = array_diff(scandir($dir), array('.','..'));
- foreach ($files as $file) {
- (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
- }
- return rmdir($dir);
- }
+require_once('wallabag_compatibility_test.php');
if (isset($_GET['clean'])) {
if (is_dir('install')){
@@ -58,135 +47,108 @@ if (isset($_POST['download'])) {
else if (isset($_POST['install'])) {
if (!is_dir('vendor')) {
$errors[] = 'You must install twig before.';
- }
- else {
+ } else {
$continue = true;
- // Create config.inc.php
- if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) {
- $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.';
- $continue = false;
- }
- else {
- function generate_salt() {
- mt_srand(microtime(true)*100000 + memory_get_usage(true));
- return md5(uniqid(mt_rand(), true));
- }
+ $salt = generate_salt();
+ $content = file_get_contents('inc/poche/config.inc.default.php');
- $content = file_get_contents('inc/poche/config.inc.php');
- $salt = generate_salt();
- $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content);
- file_put_contents('inc/poche/config.inc.php', $content);
- }
+ // User informations
+ $username = trim($_POST['username']);
+ $password = trim($_POST['password']);
+ $salted_password = sha1($password . $username . $salt);
- if ($continue) {
+ // Database informations
+ $moreQueries = array();
- // User informations
- $username = trim($_POST['username']);
- $password = trim($_POST['password']);
- $salted_password = sha1($password . $username . $salt);
-
- // Database informations
- $moreQueries = array();
- if ($_POST['db_engine'] == 'sqlite') {
- if (!copy('install/poche.sqlite', 'db/poche.sqlite')) {
- $errors[] = 'Impossible to create inc/poche/config.inc.php file.';
- $continue = false;
- }
- else {
- $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite';
- $handle = new PDO($db_path);
- $sql_structure = "";
- }
+ if ($_POST['db_engine'] == 'sqlite') {
+ if (!copy('install/poche.sqlite', 'db/poche.sqlite')) {
+ $errors[] = 'Impossible to create the SQLite database file.';
}
else {
- $content = file_get_contents('inc/poche/config.inc.php');
+ $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite';
+ $handle = new PDO($db_path);
+ $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $sql_structure = "";
+ }
+ } else {
+ // MySQL and Postgre
+ try {
- if ($_POST['db_engine'] == 'mysql') {
- $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4';
- $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content);
- $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content);
- $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content);
- $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content);
- $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
- ));
+ if ($_POST['db_engine'] == 'mysql') {
+ $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4';
+ $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content);
+ $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content);
+ $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content);
+ $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content);
+ $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array(
+ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
+ ));
- $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES
+ $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES
(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),
(2, 'wallabag/wallabag', 'https://github.com/wallabag/wallabag', 0, 0, 0x3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a, 1),
(3, 'a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', 0, 1, 0x0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a, 1);";
- $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');";
- $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);";
+ $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');";
+ $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);";
- $sql_structure = file_get_contents('install/mysql.sql');
- }
- else if ($_POST['db_engine'] == 'postgres') {
- $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database'];
- $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content);
- $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content);
- $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content);
- $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content);
- $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']);
-
- $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES
+ $sql_structure = file_get_contents('install/mysql.sql');
+ }
+ else if ($_POST['db_engine'] == 'postgres') {
+ $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database'];
+ $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content);
+ $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content);
+ $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content);
+ $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content);
+ $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']);
+
+ $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES
('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),
('wallabag/wallabag', 'https://github.com/wallabag/wallabag', false, false, convert_from(decode('3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a', 'hex'), 'UTF8'), 1),
('a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', false, true, convert_from(decode('3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a', 'hex'), 'UTF8'), 1)";
- $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')";
- $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)";
+ $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')";
+ $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)";
- $sql_structure = file_get_contents('install/postgres.sql');
- }
-
- $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content);
- file_put_contents('inc/poche/config.inc.php', $content);
- }
-
- if ($continue) {
-
- function executeQuery($handle, $sql, $params) {
- try
- {
- $query = $handle->prepare($sql);
- $query->execute($params);
- return $query->fetchAll();
- }
- catch (Exception $e)
- {
- return FALSE;
- }
- }
-
- if ($_POST['db_engine'] != "sqlite") {
- // create database structure
- $query = $handle->exec($sql_structure);
- }
-
- // Create user
- $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
- $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')";
- $params = array($username, $salted_password, $username);
- $query = executeQuery($handle, $sql, $params);
-
- $id_user = (int)$handle->lastInsertId('users_id_seq');
-
- $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
- $params = array($id_user, 'pager', '10');
- $query = executeQuery($handle, $sql, $params);
-
- $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
- $params = array($id_user, 'language', 'en_EN.UTF8');
- $query = executeQuery($handle, $sql, $params);
-
- foreach ($moreQueries as $query) {
- executeQuery($handle, $query, array());
- }
-
- $successes[] = 'wallabag is now installed. You can now access it ! ';
+ $sql_structure = file_get_contents('install/postgres.sql');
}
+ // create database structure
+ $query = $handle->exec($sql_structure);
+ } catch (PDOException $e) {
+ $errors[] = $e->getMessage();
+ $continue = false;
+ }
}
}
+ if ($continue) {
+ $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')";
+ $params = array($username, $salted_password, $username);
+ $query = executeQuery($handle, $sql, $params);
+
+ $id_user = (int)$handle->lastInsertId('users_id_seq');
+
+ $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
+ $params = array($id_user, 'pager', '10');
+ $query = executeQuery($handle, $sql, $params);
+
+ $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
+ $params = array($id_user, 'language', 'en_EN.UTF8');
+ $query = executeQuery($handle, $sql, $params);
+
+ foreach ($moreQueries as $query) {
+ executeQuery($handle, $query, array());
+ }
+ $successes[] = 'wallabag is now installed. You can now access it ! ';
+
+ if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) {
+ $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.';
+ } else {
+ if ($_POST['db_engine'] != 'sqlite') {
+ $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content);
+ file_put_contents('inc/poche/config.inc.php', $content);
+ }
+ $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content);
+ file_put_contents('inc/poche/config.inc.php', $content);
+ }
+}
}
?>
@@ -210,6 +172,160 @@ else if (isset($_POST['install'])) {
+
+
+
+
@@ -259,24 +375,192 @@ else if (isset($_POST['install'])) {
To install wallabag, you just have to fill the following fields. That's all.
If you need help, you can read the doc: offline documentation and online one (already up-to-date).
- Don't forget to check your server compatibility here .
-