50
39
GSList *data; /** list of metadata values */
54
metadata_type_register (const gchar *name, gint type)
57
metadataTypes = g_hash_table_new (g_str_hash, g_str_equal);
59
g_hash_table_insert (metadataTypes, (gpointer)name, GINT_TO_POINTER (type));
42
/* register metadata types to check validity on adding */
63
44
metadata_init (void)
65
/* register metadata types to check validity on adding */
46
g_assert (NULL == metadataTypes);
48
metadataTypes = g_hash_table_new (g_str_hash, g_str_equal);
67
50
/* generic types */
68
51
metadata_type_register ("author", METADATA_TYPE_HTML);
69
52
metadata_type_register ("contributor", METADATA_TYPE_HTML);
70
53
metadata_type_register ("copyright", METADATA_TYPE_HTML);
71
54
metadata_type_register ("language", METADATA_TYPE_HTML);
72
metadata_type_register ("pubDate", METADATA_TYPE_ASCII);
73
metadata_type_register ("contentUpdateDate", METADATA_TYPE_ASCII);
55
metadata_type_register ("pubDate", METADATA_TYPE_TEXT);
56
metadata_type_register ("contentUpdateDate", METADATA_TYPE_TEXT);
74
57
metadata_type_register ("managingEditor", METADATA_TYPE_HTML);
75
58
metadata_type_register ("webmaster", METADATA_TYPE_HTML);
76
59
metadata_type_register ("feedgenerator", METADATA_TYPE_HTML);
77
60
metadata_type_register ("imageUrl", METADATA_TYPE_URL);
61
metadata_type_register ("icon", METADATA_TYPE_URL);
78
62
metadata_type_register ("homepage", METADATA_TYPE_URL);
79
63
metadata_type_register ("textInput", METADATA_TYPE_HTML);
80
64
metadata_type_register ("errorReportsTo", METADATA_TYPE_HTML);
81
65
metadata_type_register ("feedgeneratorUri", METADATA_TYPE_URL);
82
66
metadata_type_register ("category", METADATA_TYPE_HTML);
83
metadata_type_register ("enclosure", METADATA_TYPE_ASCII);
67
metadata_type_register ("enclosure", METADATA_TYPE_TEXT);
84
68
metadata_type_register ("commentsUri", METADATA_TYPE_URL);
85
69
metadata_type_register ("commentFeedUri", METADATA_TYPE_URL);
86
70
metadata_type_register ("feedTitle", METADATA_TYPE_HTML);
138
143
type = GPOINTER_TO_INT (g_hash_table_lookup (metadataTypes, (gpointer)name));
140
debug1 (DEBUG_PARSING, "unknown metadata type (%s)", name);
145
g_warning ("Unknown metadata type: %s, please report this Liferea bug!", name);
145
GSList * metadata_list_append(GSList *metadata, const gchar *strid, const gchar *data) {
151
metadata_list_append (GSList *metadata, const gchar *strid, const gchar *data)
146
153
GSList *iter = metadata;
147
154
gchar *tmp, *checked_data = NULL;
153
160
/* lookup type and check format */
154
switch(metadata_get_type(strid)) {
155
case METADATA_TYPE_ASCII:
161
switch (metadata_get_type (strid)) {
162
case METADATA_TYPE_TEXT:
156
163
/* No check because renderer will process further */
157
checked_data = g_strdup(data);
164
checked_data = g_strdup (data);
159
166
case METADATA_TYPE_URL:
160
167
/* Simple sanity check to see if it doesn't break XML */
161
if(!strchr(data, '<') && !(strchr(data, '>')) && !(strchr(data, '&'))) {
162
checked_data = g_strdup(data);
168
if (!strchr(data, '<') && !(strchr (data, '>')) && !(strchr (data, '&'))) {
169
checked_data = g_strdup (data);
164
checked_data = common_uri_escape(data);
171
checked_data = common_uri_escape (data);
167
174
/* finally strip whitespace */
168
175
checked_data = g_strchomp (checked_data);
171
debug1(DEBUG_CACHE, "Unknown metadata type \"%s\", this is a program bug! Treating as HTML.", strid);
178
g_warning ("Unknown metadata type: %s (id=%d), please report this Liferea bug! Treating as HTML.", strid, metadata_get_type (strid));
172
179
case METADATA_TYPE_HTML:
173
180
/* Needs to check for proper XHTML */
174
181
if (xhtml_is_well_formed (data)) {
188
195
p = (struct pair*)iter->data;
189
if(g_str_equal(p->strid, strid)) {
190
p->data = g_slist_append(p->data, checked_data);
196
if (g_str_equal (p->strid, strid)) {
197
p->data = g_slist_append (p->data, checked_data);
193
200
iter = iter->next;
195
p = g_new(struct pair, 1);
196
p->strid = g_strdup(strid);
197
p->data = g_slist_append(NULL, checked_data);
198
metadata = g_slist_append(metadata, p);
202
p = g_new (struct pair, 1);
203
p->strid = g_strdup (strid);
204
p->data = g_slist_append (NULL, checked_data);
205
metadata = g_slist_append (metadata, p);
202
void metadata_list_set(GSList **metadata, const gchar *strid, const gchar *data) {
210
metadata_list_set (GSList **metadata, const gchar *strid, const gchar *data)
203
212
GSList *iter = *metadata;
207
216
p = (struct pair*)iter->data;
208
if(g_str_equal(p->strid, strid)) {
217
if (g_str_equal (p->strid, strid)) {
210
219
/* exchange old value */
211
g_free(((GSList *)p->data)->data);
212
((GSList *)p->data)->data = g_strdup(data);
220
g_free (((GSList *)p->data)->data);
221
((GSList *)p->data)->data = g_strdup (data);
214
p->data = g_slist_append(p->data, g_strdup(data));
223
p->data = g_slist_append (p->data, g_strdup (data));
218
227
iter = iter->next;
220
p = g_new(struct pair, 1);
221
p->strid = g_strdup(strid);
222
p->data = g_slist_append(NULL, g_strdup(data));
223
*metadata = g_slist_append(*metadata, p);
229
p = g_new (struct pair, 1);
230
p->strid = g_strdup (strid);
231
p->data = g_slist_append (NULL, g_strdup (data));
232
*metadata = g_slist_append (*metadata, p);
226
void metadata_list_foreach(GSList *metadata, metadataForeachFunc func, gpointer user_data) {
236
metadata_list_foreach (GSList *metadata, metadataForeachFunc func, gpointer user_data)
227
238
GSList *list = metadata;
231
242
struct pair *p = (struct pair*)list->data;
232
243
GSList *values = (GSList *)p->data;
235
246
(*func)(p->strid, values->data, index, user_data);
236
values = g_slist_next(values);
247
values = g_slist_next (values);
238
249
list = list->next;
242
GSList * metadata_list_get_values(GSList *metadata, const gchar *strid) {
254
metadata_list_get_values (GSList *metadata, const gchar *strid)
243
256
GSList *list = metadata;
246
259
struct pair *p = (struct pair*)list->data;
247
if(g_str_equal(p->strid, strid))
260
if (g_str_equal (p->strid, strid))
249
262
list = list->next;
254
const gchar * metadata_list_get(GSList *metadata, const gchar *strid) {
268
metadata_list_get (GSList *metadata, const gchar *strid)
257
values = metadata_list_get_values(metadata, strid);
272
values = metadata_list_get_values (metadata, strid);
258
273
return values?values->data:NULL;
262
GSList * metadata_list_copy(GSList *list) {
278
metadata_list_copy (GSList *list)
263
280
GSList *copy = NULL;
264
GSList *list2, *iter2, *iter = list;
281
GSList *iter2, *iter = list;
268
285
p = (struct pair*)iter->data;
269
iter2 = list2 = p->data;
271
copy = metadata_list_append(copy, p->strid, iter2->data);
288
copy = metadata_list_append (copy, p->strid, iter2->data);
272
289
iter2 = iter2->next;
274
291
iter = iter->next;
280
void metadata_list_free(GSList *metadata) {
298
metadata_list_free (GSList *metadata)
281
300
GSList *list2, *iter2, *iter = metadata;
284
while(iter != NULL) {
285
304
p = (struct pair*)iter->data;
288
while(iter2 != NULL) {
308
g_free (iter2->data);
290
309
iter2 = iter2->next;
311
g_slist_free (list2);
295
314
iter = iter->next;
297
g_slist_free(metadata);
316
g_slist_free (metadata);
300
void metadata_add_xml_nodes(GSList *metadata, xmlNodePtr parentNode) {
320
metadata_add_xml_nodes (GSList *metadata, xmlNodePtr parentNode)
301
322
GSList *list = metadata;
302
323
xmlNodePtr attribute;
303
xmlNodePtr metadataNode = xmlNewChild(parentNode, NULL, "attributes", NULL);
324
xmlNodePtr metadataNode = xmlNewChild (parentNode, NULL, "attributes", NULL);
306
327
struct pair *p = (struct pair*)list->data;
307
328
GSList *list2 = p->data;
309
attribute = xmlNewTextChild(metadataNode, NULL, "attribute", list2->data);
310
xmlNewProp(attribute, "name", p->strid);
330
attribute = xmlNewTextChild (metadataNode, NULL, "attribute", list2->data);
331
xmlNewProp (attribute, "name", p->strid);
311
332
list2 = list2->next;
313
334
list = list->next;
317
GSList * metadata_parse_xml_nodes(xmlNodePtr cur) {
339
metadata_parse_xml_nodes (xmlNodePtr cur)
318
341
xmlNodePtr attribute = cur->xmlChildrenNode;
319
342
GSList *metadata = NULL;
322
if(attribute->type == XML_ELEMENT_NODE &&
323
!xmlStrcmp(attribute->name, BAD_CAST"attribute")) {
324
xmlChar *name = xmlGetProp(attribute, BAD_CAST"name");
326
gchar *value = xmlNodeListGetString(cur->doc, attribute->xmlChildrenNode, TRUE);
328
metadata = metadata_list_append(metadata, name, value);
345
if (attribute->type == XML_ELEMENT_NODE &&
346
!xmlStrcmp (attribute->name, BAD_CAST"attribute")) {
347
xmlChar *name = xmlGetProp (attribute, BAD_CAST"name");
349
gchar *value = xmlNodeListGetString (cur->doc, attribute->xmlChildrenNode, TRUE);
351
metadata = metadata_list_append (metadata, name, value);
334
357
attribute = attribute->next;