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