[pan2/testing: 171/279] theading is now: (original post) +-- reply with body +-- file 1 +-- file 2 . . .
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 171/279] theading is now: (original post) +-- reply with body +-- file 1 +-- file 2 . . .
- Date: Sat, 3 Dec 2011 22:36:32 +0000 (UTC)
commit cf38fefbfc3a0678e27a75dba38363c0544f1148
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Mon Jul 18 09:57:00 2011 +0200
theading is now:
(original post)
+-- reply with body
+-- file 1
+-- file 2
.
.
.
+-- last file
for all the other files the message body is discarded.
pan.cbp | 2 +
pan/gui/gui.cc | 16 ++--
pan/gui/post-ui.cc | 98 +++++++++++++----------
pan/gui/post-ui.h | 6 +-
pan/gui/prefs-ui.cc | 19 +++--
pan/tasks/Makefile.am | 2 +
pan/tasks/encoder.cc | 10 +--
pan/tasks/encoder.h | 4 +-
pan/tasks/task-multipost.cc | 181 +++++++++++++++++++++++++++++++++++++++++++
pan/tasks/task-multipost.h | 122 +++++++++++++++++++++++++++++
pan/tasks/task-upload.cc | 83 +++++++++++--------
pan/tasks/task-upload.h | 28 +++++--
uulib/uuencode.c | 2 -
13 files changed, 455 insertions(+), 118 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index 3c1517b..4c546b9 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -227,6 +227,8 @@
<Unit filename="pan/tasks/task-article.h" />
<Unit filename="pan/tasks/task-groups.cc" />
<Unit filename="pan/tasks/task-groups.h" />
+ <Unit filename="pan/tasks/task-multipost.cc" />
+ <Unit filename="pan/tasks/task-multipost.h" />
<Unit filename="pan/tasks/task-post.cc" />
<Unit filename="pan/tasks/task-post.h" />
<Unit filename="pan/tasks/task-upload.cc" />
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 48e7bfa..cc22eb3 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -170,9 +170,9 @@ namespace
};
static GtkTargetEntry target_list[] = {
- { "STRING", 0, TARGET_STRING },
- { "text/plain", 0, TARGET_STRING },
- { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
+ { const_cast<char*>("STRING"), 0, TARGET_STRING },
+ { const_cast<char*>("text/plain"), 0, TARGET_STRING },
+ { const_cast<char*>("application/x-rootwindow-drop"), 0, TARGET_ROOTWIN }
};
}
@@ -276,11 +276,11 @@ GUI :: GUI (Data& data, Queue& queue, ArticleCache& cache, EncodeCache& encode_c
g_signal_connect (w, "clicked", G_CALLBACK(show_task_window_cb), this);
// drag and drop for message-ids
-// gtk_drag_dest_set(w,GTK_DEST_DEFAULT_ALL,target_list,3,GDK_ACTION_COPY);
-// gtk_drag_dest_add_text_targets(w);
-// gtk_drag_dest_add_uri_targets(w);
-// g_signal_connect (w, "drag-data-received", G_CALLBACK(dragged_rcvd), this);
-// g_signal_connect (w, "drag-drop", G_CALLBACK (dragged), this);
+// gtk_drag_dest_set(_workarea_bin,GTK_DEST_DEFAULT_ALL,target_list,3,GDK_ACTION_COPY);
+// gtk_drag_dest_add_text_targets(_workarea_bin);
+// gtk_drag_dest_add_uri_targets(_workarea_bin);
+// g_signal_connect (_workarea_bin, "drag-data-received", G_CALLBACK(dragged_rcvd), this);
+// g_signal_connect (_workarea_bin, "drag-drop", G_CALLBACK (dragged), this);
gtk_container_add (GTK_CONTAINER(w), _queue_size_label);
frame = gtk_frame_new (NULL);
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 20d5c02..1b71f9c 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -927,7 +927,10 @@ PostUI :: maybe_mail_message (GMimeMessage * message)
void
PostUI :: on_progress_finished (Progress&, int status) // posting finished
{
- bool close(false);
+
+ std::cerr<<"status "<<status<<std::endl;
+ if (status==-1) { --_running_uploads; return; }
+
if (_file_queue_empty)
{
_post_task->remove_listener (this);
@@ -939,23 +942,24 @@ PostUI :: on_progress_finished (Progress&, int status) // posting finished
gtk_widget_destroy (_post_dialog);
} else
{
+ --_running_uploads;
+ int no = status;
+ TaskUpload * ptr = _upload_queue[no];
+
if (!_save_file.empty())
{
mut.lock();
- int no = status;
- TaskUpload * ptr = _upload_queue[no];
if (ptr) NZB :: upload_list_to_xml_file (_out, ptr->_upload_list);
- --_running_uploads;
if (_running_uploads==0 )
{
_out << "</nzb>\n";
_out.close();
- close = true;
}
mut.unlock();
- if (close) close_window(true);
}
+
}
+ if (_running_uploads==0) close_window(true);
}
void
@@ -1074,7 +1078,6 @@ PostUI :: maybe_post_message (GMimeMessage * message)
_upload_queue.get_all_tasks(tasks);
int cnt(0);
char buf[2048];
- int lpf = _prefs.get_int("upload-option-bpf",1024*512);
struct stat sb;
_running_uploads = tasks.size();
@@ -1085,9 +1088,33 @@ PostUI :: maybe_post_message (GMimeMessage * message)
d = !profile.fqdn.empty()
? GNKSA::generate_message_id (profile.fqdn)
: GNKSA::generate_message_id_from_email_address (profile.address);
- StringView domain(d);
+ StringView d2(d);
+ StringView domain;
+ const char * pch = d2.strchr ('@');
+ if (pch != NULL)
+ domain = d2.substr (pch+1, NULL);
+ else
+ domain = d2;
- /// TODO maybe update tasks' msg headers here ???
+ std::string last_mid;
+ std::string first_mid;
+
+ // dummy taskupload for master article without attachment, dbg!!
+ const Profile profile (get_current_profile ());
+ std::string out;
+ generate_unique_id(domain, 1,out);
+ first_mid = out;
+ Article a(tasks[0]->_article);
+
+ TaskUpload::UploadInfo f;
+ f.total=1;
+ TaskUpload::Needed n;
+ n.mid = out;
+ TaskUpload * tmp = new TaskUpload("",profile.posting_server,_cache,a,f,new_message_from_ui(UPLOADING));
+ tmp->_needed.insert(std::pair<int, TaskUpload::Needed>(1,n));
+ tmp->_queue_pos = -1;
+ _queue.add_task (tmp, Queue::BOTTOM);
+ tmp->add_listener(this);
/* init taskupload variables before adding the tasks to the queue for processing */
foreach (PostUI::tasks_t, tasks, it)
@@ -1099,39 +1126,24 @@ PostUI :: maybe_post_message (GMimeMessage * message)
TaskUpload::Needed n;
// generate domain for rng numbers
- int total = get_total_parts(t->_filename.c_str(), t);
- StringView d;
- const char * pch = domain.strchr ('@');
- if (pch != NULL)
- d = domain.substr (pch+1, NULL);
- else
- d = domain;
-
- // generate rng number for message-ids
- // compose subject lines
- // build needed struct for upload
- // set queue position for listeners
- // start queue and initialize listeners
- // NOTE: the postui class won't be destroyed after that, because we need some data from it
- // (for example for saving the nzb file). it will be hidden and destroyed on destruction of
- // the last Taskupload task.
- // (perhaps this could be changed if we added a listener for this in gui.cc and let post-ui.cc die) (??)
-
- std::string last_mid;
+ int total = get_total_parts(t->_filename.c_str());
+ std::cerr<<"total of "<<t->_filename<<" : "<<total<<std::endl;
foreach (std::set<int>, t->_wanted, pit)
{
if (custom_mid)
{
std::string out;
- generate_unique_id(d, *pit,out);
+ generate_unique_id(domain, *pit,out);
n.mid = out;
+ if (first_mid.empty()) first_mid = out;
}
g_snprintf(buf,sizeof(buf),"%s.%d", basename, *pit);
n.message_id = buf;
n.partno = *pit;
n.last_mid = last_mid;
+ t->_first_mid = first_mid;
last_mid = n.mid;
t->_needed.insert(std::pair<int,TaskUpload::Needed>(*pit,n));
}
@@ -1141,8 +1153,6 @@ PostUI :: maybe_post_message (GMimeMessage * message)
_queue.add_task (*it, Queue::BOTTOM);
t->add_listener(this);
-
- _upload_listeners.push_back(t);
}
gtk_widget_hide (_root); // hide the main window, we still need the class' data
}
@@ -2717,7 +2727,7 @@ PostUI :: select_encode (GtkAction* a)
foreach(tasks_t, tasks, it)
{
const char* f = (*it)->_filename.c_str();
- int total(get_total_parts (f,*it));
+ int total(get_total_parts (f));
(*it)->_encode_mode = tmp;
(*it)->_total_parts = total;
@@ -2730,11 +2740,12 @@ PostUI :: select_encode (GtkAction* a)
}
int
-PostUI :: get_total_parts(const char* file, TaskUpload* it)
+PostUI :: get_total_parts(const char* file)
{
struct stat sb;
stat (file,&sb);
- return std::max(1,(int)std::ceil((double)sb.st_size / (double)_prefs.get_int("upload-option-bpf",1024*512)));
+ int max (std::max(1,(int)std::ceil((double)sb.st_size / (1024*_prefs.get_int("upload-option-kbpf",512)))));
+ return max;
}
void
@@ -2791,7 +2802,7 @@ PostUI :: select_parts ()
if (!_upload_ptr) return;
- int new_parts = get_total_parts(_upload_ptr->_filename.c_str(), _upload_ptr);
+ int new_parts = get_total_parts(_upload_ptr->_filename.c_str());
if (_total_parts != new_parts)
{
_upload_ptr->_wanted.clear();
@@ -2909,9 +2920,12 @@ PostUI :: PostUI (GtkWindow * parent,
_body_changed_id(0),
_body_changed_idle_tag(0),
_filequeue_eventbox (0),
- _filequeue_label (0)
+ _filequeue_label (0),
+ _multipart(g_mime_multipart_new_with_subtype("mixed"))
{
+ g_mime_multipart_set_boundary(_multipart,"$pan_multipart_gmime_message$");
+
rng.seed();
_upload_queue.add_listener (this);
@@ -3029,12 +3043,9 @@ PostUI :: prompt_user_for_queueable_files (GtkWindow * parent, const Prefs& pref
gtk_widget_destroy (w);
TaskUpload::UploadInfo ui;
- // not used for now...
- ui.comment1 = _prefs.get_flag("upload-queue-append-subject-enabled",false);
// query lines per file value
- ui.bpf = _prefs.get_int("upload-option-bpf",1024*512);
+ ui.kbpf = _prefs.get_int("upload-option-kbpf",512);
- GSList * cur = g_slist_nth (tmp_list,0);
std::string author;
profile.get_from_header(author);
std::string subject(utf8ize (g_mime_message_get_subject (tmp)));
@@ -3049,6 +3060,7 @@ PostUI :: prompt_user_for_queueable_files (GtkWindow * parent, const Prefs& pref
groups.insert(Quark(groupname));
}
+ GSList * cur = g_slist_nth (tmp_list,0);
for (; cur; cur = cur->next)
{
GMimeMessage * msg (new_message_from_ui (UPLOADING));
@@ -3062,11 +3074,11 @@ PostUI :: prompt_user_for_queueable_files (GtkWindow * parent, const Prefs& pref
struct stat sb;
// yEnc encoding is the default, user can change that with popup-menu
- stat ((const char*)cur->data,&sb);
- ui.total = std::max(1,(int)std::ceil((double)sb.st_size / (double)_prefs.get_int("upload-option-bpf",1024*512)));
+ ui.total = get_total_parts((const char*)cur->data);
+ std::cerr<<"ui total "<<ui.total<<" "<<(const char*)cur->data<<" "<<get_total_parts((const char*)cur->data)<<std::endl;
TaskUpload* tmp = new TaskUpload(std::string((const char*)cur->data),
profile.posting_server, _cache,
- a, ui, msg ,0, TaskUpload::YENC);
+ a, ui, msg ,0, TaskUpload::YENC, TaskUpload::BULK );
// insert wanted parts to upload
for (int i=1;i<=ui.total; ++i)
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index 753f1ff..b67867e 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -112,7 +112,7 @@ namespace pan
void set_message (GMimeMessage*);
private:
- virtual void on_progress_finished (Progress&, int status);
+ virtual void on_progress_finished (Progress&, int status=OK);
virtual void on_progress_error (Progress&, const StringView&);
virtual void on_progress_step (Progress&, int p) {}
@@ -150,7 +150,6 @@ namespace pan
std::string _current_signature;
GtkWidget * _post_dialog;
TaskPost * _post_task;
- std::vector<TaskUpload*> _upload_listeners;
typedef std::map<std::string, std::string> str2str_t;
str2str_t _hidden_headers;
str2str_t _profile_headers;
@@ -163,6 +162,7 @@ namespace pan
int _total_parts;
std::string _save_file;
MTRand rng;
+ GMimeMultipart * _multipart;
private:
friend class UploadQueue;
@@ -246,7 +246,7 @@ namespace pan
void generate_unique_id (StringView& mid, int cnt, std::string& s);
- int get_total_parts(const char* file, TaskUpload* it);
+ int get_total_parts(const char* file);
private:
guint _draft_autosave_id;
diff --git a/pan/gui/prefs-ui.cc b/pan/gui/prefs-ui.cc
index 479f71b..d9fbc2c 100644
--- a/pan/gui/prefs-ui.cc
+++ b/pan/gui/prefs-ui.cc
@@ -622,18 +622,19 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
row = 0;
t = HIG :: workarea_create ();
- HIG :: workarea_add_section_title (t, &row, _("Upload Subject Line Appearance"));
+ HIG :: workarea_add_section_title (t, &row, _("Encoding Options"));
HIG :: workarea_add_section_spacer (t, row, 4);
- w = new_check_button (_("Append Subject to all Posts"), "upload-queue-append-subject-enabled", false, prefs);
- HIG :: workarea_add_wide_control (t, &row, w);
- HIG :: workarea_add_section_title (t, &row, _("Upload Subject Line Appearance"));
- HIG :: workarea_add_section_spacer (t, row, 4);
- // 256 mb blocks max, 512 kb min
- w = new_spin_button ("upload-option-bpf", 5000, 1024*1024*256, prefs);
- l = gtk_label_new(_("Default Bytes per File (for yEnc Encoder)"));
+ // 16 MiB blocks max, 512 kb min
+ w = new_spin_button ("upload-option-kbpf", 512, 1024*16, prefs);
+ l = gtk_label_new(_("Default KB per File (for Encoder)"));
gtk_misc_set_alignment (GTK_MISC(l), 0.0, 0.5);
- gtk_label_set_mnemonic_widget(GTK_LABEL(l), w);
HIG::workarea_add_row (t, &row, w, l);
+
+// HIG::workarea_add_section_divider (t, &row);
+// HIG :: workarea_add_section_title (t, &row, _("Attachment Options (Bulk Uploads)"));
+// w = new_check_button (_("Single master reply/followup with body, attachments are replies"), "upload-option-reply-multi", false, prefs);
+// HIG :: workarea_add_wide_control (t, &row, w);
+
HIG :: workarea_finish (t, &row);
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), t, gtk_label_new_with_mnemonic(_("_Upload options")));
diff --git a/pan/tasks/Makefile.am b/pan/tasks/Makefile.am
index 9e3bbdd..5626290 100644
--- a/pan/tasks/Makefile.am
+++ b/pan/tasks/Makefile.am
@@ -12,6 +12,7 @@ libtasks_a_SOURCES = \
task-post.cc \
task-xover.cc \
task-upload.cc \
+ task-multipost.cc \
nntp.cc \
nzb.cc \
queue.cc \
@@ -34,6 +35,7 @@ noinst_HEADERS = \
task-groups.h \
task-post.h \
task-upload.h \
+ task-multipost.h \
task-weak-ordering.h \
task-xover.h \
nntp.h \
diff --git a/pan/tasks/encoder.cc b/pan/tasks/encoder.cc
index bedfac1..1e17282 100644
--- a/pan/tasks/encoder.cc
+++ b/pan/tasks/encoder.cc
@@ -66,7 +66,7 @@ Encoder :: enqueue (TaskUpload * task,
std::string & filename,
std::string & basename,
std::string & subject,
- int bpf,
+ int kbpf,
const TaskUpload::EncodeMode enc)
{
@@ -79,7 +79,7 @@ Encoder :: enqueue (TaskUpload * task,
this->needed = &task->_needed;
this->cache = cache;
this->article = article;
- this->bpf = bpf;
+ this->kbpf = kbpf;
this->subject = subject;
percent = 0;
@@ -150,7 +150,7 @@ Encoder :: do_work()
continue;
}
- res = UUEncodePartial_byFSize (fp, NULL, (char*)filename.c_str(), enc , (char*)basename.c_str(), NULL, 0644, cnt, bpf ,&crc);
+ res = UUEncodePartial_byFSize (fp, NULL, (char*)filename.c_str(), enc , (char*)basename.c_str(), 0, 0, cnt, kbpf*1024 ,&crc);
if (fp) fclose(fp);
_no_encode:
@@ -177,13 +177,9 @@ _no_encode:
log_errors.push_back(buf); // log error
} else
task->_upload_list.push_back(tmp);
-
UUCleanUp ();
-
}
-
disable_progress_update();
-
}
/***
diff --git a/pan/tasks/encoder.h b/pan/tasks/encoder.h
index 6f962cd..d0992ef 100644
--- a/pan/tasks/encoder.h
+++ b/pan/tasks/encoder.h
@@ -66,7 +66,7 @@ namespace pan
std::string & filename,
std::string & basename,
std::string & subject,
- int bpf,
+ int kbpf,
const TaskUpload::EncodeMode enc = TaskUpload::YENC);
public:
@@ -85,7 +85,7 @@ namespace pan
TaskUpload * task;
TaskUpload::EncodeMode encode_mode;
std::string basename, filename, subject;
- int bpf;
+ int kbpf;
EncodeCache * cache;
TaskUpload::needed_t * needed;
Article * article;
diff --git a/pan/tasks/task-multipost.cc b/pan/tasks/task-multipost.cc
new file mode 100644
index 0000000..cfd8f87
--- /dev/null
+++ b/pan/tasks/task-multipost.cc
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2007 Charles Kerr <charles rebelbase com>
+ *
+ * This File:
+ * Copyright (C) 2007 Charles Kerr <charles rebelbase com>
+ * Copyright (C) 2007 Calin Culianu <calin ajvar org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <algorithm>
+#include <cassert>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <cstdio>
+
+#include <pan/general/debug.h>
+#include <pan/general/file-util.h>
+#include <pan/general/log.h>
+#include <pan/general/macros.h>
+#include <pan/usenet-utils/mime-utils.h>
+#include <pan/usenet-utils/gnksa.h>
+#include "task-multipost.h"
+#include "nzb.h"
+
+using namespace pan;
+
+namespace
+{
+ std::string get_description (const char* name)
+ {
+ char buf[4096];
+ char * freeme = g_path_get_basename(name);
+ snprintf (buf, sizeof(buf), _("Uploading %s"), freeme);
+ g_free(freeme);
+ return buf;
+ }
+
+ std::string g_get_basename(const char* f)
+ {
+ char buf[4096];
+ char * freeme = g_path_get_basename(f);
+ snprintf (buf, sizeof(buf), "%s", freeme);
+ g_free(freeme);
+ return buf;
+ }
+}
+
+/***
+****
+***/
+
+TaskMultiPost :: TaskMultiPost (const std::string & filename,
+ const Quark & server,
+ Article article,
+ GMimeMessage * msg,
+ Progress::Listener * listener):
+ Task ("UPLOAD", get_description(filename.c_str())),
+ _filename(filename),
+ _basename (g_get_basename(filename.c_str())),
+ _server(server),
+ _article(article),
+ _subject (article.subject.to_string()),
+ _author(article.author.to_string()),
+ _msg (msg)
+{
+
+
+// struct stat sb;
+// stat(filename.c_str(),&sb);
+// _bytes = sb.st_size;
+
+}
+
+void
+TaskMultiPost :: build_needed_tasks()
+{
+
+ foreach (needed_t, _needed, it)
+ {
+ _mids.push_back(Quark(it->second.message_id));
+ }
+
+}
+
+void
+TaskMultiPost :: update_work (NNTP* checkin_pending)
+{
+
+ int working(0);
+ foreach (needed_t, _needed, nit)
+ {
+ TaskUpload::Needed& n (nit->second);
+ if (n.nntp && n.nntp!=checkin_pending)
+ ++working;
+ }
+
+ /* only need encode if mode is NOT plain */
+ if (working)
+ {
+ _state.set_working();
+ }
+ else if (!working)
+ {
+ _state.set_need_nntp(_server);
+ }
+ else if (_needed.empty())
+ {
+ _state.set_completed();
+ set_finished(OK);
+ }
+}
+
+
+void
+TaskMultiPost :: use_nntp (NNTP * nntp)
+{
+ nntp->post(StringView(""), this);
+
+ update_work ();
+}
+
+/***
+****
+***/
+
+void
+TaskMultiPost :: on_nntp_line (NNTP * nntp,
+ const StringView & line_in) {}
+
+void
+TaskMultiPost :: on_nntp_done (NNTP * nntp,
+ Health health,
+ const StringView & response)
+{
+
+ update_work(nntp);
+ check_in (nntp, health);
+
+}
+
+/***
+****
+***/
+
+unsigned long
+TaskMultiPost :: get_bytes_remaining () const
+{
+ unsigned long bytes (0);
+ foreach_const (needed_t, _needed, it)
+ bytes += (unsigned long)it->second.bytes;
+ return bytes;
+}
+
+
+void
+TaskMultiPost :: stop ()
+{
+}
+
+
+TaskMultiPost :: ~TaskMultiPost ()
+{
+
+
+}
diff --git a/pan/tasks/task-multipost.h b/pan/tasks/task-multipost.h
new file mode 100644
index 0000000..b17c276
--- /dev/null
+++ b/pan/tasks/task-multipost.h
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * This file
+ * Copyright (C) 2007 Charles Kerr <charles rebelbase com>
+ * Copyright (C) 2007 Calin Culianu <calin ajvar org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TaskMultiPost_h_
+#define _TaskMultiPost_h_
+
+#include <pan/general/locking.h>
+#include <pan/data/article.h>
+#include <pan/data/data.h>
+#include <pan/general/log.h>
+#include <pan/data/xref.h>
+#include <pan/tasks/nntp.h>
+#include <pan/tasks/task.h>
+#include <pan/tasks/task-upload.h>
+
+extern "C" {
+ #define PROTOTYPES
+ #include <uulib/uudeview.h>
+ #include <glib/gi18n.h>
+};
+
+#include <set>
+
+namespace pan
+{
+ /**
+ * Task for uploading binary data to usenet
+ * @ingroup tasks
+ */
+ class TaskMultiPost: public Task,
+ private NNTP::Listener
+
+ {
+ public:
+
+ const Article& get_article () { return _article; }
+
+ typedef std::vector<Quark> mid_sequence_t;
+
+ typedef std::map<int, TaskUpload::Needed> needed_t;
+
+ // life cycle
+ TaskMultiPost ( const std::string & filename,
+ const Quark & server,
+ Article article,
+ GMimeMessage * msg,
+ Progress::Listener * listener= 0);
+
+ virtual ~TaskMultiPost ();
+
+ public: // Task subclass
+ unsigned long get_bytes_remaining () const;
+ void stop ();
+ const std::string& get_basename() { return _basename; }
+
+ /** 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 ENCODING state.
+ */
+ private: // Task subclass
+ virtual void use_nntp (NNTP * nntp);
+
+ private: // NNTP::Listener subclass
+ virtual void on_nntp_line (NNTP*, const StringView&);
+ virtual void on_nntp_done (NNTP*, Health, const StringView&);
+
+
+ protected:
+ Quark _server;
+
+ private: // implementation
+ friend class PostUI;
+ friend class Queue;
+
+ std::string _filename;
+ std::string _basename;
+ std::string _subject, _master_subject, _author;
+ std::string _save_file;
+ int _total_parts, _needed_parts;
+ unsigned long _bytes;
+ Article _article;
+ unsigned long _all_bytes;
+
+ Article::mid_sequence_t _mids;
+ TaskUpload::needed_t _needed;
+
+ void update_work (NNTP * checkin_pending = 0);
+
+ public:
+ needed_t& needed() { return _needed; }
+ void build_needed_tasks();
+
+ private:
+ std::set<int> _wanted;
+ GMimeMessage * _msg;
+
+ };
+}
+
+#endif
diff --git a/pan/tasks/task-upload.cc b/pan/tasks/task-upload.cc
index c4937ad..6d16951 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -28,9 +28,7 @@
#include <iostream>
#include <fstream>
#include <cstdio>
-extern "C" {
-#include <glib/gi18n.h>
-}
+
#include <pan/general/debug.h>
#include <pan/general/file-util.h>
#include <pan/general/log.h>
@@ -76,7 +74,8 @@ TaskUpload :: TaskUpload (const std::string & filename,
UploadInfo format,
GMimeMessage * msg,
Progress::Listener * listener,
- const TaskUpload::EncodeMode enc):
+ const TaskUpload::EncodeMode enc,
+ const TaskUpload::AttachMode att):
Task ("UPLOAD", get_description(filename.c_str())),
_filename(filename),
_basename (g_get_basename(filename.c_str())),
@@ -89,23 +88,23 @@ TaskUpload :: TaskUpload (const std::string & filename,
_encoder_has_run (false),
_encode_mode(enc),
_all_bytes(0),
- _bpf(format.bpf),
+ _kbpf(format.kbpf),
_queue_pos(0),
_msg (msg),
_total_parts(format.total),
_save_file(format.save_file),
- _first(true)
+ _first(true),
+ _att_mode(att)
{
-
const char * tmp (g_mime_object_get_header ((GMimeObject *)_msg, "References"));
if (tmp) _references = std::string(tmp);
struct stat sb;
stat(filename.c_str(),&sb);
_bytes = sb.st_size;
- _state.set_paused();
+ _state.set_paused();
}
namespace
@@ -125,7 +124,6 @@ namespace
void
TaskUpload :: build_needed_tasks()
{
-
foreach (needed_t, _needed, it)
{
_mids.push_back(Quark(it->second.message_id));
@@ -150,8 +148,13 @@ TaskUpload :: update_work (NNTP* checkin_pending)
++working;
}
+ if (_queue_pos == -1)
+ {
+ _state.set_need_nntp(_server);
+ }
+
/* only need encode if mode is NOT plain */
- if (!_encoder_has_run)
+ if (!_encoder_has_run && !_encoder && _queue_pos != -1)
{
_state.set_need_encoder();
}
@@ -161,9 +164,7 @@ TaskUpload :: update_work (NNTP* checkin_pending)
}
else if ((_encoder_has_run && !_needed.empty()))
{
-// _state.set_completed();
-// set_finished(_queue_pos);
- _state.set_need_nntp(_server);
+ _state.set_need_nntp(_server);
}
else if (_needed.empty())
{
@@ -172,17 +173,6 @@ TaskUpload :: update_work (NNTP* checkin_pending)
}
}
-namespace
-{
- void mod_refs (GMimeMessage* msg, std::string& refs, std::string& mid)
- {
- if (mid.empty()) return ; // do nothing if no new mids are added
- char buf[4096];
- g_snprintf(buf,sizeof(buf), "%s <%s>", refs.c_str(), mid.c_str());
- g_mime_object_set_header ((GMimeObject *) msg, "References", buf);
- }
-}
-
void
TaskUpload :: prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::string& d)
{
@@ -193,24 +183,34 @@ TaskUpload :: prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::st
//modify subject
char buf[4096];
- g_mime_message_set_subject (msg, build_subject_line (buf, 4096, _subject, _basename, n->partno, _total_parts, _encode_mode));
+ if (_queue_pos != -1)
+ g_mime_message_set_subject (msg, build_subject_line (buf, 4096, _subject, _basename, n->partno, _total_parts, _encode_mode));
//modify references header
- mod_refs (msg, _references, n->last_mid);
+ std::string mids(_references);
+ mids += " <" + _first_mid + "> ";
+ if (_first_mid != n->last_mid && !_first) mids += "<" + n->last_mid + ">";
+ g_mime_object_set_header ((GMimeObject *) msg, "References", mids.c_str());
- //extract whole message with headers (for first message, others only post headers + encoded data)
char * all;
- if (_first) all = g_mime_object_to_string ((GMimeObject *) msg);
+ if (_first && _queue_pos==-1)
+ all = g_mime_object_to_string ((GMimeObject *) msg);
else
all = g_mime_object_get_headers ((GMimeObject *) msg);
out << all << "\n";
out << d;
d = out.str();
- if (_first) g_free(all);
+ if (_first && _queue_pos==0) g_free(all);
if (_first) _first = !_first;
}
+GMimeObject *
+TaskUpload :: get_body(Needed* n)
+{
+ return 0;
+}
+
void
TaskUpload :: use_nntp (NNTP * nntp)
{
@@ -258,22 +258,29 @@ TaskUpload :: on_nntp_done (NNTP * nntp,
Health health,
const StringView & response)
{
+
char buf[4096];
Log::Entry tmp;
tmp.date = time(NULL);
tmp.is_child = true;
+ bool found(false);
needed_t::iterator it;
for (it=_needed.begin(); it!=_needed.end(); ++it)
- if (it->second.nntp == nntp)
+ if (it->second.nntp == nntp) {
+ found=true;
break;
+ }
+
+ if (!found) return;
bool post_ok(false);
switch (health)
{
case OK:
- increment_step(it->second.bytes);
- _needed.erase (it);
+ std::cerr<<"OK "<<_queue_pos<<std::endl;
+// increment_step(it->second.bytes);
+// _needed.erase (it);
post_ok = true;
break;
case ERR_NETWORK:
@@ -372,6 +379,9 @@ TaskUpload :: get_bytes_remaining () const
void
TaskUpload :: use_encoder (Encoder* encoder)
{
+
+ if (!encoder) return;
+
if (_state._work != NEED_ENCODER)
check_in (encoder);
@@ -379,7 +389,7 @@ TaskUpload :: use_encoder (Encoder* encoder)
init_steps(100);
_state.set_working();
- _encoder->enqueue (this, &_cache, &_article, _filename, _basename, _master_subject, _bpf, _encode_mode);
+ _encoder->enqueue (this, &_cache, &_article, _filename, _basename, _master_subject, _kbpf, _encode_mode);
debug ("encoder thread was free, enqueued work");
}
@@ -437,6 +447,9 @@ TaskUpload :: ~TaskUpload ()
_encoder->cancel_silently();
g_object_unref (G_OBJECT(_msg));
-// _cache.release(_mids);
-// _cache.resize();
+ if (_att_mode==BULK && _queue_pos != -1)
+ {
+ _cache.release(_mids);
+ _cache.resize();
+ }
}
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index b260002..adbf3b0 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -35,8 +35,10 @@
#include <pan/tasks/task.h>
extern "C" {
-#define PROTOTYPES
-#include <uulib/uudeview.h>
+ #define PROTOTYPES
+ #include <uulib/uudeview.h>
+ #include <gmime/gmime.h>
+ #include <glib/gi18n.h>
};
#include <set>
@@ -57,10 +59,9 @@ namespace pan
struct UploadInfo
{
- bool comment1;
std::string save_file;
std::string mid;
- int bpf;
+ int kbpf;
int total;
};
@@ -89,15 +90,22 @@ namespace pan
YENC=2,
};
+ enum AttachMode
+ {
+ BULK,
+ INLINE
+ };
+
// life cycle
TaskUpload ( const std::string & filename,
const Quark & server,
EncodeCache & cache,
Article article,
UploadInfo format,
- GMimeMessage * msg,
+ GMimeMessage * msg=0,
Progress::Listener * listener= 0,
- EncodeMode enc= YENC);
+ const EncodeMode enc= YENC,
+ const AttachMode att= BULK);
virtual ~TaskUpload ();
@@ -158,7 +166,8 @@ namespace pan
bool _encoder_has_run;
std::string _filename;
std::string _basename;
- TaskUpload::EncodeMode _encode_mode;
+ EncodeMode _encode_mode;
+ AttachMode _att_mode;
std::string _subject, _master_subject, _author;
std::string _save_file;
int _total_parts, _needed_parts;
@@ -170,9 +179,10 @@ namespace pan
std::vector<Article*> _upload_list;
Article::mid_sequence_t _mids;
int _queue_pos;
- int _bpf;
+ int _kbpf;
needed_t _needed;
std::string _references; // original references, not to be touched!
+ std::string _first_mid;
void update_work (NNTP * checkin_pending = 0);
@@ -186,9 +196,9 @@ namespace pan
std::set<int> _wanted;
GMimeMessage * _msg;
void prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::string& d);
+ GMimeObject * get_body(Needed* n);
void add_reference_to_list(std::string s);
bool _first;
-
};
}
diff --git a/uulib/uuencode.c b/uulib/uuencode.c
index 5b4d1c6..4eebc69 100644
--- a/uulib/uuencode.c
+++ b/uulib/uuencode.c
@@ -1737,8 +1737,6 @@ UUEncodePartial_byFSize (FILE *outfile, FILE *infile,
}
}
- printf("numparts %d\n", numparts);
-
if (encoding == YENC_ENCODED)
{
pcrc = crc32(0L, Z_NULL, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]