diff options
Diffstat (limited to 'inc/poche')
-rwxr-xr-x | inc/poche/Database.class.php | 12 | ||||
-rwxr-xr-x | inc/poche/Poche.class.php | 163 | ||||
-rwxr-xr-x | inc/poche/Tools.class.php | 4 |
3 files changed, 98 insertions, 81 deletions
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php index 6244df88..036c9d1b 100755 --- a/inc/poche/Database.class.php +++ b/inc/poche/Database.class.php | |||
@@ -77,7 +77,7 @@ class Database { | |||
77 | } | 77 | } |
78 | else { | 78 | else { |
79 | $sql = ' | 79 | $sql = ' |
80 | CREATE TABLE tags ( | 80 | CREATE TABLE IF NOT EXISTS tags ( |
81 | id bigserial primary key, | 81 | id bigserial primary key, |
82 | value varchar(255) NOT NULL | 82 | value varchar(255) NOT NULL |
83 | ); | 83 | ); |
@@ -110,7 +110,7 @@ class Database { | |||
110 | } | 110 | } |
111 | else { | 111 | else { |
112 | $sql = ' | 112 | $sql = ' |
113 | CREATE TABLE tags_entries ( | 113 | CREATE TABLE IF NOT EXISTS tags_entries ( |
114 | id bigserial primary key, | 114 | id bigserial primary key, |
115 | entry_id integer NOT NULL, | 115 | entry_id integer NOT NULL, |
116 | tag_id integer NOT NULL | 116 | tag_id integer NOT NULL |
@@ -245,7 +245,7 @@ class Database { | |||
245 | $sql_limit = "LIMIT ".$limit." OFFSET 0"; | 245 | $sql_limit = "LIMIT ".$limit." OFFSET 0"; |
246 | } | 246 | } |
247 | 247 | ||
248 | $sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND user_id=? ORDER BY id " . $sql_limit; | 248 | $sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=? ORDER BY id " . $sql_limit; |
249 | $query = $this->executeQuery($sql, array($user_id)); | 249 | $query = $this->executeQuery($sql, array($user_id)); |
250 | $entries = $query->fetchAll(); | 250 | $entries = $query->fetchAll(); |
251 | 251 | ||
@@ -253,7 +253,7 @@ class Database { | |||
253 | } | 253 | } |
254 | 254 | ||
255 | public function retrieveUnfetchedEntriesCount($user_id) { | 255 | public function retrieveUnfetchedEntriesCount($user_id) { |
256 | $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND user_id=?"; | 256 | $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=?"; |
257 | $query = $this->executeQuery($sql, array($user_id)); | 257 | $query = $this->executeQuery($sql, array($user_id)); |
258 | list($count) = $query->fetch(); | 258 | list($count) = $query->fetch(); |
259 | 259 | ||
@@ -374,7 +374,7 @@ class Database { | |||
374 | $id = null; | 374 | $id = null; |
375 | } | 375 | } |
376 | else { | 376 | else { |
377 | $id = intval($this->getLastId( (STORAGE == 'postgres') ? 'users_id_seq' : '' )); | 377 | $id = intval($this->getLastId( (STORAGE == 'postgres') ? 'entries_id_seq' : '') ); |
378 | } | 378 | } |
379 | return $id; | 379 | return $id; |
380 | } | 380 | } |
@@ -407,7 +407,7 @@ class Database { | |||
407 | public function getLastId($column = '') { | 407 | public function getLastId($column = '') { |
408 | return $this->getHandle()->lastInsertId($column); | 408 | return $this->getHandle()->lastInsertId($column); |
409 | } | 409 | } |
410 | 410 | ||
411 | public function search($term, $user_id, $limit = '') { | 411 | public function search($term, $user_id, $limit = '') { |
412 | $search = '%'.$term.'%'; | 412 | $search = '%'.$term.'%'; |
413 | $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL | 413 | $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL |
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index a662f695..811895dc 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php | |||
@@ -373,9 +373,7 @@ class Poche | |||
373 | $body = $content['rss']['channel']['item']['description']; | 373 | $body = $content['rss']['channel']['item']['description']; |
374 | 374 | ||
375 | // clean content from prevent xss attack | 375 | // clean content from prevent xss attack |
376 | $config = HTMLPurifier_Config::createDefault(); | 376 | $purifier = $this->getPurifier(); |
377 | $config->set('Cache.SerializerPath', CACHE); | ||
378 | $purifier = new HTMLPurifier($config); | ||
379 | $title = $purifier->purify($title); | 377 | $title = $purifier->purify($title); |
380 | $body = $purifier->purify($body); | 378 | $body = $purifier->purify($body); |
381 | 379 | ||
@@ -828,10 +826,12 @@ class Poche | |||
828 | define('IMPORT_LIMIT', 5); | 826 | define('IMPORT_LIMIT', 5); |
829 | } | 827 | } |
830 | if (!defined('IMPORT_DELAY')) { | 828 | if (!defined('IMPORT_DELAY')) { |
831 | define('IMPORT_DELAY', 5); | 829 | define('IMPORT_DELAY', 5); |
832 | } | 830 | } |
833 | 831 | ||
834 | if ( isset($_FILES['file']) ) { | 832 | if ( isset($_FILES['file']) ) { |
833 | Tools::logm('Import stated: parsing file'); | ||
834 | |||
835 | // assume, that file is in json format | 835 | // assume, that file is in json format |
836 | $str_data = file_get_contents($_FILES['file']['tmp_name']); | 836 | $str_data = file_get_contents($_FILES['file']['tmp_name']); |
837 | $data = json_decode($str_data, true); | 837 | $data = json_decode($str_data, true); |
@@ -844,18 +844,18 @@ class Poche | |||
844 | $read = 0; | 844 | $read = 0; |
845 | foreach (array('ol','ul') as $list) { | 845 | foreach (array('ol','ul') as $list) { |
846 | foreach ($html->find($list) as $ul) { | 846 | foreach ($html->find($list) as $ul) { |
847 | foreach ($ul->find('li') as $li) { | 847 | foreach ($ul->find('li') as $li) { |
848 | $tmpEntry = array(); | 848 | $tmpEntry = array(); |
849 | $a = $li->find('a'); | 849 | $a = $li->find('a'); |
850 | $tmpEntry['url'] = $a[0]->href; | 850 | $tmpEntry['url'] = $a[0]->href; |
851 | $tmpEntry['tags'] = $a[0]->tags; | 851 | $tmpEntry['tags'] = $a[0]->tags; |
852 | $tmpEntry['is_read'] = $read; | 852 | $tmpEntry['is_read'] = $read; |
853 | if ($tmpEntry['url']) { | 853 | if ($tmpEntry['url']) { |
854 | $data[] = $tmpEntry; | 854 | $data[] = $tmpEntry; |
855 | } | 855 | } |
856 | } | 856 | } |
857 | # the second <ol/ul> is for read links | 857 | # the second <ol/ul> is for read links |
858 | $read = ((sizeof($data) && $read)?0:1); | 858 | $read = ((sizeof($data) && $read)?0:1); |
859 | } | 859 | } |
860 | } | 860 | } |
861 | } | 861 | } |
@@ -866,16 +866,16 @@ class Poche | |||
866 | $data[] = $record; | 866 | $data[] = $record; |
867 | foreach ($record as $record2) { | 867 | foreach ($record as $record2) { |
868 | if (is_array($record2)) { | 868 | if (is_array($record2)) { |
869 | $data[] = $record2; | 869 | $data[] = $record2; |
870 | } | 870 | } |
871 | } | 871 | } |
872 | } | 872 | } |
873 | } | 873 | } |
874 | 874 | ||
875 | $i = 0; //counter for articles inserted | 875 | $urlsInserted = array(); //urls of articles inserted |
876 | foreach ($data as $record) { | 876 | foreach ($data as $record) { |
877 | $url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') ); | 877 | $url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') ); |
878 | if ( $url ) { | 878 | if ( $url and !in_array($url, $urlsInserted) ) { |
879 | $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>'); | 879 | $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>'); |
880 | $body = (isset($record['content']) ? $record['content'] : ''); | 880 | $body = (isset($record['content']) ? $record['content'] : ''); |
881 | $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0)); | 881 | $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0)); |
@@ -883,19 +883,21 @@ class Poche | |||
883 | //insert new record | 883 | //insert new record |
884 | $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead); | 884 | $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead); |
885 | if ( $id ) { | 885 | if ( $id ) { |
886 | //increment no of records inserted | 886 | $urlsInserted[] = $url; //add |
887 | $i++; | 887 | |
888 | if ( isset($record['tags']) && trim($record['tags']) ) { | 888 | if ( isset($record['tags']) && trim($record['tags']) ) { |
889 | //@TODO: set tags | 889 | //@TODO: set tags |
890 | 890 | ||
891 | } | 891 | } |
892 | } | 892 | } |
893 | } | 893 | } |
894 | } | 894 | } |
895 | 895 | ||
896 | $i = sizeof($urlsInserted); | ||
896 | if ( $i > 0 ) { | 897 | if ( $i > 0 ) { |
897 | $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".')); | 898 | $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".')); |
898 | } | 899 | } |
900 | Tools::logm('Import of articles finished: '.$i.' articles added (w/o content if not provided).'); | ||
899 | } | 901 | } |
900 | //file parsing finished here | 902 | //file parsing finished here |
901 | 903 | ||
@@ -906,30 +908,32 @@ class Poche | |||
906 | if ( $recordsDownloadRequired == 0 ) { | 908 | if ( $recordsDownloadRequired == 0 ) { |
907 | //nothing to download | 909 | //nothing to download |
908 | $this->messages->add('s', _('Import finished.')); | 910 | $this->messages->add('s', _('Import finished.')); |
911 | Tools::logm('Import finished completely'); | ||
909 | Tools::redirect(); | 912 | Tools::redirect(); |
910 | } | 913 | } |
911 | else { | 914 | else { |
912 | //if just inserted - don't download anything, download will start in next reload | 915 | //if just inserted - don't download anything, download will start in next reload |
913 | if ( !isset($_FILES['file']) ) { | 916 | if ( !isset($_FILES['file']) ) { |
914 | //download next batch | 917 | //download next batch |
918 | Tools::logm('Fetching next batch of articles...'); | ||
915 | $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT); | 919 | $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT); |
916 | 920 | ||
917 | $config = HTMLPurifier_Config::createDefault(); | 921 | $purifier = $this->getPurifier(); |
918 | $config->set('Cache.SerializerPath', CACHE); | ||
919 | $purifier = new HTMLPurifier($config); | ||
920 | 922 | ||
921 | foreach ($items as $item) { | 923 | foreach ($items as $item) { |
922 | $url = new Url(base64_encode($item['url'])); | 924 | $url = new Url(base64_encode($item['url'])); |
923 | $content = Tools::getPageContent($url); | 925 | Tools::logm('Fetching article '.$item['id']); |
926 | $content = Tools::getPageContent($url); | ||
924 | 927 | ||
925 | $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled')); | 928 | $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled')); |
926 | $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined')); | 929 | $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined')); |
927 | 930 | ||
928 | //clean content to prevent xss attack | 931 | //clean content to prevent xss attack |
929 | $title = $purifier->purify($title); | 932 | $title = $purifier->purify($title); |
930 | $body = $purifier->purify($body); | 933 | $body = $purifier->purify($body); |
931 | 934 | ||
932 | $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId()); | 935 | $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId()); |
936 | Tools::logm('Article '.$item['id'].' updated.'); | ||
933 | } | 937 | } |
934 | 938 | ||
935 | } | 939 | } |
@@ -942,16 +946,15 @@ class Poche | |||
942 | * export poche entries in json | 946 | * export poche entries in json |
943 | * @return json all poche entries | 947 | * @return json all poche entries |
944 | */ | 948 | */ |
945 | public function export() | 949 | public function export() { |
946 | { | 950 | $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json"; |
947 | $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json"; | 951 | header('Content-Disposition: attachment; filename='.$filename); |
948 | header('Content-Disposition: attachment; filename='.$filename); | 952 | |
949 | 953 | $entries = $this->store->retrieveAll($this->user->getId()); | |
950 | $entries = $this->store->retrieveAll($this->user->getId()); | 954 | echo $this->tpl->render('export.twig', array( |
951 | echo $this->tpl->render('export.twig', array( | 955 | 'export' => Tools::renderJson($entries), |
952 | 'export' => Tools::renderJson($entries), | 956 | )); |
953 | )); | 957 | Tools::logm('export view'); |
954 | Tools::logm('export view'); | ||
955 | } | 958 | } |
956 | 959 | ||
957 | /** | 960 | /** |
@@ -959,43 +962,42 @@ class Poche | |||
959 | * @param string $which 'prod' or 'dev' | 962 | * @param string $which 'prod' or 'dev' |
960 | * @return string latest $which version | 963 | * @return string latest $which version |
961 | */ | 964 | */ |
962 | private function getPocheVersion($which = 'prod') | 965 | private function getPocheVersion($which = 'prod') { |
963 | { | 966 | $cache_file = CACHE . '/' . $which; |
964 | $cache_file = CACHE . '/' . $which; | 967 | $check_time = time(); |
965 | $check_time = time(); | 968 | |
966 | 969 | # checks if the cached version file exists | |
967 | # checks if the cached version file exists | 970 | if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) { |
968 | if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) { | 971 | $version = file_get_contents($cache_file); |
969 | $version = file_get_contents($cache_file); | 972 | $check_time = filemtime($cache_file); |
970 | $check_time = filemtime($cache_file); | 973 | } else { |
971 | } else { | 974 | $version = file_get_contents('http://static.wallabag.org/versions/' . $which); |
972 | $version = file_get_contents('http://static.wallabag.org/versions/' . $which); | 975 | file_put_contents($cache_file, $version, LOCK_EX); |
973 | file_put_contents($cache_file, $version, LOCK_EX); | 976 | } |
974 | } | 977 | return array($version, $check_time); |
975 | return array($version, $check_time); | ||
976 | } | 978 | } |
977 | 979 | ||
978 | public function generateToken() | 980 | public function generateToken() |
979 | { | 981 | { |
980 | if (ini_get('open_basedir') === '') { | 982 | if (ini_get('open_basedir') === '') { |
981 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | 983 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
982 | echo 'This is a server using Windows!'; | 984 | echo 'This is a server using Windows!'; |
983 | // alternative to /dev/urandom for Windows | 985 | // alternative to /dev/urandom for Windows |
984 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); | 986 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); |
985 | } else { | 987 | } else { |
986 | $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15); | 988 | $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15); |
987 | } | ||
988 | } | ||
989 | else { | ||
990 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); | ||
991 | } | 989 | } |
990 | } | ||
991 | else { | ||
992 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); | ||
993 | } | ||
992 | 994 | ||
993 | $token = str_replace('+', '', $token); | 995 | $token = str_replace('+', '', $token); |
994 | $this->store->updateUserConfig($this->user->getId(), 'token', $token); | 996 | $this->store->updateUserConfig($this->user->getId(), 'token', $token); |
995 | $currentConfig = $_SESSION['poche_user']->config; | 997 | $currentConfig = $_SESSION['poche_user']->config; |
996 | $currentConfig['token'] = $token; | 998 | $currentConfig['token'] = $token; |
997 | $_SESSION['poche_user']->setConfig($currentConfig); | 999 | $_SESSION['poche_user']->setConfig($currentConfig); |
998 | Tools::redirect(); | 1000 | Tools::redirect(); |
999 | } | 1001 | } |
1000 | 1002 | ||
1001 | public function generateFeeds($token, $user_id, $tag_id, $type = 'home') | 1003 | public function generateFeeds($token, $user_id, $tag_id, $type = 'home') |
@@ -1031,6 +1033,7 @@ class Poche | |||
1031 | foreach ($entries as $entry) { | 1033 | foreach ($entries as $entry) { |
1032 | $newItem = $feed->createNewItem(); | 1034 | $newItem = $feed->createNewItem(); |
1033 | $newItem->setTitle($entry['title']); | 1035 | $newItem->setTitle($entry['title']); |
1036 | $newItem->setSource(Tools::getPocheUrl() . '?view=view&id=' . $entry['id']); | ||
1034 | $newItem->setLink($entry['url']); | 1037 | $newItem->setLink($entry['url']); |
1035 | $newItem->setDate(time()); | 1038 | $newItem->setDate(time()); |
1036 | $newItem->setDescription($entry['content']); | 1039 | $newItem->setDescription($entry['content']); |
@@ -1057,4 +1060,16 @@ class Poche | |||
1057 | $this->messages->add('s', _('Cache deleted.')); | 1060 | $this->messages->add('s', _('Cache deleted.')); |
1058 | Tools::redirect(); | 1061 | Tools::redirect(); |
1059 | } | 1062 | } |
1063 | |||
1064 | /** | ||
1065 | * return new purifier object with actual config | ||
1066 | */ | ||
1067 | protected function getPurifier() { | ||
1068 | $config = HTMLPurifier_Config::createDefault(); | ||
1069 | $config->set('Cache.SerializerPath', CACHE); | ||
1070 | $config->set('HTML.SafeIframe', true); | ||
1071 | $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo$purifier = new HTMLPurifier($config); | ||
1072 | |||
1073 | return new HTMLPurifier($config); | ||
1074 | } | ||
1060 | } | 1075 | } |
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php index a130e94b..7f064020 100755 --- a/inc/poche/Tools.class.php +++ b/inc/poche/Tools.class.php | |||
@@ -59,8 +59,10 @@ class Tools | |||
59 | return $scriptname; | 59 | return $scriptname; |
60 | } | 60 | } |
61 | 61 | ||
62 | $host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'])); | ||
63 | |||
62 | return 'http' . ($https ? 's' : '') . '://' | 64 | return 'http' . ($https ? 's' : '') . '://' |
63 | . $_SERVER["HTTP_HOST"] . $serverport . $scriptname; | 65 | . $host . $serverport . $scriptname; |
64 | } | 66 | } |
65 | 67 | ||
66 | public static function redirect($url = '') | 68 | public static function redirect($url = '') |