mirror of https://github.com/BOINC/boinc.git
- 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:
parent
3239f120cf
commit
36b04b6279
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue