aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cron.php53
-rwxr-xr-xinc/poche/Database.class.php67
-rwxr-xr-xinc/poche/Poche.class.php110
-rw-r--r--inc/poche/Tools.class.php63
-rw-r--r--index.php2
-rw-r--r--themes/baggy/config.twig33
6 files changed, 225 insertions, 103 deletions
diff --git a/cron.php b/cron.php
new file mode 100644
index 00000000..cc137ca2
--- /dev/null
+++ b/cron.php
@@ -0,0 +1,53 @@
1<?php
2
3include_once 'inc/poche/global.inc.php';
4include_once 'inc/poche/config.inc.php';
5
6if (php_sapi_name() === 'cli') {
7 $options_cli = getopt('', array(
8 'limit::',
9 'user-id::',
10 'token::',
11 ));
12}
13else {
14 $options_cli = $_GET;
15}
16
17$limit = ! empty($options_cli['limit']) && ctype_digit($options_cli['limit']) ? (int) $options_cli['limit'] : 10;
18$user_id = ! empty($options_cli['user-id']) && ctype_digit($options_cli['user-id']) ? (int) $options_cli['user-id'] : null;
19$token = ! empty($options_cli['token']) ? $options_cli['token'] : null;
20
21if (is_null($user_id)) {
22 die('You must give a user id');
23}
24
25if (is_null($token)) {
26 die('You must give a token');
27}
28
29$store = new Database();
30$config = $store->getConfigUser($user_id);
31
32if ($token != $config['token']) {
33 die(_('Uh, there is a problem with the cron.'));
34}
35
36$items = $store->retrieveUnfetchedEntries($user_id, $limit);
37
38foreach ($items as $item) {
39 $url = new Url(base64_encode($item['url']));
40 $content = Tools::getPageContent($url);
41
42 $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled');
43 $body = $content['rss']['channel']['item']['description'];
44
45 // // clean content from prevent xss attack
46 // $config = HTMLPurifier_Config::createDefault();
47 // $purifier = new HTMLPurifier($config);
48 // $title = $purifier->purify($title);
49 // $body = $purifier->purify($body);
50
51
52 $store->updateContentAndTitle($item['id'], $title, $body, $user_id);
53} \ No newline at end of file
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index c998fe14..edc775f5 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -230,8 +230,30 @@ class Database {
230 } 230 }
231 } 231 }
232 232
233 public function updateContentAndTitle($id, $title, $body, $user_id) {
234 $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?';
235 $params_action = array($body, $title, $id, $user_id);
236 $query = $this->executeQuery($sql_action, $params_action);
237
238 return $query;
239 }
240
241 public function retrieveUnfetchedEntries($user_id, $limit) {
242
243 $sql_limit = "LIMIT 0,".$limit;
244 if (STORAGE == 'postgres') {
245 $sql_limit = "LIMIT ".$limit." OFFSET 0";
246 }
247
248 $sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND user_id=? ORDER BY id " . $sql_limit;
249 $query = $this->executeQuery($sql, array($user_id));
250 $entries = $query->fetchAll();
251
252 return $entries;
253 }
254
233 public function retrieveAll($user_id) { 255 public function retrieveAll($user_id) {
234 $sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id"; 256 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? ORDER BY id";
235 $query = $this->executeQuery($sql, array($user_id)); 257 $query = $this->executeQuery($sql, array($user_id));
236 $entries = $query->fetchAll(); 258 $entries = $query->fetchAll();
237 259
@@ -250,7 +272,7 @@ class Database {
250 272
251 public function retrieveOneByURL($url, $user_id) { 273 public function retrieveOneByURL($url, $user_id) {
252 $entry = NULL; 274 $entry = NULL;
253 $sql = "SELECT * FROM entries WHERE url=? AND user_id=?"; 275 $sql = "SELECT * FROM entries WHERE content <> '' AND url=? AND user_id=?";
254 $params = array($url, $user_id); 276 $params = array($url, $user_id);
255 $query = $this->executeQuery($sql, $params); 277 $query = $this->executeQuery($sql, $params);
256 $entry = $query->fetchAll(); 278 $entry = $query->fetchAll();
@@ -267,21 +289,22 @@ class Database {
267 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) { 289 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) {
268 switch ($view) { 290 switch ($view) {
269 case 'archive': 291 case 'archive':
270 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? "; 292 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
271 $params = array($user_id, 1); 293 $params = array($user_id, 1);
272 break; 294 break;
273 case 'fav' : 295 case 'fav' :
274 $sql = "SELECT * FROM entries WHERE user_id=? AND is_fav=? "; 296 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_fav=? ";
275 $params = array($user_id, 1); 297 $params = array($user_id, 1);
276 break; 298 break;
277 case 'tag' : 299 case 'tag' :
278 $sql = "SELECT entries.* FROM entries 300 $sql = "SELECT entries.* FROM entries
279 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 301 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
280 WHERE entries.user_id=? AND tags_entries.tag_id = ? "; 302 WHERE entries.content <> '' AND
303 entries.user_id=? AND tags_entries.tag_id = ? ";
281 $params = array($user_id, $tag_id); 304 $params = array($user_id, $tag_id);
282 break; 305 break;
283 default: 306 default:
284 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? "; 307 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
285 $params = array($user_id, 0); 308 $params = array($user_id, 0);
286 break; 309 break;
287 } 310 }
@@ -294,24 +317,25 @@ class Database {
294 return $entries; 317 return $entries;
295 } 318 }
296 319
297 public function getEntriesByViewCount($view, $user_id, $tag_id = 0) { 320 public function getEntriesByViewCount($view, $user_id, $tag_id = 0) {
298 switch ($view) { 321 switch ($view) {
299 case 'archive': 322 case 'archive':
300 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? "; 323 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
301 $params = array($user_id, 1); 324 $params = array($user_id, 1);
302 break; 325 break;
303 case 'fav' : 326 case 'fav' :
304 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_fav=? "; 327 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_fav=? ";
305 $params = array($user_id, 1); 328 $params = array($user_id, 1);
306 break; 329 break;
307 case 'tag' : 330 case 'tag' :
308 $sql = "SELECT count(*) FROM entries 331 $sql = "SELECT count(*) FROM entries
309 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 332 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
310 WHERE entries.user_id=? AND tags_entries.tag_id = ? "; 333 WHERE entries.content <> '' AND
311 $params = array($user_id, $tag_id); 334 entries.user_id=? AND tags_entries.tag_id = ? ";
312 break; 335 $params = array($user_id, $tag_id);
336 break;
313 default: 337 default:
314 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? "; 338 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
315 $params = array($user_id, 0); 339 $params = array($user_id, 0);
316 break; 340 break;
317 } 341 }
@@ -319,7 +343,7 @@ class Database {
319 $query = $this->executeQuery($sql, $params); 343 $query = $this->executeQuery($sql, $params);
320 list($count) = $query->fetch(); 344 list($count) = $query->fetch();
321 345
322 return $count; 346 return $count;
323 } 347 }
324 348
325 public function updateContent($id, $content, $user_id) { 349 public function updateContent($id, $content, $user_id) {
@@ -369,7 +393,7 @@ class Database {
369 $sql = "SELECT DISTINCT tags.* FROM tags 393 $sql = "SELECT DISTINCT tags.* FROM tags
370 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 394 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
371 LEFT JOIN entries ON tags_entries.entry_id=entries.id 395 LEFT JOIN entries ON tags_entries.entry_id=entries.id
372 WHERE entries.user_id=?"; 396 WHERE entries.content <> '' AND entries.user_id=?";
373 $query = $this->executeQuery($sql, array($user_id)); 397 $query = $this->executeQuery($sql, array($user_id));
374 $tags = $query->fetchAll(); 398 $tags = $query->fetchAll();
375 399
@@ -381,7 +405,7 @@ class Database {
381 $sql = "SELECT DISTINCT tags.* FROM tags 405 $sql = "SELECT DISTINCT tags.* FROM tags
382 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 406 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
383 LEFT JOIN entries ON tags_entries.entry_id=entries.id 407 LEFT JOIN entries ON tags_entries.entry_id=entries.id
384 WHERE tags.id=? AND entries.user_id=?"; 408 WHERE entries.content <> '' AND tags.id=? AND entries.user_id=?";
385 $params = array(intval($id), $user_id); 409 $params = array(intval($id), $user_id);
386 $query = $this->executeQuery($sql, $params); 410 $query = $this->executeQuery($sql, $params);
387 $tag = $query->fetchAll(); 411 $tag = $query->fetchAll();
@@ -393,7 +417,8 @@ class Database {
393 $sql = 417 $sql =
394 "SELECT entries.* FROM entries 418 "SELECT entries.* FROM entries
395 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 419 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
396 WHERE tags_entries.tag_id = ? AND entries.user_id=?"; 420 WHERE entries.content <> '' AND
421 tags_entries.tag_id = ? AND entries.user_id=?";
397 $query = $this->executeQuery($sql, array($tag_id, $user_id)); 422 $query = $this->executeQuery($sql, array($tag_id, $user_id));
398 $entries = $query->fetchAll(); 423 $entries = $query->fetchAll();
399 424
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index ba262c98..fb4e1a7f 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -362,60 +362,6 @@ class Poche
362 ); 362 );
363 } 363 }
364 364
365 protected function getPageContent(Url $url)
366 {
367 // Saving and clearing context
368 $REAL = array();
369 foreach( $GLOBALS as $key => $value ) {
370 if( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
371 $GLOBALS[$key] = array();
372 $REAL[$key] = $value;
373 }
374 }
375 // Saving and clearing session
376 $REAL_SESSION = array();
377 foreach( $_SESSION as $key => $value ) {
378 $REAL_SESSION[$key] = $value;
379 unset($_SESSION[$key]);
380 }
381
382 // Running code in different context
383 $scope = function() {
384 extract( func_get_arg(1) );
385 $_GET = $_REQUEST = array(
386 "url" => $url->getUrl(),
387 "max" => 5,
388 "links" => "preserve",
389 "exc" => "",
390 "format" => "json",
391 "submit" => "Create Feed"
392 );
393 ob_start();
394 require func_get_arg(0);
395 $json = ob_get_flush();
396 return $json;
397 };
398 $json = $scope( "inc/3rdparty/makefulltextfeed.php", array("url" => $url) );
399
400 // Clearing and restoring context
401 foreach( $GLOBALS as $key => $value ) {
402 if( $key != "GLOBALS" && $key != "_SESSION" ) {
403 unset($GLOBALS[$key]);
404 }
405 }
406 foreach( $REAL as $key => $value ) {
407 $GLOBALS[$key] = $value;
408 }
409 // Clearing and restoring session
410 foreach( $_SESSION as $key => $value ) {
411 unset($_SESSION[$key]);
412 }
413 foreach( $REAL_SESSION as $key => $value ) {
414 $_SESSION[$key] = $value;
415 }
416 return json_decode($json, true);
417 }
418
419 /** 365 /**
420 * Call action (mark as fav, archive, delete, etc.) 366 * Call action (mark as fav, archive, delete, etc.)
421 */ 367 */
@@ -424,15 +370,21 @@ class Poche
424 switch ($action) 370 switch ($action)
425 { 371 {
426 case 'add': 372 case 'add':
427 $content = $this->getPageContent($url); 373 if (!$import) {
428 $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'); 374 $content = Tools::getPageContent($url);
429 $body = $content['rss']['channel']['item']['description']; 375 $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled');
430 376 $body = $content['rss']['channel']['item']['description'];
431 // clean content from prevent xss attack 377
432 $config = HTMLPurifier_Config::createDefault(); 378 // clean content from prevent xss attack
433 $purifier = new HTMLPurifier($config); 379 $config = HTMLPurifier_Config::createDefault();
434 $title = $purifier->purify($title); 380 $purifier = new HTMLPurifier($config);
435 $body = $purifier->purify($body); 381 $title = $purifier->purify($title);
382 $body = $purifier->purify($body);
383 }
384 else {
385 $title = '';
386 $body = '';
387 }
436 388
437 //search for possible duplicate if not in import mode 389 //search for possible duplicate if not in import mode
438 if (!$import) { 390 if (!$import) {
@@ -903,7 +855,7 @@ class Poche
903 # the second <ol> is for read links 855 # the second <ol> is for read links
904 $read = 1; 856 $read = 1;
905 } 857 }
906 $this->messages->add('s', _('import from instapaper completed')); 858 $this->messages->add('s', _('import from instapaper completed. You have to execute the cron to fetch content.'));
907 Tools::logm('import from instapaper completed'); 859 Tools::logm('import from instapaper completed');
908 Tools::redirect(); 860 Tools::redirect();
909 } 861 }
@@ -947,7 +899,7 @@ class Poche
947 # the second <ul> is for read links 899 # the second <ul> is for read links
948 $read = 1; 900 $read = 1;
949 } 901 }
950 $this->messages->add('s', _('import from pocket completed')); 902 $this->messages->add('s', _('import from pocket completed. You have to execute the cron to fetch content.'));
951 Tools::logm('import from pocket completed'); 903 Tools::logm('import from pocket completed');
952 Tools::redirect(); 904 Tools::redirect();
953 } 905 }
@@ -1003,7 +955,7 @@ class Poche
1003 } 955 }
1004 } 956 }
1005 } 957 }
1006 $this->messages->add('s', _('import from Readability completed. ' . $count . ' new links.')); 958 $this->messages->add('s', _('import from Readability completed. You have to execute the cron to fetch content.'));
1007 Tools::logm('import from Readability completed'); 959 Tools::logm('import from Readability completed');
1008 Tools::redirect(); 960 Tools::redirect();
1009 } 961 }
@@ -1049,7 +1001,7 @@ class Poche
1049 } 1001 }
1050 1002
1051 } 1003 }
1052 $this->messages->add('s', _('import from Poche completed. ' . $count . ' new links.')); 1004 $this->messages->add('s', _('import from Poche completed. You have to execute the cron to fetch content.'));
1053 Tools::logm('import from Poche completed'); 1005 Tools::logm('import from Poche completed');
1054 Tools::redirect(); 1006 Tools::redirect();
1055 } 1007 }
@@ -1074,13 +1026,7 @@ class Poche
1074 Tools::redirect(); 1026 Tools::redirect();
1075 } 1027 }
1076 1028
1077 $targetDefinition = 'IMPORT_' . strtoupper($from) . '_FILE'; 1029 $targetFile = CACHE . '/' . constant(strtoupper($from) . '_FILE');
1078 $targetFile = constant($targetDefinition);
1079
1080 if (! defined($targetDefinition)) {
1081 $this->messages->add('e', _('Incomplete inc/poche/define.inc.php file, please define "' . $targetDefinition . '".'));
1082 Tools::redirect();
1083 }
1084 1030
1085 if (! file_exists($targetFile)) { 1031 if (! file_exists($targetFile)) {
1086 $this->messages->add('e', _('Could not find required "' . $targetFile . '" import file.')); 1032 $this->messages->add('e', _('Could not find required "' . $targetFile . '" import file.'));
@@ -1090,6 +1036,22 @@ class Poche
1090 $this->$providers[$from]($targetFile); 1036 $this->$providers[$from]($targetFile);
1091 } 1037 }
1092 1038
1039 public function uploadFile() {
1040 if(isset($_FILES['file']))
1041 {
1042 $dir = CACHE . '/';
1043 $file = basename($_FILES['file']['name']);
1044 if(move_uploaded_file($_FILES['file']['tmp_name'], $dir . $file)) {
1045 $this->messages->add('s', _('File uploaded. You can now execute import.'));
1046 }
1047 else {
1048 $this->messages->add('e', _('Error while importing file. Do you have access to upload it?'));
1049 }
1050 }
1051
1052 Tools::redirect('?view=config');
1053 }
1054
1093 /** 1055 /**
1094 * export poche entries in json 1056 * export poche entries in json
1095 * @return json all poche entries 1057 * @return json all poche entries
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index 4ed28ed1..eeb101b4 100644
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -193,7 +193,7 @@ class Tools
193 193
194 public static function logm($message) 194 public static function logm($message)
195 { 195 {
196 if (DEBUG_POCHE) { 196 if (DEBUG_POCHE && php_sapi_name() != 'cli') {
197 $t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n"; 197 $t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n";
198 file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND); 198 file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND);
199 error_log('DEBUG POCHE : ' . $message); 199 error_log('DEBUG POCHE : ' . $message);
@@ -241,7 +241,6 @@ class Tools
241 } 241 }
242 } 242 }
243 243
244
245 public static function download_db() { 244 public static function download_db() {
246 header('Content-Disposition: attachment; filename="poche.sqlite.gz"'); 245 header('Content-Disposition: attachment; filename="poche.sqlite.gz"');
247 self::status(200); 246 self::status(200);
@@ -252,4 +251,64 @@ class Tools
252 251
253 exit; 252 exit;
254 } 253 }
254
255 public static function getPageContent(Url $url)
256 {
257 // Saving and clearing context
258 $REAL = array();
259 foreach( $GLOBALS as $key => $value ) {
260 if( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
261 $GLOBALS[$key] = array();
262 $REAL[$key] = $value;
263 }
264 }
265 // Saving and clearing session
266 if ( isset($_SESSION) ) {
267 $REAL_SESSION = array();
268 foreach( $_SESSION as $key => $value ) {
269 $REAL_SESSION[$key] = $value;
270 unset($_SESSION[$key]);
271 }
272 }
273
274 // Running code in different context
275 $scope = function() {
276 extract( func_get_arg(1) );
277 $_GET = $_REQUEST = array(
278 "url" => $url->getUrl(),
279 "max" => 5,
280 "links" => "preserve",
281 "exc" => "",
282 "format" => "json",
283 "submit" => "Create Feed"
284 );
285 ob_start();
286 require func_get_arg(0);
287 $json = ob_get_contents();
288 ob_end_clean();
289 return $json;
290 };
291 $json = $scope( "inc/3rdparty/makefulltextfeed.php", array("url" => $url) );
292
293 // Clearing and restoring context
294 foreach( $GLOBALS as $key => $value ) {
295 if( $key != "GLOBALS" && $key != "_SESSION" ) {
296 unset($GLOBALS[$key]);
297 }
298 }
299 foreach( $REAL as $key => $value ) {
300 $GLOBALS[$key] = $value;
301 }
302 // Clearing and restoring session
303 if ( isset($REAL_SESSION) ) {
304 foreach( $_SESSION as $key => $value ) {
305 unset($_SESSION[$key]);
306 }
307 foreach( $REAL_SESSION as $key => $value ) {
308 $_SESSION[$key] = $value;
309 }
310 }
311
312 return json_decode($json, true);
313 }
255} 314}
diff --git a/index.php b/index.php
index 06ab7d3c..5ca8bef5 100644
--- a/index.php
+++ b/index.php
@@ -74,6 +74,8 @@ if (isset($_GET['login'])) {
74 $poche->updateTheme(); 74 $poche->updateTheme();
75} elseif (isset($_GET['updatelanguage'])) { 75} elseif (isset($_GET['updatelanguage'])) {
76 $poche->updateLanguage(); 76 $poche->updateLanguage();
77} elseif (isset($_GET['uploadfile'])) {
78 $poche->uploadFile();
77} elseif (isset($_GET['feed'])) { 79} elseif (isset($_GET['feed'])) {
78 if (isset($_GET['action']) && $_GET['action'] == 'generate') { 80 if (isset($_GET['action']) && $_GET['action'] == 'generate') {
79 $poche->generateToken(); 81 $poche->generateToken();
diff --git a/themes/baggy/config.twig b/themes/baggy/config.twig
index d83b69ab..95db92fe 100644
--- a/themes/baggy/config.twig
+++ b/themes/baggy/config.twig
@@ -105,15 +105,36 @@
105 {% endif %} 105 {% endif %}
106 106
107 <h2>{% trans "Import" %}</h2> 107 <h2>{% trans "Import" %}</h2>
108 <p>{% trans "Please execute the import script locally as it can take a very long time." %}</p> 108 <p>1. {% trans "Select a file on your computer and upload it." %}</p>
109 <p>{% trans "More info in the official documentation:" %} <a href="http://doc.wallabag.org/doku.php?id=users:migrate">wallabag.org</a></p> 109 <form method="post" action="?uploadfile" name="uploadfile" enctype="multipart/form-data">
110 <fieldset class="w500p">
111 <div class="row">
112 <label class="col w150p" for="file">{% trans "File:" %}</label>
113 <input class="col" type="file" id="file" name="file" tabindex="4">
114 </div>
115 <div class="row mts txtcenter">
116 <button class="bouton" type="submit" tabindex="4">{% trans "Upload" %}</button>
117 </div>
118 </fieldset>
119 <input type="hidden" name="MAX_FILE_SIZE" value="1048576">
120 <input type="hidden" name="returnurl" value="{{ referer }}">
121 </form>
122 <p>2. {% trans "Then, click on the right link below." %}</p>
110 <ul> 123 <ul>
111 <li><a href="./?import&amp;from=pocket">{% trans "Import from Pocket" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('POCKET_FILE')) }}</li> 124 <li><a href="./?import&amp;from=pocket">{% trans "Import from Pocket" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCKET_FILE')) }}</li>
112 <li><a href="./?import&amp;from=readability">{% trans "Import from Readability" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('READABILITY_FILE')) }}</li> 125 <li><a href="./?import&amp;from=readability">{% trans "Import from Readability" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('READABILITY_FILE')) }}</li>
113 <li><a href="./?import&amp;from=instapaper">{% trans "Import from Instapaper" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('INSTAPAPER_FILE')) }}</li> 126 <li><a href="./?import&amp;from=instapaper">{% trans "Import from Instapaper" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('INSTAPAPER_FILE')) }}</li>
114 <li><a href="./?import&amp;from=poche">{% trans "Import from wallabag" %}</a> {{ '(you must have a %s file on your server)'|trans|format(constant('POCHE_FILE')) }}</li> 127 <li><a href="./?import&amp;from=poche">{% trans "Import from wallabag" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCHE_FILE')) }}</li>
115 </ul> 128 </ul>
116 129
130 {% if token == '' %}
131 <p>{% trans "3. Your feed token is currently empty and must first be generated to fetch content. Click <a href='?feed&amp;action=generate'>here to generate it</a>." %}</p>
132 {% else %}
133 <p>3. {% trans "You can fetch content for imported items." %} <a href="cron.php?limit=10&amp;user-id={{ user_id }}&amp;token={{token}}" target="_blank">Click here</a> to fetch content for 10 articles.</p>
134 <p>{% trans "You can also create a cron task:" %}</p>
135 <pre><code>0 */4 * * * cd /path/to/wallabag && php cron.php --limit=10 --user-id={{user_id}} --token={{token}} >/dev/null 2>&1</code></pre>
136 {% endif %}
137
117 <h2>{% trans "Export your wallabag data" %}</h2> 138 <h2>{% trans "Export your wallabag data" %}</h2>
118 {% if constant('STORAGE') == 'sqlite' %} 139 {% if constant('STORAGE') == 'sqlite' %}
119 <p><a href="?download" target="_blank">{% trans "Click here" %}</a> {% trans "to download your database." %}</p>{% endif %} 140 <p><a href="?download" target="_blank">{% trans "Click here" %}</a> {% trans "to download your database." %}</p>{% endif %}