host = $host; $host->add_hook($host::HOOK_PREFS_TAB, $this); $host->add_command("xml-import", "import articles from XML", $this, ":", "FILE"); } function about() { return array(1.0, "Imports and exports user data using neutral XML format", "fox"); } function xml_import($args) { $filename = $args['xml_import']; if (!is_file($filename)) { print "error: input filename ($filename) doesn't exist.\n"; return; } Debug::log("please enter your username:"); $username = trim(read_stdin()); Debug::log("importing $filename for user $username...\n"); $sth = $this->pdo->prepare("SELECT id FROM ttrss_users WHERE login = ?"); $sth->execute($username); if ($row = $sth->fetch()) { $owner_uid = $row['id']; $this->perform_data_import($filename, $owner_uid); } else { print "error: could not find user $username.\n"; return; } } function get_prefs_js() { return file_get_contents(dirname(__FILE__) . "/import_export.js"); } function hook_prefs_tab($args) { if ($args != "prefFeeds") return; print "
"; # pane } function csrf_ignore($method) { return in_array($method, array("exportget")); } /** * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ function before($method) { return $_SESSION["uid"] != false; } function after() { return true; } /** * @SuppressWarnings(unused) */ function exportget() { $exportname = CACHE_DIR . "/export/" . sha1($_SESSION['uid'] . $_SESSION['login']) . ".xml"; if (file_exists($exportname)) { header("Content-type: text/xml"); $timestamp_suffix = date("Y-m-d", filemtime($exportname)); if (function_exists('gzencode')) { header("Content-Disposition: attachment; filename=TinyTinyRSS_exported_${timestamp_suffix}.xml.gz"); echo gzencode(file_get_contents($exportname)); } else { header("Content-Disposition: attachment; filename=TinyTinyRSS_exported_${timestamp_suffix}.xml"); echo file_get_contents($exportname); } } else { echo "File not found."; } } function exportrun() { $offset = (int) $_REQUEST['offset']; $exported = 0; $limit = 250; if ($offset < 10000 && is_writable(CACHE_DIR . "/export")) { $sth = $this->pdo->prepare("SELECT ttrss_entries.guid, ttrss_entries.title, content, marked, published, score, note, link, tag_cache, label_cache, ttrss_feeds.title AS feed_title, ttrss_feeds.feed_url AS feed_url, ttrss_entries.updated FROM ttrss_user_entries LEFT JOIN ttrss_feeds ON (ttrss_feeds.id = feed_id), ttrss_entries WHERE (marked = true OR feed_id IS NULL) AND ref_id = ttrss_entries.id AND ttrss_user_entries.owner_uid = ? ORDER BY ttrss_entries.id LIMIT $limit OFFSET $offset"); $sth->execute([$_SESSION['uid']]); $exportname = sha1($_SESSION['uid'] . $_SESSION['login']); if ($offset == 0) { $fp = fopen(CACHE_DIR . "/export/$exportname.xml", "w"); fputs($fp, "" .__("Could not import: incorrect schema version.") . "
"; return; } } else { print "" . __("Could not import: unrecognized document format.") . "
"; return; } $articles = $xpath->query("//article"); foreach ($articles as $article_node) { if ($article_node->childNodes) { $ref_id = 0; $article = array(); foreach ($article_node->childNodes as $child) { if ($child->nodeName == 'content' || $child->nodeName == 'label_cache') { $article[$child->nodeName] = $child->nodeValue; } else { $article[$child->nodeName] = clean($child->nodeValue); } } //print_r($article); if ($article['guid']) { ++$num_processed; $this->pdo->beginTransaction(); //print 'GUID:' . $article['guid'] . "\n"; $sth = $this->pdo->prepare("SELECT id FROM ttrss_entries WHERE guid = ?"); $sth->execute([$article['guid']]); if ($row = $sth->fetch()) { $ref_id = $row['id']; } else { $sth = $this->pdo->prepare( "INSERT INTO ttrss_entries (title, guid, link, updated, content, content_hash, no_orig_date, date_updated, date_entered, comments, num_comments, author) VALUES (?, ?, ?, ?, ?, ?, false, NOW(), NOW(), '', '0', '')"); $sth->execute([ $article['title'], $article['guid'], $article['link'], $article['updated'], $article['content'], sha1($article['content']) ]); $sth = $this->pdo->prepare("SELECT id FROM ttrss_entries WHERE guid = ?"); $sth->execute([$article['guid']]); if ($row = $sth->fetch()) { $ref_id = $row['id']; } } //print "Got ref ID: $ref_id\n"; if ($ref_id) { $feed = NULL; if ($article['feed_url'] && $article['feed_title']) { $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE feed_url = ? AND owner_uid = ?"); $sth->execute([$article['feed_url'], $owner_uid]); if ($row = $sth->fetch()) { $feed = $row['id']; } else { // try autocreating feed in Uncategorized... $sth = $this->pdo->prepare("INSERT INTO ttrss_feeds (owner_uid, feed_url, title) VALUES (?, ?, ?)"); $res = $sth->execute([$owner_uid, $article['feed_url'], $article['feed_title']]); if ($res) { $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE feed_url = ? AND owner_uid = ?"); $sth->execute([$article['feed_url'], $owner_uid]); if ($row = $sth->fetch()) { ++$num_feeds_created; $feed = $row['id']; } } } } if ($feed) $feed_qpart = "feed_id = " . (int) $feed; else $feed_qpart = "feed_id IS NULL"; //print "$ref_id / $feed / " . $article['title'] . "\n"; $sth = $this->pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE ref_id = ? AND owner_uid = ? AND $feed_qpart"); $sth->execute([$ref_id, $owner_uid]); if (!$sth->fetch()) { $score = (int) $article['score']; $tag_cache = $article['tag_cache']; $note = $article['note']; //print "Importing " . $article['title'] . "" . __("Finished: "). vsprintf(_ngettext("%d article processed, ", "%d articles processed, ", $num_processed), $num_processed). vsprintf(_ngettext("%d imported, ", "%d imported, ", $num_imported), $num_imported). vsprintf(_ngettext("%d feed created.", "%d feeds created.", $num_feeds_created), $num_feeds_created). "
"; } else { print "" . __("Could not load XML document.") . "
"; } } function exportData() { print "You need to prepare exported data first by clicking the button below.
"; print "