mirror of
https://github.com/wallabag/wallabag.git
synced 2025-09-15 18:57:05 +00:00
Merge branch 'dev' into randomarticle
This commit is contained in:
commit
c416cab8c9
21 changed files with 1092 additions and 2277 deletions
4
inc/3rdparty/libraries/MOBIClass/MOBI.php
vendored
4
inc/3rdparty/libraries/MOBIClass/MOBI.php
vendored
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__)."/readability/Readability.php");
|
||||
require_once(dirname(__FILE__)."/../readability/Readability.php");
|
||||
require_once(dirname(__FILE__).'/CharacterEntities.php');
|
||||
require_once(dirname(__FILE__).'/constants.php');
|
||||
require_once(dirname(__FILE__).'/ContentProvider.php');
|
||||
|
@ -189,4 +189,4 @@ class MOBI {
|
|||
}
|
||||
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* JavaScript-like HTML DOM Element
|
||||
*
|
||||
* This class extends PHP's DOMElement to allow
|
||||
* users to get and set the innerHTML property of
|
||||
* HTML elements in the same way it's done in
|
||||
* JavaScript.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* require_once 'JSLikeHTMLElement.php';
|
||||
* header('Content-Type: text/plain');
|
||||
* $doc = new DOMDocument();
|
||||
* $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
|
||||
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
|
||||
* $elem = $doc->getElementsByTagName('div')->item(0);
|
||||
*
|
||||
* // print innerHTML
|
||||
* echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'
|
||||
* echo "\n\n";
|
||||
*
|
||||
* // set innerHTML
|
||||
* $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';
|
||||
* echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'
|
||||
* echo "\n\n";
|
||||
*
|
||||
* // print document (with our changes)
|
||||
* echo $doc->saveXML();
|
||||
* @endcode
|
||||
*
|
||||
* @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net
|
||||
* @see http://fivefilters.org (the project this was written for)
|
||||
*/
|
||||
class JSLikeHTMLElement extends DOMElement
|
||||
{
|
||||
/**
|
||||
* Used for setting innerHTML like it's done in JavaScript:
|
||||
* @code
|
||||
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
|
||||
* @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 <htmlfragment> 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 <html><body> tags which we don't really want to keep.
|
||||
// Note: despite the warning, if loadHTML succeeds it will return true.
|
||||
$result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>');
|
||||
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.']';
|
||||
}
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
|||
}
|
||||
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
|
10
inc/3rdparty/libraries/tcpdf/tcpdf.php
vendored
10
inc/3rdparty/libraries/tcpdf/tcpdf.php
vendored
|
@ -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('<strong>TCPDF ERROR: </strong>'.$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
|
||||
|
|
2
inc/3rdparty/makefulltextfeed.php
vendored
2
inc/3rdparty/makefulltextfeed.php
vendored
|
@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
//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()) {
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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'])) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
. "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n"
|
||||
|
@ -155,6 +158,11 @@ class WallabagEpub extends WallabagEBooks
|
|||
$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 = '<h1>' . $item['title'] . '</h1>';
|
||||
$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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue