]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #532 from wallabag/upload-file
authorNicolas Lœuillet <nicolas@loeuillet.org>
Fri, 7 Mar 2014 12:26:56 +0000 (13:26 +0100)
committerNicolas Lœuillet <nicolas@loeuillet.org>
Fri, 7 Mar 2014 12:26:56 +0000 (13:26 +0100)
New import system

cron.php [new file with mode: 0644]
inc/poche/Database.class.php
inc/poche/Poche.class.php
inc/poche/Tools.class.php
index.php
themes/baggy/config.twig

diff --git a/cron.php b/cron.php
new file mode 100644 (file)
index 0000000..cc137ca
--- /dev/null
+++ b/cron.php
@@ -0,0 +1,53 @@
+<?php
+
+include_once 'inc/poche/global.inc.php';
+include_once 'inc/poche/config.inc.php';
+
+if (php_sapi_name() === 'cli') {
+    $options_cli = getopt('', array(
+        'limit::',
+        'user-id::',
+        'token::',
+    ));
+}
+else {
+    $options_cli = $_GET;
+}
+
+$limit = ! empty($options_cli['limit']) && ctype_digit($options_cli['limit']) ? (int) $options_cli['limit'] : 10;
+$user_id = ! empty($options_cli['user-id']) && ctype_digit($options_cli['user-id']) ? (int) $options_cli['user-id'] : null;
+$token = ! empty($options_cli['token']) ? $options_cli['token'] : null;
+
+if (is_null($user_id)) {
+    die('You must give a user id');
+}
+
+if (is_null($token)) {
+    die('You must give a token');
+}
+
+$store = new Database();
+$config = $store->getConfigUser($user_id);
+
+if ($token != $config['token']) {
+    die(_('Uh, there is a problem with the cron.'));
+}
+
+$items = $store->retrieveUnfetchedEntries($user_id, $limit);
+
+foreach ($items as $item) {
+    $url = new Url(base64_encode($item['url']));
+    $content = Tools::getPageContent($url);
+
+    $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled');
+    $body = $content['rss']['channel']['item']['description'];
+
+    // // clean content from prevent xss attack
+    // $config = HTMLPurifier_Config::createDefault();
+    // $purifier = new HTMLPurifier($config);
+    // $title = $purifier->purify($title);
+    // $body = $purifier->purify($body);
+
+
+    $store->updateContentAndTitle($item['id'], $title, $body, $user_id);
+}
\ No newline at end of file
index c998fe14db5fcd40dd79a9ab9c22501633c39139..edc775f594d778ffc70a0d8b3a941b63470862ba 100755 (executable)
@@ -230,8 +230,30 @@ class Database {
         }
     }
 
+    public function updateContentAndTitle($id, $title, $body, $user_id) {
+        $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?';
+        $params_action = array($body, $title, $id, $user_id);
+        $query = $this->executeQuery($sql_action, $params_action);
+
+        return $query;
+    }
+
+    public function retrieveUnfetchedEntries($user_id, $limit) {
+
+        $sql_limit = "LIMIT 0,".$limit;
+        if (STORAGE == 'postgres') {
+            $sql_limit = "LIMIT ".$limit." OFFSET 0";
+        }
+
+        $sql        = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND user_id=? ORDER BY id " . $sql_limit;
+        $query      = $this->executeQuery($sql, array($user_id));
+        $entries    = $query->fetchAll();
+
+        return $entries;
+    }
+
     public function retrieveAll($user_id) {
-        $sql        = "SELECT * FROM entries WHERE user_id=? ORDER BY id";
+        $sql        = "SELECT * FROM entries WHERE content <> '' AND user_id=? ORDER BY id";
         $query      = $this->executeQuery($sql, array($user_id));
         $entries    = $query->fetchAll();
 
@@ -250,7 +272,7 @@ class Database {
 
     public function retrieveOneByURL($url, $user_id) {
         $entry  = NULL;
-        $sql    = "SELECT * FROM entries WHERE url=? AND user_id=?";
+        $sql    = "SELECT * FROM entries WHERE content <> '' AND url=? AND user_id=?";
         $params = array($url, $user_id);
         $query  = $this->executeQuery($sql, $params);
         $entry  = $query->fetchAll();
@@ -267,21 +289,22 @@ class Database {
     public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) {
         switch ($view) {
             case 'archive':
-                $sql    = "SELECT * FROM entries WHERE user_id=? AND is_read=? ";
+                $sql    = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
                 $params = array($user_id, 1);
                 break;
             case 'fav' :
-                $sql    = "SELECT * FROM entries WHERE user_id=? AND is_fav=? ";
+                $sql    = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_fav=? ";
                 $params = array($user_id, 1);
                 break;
             case 'tag' :
                 $sql    = "SELECT entries.* FROM entries
                 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
-                WHERE entries.user_id=? AND tags_entries.tag_id = ? ";
+                WHERE entries.content <> '' AND
+                entries.user_id=? AND tags_entries.tag_id = ? ";
                 $params = array($user_id, $tag_id);
                 break;
             default:
-                $sql    = "SELECT * FROM entries WHERE user_id=? AND is_read=? ";
+                $sql    = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
                 $params = array($user_id, 0);
                 break;
         }
@@ -294,24 +317,25 @@ class Database {
                 return $entries;
         }
 
-    public function getEntriesByViewCount($view, $user_id, $tag_id = 0) {\r
-        switch ($view) {\r
+    public function getEntriesByViewCount($view, $user_id, $tag_id = 0) {
+        switch ($view) {
             case 'archive':
-                    $sql    = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? ";\r
+                    $sql    = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
                 $params = array($user_id, 1);
                 break;
             case 'fav' :
-                    $sql    = "SELECT count(*) FROM entries WHERE user_id=? AND is_fav=? ";\r
+                    $sql    = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_fav=? ";
                 $params = array($user_id, 1);
                 break;
-            case 'tag' :\r
-                $sql    = "SELECT count(*) FROM entries\r
-                    LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id\r
-                    WHERE entries.user_id=? AND tags_entries.tag_id = ? ";\r
-                $params = array($user_id, $tag_id);\r
-                break;\r
+            case 'tag' :
+                $sql    = "SELECT count(*) FROM entries
+                    LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
+                    WHERE entries.content <> '' AND
+                    entries.user_id=? AND tags_entries.tag_id = ? ";
+                $params = array($user_id, $tag_id);
+                break;
             default:
-                $sql    = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? ";\r
+                $sql    = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? ";
                 $params = array($user_id, 0);
                 break;
         }
@@ -319,7 +343,7 @@ class Database {
         $query = $this->executeQuery($sql, $params);
         list($count) = $query->fetch();
 
-        return $count;\r
+        return $count;
     }
 
     public function updateContent($id, $content, $user_id) {
@@ -369,7 +393,7 @@ class Database {
         $sql = "SELECT DISTINCT tags.* FROM tags
           LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
           LEFT JOIN entries ON tags_entries.entry_id=entries.id
-          WHERE entries.user_id=?";
+          WHERE entries.content <> '' AND entries.user_id=?";
         $query = $this->executeQuery($sql, array($user_id));
         $tags = $query->fetchAll();
 
@@ -381,7 +405,7 @@ class Database {
         $sql    = "SELECT DISTINCT tags.* FROM tags
           LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
           LEFT JOIN entries ON tags_entries.entry_id=entries.id
-          WHERE tags.id=? AND entries.user_id=?";
+          WHERE entries.content <> '' AND tags.id=? AND entries.user_id=?";
         $params = array(intval($id), $user_id);
         $query  = $this->executeQuery($sql, $params);
         $tag  = $query->fetchAll();
@@ -393,7 +417,8 @@ class Database {
         $sql = 
             "SELECT entries.* FROM entries
             LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
-            WHERE tags_entries.tag_id = ? AND entries.user_id=?";
+            WHERE entries.content <> '' AND
+            tags_entries.tag_id = ? AND entries.user_id=?";
         $query = $this->executeQuery($sql, array($tag_id, $user_id));
         $entries = $query->fetchAll();
 
index ba262c98ec1bb329f0f63b1d490419d6e7778ff7..fb4e1a7fed98114d8b9004538c5f52ad658a6b24 100755 (executable)
@@ -362,60 +362,6 @@ class Poche
         );
     }
 
-    protected function getPageContent(Url $url)
-    {
-        // Saving and clearing context
-        $REAL = array();
-        foreach( $GLOBALS as $key => $value ) {
-            if( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
-                $GLOBALS[$key] = array();
-                $REAL[$key] = $value;
-            }
-        }
-        // Saving and clearing session
-        $REAL_SESSION = array();
-        foreach( $_SESSION as $key => $value ) {
-            $REAL_SESSION[$key] = $value;
-            unset($_SESSION[$key]);
-        }
-
-        // Running code in different context
-        $scope = function() {
-            extract( func_get_arg(1) );
-            $_GET = $_REQUEST = array(
-                        "url" => $url->getUrl(),
-                        "max" => 5,
-                        "links" => "preserve",
-                        "exc" => "",
-                        "format" => "json",
-                        "submit" => "Create Feed"
-            );
-            ob_start();
-            require func_get_arg(0);
-            $json = ob_get_flush();
-            return $json;
-        };
-        $json = $scope( "inc/3rdparty/makefulltextfeed.php", array("url" => $url) );
-
-        // Clearing and restoring context
-        foreach( $GLOBALS as $key => $value ) {
-            if( $key != "GLOBALS" && $key != "_SESSION" ) {
-                unset($GLOBALS[$key]);
-            }
-        }
-        foreach( $REAL as $key => $value ) {
-            $GLOBALS[$key] = $value;
-        }
-        // Clearing and restoring session
-        foreach( $_SESSION as $key => $value ) {
-            unset($_SESSION[$key]);
-        }
-        foreach( $REAL_SESSION as $key => $value ) {
-            $_SESSION[$key] = $value;
-        }
-        return json_decode($json, true);
-    }
-
     /**
      * Call action (mark as fav, archive, delete, etc.)
      */
@@ -424,15 +370,21 @@ class Poche
         switch ($action)
         {
             case 'add':
-                $content = $this->getPageContent($url);
-                $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled');
-                $body = $content['rss']['channel']['item']['description'];
-
-                // clean content from prevent xss attack
-                $config = HTMLPurifier_Config::createDefault();
-                $purifier = new HTMLPurifier($config);
-                $title = $purifier->purify($title);
-                $body = $purifier->purify($body);
+                if (!$import) {
+                    $content = Tools::getPageContent($url);
+                    $title = ($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled');
+                    $body = $content['rss']['channel']['item']['description'];
+
+                    // clean content from prevent xss attack
+                    $config = HTMLPurifier_Config::createDefault();
+                    $purifier = new HTMLPurifier($config);
+                    $title = $purifier->purify($title);
+                    $body = $purifier->purify($body);
+                }
+                else {
+                    $title = '';
+                    $body = '';
+                }
 
                 //search for possible duplicate if not in import mode
                 if (!$import) {
@@ -903,7 +855,7 @@ class Poche
             # the second <ol> is for read links
             $read = 1;
         }
-        $this->messages->add('s', _('import from instapaper completed'));
+        $this->messages->add('s', _('import from instapaper completed. You have to execute the cron to fetch content.'));
         Tools::logm('import from instapaper completed');
         Tools::redirect();
     }
@@ -947,7 +899,7 @@ class Poche
             # the second <ul> is for read links
             $read = 1;
         }
-        $this->messages->add('s', _('import from pocket completed'));
+        $this->messages->add('s', _('import from pocket completed. You have to execute the cron to fetch content.'));
         Tools::logm('import from pocket completed');
         Tools::redirect();
     }
@@ -1003,7 +955,7 @@ class Poche
                 }
             }
         }
-        $this->messages->add('s', _('import from Readability completed. ' . $count . ' new links.'));
+        $this->messages->add('s', _('import from Readability completed. You have to execute the cron to fetch content.'));
         Tools::logm('import from Readability completed');
         Tools::redirect();
     }
@@ -1049,7 +1001,7 @@ class Poche
             }
             
         }
-        $this->messages->add('s', _('import from Poche completed. ' . $count . ' new links.'));
+        $this->messages->add('s', _('import from Poche completed. You have to execute the cron to fetch content.'));
         Tools::logm('import from Poche completed');
         Tools::redirect();
     }
@@ -1074,13 +1026,7 @@ class Poche
             Tools::redirect();
         }
         
-        $targetDefinition = 'IMPORT_' . strtoupper($from) . '_FILE';
-        $targetFile = constant($targetDefinition);
-        
-        if (! defined($targetDefinition)) {
-            $this->messages->add('e', _('Incomplete inc/poche/define.inc.php file, please define "' . $targetDefinition . '".'));
-            Tools::redirect();
-        }
+        $targetFile = CACHE . '/' . constant(strtoupper($from) . '_FILE');
         
         if (! file_exists($targetFile)) {
             $this->messages->add('e', _('Could not find required "' . $targetFile . '" import file.'));
@@ -1090,6 +1036,22 @@ class Poche
         $this->$providers[$from]($targetFile);
     }
 
+    public function uploadFile() {
+        if(isset($_FILES['file']))
+        { 
+            $dir = CACHE . '/';
+            $file = basename($_FILES['file']['name']);
+            if(move_uploaded_file($_FILES['file']['tmp_name'], $dir . $file)) {
+                $this->messages->add('s', _('File uploaded. You can now execute import.'));
+            }
+            else {
+                $this->messages->add('e', _('Error while importing file. Do you have access to upload it?'));
+            }
+        }
+        
+        Tools::redirect('?view=config');
+    }
+
     /**
      * export poche entries in json
      * @return json all poche entries
index 4ed28ed1b07a925991feeef349c498369c79cd9b..eeb101b40c546c037d217c50813c0d2a229f2613 100644 (file)
@@ -193,7 +193,7 @@ class Tools
 
     public static function logm($message)
     {
-        if (DEBUG_POCHE) {
+        if (DEBUG_POCHE && php_sapi_name() != 'cli') {
             $t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n";
             file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND);
             error_log('DEBUG POCHE : ' . $message);
@@ -241,7 +241,6 @@ class Tools
         }
     }
 
-
     public static function download_db() {
         header('Content-Disposition: attachment; filename="poche.sqlite.gz"');
         self::status(200);
@@ -252,4 +251,64 @@ class Tools
 
         exit;
     }
+
+    public static function getPageContent(Url $url)
+    {
+        // Saving and clearing context
+        $REAL = array();
+        foreach( $GLOBALS as $key => $value ) {
+            if( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
+                $GLOBALS[$key] = array();
+                $REAL[$key] = $value;
+            }
+        }
+        // Saving and clearing session
+        if ( isset($_SESSION) ) {
+            $REAL_SESSION = array();
+            foreach( $_SESSION as $key => $value ) {
+                $REAL_SESSION[$key] = $value;
+                unset($_SESSION[$key]);
+            }
+        }
+
+        // Running code in different context
+        $scope = function() {
+            extract( func_get_arg(1) );
+            $_GET = $_REQUEST = array(
+                        "url" => $url->getUrl(),
+                        "max" => 5,
+                        "links" => "preserve",
+                        "exc" => "",
+                        "format" => "json",
+                        "submit" => "Create Feed"
+            );
+            ob_start();
+            require func_get_arg(0);
+            $json = ob_get_contents();
+            ob_end_clean();
+            return $json;
+        };
+        $json = $scope( "inc/3rdparty/makefulltextfeed.php", array("url" => $url) );
+
+        // Clearing and restoring context
+        foreach( $GLOBALS as $key => $value ) {
+            if( $key != "GLOBALS" && $key != "_SESSION" ) {
+                unset($GLOBALS[$key]);
+            }
+        }
+        foreach( $REAL as $key => $value ) {
+            $GLOBALS[$key] = $value;
+        }
+        // Clearing and restoring session
+        if ( isset($REAL_SESSION) ) {
+            foreach( $_SESSION as $key => $value ) {
+                unset($_SESSION[$key]);
+            }
+            foreach( $REAL_SESSION as $key => $value ) {
+                $_SESSION[$key] = $value;
+            }
+        }
+
+        return json_decode($json, true);
+    }
 }
index 06ab7d3c0b873c00133bfa644224359e9f431135..5ca8bef5b3de0af9c49a2737cd8859efd034c5c2 100644 (file)
--- a/index.php
+++ b/index.php
@@ -74,6 +74,8 @@ if (isset($_GET['login'])) {
     $poche->updateTheme();
 } elseif (isset($_GET['updatelanguage'])) {
     $poche->updateLanguage();
+} elseif (isset($_GET['uploadfile'])) {
+    $poche->uploadFile();
 } elseif (isset($_GET['feed'])) {
     if (isset($_GET['action']) && $_GET['action'] == 'generate') {
         $poche->generateToken();
index d83b69abdb19eccb6977b02d1367463a2b1b32c3..95db92fe6825b7afc90a99abb6213210ef1ad68d 100644 (file)
             {% endif %}
 
             <h2>{% trans "Import" %}</h2>
-            <p>{% trans "Please execute the import script locally as it can take a very long time." %}</p>
-            <p>{% trans "More info in the official documentation:" %} <a href="http://doc.wallabag.org/doku.php?id=users:migrate">wallabag.org</a></p>
+            <p>1. {% trans "Select a file on your computer and upload it." %}</p>
+            <form method="post" action="?uploadfile" name="uploadfile" enctype="multipart/form-data">
+                <fieldset class="w500p">
+                    <div class="row">
+                        <label class="col w150p" for="file">{% trans "File:" %}</label>
+                        <input class="col" type="file" id="file" name="file" tabindex="4">
+                    </div>
+                    <div class="row mts txtcenter">
+                        <button class="bouton" type="submit" tabindex="4">{% trans "Upload" %}</button>
+                    </div>
+                </fieldset>
+                <input type="hidden" name="MAX_FILE_SIZE" value="1048576">
+                <input type="hidden" name="returnurl" value="{{ referer }}">
+            </form>
+            <p>2. {% trans "Then, click on the right link below." %}</p>
             <ul>
-                <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>
-                <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>
-                <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>
-                <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>
+                <li><a href="./?import&amp;from=pocket">{% trans "Import from Pocket" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCKET_FILE')) }}</li>
+                <li><a href="./?import&amp;from=readability">{% trans "Import from Readability" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('READABILITY_FILE')) }}</li>
+                <li><a href="./?import&amp;from=instapaper">{% trans "Import from Instapaper" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('INSTAPAPER_FILE')) }}</li>
+                <li><a href="./?import&amp;from=poche">{% trans "Import from wallabag" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCHE_FILE')) }}</li>
             </ul>
 
+            {% if token == '' %}
+                <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>
+            {% else %}
+            <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>
+            <p>{% trans "You can also create a cron task:" %}</p>
+            <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>
+            {% endif %}
+
             <h2>{% trans "Export your wallabag data" %}</h2>
             {% if constant('STORAGE') == 'sqlite' %}
             <p><a href="?download" target="_blank">{% trans "Click here" %}</a> {% trans "to download your database." %}</p>{% endif %}