[pan2: 6/23] Create nzb file from list of articles.



commit 0f9790bb35104259736ee76cf206ab37f25a1cf6
Author: Heinrich Mueller <eddie_v gmx de>
Date:   Thu May 5 18:05:46 2011 -0600

    Create nzb file from list of articles.

 pan/gui/actions.cc     |    6 ++++
 pan/gui/gui.cc         |   64 +++++++++++++++++++++++++++++++++++++++++++++++-
 pan/gui/gui.h          |    3 +-
 pan/gui/header-pane.cc |    1 +
 pan/gui/pan-ui.h       |    1 +
 pan/gui/pan.ui.h       |    2 +
 pan/tasks/nzb.cc       |   63 +++++++++++++++++++++++++++++++++++++++++++++++
 pan/tasks/nzb.h        |    5 +++
 pan/tasks/queue.h      |    2 +-
 9 files changed, 144 insertions(+), 3 deletions(-)
---
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index ba34b77..51d89dd 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -106,6 +106,7 @@ namespace
   void do_unsubscribe_selected_groups  (GtkAction*) { pan_ui->do_unsubscribe_selected_groups(); }
   void do_save_articles                (GtkAction*) { pan_ui->do_save_articles(); }
   void do_save_articles_from_nzb       (GtkAction*) { pan_ui->do_save_articles_from_nzb(); }
+  void do_save_articles_to_nzb	       (GtkAction*) { pan_ui->do_save_articles_to_nzb(); }
   void do_print                        (GtkAction*) { pan_ui->do_print(); }
   void do_import_tasks                 (GtkAction*) { pan_ui->do_import_tasks(); }
   void do_cancel_latest_task           (GtkAction*) { pan_ui->do_cancel_latest_task(); }
@@ -324,6 +325,11 @@ namespace
       N_("Save Articles from this NZB"),
       G_CALLBACK(do_save_articles_from_nzb) },
 
+    { "save-articles-to-nzb", GTK_STOCK_SAVE,
+      N_("_Save Articles to an NZB File..."), NULL,
+      N_("Save Articles to an NZB File"),
+      G_CALLBACK(do_save_articles_to_nzb) },
+
     { "print", GTK_STOCK_PRINT,
       NULL, "<control>P",
       NULL,
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 79843ff..7743777 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -21,6 +21,7 @@
 #include <map>
 #include <string>
 #include <sstream>
+#include <fstream>
 extern "C" {
   #include <sys/types.h> // for chmod
   #include <sys/stat.h> // for chmod
@@ -498,7 +499,7 @@ GUI :: disable_accelerators_when_focused (GtkWidget * w) const
 
 namespace
 {
-  static std::string prev_path;
+  static std::string prev_path, prev_file;
 }
 
 std::string
@@ -528,6 +529,39 @@ GUI :: prompt_user_for_save_path (GtkWindow * parent, const Prefs& prefs)
   return path;
 }
 
+std::string
+GUI :: prompt_user_for_filename (GtkWindow * parent, const Prefs& prefs)
+{
+	
+  if (prev_path.empty())
+    prev_path = prefs.get_string ("default-save-attachments-path", g_get_home_dir ());
+  if (!file :: file_exists (prev_path.c_str()))
+  prev_path = g_get_home_dir ();
+    prev_file = std::string(_("Untitled.nzb"));
+    
+  GtkWidget * w = gtk_file_chooser_dialog_new (_("Save NZB File as"),
+				      parent,
+				      GTK_FILE_CHOOSER_ACTION_SAVE,
+				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+				      NULL);
+	gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (w), TRUE);
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), prev_path.c_str());
+	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (w), prev_file.c_str());
+	
+	std::string file;
+	const int response (gtk_dialog_run (GTK_DIALOG(w)));
+	if (response == GTK_RESPONSE_ACCEPT) {
+		char *tmp;
+		tmp = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w));
+		file=tmp;
+		g_free (tmp);
+	}
+	gtk_widget_destroy (w);
+
+  return file;
+}
+
 void GUI :: do_save_articles ()
 {
   std::string path;
@@ -544,6 +578,34 @@ void GUI :: do_save_articles ()
   }
 }
 
+
+void GUI :: do_save_articles_to_nzb ()
+{
+
+  std::string path;
+  const std::vector<const Article*> articles (_header_pane->get_full_selection_v ());
+
+  std::vector<Article> copies;
+  copies.reserve (articles.size());
+  foreach_const (std::vector<const Article*>, articles, it)
+    copies.push_back (**it);
+
+  const std::string file (GUI :: prompt_user_for_filename (get_window(_root), _prefs));
+    if (!file.empty()) {
+      Queue::tasks_t tasks;
+      std::string emptystring;
+      foreach_const (std::vector<Article>, copies, it)
+        tasks.push_back (new TaskArticle (_data, _data, *it, _cache, _data, 0, TaskArticle::RAW,emptystring));
+    
+          // write them to a file
+          std::ofstream tmp(file.c_str());
+          if (tmp.good()) {
+            NZB :: nzb_to_xml_file (tmp, tasks); 
+            tmp.close();
+          }
+    }
+}
+
 namespace
 {
   struct SaveArticlesFromNZB: public Progress::Listener
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 1cf817e..006ed63 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -79,6 +79,7 @@ namespace pan
       virtual void do_prompt_for_charset ();
       virtual void do_save_articles ();
       virtual void do_save_articles_from_nzb ();
+      virtual void do_save_articles_to_nzb ();
       virtual void do_print ();
       virtual void do_quit ();
       virtual void do_import_tasks ();
@@ -159,7 +160,7 @@ namespace pan
 
     public:
       static std::string prompt_user_for_save_path (GtkWindow * parent, const Prefs& prefs);
-
+	  static std::string prompt_user_for_filename  (GtkWindow * parent, const Prefs& prefs);
 
     private: // Queue::Listener
       friend class Queue;
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index f2fa81e..ab62206 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -1564,6 +1564,7 @@ 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",
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index 6e202eb..47c7ab5 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -33,6 +33,7 @@ namespace pan
     virtual void do_prompt_for_charset () = 0;
     virtual void do_save_articles () = 0;
     virtual void do_save_articles_from_nzb () = 0;
+    virtual void do_save_articles_to_nzb () = 0;
     virtual void do_print () = 0;
     virtual void do_import_tasks () = 0;
     virtual void do_cancel_latest_task () = 0;
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index 1b8d14b..7284308 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -114,6 +114,7 @@ const char * fallback_ui_file =
 "      <menu action='article-actions-menu'>\n"
 "        <menuitem action='save-articles' />\n"
 "        <menuitem action='save-articles-from-nzb' />\n"
+"        <menuitem action='save-articles-to-nzb' />\n"
 "        <separator />\n"
 "        <menuitem action='read-selected-article' />\n"
 "        <menuitem action='download-selected-article' />\n"
@@ -175,6 +176,7 @@ const char * fallback_ui_file =
 "  <popup name='header-pane-popup'>\n"
 "    <menuitem action='save-articles' />\n"
 "    <menuitem action='save-articles-from-nzb' />\n"
+"    <menuitem action='save-articles-to-nzb' />\n"
 "    <separator />\n"
 "    <menuitem action='read-selected-article' />\n"
 "    <menuitem action='download-selected-article' />\n"
diff --git a/pan/tasks/nzb.cc b/pan/tasks/nzb.cc
index a63a575..b27e8b4 100644
--- a/pan/tasks/nzb.cc
+++ b/pan/tasks/nzb.cc
@@ -215,6 +215,7 @@ namespace
   }
 }
 
+/* Saves all current tasks to tasks.nzb */
 std::ostream&
 NZB :: nzb_to_xml (std::ostream             & out,
                    const std::vector<Task*> & tasks)
@@ -286,3 +287,65 @@ NZB :: nzb_to_xml (std::ostream             & out,
   out << indent(--depth) << "</nzb>\n";
   return out;
 }
+
+/* Saves selected files to a chosen XML file */
+std::ostream&
+NZB :: nzb_to_xml_file (std::ostream             & out,
+                   const std::vector<Task*> & tasks)
+{
+  int depth (0);
+
+  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++)
+      << "<nzb xmlns=\"http://www.newzbin.com/DTD/2003/nzb\";>\n";
+
+  foreach_const (tasks_t, tasks, it)
+  {
+    TaskArticle * task (dynamic_cast<TaskArticle*>(*it));
+    if (!task) // not a download task...
+      continue;
+
+    const Article& a (task->get_article());
+    out << indent(depth++)
+        << "<file" << " poster=\"";
+    escaped (out, a.author.to_view());
+    out  << "\" date=\"" << a.time_posted << "\" subject=\"";
+    escaped (out, a.subject.to_view()) << "\">\n";
+
+    // what groups was this crossposted in?
+    quarks_t groups;
+    foreach_const (Xref, a.xref, xit)
+      groups.insert (xit->group);
+    out << indent(depth++) << "<groups>\n";
+    foreach_const (quarks_t, groups, git)
+      out << indent(depth) << "<group>" << *git << "</group>\n";
+    out << indent(--depth) << "</groups>\n";
+
+    // now for the parts...
+    out << indent(depth++) << "<segments>\n";
+    for (Article::part_iterator it(a.pbegin()), end(a.pend()); it!=end; ++it)
+    {
+      std::string mid = it.mid ();
+
+      // remove the surrounding < > as per nzb spec
+      if (mid.size()>=2 && mid[0]=='<') {
+        mid.erase (0, 1);
+        mid.resize (mid.size()-1);
+      }
+
+      // serialize this part
+      out << indent(depth)
+          << "<segment" << " bytes=\"" << it.bytes() << '"'
+                        << " number=\"" << it.number() << '"'
+                        << ">";
+      escaped(out, mid);
+      out  << "</segment>\n";
+    }
+    out << indent(--depth) << "</segments>\n";
+    out << indent(--depth) << "</file>\n";
+  }
+
+  out << indent(--depth) << "</nzb>\n";
+  return out;
+}
diff --git a/pan/tasks/nzb.h b/pan/tasks/nzb.h
index 80efd32..0d9eec1 100644
--- a/pan/tasks/nzb.h
+++ b/pan/tasks/nzb.h
@@ -53,6 +53,11 @@ namespace pan
 
     static std::ostream&  nzb_to_xml (std::ostream             & out,
                                       const std::vector<Task*> & tasks);
+                                      
+    
+    static std::ostream&  nzb_to_xml_file (std::ostream             & out,
+                                      const std::vector<Task*> & tasks);
+
   };
 }
 
diff --git a/pan/tasks/queue.h b/pan/tasks/queue.h
index db1e13b..09b97ef 100644
--- a/pan/tasks/queue.h
+++ b/pan/tasks/queue.h
@@ -25,8 +25,8 @@
 #include <vector>
 #include <pan/general/macros.h> // for UNUSED
 #include <pan/general/map-vector.h>
-#include <pan/general/quark.h>
 #include <pan/tasks/decoder.h>
+#include <pan/general/quark.h>
 #include <pan/tasks/nntp-pool.h>
 #include <pan/tasks/socket.h>
 #include <pan/tasks/adaptable-set.h>



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