[pan2/testing: 67/279] bla
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 67/279] bla
- Date: Sat, 3 Dec 2011 22:29:04 +0000 (UTC)
commit d9c273c0e4da798995ae0104f165a7f4d53d8faf
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Mon May 30 12:18:42 2011 +0200
bla
pan/data-impl/headers.cc | 10 ++--
pan/general/file-util.cc | 49 +++++++++++++-
pan/general/file-util.h | 2 +
pan/gui/gui.cc | 6 ++
pan/gui/post-ui.cc | 171 ++++++++++++++++++++++++++++++++-------------
pan/gui/post-ui.h | 19 +++++-
pan/tasks/decoder.cc | 4 +-
pan/tasks/encoder.cc | 9 +--
pan/tasks/encoder.h | 1 +
pan/tasks/nzb.cc | 29 ++++----
pan/tasks/task-article.cc | 4 +-
pan/tasks/task-upload.cc | 147 +++++++++++++++++++++++----------------
pan/tasks/task-upload.h | 25 ++++---
uulib/uuencode.c | 5 +-
14 files changed, 324 insertions(+), 157 deletions(-)
---
diff --git a/pan/data-impl/headers.cc b/pan/data-impl/headers.cc
index b8d5127..dbe20c3 100644
--- a/pan/data-impl/headers.cc
+++ b/pan/data-impl/headers.cc
@@ -117,7 +117,7 @@ DataImpl :: GroupHeaders :: remove_articles (const quarks_t& mids)
(*it)->_article = 0;
_dirty = true;
}
-
+
const DataImpl :: GroupHeaders*
DataImpl :: get_group_headers (const Quark& group) const
{
@@ -239,7 +239,7 @@ void
DataImpl :: load_article (const Quark & group,
Article * article,
const StringView & references)
-
+
{
#if 0
std::cerr << LINE_ID << " adding article "
@@ -371,7 +371,7 @@ DataImpl :: get_references (const Quark& group, const Article& a) const
s.insert (0, v.str, v.len);
node = node->parent;
}
-std::cerr << "article " << a.message_id << " references " << s << std::endl;
+// std::cerr << "article " << a.message_id << " references " << s << std::endl;
return s;
}
#endif
@@ -463,7 +463,7 @@ DataImpl :: load_headers (const DataIO & data_io,
Xref::targets_t targets;
std::vector<Xref::Target>& targets_v (targets.get_container());
-
+
// each article in this group...
unsigned int expire_count (0);
in->getline (line);
@@ -1094,7 +1094,7 @@ DataImpl :: delete_articles (const unique_articles_t& articles)
// remove the articles from our lookup table...
GroupHeaders * h (get_group_headers (group));
- if (h)
+ if (h)
h->remove_articles (it->second.mids);
}
diff --git a/pan/general/file-util.cc b/pan/general/file-util.cc
index 1a90d89..2d650d6 100644
--- a/pan/general/file-util.cc
+++ b/pan/general/file-util.cc
@@ -31,6 +31,8 @@ extern "C"
#include <glib.h>
#include <glib/gi18n.h>
+
+ #include <dirent.h>
}
#include "debug.h"
@@ -54,10 +56,55 @@ file :: get_uulib_path()
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);
+ if (pch) g_free (pch);
return path;
}
+/// TODO perhaps implement another cache for uulib files ??
+// delete cached files to avoid "disk full" problems
+void
+file :: uulib_cache_clear ()
+{
+ DIR *dp;
+ struct dirent *ep;
+ struct stat st;
+ const char * dir = get_uulib_path().c_str();
+ std::cerr<<"opening dir : "<<dir<<std::endl;
+ dp = opendir (dir);
+ if (dp != NULL)
+ {
+ while (ep = readdir (dp))
+ {
+ stat(ep->d_name, &st);
+ if (S_ISDIR(st.st_mode) == 0) {
+ std::cerr<<"deleting file :"<<ep->d_name<<"\n";
+ unlink(ep->d_name);
+ }
+ }
+ (void) closedir (dp);
+ } else
+ std::cerr<<"error clearing uulib cache!\n";
+}
+
+// void clear_cached_range (const char* file)
+// {
+// DIR *dp;
+// struct dirent *ep;
+// struct stat st;
+// const char * dir = file :: get_uulib_path().c_str();
+// dp = opendir (dir);
+// if (dp != NULL)
+// {
+// while (ep = readdir (dp))
+// {
+// stat(ep->d_name, &st);
+// if (S_ISDIR(st.st_mode) == 0 && strstr(file,ep->d_name))
+// unlink(ep->d_name);
+// }
+// (void) closedir (dp);
+// }
+// }
+
std::string
file :: get_pan_home ()
{
diff --git a/pan/general/file-util.h b/pan/general/file-util.h
index 25bde1c..1d43bf0 100644
--- a/pan/general/file-util.h
+++ b/pan/general/file-util.h
@@ -60,6 +60,8 @@ namespace pan
std::string get_uulib_path();
+ void uulib_cache_clear();
+
/**
* If the specified directory doesn't exist, Pan tries to create it.
* @param path
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index bfce0ae..5350434 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -26,6 +26,7 @@ extern "C" {
#include <sys/types.h> // for chmod
#include <sys/stat.h> // for chmod
#include <glib/gi18n.h>
+ #include <dirent.h>
}
#include <pan/general/debug.h>
#include <pan/general/e-util.h>
@@ -184,6 +185,11 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, Prefs& prefs, GroupPr
_queue_size_button (0),
_taskbar (0)
{
+
+ //clear uulib encode cache
+ ///TODO perhaps remember by crc32-ptr and then assign already saved parts??
+// file :: uulib_cache_clear();
+
char * filename = g_build_filename (file::get_pan_home().c_str(), "pan.ui", NULL);
if (!gtk_ui_manager_add_ui_from_file (_ui_manager, filename, NULL))
gtk_ui_manager_add_ui_from_string (_ui_manager, fallback_ui_file, -1, NULL);
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 4a9300c..18a4ea2 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -2033,8 +2033,42 @@ PostUI :: create_filequeue_tab ()
return vbox;
}
+void
+PostUI:: on_parts_box_clicked_cb (GtkCellRendererToggle *cell, gchar *path_str, gpointer user_data)
+{
+ PostUI* data(static_cast<PostUI*>(user_data));
+ GtkWidget * w = data->parts_store() ;
+ GtkListStore *store = GTK_LIST_STORE(
+ gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
+ GtkTreeModel * model = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
+ int part(42);
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ gboolean enabled;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+
+ gtk_tree_model_get (model, &iter, 0, &part, 1, &enabled, -1);
+
+ enabled ^= 1;
+ if (enabled==0)
+ data->upload_ptr()->needed().erase(part);
+ else
+ {
+ TaskUpload::Needed tmp;
+ tmp.partno = part;
+ tmp.partial = true;
+ data->upload_ptr()->needed().insert(std::pair<int, TaskUpload::Needed>(part,tmp));
+
+ }
+ gtk_list_store_set(GTK_LIST_STORE( model ), &iter, 1, false, -1);
+ gtk_tree_path_free (path);
+ data->update_parts_tab();
+}
+
+
GtkWidget*
-PostUI :: create_parts_tab (TaskUpload* ptr)
+PostUI :: create_parts_tab ()
{
const GtkAttachOptions fill ((GtkAttachOptions)(GTK_FILL));
@@ -2047,69 +2081,83 @@ PostUI :: create_parts_tab (TaskUpload* ptr)
GtkWidget *t = gtk_table_new (8, 2, false);
gtk_table_set_col_spacings (GTK_TABLE(t), PAD);
- ++row; //empty line
+ ++row; //1
l = gtk_label_new (NULL);
gtk_table_attach (GTK_TABLE(t), l, 0, 2, row, row+1, fe, fill, 0, 0);
- ++row; //1
+ ++row; //2
g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("Filename"));
l = gtk_label_new (buf);
gtk_label_set_use_markup (GTK_LABEL(l), true);
gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
gtk_table_attach (GTK_TABLE(t), l, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
- g_snprintf (buf, sizeof(buf), "%s", ptr->basename().c_str());
+ g_snprintf (buf, sizeof(buf), "%s", _upload_ptr->basename().c_str());
l = gtk_label_new (buf);
gtk_misc_set_alignment (GTK_MISC(l), 0.5f, 0.5f);
gtk_widget_set_tooltip_text (l, _("The current filename"));
gtk_table_attach (GTK_TABLE(t), l, 1, 2, row, row+1, fe, fill, 0, 0);
- ++row; //2
+ ++row; //3
g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("Subject Line"));
l = gtk_label_new (buf);
gtk_label_set_use_markup (GTK_LABEL(l), true);
gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
gtk_table_attach (GTK_TABLE(t), l, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
- g_snprintf (buf, sizeof(buf), "%s", ptr->subject().c_str());
+ g_snprintf (buf, sizeof(buf), "%s", _upload_ptr->subject().c_str());
l = gtk_label_new (buf);
gtk_misc_set_alignment (GTK_MISC(l), 0.5f, 0.5f);
gtk_widget_set_tooltip_text (l, _("The current Subject Line"));
gtk_table_attach (GTK_TABLE(t), l, 1, 2, row, row+1, fe, fill, 0, 0);
- ++row; //3
+ ++row; //4
g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("Lines / File"));
l = gtk_label_new (buf);
gtk_label_set_use_markup (GTK_LABEL(l), true);
gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
gtk_table_attach (GTK_TABLE(t), l, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
- //todo make generic!!
+ ///TODO make generic!!
g_snprintf (buf, sizeof(buf), "%d", 4000);
l = gtk_label_new_with_mnemonic (buf);
gtk_misc_set_alignment (GTK_MISC(l), 0.5f, 0.5f);
gtk_widget_set_tooltip_text (l, _("The current Number of Lines per File"));
gtk_table_attach (GTK_TABLE(t), l, 1, 2, row, row+1, fe, fill, 0, 0);
- //4
+ ++row; // 5
+ g_snprintf (buf, sizeof(buf), "<b>%s:</b>", _("Parts"));
+ l = gtk_label_new (buf);
+ gtk_label_set_use_markup (GTK_LABEL(l), true);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+ gtk_table_attach (GTK_TABLE(t), l, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
+ g_snprintf (buf, sizeof(buf), "%d", _total_parts);
+ l = gtk_label_new_with_mnemonic (buf);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.5f, 0.5f);
+ gtk_widget_set_tooltip_text (l, _("The current Number of Parts of the queued File"));
+ gtk_table_attach (GTK_TABLE(t), l, 1, 2, row, row+1, fe, fill, 0, 0);
+
+ //6
++row;
l = gtk_label_new (NULL);
gtk_table_attach (GTK_TABLE(t), l, 0, 2, row, row+1, fe, fill, 0, 0);
- //5
+ //7
++row;
- gtk_table_attach (GTK_TABLE(gtk_hseparator_new()), l, 0, 2, row, row+1, fe, fill, 0, 0);
-
- // 6
+ // 8
//treeview for parts list
- w = _parts_store = gtk_tree_view_new_with_model (GTK_TREE_MODEL(gtk_list_store_new (2, G_TYPE_BOOLEAN, G_TYPE_STRING)));
+ w = _parts_store = gtk_tree_view_new_with_model (GTK_TREE_MODEL(gtk_list_store_new (3, G_TYPE_UINT, G_TYPE_BOOLEAN, G_TYPE_STRING)));
// add columns
- renderer = gtk_cell_renderer_toggle_new();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), 0,
- (_("Part No.")),renderer,"active", 1,NULL);
renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), 0,
+ (_("No. ")),renderer,"text", 0,NULL);
+ renderer = gtk_cell_renderer_toggle_new();
+ g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK(on_parts_box_clicked_cb), this);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), 1,
- (_("Filename")),renderer,"text", 1,NULL);
+ (_("Enable/Disable")),renderer,"active", 1,NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), 2,
+ (_("Filename")),renderer,"text", 2,NULL);
//set hint and selection
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(w),TRUE);
@@ -2120,14 +2168,10 @@ PostUI :: create_parts_tab (TaskUpload* ptr)
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(w), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(w), GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER(w), _parts_store);
- ++row; //todo
- gtk_table_attach (GTK_TABLE(t), w, 0, 2, row, row+2, fe, fill, 0, 0);
-
- //7: OK and close Buttons
++row;
+ gtk_table_attach (GTK_TABLE(t), w, 0, 2, row, row+1, fe, fill, 0, 0);
return t;
-
}
GtkWidget*
@@ -2249,7 +2293,10 @@ PostUI :: remove_files (void)
tasks_set tasks = get_selected_files();
tasks_set::iterator nit;
for (nit = tasks.begin(); nit != tasks.end();nit, ++nit)
- _file_queue_tasks.erase(*nit);
+ {
+ delete (*nit);
+ _file_queue_tasks.erase(*nit);
+ }
update_filequeue_tab();
}
@@ -2339,18 +2386,21 @@ PostUI :: ~PostUI ()
g_object_unref (G_OBJECT(_message));
}
+
+
void
PostUI :: select_parts ()
{
- TaskUpload* ptr(0);
tasks_set set(get_selected_files());
- ptr = *set.begin();
+ _upload_ptr = *set.begin();
+
+ if (!_upload_ptr) return;
+
+ _total_parts = (int) (((long)_upload_ptr->get_byte_count() + (4000*128-1)) / (4000*128));
+
GtkWidget * w;
GtkTreeIter iter;
- const int total = (int) (((long)ptr->get_byte_count() + (4000*128-1)) / (4000*128));
-
- std::cerr<<total<<std::endl;
w = _part_select = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (_part_select, "delete-event", G_CALLBACK(delete_parts_cb), this);
@@ -2358,7 +2408,7 @@ PostUI :: select_parts ()
gtk_window_set_title (GTK_WINDOW(w), _("Select Parts"));
int x,h;
x = 350;
- h = 450;
+ h = 650;
gtk_window_set_default_size (GTK_WINDOW(w), x, h);
// populate the window
@@ -2366,25 +2416,34 @@ PostUI :: select_parts ()
gtk_container_add (GTK_CONTAINER(w), vbox);
GtkWidget * notebook = gtk_notebook_new ();
- gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_parts_tab(ptr), gtk_label_new_with_mnemonic(_("_Parts")));
- gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_log_tab(), gtk_label_new_with_mnemonic(_("_Log")));
+ gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_parts_tab(), gtk_label_new_with_mnemonic(_("_Parts")));
+// gtk_notebook_append_page (GTK_NOTEBOOK(notebook), create_log_tab(), gtk_label_new_with_mnemonic(_("_Log")));
pan_box_pack_start_defaults (GTK_BOX(vbox), notebook);
- //populate parts tab
- GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(_parts_store)));
- for (int i=1;i<=total+100;++i)
+ gtk_widget_show_all (w);
+ update_parts_tab();
+
+}
+
+void
+PostUI :: update_parts_tab()
+{
+ GtkWidget * w = _parts_store ;
+ GtkListStore *store = GTK_LIST_STORE(
+ gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
+ GtkTreeIter iter;
+ gtk_list_store_clear(store);
+ gboolean res(FALSE);
+
+ for (int i=1;i<=_total_parts;++i)
{
gtk_list_store_append (store, &iter);
+ res = (_upload_ptr->_needed.find(i) != _upload_ptr->_needed.end()) ? TRUE : FALSE;
gtk_list_store_set (store, &iter,
- 0, true,
- 1, ptr->basename().c_str(), -1);
+ 0, i,
+ 1, res,
+ 2, _upload_ptr->basename().c_str(), -1);
}
-
- gtk_widget_show_all (w);
-
-
-// update_parts_tab();
-
}
PostUI :: PostUI (GtkWindow * parent,
@@ -2414,7 +2473,10 @@ PostUI :: PostUI (GtkWindow * parent,
_charset (DEFAULT_CHARSET),
_group_entry_changed_id (0),
_group_entry_changed_idle_tag (0),
- _file_queue_empty(true)
+ _file_queue_empty(true),
+ _upload_ptr(0),
+ _total_parts(0),
+ _upload_cursor(0)
{
g_assert (profiles.has_profiles());
g_return_if_fail (message != 0);
@@ -2534,13 +2596,22 @@ PostUI :: prompt_user_for_queueable_files (tasks_set& queue, GtkWindow * parent,
groups.insert(groupname);
}
- for (; cur; cur = cur->next)
+ int i(0);
+ for (; cur; cur = cur->next, ++i)
{
- TaskUpload::needed_t tmp; //todo
- _file_queue_tasks.insert( new TaskUpload(std::string((const char*)cur->data),
- profile.posting_server,
- groups, subject, author, tmp, 0,
- TaskUpload::YENC));
+ TaskUpload* tmp = new TaskUpload(std::string((const char*)cur->data),
+ profile.posting_server,
+ groups, subject, author, 0,
+ TaskUpload::YENC);
+ _file_queue_tasks.insert(tmp);
+ TaskUpload::Needed tmp2;
+ const int parts = (int) (((long)tmp->get_byte_count() + (4000*128-1)) / (4000*128));
+ for (int j=1; j<=parts; ++j)
+ {
+ tmp2.partial = true;
+ tmp2.partno = j;
+ tmp->needed().insert(needed_p(j,tmp2));
+ }
}
g_slist_free (tmp_list);
}
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index ded6d83..1973d68 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -35,7 +35,7 @@ namespace pan
class Queue;
- typedef std::multiset<TaskUpload*> tasks_set;
+ typedef std::set<TaskUpload*> tasks_set;
/**
* Dialog for posting new messages Pan's GTK GUI.
@@ -58,6 +58,7 @@ namespace pan
public:
GtkWidget * root() { return _root; }
GtkWidget * part_select() { return _part_select; }
+ GtkWidget * parts_store() { return _parts_store; }
void rot13_selection ();
void wrap_body ();
void spawn_editor ();
@@ -73,6 +74,7 @@ namespace pan
void set_wrap_mode (bool wrap);
void set_always_run_editor (bool);
void update_filequeue_tab();
+ void update_parts_tab();
//popup action entries
void remove_files ();
@@ -158,8 +160,15 @@ namespace pan
GtkWidget* create_main_tab ();
GtkWidget* create_extras_tab ();
GtkWidget* create_filequeue_tab ();
- GtkWidget* create_parts_tab (TaskUpload* ptr);
+ GtkWidget* create_parts_tab ();
GtkWidget* create_log_tab ();
+ TaskUpload* _upload_ptr;
+ int _total_parts;
+ typedef std::map<int, TaskUpload::Needed> needed_t;
+ typedef std::pair<int, TaskUpload::Needed> needed_p;
+ typedef std::vector<needed_t> needed_v;
+ needed_v _needed_v;
+ int _upload_cursor;
private:
std::string utf8ize (const StringView&) const;
@@ -194,6 +203,12 @@ namespace pan
static void top_clicked_cb (GtkButton*, PostUI*);
static void bottom_clicked_cb (GtkButton*, PostUI*);
static void delete_clicked_cb (GtkButton*, PostUI*);
+ static void on_parts_box_clicked_cb (GtkCellRendererToggle *cell, gchar *path_str, gpointer user_data);
+
+ public:
+ TaskUpload* upload_ptr() { return _upload_ptr; }
+ int cursor() { return _upload_cursor; }
+
};
}
diff --git a/pan/tasks/decoder.cc b/pan/tasks/decoder.cc
index 5e8bfa8..2295b2f 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" );
diff --git a/pan/tasks/encoder.cc b/pan/tasks/encoder.cc
index f50aa31..57c5fa1 100644
--- a/pan/tasks/encoder.cc
+++ b/pan/tasks/encoder.cc
@@ -100,7 +100,6 @@ Encoder :: do_work()
if (((res = UUInitialize())) != UURET_OK)
{
log_errors.push_back(_("Error initializing uulib")); // log error
- this->cancel();
} else {
UUSetMsgCallback (this, uu_log);
UUSetBusyCallback (this, uu_busy_poll, 100);
@@ -109,13 +108,6 @@ Encoder :: do_work()
outfile = fopen(buf,"wb");
while (1) {
- // skip not wanted parts of binary file
-// if (parts->end() != parts->find(cnt))
-// {
-// ++cnt;
-// res = UURET_CONT;
-// goto _end;
-// }
// 4000 lines SHOULD be OK for ANY nntp server ...
res = UUE_PrepPartial (outfile, NULL, (char*)filename.c_str(),YENC_ENCODED,
(char*)basename.c_str(),0644, cnt, 4000,
@@ -154,6 +146,7 @@ void
Encoder :: uu_log (void* data, char* message, int severity)
{
Encoder *self = static_cast<Encoder *>(data);
+ if (self->was_cancelled()) return;
char * pch (g_locale_to_utf8 (message, -1, 0, 0, 0));
if (severity >= UUMSG_WARNING)
diff --git a/pan/tasks/encoder.h b/pan/tasks/encoder.h
index 5808963..e31afa4 100644
--- a/pan/tasks/encoder.h
+++ b/pan/tasks/encoder.h
@@ -79,6 +79,7 @@ namespace pan
std::set<int>* parts;
friend class TaskUpload;
+ friend class PostUI;
TaskUpload * task;
TaskUpload::EncodeMode encode_mode;
std::string filename;
diff --git a/pan/tasks/nzb.cc b/pan/tasks/nzb.cc
index d8c382e..8eb5d32 100644
--- a/pan/tasks/nzb.cc
+++ b/pan/tasks/nzb.cc
@@ -51,6 +51,7 @@ namespace
TaskUpload::needed_t needed_parts; // TaskUpload
Article a;
Quark posting_server;
+ bool encoded; // encoder was done already
PartBatch parts;
tasks_t tasks;
ArticleCache& cache;
@@ -103,7 +104,6 @@ namespace
else if (!strcmp (*k,"subject")) mc.a.subject = *v;
else if (!strcmp (*k,"server")) mc.posting_server = Quark(*v);
}
- std::cerr<<"upload begin tag\n";
}
else if (!strcmp (element_name, "segment")) {
@@ -122,9 +122,7 @@ namespace
if (!strcmp (*k,"bytes")) mc.bytes = strtoul (*v,0,10);
else if (!strcmp (*k,"number")) mc.number = atoi (*v);
}
- std::cerr<<"part begin tag\n";
}
-
}
// Called for close tags </foo>
@@ -155,8 +153,9 @@ namespace
n.bytes = mc.bytes;
n.filename = mc.text;
n.partno = mc.number;
- mc.needed_parts.push_back(n);
- std::cerr<<"part end tag\n";
+ n.partial = false;
+ std::pair<int,TaskUpload::Needed> tmp(mc.number,n);
+ mc.needed_parts.insert(tmp);
}
else if (!strcmp(element_name,"path"))
@@ -181,8 +180,12 @@ namespace
else if (!strcmp (element_name, "upload"))
{
debug("adding taskupload from nzb.\n");
- mc.tasks.push_back (new TaskUpload (mc.path, const_cast<const Quark&>(mc.posting_server),
- mc.groups, mc.a.subject.to_string(), mc.a.author.to_string(), mc.needed_parts, 0, TaskUpload::YENC));
+ TaskUpload* tmp = new TaskUpload (mc.path, const_cast<const Quark&>(mc.posting_server),
+ mc.groups, mc.a.subject.to_string(), mc.a.author.to_string(), 0, TaskUpload::YENC);
+ //update needed struct
+ foreach (TaskUpload::needed_t, mc.needed_parts, it)
+ tmp->needed().insert(*it);
+ mc.tasks.push_back (tmp);
}
}
@@ -346,11 +349,7 @@ NZB :: nzb_to_xml (std::ostream & out,
out << "\" subject=\"";
escaped (out, task->_subject);
out << "\" server=\"";
- escaped (out, task->_server.to_string());
- out << "\" encoded=\"";
- char buf[3];
- g_snprintf(buf,3,"%d",(int)task->_encoder_has_run);
- escaped (out, StringView(buf)) << "\">\n";
+ escaped (out, task->_server.to_string()) << "\">\n";
++depth;
out << indent(depth)
<< "<path>" << task->_filename << "</path>\n";
@@ -367,9 +366,9 @@ NZB :: nzb_to_xml (std::ostream & out,
foreach_const (TaskUpload::needed_t, task->_needed, it)
out << indent(depth)
- << "<part" << " bytes=\"" << (*it).bytes << '"'
- << " number=\"" << (*it).partno << '"'
- << ">" << (*it).filename<< "</part>\n";
+ << "<part" << " bytes=\"" << (*it).second.bytes << '"'
+ << " number=\"" << (*it).second.partno << '"'
+ << ">" << (*it).second.filename<< "</part>\n";
--depth;
out << indent(depth) << "</parts>\n";
--depth;
diff --git a/pan/tasks/task-article.cc b/pan/tasks/task-article.cc
index 3c77f7b..e529d52 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-upload.cc b/pan/tasks/task-upload.cc
index 0728fe9..0f62983 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -27,7 +27,7 @@
#include <sstream>
#include <iostream>
#include <fstream>
-
+#include <cstdio>
extern "C" {
#include <glib/gi18n.h>
}
@@ -44,14 +44,31 @@ using namespace pan;
namespace
{
- std::string get_description (const char* name, bool enc)
+ std::string get_description (const char* name)
{
char buf[1024];
- if (!enc)
- snprintf (buf, sizeof(buf), _("Uploading %s"), name);
- else
- snprintf (buf, sizeof(buf), _("Encoding %s"), name);
- return std::string (buf);
+ char * freeme = g_path_get_basename(name);
+ snprintf (buf, sizeof(buf), _("Uploading %s"), freeme);
+ g_free(freeme);
+ return buf;
+ }
+
+ std::string get_basename(const char* f)
+ {
+ char buf[1024];
+ char * freeme = g_path_get_basename(f);
+ snprintf (buf, sizeof(buf), _("%s"), freeme);
+ g_free(freeme);
+ return buf;
+ }
+}
+
+
+namespace
+{
+ void delete_cache(const TaskUpload::Needed& n)
+ {
+ unlink(n.filename.c_str());
}
}
@@ -64,20 +81,18 @@ TaskUpload :: TaskUpload ( const std::string & filename,
quarks_t & groups,
std::string subject,
std::string author,
- needed_t & todo,
Progress::Listener * listener,
const TaskUpload::EncodeMode enc):
- Task ("UPLOAD", get_description(filename.c_str(), true)),
+ Task ("UPLOAD", get_description(filename.c_str())),
_filename(filename),
- _basename (std::string(g_path_get_basename(filename.c_str()))),
+ _basename (g_path_get_basename(filename.c_str())),
_server(server),
_groups(groups),
_subject (subject),
_author(author),
_encoder(0),
_encoder_has_run (false),
- _encode_mode(enc),
- _extern(todo)
+ _encode_mode(enc)
{
if (listener != 0)
add_listener (listener);
@@ -85,7 +100,6 @@ TaskUpload :: TaskUpload ( const std::string & filename,
struct stat sb;
stat(filename.c_str(),&sb);
_bytes = sb.st_size;
-
update_work ();
}
@@ -95,7 +109,7 @@ TaskUpload :: update_work (NNTP* checkin_pending)
int working(0);
foreach (needed_t, _needed, nit) {
- Needed& n (*nit);
+ Needed& n (nit->second);
if (n.nntp && n.nntp!=checkin_pending)
++working;
}
@@ -126,8 +140,8 @@ TaskUpload :: use_nntp (NNTP * nntp)
Needed * needed (0);
for (needed_t::iterator it(_needed.begin()), end(_needed.end()); !needed && it!=end; ++it)
- if (it->nntp==0)
- needed = &*it;
+ if (it->second.nntp==0)
+ needed = &it->second;
if (!needed)
{
@@ -159,16 +173,6 @@ TaskUpload :: on_nntp_line (NNTP * nntp,
const StringView & line_in)
{}
-
-// delete cached files to avoid "disk full" problems
-namespace
-{
- void delete_cache(const TaskUpload::Needed& n)
- {
- unlink(n.filename.c_str());
- }
-}
-
void
TaskUpload :: on_nntp_done (NNTP * nntp,
Health health,
@@ -177,10 +181,20 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
needed_t::iterator it;
for (it=_needed.begin(); it!=_needed.end(); ++it)
- if (it->nntp == nntp)
+ if (it->second.nntp == nntp)
break;
- bool post_ok(false);
+ switch (health)
+ {
+ case OK:
+ break;
+ /* if the connection was aborted with SIGPIPE, let this error silently by and
+ * let GIOSocket code handle this */
+ case ERR_NETWORK:
+ std::cerr<<"err network!\n";
+ it->second.reset();
+ goto _end;
+ }
switch (atoi(response.str))
{
@@ -192,7 +206,12 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
Log :: add_err_va (_("Posting of file %s failed: %s"), _basename.c_str(), response.str);
break;
case ARTICLE_POSTED_OK:
- post_ok = true;
+ delete_cache(it->second);
+ _needed.erase (it);
+ increment_step(1);
+ if (_needed.empty())
+ Log :: add_info_va(_("Posting of file %s succesful: %s"),
+ _basename.c_str(), response.str);
break;
case TOO_MANY_CONNECTIONS:
// lockout for 120 secs, but try
@@ -203,23 +222,8 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
break;
}
- switch (health)
- {
- case OK:
- delete_cache(*it);
- _needed.erase (it);
- if (_needed.empty() && post_ok)
- Log :: add_info_va(_("Posting of file %s succesful: %s"),
- _basename.c_str(), response.str);
- break;
-
- case ERR_NETWORK:
- _state.set_need_nntp(nntp->_server);
- break;
- }
-
- update_work();
- increment_step(1);
+ _end:
+ update_work(nntp);
check_in (nntp, health);
}
@@ -233,7 +237,7 @@ TaskUpload :: get_bytes_remaining () const
{
unsigned long bytes (0);
foreach_const (needed_t, _needed, it)
- bytes += it->bytes;
+ bytes += it->second.bytes;
return bytes;
}
@@ -263,8 +267,8 @@ TaskUpload :: use_encoder (Encoder* encoder)
void
TaskUpload :: stop ()
{
- if (_encoder)
- _encoder->cancel();
+// if (_encoder)
+// _encoder->cancel();
}
// called in the main thread by WorkerPool
@@ -286,12 +290,20 @@ TaskUpload :: on_worker_done (bool cancelled)
foreach_const(Encoder::log_t, _encoder->log_infos, it)
Log :: add_info(it->c_str());
+ int num_errors = _encoder->log_severe.size() +
+ _encoder->log_errors.size();
+
if (!_encoder->log_errors.empty())
set_error (_encoder->log_errors.front());
- if (!_encoder->log_severe.empty())
- _state.set_health (ERR_LOCAL);
- else {
+ if (num_errors>0)
+ {
+ /* stop state if encoder has encountered errors */
+ _state.set_completed ();
+ set_finished(ERR_LOCAL);
+ }
+ else
+ {
set_step (100);
_encoder_has_run = true;
_total_parts = _encoder->total_parts;
@@ -304,20 +316,37 @@ TaskUpload :: on_worker_done (bool cancelled)
char buf[2048];
struct stat sb;
- for (int i=1; i<=_total_parts; ++i)
+ int total(0);
+ /* not found: skip, we don't need that part
+ found: if (partial) then assign the needed values
+ */
+ for (int i=1; i<=_total_parts; ++i)
+ {
+ needed_t::iterator it = _needed.find(i);
+ if (it == _needed.end())
+ continue;
+ else if (it->second.partial)
{
n.partno = i;
g_snprintf(buf,sizeof(buf),"%s/%s.%d",
- file::get_uulib_path().c_str(),
- _basename.c_str(), i);
+ file::get_uulib_path().c_str(),
+ _basename.c_str(), i);
n.filename = buf;
stat(buf, &sb);
n.bytes = sb.st_size;
- _needed.push_back (n);
}
-
- init_steps (_total_parts);
- set_step (0);
+ ++total;
+ }
+
+ if (total==0)
+ {
+ _state.set_completed();
+ set_finished(OK);
+ } else
+ {
+ init_steps (_total_parts);
+ set_step (total);
+ }
}
}
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index 7a7b1fd..edd309c 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -53,10 +53,12 @@ namespace pan
unsigned long bytes;
int partno;
NNTP* nntp;
- Needed (): nntp(0) {}
+ bool partial;
+ Needed (): nntp(0), bytes(0) , partial(false) {}
+ void reset() { nntp = 0; }
};
- typedef std::deque<Needed> needed_t;
+ typedef std::map<int, Needed> needed_t;
enum EncodeMode
{
@@ -71,7 +73,6 @@ namespace pan
quarks_t & groups,
std::string subject,
std::string author,
- needed_t & todo,
Progress::Listener * listener= 0,
TaskUpload::EncodeMode enc= YENC);
virtual ~TaskUpload ();
@@ -83,14 +84,15 @@ namespace pan
const std::string& filename() { return _filename; }
const std::string& subject () { return _subject; }
unsigned long get_byte_count() { return _bytes; }
+ needed_t& needed() { return _needed; }
- /** only call this for tasks in the NEED_DECODE state
- * attempts to acquire the saver thread and start saving
- * returns false if failed or true if the save process started
+ /** only call this for tasks in the NEED_ENCODE state
+ * attempts to acquire the encoder thread and start encoding
+ * returns false if failed or true if the encoding process started
* (intended to be used with the Queue class). If true is returned,
- * a side-effect is that the task is now in the DECODING state.
+ * a side-effect is that the task is now in the ENCODING state.
*/
- virtual void use_encoder (Encoder*);
+ virtual void use_encoder (Encoder*);
private: // Task subclass
virtual void use_nntp (NNTP * nntp);
@@ -107,6 +109,7 @@ namespace pan
private: // implementation
friend class Encoder;
+ friend class PostUI;
friend class NZB;
Encoder * _encoder;
bool _encoder_has_run;
@@ -118,13 +121,13 @@ namespace pan
int _total_parts; // filled in by encoder
unsigned long _bytes;
Mutex mut;
+ int _pos_in_queue;
+ char* _tmp; // for g_path etc...
private:
needed_t _needed;
- needed_t _extern;
- std::set<int> _parts;
-
void update_work (NNTP * checkin_pending = 0);
+
};
// from mime-utils.cc
diff --git a/uulib/uuencode.c b/uulib/uuencode.c
index 2d985a2..b57e389 100644
--- a/uulib/uuencode.c
+++ b/uulib/uuencode.c
@@ -1779,12 +1779,13 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile,
_FP_free (subline);
+ /* pan change (imhotep): these could lead to SIGSEV, so I changed them to check for NULL pointers */
if (infile==NULL) {
- if (res != UURET_OK) {
+ if (res != UURET_OK && theifile) {
fclose (theifile);
return res;
}
- if (feof (theifile)) {
+ if (feof (theifile) && theifile) {
fclose (theifile);
return UURET_OK;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]