[pan2: 6/23] Create nzb file from list of articles.
- From: Petr Kovář <pmkovar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2: 6/23] Create nzb file from list of articles.
- Date: Sun, 29 May 2011 13:04:03 +0000 (UTC)
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]