]>
Commit | Line | Data |
---|---|---|
493c2f88 | 1 | <?php |
93e79595 | 2 | class GoogleReaderImport extends Plugin { |
493c2f88 AD |
3 | |
4 | ||
5 | private $link; | |
6 | private $host; | |
7 | ||
8 | function about() { | |
9 | return array(1.0, | |
7c93962d | 10 | "Import starred/shared items from Google Reader takeout", |
493c2f88 AD |
11 | "fox", |
12 | false, | |
13 | ""); | |
14 | } | |
15 | ||
16 | function init($host) { | |
17 | $this->link = $host->get_link(); | |
18 | $this->host = $host; | |
19 | ||
4cf0f9a9 AD |
20 | $host->add_command("greader-import", |
21 | "import data in Google Reader JSON format", | |
22 | $this, ":", "FILE"); | |
23 | ||
493c2f88 AD |
24 | $host->add_hook($host::HOOK_PREFS_TAB, $this); |
25 | } | |
26 | ||
4cf0f9a9 AD |
27 | function greader_import($args) { |
28 | $file = $args['greader_import']; | |
29 | ||
30 | if (!file_exists($file)) { | |
31 | _debug("file not found: $file"); | |
32 | return; | |
33 | } | |
34 | ||
35 | _debug("please enter your username:"); | |
36 | ||
37 | $username = db_escape_string($this->link, trim(read_stdin())); | |
38 | ||
39 | _debug("looking up user: $username..."); | |
40 | ||
41 | $result = db_query($this->link, "SELECT id FROM ttrss_users | |
42 | WHERE login = '$username'"); | |
43 | ||
44 | if (db_num_rows($result) == 0) { | |
45 | _debug("user not found."); | |
46 | return; | |
47 | } | |
48 | ||
49 | $owner_uid = db_fetch_result($result, 0, "id"); | |
50 | ||
51 | _debug("processing: $file (owner_uid: $owner_uid)"); | |
52 | ||
53 | $this->import($file, $owner_uid); | |
54 | } | |
55 | ||
493c2f88 AD |
56 | function get_prefs_js() { |
57 | return file_get_contents(dirname(__FILE__) . "/init.js"); | |
58 | } | |
59 | ||
4cf0f9a9 | 60 | function import($file = false, $owner_uid = 0) { |
493c2f88 | 61 | |
749da11b AD |
62 | purge_orphans($this->link); |
63 | ||
4cf0f9a9 AD |
64 | if (!$file) { |
65 | header("Content-Type: text/html"); | |
493c2f88 | 66 | |
93e79595 AD |
67 | $owner_uid = $_SESSION["uid"]; |
68 | ||
4cf0f9a9 AD |
69 | if (is_file($_FILES['starred_file']['tmp_name'])) { |
70 | $doc = json_decode(file_get_contents($_FILES['starred_file']['tmp_name']), true); | |
71 | } else { | |
72 | print_error(__('No file uploaded.')); | |
73 | return; | |
74 | } | |
493c2f88 | 75 | } else { |
4cf0f9a9 | 76 | $doc = json_decode(file_get_contents($file), true); |
493c2f88 AD |
77 | } |
78 | ||
4cf0f9a9 AD |
79 | if ($file) { |
80 | $sql_set_marked = strtolower(basename($file)) == 'starred.json' ? 'true' : 'false'; | |
81 | _debug("will set articles as starred: $sql_set_marked"); | |
82 | ||
83 | } else { | |
84 | $sql_set_marked = strtolower($_FILES['starred_file']['name']) == 'starred.json' ? 'true' : 'false'; | |
85 | } | |
4c92878f | 86 | |
493c2f88 AD |
87 | if ($doc) { |
88 | if (isset($doc['items'])) { | |
89 | $processed = 0; | |
90 | ||
91 | foreach ($doc['items'] as $item) { | |
92 | // print_r($item); | |
93 | ||
05e1e0ff | 94 | $guid = db_escape_string($this->link, mb_substr($item['id'], 0, 250)); |
493c2f88 AD |
95 | $title = db_escape_string($this->link, $item['title']); |
96 | $updated = date('Y-m-d h:i:s', $item['updated']); | |
97 | $link = ''; | |
98 | $content = ''; | |
99 | $author = db_escape_string($this->link, $item['author']); | |
4188225c | 100 | $tags = array(); |
749da11b | 101 | $orig_feed_data = array(); |
493c2f88 AD |
102 | |
103 | if (is_array($item['alternate'])) { | |
104 | foreach ($item['alternate'] as $alt) { | |
105 | if (isset($alt['type']) && $alt['type'] == 'text/html') { | |
106 | $link = db_escape_string($this->link, $alt['href']); | |
107 | } | |
108 | } | |
109 | } | |
110 | ||
b87bd8ed AD |
111 | if (is_array($item['summary'])) { |
112 | $content = db_escape_string($this->link, | |
113 | $item['summary']['content'], false); | |
114 | } | |
115 | ||
493c2f88 AD |
116 | if (is_array($item['content'])) { |
117 | $content = db_escape_string($this->link, | |
118 | $item['content']['content'], false); | |
119 | } | |
120 | ||
4188225c AD |
121 | if (is_array($item['categories'])) { |
122 | foreach ($item['categories'] as $cat) { | |
123 | if (strstr($cat, "com.google/") === FALSE) { | |
124 | array_push($tags, sanitize_tag($cat)); | |
125 | } | |
126 | } | |
127 | } | |
128 | ||
749da11b AD |
129 | if (is_array($item['origin'])) { |
130 | if (strpos($item['origin']['streamId'], 'feed/') === 0) { | |
131 | ||
132 | $orig_feed_data['feed_url'] = db_escape_string($this->link, | |
61096207 AD |
133 | mb_substr(preg_replace("/^feed\//", |
134 | "", $item['origin']['streamId']), 0, 200)); | |
749da11b AD |
135 | |
136 | $orig_feed_data['title'] = db_escape_string($this->link, | |
61096207 | 137 | mb_substr($item['origin']['title'], 0, 200)); |
749da11b AD |
138 | |
139 | $orig_feed_data['site_url'] = db_escape_string($this->link, | |
61096207 | 140 | mb_substr($item['origin']['htmlUrl'], 0, 200)); |
749da11b AD |
141 | } |
142 | } | |
143 | ||
493c2f88 AD |
144 | $processed++; |
145 | ||
4cf0f9a9 | 146 | $imported += (int) $this->create_article($owner_uid, $guid, $title, |
749da11b AD |
147 | $updated, $link, $content, $author, $sql_set_marked, $tags, |
148 | $orig_feed_data); | |
b9fc62a7 AD |
149 | |
150 | if ($file && $processed % 25 == 0) { | |
151 | _debug("processed $processed articles..."); | |
152 | } | |
493c2f88 AD |
153 | } |
154 | ||
4cf0f9a9 AD |
155 | if ($file) { |
156 | _debug(sprintf("All done. %d of %d articles imported.", $imported, $processed)); | |
157 | } else { | |
158 | print "<p style='text-align : center'>" . T_sprintf("All done. %d out of %d articles imported.", $imported, $processed) . "</p>"; | |
159 | } | |
493c2f88 AD |
160 | |
161 | } else { | |
162 | print_error(__('The document has incorrect format.')); | |
163 | } | |
164 | ||
165 | } else { | |
166 | print_error(__('Error while parsing document.')); | |
167 | } | |
168 | ||
4cf0f9a9 AD |
169 | if (!$file) { |
170 | print "<div align='center'>"; | |
171 | print "<button dojoType=\"dijit.form.Button\" | |
172 | onclick=\"dijit.byId('starredImportDlg').execute()\">". | |
173 | __('Close this window')."</button>"; | |
174 | print "</div>"; | |
175 | } | |
493c2f88 AD |
176 | } |
177 | ||
178 | // expects ESCAPED data | |
749da11b | 179 | private function create_article($owner_uid, $guid, $title, $updated, $link, $content, $author, $marked, $tags, $orig_feed_data) { |
493c2f88 AD |
180 | |
181 | if (!$guid) $guid = sha1($link); | |
182 | ||
b9fc62a7 | 183 | $create_archived_feeds = true; |
fc5cd158 | 184 | |
493c2f88 AD |
185 | $guid = "$owner_uid,$guid"; |
186 | ||
187 | $content_hash = sha1($content); | |
188 | ||
189 | if (filter_var($link, FILTER_VALIDATE_URL) === FALSE) return false; | |
190 | ||
191 | db_query($this->link, "BEGIN"); | |
192 | ||
749da11b AD |
193 | $feed_id = 'NULL'; |
194 | ||
195 | // let's check for archived feed entry | |
196 | ||
197 | $feed_inserted = false; | |
198 | ||
199 | // before dealing with archived feeds we must check ttrss_feeds to maintain id consistency | |
200 | ||
fc5cd158 | 201 | if ($orig_feed_data['feed_url'] && $create_archived_feeds) { |
749da11b AD |
202 | $result = db_query($this->link, |
203 | "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' | |
204 | AND owner_uid = $owner_uid"); | |
205 | ||
206 | if (db_num_rows($result) != 0) { | |
207 | $feed_id = db_fetch_result($result, 0, "id"); | |
208 | } else { | |
209 | // let's insert it | |
210 | ||
211 | if (!$orig_feed_data['title']) $orig_feed_data['title'] = '[Unknown]'; | |
212 | ||
213 | $result = db_query($this->link, | |
214 | "INSERT INTO ttrss_feeds | |
215 | (owner_uid,feed_url,site_url,title,cat_id,auth_login,auth_pass,update_method) | |
216 | VALUES ($owner_uid, | |
217 | '".$orig_feed_data['feed_url']."', | |
218 | '".$orig_feed_data['site_url']."', | |
219 | '".$orig_feed_data['title']."', | |
220 | NULL, '', '', 0)"); | |
221 | ||
222 | $result = db_query($this->link, | |
223 | "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' | |
224 | AND owner_uid = $owner_uid"); | |
225 | ||
226 | if (db_num_rows($result) != 0) { | |
227 | $feed_id = db_fetch_result($result, 0, "id"); | |
228 | $feed_inserted = true; | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
61096207 | 233 | if ($feed_id && $feed_id != 'NULL') { |
749da11b AD |
234 | // locate archived entry to file entries in, we don't want to file them in actual feeds because of purging |
235 | // maybe file marked in real feeds because eh | |
236 | ||
237 | $result = db_query($this->link, "SELECT id FROM ttrss_archived_feeds WHERE | |
238 | feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); | |
239 | ||
240 | if (db_num_rows($result) != 0) { | |
241 | $orig_feed_id = db_fetch_result($result, 0, "id"); | |
242 | } else { | |
243 | db_query($this->link, "INSERT INTO ttrss_archived_feeds | |
244 | (id, owner_uid, title, feed_url, site_url) | |
245 | SELECT id, owner_uid, title, feed_url, site_url from ttrss_feeds | |
246 | WHERE id = '$feed_id'"); | |
247 | ||
248 | $result = db_query($this->link, "SELECT id FROM ttrss_archived_feeds WHERE | |
249 | feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); | |
250 | ||
251 | if (db_num_rows($result) != 0) { | |
252 | $orig_feed_id = db_fetch_result($result, 0, "id"); | |
749da11b AD |
253 | } |
254 | } | |
255 | } | |
256 | ||
b9fc62a7 AD |
257 | // delete temporarily inserted feed |
258 | if ($feed_id && $feed_inserted) { | |
259 | db_query($this->link, "DELETE FROM ttrss_feeds WHERE id = $feed_id"); | |
260 | } | |
261 | ||
61096207 AD |
262 | if (!$orig_feed_id) $orig_feed_id = 'NULL'; |
263 | ||
493c2f88 AD |
264 | $result = db_query($this->link, "SELECT id FROM ttrss_entries, ttrss_user_entries WHERE |
265 | guid = '$guid' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1"); | |
266 | ||
267 | if (db_num_rows($result) == 0) { | |
268 | $result = db_query($this->link, "INSERT INTO ttrss_entries | |
269 | (title, guid, link, updated, content, content_hash, date_entered, date_updated, author) | |
270 | VALUES | |
271 | ('$title', '$guid', '$link', '$updated', '$content', '$content_hash', NOW(), NOW(), '$author')"); | |
272 | ||
273 | $result = db_query($this->link, "SELECT id FROM ttrss_entries WHERE guid = '$guid'"); | |
274 | ||
275 | if (db_num_rows($result) != 0) { | |
276 | $ref_id = db_fetch_result($result, 0, "id"); | |
277 | ||
278 | db_query($this->link, "INSERT INTO ttrss_user_entries | |
279 | (ref_id, uuid, feed_id, orig_feed_id, owner_uid, marked, tag_cache, label_cache, | |
280 | last_read, note, unread, last_marked) | |
281 | VALUES | |
b9fc62a7 | 282 | ('$ref_id', '', NULL, $orig_feed_id, $owner_uid, $marked, '', '', NOW(), '', false, NOW())"); |
493c2f88 | 283 | |
4188225c AD |
284 | $result = db_query($this->link, "SELECT int_id FROM ttrss_user_entries, ttrss_entries |
285 | WHERE owner_uid = $owner_uid AND ref_id = id AND ref_id = $ref_id"); | |
286 | ||
287 | if (db_num_rows($result) != 0 && is_array($tags)) { | |
288 | ||
289 | $entry_int_id = db_fetch_result($result, 0, "int_id"); | |
290 | $tags_to_cache = array(); | |
291 | ||
292 | foreach ($tags as $tag) { | |
293 | ||
294 | $tag = db_escape_string($this->link, sanitize_tag($tag)); | |
295 | ||
296 | if (!tag_is_valid($tag)) continue; | |
297 | ||
298 | $result = db_query($this->link, "SELECT id FROM ttrss_tags | |
299 | WHERE tag_name = '$tag' AND post_int_id = '$entry_int_id' AND | |
300 | owner_uid = '$owner_uid' LIMIT 1"); | |
301 | ||
302 | if ($result && db_num_rows($result) == 0) { | |
303 | db_query($this->link, "INSERT INTO ttrss_tags | |
304 | (owner_uid,tag_name,post_int_id) | |
305 | VALUES ('$owner_uid','$tag', '$entry_int_id')"); | |
306 | } | |
307 | ||
308 | array_push($tags_to_cache, $tag); | |
493c2f88 | 309 | } |
4188225c AD |
310 | |
311 | /* update the cache */ | |
312 | ||
313 | $tags_to_cache = array_unique($tags_to_cache); | |
314 | $tags_str = db_escape_string($this->link, join(",", $tags_to_cache)); | |
315 | ||
316 | db_query($this->link, "UPDATE ttrss_user_entries | |
317 | SET tag_cache = '$tags_str' WHERE ref_id = '$ref_id' | |
318 | AND owner_uid = $owner_uid"); | |
493c2f88 AD |
319 | } |
320 | ||
321 | $rc = true; | |
322 | } | |
323 | } | |
324 | ||
1b1db717 | 325 | db_query($this->link, "COMMIT"); |
493c2f88 AD |
326 | |
327 | return $rc; | |
328 | } | |
329 | ||
330 | function hook_prefs_tab($args) { | |
331 | if ($args != "prefFeeds") return; | |
332 | ||
4c92878f | 333 | print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Import starred or shared items from Google Reader")."\">"; |
493c2f88 | 334 | |
4c92878f | 335 | print_notice("Your imported articles will appear in Starred (in file is named starred.json) and Archived feeds."); |
493c2f88 | 336 | |
4c92878f | 337 | print "<p>".__("Paste your starred.json or shared.json into the form below."). "</p>"; |
493c2f88 AD |
338 | |
339 | print "<iframe id=\"starred_upload_iframe\" | |
340 | name=\"starred_upload_iframe\" onload=\"starredImportComplete(this)\" | |
341 | style=\"width: 400px; height: 100px; display: none;\"></iframe>"; | |
342 | ||
343 | print "<form name=\"starred_form\" style='display : block' target=\"starred_upload_iframe\" | |
344 | enctype=\"multipart/form-data\" method=\"POST\" | |
345 | action=\"backend.php\"> | |
346 | <input id=\"starred_file\" name=\"starred_file\" type=\"file\"> | |
347 | <input type=\"hidden\" name=\"op\" value=\"pluginhandler\"> | |
348 | <input type=\"hidden\" name=\"method\" value=\"import\"> | |
93e79595 | 349 | <input type=\"hidden\" name=\"plugin\" value=\"googlereaderimport\"> |
493c2f88 AD |
350 | <button dojoType=\"dijit.form.Button\" onclick=\"return starredImport();\" type=\"submit\">" . |
351 | __('Import my Starred items') . "</button>"; | |
352 | ||
353 | ||
354 | print "</div>"; #pane | |
355 | } | |
356 | } | |
357 | ?> |