From 36b04b62791f2132c7c95cdf55dafbd6e8cc6eb3 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 23 Dec 2009 17:18:13 +0000 Subject: [PATCH] - client: further work on notices. The RSS feed part of it is mostly working. - client: fix bug in XML_PARSER (tags with attributes weren't parsed correctly if no attribute buffer supplied) svn path=/trunk/boinc/; revision=20026 --- checkin_notes | 12 +++++++++++ client/cs_notice.cpp | 51 ++++++++++++++++++++++++++++++++++++-------- client/cs_notice.h | 5 +++-- lib/notice.cpp | 24 +++++++++++++++------ lib/notice.h | 2 +- lib/parse.cpp | 8 ++++--- 6 files changed, 81 insertions(+), 21 deletions(-) diff --git a/checkin_notes b/checkin_notes index 9aa71189c1..3add06d4ac 100644 --- a/checkin_notes +++ b/checkin_notes @@ -10670,3 +10670,15 @@ Charlie 23 Dec 2009 clientgui/ DlgEventLog.cpp + +David 23 Dec 2009 + - client: further work on notices. + The RSS feed part of it is mostly working. + - client: fix bug in XML_PARSER (tags with attributes weren't + parsed correctly if no attribute buffer supplied) + + client/ + cs_notice.cpp,h + lib/ + notice.cpp,h + parse.cpp diff --git a/client/cs_notice.cpp b/client/cs_notice.cpp index 7f26ee5a89..1784b651c9 100644 --- a/client/cs_notice.cpp +++ b/client/cs_notice.cpp @@ -62,7 +62,7 @@ void NOTICES::write(int seqno, MIOFILE& fout, bool public_only) { NOTICE& n = notices[i]; if (n.seqno <= seqno) break; if (public_only && n.is_private) continue; - n.write(fout); + n.write(fout, true); } fout.printf("\n"); } @@ -76,10 +76,10 @@ void NOTICES::append(NOTICE& n) { notices.push_front(n); } -void NOTICES::append_unique(NOTICE& n) { +bool NOTICES::append_unique(NOTICE& n) { for (unsigned int i=0; i\n"); + if (!f) return; + for (unsigned int i=0; i\n"); + fclose(f); +} + // called on startup. Get list of feeds. Read archives. // void RSS_FEEDS::init() { @@ -239,7 +258,7 @@ int RSS_FEED::read_archive_file() { char tag[256]; bool is_tag; - feed_file_name(path); + archive_file_name(path); FILE* f = fopen(path, "r"); if (!f) { if (log_flags.notice_debug) { @@ -328,22 +347,30 @@ void RSS_FEED::write(MIOFILE& fout) { ); } -// parse the actual RSS feed +// parse the actual RSS feed. +// Return true if got any new ones. // -int RSS_FEED::parse_items(XML_PARSER& xp) { +int RSS_FEED::parse_items(XML_PARSER& xp, int& nitems) { char tag[256]; bool is_tag; + nitems = 0; while (!xp.get(tag, sizeof(tag), is_tag)) { if (!is_tag) continue; - if (!strcmp(tag, "/rss")) return 0; + if (!strcmp(tag, "/rss")) { + return 0; + } if (!strcmp(tag, "item")) { NOTICE n; int retval = n.parse_rss(xp); if (!retval) { + n.arrival_time = gstate.now; if (append_seqno) { notices.append(n); + nitems++; } else { - notices.append_unique(n); + if (notices.append_unique(n)) { + nitems++; + } } } continue; @@ -384,6 +411,7 @@ bool RSS_FEED_OP::poll() { // void RSS_FEED_OP::handle_reply(int http_op_retval) { char filename[256]; + int nitems; if (http_op_retval) { if (log_flags.notice_debug) { @@ -405,7 +433,7 @@ void RSS_FEED_OP::handle_reply(int http_op_retval) { MIOFILE fin; fin.init_file(f); XML_PARSER xp(&fin); - int retval = rfp->parse_items(xp); + int retval = rfp->parse_items(xp, nitems); if (retval) { if (log_flags.notice_debug) { msg_printf(0, MSG_INFO, @@ -414,6 +442,10 @@ void RSS_FEED_OP::handle_reply(int http_op_retval) { } } fclose(f); + + if (nitems) { + notices.write_archive(rfp->url); + } } // parse feed descs from scheduler reply or feed list file @@ -555,6 +587,7 @@ int NOTICE::parse_rss(XML_PARSER& xp) { char tag[1024], buf[256]; bool is_tag; + memset(this, 0, sizeof(*this)); while (!xp.get(tag, sizeof(tag), is_tag)) { if (!is_tag) continue; if (!strcmp(tag, "/item")) return 0; diff --git a/client/cs_notice.h b/client/cs_notice.h index 838f89e1cf..d470d7e574 100644 --- a/client/cs_notice.h +++ b/client/cs_notice.h @@ -71,8 +71,9 @@ struct NOTICES { std::deque notices; void write(int seqno, MIOFILE&, bool public_only); void append(NOTICE&); - void append_unique(NOTICE&); + bool append_unique(NOTICE&); void init(); + void write_archive(char* url); }; extern NOTICES notices; @@ -93,7 +94,7 @@ struct RSS_FEED { void write(MIOFILE&); int parse_desc(XML_PARSER&); - int parse_items(XML_PARSER&); + int parse_items(XML_PARSER&, int&); void feed_file_name(char*); void archive_file_name(char*); int read_archive_file(); diff --git a/lib/notice.cpp b/lib/notice.cpp index 0e0cdb20da..c94bacf5cc 100644 --- a/lib/notice.cpp +++ b/lib/notice.cpp @@ -26,9 +26,12 @@ int NOTICE::parse(XML_PARSER& xp) { char tag[1024]; bool is_tag; + memset(this, 0, sizeof(*this)); while (!xp.get(tag, sizeof(tag), is_tag)) { if (!is_tag) continue; - if (!strcmp(tag, "/notice")) return 0; + if (!strcmp(tag, "/notice")) { + return 0; + } if (xp.parse_int(tag, "seqno", seqno)) continue; if (xp.parse_str(tag, "title", title, sizeof(title))) continue; if (xp.parse_string(tag, "description", description)) continue; @@ -41,19 +44,16 @@ int NOTICE::parse(XML_PARSER& xp) { return ERR_XML_PARSE; } -void NOTICE::write(MIOFILE& f) { +void NOTICE::write(MIOFILE& f, bool for_gui) { f.printf( "\n" - " %d\n" " %s\n" " %s\n" " %f\n" " %f\n" " %d\n" " %s\n" - " %s\n" - "\n", - seqno, + " %s\n", title, description.c_str(), create_time, @@ -62,4 +62,16 @@ void NOTICE::write(MIOFILE& f) { category, url ); + if (!for_gui) { + f.printf( + " %s\n", guid + ); + } else { + f.printf( + " %d\n", seqno + ); + } + f.printf( + "\n" + ); } diff --git a/lib/notice.h b/lib/notice.h index 59c34de88a..e7fe08f5c2 100644 --- a/lib/notice.h +++ b/lib/notice.h @@ -39,7 +39,7 @@ struct NOTICE { int parse(XML_PARSER&); int parse_rss(XML_PARSER&); - void write(MIOFILE&); + void write(MIOFILE&, bool for_gui); }; #endif diff --git a/lib/parse.cpp b/lib/parse.cpp index 9544215113..db7d8859dd 100644 --- a/lib/parse.cpp +++ b/lib/parse.cpp @@ -518,9 +518,11 @@ int XML_PARSER::scan_tag( *tag_buf++ = c; } } else { - if (found_space && attr_buf) { - if (--attr_len > 0) { - *attr_buf++ = c; + if (found_space) { + if (attr_buf) { + if (--attr_len > 0) { + *attr_buf++ = c; + } } } else { if (--tag_len > 0) {