2 /* This file is disabled by default.
4 * Warning: XML-RPC server is not disabled by "Enable API access" per-user preference.
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 */
9 require "lib/xmlrpc/lib/xmlrpc.inc";
10 require "lib/xmlrpc/lib/xmlrpcs.inc";
12 require_once "sanity_check.php";
13 require_once "config.php";
15 require_once "db.php";
16 require_once "db-prefs.php";
17 require_once "functions.php";
19 $GLOBALS['xmlrpc_internalencoding'] = "UTF-8";
21 $link = db_connect(DB_HOST
, DB_USER
, DB_PASS
, DB_NAME
);
24 if (DB_TYPE
== "mysql") {
27 // PG seems to display its own errors just fine by default.
31 init_connection($link);
33 function getVirtualFeeds($msg) {
38 $login_o = $msg->getParam(0);
39 $pass_o = $msg->getParam(1);
41 $login = $login_o->scalarval();
42 $pass = $pass_o->scalarval();
44 $user_id = authenticate_user($link, $login, $pass);
46 $counters_ret = array();
48 if (authenticate_user($link, $login, $pass)) {
50 $counters = getLabelCounters($link, true);
52 foreach (array_keys($counters) as $id) {
53 $line_struct = new xmlrpcval(
55 "id" => new xmlrpcval($id, "int"),
56 "title" => new xmlrpcval($counters[$id]["description"]),
57 "unread" => new xmlrpcval($counters[$id]["counter"], "int")
61 array_push($counters_ret, $line_struct);
64 $reply = new xmlrpcval($counters_ret, "array");
67 $reply_msg = "Login failed.";
71 if ($error_code != 0) {
72 return new xmlrpcresp(0, $error_code, $reply_msg);
74 return new xmlrpcresp($reply);
79 function getCategories($msg) {
82 $login_o = $msg->getParam(0);
83 $pass_o = $msg->getParam(1);
85 $login = $login_o->scalarval();
86 $pass = $pass_o->scalarval();
88 $user_id = authenticate_user($link, $login, $pass);
92 if (authenticate_user($link, $login, $pass)) {
94 $result = db_query($link, "SELECT
95 id, title FROM ttrss_feed_categories
101 while ($line = db_fetch_assoc($result)) {
103 $unread = getFeedUnread($link, $line["id"], true);
105 $line_struct = new xmlrpcval(
107 "title" => new xmlrpcval($line["title"]),
108 "id" => new xmlrpcval($line["id"], "int"),
109 "unread" => new xmlrpcval($unread, "int")
113 array_push($feeds, $line_struct);
116 $reply = new xmlrpcval($feeds, "array");
119 $reply = "Login failed.";
123 if ($error_code != 0) {
124 return new xmlrpcresp(0, $error_code, $reply_msg);
126 return new xmlrpcresp($reply);
131 function getTotalUnread($msg) {
136 $login_o = $msg->getParam(0);
137 $pass_o = $msg->getParam(1);
139 $login = $login_o->scalarval();
140 $pass = $pass_o->scalarval();
142 $user_id = authenticate_user($link, $login, $pass);
145 if (authenticate_user($link, $login, $pass)) {
147 $reply_msg = getGlobalUnread($link);
150 $reply_msg = "Login failed.";
154 if ($error_code != 0) {
155 return new xmlrpcresp(0, $error_code, $reply_msg);
157 return new xmlrpcresp(new xmlrpcval($reply_msg));
162 function getVersion() {
163 return new xmlrpcval(VERSION
);
166 function getSubscribedFeeds($msg) {
169 $login_o = $msg->getParam(0);
170 $pass_o = $msg->getParam(1);
172 $login = $login_o->scalarval();
173 $pass = $pass_o->scalarval();
175 $user_id = authenticate_user($link, $login, $pass);
177 if (authenticate_user($link, $login, $pass)) {
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 = " .
186 while ($line = db_fetch_assoc($result)) {
188 $unread = getFeedUnread($link, $line["id"]);
190 $line_struct = new xmlrpcval(
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")
201 array_push($feeds, $line_struct);
204 $reply = new xmlrpcval($feeds, "array");
207 $reply = new xmlrpcval("Login failed.");
210 return new xmlrpcresp($reply);
213 function subscribeToFeed($msg) {
218 $login_o = $msg->getParam(0);
219 $pass_o = $msg->getParam(1);
220 $feed_url_o = $msg->getParam(2);
222 $login = $login_o->scalarval();
223 $pass = $pass_o->scalarval();
224 $feed_url = $feed_url_o->scalarval();
226 if (authenticate_user($link, $login, $pass)) {
227 if (subscribe_to_feed($link, $feed_url)) {
228 $reply_msg = "Subscribed successfully.";
230 $reply_msg = "Feed already exists in the database.";
234 $reply_msg = "Login failed.";
238 if ($error_code != 0) {
239 return new xmlrpcresp(0, $error_code, $reply_msg);
241 return new xmlrpcresp(new xmlrpcval($reply_msg));
245 function getFeedHeadlines($msg) {
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);
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();
262 if (authenticate_user($link, $login, $pass)) {
265 $view_mode = "unread";
266 } else if ($filter == 2) {
267 $view_mode = "marked";
268 } else if ($filter == 3) {
269 $view_mode = "adaptive";
277 $qfh_ret = queryFeedHeadlines($link, $feed_id, $limit,
278 $view_mode, $cat_view, $search, $search_mode, $match_on);
280 $result = $qfh_ret[0];
281 $feed_title = $qfh_ret[1];
285 while ($line = db_fetch_assoc($result)) {
287 $is_updated = ($line["last_read"] == "" && ($line["unread"] != "t" && $line["unread"] != "1"));
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"),
296 "title" => new xmlrpcval($line["title"])
300 $headline_items["feed_id"] = new xmlrpcval($line["feed_id"], "int");
303 $line_struct = new xmlrpcval($headline_items,
306 array_push($articles, $line_struct);
309 $reply = new xmlrpcval(
311 "title" => new xmlrpcval($feed_title),
312 "headlines" => new xmlrpcval($articles, "array")
317 $reply_msg = "Login failed.";
321 if ($error_code != 0) {
322 return new xmlrpcresp(0, $error_code, $reply_msg);
324 return new xmlrpcresp($reply);
329 function getArticle($msg) {
334 $login_o = $msg->getParam(0);
335 $pass_o = $msg->getParam(1);
336 $article_id_o = $msg->getParam(2);
338 $login = $login_o->scalarval();
339 $pass = $pass_o->scalarval();
340 $article_id = $article_id_o->scalarval();
342 if (authenticate_user($link, $login, $pass)) {
344 $query = "SELECT title,link,content,feed_id,comments,int_id,
346 ".SUBSTRING_FOR_DATE
."(updated,1,16) as updated,
348 FROM ttrss_entries,ttrss_user_entries
349 WHERE id = '$article_id' AND ref_id = id AND owner_uid = " . $_SESSION["uid"] ;
351 $result = db_query($link, $query);
353 if (db_num_rows($result) == 1) {
355 $line = db_fetch_assoc($result);
357 $reply = new xmlrpcval(
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"])
371 $reply_msg = "Article not found.";
376 $reply_msg = "Login failed.";
380 if ($error_code != 0) {
381 return new xmlrpcresp(0, $error_code, $reply_msg);
383 return new xmlrpcresp($reply);
387 function setArticleMarked($msg) {
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);
397 $login = $login_o->scalarval();
398 $pass = $pass_o->scalarval();
399 $article_id = $article_id_o->scalarval();
400 $marked = $marked_o->scalarval();
402 if (authenticate_user($link, $login, $pass)) {
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";
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"]);
416 if (db_affected_rows($link, $result) == 1) {
420 $reply_msg = "Failed to update article.";
424 $reply_msg = "Login failed.";
428 if ($error_code != 0) {
429 return new xmlrpcresp(0, $error_code, $reply_msg);
431 return new xmlrpcresp(new xmlrpcval($reply_msg));
436 function setArticleRead($msg) {
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);
446 $login = $login_o->scalarval();
447 $pass = $pass_o->scalarval();
448 $article_id = $article_id_o->scalarval();
449 $read = $read_o->scalarval();
451 if (authenticate_user($link, $login, $pass)) {
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";
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"]);
465 if (db_affected_rows($link, $result) == 1) {
469 $reply_msg = "Failed to update article.";
473 $reply_msg = "Login failed.";
477 if ($error_code != 0) {
478 return new xmlrpcresp(0, $error_code, $reply_msg);
480 return new xmlrpcresp(new xmlrpcval($reply_msg));
485 $subscribeToFeed_sig = array(array($xmlrpcString,
486 $xmlrpcString, $xmlrpcString, $xmlrpcString));
488 $getSubscribedFeeds_sig = array(array($xmlrpcString,
489 $xmlrpcString, $xmlrpcString));
491 $getFeedHeadlines_sig = array(array($xmlrpcString,
492 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt, $xmlrpcInt));
494 $getArticle_sig = array(array($xmlrpcString,
495 $xmlrpcString, $xmlrpcString, $xmlrpcInt));
497 $setArticleMarked_sig = array(array($xmlrpcString,
498 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt));
500 $setArticleUnread_sig = array(array($xmlrpcString,
501 $xmlrpcString, $xmlrpcString, $xmlrpcInt, $xmlrpcInt));
503 $getVersion_sig = array(array($xmlrpcString));
505 $getTotalUnread_sig = array(array($xmlrpcInt, $xmlrpcString,
508 $getCategories_sig = array(array($xmlrpcString,
509 $xmlrpcString, $xmlrpcString));
511 $getVirtualFeeds_sig = array(array($xmlrpcInt, $xmlrpcString,
514 $s = new xmlrpc_server(
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
537 $s->response_charset_encoding
= "UTF-8";