index.php 9.65 KB
Newer Older
Andrew Dolgov's avatar
Andrew Dolgov committed
1 2 3 4
<?php
	error_reporting(E_ERROR | E_PARSE);

	require_once "../config.php";
5

Andrew Dolgov's avatar
Andrew Dolgov committed
6 7 8 9
	require_once "../db.php";
	require_once "../db-prefs.php";
	require_once "../functions.php";

10 11 12
	define('API_STATUS_OK', 0);
	define('API_STATUS_ERR', 1);

13 14 15 16
	if (defined('ENABLE_GZIP_OUTPUT') && ENABLE_GZIP_OUTPUT) {
		ob_start("ob_gzhandler");
	}

17
	$link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
Andrew Dolgov's avatar
Andrew Dolgov committed
18 19 20 21

	$session_expire = SESSION_EXPIRE_TIME; //seconds
	$session_name = (!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid_api" : TTRSS_SESSION_NAME . "_api";

22 23 24 25 26 27
	session_name($session_name);

	if ($_REQUEST["sid"]) {
		session_id($_REQUEST["sid"]);
	}

Andrew Dolgov's avatar
Andrew Dolgov committed
28 29 30 31 32 33
	session_start();

	if (!$link) {
		if (DB_TYPE == "mysql") {
			print mysql_error();
		}
34
		// PG seems to display its own errors just fine by default.
Andrew Dolgov's avatar
Andrew Dolgov committed
35 36 37 38 39 40
		return;
	}

	init_connection($link);

	$op = db_escape_string($_REQUEST["op"]);
41
	$seq = (int) $_REQUEST["seq"];
Andrew Dolgov's avatar
Andrew Dolgov committed
42 43 44

//	header("Content-Type: application/json");

45 46 47 48 49 50
	function api_wrap_reply($status, $seq, $reply) {
		print json_encode(array("seq" => $seq,
			"status" => $status,
			"content" => $reply));
	}

Andrew Dolgov's avatar
Andrew Dolgov committed
51
	if (!$_SESSION["uid"] && $op != "login" && $op != "isLoggedIn") {
52
		print api_wrap_reply(API_STATUS_ERR, $seq, array("error" => 'NOT_LOGGED_IN'));
Andrew Dolgov's avatar
Andrew Dolgov committed
53 54 55
		return;
	}

56
	if ($_SESSION["uid"] && $op != "logout" && !get_pref($link, 'ENABLE_API_ACCESS')) {
57
		print api_wrap_reply(API_STATUS_ERR, $seq, array("error" => 'API_DISABLED'));
Andrew Dolgov's avatar
Andrew Dolgov committed
58
		return;
59
	}
Andrew Dolgov's avatar
Andrew Dolgov committed
60 61

	switch ($op) {
62

Andrew Dolgov's avatar
Andrew Dolgov committed
63 64
		case "getVersion":
			$rv = array("version" => VERSION);
65
			print api_wrap_reply(API_STATUS_OK, $seq, $rv);
66
			break;
67

Andrew Dolgov's avatar
Andrew Dolgov committed
68 69 70
		case "login":
			$login = db_escape_string($_REQUEST["user"]);
			$password = db_escape_string($_REQUEST["password"]);
71
			$password_base64 = db_escape_string(base64_decode($_REQUEST["password"]));
Andrew Dolgov's avatar
Andrew Dolgov committed
72

73 74
			if (SINGLE_USER_MODE) $login = "admin";

75 76 77 78 79 80 81 82
			$result = db_query($link, "SELECT id FROM ttrss_users WHERE login = '$login'");

			if (db_num_rows($result) != 0) {
				$uid = db_fetch_result($result, 0, "id");
			} else {
				$uid = 0;
			}

83 84 85 86 87 88 89
			if (!$uid) {
				print api_wrap_reply(API_STATUS_ERR, $seq,
					array("error" => "LOGIN_ERROR"));
				return;
			}

			if (get_pref($link, "ENABLE_API_ACCESS", $uid)) {
90
				if (authenticate_user($link, $login, $password)) {               // try login with normal password
91
					print api_wrap_reply(API_STATUS_OK, $seq,
92
						array("session_id" => session_id()));
93
				} else if (authenticate_user($link, $login, $password_base64)) { // else try with base64_decoded password
94
					print api_wrap_reply(API_STATUS_OK, $seq,
95
						array("session_id" => session_id()));
96
				} else {                                                         // else we are not logged in
97
					print api_wrap_reply(API_STATUS_ERR, $seq,
98
						array("error" => "LOGIN_ERROR"));
99
				}
Andrew Dolgov's avatar
Andrew Dolgov committed
100
			} else {
101 102
				print api_wrap_reply(API_STATUS_ERR, $seq,
					array("error" => "API_DISABLED"));
Andrew Dolgov's avatar
Andrew Dolgov committed
103 104 105
			}

			break;
106

Andrew Dolgov's avatar
Andrew Dolgov committed
107 108
		case "logout":
			logout_user();
109
			print api_wrap_reply(API_STATUS_OK, $seq, array("status" => "OK"));
Andrew Dolgov's avatar
Andrew Dolgov committed
110
			break;
111

Andrew Dolgov's avatar
Andrew Dolgov committed
112
		case "isLoggedIn":
113
			print api_wrap_reply(API_STATUS_OK, $seq,
114
				array("status" => $_SESSION["uid"] != ''));
Andrew Dolgov's avatar
Andrew Dolgov committed
115
			break;
116

Andrew Dolgov's avatar
Andrew Dolgov committed
117 118 119 120 121
		case "getUnread":
			$feed_id = db_escape_string($_REQUEST["feed_id"]);
			$is_cat = db_escape_string($_REQUEST["is_cat"]);

			if ($feed_id) {
122
				print api_wrap_reply(API_STATUS_OK, $seq,
123
					array("unread" => getFeedUnread($link, $feed_id, $is_cat)));
Andrew Dolgov's avatar
Andrew Dolgov committed
124
			} else {
125
				print api_wrap_reply(API_STATUS_OK, $seq,
126
					array("unread" => getGlobalUnread($link)));
Andrew Dolgov's avatar
Andrew Dolgov committed
127
			}
128
			break;
129

130
		/* Method added for ttrss-reader for Android */
131
		case "getCounters":
132

133 134
			/* flct (flc is the default) FIXME: document */
			$output_mode = db_escape_string($_REQUEST["output_mode"]);
135

136
			print api_wrap_reply(API_STATUS_OK, $seq,
137
				getAllCounters($link, $output_mode));
Andrew Dolgov's avatar
Andrew Dolgov committed
138
			break;
139

Andrew Dolgov's avatar
Andrew Dolgov committed
140 141 142
		case "getFeeds":
			$cat_id = db_escape_string($_REQUEST["cat_id"]);
			$unread_only = (bool)db_escape_string($_REQUEST["unread_only"]);
143 144 145
			$limit = (int) db_escape_string($_REQUEST["limit"]);
			$offset = (int) db_escape_string($_REQUEST["offset"]);

146 147
			chdir(".."); // so feed_has_icon() would work properly for relative ICONS_DIR

148
			$feeds = api_get_feeds($link, $cat_id, $unread_only, $limit, $offset);
149

150
			print api_wrap_reply(API_STATUS_OK, $seq, $feeds);
Andrew Dolgov's avatar
Andrew Dolgov committed
151 152

			break;
153

Andrew Dolgov's avatar
Andrew Dolgov committed
154
		case "getCategories":
Andrew Dolgov's avatar
Andrew Dolgov committed
155 156
			$unread_only = (bool)db_escape_string($_REQUEST["unread_only"]);

157 158 159
			$result = db_query($link, "SELECT
					id, title FROM ttrss_feed_categories
				WHERE owner_uid = " .
Andrew Dolgov's avatar
Andrew Dolgov committed
160 161 162 163 164 165
				$_SESSION["uid"]);

			$cats = array();

			while ($line = db_fetch_assoc($result)) {
				$unread = getFeedUnread($link, $line["id"], true);
Andrew Dolgov's avatar
Andrew Dolgov committed
166 167

				if ($unread || !$unread_only) {
168
					array_push($cats, array("id" => $line["id"],
169
						"title" => $line["title"],
170
						"unread" => $unread));
Andrew Dolgov's avatar
Andrew Dolgov committed
171
				}
Andrew Dolgov's avatar
Andrew Dolgov committed
172 173
			}

174
			print api_wrap_reply(API_STATUS_OK, $seq, $cats);
Andrew Dolgov's avatar
Andrew Dolgov committed
175
			break;
176

Andrew Dolgov's avatar
Andrew Dolgov committed
177 178 179
		case "getHeadlines":
			$feed_id = db_escape_string($_REQUEST["feed_id"]);
			$limit = (int)db_escape_string($_REQUEST["limit"]);
180
			$offset = (int)db_escape_string($_REQUEST["skip"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
181 182
			$filter = db_escape_string($_REQUEST["filter"]);
			$is_cat = (bool)db_escape_string($_REQUEST["is_cat"]);
183 184
			$show_excerpt = (bool)db_escape_string($_REQUEST["show_excerpt"]);
			$show_content = (bool)db_escape_string($_REQUEST["show_content"]);
185 186
			/* all_articles, unread, adaptive, marked, updated */
			$view_mode = db_escape_string($_REQUEST["view_mode"]);
187
			$include_attachments = (bool)db_escape_string($_REQUEST["include_attachments"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
188

189
			$headlines = api_get_headlines($link, $feed_id, $limit, $offset,
190 191
				$filter, $is_cat, $show_excerpt, $show_content, $view_mode, false,
				$include_attachments);
Andrew Dolgov's avatar
Andrew Dolgov committed
192

193
			print api_wrap_reply(API_STATUS_OK, $seq, $headlines);
Andrew Dolgov's avatar
Andrew Dolgov committed
194

Andrew Dolgov's avatar
Andrew Dolgov committed
195
			break;
196

Andrew Dolgov's avatar
Andrew Dolgov committed
197
		case "updateArticle":
198
			$article_ids = split(",", db_escape_string($_REQUEST["article_ids"]));
Andrew Dolgov's avatar
Andrew Dolgov committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
			$mode = (int) db_escape_string($_REQUEST["mode"]);
			$field_raw = (int)db_escape_string($_REQUEST["field"]);

			$field = "";
			$set_to = "";

			switch ($field_raw) {
				case 0:
					$field = "marked";
					break;
				case 1:
					$field = "published";
					break;
				case 2:
					$field = "unread";
					break;
			};

			switch ($mode) {
				case 1:
					$set_to = "true";
					break;
				case 0:
					$set_to = "false";
					break;
				case 2:
					$set_to = "NOT $field";
					break;
			}

229 230 231 232
			if ($field && $set_to && count($article_ids) > 0) {

				$article_ids = join(", ", $article_ids);

Andrew Dolgov's avatar
Andrew Dolgov committed
233 234 235
				if ($field == "unread") {
					$result = db_query($link, "UPDATE ttrss_user_entries SET $field = $set_to,
						last_read = NOW()
236
						WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
237 238
				} else {
					$result = db_query($link, "UPDATE ttrss_user_entries SET $field = $set_to
239
						WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
240
				}
241

242 243 244 245 246 247 248 249 250 251 252
				$num_updated = db_affected_rows($link, $result);

				if ($num_updated > 0 && $field == "unread") {
					$result = db_query($link, "SELECT DISTINCT feed_id FROM ttrss_user_entries
						WHERE ref_id IN ($article_ids)");

					while ($line = db_fetch_assoc($result)) {
						ccache_update($link, $line["feed_id"], $_SESSION["uid"]);
					}
				}

253
				print api_wrap_reply(API_STATUS_OK, $seq, array("status" => "OK",
254 255 256
					"updated" => $num_updated));

			} else {
257
				print api_wrap_reply(API_STATUS_ERR, $seq,
258
					array("error" => 'INCORRECT_USAGE'));
Andrew Dolgov's avatar
Andrew Dolgov committed
259 260 261 262
			}

			break;

Andrew Dolgov's avatar
Andrew Dolgov committed
263 264
		case "getArticle":

265
			$article_id = db_escape_string($_REQUEST["article_id"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
266

267
			$query = "SELECT id,title,link,content,feed_id,comments,int_id,
Andrew Dolgov's avatar
Andrew Dolgov committed
268
				marked,unread,published,
Andrew Dolgov's avatar
Andrew Dolgov committed
269 270 271
				".SUBSTRING_FOR_DATE."(updated,1,16) as updated,
				author
				FROM ttrss_entries,ttrss_user_entries
272
				WHERE	id IN ($article_id) AND ref_id = id AND owner_uid = " .
Andrew Dolgov's avatar
Andrew Dolgov committed
273 274 275
					$_SESSION["uid"] ;

			$result = db_query($link, $query);
276 277 278

			$articles = array();

Andrew Dolgov's avatar
Andrew Dolgov committed
279 280
			if (db_num_rows($result) != 0) {

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
				while ($line = db_fetch_assoc($result)) {

					$attachments = get_article_enclosures($link, $line['id']);

					$article = array(
						"id" => $line["id"],
						"title" => $line["title"],
						"link" => $line["link"],
						"labels" => get_article_labels($link, $line['id']),
						"unread" => sql_bool_to_bool($line["unread"]),
						"marked" => sql_bool_to_bool($line["marked"]),
						"published" => sql_bool_to_bool($line["published"]),
						"comments" => $line["comments"],
						"author" => $line["author"],
						"updated" => strtotime($line["updated"]),
						"content" => $line["content"],
						"feed_id" => $line["feed_id"],
						"attachments" => $attachments
					);

301 302
					array_push($articles, $article);

303 304
				}
			}
Andrew Dolgov's avatar
Andrew Dolgov committed
305

306 307
			print api_wrap_reply(API_STATUS_OK, $seq, $articles);

Andrew Dolgov's avatar
Andrew Dolgov committed
308
			break;
309

Andrew Dolgov's avatar
Andrew Dolgov committed
310 311 312 313 314
		case "getConfig":
			$config = array(
				"icons_dir" => ICONS_DIR,
				"icons_url" => ICONS_URL);

315
			$config["daemon_is_running"] = file_is_locked("update_daemon.lock");
Andrew Dolgov's avatar
Andrew Dolgov committed
316 317 318 319 320 321 322

			$result = db_query($link, "SELECT COUNT(*) AS cf FROM
				ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"]);

			$num_feeds = db_fetch_result($result, 0, "cf");

			$config["num_feeds"] = (int)$num_feeds;
323

324
			print api_wrap_reply(API_STATUS_OK, $seq, $config);
Andrew Dolgov's avatar
Andrew Dolgov committed
325

Andrew Dolgov's avatar
Andrew Dolgov committed
326
			break;
Andrew Dolgov's avatar
Andrew Dolgov committed
327

Andrew Dolgov's avatar
Andrew Dolgov committed
328 329 330
		case "updateFeed":
			$feed_id = db_escape_string($_REQUEST["feed_id"]);

331
			update_rss_feed($link, $feed_id, true);
Andrew Dolgov's avatar
Andrew Dolgov committed
332

333
			print api_wrap_reply(API_STATUS_OK, $seq, array("status" => "OK"));
Andrew Dolgov's avatar
Andrew Dolgov committed
334

Andrew Dolgov's avatar
Andrew Dolgov committed
335 336
			break;

Andrew Dolgov's avatar
Andrew Dolgov committed
337 338
		case "catchupFeed":
			$feed_id = db_escape_string($_REQUEST["feed_id"]);
339
			$is_cat = db_escape_string($_REQUEST["is_cat"]);
Andrew Dolgov's avatar
Andrew Dolgov committed
340

Andrew Dolgov's avatar
Andrew Dolgov committed
341
			catchup_feed($link, $feed_id, $is_cat);
Andrew Dolgov's avatar
Andrew Dolgov committed
342

343
			print api_wrap_reply(API_STATUS_OK, $seq, array("status" => "OK"));
Andrew Dolgov's avatar
Andrew Dolgov committed
344 345 346

			break;

Andrew Dolgov's avatar
Andrew Dolgov committed
347 348
		case "getPref":
			$pref_name = db_escape_string($_REQUEST["pref_name"]);
349

350
			print api_wrap_reply(API_STATUS_OK, $seq,
351
				array("value" => get_pref($link, $pref_name)));
Andrew Dolgov's avatar
Andrew Dolgov committed
352
			break;
353

354
		default:
355
			print api_wrap_reply(API_STATUS_ERR, $seq,
356
				array("error" => 'UNKNOWN_METHOD'));
357 358
			break;

Andrew Dolgov's avatar
Andrew Dolgov committed
359 360 361
	}

	db_close($link);
362

Andrew Dolgov's avatar
Andrew Dolgov committed
363
?>