2a94e99bf3f60e063c667f306d667751d82f89a6
[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 "phttp.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
63         rq = create_op("login");
64         json_object_object_add(rq, "user", json_object_new_string(user));
65         json_object_object_add(rq,
66                                "password",
67                                json_object_new_string(password));
68
69         rp = post_json_object(session_url, rq);
70         json_object_put(rq);
71
72         content = json_object_object_get(rp, "content");
73         if (!content) {
74                 fprintf(stderr, "Login failed: no content\n");
75                 return ;
76         }
77
78         error = json_object_object_get(content, "error");
79         if (error) {
80                 fprintf(stderr, "Login failed\n");
81                 return ;
82         }
83
84         sid = json_object_object_get(content, "session_id");
85
86         if (session_id) {
87                 free(session_id);
88                 session_id = NULL;
89         }
90
91         session_id = strdup(json_object_get_string(sid));
92
93         printf("Session id: %s\n", session_id);
94
95         json_object_put(rp);
96 }
97
98 const char *ttrss_get_headline_content(struct headline *h)
99 {
100         struct json_object *rp, *rq, *content, *array, *item;
101
102         printf("get_headlines %d\n", h->id);
103
104         if (!h->content) {
105                 rq = create_op("getArticle");
106                 json_object_object_add(rq, "article_id",
107                                        json_object_new_int(h->id));
108                 
109                 rp = post_json_object(session_url, rq);
110                 
111                 json_object_put(rq);
112                 
113                 array = json_object_object_get(rp, "content");
114
115                 if (!array)
116                         goto release;
117
118                 item = json_object_array_get_idx(array, 0);
119
120                 if (!item)
121                         goto release;
122
123                 content = json_object_object_get(item, "content");
124
125                 h->content = strdup(json_object_get_string(content));
126                         
127         release:
128                 json_object_put(rp);
129         }
130         return h->content;
131 }
132
133 static struct headline **get_headlines(int feed_id)
134 {
135         struct json_object *rp, *rq, *content, *jheadline, *j;
136         int i, n;
137         struct headline **headlines, *h;
138
139         printf("get_headlines %d\n", feed_id);
140
141         rq = create_op("getHeadlines");
142         json_object_object_add(rq, "feed_id", json_object_new_int(feed_id));
143
144         rp = post_json_object(session_url, rq);
145
146         json_object_put(rq);
147
148         content = json_object_object_get(rp, "content");
149
150         if (content) {
151                 n = json_object_array_length(content);
152                 headlines = malloc((n+1)*sizeof(struct headline *));
153                 for (i = 0; i < n; i++) {
154                         jheadline = json_object_array_get_idx(content, i);
155
156                         h = malloc(sizeof(struct headline));
157
158                         j = json_object_object_get(jheadline, "id");
159                         h->id = json_object_get_int(j);
160
161                         j = json_object_object_get(jheadline, "title");
162                         h->title = strdup(json_object_get_string(j));
163
164                         j = json_object_object_get(jheadline, "link");
165                         h->url = strdup(json_object_get_string(j));
166
167                         h->excerpt = NULL;
168                         h->content = NULL;
169
170                         j = json_object_object_get(jheadline, "unread");
171                         h->unread = json_object_get_boolean(j);
172
173                         headlines[i] = h;
174                 }
175                 headlines[n] = NULL;
176         } else {
177                 headlines = NULL;
178         }
179
180         json_object_put(rp);
181
182         printf("get_headlines %d end\n", feed_id);
183
184         return headlines;
185 }
186
187 static int feeds_length(struct feed **list)
188 {
189         int n;
190
191         if (!list)
192                 return 0;
193         
194         n = 0;
195         while(*list) {
196                 n++;
197                 list++;
198         }
199
200         return n;
201 }
202
203 static struct feed **feeds_add(struct feed **feeds, struct feed *feed)
204 {
205         int n;
206         struct feed **result;
207
208         n = feeds_length(feeds);
209
210         result = malloc((n + 1 + 1) * sizeof(struct feed *));
211
212         if (feeds)
213                 memcpy(result, feeds, n * sizeof(struct feed *));
214
215         result[n] = feed;
216         result[n + 1] = NULL;
217
218         return result;
219 }
220
221 struct feed **ttrss_get_feeds()
222 {
223         struct json_object *rp, *rq, *content, *jfeed, *j;
224         int i, n;
225         struct feed **feeds, *feed, **tmp;
226
227         printf("ttrss_get_feeds\n");
228
229         rq = create_op("getFeeds");
230
231         rp = post_json_object(session_url, rq);
232         json_object_put(rq);
233
234         content = json_object_object_get(rp, "content");
235
236         if (content) {
237                 n = json_object_array_length(content);
238
239                 feeds = NULL;
240                 for (i = 0; i < n; i++) {
241                         jfeed = json_object_array_get_idx(content, i);
242
243                         feed = malloc(sizeof(struct feed));
244
245                         j = json_object_object_get(jfeed, "title");
246                         feed->title = strdup(json_object_get_string(j));
247
248                         j = json_object_object_get(jfeed, "feed_url");
249                         feed->url = strdup(json_object_get_string(j));
250
251                         j = json_object_object_get(jfeed, "id");
252                         feed->id = json_object_get_int(j);
253
254                         j = json_object_object_get(jfeed, "unread");
255                         feed->unread = json_object_get_int(j);
256
257                         feed->headlines = NULL;
258
259                         tmp = feeds_add(feeds, feed);
260                         free(feeds);
261                         feeds = tmp;
262                 }
263         } else {
264                 feeds = NULL;
265         }
266
267         json_object_put(rp);
268
269         printf("ttrss_get_feeds ended\n");
270
271         return feeds;
272 }
273
274 struct headline **ttrss_get_headlines(struct feed *f)
275 {
276         if (!f->headlines)
277                 f->headlines = get_headlines(f->id);
278
279         return f->headlines;
280 }
281
282 void ttrss_set_article_unread(int id, int unread)
283 {
284         struct json_object *rp, *rq;
285
286         printf("ttrss_set_article_unread %d %d\n", id, unread);
287
288         rq = create_op("updateArticle");
289         json_object_object_add(rq, "article_ids", json_object_new_int(id));
290         json_object_object_add(rq, "field", json_object_new_int(2));
291         json_object_object_add(rq, "mode", json_object_new_int(unread));
292
293         rp = post_json_object(session_url, rq);
294         
295         json_object_put(rq);
296         json_object_put(rp);
297 }