summaryrefslogtreecommitdiff
path: root/sfeed_opml_import.c
diff options
context:
space:
mode:
authorHiltjo Posthuma <hiltjo@codemadness.org>2012-08-03 14:59:22 +0200
committerHiltjo Posthuma <hiltjo@codemadness.org>2012-08-03 14:59:22 +0200
commit50d0bc170c2b7c783e09d81d38a824422712b6e5 (patch)
tree992cc8881872888e649e2e4146455ec447290cfa /sfeed_opml_import.c
parent6df391bcd6dc4cd03349907400d98e6445211f66 (diff)
Rename sfeed_opml_config to sfeed_opml_import
Because I'm adding a sfeed_opml_export script. Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
Diffstat (limited to 'sfeed_opml_import.c')
-rw-r--r--sfeed_opml_import.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/sfeed_opml_import.c b/sfeed_opml_import.c
new file mode 100644
index 0000000..f328fc1
--- /dev/null
+++ b/sfeed_opml_import.c
@@ -0,0 +1,89 @@
+/* convert an opml file to sfeedrc file */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <expat.h> /* libexpat */
+
+XML_Parser parser; /* expat XML parser state */
+
+char * /* search for attr value by attr name in attributes list */
+getattrvalue(const char **atts, const char *name) {
+ const char **attr = NULL, *key, *value;
+ if(!atts || !(*atts))
+ return NULL;
+ for(attr = atts; *attr; ) {
+ key = *(attr++);
+ value = *(attr++);
+ if(key && value && !strcasecmp(key, name))
+ return (char *)value;
+ }
+ return NULL;
+}
+
+void XMLCALL
+xml_handler_start_element(void *data, const char *name, const char **atts) {
+ char *feedurl = NULL, *feedname = NULL, *basesiteurl = NULL;
+
+ if(!strcasecmp(name, "outline")) {
+ if(!(feedname = getattrvalue(atts, "text")) &&
+ !(feedname = getattrvalue(atts, "title")))
+ feedname = "unnamed";
+ if(!(basesiteurl = getattrvalue(atts, "htmlurl")))
+ basesiteurl = "";
+ if(!(feedurl = getattrvalue(atts, "xmlurl")))
+ feedurl = "";
+ printf("\tfeed \"%s\" \"%s\" \"%s\"\n", feedname, feedurl, basesiteurl);
+ }
+}
+
+void XMLCALL
+xml_handler_end_element(void *data, const char *name) {
+}
+
+int /* parse XML from stream using setup parser, return 1 on success, 0 on failure. */
+xml_parse_stream(XML_Parser parser, FILE *fp) {
+ char buffer[BUFSIZ];
+ int done = 0, len = 0;
+
+ while(!feof(fp)) {
+ len = fread(buffer, 1, sizeof(buffer), fp);
+ done = (feof(fp) || ferror(fp));
+ if(XML_Parse(parser, buffer, len, done) == XML_STATUS_ERROR && (len > 0)) {
+ if(XML_GetErrorCode(parser) == XML_ERROR_NO_ELEMENTS)
+ return 1; /* Ignore "no elements found" / empty document as an error */
+ fprintf(stderr, "sfeed_opml_config: error parsing xml %s at line %lu column %lu\n",
+ XML_ErrorString(XML_GetErrorCode(parser)), (unsigned long)XML_GetCurrentLineNumber(parser),
+ (unsigned long)XML_GetCurrentColumnNumber(parser));
+ return 0;
+ }
+ } while(!done);
+ return 1;
+}
+
+int main(void) {
+ int status;
+
+ if(!(parser = XML_ParserCreate("UTF-8"))) {
+ fputs("sfeed_opml_config: can't create parser", stderr);
+ exit(EXIT_FAILURE);
+ }
+ XML_SetElementHandler(parser, xml_handler_start_element, xml_handler_end_element);
+
+ fputs(
+ "# paths\n"
+ "# NOTE: make sure to uncomment all these if you change it.\n"
+ "#sfeedpath=\"$HOME/.sfeed\"\n"
+ "#sfeedfile=\"$sfeedpath/feeds\"\n"
+ "#sfeedfilenew=\"$sfeedfile.new\"\n"
+ "\n"
+ "# list of feeds to fetch:\n"
+ "feeds() {\n"
+ " # feed <name> <url> [encoding]\n", stdout);
+ status = xml_parse_stream(parser, stdin);
+ fputs("}\n", stdout);
+
+ XML_ParserFree(parser);
+
+ return status ? EXIT_SUCCESS : EXIT_FAILURE;
+}