[pan2] * hotfixes for xfeature * patch for 'match only read' (Cal Peake)
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2] * hotfixes for xfeature * patch for 'match only read' (Cal Peake)
- Date: Tue, 8 Jan 2013 20:41:48 +0000 (UTC)
commit 49220459edc5430a58e929277cce9c29d19cab11
Author: Heinrich MÃller <henmull src gnome org>
Date: Tue Jan 8 20:38:54 2013 +0100
* hotfixes for xfeature
* patch for 'match only read' (Cal Peake)
pan/data-impl/article-filter.cc | 4 +
pan/general/compression.h | 2 +-
pan/gui/actions.cc | 19 +++-
pan/gui/gui.cc | 1 +
pan/gui/gui.h | 1 +
pan/gui/header-pane.cc | 6 +
pan/gui/pan-ui.h | 1 +
pan/gui/pan.ui.h | 2 +
pan/gui/pan.ui.ssl.h | 2 +
pan/icons/Makefile.am | 1 +
pan/tasks/nntp.cc | 284 +++++++++++++++++++-------------------
pan/tasks/socket-impl-gio.cc | 4 +-
pan/tasks/socket-impl-openssl.cc | 4 +-
pan/tasks/task-groups.cc | 20 ++-
pan/tasks/task-groups.h | 2 +
pan/tasks/task-xover.cc | 27 ++--
pan/usenet-utils/filter-info.cc | 7 +-
pan/usenet-utils/filter-info.h | 2 +
18 files changed, 222 insertions(+), 167 deletions(-)
---
diff --git a/pan/data-impl/article-filter.cc b/pan/data-impl/article-filter.cc
index 9a25dbb..effdf69 100644
--- a/pan/data-impl/article-filter.cc
+++ b/pan/data-impl/article-filter.cc
@@ -96,6 +96,10 @@ ArticleFilter :: test_article (const Data & data,
pass = data.has_from_header (article.author.to_view());
break;
+ case FilterInfo::IS_READ:
+ pass = data.is_read (&article);
+ break;
+
case FilterInfo::IS_UNREAD:
pass = !data.is_read (&article);
break;
diff --git a/pan/general/compression.h b/pan/general/compression.h
index b4bc715..defa2f2 100644
--- a/pan/general/compression.h
+++ b/pan/general/compression.h
@@ -48,7 +48,7 @@ namespace pan
void ydecode(std::stringstream* in, std::stringstream* out);
- void deflate_gzip (const StringView& line, std::vector<std::string>& fillme);
+ void inflate_gzip (std::stringstream* stream, std::vector<std::string>& fillme);
}
}
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index 0088820..dd8f7ad 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -61,6 +61,7 @@ namespace pan
{ icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" },
{ icon_filter_only_cached, "ICON_ONLY_CACHED" },
{ icon_filter_only_me, "ICON_ONLY_ME" },
+ { icon_filter_only_read, "ICON_ONLY_READ" },
{ icon_filter_only_unread, "ICON_ONLY_UNREAD" },
{ icon_filter_only_watched, "ICON_ONLY_WATCHED" },
{ icon_get_dialog, "ICON_GET_DIALOG" },
@@ -283,7 +284,22 @@ namespace pan
void do_match_only_cached_articles (GtkToggleAction * a) { pan_ui->do_match_only_cached_articles (gtk_toggle_action_get_active(a)); }
void do_match_only_binary_articles (GtkToggleAction * a) { pan_ui->do_match_only_binary_articles (gtk_toggle_action_get_active(a)); }
void do_match_only_my_articles (GtkToggleAction * a) { pan_ui->do_match_only_my_articles (gtk_toggle_action_get_active(a)); }
- void do_match_only_unread_articles (GtkToggleAction * a) { pan_ui->do_match_only_unread_articles (gtk_toggle_action_get_active(a)); }
+ void do_match_only_unread_articles (GtkToggleAction * a)
+ {
+ const bool active (gtk_toggle_action_get_active(a));
+ toggle_action_set_active("match-only-unread-articles", active);
+ if (active)
+ toggle_action_set_active("match-only-read-articles", !active);
+ pan_ui->do_match_only_unread_articles(true);
+ }
+ void do_match_only_read_articles (GtkToggleAction * a)
+ {
+ const bool active (gtk_toggle_action_get_active(a));
+ toggle_action_set_active("match-only-read-articles", active);
+ if (active)
+ toggle_action_set_active("match-only-unread-articles", !active);
+ pan_ui->do_match_only_read_articles(true);
+ }
GtkActionEntry entries[] =
{
@@ -725,6 +741,7 @@ namespace pan
{ "show-toolbar", NULL, N_("Show _Toolbar"), NULL, NULL, G_CALLBACK(do_show_toolbar), true },
{ "shorten-group-names", GTK_STOCK_ZOOM_OUT, N_("Abbreviate Group Names"), "B", NULL, G_CALLBACK(do_shorten_group_names), false },
+ { "match-only-read-articles", "ICON_ONLY_READ", N_("Match Only _Read Articles"), NULL, N_("Match Only Read Articles"), G_CALLBACK(do_match_only_read_articles), false },
{ "match-only-unread-articles", "ICON_ONLY_UNREAD", N_("Match Only _Unread Articles"), NULL, N_("Match Only Unread Articles"), G_CALLBACK(do_match_only_unread_articles), false },
{ "match-only-cached-articles", "ICON_ONLY_CACHED", N_("Match Only _Cached Articles"), NULL, N_("Match Only Cached Articles"), G_CALLBACK(do_match_only_cached_articles), false },
{ "match-only-binary-articles", "ICON_ONLY_ATTACHMENTS", N_("Match Only _Complete Articles"), NULL, N_("Match Only Complete Articles"), G_CALLBACK(do_match_only_binary_articles), false },
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 8d4cd61..9c87c0a 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -1867,6 +1867,7 @@ void GUI :: do_shorten_group_names (bool b)
_group_pane->set_name_collapse (b);
}
+void GUI :: do_match_only_read_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_only_unread_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_only_cached_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_only_binary_articles (bool) { _header_pane->refilter (); }
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 1d44935..e67fd07 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -183,6 +183,7 @@ namespace pan
virtual void do_match_only_binary_articles (bool);
virtual void do_match_only_my_articles (bool);
virtual void do_match_only_unread_articles (bool);
+ virtual void do_match_only_read_articles (bool);
virtual void do_enable_toggle_rules (bool enable);
virtual void do_match_on_score_state (int);
virtual void do_show_matches (const Data::ShowType);
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 7b571fc..46bf9c4 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -1418,6 +1418,12 @@ HeaderPane :: rebuild_filter (const std::string& text, int mode)
f._aggregates.push_back (entry_filter);
}
+ if (_action_manager.is_action_active("match-only-read-articles")) {
+//std::cerr << LINE_ID << " AND is read" << std::endl;
+ FilterInfo tmp;
+ tmp.set_type_is_read ();
+ f._aggregates.push_back (tmp);
+ }
if (_action_manager.is_action_active("match-only-unread-articles")) {
//std::cerr << LINE_ID << " AND is unread" << std::endl;
FilterInfo tmp;
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index e9eca00..765c45e 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -123,6 +123,7 @@ namespace pan
virtual void do_show_toolbar (bool) = 0;
virtual void do_shorten_group_names (bool) = 0;
+ virtual void do_match_only_read_articles (bool) = 0;
virtual void do_match_only_unread_articles (bool) = 0;
virtual void do_match_only_cached_articles (bool) = 0;
virtual void do_match_only_binary_articles (bool) = 0;
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index a24fd70..57a5efd 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -51,6 +51,7 @@ const char * fallback_ui_file =
" <menuitem action='show-matching-subthreads' />\n"
" <separator />\n"
" <menuitem action='match-only-unread-articles' />\n"
+" <menuitem action='match-only-read-articles' />\n"
" <menuitem action='match-only-cached-articles' />\n"
" <menuitem action='match-only-binary-articles' />\n"
" <menuitem action='match-only-my-articles' />\n"
@@ -179,6 +180,7 @@ const char * fallback_ui_file =
" <placeholder name='header-pane-filter' />\n"
" <separator />\n"
" <toolitem action='match-only-unread-articles' />\n"
+" <toolitem action='match-only-read-articles' />\n"
" <toolitem action='match-only-cached-articles' />\n"
" <toolitem action='match-only-binary-articles' />\n"
" <toolitem action='match-only-my-articles' />\n"
diff --git a/pan/gui/pan.ui.ssl.h b/pan/gui/pan.ui.ssl.h
index ce1e573..e90c406 100644
--- a/pan/gui/pan.ui.ssl.h
+++ b/pan/gui/pan.ui.ssl.h
@@ -50,6 +50,7 @@ const char * fallback_ui_file =
" <menuitem action='show-matching-subthreads' />\n"
" <separator />\n"
" <menuitem action='match-only-unread-articles' />\n"
+" <menuitem action='match-only-read-articles' />\n"
" <menuitem action='match-only-cached-articles' />\n"
" <menuitem action='match-only-binary-articles' />\n"
" <menuitem action='match-only-my-articles' />\n"
@@ -178,6 +179,7 @@ const char * fallback_ui_file =
" <placeholder name='header-pane-filter' />\n"
" <separator />\n"
" <toolitem action='match-only-unread-articles' />\n"
+" <toolitem action='match-only-read-articles' />\n"
" <toolitem action='match-only-cached-articles' />\n"
" <toolitem action='match-only-binary-articles' />\n"
" <toolitem action='match-only-my-articles' />\n"
diff --git a/pan/icons/Makefile.am b/pan/icons/Makefile.am
index 1209d7e..7804d3c 100644
--- a/pan/icons/Makefile.am
+++ b/pan/icons/Makefile.am
@@ -18,6 +18,7 @@ stock_images = \
icon_filter_only_attachments.png \
icon_filter_only_cached.png \
icon_filter_only_me.png \
+ icon_filter_only_read.png \
icon_filter_only_unread.png \
icon_filter_only_watched.png \
icon_get_dialog.png \
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index 92e2834..0d52cc5 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -76,34 +76,20 @@ NNTP :: on_socket_response (Socket * sock UNUSED, const StringView& line_in)
enum State { CMD_FAIL, CMD_DONE, CMD_MORE, CMD_NEXT, CMD_RETRY };
State state;
StringView line (line_in);
-
- //check for compression
- _compression = strcasestr (line.str, COMPRESS_GZIP);
+ std::string old_line = line;
// strip off trailing \r\n
if (line.len>=2 && line.str[line.len-2]=='\r' && line.str[line.len-1]=='\n')
line.truncate (line.len-2);
-// std::cerr <<"_nntp_response_text: " << _nntp_response_text<<std::endl;
- if (_compression)
- {
- //check if we're done
- if (strcasestr (line_in.str, ".\r\n") != 0)
- {
- if (_listener)
- _listener->on_nntp_line (this, line);
- line = ".";
- state = CMD_DONE;
- }
- }
- else if (_nntp_response_text)
+ if (_nntp_response_text)
{
if (line.len==1 && line.str[0]=='.') // end-of-list
{
state = CMD_DONE;
_nntp_response_text = false;
}
- else
+ else if (!_compression)
{
state = CMD_MORE;
@@ -114,144 +100,164 @@ NNTP :: on_socket_response (Socket * sock UNUSED, const StringView& line_in)
if (_listener)
_listener->on_nntp_line (this, line);
}
+
+ if (_compression)
+ {
+ state = CMD_MORE;
+ assert (_listener != 0);
+ if (_listener)
+ _listener->on_nntp_line (this, line_in);
+ if (line_in.len >= 3 && line_in.strstr(".\r\n"))
+ {
+ _compression = false;
+ _nntp_response_text = false;
+ line = ".";
+ }
+ }
}
- else switch (atoi (line.str))
+ else
{
- case SERVER_READY:
- case SERVER_READY_NO_POSTING:
- case SERVER_READY_STREAMING_OK:
- state = CMD_DONE;
- break;
+ //check for compression
+ _compression = strcasestr (line_in.str, COMPRESS_GZIP);
+
+ switch (atoi (line.str))
+ {
+ case SERVER_READY:
+ case SERVER_READY_NO_POSTING:
+ case SERVER_READY_STREAMING_OK:
+ state = CMD_DONE;
+ break;
+
+ case ARTICLE_POSTED_OK:
+ case GOODBYE:
+ case XOVER_NO_ARTICLES:
+ state = CMD_DONE;
+ break;
+
+ case AUTH_REQUIRED: { // must send username
+ if (!_username.empty()) {
+ _commands.push_front (_previous_command);
+ _socket->write_command_va (this, "AUTHINFO USER %s\r\n", _username.c_str());
+ state = CMD_NEXT;
+ } else {
+ std::string host;
+ _socket->get_host (host);
+ Log::add_err_va (_("%s requires a username, but none is set."), host.c_str());
+ state = CMD_FAIL;
+ }
+ break;
+ }
- case ARTICLE_POSTED_OK:
- case GOODBYE:
- case XOVER_NO_ARTICLES:
- state = CMD_DONE;
- break;
+ case AUTH_NEED_MORE: { // must send password
+ if (!_password.empty()) {
+ _socket->write_command_va (this, "AUTHINFO PASS %s\r\n", _password.c_str());
+ state = CMD_NEXT;
+ } else {
+ std::string host;
+ _socket->get_host (host);
+ Log::add_err_va (_("%s requires a password, but none is set."), host.c_str());
+ state = CMD_FAIL;
+ }
+ break;
+ }
- case AUTH_REQUIRED: { // must send username
- if (!_username.empty()) {
- _commands.push_front (_previous_command);
- _socket->write_command_va (this, "AUTHINFO USER %s\r\n", _username.c_str());
+ case AUTH_ACCEPTED:
+ // try to enable compression xfeature
+ _socket->write_command (ENABLE_COMPRESS_GZIP, this);
state = CMD_NEXT;
- } else {
- std::string host;
- _socket->get_host (host);
- Log::add_err_va (_("%s requires a username, but none is set."), host.c_str());
- state = CMD_FAIL;
- }
- break;
- }
+ break;
+
+ case FEATURE_ENABLED:
+ state= CMD_DONE;
+ break;
+
+ case GROUP_RESPONSE: {
+ // response is of form "211 qty low high group_name"
+ StringView tok, myline (line);
+ myline.pop_token (tok, ' ');
+ myline.pop_token (tok, ' ');
+ const unsigned long aqty (strtoul (tok.str, NULL, 10));
+ myline.pop_token (tok, ' ');
+ const unsigned long alo (strtoul (tok.str, NULL, 10));
+ myline.pop_token (tok, ' ');
+ const unsigned long ahi (strtoul (tok.str, NULL, 10));
+ myline.pop_token (tok, ' ');
+ const pan::Quark group (tok);
+ if (_listener)
+ _listener->on_nntp_group (this, group, aqty, alo, ahi);
+ _group = group;
+ state = CMD_DONE;
+ break;
+ }
- case AUTH_NEED_MORE: { // must send password
- if (!_password.empty()) {
- _socket->write_command_va (this, "AUTHINFO PASS %s\r\n", _password.c_str());
+ case SEND_ARTICLE_NOW:
+ // ready to get article; send it now
+ _socket->write_command (_post, this);
state = CMD_NEXT;
- } else {
+ break;
+
+ case NO_POSTING:
+ case POSTING_FAILED:
+ // if we hit a dupe, we silently continue
+ if (line.strstr("435"))
+ {
+ state = CMD_DONE;
+ break;
+ }
+ case GROUP_NONEXISTENT:
+ state = CMD_FAIL;
+ break;
+
+ case XOVER_FOLLOWS:
+ case ARTICLE_FOLLOWS:
+ case NEWGROUPS_FOLLOWS:
+ case INFORMATION_FOLLOWS:
+ state = CMD_MORE;
+ _nntp_response_text = true;
+ break;
+
+ case AUTH_REJECTED:
+ case NO_GROUP_SELECTED:
+ case ERROR_CMD_NOT_UNDERSTOOD:
+ case ERROR_CMD_NOT_SUPPORTED:
+ case NO_PERMISSION:
+ case FEATURE_NOT_SUPPORTED: {
+ std::string cmd (_previous_command);
+ if (cmd.size()>=2 && cmd[cmd.size()-1]=='\n' && cmd[cmd.size()-2]=='\r')
+ cmd.resize (cmd.size()-2);
std::string host;
_socket->get_host (host);
- Log::add_err_va (_("%s requires a password, but none is set."), host.c_str());
+ Log::add_err_va (_("Sending \"%s\" to %s returned an error: %s"),
+ cmd.c_str(),
+ host.c_str(),
+ line.to_string().c_str());
state = CMD_FAIL;
+ break;
}
- break;
- }
- case AUTH_ACCEPTED:
- // try to enable compression xfeature
- _socket->write_command (ENABLE_COMPRESS_GZIP, this);
- state = CMD_NEXT;
- break;
-
- case FEATURE_ENABLED:
- state= CMD_DONE;
- break;
-
- case GROUP_RESPONSE: {
- // response is of form "211 qty low high group_name"
- StringView tok, myline (line);
- myline.pop_token (tok, ' ');
- myline.pop_token (tok, ' ');
- const unsigned long aqty (strtoul (tok.str, NULL, 10));
- myline.pop_token (tok, ' ');
- const unsigned long alo (strtoul (tok.str, NULL, 10));
- myline.pop_token (tok, ' ');
- const unsigned long ahi (strtoul (tok.str, NULL, 10));
- myline.pop_token (tok, ' ');
- const pan::Quark group (tok);
- if (_listener)
- _listener->on_nntp_group (this, group, aqty, alo, ahi);
- _group = group;
- state = CMD_DONE;
- break;
- }
+ case NO_SUCH_ARTICLE_NUMBER:
+ case NO_SUCH_ARTICLE:
+ state = CMD_FAIL;
+ break;
- case SEND_ARTICLE_NOW:
- // ready to get article; send it now
- _socket->write_command (_post, this);
- state = CMD_NEXT;
- break;
+ case TOO_MANY_CONNECTIONS:
+ state = CMD_RETRY;
+ break;
- case NO_POSTING:
- case POSTING_FAILED:
- // if we hit a dupe, we silently continue
- if (line.strstr("435"))
- {
- state = CMD_DONE;
- break;
+ default: {
+ std::string cmd (_previous_command);
+ if (cmd.size()>=2 && cmd[cmd.size()-1]=='\n' && cmd[cmd.size()-2]=='\r')
+ cmd.resize (cmd.size()-2);
+ std::string host;
+ _socket->get_host (host);
+ Log::add_err_va (_("Sending \"%s\" to %s returned an unrecognized response: \"%s\""),
+ _previous_command.c_str(),
+ host.c_str(),
+ line.to_string().c_str());
+ state = CMD_FAIL;
+ break;
}
- case GROUP_NONEXISTENT:
- state = CMD_FAIL;
- break;
-
- case XOVER_FOLLOWS:
- case ARTICLE_FOLLOWS:
- case NEWGROUPS_FOLLOWS:
- case INFORMATION_FOLLOWS:
- state = CMD_MORE;
- _nntp_response_text = true;
- break;
-
- case AUTH_REJECTED:
- case NO_GROUP_SELECTED:
- case ERROR_CMD_NOT_UNDERSTOOD:
- case ERROR_CMD_NOT_SUPPORTED:
- case NO_PERMISSION:
- case FEATURE_NOT_SUPPORTED: {
- std::string cmd (_previous_command);
- if (cmd.size()>=2 && cmd[cmd.size()-1]=='\n' && cmd[cmd.size()-2]=='\r')
- cmd.resize (cmd.size()-2);
- std::string host;
- _socket->get_host (host);
- Log::add_err_va (_("Sending \"%s\" to %s returned an error: %s"),
- cmd.c_str(),
- host.c_str(),
- line.to_string().c_str());
- state = CMD_FAIL;
- break;
- }
-
- case NO_SUCH_ARTICLE_NUMBER:
- case NO_SUCH_ARTICLE:
- state = CMD_FAIL;
- break;
-
- case TOO_MANY_CONNECTIONS:
- state = CMD_RETRY;
- break;
-
- default: {
- std::string cmd (_previous_command);
- if (cmd.size()>=2 && cmd[cmd.size()-1]=='\n' && cmd[cmd.size()-2]=='\r')
- cmd.resize (cmd.size()-2);
- std::string host;
- _socket->get_host (host);
- Log::add_err_va (_("Sending \"%s\" to %s returned an unrecognized response: \"%s\""),
- _previous_command.c_str(),
- host.c_str(),
- line.to_string().c_str());
- state = CMD_FAIL;
- break;
- }
+ }
}
if ((state == CMD_DONE) && !_commands.empty())
diff --git a/pan/tasks/socket-impl-gio.cc b/pan/tasks/socket-impl-gio.cc
index b81c0cb..252d590 100644
--- a/pan/tasks/socket-impl-gio.cc
+++ b/pan/tasks/socket-impl-gio.cc
@@ -338,8 +338,8 @@ GIOChannelSocket :: do_read ()
debug_v ("read [" << g->str << "]"); // verbose debug, if --debug --debug was on the command-line
increment_xfer_byte_count (g->len);
- if (g_str_has_suffix (g->str, "\r\n"))
- g_string_truncate (g, g->len-2);
+ //if (g_str_has_suffix (g->str, "\r\n"))
+ // g_string_truncate (g, g->len-2);
more = _listener->on_socket_response (this, StringView (g->str, g->len));
_listener->on_socket_bytes_transferred(g->len, this);
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index 229788e..2b33479 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -623,8 +623,8 @@ GIOChannelSocketGnuTLS :: do_read ()
debug_v ("read [" << g->str << "]");
increment_xfer_byte_count (g->len);
- if (g_str_has_suffix (g->str, "\r\n"))
- g_string_truncate (g, g->len-2);
+ //if (g_str_has_suffix (g->str, "\r\n"))
+ // g_string_truncate (g, g->len-2);
more = _listener->on_socket_response (this, StringView (g->str, g->len));
//_listener->on_socket_bytes_transferred(g->len, this);
}
diff --git a/pan/tasks/task-groups.cc b/pan/tasks/task-groups.cc
index d8fae9a..271c082 100644
--- a/pan/tasks/task-groups.cc
+++ b/pan/tasks/task-groups.cc
@@ -21,6 +21,7 @@
#include <cassert>
extern "C" {
#include <glib/gi18n.h>
+ #include <stdlib.h>
}
#include <pan/general/debug.h>
#include <pan/general/macros.h>
@@ -74,18 +75,12 @@ TaskGroups :: use_nntp (NNTP * nntp)
assert (0);
}
-
void
TaskGroups :: on_nntp_line (NNTP * nntp,
const StringView & line)
{
if (nntp->_compression)
- {
- std::vector<std::string> lines;
- compression::deflate_gzip (line, lines);
- foreach (std::vector<std::string>, lines, it)
- on_nntp_line_process (nntp, *it);
- }
+ stream << line;
else on_nntp_line_process (nntp, line);
}
void
@@ -143,7 +138,7 @@ TaskGroups :: on_nntp_line_process (NNTP * nntp UNUSED,
void
TaskGroups :: on_nntp_done (NNTP * nntp,
Health health,
- const StringView & response UNUSED)
+ const StringView & response)
{
debug ("groups task got an on_nntp_done() from " << nntp->_server);
@@ -153,6 +148,15 @@ TaskGroups :: on_nntp_done (NNTP * nntp,
}
else // health is OK or FAIL
{
+ if (response == ".")
+ {
+ std::vector<std::string> lines;
+ compression::inflate_gzip (&stream, lines);
+ foreach (std::vector<std::string>, lines, it)
+ on_nntp_line_process (nntp, *it);
+ stream.str().clear();
+ }
+
if (_step == LIST_NEWSGROUPS)
{
int i (0);
diff --git a/pan/tasks/task-groups.h b/pan/tasks/task-groups.h
index 4a27c78..b7886eb 100644
--- a/pan/tasks/task-groups.h
+++ b/pan/tasks/task-groups.h
@@ -60,6 +60,8 @@ namespace pan
enum Step { LIST, LIST_NEWSGROUPS, DONE };
Step _step;
+
+ std::stringstream stream;
};
};
diff --git a/pan/tasks/task-xover.cc b/pan/tasks/task-xover.cc
index 0dd37a4..912fa3b 100644
--- a/pan/tasks/task-xover.cc
+++ b/pan/tasks/task-xover.cc
@@ -172,9 +172,7 @@ TaskXOver::use_nntp(NNTP* nntp)
case MiniTask::XOVER:
debug("XOVER " << mt._low << '-' << mt._high << " to " << server);
_last_xover_number[nntp] = mt._low;
- if (comp == HEADER_COMPRESS_XFEATURE)
- nntp->xfeat(_group, mt._low, mt._high, this);
- else if (comp == HEADER_COMPRESS_XZVER || comp == HEADER_COMPRESS_DIABLO)
+ if (comp == HEADER_COMPRESS_XZVER || comp == HEADER_COMPRESS_DIABLO)
nntp->xzver(_group, mt._low, mt._high, this);
else
nntp->xover(_group, mt._low, mt._high, this);
@@ -318,17 +316,14 @@ TaskXOver::on_nntp_line(NNTP * nntp, const StringView & line)
_data.get_server_compression_type(server, comp);
if (comp != HEADER_COMPRESS_NONE)
- {
- int sock_id = nntp->_socket->get_id();
- if (_streams.count(sock_id) == 0)
- _streams[sock_id] = new std::stringstream();
- *_streams[sock_id] << line << "\r\n";
- }
+ {
+ int sock_id = nntp->_socket->get_id();
+ if (_streams.count(sock_id) == 0)
+ _streams[sock_id] = new std::stringstream();
+ *_streams[sock_id] << line << "\r\n";
+ }
else
- {
- on_nntp_line_process(nntp, line);
- }
-
+ on_nntp_line_process(nntp, line);
}
void
@@ -464,8 +459,14 @@ TaskXOver::on_nntp_done(NNTP * nntp, Health health, const StringView & response)
{
std::stringstream* buffer = _streams[nntp->_socket->get_id()];
std::stringstream out, out2;
+ if (comp == HEADER_COMPRESS_XZVER || comp == HEADER_COMPRESS_DIABLO)
+ {
compression::ydecode(buffer, &out);
compression::inflate_zlib(&out, &out2, comp);
+ }
+ else
+ compression::inflate_zlib(buffer, &out2, comp);
+
char buf1[4096];
while (!out2.getline(buf1, sizeof(buf1)).eof())
{
diff --git a/pan/usenet-utils/filter-info.cc b/pan/usenet-utils/filter-info.cc
index f83b939..21e525c 100644
--- a/pan/usenet-utils/filter-info.cc
+++ b/pan/usenet-utils/filter-info.cc
@@ -142,6 +142,11 @@ FilterInfo :: set_type_score_le (unsigned long le)
set_type_le (SCORE_GE, le);
}
void
+FilterInfo :: set_type_is_read ()
+{
+ set_type_is (IS_READ);
+}
+void
FilterInfo :: set_type_is_unread ()
{
set_type_is (IS_UNREAD);
@@ -182,7 +187,7 @@ FilterInfo :: describe () const
{
ret = _("the article was posted by you");
}
- else if (_type==IS_UNREAD && _negate)
+ else if (_type==IS_READ)
{
ret = _("the article has been read");
}
diff --git a/pan/usenet-utils/filter-info.h b/pan/usenet-utils/filter-info.h
index 408b6ae..32e3967 100644
--- a/pan/usenet-utils/filter-info.h
+++ b/pan/usenet-utils/filter-info.h
@@ -43,6 +43,7 @@ namespace pan
IS_BINARY,
IS_CACHED,
IS_POSTED_BY_ME,
+ IS_READ,
IS_UNREAD,
BYTE_COUNT_GE,
CROSSPOST_COUNT_GE,
@@ -103,6 +104,7 @@ namespace pan
void set_type_line_count_ge (unsigned long ge);
void set_type_score_ge (unsigned long ge);
void set_type_score_le (unsigned long le);
+ void set_type_is_read ();
void set_type_is_unread ();
void set_type_posted_by_me ();
void set_type_text (const Quark& header,const TextMatch::Description&);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]