link = $host->get_link(); $this->host = $host; $host->add_command("greader-import", "import data in Google Reader JSON format", $this, ":", "FILE"); $host->add_hook($host::HOOK_PREFS_TAB, $this); } function greader_import($args) { $file = $args['greader_import']; if (!file_exists($file)) { _debug("file not found: $file"); return; } _debug("please enter your username:"); $username = db_escape_string($this->link, trim(read_stdin())); _debug("looking up user: $username..."); $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE login = '$username'"); if (db_num_rows($result) == 0) { _debug("user not found."); return; } $owner_uid = db_fetch_result($result, 0, "id"); _debug("processing: $file (owner_uid: $owner_uid)"); $this->import($file, $owner_uid); } function get_prefs_js() { return file_get_contents(dirname(__FILE__) . "/init.js"); } function import($file = false, $owner_uid = 0) { purge_orphans($this->link); if (!$file) { header("Content-Type: text/html"); $owner_uid = $_SESSION["uid"]; if (is_file($_FILES['starred_file']['tmp_name'])) { $doc = json_decode(file_get_contents($_FILES['starred_file']['tmp_name']), true); } else { print_error(__('No file uploaded.')); return; } } else { $doc = json_decode(file_get_contents($file), true); } if ($file) { $sql_set_marked = strtolower(basename($file)) == 'starred.json' ? 'true' : 'false'; _debug("will set articles as starred: $sql_set_marked"); } else { $sql_set_marked = strtolower($_FILES['starred_file']['name']) == 'starred.json' ? 'true' : 'false'; } if ($doc) { if (isset($doc['items'])) { $processed = 0; foreach ($doc['items'] as $item) { // print_r($item); $guid = db_escape_string($this->link, mb_substr($item['id'], 0, 250)); $title = db_escape_string($this->link, $item['title']); $updated = date('Y-m-d h:i:s', $item['updated']); $link = ''; $content = ''; $author = db_escape_string($this->link, $item['author']); $tags = array(); $orig_feed_data = array(); if (is_array($item['alternate'])) { foreach ($item['alternate'] as $alt) { if (isset($alt['type']) && $alt['type'] == 'text/html') { $link = db_escape_string($this->link, $alt['href']); } } } if (is_array($item['content'])) { $content = db_escape_string($this->link, $item['content']['content'], false); } if (is_array($item['categories'])) { foreach ($item['categories'] as $cat) { if (strstr($cat, "com.google/") === FALSE) { array_push($tags, sanitize_tag($cat)); } } } if (is_array($item['origin'])) { if (strpos($item['origin']['streamId'], 'feed/') === 0) { $orig_feed_data['feed_url'] = db_escape_string($this->link, mb_substr(preg_replace("/^feed\//", "", $item['origin']['streamId']), 0, 200)); $orig_feed_data['title'] = db_escape_string($this->link, mb_substr($item['origin']['title'], 0, 200)); $orig_feed_data['site_url'] = db_escape_string($this->link, mb_substr($item['origin']['htmlUrl'], 0, 200)); } } $processed++; $imported += (int) $this->create_article($owner_uid, $guid, $title, $updated, $link, $content, $author, $sql_set_marked, $tags, $orig_feed_data); if ($file && $processed % 25 == 0) { _debug("processed $processed articles..."); } } if ($file) { _debug(sprintf("All done. %d of %d articles imported.", $imported, $processed)); } else { print "

" . T_sprintf("All done. %d out of %d articles imported.", $imported, $processed) . "

"; } } else { print_error(__('The document has incorrect format.')); } } else { print_error(__('Error while parsing document.')); } if (!$file) { print "
"; print ""; print "
"; } } // expects ESCAPED data private function create_article($owner_uid, $guid, $title, $updated, $link, $content, $author, $marked, $tags, $orig_feed_data) { if (!$guid) $guid = sha1($link); $create_archived_feeds = true; $guid = "$owner_uid,$guid"; $content_hash = sha1($content); if (filter_var($link, FILTER_VALIDATE_URL) === FALSE) return false; db_query($this->link, "BEGIN"); $feed_id = 'NULL'; // let's check for archived feed entry $feed_inserted = false; // before dealing with archived feeds we must check ttrss_feeds to maintain id consistency if ($orig_feed_data['feed_url'] && $create_archived_feeds) { $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); if (db_num_rows($result) != 0) { $feed_id = db_fetch_result($result, 0, "id"); } else { // let's insert it if (!$orig_feed_data['title']) $orig_feed_data['title'] = '[Unknown]'; $result = db_query($this->link, "INSERT INTO ttrss_feeds (owner_uid,feed_url,site_url,title,cat_id,auth_login,auth_pass,update_method) VALUES ($owner_uid, '".$orig_feed_data['feed_url']."', '".$orig_feed_data['site_url']."', '".$orig_feed_data['title']."', NULL, '', '', 0)"); $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); if (db_num_rows($result) != 0) { $feed_id = db_fetch_result($result, 0, "id"); $feed_inserted = true; } } } if ($feed_id && $feed_id != 'NULL') { // locate archived entry to file entries in, we don't want to file them in actual feeds because of purging // maybe file marked in real feeds because eh $result = db_query($this->link, "SELECT id FROM ttrss_archived_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); if (db_num_rows($result) != 0) { $orig_feed_id = db_fetch_result($result, 0, "id"); } else { db_query($this->link, "INSERT INTO ttrss_archived_feeds (id, owner_uid, title, feed_url, site_url) SELECT id, owner_uid, title, feed_url, site_url from ttrss_feeds WHERE id = '$feed_id'"); $result = db_query($this->link, "SELECT id FROM ttrss_archived_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); if (db_num_rows($result) != 0) { $orig_feed_id = db_fetch_result($result, 0, "id"); } } } // delete temporarily inserted feed if ($feed_id && $feed_inserted) { db_query($this->link, "DELETE FROM ttrss_feeds WHERE id = $feed_id"); } if (!$orig_feed_id) $orig_feed_id = 'NULL'; $result = db_query($this->link, "SELECT id FROM ttrss_entries, ttrss_user_entries WHERE guid = '$guid' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1"); if (db_num_rows($result) == 0) { $result = db_query($this->link, "INSERT INTO ttrss_entries (title, guid, link, updated, content, content_hash, date_entered, date_updated, author) VALUES ('$title', '$guid', '$link', '$updated', '$content', '$content_hash', NOW(), NOW(), '$author')"); $result = db_query($this->link, "SELECT id FROM ttrss_entries WHERE guid = '$guid'"); if (db_num_rows($result) != 0) { $ref_id = db_fetch_result($result, 0, "id"); db_query($this->link, "INSERT INTO ttrss_user_entries (ref_id, uuid, feed_id, orig_feed_id, owner_uid, marked, tag_cache, label_cache, last_read, note, unread, last_marked) VALUES ('$ref_id', '', NULL, $orig_feed_id, $owner_uid, $marked, '', '', NOW(), '', false, NOW())"); $result = db_query($this->link, "SELECT int_id FROM ttrss_user_entries, ttrss_entries WHERE owner_uid = $owner_uid AND ref_id = id AND ref_id = $ref_id"); if (db_num_rows($result) != 0 && is_array($tags)) { $entry_int_id = db_fetch_result($result, 0, "int_id"); $tags_to_cache = array(); foreach ($tags as $tag) { $tag = db_escape_string($this->link, sanitize_tag($tag)); if (!tag_is_valid($tag)) continue; $result = db_query($this->link, "SELECT id FROM ttrss_tags WHERE tag_name = '$tag' AND post_int_id = '$entry_int_id' AND owner_uid = '$owner_uid' LIMIT 1"); if ($result && db_num_rows($result) == 0) { db_query($this->link, "INSERT INTO ttrss_tags (owner_uid,tag_name,post_int_id) VALUES ('$owner_uid','$tag', '$entry_int_id')"); } array_push($tags_to_cache, $tag); } /* update the cache */ $tags_to_cache = array_unique($tags_to_cache); $tags_str = db_escape_string($this->link, join(",", $tags_to_cache)); db_query($this->link, "UPDATE ttrss_user_entries SET tag_cache = '$tags_str' WHERE ref_id = '$ref_id' AND owner_uid = $owner_uid"); } $rc = true; } } db_query($this->link, "COMMIT"); return $rc; } function hook_prefs_tab($args) { if ($args != "prefFeeds") return; print "
"; print_notice("Your imported articles will appear in Starred (in file is named starred.json) and Archived feeds."); print "

".__("Paste your starred.json or shared.json into the form below."). "

"; print ""; print "
  "; print "
"; #pane } } ?>