Big code clean-up and some refactoring. Added docstrings but more are
needed.
This commit is contained in:
parent
f3c80eb816
commit
6a525530ee
|
@ -0,0 +1 @@
|
||||||
|
"""Deluge"""
|
|
@ -31,15 +31,12 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""Common functions for various parts of Deluge to use."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
import xdg, xdg.BaseDirectory
|
import xdg, xdg.BaseDirectory
|
||||||
import gettext
|
|
||||||
|
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
"""Returns the program version from the egg metadata"""
|
"""Returns the program version from the egg metadata"""
|
||||||
|
@ -76,7 +73,7 @@ def estimate_eta(total_size, total_done, download_rate):
|
||||||
try:
|
try:
|
||||||
return ftime(get_eta(total_size, total_done, download_rate))
|
return ftime(get_eta(total_size, total_done, download_rate))
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
return _("Infinity")
|
return "Infinity"
|
||||||
|
|
||||||
def get_eta(size, done, speed):
|
def get_eta(size, done, speed):
|
||||||
"""Returns the ETA in seconds
|
"""Returns the ETA in seconds
|
||||||
|
@ -93,20 +90,20 @@ def fsize(fsize_b):
|
||||||
"""
|
"""
|
||||||
fsize_kb = float (fsize_b / 1024.0)
|
fsize_kb = float (fsize_b / 1024.0)
|
||||||
if fsize_kb < 1000:
|
if fsize_kb < 1000:
|
||||||
return _("%.1f KiB")%fsize_kb
|
return "%.1f KiB" % fsize_kb
|
||||||
fsize_mb = float (fsize_kb / 1024.0)
|
fsize_mb = float (fsize_kb / 1024.0)
|
||||||
if fsize_mb < 1000:
|
if fsize_mb < 1000:
|
||||||
return _("%.1f MiB")%fsize_mb
|
return "%.1f MiB" % fsize_mb
|
||||||
fsize_gb = float (fsize_mb / 1024.0)
|
fsize_gb = float (fsize_mb / 1024.0)
|
||||||
return _("%.1f GiB")%fsize_gb
|
return "%.1f GiB" % fsize_gb
|
||||||
|
|
||||||
def fpcnt(dec):
|
def fpcnt(dec):
|
||||||
"""Returns a formatted string representing a percentage"""
|
"""Returns a formatted string representing a percentage"""
|
||||||
return '%.2f%%'%(dec * 100)
|
return '%.2f%%' % (dec * 100)
|
||||||
|
|
||||||
def fspeed(bps):
|
def fspeed(bps):
|
||||||
"""Returns a formatted string representing transfer speed"""
|
"""Returns a formatted string representing transfer speed"""
|
||||||
return '%s/s'%(fsize(bps))
|
return '%s/s' % (fsize(bps))
|
||||||
|
|
||||||
def fseed(num_seeds, total_seeds):
|
def fseed(num_seeds, total_seeds):
|
||||||
"""Returns a formatted string num_seeds (total_seeds)"""
|
"""Returns a formatted string num_seeds (total_seeds)"""
|
||||||
|
@ -119,21 +116,21 @@ def fpeer(num_peers, total_peers):
|
||||||
def ftime(seconds):
|
def ftime(seconds):
|
||||||
"""Returns a formatted time string"""
|
"""Returns a formatted time string"""
|
||||||
if seconds < 60:
|
if seconds < 60:
|
||||||
return '%ds'%(seconds)
|
return '%ds' % (seconds)
|
||||||
minutes = int(seconds/60)
|
minutes = int(seconds/60)
|
||||||
seconds = seconds % 60
|
seconds = seconds % 60
|
||||||
if minutes < 60:
|
if minutes < 60:
|
||||||
return '%dm %ds'%(minutes, seconds)
|
return '%dm %ds' % (minutes, seconds)
|
||||||
hours = int(minutes/60)
|
hours = int(minutes/60)
|
||||||
minutes = minutes % 60
|
minutes = minutes % 60
|
||||||
if hours < 24:
|
if hours < 24:
|
||||||
return '%dh %dm'%(hours, minutes)
|
return '%dh %dm' % (hours, minutes)
|
||||||
days = int(hours/24)
|
days = int(hours/24)
|
||||||
hours = hours % 24
|
hours = hours % 24
|
||||||
if days < 7:
|
if days < 7:
|
||||||
return '%dd %dh'%(days, hours)
|
return '%dd %dh' % (days, hours)
|
||||||
weeks = int(days/7)
|
weeks = int(days/7)
|
||||||
days = days % 7
|
days = days % 7
|
||||||
if weeks < 10:
|
if weeks < 10:
|
||||||
return '%dw %dd'%(weeks, days)
|
return '%dw %dd' % (weeks, days)
|
||||||
return 'unknown'
|
return 'unknown'
|
||||||
|
|
|
@ -31,15 +31,16 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""Configuration class used to access/create/modify configuration files."""
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
"""This class is used to access configuration files."""
|
||||||
|
|
||||||
def __init__(self, filename, defaults=None):
|
def __init__(self, filename, defaults=None):
|
||||||
log.debug("Config created with filename: %s", filename)
|
log.debug("Config created with filename: %s", filename)
|
||||||
log.debug("Config defaults: %s", defaults)
|
log.debug("Config defaults: %s", defaults)
|
||||||
|
@ -59,6 +60,8 @@ class Config:
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def load(self, filename=None):
|
def load(self, filename=None):
|
||||||
|
"""Load a config file either by 'filename' or the filename set during
|
||||||
|
construction of this object."""
|
||||||
# Use self.config_file if filename is None
|
# Use self.config_file if filename is None
|
||||||
if filename is None:
|
if filename is None:
|
||||||
filename = self.config_file
|
filename = self.config_file
|
||||||
|
@ -76,6 +79,8 @@ class Config:
|
||||||
pkl_file.close()
|
pkl_file.close()
|
||||||
|
|
||||||
def save(self, filename=None):
|
def save(self, filename=None):
|
||||||
|
"""Save configuration to either 'filename' or the filename set during
|
||||||
|
construction of this object."""
|
||||||
# Saves the config dictionary
|
# Saves the config dictionary
|
||||||
if filename is None:
|
if filename is None:
|
||||||
filename = self.config_file
|
filename = self.config_file
|
||||||
|
@ -89,6 +94,7 @@ class Config:
|
||||||
log.warning("IOError: Unable to save file '%s'", filename)
|
log.warning("IOError: Unable to save file '%s'", filename)
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value):
|
||||||
|
"""Set the 'key' with 'value'."""
|
||||||
# Sets the "key" with "value" in the config dict
|
# Sets the "key" with "value" in the config dict
|
||||||
log.debug("Setting '%s' to %s", key, value)
|
log.debug("Setting '%s' to %s", key, value)
|
||||||
self.config[key] = value
|
self.config[key] = value
|
||||||
|
@ -96,6 +102,8 @@ class Config:
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
|
"""Get the value of 'key'. If it is an invalid key then get() will
|
||||||
|
return None."""
|
||||||
# Attempts to get the "key" value and returns None if the key is
|
# Attempts to get the "key" value and returns None if the key is
|
||||||
# invalid
|
# invalid
|
||||||
try:
|
try:
|
||||||
|
@ -104,7 +112,7 @@ class Config:
|
||||||
return value
|
return value
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log.warning("Key does not exist, returning None")
|
log.warning("Key does not exist, returning None")
|
||||||
return
|
return None
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return self.config[key]
|
return self.config[key]
|
||||||
|
|
|
@ -31,34 +31,20 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
import os.path
|
|
||||||
import pickle
|
import pickle
|
||||||
|
import dbus
|
||||||
try:
|
import dbus.service
|
||||||
import dbus, dbus.service
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
dbus_version = getattr(dbus, "version", (0,0,0))
|
DBusGMainLoop(set_as_default=True)
|
||||||
if dbus_version >= (0,41,0) and dbus_version < (0,80,0):
|
|
||||||
import dbus.glib
|
|
||||||
elif dbus_version >= (0,80,0):
|
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
|
||||||
DBusGMainLoop(set_as_default=True)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
except: dbus_imported = False
|
|
||||||
else: dbus_imported = True
|
|
||||||
|
|
||||||
import gobject
|
import gobject
|
||||||
import deluge.libtorrent as lt
|
|
||||||
import pkg_resources
|
|
||||||
|
|
||||||
|
import deluge.libtorrent as lt
|
||||||
from deluge.config import Config
|
from deluge.config import Config
|
||||||
import deluge.common
|
import deluge.common
|
||||||
from deluge.core.torrentmanager import TorrentManager
|
from deluge.core.torrentmanager import TorrentManager
|
||||||
from deluge.core.pluginmanager import PluginManager
|
from deluge.core.pluginmanager import PluginManager
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
DEFAULT_PREFS = {
|
DEFAULT_PREFS = {
|
||||||
"compact_allocation": True,
|
"compact_allocation": True,
|
||||||
|
|
|
@ -30,25 +30,12 @@
|
||||||
# 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
|
||||||
# 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.
|
||||||
try:
|
|
||||||
import dbus, dbus.service
|
|
||||||
dbus_version = getattr(dbus, "version", (0,0,0))
|
|
||||||
if dbus_version >= (0,41,0) and dbus_version < (0,80,0):
|
|
||||||
import dbus.glib
|
|
||||||
elif dbus_version >= (0,80,0):
|
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
|
||||||
DBusGMainLoop(set_as_default=True)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
except: dbus_imported = False
|
|
||||||
else: dbus_imported = True
|
|
||||||
|
|
||||||
import logging
|
import dbus
|
||||||
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
|
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class Daemon:
|
class Daemon:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -31,15 +31,18 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""PluginManager for Core"""
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
# Get the logger
|
from deluge.log import LOG as log
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class PluginManager:
|
class PluginManager:
|
||||||
|
"""PluginManager handles the loading of plugins and provides plugins with
|
||||||
|
functions to access parts of the core."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Set up the hooks dictionary
|
# Set up the hooks dictionary
|
||||||
self.hooks = {
|
self.hooks = {
|
||||||
|
@ -61,7 +64,6 @@ class PluginManager:
|
||||||
for name in pkg_env:
|
for name in pkg_env:
|
||||||
egg = pkg_env[name][0]
|
egg = pkg_env[name][0]
|
||||||
egg.activate()
|
egg.activate()
|
||||||
modules = []
|
|
||||||
for name in egg.get_entry_map("deluge.plugin.core"):
|
for name in egg.get_entry_map("deluge.plugin.core"):
|
||||||
entry_point = egg.get_entry_info("deluge.plugin.core", name)
|
entry_point = egg.get_entry_info("deluge.plugin.core", name)
|
||||||
cls = entry_point.load()
|
cls = entry_point.load()
|
||||||
|
@ -78,6 +80,7 @@ class PluginManager:
|
||||||
self.status_fields[field] = function
|
self.status_fields[field] = function
|
||||||
|
|
||||||
def get_status(self, torrent_id, fields):
|
def get_status(self, torrent_id, fields):
|
||||||
|
"""Return the value of status fields for the selected torrent_id."""
|
||||||
status = {}
|
status = {}
|
||||||
for field in fields:
|
for field in fields:
|
||||||
try:
|
try:
|
||||||
|
@ -94,22 +97,16 @@ class PluginManager:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log.warning("Plugin attempting to register invalid hook.")
|
log.warning("Plugin attempting to register invalid hook.")
|
||||||
|
|
||||||
def run_hook(self, hook, data):
|
|
||||||
log.debug("Running hook %s", hook)
|
|
||||||
|
|
||||||
|
|
||||||
def run_post_torrent_add(self, torrent_id):
|
def run_post_torrent_add(self, torrent_id):
|
||||||
|
"""This hook is run after a torrent has been added to the session."""
|
||||||
log.debug("run_post_torrent_add")
|
log.debug("run_post_torrent_add")
|
||||||
try:
|
|
||||||
for function in self.hooks["post_torrent_add"]:
|
for function in self.hooks["post_torrent_add"]:
|
||||||
function(torrent_id)
|
function(torrent_id)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def run_post_torrent_remove(self, torrent_id):
|
def run_post_torrent_remove(self, torrent_id):
|
||||||
|
"""This hook is run after a torrent has been removed from the session.
|
||||||
|
"""
|
||||||
log.debug("run_post_torrent_remove")
|
log.debug("run_post_torrent_remove")
|
||||||
try:
|
|
||||||
for function in self.hooks["post_torrent_remove"]:
|
for function in self.hooks["post_torrent_remove"]:
|
||||||
function(torrent_id)
|
function(torrent_id)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
|
@ -31,14 +31,11 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""Internal Torrent class"""
|
||||||
|
|
||||||
import deluge.libtorrent as lt
|
|
||||||
|
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class Torrent:
|
class Torrent:
|
||||||
|
"""Torrent holds information about torrents added to the libtorrent session.
|
||||||
|
"""
|
||||||
def __init__(self, filename, handle):
|
def __init__(self, filename, handle):
|
||||||
# Set the filename
|
# Set the filename
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""TorrentManager handles Torrent objects"""
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
@ -41,11 +42,13 @@ import deluge.common
|
||||||
from deluge.config import Config
|
from deluge.config import Config
|
||||||
from deluge.core.torrent import Torrent
|
from deluge.core.torrent import Torrent
|
||||||
from deluge.core.torrentmanagerstate import TorrentManagerState, TorrentState
|
from deluge.core.torrentmanagerstate import TorrentManagerState, TorrentState
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class TorrentManager:
|
class TorrentManager:
|
||||||
|
"""TorrentManager contains a list of torrents in the current libtorrent
|
||||||
|
session. This object is also responsible for saving the state of the
|
||||||
|
session for use on restart."""
|
||||||
|
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
log.debug("TorrentManager init..")
|
log.debug("TorrentManager init..")
|
||||||
# Set the libtorrent session
|
# Set the libtorrent session
|
||||||
|
@ -79,7 +82,8 @@ class TorrentManager:
|
||||||
handle = None
|
handle = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
handle = self.session.add_torrent(lt.torrent_info(torrent_filedump),
|
handle = self.session.add_torrent(
|
||||||
|
lt.torrent_info(torrent_filedump),
|
||||||
config["download_location"],
|
config["download_location"],
|
||||||
config["compact_allocation"])
|
config["compact_allocation"])
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
|
@ -92,11 +96,11 @@ class TorrentManager:
|
||||||
# Write the .torrent file to the torrent directory
|
# Write the .torrent file to the torrent directory
|
||||||
log.debug("Attemping to save torrent file: %s", filename)
|
log.debug("Attemping to save torrent file: %s", filename)
|
||||||
try:
|
try:
|
||||||
f = open(os.path.join(config["torrentfiles_location"],
|
save_file = open(os.path.join(config["torrentfiles_location"],
|
||||||
filename),
|
filename),
|
||||||
"wb")
|
"wb")
|
||||||
f.write(filedump)
|
save_file.write(filedump)
|
||||||
f.close()
|
save_file.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
log.warning("Unable to save torrent file: %s", filename)
|
log.warning("Unable to save torrent file: %s", filename)
|
||||||
|
|
||||||
|
@ -143,14 +147,15 @@ class TorrentManager:
|
||||||
"""Save the state of the TorrentManager to the torrents.state file"""
|
"""Save the state of the TorrentManager to the torrents.state file"""
|
||||||
state = TorrentManagerState()
|
state = TorrentManagerState()
|
||||||
# Create the state for each Torrent and append to the list
|
# Create the state for each Torrent and append to the list
|
||||||
for (key, torrent) in self.torrents:
|
for torrent in self.torrents.values():
|
||||||
t = TorrentState(torrent.get_state())
|
torrent_state = TorrentState(torrent.get_state())
|
||||||
state.torrents.append(t)
|
state.torrents.append(torrent_state)
|
||||||
|
|
||||||
# Pickle the TorrentManagerState object
|
# Pickle the TorrentManagerState object
|
||||||
try:
|
try:
|
||||||
log.debug("Saving torrent state file.")
|
log.debug("Saving torrent state file.")
|
||||||
state_file = open(deluge.common.get_config_dir("torrents.state"), "wb")
|
state_file = open(deluge.common.get_config_dir("torrents.state"),
|
||||||
|
"wb")
|
||||||
pickle.dump(state, state_file)
|
pickle.dump(state, state_file)
|
||||||
state_file.close()
|
state_file.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
|
|
|
@ -31,10 +31,7 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class TorrentState:
|
class TorrentState:
|
||||||
def __init__(self, torrent_id, filename):
|
def __init__(self, torrent_id, filename):
|
||||||
|
|
|
@ -34,24 +34,18 @@
|
||||||
# The main starting point for the program. This function is called when the
|
# The main starting point for the program. This function is called when the
|
||||||
# user runs the command 'deluge'.
|
# user runs the command 'deluge'.
|
||||||
|
|
||||||
import logging
|
"""Main starting point for Deluge. Contains the main() entry point."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import signal
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
from deluge.core.daemon import Daemon
|
from deluge.core.daemon import Daemon
|
||||||
from deluge.ui.ui import UI
|
from deluge.ui.ui import UI
|
||||||
|
from deluge.log import LOG as log
|
||||||
import deluge.common
|
import deluge.common
|
||||||
|
|
||||||
# Setup the logger
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.DEBUG,
|
|
||||||
format="[%(levelname)-8s] %(name)s:%(module)s:%(lineno)d %(message)s"
|
|
||||||
)
|
|
||||||
# Get the logger for deluge
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""Entry point for Deluge"""
|
||||||
# Setup the argument parser
|
# Setup the argument parser
|
||||||
parser = OptionParser(usage="%prog [options] [actions]",
|
parser = OptionParser(usage="%prog [options] [actions]",
|
||||||
version=deluge.common.get_version())
|
version=deluge.common.get_version())
|
||||||
|
@ -68,9 +62,7 @@ def main():
|
||||||
log.debug("options: %s", options)
|
log.debug("options: %s", options)
|
||||||
log.debug("args: %s", args)
|
log.debug("args: %s", args)
|
||||||
|
|
||||||
daemon = None
|
|
||||||
pid = None
|
pid = None
|
||||||
uri = None
|
|
||||||
|
|
||||||
# Start the daemon
|
# Start the daemon
|
||||||
if options.daemon:
|
if options.daemon:
|
||||||
|
@ -82,9 +74,9 @@ def main():
|
||||||
# Since we are starting daemon this process will not start a UI
|
# Since we are starting daemon this process will not start a UI
|
||||||
options.ui = False
|
options.ui = False
|
||||||
# Create the daemon object
|
# Create the daemon object
|
||||||
daemon = Daemon()
|
Daemon()
|
||||||
|
|
||||||
# Start the UI
|
# Start the UI
|
||||||
if options.ui:
|
if options.ui:
|
||||||
log.info("Starting ui..")
|
log.info("Starting ui..")
|
||||||
ui = UI()
|
UI()
|
||||||
|
|
|
@ -31,29 +31,18 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
import os.path
|
import os.path
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
try:
|
import dbus
|
||||||
import dbus, dbus.service
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
dbus_version = getattr(dbus, "version", (0,0,0))
|
DBusGMainLoop(set_as_default=True)
|
||||||
if dbus_version >= (0,41,0) and dbus_version < (0,80,0):
|
|
||||||
import dbus.glib
|
|
||||||
elif dbus_version >= (0,80,0):
|
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
|
||||||
DBusGMainLoop(set_as_default=True)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
except: dbus_imported = False
|
|
||||||
else: dbus_imported = True
|
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk, gtk.glade
|
import gtk, gtk.glade
|
||||||
|
|
||||||
# Get the logger
|
from deluge.log import LOG as log
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
def get_core():
|
def get_core():
|
||||||
"""Get the core object and return it"""
|
"""Get the core object and return it"""
|
||||||
|
|
|
@ -31,16 +31,13 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk, gtk.glade
|
import gtk, gtk.glade
|
||||||
|
import gettext
|
||||||
|
|
||||||
from deluge.config import Config
|
from deluge.config import Config
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class AddTorrentDialog:
|
class AddTorrentDialog:
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
@ -55,14 +52,14 @@ class AddTorrentDialog:
|
||||||
self.chooser.set_property("skip-taskbar-hint", True)
|
self.chooser.set_property("skip-taskbar-hint", True)
|
||||||
|
|
||||||
# Add .torrent and * file filters
|
# Add .torrent and * file filters
|
||||||
f0 = gtk.FileFilter()
|
file_filter = gtk.FileFilter()
|
||||||
f0.set_name(_("Torrent files"))
|
file_filter.set_name(_("Torrent files"))
|
||||||
f0.add_pattern("*." + "torrent")
|
file_filter.add_pattern("*." + "torrent")
|
||||||
self.chooser.add_filter(f0)
|
self.chooser.add_filter(file_filter)
|
||||||
f1 = gtk.FileFilter()
|
file_filter = gtk.FileFilter()
|
||||||
f1.set_name(_("All files"))
|
file_filter.set_name(_("All files"))
|
||||||
f1.add_pattern("*")
|
file_filter.add_pattern("*")
|
||||||
self.chooser.add_filter(f1)
|
self.chooser.add_filter(file_filter)
|
||||||
|
|
||||||
# Load the 'default_load_path' from the config
|
# Load the 'default_load_path' from the config
|
||||||
self.config = Config("gtkui.conf")
|
self.config = Config("gtkui.conf")
|
||||||
|
|
|
@ -31,50 +31,51 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
import gettext
|
import gettext
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
# Cell data functions to pass to add_func_column()
|
# Cell data functions to pass to add_func_column()
|
||||||
|
|
||||||
def cell_data_speed(column, cell, model, iter, data):
|
def cell_data_speed(column, cell, model, row, data):
|
||||||
speed = int(model.get_value(iter, data))
|
"""Display value as a speed, eg. 2 KiB/s"""
|
||||||
|
speed = int(model.get_value(row, data))
|
||||||
speed_str = deluge.common.fspeed(speed)
|
speed_str = deluge.common.fspeed(speed)
|
||||||
cell.set_property('text', speed_str)
|
cell.set_property('text', speed_str)
|
||||||
|
|
||||||
def cell_data_size(column, cell, model, iter, data):
|
def cell_data_size(column, cell, model, row, data):
|
||||||
size = long(model.get_value(iter, data))
|
"""Display value in terms of size, eg. 2 MB"""
|
||||||
|
size = long(model.get_value(row, data))
|
||||||
size_str = deluge.common.fsize(size)
|
size_str = deluge.common.fsize(size)
|
||||||
cell.set_property('text', size_str)
|
cell.set_property('text', size_str)
|
||||||
|
|
||||||
def cell_data_peer(column, cell, model, iter, data):
|
def cell_data_peer(column, cell, model, row, data):
|
||||||
c1, c2 = data
|
"""Display values as 'value1 (value2)'"""
|
||||||
a = int(model.get_value(iter, c1))
|
column1, column2 = data
|
||||||
b = int(model.get_value(iter, c2))
|
first = int(model.get_value(row, column1))
|
||||||
cell.set_property('text', '%d (%d)'%(a, b))
|
second = int(model.get_value(row, column2))
|
||||||
|
cell.set_property('text', '%d (%d)' % (first, second))
|
||||||
|
|
||||||
def cell_data_time(column, cell, model, iter, data):
|
def cell_data_time(column, cell, model, row, data):
|
||||||
time = int(model.get_value(iter, data))
|
"""Display value as time, eg 1m10s"""
|
||||||
|
time = int(model.get_value(row, data))
|
||||||
if time < 0 or time == 0:
|
if time < 0 or time == 0:
|
||||||
time_str = _("Infinity")
|
time_str = _("Infinity")
|
||||||
else:
|
else:
|
||||||
time_str = deluge.common.ftime(time)
|
time_str = deluge.common.ftime(time)
|
||||||
cell.set_property('text', time_str)
|
cell.set_property('text', time_str)
|
||||||
|
|
||||||
def cell_data_ratio(column, cell, model, iter, data):
|
def cell_data_ratio(column, cell, model, row, data):
|
||||||
ratio = float(model.get_value(iter, data))
|
"""Display value as a ratio with a precision of 3."""
|
||||||
|
ratio = float(model.get_value(row, data))
|
||||||
if ratio == -1:
|
if ratio == -1:
|
||||||
ratio_str = _("Unknown")
|
ratio_str = _("Unknown")
|
||||||
else:
|
else:
|
||||||
ratio_str = "%.3f"%ratio
|
ratio_str = "%.3f" % ratio
|
||||||
cell.set_property('text', ratio_str)
|
cell.set_property('text', ratio_str)
|
||||||
|
|
||||||
class ListView:
|
class ListView:
|
||||||
|
@ -87,9 +88,6 @@ class ListView:
|
||||||
self.column_indices = column_indices
|
self.column_indices = column_indices
|
||||||
# Column is a reference to the GtkTreeViewColumn object
|
# Column is a reference to the GtkTreeViewColumn object
|
||||||
self.column = None
|
self.column = None
|
||||||
# The get_function is called when a column is in need of an update
|
|
||||||
# This is primarily used by plugins.
|
|
||||||
self.get_function = None
|
|
||||||
# This is the name of the status field that the column will query
|
# This is the name of the status field that the column will query
|
||||||
# the core for if an update is called.
|
# the core for if an update is called.
|
||||||
self.status_field = None
|
self.status_field = None
|
||||||
|
@ -126,11 +124,15 @@ class ListView:
|
||||||
self.menu = None
|
self.menu = None
|
||||||
|
|
||||||
def set_treeview(self, treeview_widget):
|
def set_treeview(self, treeview_widget):
|
||||||
|
"""Set the treeview widget that this listview uses."""
|
||||||
self.treeview = treeview_widget
|
self.treeview = treeview_widget
|
||||||
self.treeview.set_model(self.liststore)
|
self.treeview.set_model(self.liststore)
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_column_index(self, name):
|
def get_column_index(self, name):
|
||||||
|
"""Get the liststore column indices belonging to this column.
|
||||||
|
Will return a list if greater than 1 column.
|
||||||
|
"""
|
||||||
# Only return as list if needed
|
# Only return as list if needed
|
||||||
if len(self.columns[name].column_indices) > 1:
|
if len(self.columns[name].column_indices) > 1:
|
||||||
return self.columns[name].column_indices
|
return self.columns[name].column_indices
|
||||||
|
@ -218,37 +220,39 @@ class ListView:
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def add_text_column(self, header, col_type=str, hidden=False,
|
def add_column(self, header, render, col_types, hidden, position,
|
||||||
position=None, get_function=None,
|
status_field, sortid, text=0, value=0, function=None):
|
||||||
status_field=None):
|
# Add the column types to liststore_columns
|
||||||
# Create a new column object and add it to the list
|
if type(col_types) is list:
|
||||||
|
for col_type in col_types:
|
||||||
self.liststore_columns.append(col_type)
|
self.liststore_columns.append(col_type)
|
||||||
|
else:
|
||||||
|
self.liststore_columns.append(col_types)
|
||||||
|
|
||||||
# Add to the index list so we know the order of the visible columns.
|
# Add to the index list so we know the order of the visible columns.
|
||||||
if position is not None:
|
if position is not None:
|
||||||
self.column_index.insert(position, header)
|
self.column_index.insert(position, header)
|
||||||
else:
|
else:
|
||||||
self.column_index.append(header)
|
self.column_index.append(header)
|
||||||
|
|
||||||
|
# Create a new column object and add it to the list
|
||||||
self.columns[header] = self.ListViewColumn(header,
|
self.columns[header] = self.ListViewColumn(header,
|
||||||
[len(self.liststore_columns) - 1])
|
[len(self.liststore_columns) - 1])
|
||||||
|
|
||||||
# Set the get_function.. This function is used mainly for plugins.
|
|
||||||
# You can have your listview call this function to update the column
|
|
||||||
# value.
|
|
||||||
if get_function is not None:
|
|
||||||
self.columns[header].get_function = get_function
|
|
||||||
|
|
||||||
self.columns[header].status_field = status_field
|
self.columns[header].status_field = status_field
|
||||||
|
|
||||||
# Create a new list with the added column
|
# Create a new list with the added column
|
||||||
self.create_new_liststore()
|
self.create_new_liststore()
|
||||||
|
|
||||||
# Now add the column to the treeview so the user can see it
|
if type(render) is gtk.CellRendererText:
|
||||||
render = gtk.CellRendererText()
|
|
||||||
column = gtk.TreeViewColumn(header, render,
|
column = gtk.TreeViewColumn(header, render,
|
||||||
text=self.columns[header].column_indices[0])
|
text=self.columns[header].column_indices[text])
|
||||||
|
else:
|
||||||
|
column = gtk.TreeViewColumn(header, render)
|
||||||
|
|
||||||
|
column.set_sort_column_id(self.columns[header].column_indices[sortid])
|
||||||
column.set_clickable(True)
|
column.set_clickable(True)
|
||||||
column.set_sort_column_id(self.columns[header].column_indices[0])
|
|
||||||
column.set_resizable(True)
|
column.set_resizable(True)
|
||||||
column.set_expand(False)
|
column.set_expand(False)
|
||||||
column.set_min_width(10)
|
column.set_min_width(10)
|
||||||
|
@ -266,6 +270,17 @@ class ListView:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def add_text_column(self, header, col_type=str, hidden=False,
|
||||||
|
position=None,
|
||||||
|
status_field=None,
|
||||||
|
sortid=0):
|
||||||
|
# Add a text column to the treeview
|
||||||
|
render = gtk.CellRendererText()
|
||||||
|
self.add_column(header, render, col_type, hidden, position,
|
||||||
|
status_field, sortid, text=0)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def add_func_column(self, header, function, column_types, sortid=0,
|
def add_func_column(self, header, function, column_types, sortid=0,
|
||||||
hidden=False, position=None, get_function=None,
|
hidden=False, position=None, get_function=None,
|
||||||
status_field=None):
|
status_field=None):
|
||||||
|
@ -321,7 +336,8 @@ class ListView:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def add_progress_column(self, header, hidden=False, position=None,
|
def add_progress_column(self, header, col_type=[float,str], hidden=False,
|
||||||
|
position=None,
|
||||||
get_function=None,
|
get_function=None,
|
||||||
status_field=None):
|
status_field=None):
|
||||||
# For the progress value
|
# For the progress value
|
||||||
|
|
|
@ -31,13 +31,11 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
# Get the logger
|
from deluge.log import LOG as log
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class PluginManager:
|
class PluginManager:
|
||||||
def __init__(self, gtkui):
|
def __init__(self, gtkui):
|
||||||
|
@ -56,7 +54,6 @@ class PluginManager:
|
||||||
for name in pkg_env:
|
for name in pkg_env:
|
||||||
egg = pkg_env[name][0]
|
egg = pkg_env[name][0]
|
||||||
egg.activate()
|
egg.activate()
|
||||||
modules = []
|
|
||||||
for name in egg.get_entry_map("deluge.plugin.ui.gtk"):
|
for name in egg.get_entry_map("deluge.plugin.ui.gtk"):
|
||||||
entry_point = egg.get_entry_info("deluge.plugin.ui.gtk", name)
|
entry_point = egg.get_entry_info("deluge.plugin.ui.gtk", name)
|
||||||
cls = entry_point.load()
|
cls = entry_point.load()
|
||||||
|
|
|
@ -31,30 +31,9 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
try:
|
|
||||||
import dbus, dbus.service
|
|
||||||
dbus_version = getattr(dbus, "version", (0,0,0))
|
|
||||||
if dbus_version >= (0,41,0) and dbus_version < (0,80,0):
|
|
||||||
import dbus.glib
|
|
||||||
elif dbus_version >= (0,80,0):
|
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
|
||||||
DBusGMainLoop(set_as_default=True)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
except: dbus_imported = False
|
|
||||||
else: dbus_imported = True
|
|
||||||
|
|
||||||
import pygtk
|
|
||||||
pygtk.require('2.0')
|
|
||||||
import gtk, gtk.glade
|
|
||||||
|
|
||||||
import deluge.ui.functions as functions
|
import deluge.ui.functions as functions
|
||||||
from deluge.config import Config
|
from deluge.config import Config
|
||||||
|
from deluge.log import LOG as log
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class Signals:
|
class Signals:
|
||||||
def __init__(self, ui):
|
def __init__(self, ui):
|
||||||
|
|
|
@ -31,21 +31,19 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import logging
|
"""The torrent view component that lists all torrents in the session."""
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk, gtk.glade
|
import gtk, gtk.glade
|
||||||
import gobject
|
|
||||||
import gettext
|
import gettext
|
||||||
|
|
||||||
import deluge.ui.functions as functions
|
import deluge.ui.functions as functions
|
||||||
import listview
|
from deluge.log import LOG as log
|
||||||
|
import deluge.ui.gtkui.listview as listview
|
||||||
# Get the logger
|
|
||||||
log = logging.getLogger("deluge")
|
|
||||||
|
|
||||||
class TorrentView(listview.ListView):
|
class TorrentView(listview.ListView):
|
||||||
|
"""TorrentView handles the listing of torrents."""
|
||||||
def __init__(self, window):
|
def __init__(self, window):
|
||||||
self.window = window
|
self.window = window
|
||||||
# Call the ListView constructor
|
# Call the ListView constructor
|
||||||
|
@ -108,28 +106,25 @@ class TorrentView(listview.ListView):
|
||||||
if self.liststore is not None:
|
if self.liststore is not None:
|
||||||
self.liststore.foreach(self.update_row, columns)
|
self.liststore.foreach(self.update_row, columns)
|
||||||
|
|
||||||
def update_row(self, model, path, row, columns=None):
|
def update_row(self, model=None, path=None, row=None, columns=None):
|
||||||
torrent_id = self.liststore.get_value(row,
|
"""Updates the column values for 'row'. If columns is None it will
|
||||||
|
update all visible columns."""
|
||||||
|
|
||||||
|
torrent_id = model.get_value(row,
|
||||||
self.columns["torrent_id"].column_indices[0])
|
self.columns["torrent_id"].column_indices[0])
|
||||||
# Store the 'status_fields' we need to send to core
|
# Store the 'status_fields' we need to send to core
|
||||||
status_keys = []
|
status_keys = []
|
||||||
# Store the actual columns we will be updating
|
# Store the actual columns we will be updating
|
||||||
columns_to_update = []
|
columns_to_update = []
|
||||||
|
|
||||||
if columns is None:
|
if columns is None:
|
||||||
# Iterate through the list of columns and only add the
|
# We need to iterate through all columns
|
||||||
# 'status-fields' of the visible ones.
|
columns = self.columns.keys()
|
||||||
for column in self.columns.values():
|
|
||||||
# Make sure column is visible and has 'status_field' set.
|
|
||||||
# If not, we can ignore it.
|
|
||||||
if column.column.get_visible() is True \
|
|
||||||
and column.hidden is False \
|
|
||||||
and column.status_field is not None:
|
|
||||||
for field in column.status_field:
|
|
||||||
status_keys.append(field)
|
|
||||||
columns_to_update.append(column.name)
|
|
||||||
else:
|
|
||||||
# Iterate through supplied list of columns to update
|
# Iterate through supplied list of columns to update
|
||||||
for column in columns:
|
for column in columns:
|
||||||
|
# Make sure column is visible and has 'status_field' set.
|
||||||
|
# If not, we can ignore it.
|
||||||
if self.columns[column].column.get_visible() is True \
|
if self.columns[column].column.get_visible() is True \
|
||||||
and self.columns[column].hidden is False \
|
and self.columns[column].hidden is False \
|
||||||
and self.columns[column].status_field is not None:
|
and self.columns[column].status_field is not None:
|
||||||
|
@ -148,23 +143,23 @@ class TorrentView(listview.ListView):
|
||||||
|
|
||||||
# Set values for each column in the row
|
# Set values for each column in the row
|
||||||
for column in columns_to_update:
|
for column in columns_to_update:
|
||||||
if type(self.get_column_index(column)) is not list:
|
column_index = self.get_column_index(column)
|
||||||
|
if type(column_index) is not list:
|
||||||
# We only have a single list store column we need to update
|
# We only have a single list store column we need to update
|
||||||
self.liststore.set_value(row,
|
model.set_value(row,
|
||||||
self.get_column_index(column),
|
column_index,
|
||||||
status[self.columns[column].status_field[0]])
|
status[self.columns[column].status_field[0]])
|
||||||
else:
|
else:
|
||||||
# We have more than 1 liststore column to update
|
# We have more than 1 liststore column to update
|
||||||
i = 0
|
for index in column_index:
|
||||||
for index in self.get_column_index(column):
|
|
||||||
# Only update the column if the status field exists
|
# Only update the column if the status field exists
|
||||||
try:
|
try:
|
||||||
self.liststore.set_value(row,
|
model.set_value(row,
|
||||||
index,
|
index,
|
||||||
status[self.columns[column].status_field[i]])
|
status[self.columns[column].status_field[
|
||||||
|
column_index.index(index)]])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
def add_row(self, torrent_id):
|
def add_row(self, torrent_id):
|
||||||
"""Adds a new torrent row to the treeview"""
|
"""Adds a new torrent row to the treeview"""
|
||||||
|
@ -176,7 +171,7 @@ class TorrentView(listview.ListView):
|
||||||
self.columns["torrent_id"].column_indices[0],
|
self.columns["torrent_id"].column_indices[0],
|
||||||
torrent_id)
|
torrent_id)
|
||||||
# Update the new row so
|
# Update the new row so
|
||||||
self.update_row(None, None, row)
|
self.update_row(model=self.liststore, row=row)
|
||||||
|
|
||||||
def remove_row(self, torrent_id):
|
def remove_row(self, torrent_id):
|
||||||
"""Removes a row with torrent_id"""
|
"""Removes a row with torrent_id"""
|
||||||
|
@ -206,6 +201,7 @@ class TorrentView(listview.ListView):
|
||||||
|
|
||||||
### Callbacks ###
|
### Callbacks ###
|
||||||
def on_button_press_event(self, widget, event):
|
def on_button_press_event(self, widget, event):
|
||||||
|
"""This is a callback for showing the right-click context menu."""
|
||||||
log.debug("on_button_press_event")
|
log.debug("on_button_press_event")
|
||||||
# We only care about right-clicks
|
# We only care about right-clicks
|
||||||
if event.button == 3:
|
if event.button == 3:
|
||||||
|
@ -215,5 +211,6 @@ class TorrentView(listview.ListView):
|
||||||
torrentmenu.popup(None, None, None, event.button, event.time)
|
torrentmenu.popup(None, None, None, event.button, event.time)
|
||||||
|
|
||||||
def on_selection_changed(self, treeselection):
|
def on_selection_changed(self, treeselection):
|
||||||
|
"""This callback is know when the selection has changed."""
|
||||||
log.debug("on_selection_changed")
|
log.debug("on_selection_changed")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue