mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-02 22:48:40 +00:00
Get the Stats plugin working again.. sort of.. It still needs a lot of work.
This commit is contained in:
parent
520be10e4d
commit
ca7f33db1f
4 changed files with 113 additions and 127 deletions
|
@ -35,42 +35,23 @@
|
||||||
# this exception statement from your version. If you delete this exception
|
# this exception statement from your version. If you delete this exception
|
||||||
# statement from all source files in the program, then also delete it here.
|
# statement from all source files in the program, then also delete it here.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
|
|
||||||
from deluge.log import LOG as log
|
from deluge.plugins.init import PluginInitBase
|
||||||
|
|
||||||
from deluge.plugins.init import PluginBase
|
class CorePlugin(PluginInitBase):
|
||||||
|
def __init__(self, plugin_name):
|
||||||
|
from core import Core as _plugin_cls
|
||||||
|
self._plugin_cls = _plugin_cls
|
||||||
|
super(CorePlugin, self).__init__(plugin_name)
|
||||||
|
|
||||||
class CorePlugin(PluginBase):
|
class GtkUIPlugin(PluginInitBase):
|
||||||
def __init__(self, plugin_api, plugin_name):
|
def __init__(self, plugin_name):
|
||||||
# Load the Core portion of the plugin
|
from gtkui import GtkUI as _plugin_cls
|
||||||
try:
|
self._plugin_cls = _plugin_cls
|
||||||
from core import Core
|
super(GtkUIPlugin, self).__init__(plugin_name)
|
||||||
self.plugin = Core(plugin_api, plugin_name)
|
|
||||||
except Exception, e:
|
|
||||||
log.debug("Did not load a Core plugin: %s", e)
|
|
||||||
|
|
||||||
class WebUIPlugin(PluginBase):
|
class WebUIPlugin(PluginInitBase):
|
||||||
def __init__(self, plugin_api, plugin_name):
|
def __init__(self, plugin_name):
|
||||||
try:
|
from webui import WebUI as _plugin_cls
|
||||||
from webui import WebUI
|
self._plugin_cls = _plugin_cls
|
||||||
self.plugin = WebUI(plugin_api, plugin_name)
|
super(WebUIPlugin, self).__init__(plugin_name)
|
||||||
except Exception, e:
|
|
||||||
log.debug("Did not load a WebUI plugin: %s", e)
|
|
||||||
|
|
||||||
class GtkUIPlugin(PluginBase):
|
|
||||||
def __init__(self, plugin_api, plugin_name):
|
|
||||||
# Load the GtkUI portion of the plugin
|
|
||||||
try:
|
|
||||||
from gtkui import GtkUI
|
|
||||||
self.plugin = GtkUI(plugin_api, plugin_name)
|
|
||||||
except Exception, e:
|
|
||||||
log.debug("Did not load a GtkUI plugin: %s", e)
|
|
||||||
|
|
|
@ -43,27 +43,27 @@
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||||
# this exception statement from your version. If you delete this exception
|
# this exception statement from your version. If you delete this exception
|
||||||
|
|
||||||
|
from twisted.internet.task import LoopingCall
|
||||||
|
|
||||||
import deluge
|
import deluge
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
from deluge.plugins.corepluginbase import CorePluginBase
|
from deluge.plugins.pluginbase import CorePluginBase
|
||||||
from deluge import component
|
from deluge import component
|
||||||
from deluge import configmanager
|
from deluge import configmanager
|
||||||
import gobject
|
from deluge.core.rpcserver import export
|
||||||
#from deluge.plugins.coreclient import client #1.1 and later only
|
|
||||||
#client: see http://dev.deluge-torrent.org/wiki/Development/UiClient#Remoteapi
|
|
||||||
|
|
||||||
DEFAULT_PREFS = {
|
DEFAULT_PREFS = {
|
||||||
"test":"NiNiNi",
|
"test": "NiNiNi",
|
||||||
"update_interval":2000, #2 seconds.
|
"update_interval": 2, #2 seconds.
|
||||||
"length":150, # 2 seconds * 150 --> 5 minutes.
|
"length": 150, # 2 seconds * 150 --> 5 minutes.
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_TOTALS = {
|
DEFAULT_TOTALS = {
|
||||||
"total_upload":0,
|
"total_upload": 0,
|
||||||
"total_download":0,
|
"total_download": 0,
|
||||||
"total_payload_upload":0,
|
"total_payload_upload": 0,
|
||||||
"total_payload_download":0,
|
"total_payload_download": 0,
|
||||||
"stats":{}
|
"stats": {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Core(CorePluginBase):
|
class Core(CorePluginBase):
|
||||||
|
@ -78,90 +78,88 @@ class Core(CorePluginBase):
|
||||||
if self.totals == {}:
|
if self.totals == {}:
|
||||||
self.totals.update(self.saved_stats.config)
|
self.totals.update(self.saved_stats.config)
|
||||||
|
|
||||||
self.stats = self.saved_stats.get("stats") or {}
|
self.stats = self.saved_stats["stats"] or {}
|
||||||
self.add_stats(
|
|
||||||
'upload_rate',
|
|
||||||
'download_rate',
|
|
||||||
'num_connections',
|
|
||||||
'dht_nodes',
|
|
||||||
'dht_cache_nodes',
|
|
||||||
'dht_torrents',
|
|
||||||
)
|
|
||||||
|
|
||||||
self.update_timer = gobject.timeout_add(
|
self.stats_keys = [
|
||||||
self.config.get("update_interval"), self.update_stats)
|
"payload_download_rate",
|
||||||
self.save_timer = gobject.timeout_add(60 * 1000, self.save_stats)
|
"payload_upload_rate"
|
||||||
self.length = self.config.get("length")
|
]
|
||||||
|
self.update_stats()
|
||||||
|
|
||||||
|
self.update_timer = LoopingCall(self.update_stats)
|
||||||
|
self.update_timer.start(self.config["update_interval"])
|
||||||
|
|
||||||
|
self.save_timer = LoopingCall(self.save_stats)
|
||||||
|
self.save_timer.start(60)
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
self.save_stats()
|
self.save_stats()
|
||||||
gobject.source_remove(self.update_timer)
|
try:
|
||||||
gobject.source_remove(self.save_timer)
|
self.update_timer.stop()
|
||||||
|
self.save_timer.stop()
|
||||||
def add_stats(self, *stats):
|
except:
|
||||||
for stat in stats:
|
pass
|
||||||
if stat not in self.stats:
|
|
||||||
self.stats[stat] = []
|
|
||||||
|
|
||||||
def update_stats(self):
|
def update_stats(self):
|
||||||
try:
|
try:
|
||||||
stats = self.core.export_get_stats()
|
status = self.core.get_session_status(self.stats_keys)
|
||||||
status = self.core.session.status()
|
for key, value in status.items():
|
||||||
for stat in dir(status):
|
if key not in self.stats:
|
||||||
if not stat.startswith('_') and stat not in stats:
|
self.stats[key] = []
|
||||||
stats[stat] = getattr(status, stat, None)
|
self.stats[key].insert(0, value)
|
||||||
|
|
||||||
for stat, stat_list in self.stats.iteritems():
|
for stat_list in self.stats.values():
|
||||||
if stat in stats:
|
if len(stat_list) > self.config["length"]:
|
||||||
stat_list.insert(0, int(stats[stat]))
|
|
||||||
|
|
||||||
if len(stat_list) > self.length:
|
|
||||||
stat_list.pop()
|
stat_list.pop()
|
||||||
except Exception,e:
|
|
||||||
log.error(e.message)
|
except Exception, e:
|
||||||
return True
|
log.exception(e)
|
||||||
|
|
||||||
def save_stats(self):
|
def save_stats(self):
|
||||||
try:
|
try:
|
||||||
self.saved_stats.set("stats", self.stats)
|
self.saved_stats["stats"] = self.stats
|
||||||
self.saved_stats.config.update(self.export_get_totals())
|
self.saved_stats.config.update(self.get_totals())
|
||||||
self.saved_stats.save()
|
self.saved_stats.save()
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
log.error(e.message)
|
log.exception(e)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
# export:
|
# export:
|
||||||
def export_get_stats(self, keys):
|
@export()
|
||||||
|
def get_stats(self, keys):
|
||||||
stats_dict = {}
|
stats_dict = {}
|
||||||
for stat in self.stats:
|
for key in keys:
|
||||||
if stat not in keys:
|
if key in self.stats:
|
||||||
continue
|
stats_dict[key] = self.stats[key]
|
||||||
stats_dict[stat] = self.stats[stat]
|
|
||||||
return stats_dict
|
return stats_dict
|
||||||
|
|
||||||
def export_get_totals(self):
|
@export()
|
||||||
|
def get_totals(self):
|
||||||
result = {}
|
result = {}
|
||||||
session_totals = self.export_get_session_totals()
|
session_totals = self.get_session_totals()
|
||||||
for key in session_totals:
|
for key in session_totals:
|
||||||
result[key] = self.totals[key] + session_totals[key]
|
result[key] = self.totals[key] + session_totals[key]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def export_get_session_totals(self):
|
@export()
|
||||||
|
def get_session_totals(self):
|
||||||
status = self.core.session.status()
|
status = self.core.session.status()
|
||||||
return {
|
return {
|
||||||
"total_upload":status.total_upload,
|
"total_upload": status.total_upload,
|
||||||
"total_download":status.total_download,
|
"total_download": status.total_download,
|
||||||
"total_payload_upload":status.total_payload_upload,
|
"total_payload_upload": status.total_payload_upload,
|
||||||
"total_payload_download":status.total_payload_download
|
"total_payload_download": status.total_payload_download
|
||||||
}
|
}
|
||||||
|
|
||||||
def export_set_config(self, config):
|
@export()
|
||||||
|
def set_config(self, config):
|
||||||
"sets the config dictionary"
|
"sets the config dictionary"
|
||||||
for key in config.keys():
|
for key in config.keys():
|
||||||
self.config[key] = config[key]
|
self.config[key] = config[key]
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
def export_get_config(self):
|
@export()
|
||||||
|
def get_config(self):
|
||||||
"returns the config dictionary"
|
"returns the config dictionary"
|
||||||
return self.config.config
|
return self.config.config
|
||||||
|
|
|
@ -49,7 +49,7 @@ port of old plugin by markybob.
|
||||||
import time
|
import time
|
||||||
import cairo
|
import cairo
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
from deluge.ui.client import aclient
|
from deluge.ui.client import client
|
||||||
|
|
||||||
black = (0, 0, 0)
|
black = (0, 0, 0)
|
||||||
gray = (0.75, 0.75, 0.75)
|
gray = (0.75, 0.75, 0.75)
|
||||||
|
@ -101,10 +101,6 @@ class Graph:
|
||||||
'color': color
|
'color': color
|
||||||
}
|
}
|
||||||
|
|
||||||
def async_request(self):
|
|
||||||
aclient.stats_get_stats(self.set_stats, self.stat_info.keys())
|
|
||||||
aclient.stats_get_config(self.set_config)
|
|
||||||
|
|
||||||
def set_stats(self, stats):
|
def set_stats(self, stats):
|
||||||
self.stats = stats
|
self.stats = stats
|
||||||
|
|
||||||
|
@ -115,12 +111,15 @@ class Graph:
|
||||||
def draw_to_context(self, context, width, height):
|
def draw_to_context(self, context, width, height):
|
||||||
self.ctx = context
|
self.ctx = context
|
||||||
self.width, self.height = width, height
|
self.width, self.height = width, height
|
||||||
self.draw_rect(white, 0, 0, self.width, self.height)
|
try:
|
||||||
self.draw_x_axis()
|
self.draw_rect(white, 0, 0, self.width, self.height)
|
||||||
self.draw_left_axis()
|
self.draw_x_axis()
|
||||||
|
self.draw_left_axis()
|
||||||
|
|
||||||
if self.legend_selected:
|
if self.legend_selected:
|
||||||
self.draw_legend()
|
self.draw_legend()
|
||||||
|
except cairo.Error, e:
|
||||||
|
log.exception(e)
|
||||||
return self.ctx
|
return self.ctx
|
||||||
|
|
||||||
def draw(self, width, height):
|
def draw(self, width, height):
|
||||||
|
@ -258,4 +257,4 @@ class Graph:
|
||||||
#self.ctx.set_dash((1, 1), 0)
|
#self.ctx.set_dash((1, 1), 0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import test
|
import test
|
||||||
|
|
|
@ -49,12 +49,15 @@ import gtk
|
||||||
import gobject
|
import gobject
|
||||||
from gtk.glade import XML
|
from gtk.glade import XML
|
||||||
|
|
||||||
|
from twisted.internet import defer
|
||||||
|
|
||||||
import graph
|
import graph
|
||||||
from deluge import component
|
from deluge import component
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
from deluge.common import fspeed
|
from deluge.common import fspeed
|
||||||
from deluge.ui.client import aclient
|
from deluge.ui.client import client
|
||||||
from deluge.ui.gtkui.torrentdetails import Tab
|
from deluge.ui.gtkui.torrentdetails import Tab
|
||||||
|
from deluge.plugins.pluginbase import GtkPluginBase
|
||||||
|
|
||||||
class GraphsTab(Tab):
|
class GraphsTab(Tab):
|
||||||
def __init__(self, glade):
|
def __init__(self, glade):
|
||||||
|
@ -72,8 +75,8 @@ class GraphsTab(Tab):
|
||||||
def bandwidth_expose(self, widget, event):
|
def bandwidth_expose(self, widget, event):
|
||||||
self.graph_widget = self.bandwidth_graph
|
self.graph_widget = self.bandwidth_graph
|
||||||
self.graph = graph.Graph()
|
self.graph = graph.Graph()
|
||||||
self.graph.add_stat('download_rate', label='Download Rate', color=graph.green)
|
self.graph.add_stat('payload_download_rate', label='Download Rate', color=graph.green)
|
||||||
self.graph.add_stat('upload_rate', label='Upload Rate', color=graph.blue)
|
self.graph.add_stat('payload_upload_rate', label='Upload Rate', color=graph.blue)
|
||||||
self.graph.set_left_axis(formatter=fspeed, min=10240)
|
self.graph.set_left_axis(formatter=fspeed, min=10240)
|
||||||
self.update_timer = gobject.timeout_add(2000, self.update_graph)
|
self.update_timer = gobject.timeout_add(2000, self.update_graph)
|
||||||
self.update_graph()
|
self.update_graph()
|
||||||
|
@ -81,21 +84,26 @@ class GraphsTab(Tab):
|
||||||
def update_graph(self):
|
def update_graph(self):
|
||||||
width, height = self.graph_widget.allocation.width, self.graph_widget.allocation.height
|
width, height = self.graph_widget.allocation.width, self.graph_widget.allocation.height
|
||||||
context = self.graph_widget.window.cairo_create()
|
context = self.graph_widget.window.cairo_create()
|
||||||
self.graph.async_request()
|
|
||||||
aclient.force_call(True)
|
log.debug("getstat keys: %s", self.graph.stat_info.keys())
|
||||||
self.graph.draw_to_context(context, width, height)
|
d1 = client.stats.get_stats(self.graph.stat_info.keys())
|
||||||
|
d1.addCallback(self.graph.set_stats)
|
||||||
|
d2 = client.stats.get_config()
|
||||||
|
d2.addCallback(self.graph.set_config)
|
||||||
|
dl = defer.DeferredList([d1, d2])
|
||||||
|
|
||||||
|
def draw_context(result):
|
||||||
|
self.graph.draw_to_context(context, width, height)
|
||||||
|
dl.addCallback(draw_context)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class GtkUI(object):
|
class GtkUI(GtkPluginBase):
|
||||||
def __init__(self, plugin_api, plugin_name):
|
|
||||||
log.debug("Calling Stats UI init")
|
|
||||||
self.plugin = plugin_api
|
|
||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
self.glade = XML(self.get_resource("config.glade"))
|
self.glade = XML(self.get_resource("config.glade"))
|
||||||
self.plugin.add_preferences_page("Stats", self.glade.get_widget("prefs_box"))
|
component.get("Preferences").add_page("Stats", self.glade.get_widget("prefs_box"))
|
||||||
self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs)
|
component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs)
|
||||||
self.plugin.register_hook("on_show_prefs", self.on_show_prefs)
|
component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs)
|
||||||
self.on_show_prefs()
|
self.on_show_prefs()
|
||||||
|
|
||||||
self.graphs_tab = GraphsTab(XML(self.get_resource("tabs.glade")))
|
self.graphs_tab = GraphsTab(XML(self.get_resource("tabs.glade")))
|
||||||
|
@ -103,19 +111,19 @@ class GtkUI(object):
|
||||||
self.torrent_details.notebook.append_page(self.graphs_tab.window, self.graphs_tab.label)
|
self.torrent_details.notebook.append_page(self.graphs_tab.window, self.graphs_tab.label)
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
self.plugin.remove_preferences_page("Stats")
|
component.get("Preferences").remove_page("Stats")
|
||||||
self.plugin.deregister_hook("on_apply_prefs", self.on_apply_prefs)
|
component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs)
|
||||||
self.plugin.deregister_hook("on_show_prefs", self.on_show_prefs)
|
component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs)
|
||||||
|
|
||||||
def on_apply_prefs(self):
|
def on_apply_prefs(self):
|
||||||
log.debug("applying prefs for Stats")
|
log.debug("applying prefs for Stats")
|
||||||
config = {
|
config = {
|
||||||
"test":self.glade.get_widget("txt_test").get_text()
|
"test":self.glade.get_widget("txt_test").get_text()
|
||||||
}
|
}
|
||||||
aclient.stats_set_config(None, config)
|
client.stats.set_config(config)
|
||||||
|
|
||||||
def on_show_prefs(self):
|
def on_show_prefs(self):
|
||||||
aclient.stats_get_config(self.cb_get_config)
|
client.stats.get_config().addCallback(self.cb_get_config)
|
||||||
|
|
||||||
def cb_get_config(self, config):
|
def cb_get_config(self, config):
|
||||||
"callback for on show_prefs"
|
"callback for on show_prefs"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue