[pan2/bug_102402] improvements
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/bug_102402] improvements
- Date: Tue, 26 Jun 2012 21:50:33 +0000 (UTC)
commit 208401655a6284512c0303641b5cc91b1c5495f0
Author: Heinrich MÃller <henmull src gnome org>
Date: Tue Jun 26 23:50:09 2012 +0200
improvements
pan/data-impl/data-impl.cc | 34 ++++--
pan/data-impl/data-impl.h | 22 ++++-
pan/data-impl/groups.cc | 36 ++++++-
pan/data-impl/server.cc | 80 +++++++++++--
pan/data/data.h | 202 +++++++++++++++++++++++++++++++--
pan/gui/actions.cc | 2 +-
pan/gui/pan.cc | 2 +-
pan/gui/server-ui.cc | 272 +++++++++++++++++++++++++++++++++++++++++++-
pan/gui/server-ui.h | 3 +
pan/gui/task-pane.cc | 4 +-
pan/tasks/socket.cc | 2 +-
11 files changed, 615 insertions(+), 44 deletions(-)
---
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index f6a5375..2aa37a0 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -77,10 +77,7 @@ DataImpl :: DataImpl (const StringView& cache_ext, Prefs& prefs, bool unit_test,
_prefs (prefs),
_descriptions_loaded (false),
newsrc_autosave_id (0),
- newsrc_autosave_timeout (0),
- xfer_autosave_id (0),
- xfer_autosave_timeout (0)
-
+ newsrc_autosave_timeout (0)
{
rebuild_backend ();
}
@@ -139,10 +136,23 @@ DataImpl :: load_xfer_files (const DataIO& data_io)
while (!in->fail() && in->getline (line))
{
StringView server;
- line.pop_token(server);
StringView val;
- line.pop_token (val);
- unsigned long bytes (atoi(val.str));
+ XferBytes bytes_array;
+ int cnt(0), line_cnt(1);
+ if (line.pop_token(server))
+ {
+
+ while (line.pop_token(val))
+ {
+ unsigned long bytes (atoi(val.str));
+ bytes_array.bytes[cnt++] = bytes;
+
+ }
+ bytes_array.update_timestamp(line_cnt%2==0 ? MONTHLY : DAILY, time(0));
+ set_server_xfer (server, bytes_array);
+ bytes_array.increment(0);
+ ++line_cnt;
+ }
}
delete in;
@@ -165,9 +175,15 @@ DataImpl :: save_xfer_files (DataIO& data_io) const
foreach_const (servers_t, _servers, sit)
{
const Quark& server (sit->first);
- const Server& s (sit->second);
- out << server<<" "<<s.xfer<<"\n";
+ Server s (sit->second);
+ s.xfer.increment(0);
+ out << server;
+ for (int i=0;i<5;++i)
+ out<<" "<<s.xfer.bytes[i];
+ out<<"\n";
}
+ out<<"\n";
+
data_io.write_done (&out);
}
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index ec0809a..6ea1435 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -55,7 +55,6 @@
namespace pan
{
typedef std::vector<const Article*> articles_t;
- typedef Data::PasswordData PasswordData;
/**
* File-based implementation of the `Data' backend interface.
@@ -157,7 +156,13 @@ namespace pan
virtual void set_server_article_expiration_age (const Quark & server,
int days);
- virtual void increment_server_xfer_count(const Quark& server, unsigned long bytes) ;
+ virtual void increment_server_xfer_count (const Quark& server, unsigned long bytes) ;
+
+ virtual void set_server_xfer (const Quark& server, XferBytes& bytes) ;
+
+ virtual void set_server_download_limit (const Quark& server, Rollup& rollup) ;
+
+ virtual void set_server_download_limit_action (const Quark& server, int& action) ;
virtual void save_server_info (const Quark& server);
@@ -193,6 +198,10 @@ namespace pan
virtual int get_server_article_expiration_age (const Quark & server) const;
+ virtual bool get_server_download_limit (const Quark & server, const TimeType& time_type, Rollup& rollup) const;
+
+ virtual int get_server_download_limit_action (const Quark & server) const;
+
/**
*** GROUPS
**/
@@ -205,9 +214,14 @@ namespace pan
typedef sorted_vector<Quark,true> unique_sorted_quarks_t;
typedef sorted_vector<Quark,true> groups_t;
+
+ public:
+
groups_t _moderated; // groups which are moderated
groups_t _nopost; // groups which do not allow posting
+ private:
+
typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> alpha_groups_t;
alpha_groups_t _subscribed; // subscribed groups, sorted alphabetically
alpha_groups_t _unsubscribed; // non-subscribed groups, sorted alphabetically
@@ -318,6 +332,10 @@ namespace pan
virtual char get_group_permission (const Quark & group) const;
virtual void group_get_servers (const Quark& group, quarks_t&) const;
virtual void server_get_groups (const Quark& server, quarks_t&) const;
+ virtual void server_get_groups_sorted (const Quark& servername, groups_t& addme) const;
+
+ virtual void server_get_nopost (const Quark&, std::set<Quark>& dest) const;
+ virtual void server_get_moderated (const Quark&, std::set<Quark>& dest) const;
/**
*** HEADERS
diff --git a/pan/data-impl/groups.cc b/pan/data-impl/groups.cc
index b9ef49c..a5dc09c 100644
--- a/pan/data-impl/groups.cc
+++ b/pan/data-impl/groups.cc
@@ -27,6 +27,7 @@
#include <map>
#include <set>
#include <vector>
+#include <algorithm> // set_union
#include <glib.h>
extern "C" {
@@ -232,7 +233,7 @@ DataImpl :: save_newsrc_files (DataIO& data_io) const
std::string newsrc_string;
alpha_groups_t::const_iterator sub_it (_subscribed.begin());
const alpha_groups_t::const_iterator sub_end(_subscribed.end());
- foreach_const (Server::groups_t, sit->second.groups, git) // for the groups in this server...
+ foreach_const (groups_t, sit->second.groups, git) // for the groups in this server...
{
const Quark& group (*git);
@@ -508,7 +509,7 @@ DataImpl :: add_groups (const Quark & server,
{
AlphabeticalQuarkOrdering o;
- Server::groups_t groups;
+ groups_t groups;
std::vector<Quark> tmp;
// make a groups_t from the added groups,
@@ -664,6 +665,37 @@ DataImpl :: server_get_groups (const Quark& servername, quarks_t& addme) const
}
void
+DataImpl :: server_get_groups_sorted (const Quark& servername, groups_t& addme) const
+{
+ const Server * server (find_server (servername));
+ if (server)
+ addme.insert (server->groups.begin(), server->groups.end());
+}
+
+void
+DataImpl :: server_get_nopost (const Quark& servername, std::set<Quark>& dest) const
+{
+ const Server * server (find_server (servername));
+ if (server && _nopost.size()!=0)
+ {
+ foreach_const (groups_t, server->groups, git)
+ foreach_const (groups_t, _nopost, pit)
+ if (*git==*pit) dest.insert(*pit);
+ }
+}
+void
+DataImpl :: server_get_moderated (const Quark& servername, std::set<Quark>& dest) const
+{
+ const Server * server (find_server (servername));
+ if (server && _moderated.size()!=0)
+ {
+ foreach_const (groups_t, server->groups, git)
+ foreach_const (groups_t, _moderated, pit)
+ if (*git == *pit) dest.insert(*pit);
+ }
+}
+
+void
DataImpl :: get_subscribed_groups (std::vector<Quark>& setme) const
{
setme.assign (_subscribed.begin(), _subscribed.end());
diff --git a/pan/data-impl/server.cc b/pan/data-impl/server.cc
index 89a93c7..f155785 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -215,19 +215,44 @@ DataImpl :: increment_server_xfer_count(const Quark& server, unsigned long bytes
{
Server * s (find_server (server));
assert (s);
-// mut.lock()
- s->xfer += bytes;
-// mut.unlock();
+ s->increment_xfer(bytes);
+}
+
+void
+DataImpl :: set_server_xfer (const Quark& server, XferBytes& bytes)
+{
+ Server * s (find_server (server));
+ assert (s);
+ s->xfer = bytes;
+}
+
+void
+DataImpl :: set_server_download_limit (const Quark& server, Rollup& rollup)
+{
+
+ Server * s (find_server (server));
+ assert (s);
+ if (rollup.time_type == DAILY)
+ s->daily_limit = rollup;
+ else
+ s->monthly_limit = rollup;
+}
+
+void
+DataImpl :: set_server_download_limit_action (const Quark& server, int& action)
+{
+
+ Server * s (find_server (server));
+ assert (s);
+ s->limit_action = action;
}
void
DataImpl :: save_server_info (const Quark& server)
{
-// std::cerr<<"find "<<server<<"\n";
-// Server * s (find_server (server));
-// assert (s);
+ Server * s (find_server (server));
+ assert (s);
save_server_properties (*_data_io, _prefs);
-
}
@@ -297,6 +322,32 @@ DataImpl :: get_server_trust (const Quark & server, int& setme) const
}
bool
+DataImpl :: get_server_download_limit (const Quark & server, const TimeType& type, Rollup & setme) const
+{
+ const Server * s (find_server (server));
+ const bool found (s);
+ if (found) {
+ if (type == DAILY)
+ setme = s->daily_limit;
+ else
+ setme = s->monthly_limit;
+ }
+
+ return found;
+}
+int
+DataImpl :: get_server_download_limit_action (const Quark & server) const
+{
+ const Server * s (find_server (server));
+ const bool found (s);
+ if (found) {
+ return s->limit_action;
+ }
+
+ return 0;
+}
+
+bool
DataImpl :: get_server_addr (const Quark & server,
std::string & setme_host,
int & setme_port) const
@@ -486,12 +537,12 @@ DataImpl :: load_server_properties (const DataIO& source)
s.max_connections = to_int (kv["connection-limit"], 2);
s.article_expiration_age = to_int(kv["expire-articles-n-days-old"], 31);
s.rank = to_int(kv["rank"], 1);
- s.xfer = to_int(kv["rank"], 0);
- int ssl(to_int(kv["use-ssl"], 0));
- s.ssl_support = ssl;
+ s.ssl_support = to_int(kv["use-ssl"], 0);
s.cert = kv["cert"];
- int trust(to_int(kv["trust"], 0));
- s.trust = trust;
+ s.trust = to_int(kv["trust"], 0);
+ s.daily_limit = Rollup::parse(kv["daily-limit"]);
+ s.monthly_limit = Rollup::parse(kv["monthly-limit"]);
+ s.limit_action = to_int(kv["limit-action"]);
s.newsrc_filename = kv["newsrc"];
if (s.newsrc_filename.empty()) { // set a default filename
std::ostringstream o;
@@ -556,7 +607,10 @@ else
<< indent(depth) << "<rank>" << s->rank << "</rank>\n"
<< indent(depth) << "<use-ssl>" << s->ssl_support << "</use-ssl>\n"
<< indent(depth) << "<trust>" << s->trust << "</trust>\n"
- << indent(depth) << "<cert>" << s->cert << "</cert>\n";
+ << indent(depth) << "<cert>" << s->cert << "</cert>\n"
+ << indent(depth) << "<daily-limit>" << s->daily_limit.literal() << "</daily-limit>\n"
+ << indent(depth) << "<monthly-limit>" << s->monthly_limit.literal() << "</monthly-limit>\n"
+ << indent(depth) << "<limit-action>" << s->limit_action << "</limit-action>\n";
*out << indent(--depth) << "</server>\n";
}
diff --git a/pan/data/data.h b/pan/data/data.h
index 007d41b..b0b2922 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -24,6 +24,8 @@
#include <list>
#include <map>
#include <vector>
+#include <sstream>
+#include <math.h>
#include <pan/general/macros.h>
#include <pan/general/quark.h>
@@ -35,6 +37,10 @@
#include <pan/data/cert-store.h>
#include <pan/data/server-info.h>
+extern "C" {
+ #include <glib/gi18n.h>
+}
+
#ifdef HAVE_GKR
#include <gnome-keyring-1/gnome-keyring.h>
@@ -173,16 +179,183 @@ namespace pan
public virtual ArticleReferences
{
+///TODO move to seperate header
+/*##############################*/
+
public:
+ /* holds gnome keyring password data */
struct PasswordData
{
Quark server;
StringView user;
-// StringView pw;
gchar* pw;
};
- public:
+ enum TimeType
+ {
+ DAILY, MONTHLY
+ };
+
+ // holds transferred bytes, from 0-4 : B, KB, MB, GB, TB
+ struct XferBytes
+ {
+ unsigned long bytes[5];
+ char* ref[5];
+ time_t timestamp;
+
+ void increment (unsigned long b)
+ {
+ bytes[0] += b;
+ // update array
+ for (int i=0;i<4;++i)
+ {
+ int cnt = bytes[i] / 1024;
+ bytes[i+1] += cnt;
+ bytes[i] -= cnt * 1024;
+ }
+ }
+
+ std::string get_bytes()
+ {
+ std::stringstream ret;
+ for (int i=4;i>0;--i)
+ {
+ if (bytes[i]!=0)
+ {
+ ret << bytes[i]<<" ";
+ ret << ref[i];
+ break;
+ }
+ }
+ return ret.str();
+ }
+
+ std::string type()
+ {
+ int idx=0;
+ for (int i=4;i>0;--i)
+ {
+ if (bytes[i]!=0)
+ {
+ idx = i;
+ break;
+ }
+ }
+ return ref[idx];
+ }
+
+ int type_literal()
+ {
+ int idx=0;
+ for (int i=4;i>0;--i)
+ {
+ if (bytes[i]!=0)
+ {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ }
+
+ unsigned long val()
+ {
+ int idx=0;
+ for (int i=4;i>0;--i)
+ {
+ if (bytes[i]!=0)
+ {
+ idx = i;
+ break;
+ }
+ }
+ return bytes[idx];
+ }
+
+ XferBytes() : timestamp(time(0))
+ {
+ ref[0]= _("Bytes");
+ ref[1]= _("KB");
+ ref[2]= _("MB");
+ ref[3]= _("GB");
+ ref[4]= _("TB");
+ for (int i=0;i<5;++i) bytes[i]=0;
+ }
+
+ // reset to 0 if timestamp is too old
+ void update_timestamp (const TimeType& time_type, time_t newtime)
+ {
+ time_t day (24*60*60);
+ bool reset (false);
+ if (time_type==Data::DAILY)
+ {
+ if (newtime-timestamp >= day) reset = true;
+ }
+ else
+ {
+ // hardcode to 30, don't care atm
+ if (newtime-timestamp >= day*30) reset = true;
+ }
+
+ if (reset)
+ {
+ for (int i=0;i<5;++i) bytes[i] = 0;
+ }
+ }
+ };
+
+ /* holds information about monthly rollup (download limit) */
+ struct Rollup
+ {
+
+ int type;
+ unsigned long val;
+ TimeType time_type;
+ time_t timestamp;
+
+ std::string literal() const
+ {
+ std::stringstream ret;
+ ret << type<<"@"<<val<<"$"<<timestamp;
+ return ret.str();
+ }
+
+ static Rollup parse(std::string input)
+ {
+ Rollup out;
+ size_t at (input.find("@"));
+ size_t dollar (input.find("$"));
+ out.type = atoi(input.substr(0,at).c_str());
+ out.val = atoi(input.substr(at+1, dollar).c_str());
+ out.timestamp = (time_t)atoi(input.substr(dollar+1, input.length()).c_str());
+ return out;
+ }
+
+ float percent (XferBytes& bytes)
+ {
+ float ret(0.0f);
+ int diff = type - bytes.type_literal();
+
+ float norm_a = type >= 0 ? val * pow (1024.0f , diff) : val / pow (1024.0f , diff);
+ ret = (bytes.bytes[type]/norm_a)*100.0f;
+ return ret;
+ }
+
+ std::string literal()
+ {
+ char* ref[5] = {_("Bytes"), _("KB"), _("MB"), _("GB"), _("TB") }; // dupe, todo: unite with xferbytes
+ std::stringstream out;
+ out << val<<" "<<ref[type];
+ return out.str();
+ }
+
+ Rollup() : time_type(DAILY), type(3), val(0) {}
+ };
+
+/*##############################*/
+
+ typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
+
struct Server
{
std::string username;
@@ -196,13 +369,17 @@ namespace pan
int rank;
int ssl_support;
int trust;
- typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
groups_t groups;
gchar* gkr_pw;
- unsigned long xfer;
+ XferBytes xfer;
+ Rollup daily_limit;
+ Rollup monthly_limit;
+ int limit_action;
+
+ void increment_xfer(unsigned long bytes) { xfer.increment(bytes); }
Server(): port(STD_NNTP_PORT), article_expiration_age(31), max_connections(2),
- rank(1), ssl_support(0), trust(0), gkr_pw(NULL), xfer(0) {}
+ rank(1), ssl_support(0), trust(0), gkr_pw(NULL), limit_action(0) {}
};
protected:
@@ -258,6 +435,10 @@ namespace pan
virtual void set_server_limits (const Quark & server,
int max_connections) = 0;
+ virtual void set_server_download_limit (const Quark& server, Rollup& rollup) = 0;
+
+ virtual void set_server_download_limit_action (const Quark& server, int& action) = 0;
+
virtual bool get_server_addr (const Quark & server,
std::string & setme_address,
int & setme_port) const = 0;
@@ -273,6 +454,11 @@ namespace pan
virtual int get_server_limits (const Quark & server) const = 0;
+ virtual bool get_server_download_limit (const Quark & server, const TimeType& time_type, Rollup& rollup) const = 0;
+
+ virtual int get_server_download_limit_action (const Quark & server) const = 0;
+
+
/*****************************************************************
***
*** OBSERVERS
@@ -394,10 +580,8 @@ namespace pan
virtual char get_group_permission (const Quark & group) const=0;
- //virtual void group_get_servers (const Quark& group, quarks_t&) const=0;
-
-
-
+ virtual void server_get_nopost (const Quark&, std::set<Quark>& dest) const=0;
+ virtual void server_get_moderated (const Quark&, std::set<Quark>& dest) const=0;
/*****************************************************************
***
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index 1419708..79898c5 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -428,7 +428,7 @@ namespace pan
G_CALLBACK(do_show_profiles_dialog) },
{ "show-servers-dialog", GTK_STOCK_NETWORK,
- N_("Edit _News Servers"), NULL,
+ N_("Show available _News Servers"), NULL,
NULL,
G_CALLBACK(do_show_servers_dialog) },
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index c99b3fe..30e88de 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -905,7 +905,7 @@ main (int argc, char *argv[])
if (nzb && data.get_servers().empty()) {
std::cerr << _("Please configure Pan's news servers before using it as an nzb client.") << std::endl;
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
data.set_newsrc_autosave_timeout( prefs.get_int("newsrc-autosave-timeout-min", 10 ));
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index 4c32098..ca04fc6 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -37,6 +37,7 @@ extern "C" {
#include "pad.h"
#include "hig.h"
#include "gtk-compat.h"
+#include "progress-view.h"
#ifdef HAVE_GNUTLS
#include <pan/data/cert-store.h>
@@ -57,7 +58,7 @@ namespace
Data& data;
Queue& queue;
Prefs& prefs;
- Quark server;
+ Quark server; // must be deleted
StringView cert;
GtkWidget * dialog;
GtkWidget * address_entry;
@@ -69,6 +70,11 @@ namespace
GtkWidget * rank_combo;
GtkWidget * ssl_combo;
GtkWidget * always_trust_checkbox;
+ GtkWidget * daily_limit_spin;
+ GtkWidget * daily_limit_combo;
+ GtkWidget * monthly_limit_spin;
+ GtkWidget * monthly_limit_combo;
+ GtkWidget * limit_action_combo;
ServerEditDialog (Data& d, Queue& q, Prefs& p): data(d), queue(q), prefs(p) {}
};
@@ -117,7 +123,10 @@ namespace
d->server = server;
int port(STD_NNTP_PORT), max_conn(4), age(31*3), rank(1), ssl(0), trust(0);
+ int daily_limit(0), monthly_limit(0), limit_action(0);
+ int daily_limit_val(0), monthly_limit_val(0);
std::string addr, user, cert;
+ Data::Rollup daily_rollup, monthly_rollup;
gchar* pass(NULL);
if (!server.empty()) {
d->data.get_server_addr (server, addr, port);
@@ -128,6 +137,13 @@ namespace
ssl = d->data.get_server_ssl_support(server);
cert = d->data.get_server_cert(server);
d->data.get_server_trust (server, trust);
+ d->data.get_server_download_limit(server, Data::DAILY, daily_rollup);
+ d->data.get_server_download_limit(server, Data::MONTHLY, monthly_rollup);
+ daily_limit = daily_rollup.type;
+ daily_limit_val = daily_rollup.val;
+ monthly_limit = monthly_rollup.type;
+ monthly_limit_val = monthly_rollup.val;
+ limit_action = d->data.get_server_download_limit_action (server);
}
pan_entry_set_text (d->address_entry, addr);
@@ -161,6 +177,46 @@ namespace
}
} while (gtk_tree_model_iter_next(model, &iter));
+ // set the daily limit combobox
+ combo = GTK_COMBO_BOX (d->daily_limit_combo);
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_tree_model_get_iter_first(model, &iter)) do {
+ int that;
+ gtk_tree_model_get (model, &iter, 1, &that, -1);
+ if (that == daily_limit) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
+
+ // set the monthly limit combobox
+ combo = GTK_COMBO_BOX (d->monthly_limit_combo);
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_tree_model_get_iter_first(model, &iter)) do {
+ int that;
+ gtk_tree_model_get (model, &iter, 1, &that, -1);
+ if (that == monthly_limit) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
+
+ // set limit spins
+ pan_spin_button_set (d->daily_limit_spin, daily_limit_val);
+ pan_spin_button_set (d->monthly_limit_spin, monthly_limit_val);
+
+ // set limit action combo
+ combo = GTK_COMBO_BOX (d->limit_action_combo);
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_tree_model_get_iter_first(model, &iter)) do {
+ int that;
+ gtk_tree_model_get (model, &iter, 1, &that, -1);
+ if (that == limit_action) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
+
#ifdef HAVE_GNUTLS
// set ssl combo
combo = GTK_COMBO_BOX (d->ssl_combo);
@@ -213,7 +269,24 @@ namespace
int ssl(0);
int trust(0);
- StringView cert(d->cert);
+ Data::Rollup daily_rollup;
+ daily_rollup.time_type = Data::DAILY;
+ Data::Rollup monthly_rollup;
+ monthly_rollup.time_type = Data::MONTHLY;
+ daily_rollup.val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(d->daily_limit_spin));
+ monthly_rollup.val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(d->monthly_limit_spin));
+ int daily_limit(0), monthly_limit(0);
+ combo = GTK_COMBO_BOX (d->daily_limit_combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &daily_rollup.type, -1);
+ combo = GTK_COMBO_BOX (d->monthly_limit_combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &monthly_rollup.type, -1);
+
+ int limit_action(0);
+ combo = GTK_COMBO_BOX (d->limit_action_combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &limit_action, -1);
#ifdef HAVE_GNUTLS
combo = GTK_COMBO_BOX (d->ssl_combo);
@@ -222,6 +295,8 @@ namespace
trust = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d->always_trust_checkbox)) ? 1 : 0;
#endif
+ StringView cert(d->cert);
+
const char * err_msg (0);
if (addr.empty())
err_msg = _("Please specify the server's address.");
@@ -246,6 +321,9 @@ namespace
d->data.set_server_ssl_support(d->server, ssl);
d->data.set_server_cert(d->server,cert);
d->data.set_server_trust(d->server,trust);
+ d->data.set_server_download_limit(d->server, daily_rollup);
+ d->data.set_server_download_limit(d->server, monthly_rollup);
+ d->data.set_server_download_limit_action(d->server, limit_action);
d->data.save_server_info(d->server);
@@ -291,6 +369,99 @@ pan :: import_sec_from_disk_dialog_new (Data& data, Queue& queue, GtkWindow * wi
}
GtkWidget*
+pan :: server_stats_dialog_new (Data& data, Queue& queue, Prefs& prefs, GtkWindow * window,
+ const Quark& server, const Quark& server_name)
+{
+
+ char * title = g_strdup_printf ("Statistics of '%s'", server_name.c_str());
+
+ GtkWidget * dialog = gtk_dialog_new_with_buttons (title,
+ GTK_WINDOW(window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ Data::Server * s (data.find_server(server));
+ Data::groups_t all_groups(s->groups);
+ gchar tmp[1024];
+ int row (0);
+
+ g_free (title);
+ gtk_window_set_role (GTK_WINDOW(dialog), "pan-show-server-stats-dialog");
+
+ GtkWidget * t (HIG::workarea_create ());
+
+ HIG::workarea_add_section_title (t, &row, _("Groups"));
+ HIG::workarea_add_section_spacer (t, row, 3);
+
+ g_snprintf(tmp, sizeof(tmp), "%d", all_groups.size());
+ HIG::workarea_add_row (t, &row, _("Group count:"), gtk_label_new(tmp), NULL);
+
+ std::set<Quark> nopostgroups, moderated;
+
+ data.server_get_nopost(server, nopostgroups);
+ g_snprintf(tmp, sizeof(tmp), "%d", nopostgroups.size());
+ HIG::workarea_add_row (t, &row, _("No posting allowed:"), gtk_label_new(tmp), NULL);
+
+ data.server_get_moderated(server, moderated);
+ g_snprintf(tmp, sizeof(tmp), "%d", moderated.size());
+ HIG::workarea_add_row (t, &row, _("Moderated:"), gtk_label_new(tmp), NULL);
+
+ HIG::workarea_add_section_divider (t, &row);
+
+ HIG::workarea_add_section_title (t, &row, _("Download Meter"));
+ HIG::workarea_add_section_spacer (t, row, 2);
+
+ g_snprintf(tmp, sizeof(tmp), "%s", s->xfer.get_bytes().c_str());
+ HIG::workarea_add_row (t, &row, _("Download Count:"), gtk_label_new(tmp), NULL);
+
+ /// TODO : free dynamic stuff
+
+ ProgressView* pv = new ProgressView();
+ Progress* prog = new Progress(_("Daily Limit"));
+ prog->add_steps (100);
+
+ Data::Rollup rollup;
+
+ if (data.get_server_download_limit (server, Data::DAILY, rollup))
+ {
+ float step = s->daily_limit.percent(s->xfer);
+ prog->set_step ((int)step);
+ std::stringstream tmp;
+ tmp << step<<" % ("<<s->daily_limit.literal()<<")";
+ prog->set_status (tmp.str().c_str());
+ }
+
+ pv->set_progress(prog);
+ HIG::workarea_add_row (t, &row, _("Daily Limit:"), pv->root(), NULL);
+
+ ProgressView* pv2 = new ProgressView();
+ Progress* prog2 = new Progress(_("Monthly Limit"));
+ prog2->add_steps (100);
+
+ if (data.get_server_download_limit (server, Data::MONTHLY, rollup))
+ {
+ float step = s->monthly_limit.percent(s->xfer);
+ prog2->set_step ((int)step);
+ std::stringstream tmp;
+ tmp << step<<" % ("<<s->monthly_limit.literal()<<")";
+ prog2->set_status (tmp.str().c_str());
+ }
+
+ pv2->set_progress(prog2);
+ HIG::workarea_add_row (t, &row, _("Monthly Limit:"), pv2->root(), NULL);
+
+ gtk_box_pack_start (GTK_BOX( gtk_dialog_get_content_area( GTK_DIALOG(dialog))), t, TRUE, TRUE, 0);
+ g_object_set_data_full (G_OBJECT(dialog), "dialog", dialog, 0);
+ g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
+
+ gtk_widget_show_all (dialog);
+
+ return dialog;
+}
+
+GtkWidget*
pan :: server_edit_dialog_new (Data& data, Queue& queue, Prefs& prefs, GtkWindow * window, const Quark& server)
{
ServerEditDialog * d (new ServerEditDialog (data, queue, prefs));
@@ -398,6 +569,80 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, Prefs& prefs, GtkWindow
gtk_widget_set_tooltip_text( e, _("Fallback servers are used for articles that can't be found on the primaries. One common approach is to use free servers as primaries and subscription servers as fallbacks."));
HIG::workarea_add_row (t, &row, e, w);
+ HIG::workarea_add_section_divider (t, &row);
+ HIG::workarea_add_section_title (t, &row, _("Download Limits"));
+ HIG::workarea_add_section_spacer (t, row, 2);
+
+ struct { int byte; const char * str; } byte_items[] = {
+ { 0, N_("Bytes") },
+ { 1, N_("KB") },
+ { 2, N_("MB") },
+ { 3, N_("GB") },
+ { 4, N_("TB") }
+ };
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ for (unsigned int i(0); i<G_N_ELEMENTS(byte_items); ++i) {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _(byte_items[i].str), 1, byte_items[i].byte, -1);
+ }
+
+ // daily limit
+ GtkWidget* hbox = gtk_hbox_new (FALSE, PAD);
+ a = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 1023, 1.0, 1.0, 0.0));
+ w = d->daily_limit_spin = gtk_spin_button_new (GTK_ADJUSTMENT(a), 1.0, 0u);
+ gtk_box_pack_end (GTK_BOX(hbox), w, TRUE, TRUE, 0);
+ w = d->daily_limit_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ gtk_box_pack_end (GTK_BOX(hbox), w, TRUE, TRUE, 0);
+ g_object_unref (G_OBJECT(store));
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
+ l = gtk_label_new (_("Daily Limit:"));
+ e = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER(e), l);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+ HIG::workarea_add_row (t, &row, e, hbox);
+
+ // monthly limit
+ hbox = gtk_hbox_new (FALSE, PAD);
+ a = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 1023, 1.0, 1.0, 0.0));
+ w = d->monthly_limit_spin = gtk_spin_button_new (GTK_ADJUSTMENT(a), 1.0, 0u);
+ gtk_box_pack_end (GTK_BOX(hbox), w, TRUE, TRUE, 0);
+ w = d->monthly_limit_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ gtk_box_pack_end (GTK_BOX(hbox), w, TRUE, TRUE, 0);
+ g_object_unref (G_OBJECT(store));
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
+ l = gtk_label_new (_("Monthly Limit:"));
+ e = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER(e), l);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+ HIG::workarea_add_row (t, &row, e, hbox);
+
+ struct { int action; const char * str; } action_items[] = {
+ { 0, N_("Pause Tasks on affected Server") },
+ { 1, N_("Pause entire Queue") },
+ { 2, N_("Warn once and continue") }
+ };
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ for (unsigned int i(0); i<G_N_ELEMENTS(action_items); ++i) {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _(action_items[i].str), 1, action_items[i].action, -1);
+ }
+ w = d->limit_action_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ g_object_unref (G_OBJECT(store));
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
+ l = gtk_label_new (_("Action:"));
+ e = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER(e), l);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+ HIG::workarea_add_row (t, &row, e, w);
+
// ssl 3.0 option
#ifdef HAVE_GNUTLS
// select ssl/plaintext
@@ -488,6 +733,7 @@ namespace
GtkListStore * servers_store;
GtkWidget * remove_button;
GtkWidget * edit_button;
+ GtkWidget * stats_button;
ServerListDialog (Data& d, Queue& q, Prefs& p): data(d), queue(q), prefs(p) {}
};
@@ -511,7 +757,6 @@ namespace
}
}
- //std::cerr << LINE_ID << " selected server is " << server << std::endl;
return server;
}
@@ -534,7 +779,6 @@ namespace
}
}
- //std::cerr << LINE_ID << " selected server is " << server << std::endl;
return server;
}
@@ -544,6 +788,7 @@ namespace
const bool have_sel (!get_selected_server(d).empty());
gtk_widget_set_sensitive (d->edit_button, have_sel);
gtk_widget_set_sensitive (d->remove_button, have_sel);
+ gtk_widget_set_sensitive (d->stats_button, have_sel);
}
void
@@ -627,6 +872,18 @@ namespace
}
void
+ stats_button_clicked_cb (GtkButton * button, gpointer data)
+ {
+ const Quark empty_quark;
+ GtkWidget * list_dialog = GTK_WIDGET (data);
+ ServerListDialog * d = (ServerListDialog*) g_object_get_data (G_OBJECT(list_dialog), "dialog");
+ GtkWidget * stats_dialog = server_stats_dialog_new (d->data, d->queue, d->prefs,
+ GTK_WINDOW(list_dialog), get_selected_server(d), get_selected_server_name (d));
+ g_signal_connect (stats_dialog, "destroy", G_CALLBACK(gtk_widget_destroy), stats_dialog);
+ gtk_widget_show_all (stats_dialog);
+ }
+
+ void
server_edit_dialog_destroy_cb (GtkWidget *, gpointer user_data)
{
if (GTK_IS_WIDGET (user_data))
@@ -898,6 +1155,13 @@ pan :: server_list_dialog_new (Data& data, Queue& queue, Prefs& prefs, GtkWindow
g_signal_connect (w, "clicked", G_CALLBACK(remove_button_clicked_cb), d);
d->remove_button = w;
+ //show stats
+ w = gtk_button_new_with_label (_("Statistics"));
+ gtk_box_pack_start (GTK_BOX (bbox), w, FALSE, FALSE, 0);
+ gtk_widget_set_tooltip_text(w, _("Show Server's Statistics"));
+ g_signal_connect (w, "clicked", G_CALLBACK(stats_button_clicked_cb), d->dialog);
+ d->stats_button = w;
+
server_tree_view_refresh (d);
button_refresh (d);
return d->dialog;
diff --git a/pan/gui/server-ui.h b/pan/gui/server-ui.h
index ec24feb..14005b0 100644
--- a/pan/gui/server-ui.h
+++ b/pan/gui/server-ui.h
@@ -34,6 +34,9 @@ namespace pan
GtkWidget* server_edit_dialog_new (Data&, Queue&, Prefs&, GtkWindow*, const Quark& server);
/** @ingroup GUI */
+ GtkWidget* server_stats_dialog_new (Data&, Queue&, Prefs&, GtkWindow*, const Quark& server, const Quark& server_name);
+
+ /** @ingroup GUI */
GtkWidget* server_list_dialog_new (Data&, Queue&, Prefs&, GtkWindow*);
/** @ingroup GUI */
diff --git a/pan/gui/task-pane.cc b/pan/gui/task-pane.cc
index 11cdfcc..645b458 100644
--- a/pan/gui/task-pane.cc
+++ b/pan/gui/task-pane.cc
@@ -153,9 +153,9 @@ TaskPane:: on_tooltip_query(GtkWidget *widget,
date = date_maker.get_date_string (ta->get_article().time_posted);
g_snprintf(buffer,sizeof(buffer),
_("\n<u>Download</u>\n\n<i>Subject:</i> <b>\"%s\"</b>\n<i>From:</i> <b>%s</b>\n<i>Date:</i> <b>%s</b>\n"
- "<i>Groups:</i> <b>%s</b>\n<i>Save Path:</i> <b>%s</b>\nPaused: %d"),
+ "<i>Groups:</i> <b>%s</b>\n<i>Save Path:</i>\n\n"),
a.subject.to_string().c_str(), escaped(a.author.to_string()).c_str(), date ? date : _("unknown"),
- ta->get_groups().c_str(), ta->get_save_path().to_string().c_str(), ta->start_paused());
+ ta->get_groups().c_str(), ta->get_save_path().to_string().c_str());
}
task_found = tu || ta;
diff --git a/pan/tasks/socket.cc b/pan/tasks/socket.cc
index ff317b9..384adac 100644
--- a/pan/tasks/socket.cc
+++ b/pan/tasks/socket.cc
@@ -66,7 +66,6 @@ Socket :: get_speed_KiBps ()
const int delta = now - _time_of_last_check;
const double current_speed = (_bytes_since_last_check/1024.0) / delta;
_time_of_last_check = now;
- fire_socket_data_transferred(_bytes_since_last_check);
_bytes_since_last_check = 0;
_speed_KiBps = (std::fabs(_speed_KiBps)<0.0001)
@@ -88,6 +87,7 @@ void
Socket :: increment_xfer_byte_count (unsigned long byte_count)
{
_bytes_since_last_check += byte_count;
+ fire_socket_data_transferred(byte_count);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]