18b6369abb76d52b7298677c0228241fb0e2fba9
[prss.git] / src / ttrss.c
1 /*
2  * Copyright (C) 2010-2013 jeanfi@gmail.com
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301 USA
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22
23 #include <json/json.h>
24 #include <gtk/gtk.h>
25
26 #include "http.h"
27 #include "ttrss.h"
28 #include "url.h"
29
30 static char *session_id;
31 static char *session_url;
32
33 static struct json_object *create_op(const char *op)
34 {
35         struct json_object *j;
36
37         j = json_object_new_object();
38         json_object_object_add(j, "op", json_object_new_string(op));
39
40         if (session_id && strcmp(op, "login"))
41                 json_object_object_add(j,
42                                        "sid",
43                                        json_object_new_string(session_id));
44
45         return j;
46 }
47
48 void ttrss_login(const char *url, const char *user, const char *password)
49 {
50         struct json_object *content, *rp, *error, *sid, *rq;
51         char *tmp;
52
53         if (session_url)
54                 free(session_url);
55
56         tmp = url_normalize(url);
57         session_url = malloc(strlen(tmp) + strlen("/api/") + 1);
58         strcpy(session_url, tmp);
59         strcat(session_url, "/api/");
60         free(tmp);
61
62         rq = create_op("login");
63         json_object_object_add(rq, "user", json_object_new_string(user));
64         json_object_object_add(rq,
65                                "password",
66                                json_object_new_string(password));
67
68         rp = http_json_get(session_url, rq);
69         json_object_put(rq);
70
71         content = json_object_object_get(rp, "content");
72         if (!content) {
73                 fprintf(stderr, "Login failed: no content\n");
74                 return ;
75         }
76
77         error = json_object_object_get(content, "error");
78         if (error) {
79                 fprintf(stderr, "Login failed\n");
80                 return ;
81         }
82
83         sid = json_object_object_get(content, "session_id");
84
85         if (session_id) {
86                 free(session_id);
87                 session_id = NULL;
88         }
89
90         session_id = strdup(json_object_get_string(sid));
91
92         printf("Session id: %s\n", session_id);
93
94         json_object_put(rp);
95 }
96
97 const char *ttrss_get_headline_content(struct headline *h)
98 {
99         struct json_object *rp, *rq, *content, *array, *item;
100
101         printf("get_headlines %d\n", h->id);
102
103         if (!h->content) {
104                 rq = create_op("getArticle");
105                 json_object_object_add(rq, "article_id",
106                                        json_object_new_int(h->id));
107                 
108                 rp = http_json_get(session_url, rq);
109                 
110                 json_object_put(rq);
111                 
112                 array = json_object_object_get(rp, "content");
113
114                 if (!array)
115                         goto release;
116
117                 item = json_object_array_get_idx(array, 0);
118
119                 if (!item)
120                         goto release;
121
122                 content = json_object_object_get(item, "content");
123
124                 h->content = strdup(json_object_get_string(content));
125                         
126         release:
127                 json_object_put(rp);
128         }
129         return h->content;
130 }
131
132 static struct headline **get_headlines(int feed_id)
133 {
134         struct json_object *rp, *rq, *content, *jheadline, *j;
135         int i, n;
136         struct headline **headlines, *h;
137
138         printf("get_headlines %d\n", feed_id);
139
140         rq = create_op("getHeadlines");
141         json_object_object_add(rq, "feed_id", json_object_new_int(feed_id));
142
143         rp = http_json_get(session_url, rq);
144
145         json_object_put(rq);
146
147         content = json_object_object_get(rp, "content");
148
149         if (content) {
150                 n = json_object_array_length(content);
151                 headlines = malloc((n+1)*sizeof(struct headline *));
152                 for (i = 0; i < n; i++) {
153                         jheadline = json_object_array_get_idx(content, i);
154
155                         h = malloc(sizeof(struct headline));
156
157                         j = json_object_object_get(jheadline, "id");
158                         h->id = json_object_get_int(j);
159
160                         j = json_object_object_get(jheadline, "title");
161                         h->title = strdup(json_object_get_string(j));
162
163                         j = json_object_object_get(jheadline, "link");
164                         h->url = strdup(json_object_get_string(j));
165
166                         h->excerpt = NULL;
167                         h->content = NULL;
168
169                         j = json_object_object_get(jheadline, "unread");
170                         h->unread = json_object_get_boolean(j);
171
172                         headlines[i] = h;
173                 }
174                 headlines[n] = NULL;
175         } else {
176                 headlines = NULL;
177         }
178
179         json_object_put(rp);
180
181         printf("get_headlines %d end\n", feed_id);
182
183         return headlines;
184 }
185
186 static int feeds_length(struct feed **list)
187 {
188         int n;
189
190         if (!list)
191                 return 0;
192         
193         n = 0;
194         while(*list) {
195                 n++;
196                 list++;
197         }
198
199         return n;
200 }
201
202 static struct feed **feeds_add(struct feed **feeds, struct feed *feed)
203 {
204         int n;
205         struct feed **result;
206
207         n = feeds_length(feeds);
208
209         result = malloc((n + 1 + 1) * sizeof(struct feed *));
210
211         if (feeds)
212                 memcpy(result, feeds, n * sizeof(struct feed *));
213
214         result[n] = feed;
215         result[n + 1] = NULL;
216
217         return result;
218 }
219
220 struct feed **ttrss_get_feeds()
221 {
222         struct json_object *rp, *rq, *content, *jfeed, *j;
223         int i, n;
224         struct feed **feeds, *feed, **tmp;
225
226         printf("ttrss_get_feeds\n");
227
228         rq = create_op("getFeeds");
229
230         rp = http_json_get(session_url, rq);
231         json_object_put(rq);
232
233         content = json_object_object_get(rp, "content");
234
235         if (content) {
236                 n = json_object_array_length(content);
237
238                 feeds = NULL;
239                 for (i = 0; i < n; i++) {
240                         jfeed = json_object_array_get_idx(content, i);
241
242                         feed = malloc(sizeof(struct feed));
243
244                         j = json_object_object_get(jfeed, "title");
245                         feed->title = strdup(json_object_get_string(j));
246
247                         j = json_object_object_get(jfeed, "feed_url");
248                         feed->url = strdup(json_object_get_string(j));
249
250                         j = json_object_object_get(jfeed, "id");
251                         feed->id = json_object_get_int(j);
252
253                         j = json_object_object_get(jfeed, "unread");
254                         feed->unread = json_object_get_int(j);
255
256                         feed->headlines = NULL;
257
258                         tmp = feeds_add(feeds, feed);
259                         free(feeds);
260                         feeds = tmp;
261                 }
262         } else {
263                 feeds = NULL;
264         }
265
266         json_object_put(rp);
267
268         printf("ttrss_get_feeds ended\n");
269
270         return feeds;
271 }
272
273 struct headline **ttrss_get_headlines(struct feed *f)
274 {
275         if (!f->headlines)
276                 f->headlines = get_headlines(f->id);
277
278         return f->headlines;
279 }
280
281 void ttrss_set_article_unread(int id, int unread)
282 {
283         struct json_object *rp, *rq;
284
285         printf("ttrss_set_article_unread %d %d\n", id, unread);
286
287         rq = create_op("updateArticle");
288         json_object_object_add(rq, "article_ids", json_object_new_int(id));
289         json_object_object_add(rq, "field", json_object_new_int(2));
290         json_object_object_add(rq, "mode", json_object_new_int(unread));
291
292         rp = http_json_get(session_url, rq);
293         
294         json_object_put(rq);
295         json_object_put(rp);
296 }