1 /*
2  * Copyright (C) 2006 Andrej Kacian <andrej@kacian.sk>
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,
10  * but 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
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #define __USE_GNU
21 
22 #include <stdlib.h>
23 #include <glib.h>
24 #include <curl/curl.h>
25 #include <expat.h>
26 
27 #include "feed.h"
28 #include "feeditem.h"
29 #include "feeditemenclosure.h"
30 #include "parser.h"
31 
32 /* feed_item_new()
33  * Initializes a new empty FeedItem struct, setting its parent feed,
34  * if supplied. */
feed_item_new(Feed * feed)35 FeedItem *feed_item_new(Feed *feed)
36 {
37 	FeedItem *item = NULL;
38 
39 	item = malloc( sizeof(FeedItem) );
40 	item->url = NULL;
41 	item->title = NULL;
42 	item->title_format = 0;
43 	item->summary = NULL;
44 	item->text = NULL;
45 	item->author = NULL;
46 	item->id = NULL;
47 	item->comments_url = NULL;
48 	item->parent_id = NULL;
49 	item->enclosure = NULL;
50 
51 	item->sourcetitle = NULL;
52 	item->sourceid = NULL;
53 	item->sourcedate = -1;
54 
55 	item->id_is_permalink = FALSE;
56 	item->xhtml_content = FALSE;
57 
58 	item->date_published = -1;
59 	item->date_modified = -1;
60 
61 	if( feed != NULL )
62 		item->feed = feed;
63 
64 	item->data = NULL;
65 
66 	return item;
67 }
68 
feed_item_free(FeedItem * item)69 void feed_item_free(FeedItem *item)
70 {
71 	if( item == NULL )
72 		return;
73 
74 	g_free(item->url);
75 	g_free(item->title);
76 	g_free(item->summary);
77 	g_free(item->text);
78 	g_free(item->author);
79 	g_free(item->id);
80 	g_free(item->data);
81 	g_free(item->comments_url);
82 	g_free(item->parent_id);
83 	feed_item_enclosure_free(item->enclosure);
84 
85 	g_free(item->sourcetitle);
86 	g_free(item->sourceid);
87 
88 	g_free(item);
89 	item = NULL;
90 }
91 
feed_item_get_feed(FeedItem * item)92 Feed *feed_item_get_feed(FeedItem *item)
93 {
94 	g_return_val_if_fail(item != NULL, NULL);
95 	return item->feed;
96 }
97 
98 /* URL */
feed_item_get_url(FeedItem * item)99 gchar *feed_item_get_url(FeedItem *item)
100 {
101 	g_return_val_if_fail(item != NULL, NULL);
102 	return item->url;
103 }
104 
feed_item_set_url(FeedItem * item,const gchar * url)105 void feed_item_set_url(FeedItem *item, const gchar *url)
106 {
107 	g_return_if_fail(item != NULL);
108 	g_return_if_fail(url != NULL);
109 
110 	g_free(item->url);
111 	item->url = g_strdup(url);
112 }
113 
114 /* Title */
feed_item_get_title(FeedItem * item)115 gchar *feed_item_get_title(FeedItem *item)
116 {
117 	g_return_val_if_fail(item != NULL, NULL);
118 	return item->title;
119 }
120 
feed_item_set_title(FeedItem * item,const gchar * title)121 void feed_item_set_title(FeedItem *item, const gchar *title)
122 {
123 	g_return_if_fail(item != NULL);
124 	g_return_if_fail(title != NULL);
125 
126 	g_free(item->title);
127 	item->title = g_strdup(title);
128 }
129 
130 /* Title format */
feed_item_get_title_format(FeedItem * item)131 gint feed_item_get_title_format(FeedItem *item)
132 {
133 	g_return_val_if_fail(item != NULL, -1);
134 	return item->title_format;
135 }
136 
feed_item_set_title_format(FeedItem * item,gint format)137 void feed_item_set_title_format(FeedItem *item, gint format)
138 {
139 	g_return_if_fail(item != NULL);
140 	g_return_if_fail(format >= 0 && format <= FEED_ITEM_TITLE_UNKNOWN);
141 
142 	item->title_format = format;
143 }
144 
145 /* Summary */
feed_item_get_summary(FeedItem * item)146 gchar *feed_item_get_summary(FeedItem *item)
147 {
148 	g_return_val_if_fail(item != NULL, NULL);
149 	return item->summary;
150 }
151 
feed_item_set_summary(FeedItem * item,const gchar * summary)152 void feed_item_set_summary(FeedItem *item, const gchar *summary)
153 {
154 	g_return_if_fail(item != NULL);
155 	g_return_if_fail(summary != NULL);
156 
157 	g_free(item->summary);
158 	item->summary = g_strdup(summary);
159 }
160 
161 /* Text */
feed_item_get_text(FeedItem * item)162 gchar *feed_item_get_text(FeedItem *item)
163 {
164 	g_return_val_if_fail(item != NULL, NULL);
165 	return item->text;
166 }
167 
feed_item_set_text(FeedItem * item,const gchar * text)168 void feed_item_set_text(FeedItem *item, const gchar *text)
169 {
170 	g_return_if_fail(item != NULL);
171 	g_return_if_fail(text != NULL);
172 
173 	g_free(item->text);
174 	item->text = g_strdup(text);
175 }
176 
177 /* Author */
feed_item_get_author(FeedItem * item)178 gchar *feed_item_get_author(FeedItem *item)
179 {
180 	g_return_val_if_fail(item != NULL, NULL);
181 	return item->author;
182 }
183 
feed_item_set_author(FeedItem * item,const gchar * author)184 void feed_item_set_author(FeedItem *item, const gchar *author)
185 {
186 	g_return_if_fail(item != NULL);
187 	g_return_if_fail(author != NULL);
188 
189 	g_free(item->author);
190 	item->author = g_strdup(author);
191 }
192 
193 /* ID */
feed_item_get_id(FeedItem * item)194 gchar *feed_item_get_id(FeedItem *item)
195 {
196 	g_return_val_if_fail(item != NULL, NULL);
197 	return item->id;
198 }
199 
feed_item_set_id(FeedItem * item,const gchar * id)200 void feed_item_set_id(FeedItem *item, const gchar *id)
201 {
202 	g_return_if_fail(item != NULL);
203 	g_return_if_fail(id != NULL);
204 
205 	g_free(item->id);
206 	item->id = g_strdup(id);
207 }
208 
209 /* Comments URL */
feed_item_get_comments_url(FeedItem * item)210 gchar *feed_item_get_comments_url(FeedItem *item)
211 {
212 	g_return_val_if_fail(item != NULL, NULL);
213 	return item->comments_url;
214 }
215 
feed_item_set_comments_url(FeedItem * item,const gchar * url)216 void feed_item_set_comments_url(FeedItem *item, const gchar *url)
217 {
218 	g_return_if_fail(item != NULL);
219 	g_return_if_fail(url != NULL);
220 
221 	g_free(item->comments_url);
222 	item->comments_url = g_strdup(url);
223 }
224 
225 /* Comments URL */
feed_item_get_parent_id(FeedItem * item)226 gchar *feed_item_get_parent_id(FeedItem *item)
227 {
228 	g_return_val_if_fail(item != NULL, NULL);
229 	return item->parent_id;
230 }
231 
feed_item_set_parent_id(FeedItem * item,const gchar * id)232 void feed_item_set_parent_id(FeedItem *item, const gchar *id)
233 {
234 	g_return_if_fail(item != NULL);
235 	g_return_if_fail(id != NULL);
236 
237 	g_free(item->parent_id);
238 	item->parent_id = g_strdup(id);
239 }
240 
241 /* Media enclosure */
feed_item_get_enclosure(FeedItem * item)242 FeedItemEnclosure *feed_item_get_enclosure(FeedItem *item)
243 {
244 	g_return_val_if_fail(item != NULL, NULL);
245 	return item->enclosure;
246 }
247 
feed_item_set_enclosure(FeedItem * item,FeedItemEnclosure * enclosure)248 void feed_item_set_enclosure(FeedItem *item, FeedItemEnclosure *enclosure)
249 {
250 	g_return_if_fail(item != NULL);
251 	g_return_if_fail(enclosure != NULL);
252 	g_return_if_fail(enclosure->url != NULL);
253 	g_return_if_fail(enclosure->type != NULL);
254 
255 	feed_item_enclosure_free(item->enclosure);
256 	item->enclosure = enclosure;
257 }
258 
259 /* Source title (Atom only) */
feed_item_get_sourcetitle(FeedItem * item)260 gchar *feed_item_get_sourcetitle(FeedItem *item)
261 {
262 	g_return_val_if_fail(item != NULL, NULL);
263 	return item->sourcetitle;
264 }
265 
feed_item_set_sourcetitle(FeedItem * item,const gchar * sourcetitle)266 void feed_item_set_sourcetitle(FeedItem *item, const gchar *sourcetitle)
267 {
268 	g_return_if_fail(item != NULL);
269 	g_return_if_fail(sourcetitle != NULL);
270 
271 	g_free(item->sourcetitle);
272 	item->sourcetitle = g_strdup(sourcetitle);
273 }
274 
275 /* Source ID (Atom only) */
feed_item_get_sourceid(FeedItem * item)276 gchar *feed_item_get_sourceid(FeedItem *item)
277 {
278 	g_return_val_if_fail(item != NULL, NULL);
279 	return item->sourceid;
280 }
281 
feed_item_set_sourceid(FeedItem * item,const gchar * sourceid)282 void feed_item_set_sourceid(FeedItem *item, const gchar *sourceid)
283 {
284 	g_return_if_fail(item != NULL);
285 	g_return_if_fail(sourceid != NULL);
286 
287 	g_free(item->sourceid);
288 	item->sourceid = g_strdup(sourceid);
289 }
290 
291 /* Source date (Atom only) */
feed_item_get_sourcedate(FeedItem * item)292 time_t feed_item_get_sourcedate(FeedItem *item)
293 {
294 	g_return_val_if_fail(item != NULL, -1);
295 	return item->sourcedate;
296 }
297 
feed_item_set_sourcedate(FeedItem * item,time_t date)298 void feed_item_set_sourcedate(FeedItem *item, time_t date)
299 {
300 	g_return_if_fail(item != NULL);
301 	item->sourcedate = date;
302 }
303 
304 /* Date published */
feed_item_get_date_published(FeedItem * item)305 time_t feed_item_get_date_published(FeedItem *item)
306 {
307 	g_return_val_if_fail(item != NULL, -1);
308 	return item->date_published;
309 }
310 
feed_item_set_date_published(FeedItem * item,time_t date)311 void feed_item_set_date_published(FeedItem *item, time_t date)
312 {
313 	g_return_if_fail(item != NULL);
314 	item->date_published = date;
315 }
316 
317 /* Date modified */
feed_item_get_date_modified(FeedItem * item)318 time_t feed_item_get_date_modified(FeedItem *item)
319 {
320 	g_return_val_if_fail(item != NULL, -1);
321 	return item->date_modified;
322 }
323 
feed_item_set_date_modified(FeedItem * item,time_t date)324 void feed_item_set_date_modified(FeedItem *item, time_t date)
325 {
326 	g_return_if_fail(item != NULL);
327 	item->date_modified = date;
328 }
329 
feed_item_copy(FeedItem * item)330 FeedItem *feed_item_copy(FeedItem *item)
331 {
332 	FeedItem *nitem;
333 
334 	g_return_val_if_fail(item != NULL, NULL);
335 
336 	nitem = feed_item_new(NULL);
337 
338 	nitem->url = g_strdup(item->url);
339 	nitem->title = g_strdup(item->title);
340 	nitem->summary = g_strdup(item->summary);
341 	nitem->text = g_strdup(item->text);
342 	nitem->author = g_strdup(item->author);
343 	nitem->id = g_strdup(item->id);
344 	nitem->comments_url = g_strdup(item->comments_url);
345 	nitem->parent_id = g_strdup(item->parent_id);
346 
347 	nitem->enclosure = feed_item_enclosure_copy(item->enclosure);
348 
349 	nitem->date_published = item->date_published;
350 	nitem->date_modified = item->date_modified;
351 
352 	nitem->id_is_permalink = item->id_is_permalink;
353 	nitem->xhtml_content = item->xhtml_content;
354 
355 	/* We have no way of knowing the size of object item->data is pointing
356 	 * to, so we can not reliably copy it to the new item. Caller will have
357 	 * to take care of that itself. */
358 	nitem->data = NULL;
359 
360 	return nitem;
361 }
362 
feed_item_id_is_permalink(FeedItem * item)363 gboolean feed_item_id_is_permalink(FeedItem *item)
364 {
365 	g_return_val_if_fail(item != NULL, FALSE);
366 
367 	return item->id_is_permalink;
368 }
369 
feed_item_set_id_permalink(FeedItem * item,gboolean permalink)370 void feed_item_set_id_permalink(FeedItem *item, gboolean permalink)
371 {
372 	g_return_if_fail(item != NULL);
373 
374 	item->id_is_permalink = permalink;
375 }
376