ali@0
|
1 |
/*
|
ali@0
|
2 |
* This program parses the XML data provided by sourceforge to extract the
|
ali@0
|
3 |
* list of "attached files" (which are not themselves included in the XML
|
ali@0
|
4 |
* stream and therefore need to be seperately downloaded for archiving).
|
ali@0
|
5 |
*/
|
ali@0
|
6 |
|
ali@0
|
7 |
#include <stdlib.h>
|
ali@0
|
8 |
#include <stdio.h>
|
ali@0
|
9 |
#include <string.h>
|
ali@0
|
10 |
#include <libxml/xmlmemory.h>
|
ali@0
|
11 |
#include <libxml/parser.h>
|
ali@0
|
12 |
|
ali@0
|
13 |
struct artifact_type {
|
ali@0
|
14 |
char *name;
|
ali@0
|
15 |
int id;
|
ali@0
|
16 |
} artifact_types[] = {
|
ali@0
|
17 |
"Bugs", 109746,
|
ali@0
|
18 |
"Support Requests", 209746,
|
ali@0
|
19 |
"Patches", 309746,
|
ali@0
|
20 |
"Feature Requests", 359746,
|
ali@0
|
21 |
};
|
ali@0
|
22 |
|
ali@0
|
23 |
#ifndef NO_ELEMS
|
ali@0
|
24 |
#define NO_ELEMS(array) (sizeof(array)/sizeof(*(array)))
|
ali@0
|
25 |
#endif
|
ali@0
|
26 |
|
ali@0
|
27 |
void parse_history(xmlDocPtr doc,const xmlChar *artifact_id,
|
ali@0
|
28 |
const xmlChar *artifact_type,xmlNodePtr node)
|
ali@0
|
29 |
{
|
ali@0
|
30 |
xmlNodePtr field,cur;
|
ali@0
|
31 |
xmlAttrPtr attr;
|
ali@0
|
32 |
xmlChar *name=NULL;
|
ali@0
|
33 |
xmlChar *field_name=NULL;
|
ali@0
|
34 |
xmlChar *text;
|
ali@0
|
35 |
int file_id,i;
|
ali@0
|
36 |
for(field=node->xmlChildrenNode;field;field=field->next)
|
ali@0
|
37 |
if (!xmlStrcmp(field->name,(const xmlChar *)"field"))
|
ali@0
|
38 |
{
|
ali@0
|
39 |
for(attr=field->properties;attr;attr=attr->next)
|
ali@0
|
40 |
if (!xmlStrcmp(attr->name,(const xmlChar *)"name"))
|
ali@0
|
41 |
{
|
ali@0
|
42 |
name=xmlNodeListGetString(doc,attr->children,1);
|
ali@0
|
43 |
if (!xmlStrcmp(name,(const xmlChar *)"field_name"))
|
ali@0
|
44 |
field_name=xmlNodeListGetString(doc,field->children,1);
|
ali@0
|
45 |
if (!xmlStrcmp(field_name,(const xmlChar *)"File Added") &&
|
ali@0
|
46 |
!xmlStrcmp(name,(const xmlChar *)"old_value"))
|
ali@0
|
47 |
{
|
ali@0
|
48 |
text=xmlNodeListGetString(doc,field->children,1);
|
ali@0
|
49 |
if (sscanf(text,"%d",&file_id)==1)
|
ali@0
|
50 |
{
|
ali@0
|
51 |
for(i=NO_ELEMS(artifact_types)-1;i>=0;i--)
|
ali@0
|
52 |
if (!strcmp(artifact_types[i].name,
|
ali@0
|
53 |
(const char *)artifact_type))
|
ali@0
|
54 |
break;
|
ali@0
|
55 |
if (i>=0)
|
ali@0
|
56 |
printf("%d %s %d\n",
|
ali@0
|
57 |
artifact_types[i].id,artifact_id,file_id);
|
ali@0
|
58 |
else
|
ali@0
|
59 |
fprintf(stderr,
|
ali@0
|
60 |
"Warning: Unknown artifact type \"%s\" - "
|
ali@0
|
61 |
"attached file %s ignored\n",
|
ali@0
|
62 |
artifact_type,text);
|
ali@0
|
63 |
}
|
ali@0
|
64 |
xmlFree(text);
|
ali@0
|
65 |
}
|
ali@0
|
66 |
xmlFree(name);
|
ali@0
|
67 |
}
|
ali@0
|
68 |
}
|
ali@0
|
69 |
if (field_name)
|
ali@0
|
70 |
xmlFree(field_name);
|
ali@0
|
71 |
}
|
ali@0
|
72 |
|
ali@0
|
73 |
void parse_artifact(xmlDocPtr doc,xmlNodePtr node)
|
ali@0
|
74 |
{
|
ali@0
|
75 |
xmlNodePtr field,cur;
|
ali@0
|
76 |
xmlAttrPtr attr;
|
ali@0
|
77 |
xmlChar *name=NULL;
|
ali@0
|
78 |
xmlChar *id=NULL;
|
ali@0
|
79 |
xmlChar *type=NULL;
|
ali@0
|
80 |
xmlChar *text;
|
ali@0
|
81 |
for(field=node->xmlChildrenNode;field;field=field->next)
|
ali@0
|
82 |
if (!xmlStrcmp(field->name,(const xmlChar *)"field"))
|
ali@0
|
83 |
{
|
ali@0
|
84 |
for(attr=field->properties;attr;attr=attr->next)
|
ali@0
|
85 |
if (!xmlStrcmp(attr->name,(const xmlChar *)"name"))
|
ali@0
|
86 |
{
|
ali@0
|
87 |
name=xmlNodeListGetString(doc,attr->children,1);
|
ali@0
|
88 |
if (!xmlStrcmp(name,(const xmlChar *)"artifact_id"))
|
ali@0
|
89 |
id=xmlNodeListGetString(doc,field->children,1);
|
ali@0
|
90 |
if (!xmlStrcmp(name,(const xmlChar *)"artifact_type"))
|
ali@0
|
91 |
type=xmlNodeListGetString(doc,field->children,1);
|
ali@0
|
92 |
}
|
ali@0
|
93 |
if (!xmlStrcmp(name,(const xmlChar *)"artifact_history"))
|
ali@0
|
94 |
for(cur=field->xmlChildrenNode;cur;cur=cur->next)
|
ali@0
|
95 |
if (!xmlStrcmp(cur->name,"history"))
|
ali@0
|
96 |
parse_history(doc,id,type,cur);
|
ali@0
|
97 |
if (name)
|
ali@0
|
98 |
{
|
ali@0
|
99 |
xmlFree(name);
|
ali@0
|
100 |
name=NULL;
|
ali@0
|
101 |
}
|
ali@0
|
102 |
}
|
ali@0
|
103 |
if (id)
|
ali@0
|
104 |
xmlFree(id);
|
ali@0
|
105 |
if (type)
|
ali@0
|
106 |
xmlFree(type);
|
ali@0
|
107 |
}
|
ali@0
|
108 |
|
ali@0
|
109 |
int main(int argc,char **argv)
|
ali@0
|
110 |
{
|
ali@0
|
111 |
xmlDocPtr doc;
|
ali@0
|
112 |
xmlNodePtr cur;
|
ali@0
|
113 |
doc=xmlParseFile(argv[1]);
|
ali@0
|
114 |
if (!doc)
|
ali@0
|
115 |
{
|
ali@0
|
116 |
fprintf(stderr,"Document not parsed successfully.\n");
|
ali@0
|
117 |
exit(1);
|
ali@0
|
118 |
}
|
ali@0
|
119 |
cur=xmlDocGetRootElement(doc);
|
ali@0
|
120 |
if (!cur)
|
ali@0
|
121 |
{
|
ali@0
|
122 |
fprintf(stderr,"Empty document.\n");
|
ali@0
|
123 |
xmlFreeDoc(doc);
|
ali@0
|
124 |
exit(1);
|
ali@0
|
125 |
}
|
ali@0
|
126 |
if (xmlStrcmp(cur->name,(const xmlChar *)"project_export"))
|
ali@0
|
127 |
{
|
ali@0
|
128 |
fprintf(stderr,"%s does not appear to be a project export document.\n",
|
ali@0
|
129 |
argv[1]);
|
ali@0
|
130 |
xmlFreeDoc(doc);
|
ali@0
|
131 |
exit(1);
|
ali@0
|
132 |
}
|
ali@0
|
133 |
for(cur=cur->xmlChildrenNode;cur;cur=cur->next)
|
ali@0
|
134 |
if (!xmlStrcmp(cur->name,(const xmlChar *)"artifacts"))
|
ali@0
|
135 |
break;
|
ali@0
|
136 |
if (!cur)
|
ali@0
|
137 |
{
|
ali@0
|
138 |
fprintf(stderr,"%s does not appear to contain an artifacts node.\n",
|
ali@0
|
139 |
argv[1]);
|
ali@0
|
140 |
xmlFreeDoc(doc);
|
ali@0
|
141 |
exit(1);
|
ali@0
|
142 |
}
|
ali@0
|
143 |
for(cur=cur->xmlChildrenNode;cur;cur=cur->next)
|
ali@0
|
144 |
if (!xmlStrcmp(cur->name,(const xmlChar *)"artifact"))
|
ali@0
|
145 |
parse_artifact(doc,cur);
|
ali@0
|
146 |
xmlFreeDoc(doc);
|
ali@0
|
147 |
exit(0);
|
ali@0
|
148 |
}
|