[pan2/testing: 146/279] added resume functionality



commit 317238c613e1c7227fdad1464e845d920bad129f
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Mon Jul 4 10:45:40 2011 +0200

    added resume functionality

 pan.cbp                       |    2 +
 pan/data/encode-cache.cc      |   12 +-
 pan/gui/Makefile.am           |    2 +-
 pan/gui/gui.h                 |    2 +
 pan/gui/post-ui.cc            |   64 +++++-----
 pan/gui/post-ui.h             |    9 +--
 pan/tasks/nzb.cc              |  280 ++++++++++++++++++++++++-----------------
 pan/tasks/nzb.h               |    3 +
 pan/tasks/task-upload.cc      |   34 ++++--
 pan/tasks/task-upload.h       |    8 +-
 pan/usenet-utils/Makefile.am  |    7 +-
 pan/usenet-utils/mime-utils.h |    3 +
 12 files changed, 252 insertions(+), 174 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index 5b49d1f..e964b7b 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -251,6 +251,8 @@
 		<Unit filename="pan/usenet-utils/numbers-test.cc" />
 		<Unit filename="pan/usenet-utils/numbers.cc" />
 		<Unit filename="pan/usenet-utils/numbers.h" />
+		<Unit filename="pan/usenet-utils/rng.cc" />
+		<Unit filename="pan/usenet-utils/rng.h" />
 		<Unit filename="pan/usenet-utils/scorefile-test.cc" />
 		<Unit filename="pan/usenet-utils/scorefile.cc" />
 		<Unit filename="pan/usenet-utils/scorefile.h" />
diff --git a/pan/data/encode-cache.cc b/pan/data/encode-cache.cc
index 473ddea..c0e50b9 100644
--- a/pan/data/encode-cache.cc
+++ b/pan/data/encode-cache.cc
@@ -50,7 +50,6 @@ using namespace pan;
 ******
 *****/
 
-// empty cache at construction, we don't need the old files...
 EncodeCache :: EncodeCache (const StringView& path, size_t max_megs):
    _path (path.str, path.len),
    _max_megs (max_megs),
@@ -70,16 +69,15 @@ EncodeCache :: EncodeCache (const StringView& path, size_t max_megs):
       while ((fname = g_dir_read_name (dir)))
       {
         g_snprintf (filename, sizeof(filename), "%s%c%s", _path.c_str(), G_DIR_SEPARATOR, fname);
-        add (Quark(filename));
+        // delete ALL but the gmime_messages
+        if (!strstr(filename, "_msg_")) unlink(filename);
       }
       g_dir_close (dir);
    }
-   debug ("loaded " << _mid_to_info.size() << " articles into cache from " << _path);
 }
 
 EncodeCache :: ~EncodeCache ()
-{
-}
+{}
 
 /*****
 ******
@@ -112,9 +110,9 @@ EncodeCache :: contains (const Quark& mid) const
 void
 EncodeCache :: get_filename (char* buf, const Quark& mid) const
 {
-   const char* base = g_path_get_basename(mid.c_str());
+   char* base = g_path_get_basename(mid.c_str());
    g_snprintf (buf, PATH_MAX, "%s%c%s", _path.c_str(), G_DIR_SEPARATOR, base);
-   g_free((gpointer)base);
+   g_free(base);
 }
 
 FILE*
diff --git a/pan/gui/Makefile.am b/pan/gui/Makefile.am
index 9eef8cf..b50a5ff 100644
--- a/pan/gui/Makefile.am
+++ b/pan/gui/Makefile.am
@@ -91,7 +91,7 @@ else
 WINRC =
 WINRCOBJ =
 endif
-  
+
 pan_SOURCES = gui.cc pan.cc $(WINRC)
 pan_LDADD = ./libpangui.a $(WINRCOBJ) ../data-impl/libpandata.a ../tasks/libtasks.a ../data/libdata.a ../usenet-utils/libusenetutils.a ../general/libgeneralutils.a ../../uulib/libuu.a @GTKSPELL_LIBS@ @GTK_LIBS@ @GMIME_LIBS@ @GLIB_LIBS@
 
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 23c8961..a6c1f51 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -53,6 +53,7 @@ namespace pan
     private Queue::Listener,
     private Prefs::Listener
   {
+
     public:
       GUI (Data& data, Queue&, ArticleCache&, EncodeCache&, Prefs&, GroupPrefs&);
       virtual ~GUI ();
@@ -235,6 +236,7 @@ namespace pan
       static void add_widget (GtkUIManager*, GtkWidget*, gpointer);
       static void server_list_dialog_destroyed_cb (GtkWidget*, gpointer);
       void server_list_dialog_destroyed (GtkWidget*);
+
   };
 }
 
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 03313e2..a555968 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -80,9 +80,9 @@ PostUI :: generate_unique_id (StringView& mid, int cnt, std::string& s)
   std::strftime (buf, sizeof(buf), "%Y%m%d%H%M%S", &local_now);
   out << "pan$";
   gettimeofday (&tv, NULL);
-  out << buf << "$" << std::hex << tv.tv_usec << "$" << std::hex
-      << mtrand.randInt() << "$" << std::hex << mtrand.randInt() << "$"
-      << std::hex << mtrand.randInt() << "$" << std::hex << cnt;
+  out << std::hex << tv.tv_usec << "$" << std::hex
+      << rng.randInt() << "$" << std::hex << rng.randInt() << "$"
+      << std::hex << rng.randInt() << "$" << std::hex << cnt;
   // delimit
   out<< '@';
   // add domain
@@ -1083,17 +1083,21 @@ PostUI :: maybe_post_message (GMimeMessage * message)
       : GNKSA::generate_message_id_from_email_address (profile.address);
     StringView domain(d);
 
+    /* init taskupload variables before adding the tasks to the queue for processing */
     foreach (PostUI::tasks_t, tasks, it)
     {
-      const char* basename = (*it)->_filename.c_str();
+
+      TaskUpload * t (*it);
+
+      const char* basename = t->_basename.c_str();
       TaskUpload::Needed n;
 
       stat (basename,&sb);
 
-      int total = std::max(1, (int) (((long)sb.st_size + (lpf*bpl[(*it)->_encode_mode]-1)) /
-        (lpf*bpl[(*it)->_encode_mode])));
+      int total = std::max(1, (int) (((long)sb.st_size + (lpf*bpl[t->_encode_mode]-1)) /
+        (lpf*bpl[t->_encode_mode])));
 
-      foreach (std::set<int>, (*it)->_wanted, pit)
+      foreach (std::set<int>, t->_wanted, pit)
       {
         if (custom_mid)
         {
@@ -1105,14 +1109,16 @@ PostUI :: maybe_post_message (GMimeMessage * message)
         g_snprintf(buf,sizeof(buf),"%s.%d", basename, *pit);
         n.message_id = buf;
         n.partno = *pit;
-        (*it)->_needed.insert(std::pair<int,TaskUpload::Needed>(*pit,n));
+        t->_needed.insert(std::pair<int,TaskUpload::Needed>(*pit,n));
       }
-      (*it)->build_needed_tasks();
+      t->build_needed_tasks();
 
-      (*it)->_queue_pos = cnt++;
+      t->_save_file = _save_file;
+
+      t->_queue_pos = cnt++;
       _queue.add_task (*it, Queue::BOTTOM);
-      (*it)->add_listener(this);
-      _upload_listeners.push_back(*it);
+      t->add_listener(this);
+      _upload_listeners.push_back(t);
     }
     gtk_widget_hide (_root); // hide the main window, we still need the class' data
   }
@@ -1338,20 +1344,20 @@ PostUI :: open_draft ()
 void
 PostUI :: import_draft (const char* fn)
 {
-    const char * draft = fn;
-    std::string txt;
-    if (file :: get_text_file_contents (draft, txt))
-    {
-      GMimeStream * stream = g_mime_stream_mem_new_with_buffer (txt.c_str(), txt.size());
-      GMimeParser * parser = g_mime_parser_new_with_stream (stream);
-      GMimeMessage * message = g_mime_parser_construct_message (parser);
-      if (message) {
-        set_message (message);
-        g_object_unref (G_OBJECT(message));
-      }
-      g_object_unref (G_OBJECT(parser));
-      g_object_unref (G_OBJECT(stream));
-    }
+//    const char * draft = fn;
+//    std::string txt;
+//    if (file :: get_text_file_contents (draft, txt))
+//    {
+//      GMimeStream * stream = g_mime_stream_mem_new_with_buffer (txt.c_str(), txt.size());
+//      GMimeParser * parser = g_mime_parser_new_with_stream (stream);
+//      GMimeMessage * message = g_mime_parser_construct_message (parser);
+//      if (message) {
+//        set_message (message);
+//        g_object_unref (G_OBJECT(message));
+//      }
+//      g_object_unref (G_OBJECT(parser));
+//      g_object_unref (G_OBJECT(stream));
+//    }
 }
 
 namespace
@@ -2886,7 +2892,7 @@ PostUI :: PostUI (GtkWindow    * parent,
   _filequeue_label (0)
 {
 
-  mtrand.seed();
+  rng.seed();
 
   _upload_queue.add_listener (this);
 
@@ -3003,6 +3009,7 @@ 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.lpf = _prefs.get_int("upload-option-lpf",4000);
@@ -3033,8 +3040,7 @@ PostUI :: prompt_user_for_queueable_files (GtkWindow * parent, const Prefs& pref
 
           struct stat sb;
           stat ((const char*)cur->data,&sb);
-          int lpf = _prefs.get_int("upload-option-lpf",4000);
-          int total = std::max(1, (int) (((long)sb.st_size + (lpf*bpl[TaskUpload::YENC]-1)) / (lpf*bpl[TaskUpload::YENC])));
+          int total = std::max(1, (int) (((long)sb.st_size + (ui.lpf*bpl[TaskUpload::YENC]-1)) / (ui.lpf*bpl[TaskUpload::YENC])));
           ui.total = total;
 
           TaskUpload* tmp = new TaskUpload(std::string((const char*)cur->data),
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index 105f7bc..09f5bbf 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -33,13 +33,6 @@
 
 namespace pan
 {
-   /*
-    #define B64ENCODED	(2)
-    #define PT_ENCODED	(5)
-    #define YENC_ENCODED 7)	*/
-
-  static int bpl[3] = { 45, 45, 128 };
-
   class Profiles;
   class TaskPost;
   class UploadQueue;
@@ -169,6 +162,7 @@ namespace pan
       TaskUpload* _upload_ptr;
       int _total_parts;
       std::string _save_file;
+      MTRand rng;
 
     private:
       friend class UploadQueue;
@@ -251,7 +245,6 @@ namespace pan
       static void message_id_toggled_cb (GtkToggleButton * tb, gpointer prefs_gpointer);
 
       void generate_unique_id (StringView& mid, int cnt, std::string& s);
-      MTRand mtrand;
 
       int get_total_parts(const char* file, TaskUpload* it);
 
diff --git a/pan/tasks/nzb.cc b/pan/tasks/nzb.cc
index 88a758a..0a40f9e 100644
--- a/pan/tasks/nzb.cc
+++ b/pan/tasks/nzb.cc
@@ -20,6 +20,7 @@
 
 #include <config.h>
 #include <iostream>
+#include <fstream>
 #include <sstream>
 #include <string>
 #include <map>
@@ -32,6 +33,7 @@ extern "C" {
 #include <pan/general/macros.h>
 #include <pan/general/quark.h>
 #include <pan/general/string-view.h>
+#include <pan/usenet-utils/mime-utils.h>
 #include <pan/general/utf8-utils.h>
 #include "nzb.h"
 #include "task-article.h"
@@ -41,6 +43,28 @@ using namespace pan;
 
 namespace
 {
+  GMimeMessage * import_msg(const StringView filename)
+  {
+    std::string txt;
+    GMimeMessage * msg;
+    if (file :: get_text_file_contents (filename, txt))
+    {
+      GMimeStream * stream = g_mime_stream_mem_new_with_buffer (txt.c_str(), txt.size());
+      GMimeParser * parser = g_mime_parser_new_with_stream (stream);
+      msg   = g_mime_parser_construct_message (parser);
+      g_object_unref (G_OBJECT(parser));
+      g_object_unref (G_OBJECT(stream));
+    }
+
+    //delete msg
+    unlink(filename.str);
+    g_object_ref(msg);
+    return msg;
+  }
+}
+
+namespace
+{
   typedef std::vector<Task*> tasks_t;
 
   struct MyContext
@@ -48,22 +72,24 @@ namespace
     quarks_t groups;
     std::string text;
     std::string path;
-//    std::vector<std::string>  groups_str;  // TaskUpload
-//    TaskUpload::needed_t needed_parts;     // TaskUpload
-//    std::string queue;
-    int lpf;
-    Article a;
+    std::string rng;
+    std::string save_file;
+    TaskUpload::EncodeMode enc_mode;
+    TaskUpload::needed_t needed_parts;
     PartBatch parts;
     tasks_t tasks;
+    Article a;
     ArticleCache& cache;
-    EncodeCache& encode_cache;
     ArticleRead& read;
+    EncodeCache& encode_cache;
     const ServerRank& ranks;
     const GroupServer& gs;
     Quark server;
     const StringView fallback_path;
     size_t bytes;
     size_t number;
+    std::string msg_name;
+    int lpf;
 
     MyContext (ArticleCache& ac, EncodeCache& ec, ArticleRead& r,
                const ServerRank& rank, const GroupServer& g, const StringView& p):
@@ -71,16 +97,17 @@ namespace
 
     void file_clear () {
       groups.clear ();
-//      groups_str.clear();
       text.clear ();
       path.clear ();
       a.clear ();
       bytes = 0;
       number = 0;
-//      needed_parts.clear();   // TaskUpload
-//      domain.clear();         // TaskUpload
-//      queue.clear();
-      lpf = 0;
+      needed_parts.clear();
+      save_file.clear();
+      rng.clear();
+      msg_name.clear();
+      enc_mode = TaskUpload::YENC;
+      lpf = 5000;
     }
   };
 
@@ -103,35 +130,29 @@ namespace
       }
     }
 
-//    else if (!strcmp (element_name, "upload")) {
-//      mc.file_clear ();
-//      for (const char **k(attribute_names), **v(attribute_vals); *k; ++k, ++v) {
-//             if (!strcmp (*k,"author"))  mc.a.author  = *v;
-//        else if (!strcmp (*k,"subject")) mc.a.subject = *v;
-//        else if (!strcmp (*k,"server"))  mc.server    = *v;
-//        else if (!strcmp (*k,"domain"))  mc.domain    = *v;
-//        else if (!strcmp (*k,"queue"))   mc.queue     = *v;
-//        else if (!strcmp (*k,"lpf"))     mc.lpf       = atoi(*v);
-//      }
-//    }
-
-    else if (!strcmp (element_name, "segment")) {
+    else if (!strcmp (element_name, "upload")) {
+      mc.file_clear ();
+      for (const char **k(attribute_names), **v(attribute_vals); *k; ++k, ++v) {
+             if (!strcmp (*k,"server"))     mc.server    = *v;
+        else if (!strcmp (*k,"poster"))     mc.a.author = *v;
+        else if (!strcmp (*k,"subject"))    mc.a.subject = *v;
+        else if (!strcmp (*k,"msg"))        mc.msg_name  = *v;
+        else if (!strcmp (*k,"save-file"))  mc.save_file = *v;
+        else if (!strcmp (*k,"lpf"))        mc.lpf       = atoi(*v);
+        else if (!strcmp (*k,"enc-mode"))   mc.enc_mode  = (TaskUpload::EncodeMode) atoi (*v);
+
+      }
+    }
+
+    else if (!strcmp (element_name, "segment") || !strcmp (element_name, "part")) {
       mc.bytes = 0;
       mc.number = 0;
       for (const char **k(attribute_names), **v(attribute_vals); *k; ++k, ++v) {
-             if (!strcmp (*k,"bytes"))  mc.bytes = strtoul (*v,0,10);
+             if (!strcmp (*k,"bytes"))  mc.bytes  = strtoul (*v,0,10);
         else if (!strcmp (*k,"number")) mc.number = atoi (*v);
+        else if (!strcmp (*k,"rng"))    mc.rng    = *v;
       }
     }
-
-//    else if (!strcmp (element_name, "part")) {
-//      mc.bytes = 0;
-//      mc.number = 0;
-//      for (const char **k(attribute_names), **v(attribute_vals); *k; ++k, ++v) {
-//             if (!strcmp (*k,"bytes"))  mc.bytes = strtoul (*v,0,10);
-//        else if (!strcmp (*k,"number")) mc.number = atoi (*v);
-//      }
-//    }
   }
 
   // Called for close tags </foo>
@@ -145,7 +166,6 @@ namespace
     if (!strcmp(element_name, "group"))
     {
       mc.groups.insert (Quark (mc.text));
-//      mc.groups_str.push_back(mc.text);
     }
 
     else if (!strcmp(element_name, "segment") && mc.number && !mc.text.empty()) {
@@ -157,14 +177,15 @@ namespace
       mc.parts.add_part (mc.number, mid, mc.bytes);
     }
 
-//    else if (!strcmp(element_name, "part") && mc.number && !mc.text.empty()) {
-//      mc.a.message_id = mc.text;
-//      TaskUpload::Needed n;
-//      n.partno = mc.number;
-//      n.message_id = mc.text;
-//      n.bytes = mc.bytes;
-//      mc.needed_parts.insert(std::pair<int, TaskUpload::Needed>(mc.number,n));
-//    }
+    else if (!strcmp(element_name, "part") && !mc.rng.empty() && mc.number && !mc.text.empty()) {
+      mc.a.message_id = mc.text;
+      TaskUpload::Needed n;
+      n.partno = mc.number;
+      n.message_id = mc.text;
+      n.mid = mc.rng;
+      n.bytes = mc.bytes;
+      mc.needed_parts.insert(std::pair<int, TaskUpload::Needed>(mc.number,n));
+    }
 
     else if (!strcmp(element_name,"path"))
       mc.path = mc.text;
@@ -185,25 +206,29 @@ namespace
       mc.tasks.push_back (new TaskArticle (mc.ranks, mc.gs, mc.a, mc.cache, mc.read, 0, TaskArticle::DECODE, p));
 
     }
-//    else if (!strcmp (element_name, "upload"))
-//    {
-//      debug("adding taskupload from nzb.\n");
-//      foreach_const (quarks_t, mc.groups, git)
-//        mc.a.xref.insert (mc.server, *git, 0);
-//      TaskUpload::UploadInfo format;
-//      format.comment1 = true;
-//      format.lpf = mc.lpf;
-//
-//      TaskUpload* tmp = new TaskUpload (mc.path, mc.server, mc.encode_cache,mc.a,
-//                                        format, 0, 0, TaskUpload::YENC);
-//
-//      /* build needed parts */
-//      foreach (TaskUpload::needed_t, mc.needed_parts, it)
-//        tmp->needed().insert(*it);
-//      tmp->build_needed_tasks();
-//
-//      mc.tasks.push_back (tmp);
-//    }
+    else if (!strcmp (element_name, "upload"))
+    {
+      debug("adding taskupload from nzb.\n");
+      foreach_const (quarks_t, mc.groups, git)
+        mc.a.xref.insert (mc.server, *git, 0);
+      TaskUpload::UploadInfo format;
+      format.lpf = mc.lpf;
+      format.total = std::max(1, (int) (((long)mc.bytes + (mc.lpf*bpl[TaskUpload::YENC]-1)) / (mc.lpf*bpl[TaskUpload::YENC])));
+
+      char buf[2048];
+      mc.encode_cache.get_filename (buf, Quark(mc.msg_name));
+      GMimeMessage * msg = import_msg(StringView(buf));
+
+      TaskUpload* tmp = new TaskUpload (mc.path, mc.server, mc.encode_cache, mc.a, // subject and author
+                                        format, msg, 0, mc.enc_mode);
+
+      /* build needed parts */
+      foreach (TaskUpload::needed_t, mc.needed_parts, it)
+        tmp->needed().insert(*it);
+      tmp->build_needed_tasks();
+
+      mc.tasks.push_back (tmp);
+    }
   }
 
   void text (GMarkupParseContext *context    UNUSED,
@@ -284,13 +309,20 @@ namespace
   }
 }
 
-/* Saves all current tasks to tasks.nzb */
+/* Saves all current tasks to ~/.$PAN_HOME/tasks.nzb */
 std::ostream&
 NZB :: nzb_to_xml (std::ostream             & out,
                    const std::vector<Task*> & tasks)
 {
   int depth (0);
 
+//  // init rng
+//  MTRand rng;
+//  rng.seed();
+
+  char buf[2048];
+  char name[2048];
+
   out << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
       << "<!DOCTYPE nzb PUBLIC \"-//newzBin//DTD NZB 1.0//EN\" \"http://www.newzbin.com/DTD/nzb/nzb-1.0.dtd\";>\n"
       << indent(depth++)
@@ -353,55 +385,71 @@ NZB :: nzb_to_xml (std::ostream             & out,
       out << indent(--depth) << "</segments>\n";
       out << indent(--depth) << "</file>\n";
     }
-//    else
-//    { // handle upload tasks
-//      TaskUpload * task (dynamic_cast<TaskUpload*>(*it));
-//      // not an upload task, move on
-//      if (!task) continue;
-//
-//      const Article& a (task->get_article());
-//
-//      out << indent(depth)
-//          << "<upload" << " author=\"";
-//      escaped (out, task->_author);
-//      out  << "\" subject=\"";
-//      escaped (out, task->_subject);
-//      out  << "\" server=\"";
-//      escaped (out, task->_server.to_string());
-//
-//      ///TODO _save_file
-//      out  << "\" lpf=\"";
-//      char buf[256];
-//      g_snprintf(buf,sizeof(buf),"%d",task->_lpf);
-//      escaped (out, buf);
-//      out <<"\">\n";
-//      ++depth;
-//      out << indent(depth)
-//          << "<path>" << task->_filename << "</path>\n";
-//      out  << indent(depth) << "<groups>\n";
-//
-//      ++depth;
-//      foreach_const (Xref, task->_article.xref,  xit)
-//        out << indent(depth) << "<group>" << xit->group << "</group>\n";
-//      --depth;
-//
-//      out << indent(--depth) << "</groups>\n";
-//      out  << indent(depth) << "<parts>\n";
-//      ++depth;
-//
-//      foreach (TaskUpload::needed_t, task->_needed, it)
-//      {
-//        out << indent(depth)
-//            << "<part" << " bytes=\"" << it->second.bytes << '"'
-//            << " number=\"" << it->second.partno << '"'
-//            << ">";
-//        escaped(out, it->second.message_id);
-//        out  << "</part>\n";
-//      }
-//      --depth;
-//      out  << indent(depth) << "</parts>\n";
-//      out << indent(depth) << "</upload>\n";
-//    }
+    else
+    { // handle upload tasks
+      TaskUpload * task (dynamic_cast<TaskUpload*>(*it));
+      // not an upload task, move on
+      if (!task) continue;
+
+      const Article& a (task->get_article());
+
+      out << indent(depth)
+          << "<upload" << " poster=\"";
+      escaped (out, task->_author);
+      out << "\" subject=\"";
+      escaped (out, task->_subject);
+      out << "\" save-file=\"";
+      escaped (out, task->_save_file);
+      out  << "\" server=\"";
+      escaped (out, task->_server.to_string());
+
+      out  << "\" msg=\"";
+      /* save gmimemessage from task */
+      g_snprintf(name,sizeof(name),"%s_msg_%d.%d",task->_basename.c_str(), task->_queue_pos, task->_bytes);
+      task->_cache.get_filename (buf, name);
+      std::ofstream outfile (buf, std::ios::out | std::ios::trunc);
+      char * body (g_mime_object_to_string ((GMimeObject *) task->_msg));
+      outfile << body;
+      outfile.close();
+      g_free(body);
+      escaped (out, name);
+
+      out  << "\" enc-mode=\"";
+      g_snprintf(buf,sizeof(buf),"%d",task->_encode_mode);
+      escaped (out, buf);
+      out  << "\" lpf=\"";
+      g_snprintf(buf,sizeof(buf),"%d",task->_lpf);
+      escaped (out, buf);
+      out <<"\">\n";
+
+      ++depth;
+      out << indent(depth)
+          << "<path>" << task->_filename << "</path>\n";
+      out  << indent(depth) << "<groups>\n";
+
+      ++depth;
+      foreach_const (Xref, task->_article.xref,  xit)
+        out << indent(depth) << "<group>" << xit->group << "</group>\n";
+      --depth;
+
+      out << indent(--depth) << "</groups>\n";
+      out  << indent(depth) << "<parts>\n";
+      ++depth;
+
+      foreach (TaskUpload::needed_t, task->_needed, it)
+      {
+        out << indent(depth)
+            << "<part" << " bytes=\""<< it->second.bytes << '"'
+            << " number=\""          << it->second.partno << '"'
+            << " rng=\""             << it->second.mid << '"'
+            << ">";
+        escaped(out, it->second.message_id);
+        out  << "</part>\n";
+      }
+      --depth;
+      out  << indent(depth) << "</parts>\n";
+      out << indent(depth) << "</upload>\n";
+    }
   }
   out << indent(--depth) << "</nzb>\n";
   return out;
@@ -409,14 +457,14 @@ NZB :: nzb_to_xml (std::ostream             & out,
 
 /* Saves upload_list to XML file for distribution */
 std::ostream&
-NZB :: upload_list_to_xml_file (std::ostream& out,
+NZB :: upload_list_to_xml_file (std::ostream   & out,
                    const std::vector<Article*> & tasks)
 {
 int depth (0);
 
   foreach_const (std::vector<Article*>, tasks, it)
   {
-    Article * task (dynamic_cast<Article*>(*it));
+    Article * task (*it);
     const Article& a (*task);
 
     out << indent(depth++)
@@ -462,7 +510,7 @@ int depth (0);
 
 /* Saves selected article-info to a chosen XML file */
 std::ostream&
-NZB :: nzb_to_xml_file (std::ostream             & out,
+NZB :: nzb_to_xml_file (std::ostream        & out,
                    const std::vector<Task*> & tasks)
 {
   int depth (0);
@@ -508,7 +556,7 @@ NZB :: nzb_to_xml_file (std::ostream             & out,
 
       // serialize this part
       out << indent(depth)
-          << "<segment" << " bytes=\"" << it.bytes() << '"'
+          << "<segment" << " bytes=\""  << it.bytes() << '"'
                         << " number=\"" << it.number() << '"'
                         << ">";
       escaped(out, mid);
diff --git a/pan/tasks/nzb.h b/pan/tasks/nzb.h
index 2314768..c56ba23 100644
--- a/pan/tasks/nzb.h
+++ b/pan/tasks/nzb.h
@@ -22,6 +22,7 @@
 
 #include <vector>
 #include <pan/data/data.h>
+#include <pan/usenet-utils/MersenneTwister.h>
 
 namespace pan
 {
@@ -62,6 +63,8 @@ namespace pan
     static std::ostream&  nzb_to_xml_file (std::ostream             & out,
                                            const std::vector<Task*> & tasks);
 
+
+
   };
 }
 
diff --git a/pan/tasks/task-upload.cc b/pan/tasks/task-upload.cc
index 184fc80..8f4525a 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -88,17 +88,16 @@ TaskUpload :: TaskUpload (const std::string         & filename,
   _encoder_has_run (false),
   _encode_mode(enc),
   _all_bytes(0),
-  _format(format),
   _lpf(format.lpf),
   _queue_pos(0),
   _msg (msg),
-  _total_parts(format.total)
+  _total_parts(format.total),
+  _save_file(format.save_file)
 {
 
   struct stat sb;
   stat(filename.c_str(),&sb);
   _bytes = sb.st_size;
-//  update_work ();
   _state.set_paused();
 }
 
@@ -113,10 +112,7 @@ TaskUpload :: build_needed_tasks()
   }
   _cache.reserve(_mids);
 
-   /* build new master subject */
-  char sub[2048];
-  g_snprintf(sub,2048,"%s - \"%s\" - (%03d/%03d)", _subject.c_str(), _basename.c_str(), 1, _total_parts);
-  _master_subject = sub;
+  update_master_subject ();
 
 }
 
@@ -133,7 +129,7 @@ TaskUpload :: update_work (NNTP* checkin_pending)
   }
 
   /* only need encode if mode is NOT plain */
-  if (!_encoder && !_encoder_has_run)
+  if (!_encoder_has_run)
   {
     _state.set_need_encoder();
   }
@@ -157,6 +153,21 @@ TaskUpload :: update_work (NNTP* checkin_pending)
 ***/
 
 void
+TaskUpload :: update_subjects()
+{
+  _total_parts = std::max(1, (int) (((long)_bytes + (_lpf*bpl[_encode_mode]-1)) / (_lpf*bpl[_encode_mode])));
+  update_master_subject ();
+}
+
+void TaskUpload :: update_master_subject()
+{
+  /* build new master subject */
+  char sub[2048];
+  g_snprintf(sub,2048,"%s - \"%s\" - (%03d/%03d)", _subject.c_str(), _basename.c_str(), 1, _total_parts);
+  _master_subject = sub;
+}
+
+void
 TaskUpload :: prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::string& d)
 {
     std::stringstream out;
@@ -175,6 +186,8 @@ TaskUpload :: prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::st
     out << body << "\n";
     out << d;
     d = out.str();
+
+    g_free(body);
 }
 
 void
@@ -206,6 +219,7 @@ TaskUpload :: use_nntp (NNTP * nntp)
     _cache.get_data(data,needed->message_id.c_str());
     prepend_headers(_msg,needed, data);
     nntp->post(StringView(data), this);
+
     update_work ();
   }
 }
@@ -344,7 +358,6 @@ TaskUpload :: use_encoder (Encoder* encoder)
   init_steps(100);
   _state.set_working();
 
-    ///TODO support other encode modes by choice of user
   _encoder->enqueue (this, &_cache, &_article, _filename, _basename, _master_subject, _lpf, _encode_mode);
   debug ("encoder thread was free, enqueued work");
 }
@@ -393,6 +406,9 @@ TaskUpload :: on_worker_done (bool cancelled)
   _encoder = 0;
   update_work ();
   check_in (d);
+
+  /* update stats */
+  update_subjects();
 }
 
 TaskUpload :: ~TaskUpload ()
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index 8bcd1f7..f42a9b7 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -153,13 +153,15 @@ namespace pan
       friend class Encoder;
       friend class PostUI;
       friend class Queue;
+      friend class NZB;
+
       Encoder * _encoder;
       bool _encoder_has_run;
       std::string _filename;
       std::string _basename;
       TaskUpload::EncodeMode _encode_mode;
       std::string _subject, _master_subject, _author;
-      UploadInfo _format;
+      std::string _save_file;
       int _total_parts, _needed_parts;
       unsigned long _bytes;
       EncodeCache& _cache;
@@ -175,6 +177,8 @@ namespace pan
       void update_work (NNTP * checkin_pending = 0);
 
     public:
+      void set_encoder_done (bool setme) { _encoder_has_run = setme; }
+      needed_t& needed() { return _needed; }
       void build_needed_tasks();
       void wakeup() { _state.set_working(); update_work(); }
 
@@ -182,6 +186,8 @@ namespace pan
       std::set<int> _wanted;
       GMimeMessage * _msg;
       void prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::string& d);
+      void update_subjects();
+      void update_master_subject();
 
   };
 }
diff --git a/pan/usenet-utils/Makefile.am b/pan/usenet-utils/Makefile.am
index 3d895d2..65c45d8 100644
--- a/pan/usenet-utils/Makefile.am
+++ b/pan/usenet-utils/Makefile.am
@@ -11,7 +11,7 @@ libusenetutils_a_SOURCES = \
  scorefile.cc \
  text-massager.cc \
  url-find.cc \
- MersenneTwister.h 
+ rng.cc
 
 noinst_HEADERS = \
  defgroup.h \
@@ -22,7 +22,8 @@ noinst_HEADERS = \
  numbers.h \
  scorefile.h \
  text-massager.h \
- url-find.h 
+ url-find.h \
+ rng.h
 
 #noinst_PROGRAMS = \
 # gnksa-test \
@@ -33,7 +34,7 @@ noinst_HEADERS = \
 # url-find-test
 
 #TESTS = $(noinst_PROGRAMS)
-#TEST_LDADD = ./libusenetutils.a ../general/libgeneralutils.a @GMIME_LIBS@ 
+#TEST_LDADD = ./libusenetutils.a ../general/libgeneralutils.a @GMIME_LIBS@
 # GLIB_LIBS@
 #gnksa_test_SOURCES = gnksa-test.cc
 #gnksa_test_LDADD = $(TEST_LDADD)
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index fff1b47..20aee85 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -55,6 +55,9 @@
 #define YENC_SHIFT             42
 #define YENC_QUOTE_SHIFT       64
 
+/* uudeview encoding defines */
+static int bpl[3] = { 45, 45, 128 };
+
 namespace pan
 {
   /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]