- 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
This commit is contained in:
David Anderson 2009-12-23 17:18:13 +00:00
parent 3239f120cf
commit 36b04b6279
6 changed files with 81 additions and 21 deletions

View File

@ -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

View File

@ -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("</notices>\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<notices.size(); i++) {
NOTICE& n2 = notices[i];
if (!strcmp(n.guid, n2.guid)) return;
if (!strcmp(n.guid, n2.guid)) return false;
}
if (log_flags.notice_debug) {
msg_printf(0, MSG_INFO,
@ -88,6 +88,7 @@ void NOTICES::append_unique(NOTICE& n) {
);
}
append(n);
return true;
}
static bool cmp(NOTICE n1, NOTICE n2) {
@ -109,6 +110,24 @@ void NOTICES::init() {
}
}
void NOTICES::write_archive(char* url) {
char buf[256], path[256];
escape_project_url(url, buf);
sprintf(path, "feeds/archive_%s", buf);
FILE* f = fopen(path, "w");
MIOFILE fout;
fout.init_file(f);
fout.printf("<notices>\n");
if (!f) return;
for (unsigned int i=0; i<notices.size(); i++) {
NOTICE& n = notices[i];
n.write(fout, false);
}
fout.printf("</notices>\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;

View File

@ -71,8 +71,9 @@ struct NOTICES {
std::deque<NOTICE> 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();

View File

@ -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(
"<notice>\n"
" <seqno>%d</seqno>\n"
" <title>%s</title>\n"
" <description>%s</description>\n"
" <create_time>%f</create_time>\n"
" <arrival_time>%f</arrival_time>\n"
" <is_private>%d</is_private>\n"
" <category>%s</category>\n"
" <url>%s</url>\n"
"</notice>\n",
seqno,
" <url>%s</url>\n",
title,
description.c_str(),
create_time,
@ -62,4 +62,16 @@ void NOTICE::write(MIOFILE& f) {
category,
url
);
if (!for_gui) {
f.printf(
" <guid>%s</guid>\n", guid
);
} else {
f.printf(
" <seqno>%d</seqno>\n", seqno
);
}
f.printf(
"</notice>\n"
);
}

View File

@ -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

View File

@ -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) {