[pan2: 27/68] Bug403797: allow subject line use in save path



commit c58f74413585a40a7716d203fbcee1f02d5a1d1f
Author: K. Haley <haleykd users sf net>
Date:   Sat Jul 31 17:47:08 2010 -0600

    Bug403797: allow subject line use in save path
    
    Adds %s expansion variable to the save path dialog.  It will be
    repalced by a cleaned up version of the article subject.

 pan/gui/save-ui.cc                |   26 +++++++++++++++-
 pan/usenet-utils/text-massager.cc |   57 +++++++++++++++++++++++++++++++++++++
 pan/usenet-utils/text-massager.h  |    8 +++++
 3 files changed, 89 insertions(+), 2 deletions(-)
---
diff --git a/pan/gui/save-ui.cc b/pan/gui/save-ui.cc
index e13eda5..3af574a 100644
--- a/pan/gui/save-ui.cc
+++ b/pan/gui/save-ui.cc
@@ -27,6 +27,7 @@ extern "C" {
 #include <pan/icons/pan-pixbufs.h>
 #include <pan/tasks/task-article.h>
 #include <pan/tasks/queue.h>
+#include <pan/usenet-utils/text-massager.h>
 #include "hig.h"
 #include "pad.h"
 #include "pan-file-entry.h"
@@ -52,11 +53,25 @@ namespace
     return val;
   }
 
+  std::string expand_download_dir_subject (const char * dir, const char * subjectline)
+  {
+    std::string val (dir);
+    std::string sub (subject_to_path(subjectline));
+    std::string::size_type pos;
+
+    while (((pos = val.find ("%s"))) != val.npos)
+      val.replace (pos, 2, sub.c_str(), sub.length());
+
+    return val;
+  }
+
+
   void
   show_group_substitution_help_dialog (gpointer window)
   {
     const char * str = _("%g - group as one directory (alt.binaries.pictures.trains)\n"
                          "%G - group as nested directory (/alt/binaries/pictures/trains)\n"
+                         "%s - subject line excerpt\n"
                          " \n"
                          "\"/home/user/News/Pan/%g\" becomes\n"
                          "\"/home/user/News/Pan/alt.binaries.pictures.trains\", and\n"
@@ -89,6 +104,7 @@ SaveDialog :: response_cb (GtkDialog * dialog,
   if (response == GTK_RESPONSE_OK)
   {
     SaveDialog * self (static_cast<SaveDialog*>(user_data));
+    bool subject_in_path = false;
 
     // set the path mode based on what widgets exist & are set
     GtkWidget * gr (self->_save_group_path_radio);
@@ -99,14 +115,16 @@ SaveDialog :: response_cb (GtkDialog * dialog,
       path_mode = PATH_ENTRY;
 
     // get the save path
-    std::string path;
+    std::string path, opath;
     if (path_mode == PATH_GROUP)
       path = (const char*) g_object_get_data (G_OBJECT(gr), "default-group-save-path");
     else if (path_mode == PATH_ENTRY)  {
       path = pan :: file_entry_get (self->_save_path_entry);
       self->_prefs.set_string ("default-save-attachments-path", path);
     }
-    path = expand_download_dir (path.c_str(), self->_group.to_view());
+    path = opath = expand_download_dir (path.c_str(), self->_group.to_view());
+    if (path.find("%s") != path.npos)
+      subject_in_path = true;
 
     // get the save mode
     int save_mode;
@@ -118,6 +136,9 @@ SaveDialog :: response_cb (GtkDialog * dialog,
     // make the tasks... 
     Queue::tasks_t tasks;
     foreach_const (std::vector<Article>, self->_articles, it)
+    {
+      if (subject_in_path)
+        path = expand_download_dir_subject(opath.c_str(), it->subject);
       tasks.push_back (new TaskArticle (self->_server_rank,
                                         self->_group_server,
                                         *it,
@@ -126,6 +147,7 @@ SaveDialog :: response_cb (GtkDialog * dialog,
                                         0,
                                         TaskArticle::SaveMode(save_mode),
                                         path));
+    }
 
     // get the queue mode...
     Queue::AddMode queue_mode;
diff --git a/pan/usenet-utils/text-massager.cc b/pan/usenet-utils/text-massager.cc
index 7139331..8a74e8d 100644
--- a/pan/usenet-utils/text-massager.cc
+++ b/pan/usenet-utils/text-massager.cc
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <vector>
+#include <glib.h>
 extern "C" {
 #include <glib/gi18n.h>
 }
@@ -358,3 +359,59 @@ TextMassager :: rot13_inplace (char * text)
 
    return text;
 }
+
+std::string
+pan :: subject_to_path (const char * subjectline)
+{
+  gchar *str1, *str2;
+  std::string val (subjectline);
+  std::string::size_type pos;
+  //stupid hack to silence the compiler
+  GRegexCompileFlags cf0((GRegexCompileFlags)0);
+  GRegexMatchFlags mf0((GRegexMatchFlags)0);
+
+  // delete everything after the last hyphen
+  // (perhaps if >=3 hyphens, delete everything after the 2nd hyphen?)
+  if ((pos = val.rfind("-")) != val.npos)
+    val.erase(pos);
+
+  // strip out newspost/Xnews-style multi-part strings
+  GRegex *mp1 =g_regex_new(" *[Ff]ile [0-9]+ *of *[0-9]+[: ]?", cf0, mf0, NULL);
+  str1 = g_regex_replace_literal(mp1, val.c_str(), -1, 0, "", mf0, NULL);
+  g_regex_unref(mp1);
+
+  // and the rest
+  GRegex *mp2 =g_regex_new(" *[\[(]?[0-9]* *(of|/) *[0-9]+.", cf0, mf0, NULL);
+  str2 = g_regex_replace_literal(mp2, str1, -1, 0, "", mf0, NULL);
+  g_free(str1);
+  g_regex_unref(mp2);
+
+  // try to strip out the filename (fails if it contains spaces)
+  GRegex *fn =g_regex_new("(\"*[^ ]*\"* yEnc.*)|(\".+\")?", cf0, mf0, NULL);
+  str1 = g_regex_replace_literal(fn, str2, -1, 0, "", mf0, NULL);
+  g_free(str2);
+  g_regex_unref(fn);
+
+  // try to strip out any byte counts, and trailing whitespace
+  GRegex *cnt =g_regex_new("(\\[?[0-9]+ *([Bb]ytes|[Kk][Bb]?)\\]?| $)", cf0, mf0, NULL);
+  str2 = g_regex_replace_literal(cnt, str1, -1, 0, "", mf0, NULL);
+  g_free(str1);
+  g_regex_unref(cnt);
+
+  // remove any illegal / annoying characters
+  GRegex *badc =g_regex_new("(\\\\|/|\\<|\\>|\\||\\*)", cf0, mf0, NULL);
+  str1 = g_regex_replace_literal(badc, str2, -1, 0, "", mf0, NULL);
+  g_free(str2);
+  g_regex_unref(badc);
+
+  // remove any extraneous whitespace / underscores
+  GRegex *ext =g_regex_new("[ _][ _]+", cf0, mf0, NULL);
+  str2 = g_regex_replace_literal(ext, str1, -1, 0, "", mf0, NULL);
+  g_free(str1);
+  g_regex_unref(ext);
+
+  val=str2;
+  g_free(str2);
+  //std::cout << "\nSubject was: '" << subjectline << "'\nSubject now: '" << val << "'" << std::endl;
+  return val;
+}
diff --git a/pan/usenet-utils/text-massager.h b/pan/usenet-utils/text-massager.h
index 21874d1..a2c48d5 100644
--- a/pan/usenet-utils/text-massager.h
+++ b/pan/usenet-utils/text-massager.h
@@ -54,6 +54,14 @@ namespace pan
       int _wrap_column;
       char * _quote_characters;
   };
+
+ /**
+   * Used to convert a subject line to a path for saving articles.
+   *
+   * @ingroup usenet_utils
+   */
+  std::string subject_to_path (const char * subjectline);
+
 }
 
 #endif



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