]> git.wh0rd.org - tt-rss.git/blob - xml-rpc.php
21237f6c1eee4100334b6104a38d892058369506
[tt-rss.git] / xml-rpc.php
1 <?php
2 require "xmlrpc/lib/xmlrpc.inc";
3 require "xmlrpc/lib/xmlrpcs.inc";
4
5 require_once "sanity_check.php";
6 require_once "config.php";
7
8 require_once "db.php";
9 require_once "db-prefs.php";
10 require_once "functions.php";
11
12 $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
13
14 if (!$link) {
15 if (DB_TYPE == "mysql") {
16 print mysql_error();
17 }
18 // PG seems to display its own errors just fine by default.
19 return;
20 }
21
22 if (DB_TYPE == "pgsql") {
23 pg_query("set client_encoding = 'utf-8'");
24 pg_set_client_encoding("UNICODE");
25 } else {
26 // db_query($link, "SET NAMES utf8");
27 // db_query($link, "SET CHARACTER SET utf8");
28 }
29
30 function getVirtualFeeds($msg) {
31 global $link;
32
33 $error_code = 0;
34
35 $login_o = $msg->getParam(0);
36 $pass_o = $msg->getParam(1);
37
38 $login = $login_o->scalarval();
39 $pass = $pass_o->scalarval();
40
41 $user_id = authenticate_user($link, $login, $pass);
42
43 $counters_ret = array();
44
45 if (authenticate_user($link, $login, $pass)) {
46
47 $counters = getLabelCounters($link, false, true);
48
49 foreach (array_keys($counters) as $id) {
50 $line_struct = new xmlrpcval(
51 array(
52 "id" => new xmlrpcval($id, "int"),
53 "title" => new xmlrpcval($counters[$id]["description"]),
54 "unread" => new xmlrpcval($counters[$id]["counter"], "int")
55 ),
56 "struct");
57
58 array_push($counters_ret, $line_struct);
59 }
60
61 $reply = new xmlrpcval($counters_ret, "array");
62
63 } else {
64 $reply_msg = "Login failed.";
65 $error_code = 1;
66 }
67
68 if ($error_code != 0) {
69 return new xmlrpcresp(0, $error_code, $reply_msg);
70 } else {
71 return new xmlrpcresp($reply);
72 }
73
74 }
75
76 function getCategories($msg) {
77 global $link;
78
79 $login_o = $msg->getParam(0);
80 $pass_o = $msg->getParam(1);
81
82 $login = $login_o->scalarval();
83 $pass = $pass_o->scalarval();
84
85 $user_id = authenticate_user($link, $login, $pass);
86
87 $error_code = 0;
88
89 if (authenticate_user($link, $login, $pass)) {
90
91 $result = db_query($link, "SELECT
92 id, title FROM ttrss_feed_categories
93 WHERE owner_uid = " .
94 $_SESSION["uid"]);
95
96 $feeds = array();
97
98 while ($line = db_fetch_assoc($result)) {
99
100 $unread = getFeedUnread($link, $line["id"]);
101
102 $line_struct = new xmlrpcval(
103 array(
104 "title" => new xmlrpcval($line["title"]),
105 "id" => new xmlrpcval($line["id"], "int")
106 ),
107 "struct");
108
109 array_push($feeds, $line_struct);
110 }
111
112 $reply = new xmlrpcval($feeds, "array");
113
114 } else {
115 $reply = "Login failed.";
116 $error_code = 1;
117 }
118
119 if ($error_code != 0) {
120 return new xmlrpcresp(0, $error_code, $reply_msg);
121 } else {
122 return new xmlrpcresp($reply);
123 }
124
125 }
126
127 function getTotalUnread($msg) {
128 global $link;
129
130 $error_code = 0;
131
132 $login_o = $msg->getParam(0);
133 $pass_o = $msg->getParam(1);
134
135 $login = $login_o->scalarval();
136 $pass = $pass_o->scalarval();
137
138 $user_id = authenticate_user($link, $login, $pass);
139
140
141 if (authenticate_user($link, $login, $pass)) {
142
143 $reply_msg = getGlobalUnread($link);
144
145 } else {
146 $reply_msg = "Login failed.";
147 $error_code = 1;
148 }
149
150 if ($error_code != 0) {
151 return new xmlrpcresp(0, $error_code, $reply_msg);
152 } else {
153 return new xmlrpcresp(new xmlrpcval($reply_msg));
154 }
155
156 }
157
158 function getVersion() {
159 return new xmlrpcval(VERSION);
160 }
161
162 function getSubscribedFeeds($msg) {
163 global $link;
164
165 $login_o = $msg->getParam(0);
166 $pass_o = $msg->getParam(1);
167
168 $login = $login_o->scalarval();
169 $pass = $pass_o->scalarval();
170
171 $user_id = authenticate_user($link, $login, $pass);
172
173 if (authenticate_user($link, $login, $pass)) {
174
175 $result = db_query($link, "SELECT
176 id, feed_url, cat_id, title, SUBSTRING(last_updated,1,19) AS last_updated
177 FROM ttrss_feeds WHERE owner_uid = " .
178 $_SESSION["uid"]);
179
180 $feeds = array();
181
182 while ($line = db_fetch_assoc($result)) {
183
184 $unread = getFeedUnread($link, $line["id"]);
185
186 $line_struct = new xmlrpcval(
187 array(
188 "feed_url" => new xmlrpcval($line["feed_url"]),
189 "title" => new xmlrpcval($line["title"]),
190 "id" => new xmlrpcval($line["id"], "int"),
191 "unread" => new xmlrpcval($unread, "int"),
192 "cat_id" => new xmlrpcval($line["cat_id"], "int"),
193 "last_updated" => new xmlrpcval(strtotime($line["last_updated"]), "int")
194 ),
195 "struct");
196
197 array_push($feeds, $line_struct);
198 }
199
200 $reply = new xmlrpcval($feeds, "array");
201
202 } else {
203 $reply = new xmlrpcval("Login failed.");
204 }
205
206 return new xmlrpcresp($reply);
207 }
208
209 function subscribeToFeed($msg) {
210 global $link;
211
212 $error_code = 0;
213
214 $login_o = $msg->getParam(0);
215 $pass_o = $msg->getParam(1);
216 $feed_url_o = $msg->getParam(2);
217
218 $login = $login_o->scalarval();
219 $pass = $pass_o->scalarval();
220 $feed_url = $feed_url_o->scalarval();
221
222 if (authenticate_user($link, $login, $pass)) {
223 if (subscribe_to_feed($link, $feed_url)) {
224 $reply_msg = "Subscribed successfully.";
225 } else {
226 $reply_msg = "Feed already exists in the database.";
227 $error_code = 2;
228 }
229 } else {
230 $reply_msg = "Login failed.";
231 $error_code = 1;
232 }
233
234 if ($error_code != 0) {
235 return new xmlrpcresp(0, $error_code, $reply_msg);
236 } else {
237 return new xmlrpcresp(new xmlrpcval($reply_msg));
238 }
239 }
240
241 function getFeedHeadlines($msg) {
242 global $link;
243
244 $error_code = 0;
245
246 $login_o = $msg->getParam(0);
247 $pass_o = $msg->getParam(1);
248 $feed_id_o = $msg->getParam(2);
249 $limit_o = $msg->getParam(3);
250 $filter_o = $msg->getParam(4);
251
252 $login = $login_o->scalarval();
253 $pass = $pass_o->scalarval();
254 $feed_id = $feed_id_o->scalarval();
255 $limit = $limit_o->scalarval();
256 $filter = $filter_o->scalarval();
257
258 if (authenticate_user($link, $login, $pass)) {
259
260 if ($filter == 1) {
261 $view_mode = "unread";
262 } else if ($filter == 2) {
263 $view_mode = "marked";
264 } else if ($filter == 3) {
265 $view_mode = "adaptive";
266 }
267
268 $cat_view = false;
269 $search = "";
270 $search_mode = "";
271 $match_on = "";
272
273 $qfh_ret = queryFeedHeadlines($link, $feed_id, $limit,
274 $view_mode, $cat_view, $search, $search_mode, $match_on);
275
276 $result = $qfh_ret[0];
277 $feed_title = $qfh_ret[1];
278
279 $articles = array();
280
281 while ($line = db_fetch_assoc($result)) {
282
283 $is_updated = ($line["last_read"] == "" && ($line["unread"] != "t" && $line["unread"] != "1"));
284
285 $headline_items = array(
286 "id" => new xmlrpcval($line["id"], "int"),
287 "unread" => new xmlrpcval(sql_bool_to_bool($line["unread"]), "boolean"),
288 "marked" => new xmlrpcval(sql_bool_to_bool($line["marked"]), "boolean"),
289 "updated" => new xmlrpcval(strtotime($line["updated"]), "int"),
290 "is_updated" => new xmlrpcval($is_updated, "boolean"),
291
292 "title" => new xmlrpcval($line["title"])
293 );
294
295 if ($feed_id < 0) {
296 $headline_items["feed_id"] = new xmlrpcval($line["feed_id"], "int");
297 }
298
299 $line_struct = new xmlrpcval($headline_items,
300 "struct");
301
302 array_push($articles, $line_struct);
303 }
304
305 $reply = new xmlrpcval(
306 array(
307 "title" => new xmlrpcval($feed_title),
308 "headlines" => new xmlrpcval($articles, "array")
309 ),
310 "struct");
311
312 } else {
313 $reply_msg = "Login failed.";
314 $error_code = 1;
315 }
316
317 if ($error_code != 0) {
318 return new xmlrpcresp(0, $error_code, $reply_msg);
319 } else {
320 return new xmlrpcresp($reply);
321 }
322
323 }
324
325 function getArticle($msg) {
326 global $link;
327
328 $error_code = 0;
329
330 $login_o = $msg->getParam(0);
331 $pass_o = $msg->getParam(1);
332 $article_id_o = $msg->getParam(2);
333
334 $login = $login_o->scalarval();
335 $pass = $pass_o->scalarval();
336 $article_id = $article_id_o->scalarval();
337
338 if (authenticate_user($link, $login, $pass)) {
339
340 $query = "SELECT title,link,content,feed_id,comments,int_id,
341 marked,unread,
342 SUBSTRING(updated,1,16) as updated,
343 author
344 FROM ttrss_entries,ttrss_user_entries
345 WHERE id = '$article_id' AND ref_id = id AND owner_uid = " . $_SESSION["uid"] ;
346
347 $result = db_query($link, $query);
348
349 if (db_num_rows($result) == 1) {
350
351 $line = db_fetch_assoc($result);
352
353 $reply = new xmlrpcval(
354 array(
355 "title" => new xmlrpcval($line["title"]),
356 "link" => new xmlrpcval($line["link"]),
357 "unread" => new xmlrpcval(sql_bool_to_bool($line["unread"]), "boolean"),
358 "marked" => new xmlrpcval(sql_bool_to_bool($line["marked"]), "boolean"),
359 "comments" => new xmlrpcval($line["comments"]),
360 "author" => new xmlrpcval($line["author"]),
361 "updated" => new xmlrpcval(strtotime($line["updated"], "int")),
362 "content" => new xmlrpcval($line["content"])
363 ),
364 "struct");
365
366 } else {
367 $reply_msg = "Article not found.";
368 $error_code = 2;
369 }
370
371 } else {
372 $reply_msg = "Login failed.";
373 $error_code = 1;
374 }
375
376 if ($error_code != 0) {
377 return new xmlrpcresp(0, $error_code, $reply_msg);
378 } else {
379 return new xmlrpcresp($reply);
380 }
381 }
382
383 function setArticleMarked($msg) {
384 global $link;
385
386 $error_code = 0;
387
388 $login_o = $msg->getParam(0);
389 $pass_o = $msg->getParam(1);
390 $article_id_o = $msg->getParam(2);
391 $marked_o = $msg->getParam(3);
392
393 $login = $login_o->scalarval();
394 $pass = $pass_o->scalarval();
395 $article_id = $article_id_o->scalarval();
396 $marked = $marked_o->scalarval();
397
398 if (authenticate_user($link, $login, $pass)) {
399
400 if ($marked == 0) {
401 $query_strategy_part = "marked = false";
402 } else if ($marked == 1) {
403 $query_strategy_part = "marked = true";
404 } else if ($marked == 2) {
405 $query_strategy_part = "marked = NOT marked";
406 }
407
408 $result = db_query($link, "UPDATE ttrss_user_entries SET
409 $query_strategy_part WHERE ref_id = '$article_id' AND
410 owner_uid = " . $_SESSION["uid"]);
411
412 if (db_affected_rows($link, $result) == 1) {
413 $reply_msg = "OK";
414 } else {
415 $error_code = 2;
416 $reply_msg = "Failed to update article.";
417 }
418
419 } else {
420 $reply_msg = "Login failed.";
421 $error_code = 1;
422 }
423
424 if ($error_code != 0) {
425 return new xmlrpcresp(0, $error_code, $reply_msg);
426 } else {
427 return new xmlrpcresp(new xmlrpcval($reply_msg));
428 }
429
430 }
431
432 function setArticleRead($msg) {
433 global $link;
434
435 $error_code = 0;
436
437 $login_o = $msg->getParam(0);
438 $pass_o = $msg->getParam(1);
439 $article_id_o = $msg->getParam(2);
440 $read_o = $msg->getParam(3);
441
442 $login = $login_o->scalarval();
443 $pass = $pass_o->scalarval();
444 $article_id = $article_id_o->scalarval();
445 $read = $read_o->scalarval();
446
447 if (authenticate_user($link, $login, $pass)) {
448
449 if ($read == 0) {
450 $query_strategy_part = "unread = true";
451 } else if ($read == 1) {
452 $query_strategy_part = "unread = false";
453 } else if ($read == 2) {
454 $query_strategy_part = "unread = NOT unread";
455 }
456
457 $result = db_query($link, "UPDATE ttrss_user_entries SET
458 $query_strategy_part WHERE ref_id = '$article_id' AND
459 owner_uid = " . $_SESSION["uid"]);
460
461 if (db_affected_rows($link, $result) == 1) {
462 $reply_msg = "OK";
463 } else {
464 $error_code = 2;
465 $reply_msg = "Failed to update article.";
466 }
467
468 } else {
469 $reply_msg = "Login failed.";
470 $error_code = 1;
471 }
472
473 if ($error_code != 0) {
474 return new xmlrpcresp(0, $error_code, $reply_msg);
475 } else {
476 return new xmlrpcresp(new xmlrpcval($reply_msg));
477 }
478
479 }
480
481 $subscribeToFeed_sig = array(array($xmlrpcString,
482 $xmlrpcString, $xmlrpcString, $xmlrpcString));
483
484 $getSubscribedFeeds_sig = array(array($xmlrpcString,
485 $xmlrpcString, $xmlrpcString));
486
487 $getFeedHeadlines_sig = array(array($xmlrpcString,
488 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt, $xmlrpcInt));
489
490 $getArticle_sig = array(array($xmlrpcString,
491 $xmlrpcString, $xmlrpcString, $xmlrpcInt));
492
493 $setArticleMarked_sig = array(array($xmlrpcString,
494 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt));
495
496 $setArticleUnread_sig = array(array($xmlrpcString,
497 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt));
498
499 $getVersion_sig = array(array($xmlrpcString));
500
501 $getTotalUnread_sig = array(array($xmlrpcInt, $xmlrpcString,
502 $xmlrpcString));
503
504 $getCategories_sig = array(array($xmlrpcString,
505 $xmlrpcString, $xmlrpcString));
506
507 $getVirtualFeeds_sig = array(array($xmlrpcInt, $xmlrpcString,
508 $xmlrpcString));
509
510 $s = new xmlrpc_server(
511 array(
512 "rss.getVirtualFeeds" => array("function" => "getVirtualFeeds",
513 "signature" => $getVirtualFeeds_sig),
514 "rss.getCategories" => array("function" => "getCategories",
515 "signature" => $getCategories_sig),
516 "rss.getTotalUnread" => array("function" => "getTotalUnread",
517 "signature" => $getTotalUnread_sig),
518 "rss.getVersion" => array("function" => "getVersion",
519 "signature" => $getVersion_sig),
520 "rss.setArticleRead" => array("function" => "setArticleRead",
521 "signature" => $setArticleRead_sig),
522 "rss.setArticleMarked" => array("function" => "setArticleMarked",
523 "signature" => $setArticleMarked_sig),
524 "rss.getArticle" => array("function" => "getArticle",
525 "signature" => $getArticle_sig),
526 "rss.getFeedHeadlines" => array("function" => "getFeedHeadlines",
527 "signature" => $getFeedHeadlines_sig),
528 "rss.getSubscribedFeeds" => array("function" => "getSubscribedFeeds",
529 "signature" => $getSubscribedFeeds_sig),
530 "rss.subscribeToFeed" => array("function" => "subscribeToFeed",
531 "signature" => $subscribeToFeed_sig)), 0
532 );
533 $s->response_charset_encoding = "UTF-8";
534 $s->service();
535 ?>