~ubuntu-branches/ubuntu/saucy/liferea/saucy

« back to all changes in this revision

Viewing changes to src/parsers/atom10.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.3.9) (3.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20120329141721-tbfopcrc5797wxt7
Tags: 1.8.3-0.1ubuntu1
* New upstream release (LP: #290666, #371754, #741543, #716688)
* Merge from Debian unstable (LP: #935147), remaining changes:
* debian/patches:
  - drop gtk-status-icon.patch & notification-append as in upstream
  - drop fix_systray_behavior as mostly upstreamed and rest seems unused
  - 01_ubuntu_feedlists: update & rename, move planets to "Open Source"  
  - add_X-Ubuntu-Gettext-Domain: rebase
  - libunity.patch: rebase, apply before indicator patch (liferea_shell.c)
  - libindicate_increase_version.patch: exclude from libindicate.patch
  - deactivate libindicate.patch, seems partly upstreamed and needs rework
* debian/control: libindicate-dev, libindicate-gtk-dev & libunity-dev
* debian/liferea.indicate & liferea.install: ship indicator desktop file
* debian/rules: enable libindicate

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * @file atom10.c  Atom 1.0 Parser
3
3
 * 
4
4
 * Copyright (C) 2005-2006 Nathan Conrad <t98502@users.sourceforge.net>
5
 
 * Copyright (C) 2003-2009 Lars Lindner <lars.lindner@gmail.com>
 
5
 * Copyright (C) 2003-2010 Lars Lindner <lars.lindner@gmail.com>
6
6
 *
7
7
 * This program is free software; you can redistribute it and/or modify
8
8
 * it under the terms of the GNU General Public License as published by
18
18
 * along with this program; if not, write to the Free Software
19
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
20
 */
 
21
 
 
22
#include "atom10.h"
21
23
 
22
24
#include <string.h>
23
25
 
24
26
#include "common.h"
 
27
#include "date.h"
25
28
#include "debug.h"
26
29
#include "enclosure.h"
27
30
#include "feed_parser.h"
43
46
#include "metadata.h"
44
47
#include "subscription.h"
45
48
#include "xml.h"
46
 
#include "atom10.h"
47
49
 
48
50
#define ATOM10_NS BAD_CAST"http://www.w3.org/2005/Atom"
49
51
 
106
108
        gchar *ret = NULL;
107
109
        
108
110
        if (xmlHasNsProp (cur, BAD_CAST"src", NULL )) {
109
 
                gchar *src = xml_get_ns_attribute (cur, "src", NULL);
110
 
                
111
 
                if (!src) {
112
 
                        ret = g_strdup (_("Liferea is unable to display this item's content."));
113
 
                } else {
114
 
                        gchar *baseURL = common_utf8_fix ((gchar *)xmlNodeGetBase (cur->doc, cur));
115
 
                        xmlChar *url;
116
 
                        
117
 
                        url = common_build_url (src, baseURL);
118
 
                        ret = g_markup_printf_escaped (_("<p><a href=\"%s\">View this item's content.</a></p>"), url);
119
 
                        
120
 
                        g_free (url);
121
 
                        xmlFree (baseURL);
122
 
                        xmlFree (src);
123
 
                }
 
111
                /*
 
112
                   RFC 4287 says a feed must have a summary when there's
 
113
                   a src attribute in the content (and the content therefore
 
114
                   empty). We are already parsing the summary separately.
 
115
 
 
116
                   RFC 4287 also says an entry must contain one link element
 
117
                   with rel="alternate", so there's no point in parsing
 
118
                   src and setting it as link.
 
119
                */
 
120
                ret = NULL;
124
121
        } else {
125
122
                gchar *type;
126
123
 
129
126
                
130
127
                /* Contents need to be de-encoded and should not contain sub-tags.*/
131
128
                if (type && (g_str_equal (type,"html") || !g_ascii_strcasecmp (type, "text/html"))) {
132
 
                        ret = common_utf8_fix (xhtml_extract (cur, 0, NULL));
 
129
                        ret = xhtml_extract (cur, 0, NULL);
133
130
                } else if (!type || !strcmp (type, "text") || !strncasecmp (type, "text/",5)) {
134
131
                        gchar *tmp;
135
132
                        /* Assume that "text/ *" files can be directly displayed.. kinda stated in the RFC */
136
 
                        ret = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
133
                        ret = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
137
134
                        
138
135
                        g_strchug (g_strchomp (ret));
139
136
                        
145
142
                        ret = tmp;
146
143
                } else if (!strcmp(type,"xhtml") || !g_ascii_strcasecmp (type, "application/xhtml+xml")) {
147
144
                        /* The spec says to only show the contents of the div tag that MUST be present */
148
 
                        ret = common_utf8_fix(xhtml_extract (cur, 2, NULL));
 
145
                        ret = xhtml_extract (cur, 2, NULL);
149
146
                } else {
150
147
                        /* Do nothing on unsupported content types. This allows summaries to be used. */
151
148
                        ret = NULL;
177
174
        
178
175
        /* This that need to be de-encoded and should not contain sub-tags.*/
179
176
        if (!type || !strcmp(type, "text")) {
180
 
                ret = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
177
                ret = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
181
178
                if (ret) {
182
179
                        g_strchug (g_strchomp (ret));
183
180
 
188
185
                        }
189
186
                }
190
187
        } else if (!strcmp(type, "html")) {
191
 
                ret = common_utf8_fix (xhtml_extract (cur, 0, NULL));
 
188
                ret = xhtml_extract (cur, 0, NULL);
192
189
                if (!htmlified)
193
190
                        ret = unhtmlize (unxmlize (ret));
194
191
        } else if (!strcmp (type, "xhtml")) {
195
192
                /* The spec says to show the contents of the div tag that MUST be present */
196
 
                ret = common_utf8_fix (xhtml_extract (cur, 2, NULL));
 
193
                ret = xhtml_extract (cur, 2, NULL);
197
194
                
198
195
                if (!htmlified)
199
196
                        ret = unhtmlize (ret);
224
221
                if (xmlStrEqual (cur->ns->href, ATOM10_NS)) {
225
222
                        if (xmlStrEqual (cur->name, BAD_CAST"name")) {
226
223
                                g_free (name);
227
 
                                name = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
224
                                name = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
228
225
                        }
229
226
                        
230
227
                        if (xmlStrEqual (cur->name, BAD_CAST"email")) {
231
228
                                if (email)
232
229
                                        invalid = TRUE;
233
230
                                g_free(email);
234
 
                                tmp = common_utf8_fix((gchar *)xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1));
 
231
                                tmp = (gchar *)xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);
235
232
                                email = g_markup_printf_escaped (" - <a href=\"mailto:%s\">%s</a>", tmp, tmp);
236
233
                                g_free(tmp);
237
234
                        }
240
237
                                if (!uri)
241
238
                                        invalid = TRUE;
242
239
                                g_free (uri);
243
 
                                tmp = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
244
 
                                uri = g_markup_printf_escaped (" (<a href=\"%s\">Website</a>)", tmp);
 
240
                                tmp = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
 
241
                                uri = g_markup_printf_escaped (" (<a href=\"%s\">%s</a>)", tmp, _("Website"));
245
242
                                g_free (tmp);
246
243
                        }
247
244
                } else {
253
250
                invalid = TRUE;
254
251
                name = g_strdup (_("Invalid Atom feed: unknown author"));
255
252
        }
256
 
        /* FIXME: so somthing with "invalid" flag */
 
253
        /* FIXME: so something with "invalid" flag */
257
254
        tmp = g_strdup_printf ("%s%s%s", name, uri?uri:"", email?email:"");
258
255
        g_free (uri);
259
256
        g_free (email);
271
268
        if (href) {
272
269
                xmlChar *baseURL = xmlNodeGetBase (cur->doc, cur);
273
270
                gchar *url, *relation, *type, *escTitle = NULL, *title;
 
271
                const gchar *feedURL = subscription_get_homepage (ctxt->subscription);
274
272
                
275
 
                if (!baseURL && ctxt->feed->htmlUrl && 
276
 
                    ctxt->feed->htmlUrl[0] != '|' &&
277
 
                    strstr (ctxt->feed->htmlUrl, "://"))
278
 
                        baseURL = xmlStrdup (BAD_CAST (ctxt->feed->htmlUrl));
 
273
                if (!baseURL && feedURL && feedURL[0] != '|' && strstr (feedURL, "://"))
 
274
                        baseURL = xmlStrdup (BAD_CAST (feedURL));
279
275
                url = (gchar *)common_build_url (href, (gchar *)baseURL);
280
276
 
281
277
                type = xml_get_ns_attribute (cur, "type", NULL);
384
380
{
385
381
        gchar *id;
386
382
        
387
 
        id = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
383
        id = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
388
384
        if (id) {
389
385
                if (strlen (id) > 0) {
390
386
                        item_set_id (ctxt->item, id);
411
407
{
412
408
        gchar *datestr;
413
409
        
414
 
        datestr = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
410
        datestr = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
415
411
        if (datestr) {
416
 
                ctxt->item->time = parseISO8601Date (datestr);
 
412
                ctxt->item->time = date_parse_ISO8601 (datestr);
417
413
                ctxt->item->metadata = metadata_list_append (ctxt->item->metadata, "pubDate", datestr);
418
414
                g_free (datestr);
419
415
        }
451
447
{
452
448
        gchar *title;
453
449
        
454
 
        title = common_utf8_fix (atom10_parse_text_construct(cur, FALSE));
 
450
        title = atom10_parse_text_construct(cur, FALSE);
455
451
        if (title) {
456
452
                item_set_title (ctxt->item, title);
457
453
                g_free (title);
463
459
{
464
460
        gchar *datestr;
465
461
        
466
 
        datestr = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
462
        datestr = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
467
463
        /* if pubDate is already set, don't overwrite it */
468
464
        if (datestr && !metadata_list_get(ctxt->item->metadata, "pubDate")) {
469
 
                ctxt->item->time = parseISO8601Date (datestr);
 
465
                ctxt->item->time = date_parse_ISO8601 (datestr);
470
466
                ctxt->item->metadata = metadata_list_append (ctxt->item->metadata, "contentUpdateDate", datestr);
471
467
        }
472
468
 
619
615
static void
620
616
atom10_parse_feed_icon (xmlNodePtr cur, feedParserCtxtPtr ctxt, struct atom10ParserState *state)
621
617
{
622
 
        /* FIXME: Parse icon and use as a favicon? */
 
618
        gchar *icon_uri;
 
619
 
 
620
        icon_uri = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
 
621
 
 
622
        if (icon_uri) {
 
623
                debug1 (DEBUG_PARSING, "icon URI found in atom feed: %s", icon_uri);
 
624
                ctxt->subscription->metadata = metadata_list_append (ctxt->subscription->metadata,
 
625
                                                                     "icon", icon_uri);
 
626
        }
623
627
}
624
628
 
625
629
static void
695
699
        }
696
700
}
697
701
 
 
702
/* Sort items in descending date order (newer items first). */
 
703
static gint
 
704
atom10_item_sort_by_date (gconstpointer a, gconstpointer b)
 
705
{
 
706
        itemPtr item1 = (itemPtr)a;
 
707
        itemPtr item2 = (itemPtr)b;
 
708
 
 
709
        g_assert (item1 && item2);
 
710
 
 
711
        if (item1->time == item2->time) {
 
712
                /* Items identical.. can we distinguish further? */
 
713
                return 0;
 
714
        }
 
715
        
 
716
        if (item1->time < item2->time)
 
717
                return 1;
 
718
        if (item1->time > item2->time)
 
719
                return -1;
 
720
 
 
721
        return 0;
 
722
}
 
723
 
698
724
static void
699
725
atom10_parse_feed_updated (xmlNodePtr cur, feedParserCtxtPtr ctxt, struct atom10ParserState *state)
700
726
{
701
727
        gchar *timestamp;
702
728
        
703
 
        timestamp = common_utf8_fix ((gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1));
 
729
        timestamp = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
704
730
        if (timestamp) {
705
731
                ctxt->subscription->metadata = metadata_list_append (ctxt->subscription->metadata, "contentUpdateDate", timestamp);
706
 
                ctxt->feed->time = parseISO8601Date (timestamp);
 
732
                ctxt->feed->time = date_parse_ISO8601 (timestamp);
707
733
                g_free (timestamp);
708
734
        }
709
735
}
789
815
                        } else if (xmlStrEqual (cur->name, BAD_CAST"entry")) {
790
816
                                ctxt->item = atom10_parse_entry (ctxt, cur);
791
817
                                if (ctxt->item)
792
 
                                        ctxt->items = g_list_append (ctxt->items, ctxt->item);
 
818
                                        ctxt->items = g_list_insert_sorted (ctxt->items, ctxt->item, atom10_item_sort_by_date);
793
819
                        }
794
820
                        cur = cur->next;
795
821
                }
846
872
                atom10_add_ns_handler (ns_georss_get_handler ());
847
873
        }       
848
874
        /* prepare feed handler structure */
849
 
        fhp->typeStr = "pie";
850
 
        fhp->icon = ICON_AVAILABLE;
 
875
        fhp->typeStr = "atom";
851
876
        fhp->feedParser = atom10_parse_feed;
852
877
        fhp->checkFormat = atom10_format_check;
853
 
        fhp->merge = TRUE;
854
878
 
855
879
        return fhp;
856
880
}