2 * Copyright (C) 2006 Andrej Kacian <andrej@kacian.sk>
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.
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.
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.
30 #include "parser_atom10.h"
32 void feed_parser_atom10_start(void *data, const gchar *el, const gchar **attr)
34 FeedParserCtx *ctx = (FeedParserCtx *)data;
37 if( ctx->depth == 1 ) {
39 if( !strcmp(el, "entry") ) {
40 /* Start of new feed item found.
41 * Create a new FeedItem, freeing the one we already have, if any. */
42 if( ctx->curitem != NULL )
43 feed_item_free(ctx->curitem);
44 ctx->curitem = feed_item_new(ctx->feed);
45 ctx->location = FEED_LOC_ATOM10_ENTRY;
46 } else if( !strcmp(el, "author") ) {
47 /* Start of author info for the feed found.
48 * Set correct location. */
49 ctx->location = FEED_LOC_ATOM10_AUTHOR;
50 } else ctx->location = FEED_LOC_ATOM10_NONE;
52 } else if( ctx->depth == 2 ) {
54 /* Make sure we are in one of known locations within the XML structure.
55 * This condition should never be true on a valid Atom feed. */
56 if (ctx->location != FEED_LOC_ATOM10_AUTHOR &&
57 ctx->location != FEED_LOC_ATOM10_ENTRY) {
62 if( !strcmp(el, "author") ) {
63 /* Start of author info for current feed item.
64 * Set correct location. */
65 ctx->location = FEED_LOC_ATOM10_AUTHOR;
66 } else if( !strcmp(el, "link") ) {
67 /* Capture item URL, from the "url" XML attribute. */
68 if (ctx->curitem && ctx->location == FEED_LOC_ATOM10_ENTRY)
69 ctx->curitem->url = g_strdup(feed_parser_get_attribute_value(attr, "href"));
70 } else if( !strcmp(el, "source") ) {
71 ctx->location = FEED_LOC_ATOM10_SOURCE;
72 } else ctx->location = FEED_LOC_ATOM10_ENTRY;
74 if( !strcmp(el, "title") ) {
75 a = feed_parser_get_attribute_value(attr, "type");
76 if( !a || !strcmp(a, "text") )
77 ctx->curitem->title_format = FEED_ITEM_TITLE_TEXT;
78 else if( !strcmp(a, "html") )
79 ctx->curitem->title_format = FEED_ITEM_TITLE_HTML;
80 else if( !strcmp(a, "xhtml") )
81 ctx->curitem->title_format = FEED_ITEM_TITLE_XHTML;
83 ctx->curitem->title_format = FEED_ITEM_TITLE_UNKNOWN;
84 } else if (!strcmp(el, "content") ) {
85 a = feed_parser_get_attribute_value(attr, "type");
86 if (a && !strcmp(a, "xhtml")) {
87 ctx->curitem->xhtml_content = TRUE;
88 ctx->location = FEED_LOC_ATOM10_CONTENT;
96 void feed_parser_atom10_end(void *data, const gchar *el)
98 FeedParserCtx *ctx = (FeedParserCtx *)data;
99 Feed *feed = ctx->feed;
102 if( ctx->str != NULL )
103 text = ctx->str->str;
107 switch( ctx->depth ) {
115 if( !strcmp(el, "feed") ) {
116 /* We have finished parsing the feed, reverse the list
117 * so it's not upside down. */
118 feed->items = g_slist_reverse(ctx->feed->items);
125 /* decide if we just received </entry>, so we can
126 * add a complete item to feed */
127 if( !strcmp(el, "entry") ) {
129 /* append the complete feed item */
130 if( ctx->curitem->id && ctx->curitem->title
131 && ctx->curitem->date_modified ) {
133 g_slist_prepend(feed->items, (gpointer)ctx->curitem);
136 /* since it's in the linked list, lose this pointer */
139 } else if( !strcmp(el, "title") ) { /* so it wasn't end of item */
141 } else if( !strcmp(el, "summary" ) ) {
142 FILL(feed->description)
143 } else if( !strcmp(el, "updated" ) ) {
144 feed->date = parseISO8601Date(text);
146 /* FIXME: add more later */
152 if( ctx->curitem == NULL )
155 switch(ctx->location) {
157 /* We're in feed/entry */
158 case FEED_LOC_ATOM10_ENTRY:
159 if( !strcmp(el, "title") ) {
160 FILL(ctx->curitem->title)
161 } else if( !strcmp(el, "summary") ) {
162 FILL(ctx->curitem->summary)
163 } else if( !strcmp(el, "content") ) {
164 if (!ctx->curitem->xhtml_content)
165 FILL(ctx->curitem->text)
166 } else if( !strcmp(el, "id") ) {
167 FILL(ctx->curitem->id)
168 feed_item_set_id_permalink(ctx->curitem, TRUE);
169 } else if( !strcmp(el, "published") ) {
170 ctx->curitem->date_published = parseISO8601Date(text);
171 } else if( !strcmp(el, "updated") ) {
172 ctx->curitem->date_modified = parseISO8601Date(text);
177 /* We're in feed/author or about to leave feed/entry/author */
178 case FEED_LOC_ATOM10_AUTHOR:
179 if( !strcmp(el, "author" ) ) {
180 /* We just finished parsing <author> */
181 ctx->curitem->author = g_strdup_printf("%s%s%s%s%s",
182 ctx->name ? ctx->name : "",
183 ctx->name && ctx->mail ? " <" : ctx->mail ? "<" : "",
184 ctx->mail ? ctx->mail : "",
185 ctx->mail ? ">" : "",
186 !ctx->name && !ctx->mail ? "N/A" : "");
187 ctx->location = FEED_LOC_ATOM10_ENTRY;
188 } else if( !strcmp(el, "name") ) {
199 if( ctx->curitem == NULL )
202 switch(ctx->location) {
204 /* We're in feed/entry/author */
205 case FEED_LOC_ATOM10_AUTHOR:
206 if( !strcmp(el, "name") ) {
208 } else if( !strcmp(el, "email") ) {
214 /* We're in feed/entry/source */
215 case FEED_LOC_ATOM10_SOURCE:
216 if( !strcmp(el, "title" ) ) {
217 FILL(ctx->curitem->sourcetitle)
218 } else if( !strcmp(el, "id" ) ) {
219 FILL(ctx->curitem->sourceid)
220 } else if( !strcmp(el, "updated" ) ) {
221 ctx->curitem->sourcedate = parseISO8601Date(text);
226 case FEED_LOC_ATOM10_CONTENT:
227 if (!strcmp(el, "div") && ctx->curitem->xhtml_content)
228 FILL(ctx->curitem->text)
237 if( ctx->str != NULL ) {
238 g_string_free(ctx->str, TRUE);