[pan2/testing: 40/279] xzver and basic uploading support, experimental, non-functional at point of commit.
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 40/279] xzver and basic uploading support, experimental, non-functional at point of commit.
- Date: Sat, 3 Dec 2011 22:27:54 +0000 (UTC)
commit b95cdea376d23797834b43a454bf71074a14743c
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Wed May 25 06:40:34 2011 +0200
xzver and basic uploading support, experimental, non-functional at point
of commit.
pan/data-impl/data-impl.h | 17 ++++--
pan/data-impl/server.cc | 42 +++++++++++--
pan/data/article.h | 4 +-
pan/data/data.h | 18 ++++--
pan/data/parts.cc | 2 +-
pan/data/server-info.h | 6 ++
pan/general/file-util.cc | 6 ++-
pan/general/file-util.h | 6 +-
pan/general/progress.cc | 4 +-
pan/general/string-view.h | 6 +-
pan/general/worker-pool.cc | 1 -
pan/gui/dl-headers-ui.cc | 4 +-
pan/gui/gui.cc | 3 +
pan/gui/header-pane.cc | 12 ++--
pan/gui/pan.cc | 18 +++++-
pan/gui/post-ui.cc | 71 +++++++++-------------
pan/gui/post-ui.h | 4 +-
pan/gui/prefs.h | 4 +-
pan/gui/server-ui.cc | 23 +++++++-
pan/gui/task-pane.cc | 7 +-
pan/tasks/Makefile.am | 2 +
pan/tasks/decoder.cc | 14 +++--
pan/tasks/nntp.cc | 51 ++---------------
pan/tasks/nntp.h | 52 +++++++++++++++++
pan/tasks/queue.cc | 13 ++++-
pan/tasks/task-article.cc | 4 +-
pan/tasks/task-post.cc | 1 -
pan/tasks/task-weak-ordering.h | 7 +-
pan/tasks/task-xover.cc | 125 ++++++++++++++++++++++++++++++++++------
pan/tasks/task-xover.h | 12 ++++
30 files changed, 364 insertions(+), 175 deletions(-)
---
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index cc0855b..f794737 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -51,7 +51,7 @@ namespace pan
*
* Most of the files are stored in $PAN_HOME, which defaults to
* $HOME/.pan2 if the PAN_HOME environmental variable isn't set.
- *
+ *
* @ingroup data_impl
*/
class DataImpl:
@@ -100,10 +100,11 @@ namespace pan
int article_expiration_age;
int max_connections;
int rank;
+ int xzver;
typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
groups_t groups;
- Server(): port(119), article_expiration_age(31), max_connections(2), rank(1) {}
+ Server(): port(119), article_expiration_age(31), max_connections(2), rank(1), xzver(0) {}
};
typedef Loki::AssocVector<Quark,Server> servers_t;
@@ -123,11 +124,11 @@ namespace pan
virtual void set_server_auth (const Quark & server,
const StringView & username,
const StringView & password);
-
+
virtual void set_server_addr (const Quark & server,
const StringView & host,
const int port);
-
+
virtual void set_server_limits (const Quark & server,
int max_connections);
@@ -136,6 +137,10 @@ namespace pan
virtual void set_server_article_expiration_age (const Quark & server,
int days);
+ virtual void save_server_info (const Quark& server);
+
+ virtual void set_server_xzver_support (const Quark& server, const int val);
+
public: // accessors
virtual quarks_t get_servers () const {
@@ -148,7 +153,7 @@ namespace pan
virtual bool get_server_auth (const Quark & server,
std::string & setme_username,
std::string & setme_password) const;
-
+
virtual bool get_server_addr (const Quark & server,
std::string & setme_host,
int & setme_port) const;
@@ -161,6 +166,8 @@ namespace pan
virtual int get_server_article_expiration_age (const Quark & server) const;
+ virtual int get_server_xzver_support (const Quark& server) const;
+
/**
*** GROUPS
**/
diff --git a/pan/data-impl/server.cc b/pan/data-impl/server.cc
index 7dfa952..a5da24f 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -107,9 +107,19 @@ DataImpl :: set_server_article_expiration_age (const Quark & server,
s->article_expiration_age = std::max (0, days);
- save_server_properties (*_data_io);
+// save_server_properties (*_data_io);
}
+void
+DataImpl :: set_server_xzver_support (const Quark& server, const int val)
+{
+ if (val<0 || val>1) return;
+ Server * s (find_server (server));
+ assert (s != 0);
+
+ s->xzver = val;
+
+}
void
DataImpl :: set_server_auth (const Quark & server,
@@ -122,7 +132,7 @@ DataImpl :: set_server_auth (const Quark & server,
s->username = username;
s->password = password;
- save_server_properties (*_data_io);
+// save_server_properties (*_data_io);
}
void
@@ -134,7 +144,7 @@ DataImpl :: set_server_addr (const Quark & server,
assert (s != 0);
s->host = host;
s->port = port;
- save_server_properties (*_data_io);
+// save_server_properties (*_data_io);
}
@@ -145,7 +155,7 @@ DataImpl :: set_server_limits (const Quark & server,
Server * s (find_server (server));
assert (s != 0);
s->max_connections = max_connections;
- save_server_properties (*_data_io);
+// save_server_properties (*_data_io);
}
void
@@ -155,6 +165,14 @@ DataImpl :: set_server_rank (const Quark & server,
Server * s (find_server (server));
assert (s != 0);
s->rank = rank;
+// save_server_properties (*_data_io);
+}
+
+void
+DataImpl :: save_server_info (const Quark& server)
+{
+ Server * s (find_server (server));
+ assert (s != 0);
save_server_properties (*_data_io);
}
@@ -229,6 +247,16 @@ DataImpl :: get_server_article_expiration_age (const Quark & server) const
return retval;
}
+int
+DataImpl :: get_server_xzver_support (const Quark & server) const
+{
+ int ret(0);
+ const Server * s (find_server (server));
+ if (s != 0)
+ ret = s->xzver;
+ return ret;
+}
+
/***
****
***/
@@ -324,6 +352,7 @@ DataImpl :: load_server_properties (const DataIO& source)
s.article_expiration_age = to_int(kv["expire-articles-n-days-old"], 31);
s.rank = to_int(kv["rank"], 1);
s.newsrc_filename = kv["newsrc"];
+ s.xzver = to_int(kv["xzver"],1);
if (s.newsrc_filename.empty()) { // set a default filename
std::ostringstream o;
o << file::get_pan_home() << G_DIR_SEPARATOR << "newsrc-" << it->first;
@@ -331,7 +360,7 @@ DataImpl :: load_server_properties (const DataIO& source)
}
}
- save_server_properties (*const_cast<DataIO*>(&source));
+// save_server_properties (*const_cast<DataIO*>(&source));
}
namespace
@@ -376,8 +405,7 @@ DataImpl :: save_server_properties (DataIO& data_io) const
<< indent(depth) << "<connection-limit>" << s->max_connections << "</connection-limit>\n"
<< indent(depth) << "<newsrc>" << s->newsrc_filename << "</newsrc>\n"
<< indent(depth) << "<rank>" << s->rank << "</rank>\n"
- //todo
- << indent(depth) << "<xzver>" << s->rank << "</xzver>\n";
+ << indent(depth) << "<xzver>" << s->xzver << "</xzver>\n";
*out << indent(--depth) << "</server>\n";
}
diff --git a/pan/data/article.h b/pan/data/article.h
index a2e0f9b..0d905b9 100644
--- a/pan/data/article.h
+++ b/pan/data/article.h
@@ -31,7 +31,7 @@ namespace pan
{
/**
* A Usenet article, either single-part or multipart.
- *
+ *
* To lessen the memory footprint of large binaries groups,
* Pan folds multipart posts into a single Article object.
* Only minimal information for any one part is kept
@@ -50,7 +50,6 @@ namespace pan
void set_parts (const PartBatch& b) { parts.set_parts(b); }
bool add_part (Parts::number_t num, const StringView& mid, Parts::bytes_t bytes) { return parts.add_part(num,mid,bytes,message_id); }
void set_part_count (Parts::number_t num) { parts.set_part_count(num); }
-
Parts::number_t get_total_part_count () const { return parts.get_total_part_count(); }
Parts::number_t get_found_part_count () const { return parts.get_found_part_count(); }
bool get_part_info (Parts::number_t num,
@@ -87,7 +86,6 @@ namespace pan
public:
Article (): time_posted(0), lines(0), score(0), is_binary(false) {}
- Article (const bool bin): time_posted(0), lines(0), score(0), is_binary(bin) {}
void clear ();
private:
diff --git a/pan/data/data.h b/pan/data/data.h
index 23e9823..4e03785 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -64,7 +64,7 @@ namespace pan
*
* Also, a read article should change back to unread if it changes
* from an incomplete multipart to a complete multipart as new
- * parts are added to it.
+ * parts are added to it.
*
* @ingroup data
*/
@@ -132,7 +132,7 @@ namespace pan
public:
virtual void delete_profile (const std::string& profile_name) = 0;
virtual void add_profile (const std::string& profile_name, const Profile& profile) = 0;
-
+
protected:
Profiles () {}
};
@@ -168,9 +168,9 @@ namespace pan
public:
- virtual ArticleCache& get_cache () = 0;
+ virtual ArticleCache& get_cache () = 0;
- virtual const ArticleCache& get_cache () const = 0;
+ virtual const ArticleCache& get_cache () const = 0;
public:
@@ -191,6 +191,8 @@ namespace pan
virtual void set_server_limits (const Quark & server,
int max_connections) = 0;
+ virtual void set_server_xzver_support (const Quark& server, int setme) = 0;
+
virtual bool get_server_addr (const Quark & server,
std::string & setme_address,
int & setme_port) const = 0;
@@ -201,6 +203,8 @@ namespace pan
virtual int get_server_limits (const Quark & server) const = 0;
+ virtual int get_server_xzver_support (const Quark& server) const = 0;
+
/*****************************************************************
***
*** OBSERVERS
@@ -354,7 +358,7 @@ namespace pan
*
* In the case of new articles, the Tree's existing filter
* is applied to them and new articles that survive the filter
- * are threaded into the tree.
+ * are threaded into the tree.
*
* In the case of deleted articles, their children are
* reparented to the youngest surviving ancestor and then the
@@ -442,7 +446,7 @@ namespace pan
(*it++)->on_tree_change (d);
}
}
-
+
/*************************************************************
***
@@ -555,7 +559,7 @@ namespace pan
/**
* Returns the high number of the most recent XOVER command
- * run on the specified {server,group}, or 0 if it's never
+ * run on the specified {server,group}, or 0 if it's never
* been run there.
*/
virtual uint64_t get_xover_high (const Quark & group,
diff --git a/pan/data/parts.cc b/pan/data/parts.cc
index 8b3181e..11cfe71 100644
--- a/pan/data/parts.cc
+++ b/pan/data/parts.cc
@@ -87,7 +87,7 @@ namespace
for (; b!=bmax; ++b)
if (*k++ != *m++)
break;
-
+
const int emax = std::min (shorter-b, (int)UCHAR_MAX);
k = &key.back();
m = &mid.back();
diff --git a/pan/data/server-info.h b/pan/data/server-info.h
index bcdc3f0..694f781 100644
--- a/pan/data/server-info.h
+++ b/pan/data/server-info.h
@@ -61,6 +61,10 @@ namespace pan
virtual void set_server_rank (const Quark& server,
int rank) = 0;
+ virtual void set_server_xzver_support (const Quark& server, const int val) = 0;
+
+ virtual void save_server_info (const Quark& server) = 0;
+
public: // accessors
virtual bool get_server_auth (const Quark & servername,
@@ -78,6 +82,8 @@ namespace pan
virtual int get_server_limits (const Quark & server) const = 0;
virtual int get_server_article_expiration_age (const Quark & server) const = 0;
+
+ virtual int get_server_xzver_support (const Quark& server) const = 0;
};
}
diff --git a/pan/general/file-util.cc b/pan/general/file-util.cc
index fc5cd50..a38367e 100644
--- a/pan/general/file-util.cc
+++ b/pan/general/file-util.cc
@@ -51,7 +51,11 @@ using namespace pan;
std::string
file :: get_pan_uulib_dir()
{
- return std::string("/home/imhotep/.pan2/uulib-encode-cache");
+ char * pch (g_build_filename (file::get_pan_home().c_str(), "uulib-encode-cache", NULL));
+ file :: ensure_dir_exists (pch);
+ std::string path (pch);
+ g_free (pch);
+ return path;
}
std::string
diff --git a/pan/general/file-util.h b/pan/general/file-util.h
index 6e6d3a6..7928ce5 100644
--- a/pan/general/file-util.h
+++ b/pan/general/file-util.h
@@ -49,10 +49,6 @@ namespace pan
*/
namespace file
{
-
- /** Returns the directory for encoded files, should be temporary */
- std::string get_pan_uulib_dir ();
-
/** just like strerror but never returns NULL */
const char * pan_strerror (int error_number);
@@ -62,6 +58,8 @@ namespace pan
*/
std::string get_pan_home ();
+ std::string get_pan_uulib_dir();
+
/**
* If the specified directory doesn't exist, Pan tries to create it.
* @param path
diff --git a/pan/general/progress.cc b/pan/general/progress.cc
index b292ded..a01a9e5 100644
--- a/pan/general/progress.cc
+++ b/pan/general/progress.cc
@@ -31,8 +31,8 @@ using namespace pan;
void
Progress :: fire_percentage (int p) {
-// for (listeners_cit it(_listeners.begin()), end(_listeners.end()); it!=end; )
-// (*it++)->on_progress_step (*this, p);
+ for (listeners_cit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+ (*it++)->on_progress_step (*this, p);
}
void
Progress :: fire_pulse () {
diff --git a/pan/general/string-view.h b/pan/general/string-view.h
index c7fb901..9b5c2d9 100644
--- a/pan/general/string-view.h
+++ b/pan/general/string-view.h
@@ -28,7 +28,7 @@
namespace pan
{
/**
- * A shallow copy a C string, plus utilities to let us
+ * A shallow copy a C string, plus utilities to let us
* substring, tokenize, walk, search, or otherwise
* manipulate it without having to modify the original or
* allocate new strings.
@@ -43,12 +43,12 @@ namespace pan
size_t str_a_len,
const char * str_b,
size_t str_b_len);
-
+
static char* strchr (const char * haystack,
size_t haystack_len,
char needle)
{ return (char*) memchr (haystack, needle, haystack_len); }
-
+
static char* strrchr (const char * haystack,
size_t haystack_len,
char needle);
diff --git a/pan/general/worker-pool.cc b/pan/general/worker-pool.cc
index bdbf809..6ff4b76 100644
--- a/pan/general/worker-pool.cc
+++ b/pan/general/worker-pool.cc
@@ -63,7 +63,6 @@ WorkerPool :: push_work (Worker *w, Worker::Listener *l, bool delete_worker)
w->silent = false;
w->pool = this;
w->listener = l;
- if (!l) std::cerr<<"oops, listener in push_work is null!\n";
w->delete_worker = delete_worker;
my_workers.insert (w);
g_thread_pool_push (tpool, w, 0); // jump to worker_thread_func
diff --git a/pan/gui/dl-headers-ui.cc b/pan/gui/dl-headers-ui.cc
index 689c0e5..383a863 100644
--- a/pan/gui/dl-headers-ui.cc
+++ b/pan/gui/dl-headers-ui.cc
@@ -66,7 +66,7 @@ namespace
if (response == GTK_RESPONSE_ACCEPT)
{
const bool mark_read (state->prefs.get_flag ("mark-group-read-before-xover", false));
- // xzver
+
foreach_const (quarks_t, state->groups, it) {
Task * task;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(state->all_headers_rb)))
@@ -112,7 +112,7 @@ pan :: headers_dialog (Data& data, Prefs& prefs, Queue& queue,
g_snprintf (buf, sizeof(buf), _("%d Groups"), (int)groups.size());
title += buf;
}
-
+
State * state = new State (data, prefs, queue);
state->groups = groups;
state->dialog = gtk_dialog_new_with_buttons (
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index bfce0ae..7606b85 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -1606,6 +1606,7 @@ void GUI :: do_read_selected_group ()
else if (_prefs.get_flag("get-new-headers-when-entering-group", true)) {
if (_prefs.get_flag ("mark-group-read-before-xover", false))
_data.mark_group_read (group);
+// todo xzver
_queue.add_task (new TaskXOver (_data, group, TaskXOver::NEW), Queue::TOP);
}
}
@@ -1630,6 +1631,7 @@ void GUI :: do_xover_selected_groups ()
foreach_const (quarks_v, groups, it) {
if (mark_read)
_data.mark_group_read (*it);
+ //todo xzver
_queue.add_task (new TaskXOver (_data, *it, TaskXOver::NEW), Queue::TOP);
}
}
@@ -1642,6 +1644,7 @@ void GUI :: do_xover_subscribed_groups ()
const bool mark_read (_prefs.get_flag ("mark-group-read-before-xover", false));
foreach_const_r (quarks_v, groups, it) {
if (mark_read)
+ //todo xzver
_data.mark_group_read (*it);
_queue.add_task (new TaskXOver (_data, *it, TaskXOver::NEW), Queue::TOP);
}
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 38d9deb..f2fa81e 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -130,7 +130,7 @@ namespace
const Quark & message_id)
{
int offset (ICON_EMPTY);
-
+
if (queue.contains (message_id))
offset = ICON_QUEUED;
else if (cache.contains (message_id))
@@ -318,7 +318,7 @@ HeaderPane :: create_row (const EvolutionDateMaker & e,
std::pair<mid_to_row_t::iterator,bool> result (_mid_to_row.insert (row));
g_assert (result.second);
-
+
return row;
}
@@ -687,7 +687,7 @@ HeaderPane :: on_tree_change (const Data::ArticleTree::Diffs& diffs)
}
_tree_store->insert_sorted (tmp);
}
-
+
// reparent...
if (do_thread && !diffs.reparented.empty()) {
PanTreeStore::parent_to_children_t tmp;
@@ -919,7 +919,7 @@ HeaderPane :: on_button_pressed (GtkWidget * treeview, GdkEventButton *event, gp
GtkTreeSelection * selection = gtk_tree_view_get_selection(tv);
GtkTreePath *path;
if (gtk_tree_view_get_path_at_pos (tv,
- (gint) event->x,
+ (gint) event->x,
(gint) event->y,
&path, NULL, NULL, NULL))
{
@@ -1564,7 +1564,6 @@ HeaderPane :: on_selection_changed_idle (gpointer self_gpointer)
"download-selected-article",
"save-articles",
"save-articles-from-nzb",
- "save-articles-to-nzb",
"read-selected-article",
"show-selected-article-info",
"mark-article-read",
@@ -1631,6 +1630,7 @@ HeaderPane :: HeaderPane (ActionManager & action_manager,
g_signal_connect (sel, "changed", G_CALLBACK(on_selection_changed), this);
on_selection_changed (sel, this);
+
g_signal_connect (w, "button-release-event", G_CALLBACK(on_button_pressed), this);
g_signal_connect (w, "button-press-event", G_CALLBACK(on_button_pressed), this);
g_signal_connect (w, "row-collapsed", G_CALLBACK(row_collapsed_cb), NULL);
@@ -1868,7 +1868,7 @@ namespace
}
/**
-***
+***
**/
void
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 5268ef7..555c660 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -36,6 +36,7 @@ extern "C" {
#include <pan/tasks/socket-impl-gio.h>
#include <pan/tasks/task-groups.h>
#include <pan/tasks/task-xover.h>
+#include <pan/tasks/task-xzver.h>
#include <pan/tasks/nzb.h>
#include <pan/data-impl/data-impl.h>
#include <pan/icons/pan-pixbufs.h>
@@ -118,6 +119,15 @@ namespace
g_free (foo);
}
+ void add_xzver_test_task (GtkObject *, gpointer user_data)
+ {
+ DataAndQueue * foo (static_cast<DataAndQueue*>(user_data));
+ const quarks_t new_servers (foo->data->get_servers());
+ foreach (quarks_t, new_servers, it)
+ foo->queue->add_task (new TaskXZVer (*it, *foo->data));
+ g_free (foo);
+ }
+
gboolean queue_upkeep_timer_cb (gpointer queue_gpointer)
{
static_cast<Queue*>(queue_gpointer)->upkeep ();
@@ -155,7 +165,9 @@ namespace
DataAndQueue * foo = g_new0 (DataAndQueue, 1);
foo->data = &data;
foo->queue = &queue;
- g_signal_connect (w, "destroy", G_CALLBACK(add_grouplist_task), foo);
+ g_signal_connect (w, "destroy", G_CALLBACK(add_xzver_test_task), foo);
+// g_signal_connect (w, "destroy", G_CALLBACK(add_grouplist_task), foo);
+
}
register_shutdown_signals ();
@@ -175,7 +187,7 @@ namespace
~PanKiller() { q.remove_listener(this); }
/** Method from Queue::Listener interface: quits program on zero sized Q*/
- void on_queue_size_changed (Queue&, int active, int total)
+ void on_queue_size_changed (Queue&, int active, int total)
{ if (!active && !total) mainloop_quit(); }
// all below methods from Queue::Listener interface are noops
@@ -278,7 +290,7 @@ main (int argc, char *argv[])
nzb = true;
else if (!strcmp (tok, "--version"))
{ std::cerr << "Pan " << VERSION << '\n'; return 0; }
- else if (!strcmp (tok, "-o") && i<argc-1)
+ else if (!strcmp (tok, "-o") && i<argc-1)
nzb_output_path = argv[++i];
else if (!memcmp (tok, "--output=", 9))
nzb_output_path = tok+9;
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 4271798..018bd9f 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -369,8 +369,6 @@ bool
PostUI :: check_message (const Quark& server, GMimeMessage * msg)
{
- std::cerr<<"check message\n";
-
MessageCheck :: unique_strings_t errors;
MessageCheck :: Goodness goodness;
@@ -486,22 +484,11 @@ PostUI :: send_now ()
{
if (!check_charset())
return;
- GMimeMessage * message (new_message_from_ui (POSTING));
+ GMimeMessage * message (new_message_from_ui (POSTING,get_body()));
if (!maybe_post_message (message))
g_object_unref (G_OBJECT(message));
}
-//void
-//PostUI :: send_binfiles_now()
-//{
-// if (!check_charset())
-// return;
-// GMimeMessage * message (new_message_from_ui (POSTING));
-//
-// //change headers according to
-// g_object_unref (G_OBJECT(message));
-//}
-
void
PostUI :: done_sending_message (GMimeMessage * message, bool ok)
{
@@ -593,16 +580,18 @@ PostUI :: on_progress_finished (Progress&, int status) // posting finished
int bufsz=2048;
char buf[bufsz];
- _post_task->remove_listener (this);
- gtk_widget_destroy (_post_dialog);
-
if (_file_queue_empty) {
- GMimeMessage * message (((TaskPost*)_post_task)->get_message ());
- if (status != OK) // error posting.. stop.
- done_sending_message (message, false);
- else
- maybe_mail_message (message);
+ _post_task->remove_listener (this);
+ gtk_widget_destroy (_post_dialog);
+
}
+// if (_file_queue_empty) {
+// GMimeMessage * message (((TaskPost*)_post_task)->get_message ());
+// if (status != OK) // error posting.. stop.
+// done_sending_message (message, false);
+// else
+// maybe_mail_message (message);
+// }
// else
// {
// GMimeMessage * message (((TaskUpload*)_upload_task)->get_message ());
@@ -726,13 +715,12 @@ PostUI :: maybe_post_message (GMimeMessage * message)
FileQueue::articles_it it = _file_queue.begin();
for (; it != _file_queue.end(); it, ++it, ++i) {
- GMimeMessage* msg = new_message_from_ui(POSTING);
- _queue.add_task (new TaskUpload (*it,profile.posting_server,msg
- ,0,TaskUpload::YENC,i),
- Queue::BOTTOM);
+ // get message body first, later on the attachment's content is added to the message
+ GMimeMessage* msg = new_message_from_ui (BINPOST, get_body());
+ TaskUpload* t =new TaskUpload (*it,server,msg,0,TaskUpload::YENC,i);
+ _queue.add_task (t,Queue::BOTTOM);
}
- //dbg
-// close_window(true); // dont wait for the upload queue
+ close_window(true); // dont wait for the upload queue
}
@@ -1004,7 +992,7 @@ namespace
}
GMimeMessage*
-PostUI :: new_message_from_ui (Mode mode)
+PostUI :: new_message_from_ui (Mode mode, std::string body)
{
GMimeMessage * msg (g_mime_message_new (false));
@@ -1063,11 +1051,11 @@ PostUI :: new_message_from_ui (Mode mode)
g_free (pch);
// User-Agent
- if (mode==POSTING && _prefs.get_flag (USER_AGENT_PREFS_KEY, true))
+ if ((mode==POSTING || mode == BINPOST ) && _prefs.get_flag (USER_AGENT_PREFS_KEY, true))
g_mime_object_set_header ((GMimeObject *) msg, "User-Agent", get_user_agent());
// Message-ID
- if (mode==POSTING && _prefs.get_flag (MESSAGE_ID_PREFS_KEY, false)) {
+ if ((mode==POSTING || mode == BINPOST ) && _prefs.get_flag (MESSAGE_ID_PREFS_KEY, false)) {
const std::string message_id = !profile.fqdn.empty()
? GNKSA::generate_message_id (profile.fqdn)
: GNKSA::generate_message_id_from_email_address (profile.address);
@@ -1075,10 +1063,9 @@ PostUI :: new_message_from_ui (Mode mode)
}
// body & charset
- std::string body (get_body());
GMimeStream * stream = g_mime_stream_mem_new_with_buffer (body.c_str(), body.size());
const std::string charset ((mode==POSTING && !_charset.empty()) ? _charset : "UTF-8");
- if (charset != "UTF-8") {
+ if (charset != "UTF-8") { //dbg (??)
// add a wrapper to convert from UTF-8 to $charset
GMimeStream * tmp = g_mime_stream_filter_new (stream);
g_object_unref (stream);
@@ -1090,7 +1077,12 @@ PostUI :: new_message_from_ui (Mode mode)
GMimeDataWrapper * content_object = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_DEFAULT);
g_object_unref (stream);
GMimePart * part = g_mime_part_new ();
- pch = g_strdup_printf ("text/plain; charset=%s", charset.c_str());
+
+ if (mode==BINPOST)
+ pch = g_strdup_printf ("multipart/mixed; charset=%s", charset.c_str());
+ else
+ pch = g_strdup_printf ("text/plain; charset=%s", charset.c_str());
+
GMimeContentType * type = g_mime_content_type_new_from_string (pch);
g_free (pch);
g_mime_object_set_content_type ((GMimeObject *) part, type); // part owns type now. type isn't refcounted.
@@ -1123,7 +1115,7 @@ PostUI :: save_draft ()
if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT)
{
- GMimeMessage * msg = new_message_from_ui (DRAFTING);
+ GMimeMessage * msg = new_message_from_ui (DRAFTING, get_body());
char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(d));
draft_filename = filename;
@@ -1824,7 +1816,6 @@ PostUI :: create_main_tab ()
// Newsgroup
++row;
- std::cerr<<" create main tab\n";
g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("_Newsgroups"));
l = gtk_label_new_with_mnemonic (buf);
gtk_label_set_use_markup (GTK_LABEL(l), true);
@@ -2010,8 +2001,8 @@ PostUI :: update_filequeue_tab()
{
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
- 0, (*it)->basename,
- 1, (*it)->byte_count,
+ 0, (*it).basename,
+ 1, (*it).byte_count/1024,
-1);
}
@@ -2055,7 +2046,6 @@ PostUI :: PostUI (GtkWindow * parent,
_charset (DEFAULT_CHARSET),
_group_entry_changed_id (0),
_group_entry_changed_idle_tag (0),
- //binpost
_file_queue_empty(true)
{
g_assert (profiles.has_profiles());
@@ -2153,9 +2143,6 @@ PostUI :: prompt_user_for_queueable_files (FileQueue& queue, GtkWindow * parent,
GSList * tmp_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (w));
if (_file_queue_empty) _file_queue_empty=!_file_queue_empty;
GSList * cur = g_slist_nth (tmp_list,0);
- const Profile profile (get_current_profile ());
- const StringView subject(gtk_entry_get_text (GTK_ENTRY(_subject_entry)));
- struct stat stat_buf;
for (; cur; cur = cur->next)
{
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index 43b16bf..584ecd3 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -129,8 +129,8 @@ namespace pan
void add_actions (GtkWidget* box);
void apply_profile_to_body ();
void apply_profile_to_headers ();
- enum Mode { DRAFTING, POSTING };
- GMimeMessage * new_message_from_ui (Mode mode);
+ enum Mode { DRAFTING, POSTING, BINPOST };
+ GMimeMessage * new_message_from_ui (Mode mode, std::string body);
Profile get_current_profile ();
bool check_message (const Quark& server, GMimeMessage*);
bool check_charset ();
diff --git a/pan/gui/prefs.h b/pan/gui/prefs.h
index d475b8f..0969fca 100644
--- a/pan/gui/prefs.h
+++ b/pan/gui/prefs.h
@@ -25,9 +25,7 @@
#include <string>
#include <vector>
#include <pan/general/string-view.h>
-extern "C" {
- #include <gtk/gtk.h>
-}
+#include <gtk/gtk.h>
namespace pan
{
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index ffca9d9..7bfa708 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -91,7 +91,7 @@ namespace
d->server = server;
- int port(119), max_conn(4), age(31*3), rank(1);
+ int port(119), max_conn(4), age(31*3), rank(1), xzver(0);
std::string addr, user, pass;
if (!server.empty()) {
d->data.get_server_addr (server, addr, port);
@@ -99,6 +99,7 @@ namespace
age = d->data.get_server_article_expiration_age (server);
rank = d->data.get_server_rank (server);
max_conn = d->data.get_server_limits (server);
+ xzver = d->data.get_server_xzver_support(server);
}
pan_entry_set_text (d->address_entry, addr);
@@ -131,6 +132,18 @@ namespace
break;
}
} while (gtk_tree_model_iter_next(model, &iter));
+
+ // set the xzver combo box
+ combo = GTK_COMBO_BOX (d->xzver_compression_combo);
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_tree_model_get_iter_first(model, &iter)) do {
+ int that;
+ gtk_tree_model_get (model, &iter, 1, &that, -1);
+ if (that == xzver) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
}
void
@@ -159,6 +172,10 @@ namespace
combo = GTK_COMBO_BOX (d->rank_combo);
if (gtk_combo_box_get_active_iter (combo, &iter))
gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &rank, -1);
+ int xzver(0);
+ combo = GTK_COMBO_BOX (d->xzver_compression_combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &xzver, -1);
const char * err_msg (0);
if (addr.empty())
err_msg = _("Please specify the server's address.");
@@ -180,6 +197,8 @@ namespace
d->data.set_server_limits (d->server, max_conn);
d->data.set_server_article_expiration_age (d->server, age);
d->data.set_server_rank (d->server, rank);
+ d->data.set_server_xzver_support (d->server, xzver);
+ d->data.save_server_info(d->server);
d->queue.upkeep ();
}
}
@@ -319,7 +338,7 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer2, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer2, "text", 0, NULL);
gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
- HIG::workarea_add_row (t, &row, _("Serverside _Header-compression support:"), w, NULL);
+ HIG::workarea_add_row (t, &row, _("_Header-compression support (XZVER) :"), w, NULL);
d->server = server;
edit_dialog_populate (data, server, d);
diff --git a/pan/gui/task-pane.cc b/pan/gui/task-pane.cc
index 8e7c938..15066e5 100644
--- a/pan/gui/task-pane.cc
+++ b/pan/gui/task-pane.cc
@@ -208,11 +208,11 @@ TaskPane :: update_status (const task_states_t& tasks)
{
Task * task (*it);
const Queue::TaskState state (tasks.get_state (task));
- if (state == Queue::RUNNING || state == Queue::DECODING || state == Queue::ENCODING)
+ if (state == Queue::RUNNING || state == Queue::DECODING)
++running_count;
else if (state == Queue::STOPPED)
++stopped_count;
- else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE || state == Queue::QUEUED_FOR_ENCODE)
+ else if (state == Queue::QUEUED || state == Queue::QUEUED_FOR_DECODE)
++queued_count;
if (state==Queue::RUNNING || state==Queue::QUEUED)
@@ -225,7 +225,7 @@ TaskPane :: update_status (const task_states_t& tasks)
g_snprintf (buf, sizeof(buf), _("Pan: Tasks (%d Queued, %d Running, %d Stopped)"), queued_count, running_count, stopped_count);
else if (running_count || queued_count)
g_snprintf (buf, sizeof(buf), _("Pan: Tasks (%d Queued, %d Running)"), queued_count, running_count);
- else
+ else
g_snprintf (buf, sizeof(buf), _("Pan: Tasks"));
gtk_window_set_title (GTK_WINDOW(_root), buf);
@@ -240,7 +240,6 @@ TaskPane :: update_status (const task_states_t& tasks)
minutes = tmp % 60ul; tmp /= 60ul;
hours = tmp;
}
-
g_snprintf (buf, sizeof(buf), _("%lu tasks, %s, %.1f KiBps, ETA %d:%02d:%02d"),
task_count, render_bytes(bytes), KiBps, hours, minutes, seconds);
std::string line (buf);
diff --git a/pan/tasks/Makefile.am b/pan/tasks/Makefile.am
index a1b5b3d..fb621d3 100644
--- a/pan/tasks/Makefile.am
+++ b/pan/tasks/Makefile.am
@@ -10,6 +10,7 @@ libtasks_a_SOURCES = \
task-groups.cc \
task-post.cc \
task-xover.cc \
+ task-xzver.cc \
task-upload.cc \
nntp.cc \
nzb.cc \
@@ -33,6 +34,7 @@ noinst_HEADERS = \
task-upload.h \
task-weak-ordering.h \
task-xover.h \
+ task-xzver.h \
nntp.h \
nzb.h \
queue.h \
diff --git a/pan/tasks/decoder.cc b/pan/tasks/decoder.cc
index 01616fd..5e8bfa8 100644
--- a/pan/tasks/decoder.cc
+++ b/pan/tasks/decoder.cc
@@ -171,8 +171,8 @@ Decoder :: do_work()
file :: ensure_dir_exists (save_path.c_str());
// find a unique filename...
- char * fname = file::get_unique_fname(save_path.c_str(),
- (item->filename
+ char * fname = file::get_unique_fname(save_path.c_str(),
+ (item->filename
&& *item->filename)
? item->filename
: "pan-saved-file" );
@@ -296,11 +296,13 @@ Decoder :: progress_update_timer_func (gpointer decoder)
if (!task || self->was_cancelled()) return false;
self->mut.lock();
- const double percent (self->percent);
- const std::string f (content_to_utf8 (self->current_file));
- task->set_step(int(percent));
- task->set_status_va (_("Decoding %s"), f.c_str());
+ const double percent (self->percent);
+ const std::string f (content_to_utf8 (self->current_file));
self->mut.unlock();
+
+ task->set_step(int(percent));
+ task->set_status_va (_("Decoding %s"), f.c_str());
+
return true; // keep timer func running
}
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index 2d45eaa..45891f2 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -54,51 +54,6 @@ namespace
}
};
-namespace
-{
- enum
- {
- AUTH_REQUIRED = 480,
- AUTH_NEED_MORE = 381,
- AUTH_ACCEPTED = 281,
- AUTH_REJECTED = 482,
-
- SERVER_READY = 200,
- SERVER_READY_NO_POSTING = 201,
- SERVER_READY_STREAMING_OK = 203,
-
- GOODBYE = 205,
-
- GROUP_RESPONSE = 211,
- GROUP_NONEXISTENT = 411,
-
- INFORMATION_FOLLOWS = 215,
-
- XOVER_FOLLOWS = 224,
- XOVER_NO_ARTICLES = 420,
-
- ARTICLE_FOLLOWS = 220,
-
- NEWGROUPS_FOLLOWS = 231,
-
- ARTICLE_POSTED_OK = 240,
- SEND_ARTICLE_NOW = 340,
- NO_POSTING = 440,
- POSTING_FAILED = 441,
-
- TOO_MANY_CONNECTIONS = 400,
-
- NO_GROUP_SELECTED = 412,
- NO_SUCH_ARTICLE_NUMBER = 423,
- NO_SUCH_ARTICLE = 430,
-
- ERROR_CMD_NOT_UNDERSTOOD = 500,
- ERROR_CMD_NOT_SUPPORTED = 501,
- NO_PERMISSION = 502,
- FEATURE_NOT_SUPPORTED = 503
- };
-}
-
void
NNTP :: fire_done_func (Health health, const StringView& response)
{
@@ -223,6 +178,8 @@ NNTP :: on_socket_response (Socket * sock UNUSED, const StringView& line_in)
break;
case XOVER_FOLLOWS:
+ if (_listener)
+ _listener->on_xover_follows (this, line);
case ARTICLE_FOLLOWS:
case NEWGROUPS_FOLLOWS:
case INFORMATION_FOLLOWS:
@@ -233,6 +190,8 @@ NNTP :: on_socket_response (Socket * sock UNUSED, const StringView& line_in)
case AUTH_REJECTED:
case NO_GROUP_SELECTED:
case ERROR_CMD_NOT_UNDERSTOOD:
+ if (_listener)
+ _listener->on_cmd_not_understood (this, line);
case ERROR_CMD_NOT_SUPPORTED:
case NO_PERMISSION:
case FEATURE_NOT_SUPPORTED: {
@@ -283,7 +242,7 @@ NNTP :: on_socket_response (Socket * sock UNUSED, const StringView& line_in)
switch (state) {
case CMD_FAIL: fire_done_func (ERR_COMMAND, line); more = false; break;
case CMD_DONE: if (_commands.empty()) fire_done_func (OK, line); more = false; break;
- case CMD_MORE: more = true; break; // keep listining for more on this command
+ case CMD_MORE: more = true; break; // keep listening for more on this command
case CMD_NEXT: more = false; break; // no more responses on this command; wait for next...
case CMD_RETRY: fire_done_func (ERR_NETWORK, line); more = false; break;
default: abort(); break;
diff --git a/pan/tasks/nntp.h b/pan/tasks/nntp.h
index 01480cc..57796e8 100644
--- a/pan/tasks/nntp.h
+++ b/pan/tasks/nntp.h
@@ -38,6 +38,49 @@ namespace pan
class NNTP: private Socket::Listener
{
public:
+ enum ResponseType
+ {
+ AUTH_REQUIRED = 480,
+ AUTH_NEED_MORE = 381,
+ AUTH_ACCEPTED = 281,
+ AUTH_REJECTED = 482,
+
+ SERVER_READY = 200,
+ SERVER_READY_NO_POSTING = 201,
+ SERVER_READY_STREAMING_OK = 203,
+
+ GOODBYE = 205,
+
+ GROUP_RESPONSE = 211,
+ GROUP_NONEXISTENT = 411,
+
+ INFORMATION_FOLLOWS = 215,
+
+ XOVER_FOLLOWS = 224,
+ XOVER_NO_ARTICLES = 420,
+
+ ARTICLE_FOLLOWS = 220,
+
+ NEWGROUPS_FOLLOWS = 231,
+
+ ARTICLE_POSTED_OK = 240,
+ SEND_ARTICLE_NOW = 340,
+ NO_POSTING = 440,
+ POSTING_FAILED = 441,
+
+ TOO_MANY_CONNECTIONS = 400,
+
+ NO_GROUP_SELECTED = 412,
+ NO_SUCH_ARTICLE_NUMBER = 423,
+ NO_SUCH_ARTICLE = 430,
+
+ ERROR_CMD_NOT_UNDERSTOOD = 500,
+ ERROR_CMD_NOT_SUPPORTED = 501,
+ NO_PERMISSION = 502,
+ FEATURE_NOT_SUPPORTED = 503
+ };
+
+ public:
/**
* Base class for objects that listen for NNTP events.
@@ -88,6 +131,15 @@ namespace pan
unsigned long estimated_qty UNUSED,
uint64_t low UNUSED,
uint64_t high UNUSED) {}
+
+
+ //both functions are implemented for xzver testing(!)
+ virtual void on_xover_follows (NNTP * nntp UNUSED,
+ const StringView & line UNUSED) {}
+
+ virtual void on_cmd_not_understood (NNTP * nntp UNUSED,
+ const StringView & line UNUSED) {}
+
};
public:
diff --git a/pan/tasks/queue.cc b/pan/tasks/queue.cc
index ce9de63..d4ee76f 100644
--- a/pan/tasks/queue.cc
+++ b/pan/tasks/queue.cc
@@ -550,6 +550,9 @@ Queue :: task_is_active (const Task * task) const
if (task && task==_decoder_task)
return true;
+ if (task && task==_encoder_task)
+ return true;
+
bool task_has_nntp (false);
foreach_const (nntp_to_task_t, _nntp_to_task, it)
if ((task_has_nntp = task==it->second))
@@ -599,13 +602,17 @@ Queue :: get_all_task_states (task_states_t& setme)
setme.tasks.reserve(_tasks.size());
std::vector<Task *> & need_decode = setme._need_decode.get_container();
- need_decode.clear();
+ std::vector<Task *> & need_encode = setme._need_encode.get_container();
+ need_decode.clear(); need_encode.clear();
need_decode.reserve(setme.tasks.capacity());
+ need_encode.reserve(setme.tasks.capacity());
foreach(TaskSet, _tasks, it) {
setme.tasks.push_back(*it);
if ((*it)->get_state()._work == Task::NEED_DECODER)
need_decode.push_back(*it);
+ if ((*it)->get_state()._work == Task::NEED_ENCODER)
+ need_encode.push_back(*it);
}
setme._need_decode.sort();
@@ -627,6 +634,7 @@ Queue :: get_all_task_states (task_states_t& setme)
running.insert (running.end(), tmp.begin(), tmp.end());
setme._decoding = _decoder_task;
+ setme._encoding = _encoder_task;
}
void
@@ -678,6 +686,7 @@ Queue :: check_in (Decoder* decoder UNUSED, Task* task)
{
// take care of our decoder counting...
_decoder_task = 0;
+ _encoder_task = 0;
// notify the listeners if the task isn't active anymore...
if (!task_is_active (task))
@@ -698,7 +707,7 @@ Queue :: check_in (Decoder* decoder UNUSED, Task* task)
}
void
-Queue :: check_in (Encoder* decoder UNUSED, Task* task)
+Queue :: check_in (Encoder* encoder UNUSED, Task* task)
{
// take care of our decoder counting...
_encoder_task = 0;
diff --git a/pan/tasks/task-article.cc b/pan/tasks/task-article.cc
index e529d52..3c77f7b 100644
--- a/pan/tasks/task-article.cc
+++ b/pan/tasks/task-article.cc
@@ -132,7 +132,7 @@ TaskArticle :: ~TaskArticle ()
// ensure our on_worker_done() doesn't get called after we're dead
if (_decoder)
_decoder->cancel_silently();
-
+
_cache.release (_article.get_part_mids());
}
@@ -291,7 +291,7 @@ TaskArticle :: on_nntp_done (NNTP * nntp,
}
break;
}
-
+
update_work (nntp);
check_in (nntp, health);
}
diff --git a/pan/tasks/task-post.cc b/pan/tasks/task-post.cc
index d605d18..18e7747 100644
--- a/pan/tasks/task-post.cc
+++ b/pan/tasks/task-post.cc
@@ -57,7 +57,6 @@ TaskPost :: use_nntp (NNTP * nntp)
_state.set_working ();
char * text = g_mime_object_to_string (GMIME_OBJECT(_message));
- std::cerr<<text<<std::endl;
nntp->post (text, this);
g_free (text);
}
diff --git a/pan/tasks/task-weak-ordering.h b/pan/tasks/task-weak-ordering.h
index 242315c..6f6d2fd 100644
--- a/pan/tasks/task-weak-ordering.h
+++ b/pan/tasks/task-weak-ordering.h
@@ -34,14 +34,15 @@ namespace pan
*/
struct TaskWeakOrdering
{
- const Quark BODIES, CANCEL, GROUPS, POST, SAVE, XOVER;
+ const Quark BODIES, CANCEL, GROUPS, POST, SAVE, XOVER, XZVER_TEST;
TaskWeakOrdering ():
BODIES ("BODIES"),
CANCEL ("CANCEL"),
GROUPS ("GROUPS"),
POST ("POST"),
SAVE ("SAVE"),
- XOVER ("XOVER") {}
+ XOVER ("XOVER"),
+ XZVER_TEST ("XZVER_TEST") {}
int get_rank_for_type (const Quark& type) const
{
@@ -49,7 +50,7 @@ namespace pan
if (type==BODIES || type==POST || type==CANCEL)
rank = 0;
- else if (type==XOVER || type==GROUPS)
+ else if (type==XOVER || type==GROUPS || type==XZVER_TEST)
rank = 1;
else if (type==SAVE)
rank = 2;
diff --git a/pan/tasks/task-xover.cc b/pan/tasks/task-xover.cc
index 40b292f..a3a4b80 100644
--- a/pan/tasks/task-xover.cc
+++ b/pan/tasks/task-xover.cc
@@ -17,12 +17,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+int cnt = 0; //dbg
+
#include <config.h>
#include <cassert>
#include <cerrno>
extern "C" {
+ #include <stdio.h>
+ #define PROTOTYPES
+ #include <uulib/uudeview.h>
#include <glib/gi18n.h>
#include <gmime/gmime-utils.h>
+ #include <zlib.h>
}
#include <pan/general/debug.h>
#include <pan/general/macros.h>
@@ -31,6 +37,7 @@ extern "C" {
#include <pan/data/data.h>
#include "nntp.h"
#include "task-xover.h"
+#include "task-xzver.h"
using namespace pan;
@@ -75,6 +82,38 @@ namespace
snprintf (buf, sizeof(buf), _("Sampling headers for \"%s\""), group.c_str());
return std::string (buf);
}
+
+ void decompress(const Quark& server, std::string stream)
+ {
+ char buf[512];
+ int res(UURET_OK);
+ const char* server_string = server.to_string().c_str();
+ const char* uulib_dir = (file :: get_pan_uulib_dir()).c_str();
+
+ g_snprintf(buf,512,"%s/%s.%s", uulib_dir, "headers.gz.yenc",server_string);
+ std::ofstream out(buf);
+
+ out << "=ybegin line=128 size=-1 name=headers.gz\r\n";
+ out<< stream;
+ out << "\r\n=yend crc=FFFFFFFF\r\n.\r\n";
+ out.flush();
+ out.close();
+ UULoadFile (NULL, 0, 0);
+ g_snprintf(buf,512,"%s/%s.%s", uulib_dir, "headers.gz",server_string);
+ if ((res=UUDecodeFile(UUGetFileListItem (0), buf))==UURET_OK) {
+ gzFile zf = gzopen(buf,"rb");
+ g_snprintf(buf,512,"%s/%s.%s", uulib_dir, "headers",server_string);
+ std::ofstream gz_buf(buf);
+ int res_gz(0);
+ while (1)
+ {
+ if ((res_gz=gzread(zf,buf,512))<=0) break;
+ gz_buf<<buf;
+ }
+ gzclose(zf);
+ gz_buf.close();
+ }
+ }
}
TaskXOver :: TaskXOver (Data & data,
@@ -92,18 +131,23 @@ TaskXOver :: TaskXOver (Data & data,
_bytes_so_far (0),
_parts_so_far (0ul),
_articles_so_far (0ul),
- _total_minitasks (0)
+ _total_minitasks (0),
+ _need_decompress (0ul)
{
- debug ("ctor for " << group);
// add a ``GROUP'' MiniTask for each server that has this group
// initialize the _high lookup table to boundaries
const MiniTask group_minitask (MiniTask::GROUP);
quarks_t servers;
- _data.group_get_servers (group, servers);
+ _data.group_get_servers (group, _servers);
+
+ //dbg
+ servers = _servers;
+
foreach_const (quarks_t, servers, it)
if (_data.get_server_limits(*it))
{
+ if(_data.get_server_xzver_support(*it)==1) std::cerr<<"xzver support on server"<<*it<<std::endl;
_server_to_minitasks[*it].push_front (group_minitask);
_high[*it] = data.get_xover_high (group, *it);
}
@@ -128,7 +172,9 @@ void
TaskXOver :: use_nntp (NNTP* nntp)
{
const Quark& server (nntp->_server);
- debug ("got an nntp from " << nntp->_server);
+
+ // test for compression
+ const bool compression (_data.get_server_xzver_support(server) == 1);
// if this is the first nntp we've gotten, ref the xover data
if (!_group_xover_is_reffed) {
@@ -156,7 +202,10 @@ TaskXOver :: use_nntp (NNTP* nntp)
case MiniTask::XOVER:
debug ("XOVER " << mt._low << '-' << mt._high << " to " << server);
_last_xover_number[nntp] = mt._low;
- nntp->xover (_group, mt._low, mt._high, this);
+ if (!compression)
+ nntp->xover (_group, mt._low, mt._high, this);
+ else
+ nntp->xzver (_group, mt._low, mt._high, this);
break;
default:
assert (0);
@@ -176,13 +225,16 @@ TaskXOver :: on_nntp_group (NNTP * nntp,
uint64_t low,
uint64_t high)
{
- const Quark& servername (nntp->_server);
+ const Quark& server (nntp->_server);
+
+ // test for compression
+ const bool compression (_data.get_server_xzver_support(server) == 1);
// new connections can tickle this...
- if (_servers_that_got_xover_minitasks.count(servername))
+ if (_servers_that_got_xover_minitasks.count(server))
return;
- _servers_that_got_xover_minitasks.insert (servername);
+ _servers_that_got_xover_minitasks.insert (server);
debug ("got GROUP result from " << nntp->_server << " (" << nntp << "): "
<< " qty " << qty
@@ -210,14 +262,24 @@ TaskXOver :: on_nntp_group (NNTP * nntp,
{
//std::cerr << LINE_ID << " okay, I'll try to get articles in [" << l << "..." << h << ']' << std::endl;
add_steps (h-l);
- const int INCREMENT (1000);
- MiniTasks_t& minitasks (_server_to_minitasks[servername]);
+
+ int INCREMENT(0);
+
+ if (!compression)
+ INCREMENT = 1000;
+ else
+ INCREMENT = 10000;
+
+ MiniTasks_t& minitasks (_server_to_minitasks[server]);
for (uint64_t m=l; m<=h; m+=INCREMENT) {
MiniTask mt (MiniTask::XOVER, m, m+INCREMENT);
- debug ("adding MiniTask for " << servername << ": xover [" << mt._low << '-' << mt._high << ']');
+ debug ("adding MiniTask for " << server << ": xover [" << mt._low << '-' << mt._high << ']');
minitasks.push_front (mt);
++_total_minitasks;
}
+ // give server its stream
+
+
}
else
{
@@ -267,6 +329,25 @@ void
TaskXOver :: on_nntp_line (NNTP * nntp,
const StringView & line)
{
+ const bool compression (_data.get_server_xzver_support(nntp->_server) == 1);
+ if (!compression)
+ on_nntp_line_process(nntp,line);
+ else {
+ _streams[nntp->_server] += line.str;
+ _bytes_so_far += line.len;
+
+ // emit a status update
+ uint64_t& prev = _last_xover_number[nntp];
+ increment_step (1);
+ if (!(_parts_so_far % 500))
+ set_status_va (_("%s (%lu parts, %lu articles)"), _short_group_name.c_str(), _parts_so_far, _articles_so_far);
+ }
+}
+
+void
+TaskXOver :: on_nntp_line_process (NNTP * nntp,
+ const StringView & line)
+{
pan_return_if_fail (nntp != 0);
pan_return_if_fail (!nntp->_server.empty());
pan_return_if_fail (!nntp->_group.empty());
@@ -348,11 +429,12 @@ TaskXOver :: on_nntp_line (NNTP * nntp,
void
TaskXOver :: on_nntp_done (NNTP * nntp,
Health health,
- const StringView & response UNUSED)
+ const StringView & response)
{
- //std::cerr << LINE_ID << " nntp " << nntp->_server << " (" << nntp << ") done; checking in. health==" << health << std::endl;
- update_work (true);
- check_in (nntp, health);
+
+ std::cerr<<"nntp done on server "<<nntp->_server<<std::endl;
+ update_work (true);
+ check_in (nntp, health);
}
void
@@ -362,6 +444,8 @@ TaskXOver :: update_work (bool subtract_one_from_nntp_count)
if (subtract_one_from_nntp_count)
--nntp_count;
+ std::cerr<<"update work "<<std::endl;
+
// find any servers we still need
quarks_t servers;
foreach_const (server_to_minitasks_t, _server_to_minitasks, it)
@@ -375,14 +459,20 @@ TaskXOver :: update_work (bool subtract_one_from_nntp_count)
else if (nntp_count)
_state.set_working ();
else {
- _state.set_completed ();
- set_finished (OK);
+ foreach_const (stream_t, _streams, it)
+ {
+ decompress(it->first, it->second);
+// feed_lines(_stream);
+ }
+ _state.set_completed ();
+ set_finished (OK);
}
}
unsigned long
TaskXOver :: get_bytes_remaining () const
{
+ return 0ul;
unsigned int minitasks_left (0);
foreach_const (server_to_minitasks_t, _server_to_minitasks, it)
minitasks_left += it->second.size();
@@ -391,5 +481,6 @@ TaskXOver :: get_bytes_remaining () const
if (percent_done < 0.1) // impossible to estimate
return 0;
const unsigned long total_bytes = (unsigned long)(_bytes_so_far / percent_done);
+ std::cerr<<std::endl<<"bytes remaining: "<<total_bytes - _bytes_so_far<<", percent: "<<percent_done<<std::endl;
return total_bytes - _bytes_so_far;
}
diff --git a/pan/tasks/task-xover.h b/pan/tasks/task-xover.h
index 8701808..8b63163 100644
--- a/pan/tasks/task-xover.h
+++ b/pan/tasks/task-xover.h
@@ -22,10 +22,15 @@
#include <map>
#include <vector>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <pan/general/log.h>
#include <pan/data/data.h>
#include <pan/tasks/task.h>
#include <pan/tasks/nntp.h>
+#include <pan/general/file-util.h>
namespace pan
{
@@ -48,6 +53,7 @@ namespace pan
private: // NNTP::Listener
virtual void on_nntp_line (NNTP*, const StringView&);
+ virtual void on_nntp_line_process (NNTP*, const StringView&);
virtual void on_nntp_done (NNTP*, Health, const StringView&);
virtual void on_nntp_group (NNTP*, const Quark&, unsigned long, uint64_t, uint64_t);
@@ -61,7 +67,9 @@ namespace pan
};
typedef std::deque<MiniTask> MiniTasks_t;
typedef std::map<Quark,MiniTasks_t> server_to_minitasks_t;
+ typedef std::map<Quark,std::string> stream_t;
server_to_minitasks_t _server_to_minitasks;
+ stream_t _streams;
private: // implementation
Data& _data;
@@ -80,6 +88,10 @@ namespace pan
unsigned long _parts_so_far;
unsigned long _articles_so_far;
unsigned long _total_minitasks;
+ unsigned long _need_decompress;
+ std::stringstream _stream;
+ quarks_t _servers; // dbg
+
};
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]