diff options
Diffstat (limited to 'src/tocxml.c')
-rw-r--r-- | src/tocxml.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/tocxml.c b/src/tocxml.c new file mode 100644 index 0000000..3740326 --- /dev/null +++ b/src/tocxml.c @@ -0,0 +1,264 @@ +/* + * Copyright 2006 Nick White + * + * This file is part of GetHT + * + * GetHT is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GetHT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GetHT; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libxml/xmlmemory.h> +#include <libxml/parser.h> + +#include "issue.h" +#include "getht.h" + +iss ** parsetoc(char *filepath, int * iss_no, int * latest); +int parseissue(xmlDocPtr file, xmlNodePtr node, iss * cur_issue, int * latest); +void parsesection(xmlDocPtr file, xmlNodePtr node, sec * cur_section); + +void tokenise_hyphons(char to_token[10], int * first, int * last); + +int no_of_issues; + +iss ** parsetoc(char *filepath, int * iss_no, int * latest) +/* starts parsing of xml to issue structure */ +{ + xmlDocPtr file; + xmlNodePtr node; + + if(ready_xml(filepath, "issues", &file, &node)) + return NULL; + + *node = *node->xmlChildrenNode; + + no_of_issues = -1; + + iss ** issue = NULL; + + int year; + + xmlNodePtr cnode; + + while(node != NULL) + { + if(!xmlStrncmp(node->name,(char *) "year",4)) + { + cnode = node->children; + while(cnode != NULL) + { + if(!xmlStrncmp(cnode->name,(char *) "issue",5)) + { + /* assign memory for the new issue */ + issue = assignnew_iss(issue, &no_of_issues); + + /* setup issue globals */ + issue[no_of_issues]->no_of_media = -1; + issue[no_of_issues]->no_of_sections = -1; + issue[no_of_issues]->date.year = + atoi( (const char *)(xmlStrsub(node->name,5,4)) ); + tokenise_hyphons( + xmlStrsub(cnode->name,6,5), + &(issue[no_of_issues]->date.firstmonth), + &(issue[no_of_issues]->date.lastmonth)); + + /* parse the issue */ + parseissue(file, cnode, issue[no_of_issues], latest); + } + cnode = cnode->next; + } + } + node = node->next; + } + + xmlFreeDoc(file); + + *iss_no = no_of_issues; + + issuesort(issue, no_of_issues); + + return issue; +} + +int parseissue(xmlDocPtr file, xmlNodePtr node, iss * cur_issue, int * latest) +/* parses issue from xml, saving in cur_issue structure */ +{ + strncpy(cur_issue->title, (char *) xmlGetProp(node, "title"), STR_MAX); + strncpy(cur_issue->preview_uri, (char *) xmlGetProp(node, "coverlink"), STR_MAX); + + if(xmlGetProp(node, "current") && *latest==-1) + *latest = no_of_issues; + + node = node->xmlChildrenNode; + + while(node != NULL){ + if(!xmlStrncmp(node->name, (char *) "section",7) || + !xmlStrcmp(node->name, (const xmlChar *) "cover")) + { + /* assign memory for new section */ + cur_issue->section = + assignnew_sec(cur_issue->section, &(cur_issue->no_of_sections)); + + /* setup section globals */ + cur_issue->section[cur_issue->no_of_sections]->no_of_items = -1; + + /* parse the section */ + parsesection(file, node, cur_issue->section[cur_issue->no_of_sections]); + } + node = node->next; + } + + return 0; +} + +void parsesection(xmlDocPtr file, xmlNodePtr node, sec * cur_section) +/* parses section xml, filling cur_section structure */ +{ + it * cur_item = NULL; + + strncpy(cur_section->uri, (char *) xmlGetProp(node, "pdflink"), STR_MAX); + strncpy(cur_section->title, (char *) xmlGetProp(node, "title"), STR_MAX); + + if(!xmlStrcmp(node->name, (const xmlChar *) "cover")) + cur_section->number = 0; + else + cur_section->number = atoi( (const char *)(xmlStrsub(node->name,8,1)) ); + + node = node->xmlChildrenNode; + + char * pagenums; + + it ** tmp = NULL; + + while(node != NULL) + { + if(!xmlStrcmp(node->name, (const xmlChar *) "item")) + { + if(xmlNodeListGetString(file, node->xmlChildrenNode, 1) != NULL) + /* ignore items without titles */ + { + /* assign memory for new item */ + cur_section->item = + assignnew_it( cur_section->item, &(cur_section->no_of_items)); + + cur_item = cur_section->item[cur_section->no_of_items]; + + /* parse item */ + cur_item->title = xmlNodeListGetString(file, node->xmlChildrenNode, 1); + if(pagenums = (char *) xmlGetProp(node, "pages")) + tokenise_hyphons(pagenums, &(cur_item->firstpage), &(cur_item->lastpage)); + else + { + cur_item->firstpage = 0; + cur_item->lastpage = 0; + } + } + } + node = node->next; + } +} + +void tokenise_hyphons(char to_token[10], int * first, int * last) +/* splits string to_token, filling positions passed */ +{ + char token[10]; + char * tmp; + + tmp = token; + + while(*to_token != '-' && *to_token) + { + *tmp = *to_token; + to_token++; tmp++; + } + + *first = atoi(token); + + if(!*to_token) + *last = *first; + else + { + to_token++; /* advance past '-' */ + tmp = token; /* reset tmp */ + while(*to_token) + { + *tmp = *to_token; + tmp++; to_token++; + } + *last = atoi(token); + } +} + +int cur_identifiers(char * filepath, char * title, issdates * date) +/* parses xml file to ascertain current issue title and date */ +{ + xmlDocPtr file; + + if((file = xmlParseFile(filepath)) == NULL) + { + return 1; + } + + xmlNodePtr node,cnode; + + node = xmlDocGetRootElement(file); + + if(node == NULL) + { + fprintf(stderr,"Error: xml file %s has no root element",filepath); + xmlFreeDoc(file); + return 1; + } + + if(xmlStrcmp(node->name, (const xmlChar *) "issues")) + { + fprintf(stderr,"Document of the wrong type, root node is '%s' (expected 'issues').\n",(char *) node->name); + fprintf(stderr,"Continuing regardless...\n"); + } + + /* Now that's all sorted, let's do some work */ + + node = node->xmlChildrenNode; + + xmlChar *temp; + while(node != NULL) + { + if(!xmlStrncmp(node->name,(char *) "year",4)) + { + cnode = node->children; + while(cnode != NULL) + { + if(!xmlStrncmp(cnode->name,(char *) "issue",5)) + { + temp = xmlGetProp(cnode, "current"); + if(temp) + { + strncpy(title, (char *) xmlGetProp(cnode, "title"), STR_MAX); + date->year = atoi( (const char *)(xmlStrsub(node->name,5,4)) ); + tokenise_hyphons(xmlStrsub(cnode->name,6,5), &(date->firstmonth), &(date->lastmonth)); + return 0; + } + } + cnode = cnode->next; + } + } + node = node->next; + } + + return 0; +} |