diff --git a/bin/epour b/bin/epour
index e810c34..b367476 100755
--- a/bin/epour
+++ b/bin/epour
@@ -1,13 +1,9 @@
#!/usr/bin/env python
import sys
-try:
- import elementary as elm
-except ImportError:
- from efl import elementary as elm
+import logging
+
import epour.Epour as Epour
-elm.init()
epour = Epour.Epour(sys.argv[1:])
-elm.run()
-elm.shutdown()
+logging.shutdown()
diff --git a/epour/Epour.py b/epour/Epour.py
index c263e65..dc4bb6f 100755
--- a/epour/Epour.py
+++ b/epour/Epour.py
@@ -43,7 +43,8 @@ def setup_log():
log.addHandler(ch)
fh = logging.FileHandler(os.path.join(data_dir, "epour.log"))
- fh_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ fh_formatter = logging.Formatter(
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(fh_formatter)
fh.setLevel(logging.ERROR)
log.addHandler(fh)
@@ -52,7 +53,6 @@ def setup_log():
log = setup_log()
-
try:
from e_dbus import DBusEcoreMainLoop
except ImportError:
@@ -73,11 +73,10 @@ except dbus.exceptions.DBusException:
if dbo:
if sys.argv[1:]:
for f in sys.argv[1:]:
- log.info("Sending %s via dbus" % f)
+ self.log.info("Sending %s via dbus" % f)
dbo.AddTorrent(f, dbus_interface="net.launchpad.epour")
sys.exit()
-
import mimetypes
from ConfigParser import SafeConfigParser
import cPickle
@@ -87,14 +86,9 @@ import HTMLParser
import libtorrent as lt
try:
- from efl import elementary as elm
+ from efl.ecore import Timer
except:
- import elementary as elm
-
-try:
- from efl.ecore import timer_add
-except:
- from ecore import timer_add
+ from ecore import Timer
from gui import MainInterface
@@ -112,105 +106,12 @@ class Epour(object):
for t in torrents:
self.session.add_torrent(t)
- self.dbusname = dbus.service.BusName("net.launchpad.epour", dbus.SessionBus())
+ self.dbusname = dbus.service.BusName(
+ "net.launchpad.epour", dbus.SessionBus()
+ )
self.dbo = EpourDBus(self)
- timer = timer_add(1.0, self.update)
-
- def update(self):
- while 1:
- a = self.session.pop_alert()
- if not a: break
-
- log = logging.getLogger("epour.alert")
-
- if isinstance(a, lt.torrent_alert):
- # Torrent alerts have handle
- h = a.handle
- if h.is_valid():
- try:
- i = h.get_torrent_info()
- except:
- pass
- ihash = str(h.info_hash())
- else:
- continue
-
- if isinstance(a, lt.peer_alert):
- pass
-
- elif isinstance(a, lt.state_changed_alert) \
- or isinstance(a, lt.torrent_paused_alert) \
- or isinstance(a, lt.torrent_resumed_alert):
- self.gui.update_icon(ihash)
-
- elif isinstance(a, lt.metadata_received_alert):
- log.debug("Metadata received.")
- t_path = self.write_torrent(h)
- self.session.torrents[ihash] = t_path
-
- #elif isinstance(a, lt.tracker_alert):
- # Tracker alerts also have url
-
- elif isinstance(a, lt.torrent_finished_alert):
- msg = "Torrent {} has finished downloading.".format(cgi.escape(h.name()))
- log.info(msg)
- self.gui.show_information(msg)
-
- else:
- log.debug(a)
-
- elif isinstance(a, lt.listen_failed_alert):
- errmsg = "Cannot listen on the configured ports."
- log.error(errmsg)
- self.gui.show_error(
- errmsg,
- "Please try other listen ports in the configuration."
- )
-
- elif isinstance(a, lt.file_error_alert):
- errmsg = "File error."
- log.error(errmsg)
- self.gui.show_error(
- errmsg,
- "Error with file {}, error message {}.".format(
- a.file,
- a.error
- )
- )
-
- elif isinstance(a, lt.file_rename_failed_alert):
- errmsg = "File rename failed."
- log.error(errmsg)
- self.gui.show_error(
- errmsg,
- "Renaming a file with index {} failed, error message {}.".format(
- a.index,
- a.error
- )
- )
-
- else:
- log.debug(a)
-
- self.gui.update_texts(self.session)
-
- return 1
-
- def write_torrent(self, h):
- t_info = h.get_torrent_info()
- ihash = str(h.info_hash())
-
- log.debug("Writing torrent file {}".format(ihash))
-
- md = lt.bdecode(t_info.metadata())
- t = {}
- t["info"] = md
- t_path = os.path.join(data_dir, "{}.torrent".format(t_info.info_hash()))
- with open(t_path, "wb") as f:
- f.write(lt.bencode(t))
-
- return t_path
+ self.gui.run()
def quit(self):
session = self.session
@@ -232,13 +133,13 @@ class Epour(object):
except:
log.exception("Saving conf failed")
- elm.exit()
-
class Session(lt.session):
def __init__(self, parent):
self.parent = parent
lt.session.__init__(self)
+ self.log = logging.getLogger("epour.session")
+
self.handles = {}
self.torrents = {}
@@ -254,16 +155,49 @@ class Session(lt.session):
conf = self.conf = self.setup_conf()
- self.listen_on(conf.getint("Settings", "listen_low"), conf.getint("Settings", "listen_high"))
+ self.listen_on(
+ conf.getint("Settings", "listen_low"),
+ conf.getint("Settings", "listen_high")
+ )
+
+ self.alert_manager = AlertManager(self)
+
+ self.alert_manager.callback_add(lt.metadata_received_alert, self.metadata_received)
+
+ def metadata_received(self, h):
+ ihash = str(h.info_hash())
+ self.log.debug("Metadata received.")
+ t_path = self.write_torrent(h)
+ self.torrents[ihash] = t_path
+
+ def write_torrent(self, h):
+ t_info = h.get_torrent_info()
+ ihash = str(h.info_hash())
+
+ self.log.debug("Writing torrent file {}".format(ihash))
+
+ md = lt.bdecode(t_info.metadata())
+ t = {}
+ t["info"] = md
+ t_path = os.path.join(
+ data_dir, "{}.torrent".format(ihash)
+ )
+ with open(t_path, "wb") as f:
+ f.write(lt.bencode(t))
+
+ return t_path
+
def setup_conf(self):
conf = SafeConfigParser({
- "storage_path": os.path.expanduser(os.path.join("~", "Downloads")),
+ "storage_path": os.path.expanduser(
+ os.path.join("~", "Downloads")
+ ),
"confirmations": str(False),
"delete_original": str(False),
"listen_low": str(0),
"listen_high": str(0),
- })
+ })
conf.read(conf_path)
@@ -282,7 +216,7 @@ class Session(lt.session):
state = lt.bdecode(f.read())
lt.session.load_state(self, state)
except:
- log.debug("Could not load previous session state.")
+ self.log.debug("Could not load previous session state.")
def save_state(self):
state = lt.session.save_state(self)
@@ -290,30 +224,32 @@ class Session(lt.session):
with open(os.path.join(data_dir, "session"), 'wb') as f:
f.write(lt.bencode(state))
- log.debug("Session state saved.")
+ self.log.debug("Session state saved.")
def load_torrents(self):
torrents_path = os.path.join(data_dir, "torrents")
if not os.path.exists(torrents_path):
- log.debug("No list of torrents found.")
+ self.log.debug("No list of torrents found.")
return
try:
pkl_file = open(torrents_path, 'rb')
except IOError:
- log.warning("Could not open the list of torrents.")
+ self.log.warning("Could not open the list of torrents.")
else:
try:
paths = cPickle.load(pkl_file)
except EOFError:
- log.exception("Opening the list of torrents failed.")
+ self.log.exception("Opening the list of torrents failed.")
else:
- log.debug("List of torrents opened, restoring torrents.")
+ self.log.debug("List of torrents opened, restoring torrents.")
for k, v in paths.iteritems():
try:
self.add_torrent(v)
except:
- log.exception("Restoring torrent {0} failed".format(v))
+ self.log.exception(
+ "Restoring torrent {0} failed".format(v)
+ )
finally:
pkl_file.close()
@@ -321,17 +257,20 @@ class Session(lt.session):
with open(os.path.join(data_dir, "torrents"), 'wb') as f:
cPickle.dump(self.torrents, f)
- log.debug("List of torrents saved.")
+ self.log.debug("List of torrents saved.")
# Save fast resume data
for h in self.handles.itervalues():
if not h.is_valid() or not h.has_metadata():
continue
data = lt.bencode(h.write_resume_data())
- with open(os.path.join(data_dir, '{}.fastresume'.format(h.info_hash())), 'wb') as f:
+ with open(os.path.join(
+ data_dir, '{}.fastresume'.format(h.info_hash())
+ ), 'wb'
+ ) as f:
f.write(data)
- log.debug("Fast resume data saved.")
+ self.log.debug("Fast resume data saved.")
def add_torrent(self, t_uri):
if not t_uri:
@@ -342,37 +281,47 @@ class Session(lt.session):
if not t_uri.startswith("magnet"):
mimetype = mimetypes.guess_type(t_uri)[0]
if not mimetype == "application/x-bittorrent":
- log.error("Invalid file")
+ self.log.error("Invalid file")
return
with open(t_uri, 'rb') as t:
t_raw = lt.bdecode(t.read())
if self.conf.getboolean("Settings", "delete_original"):
- log.debug("Deleting original torrent file {}".format(t_uri))
+ self.log.debug("Deleting original torrent file {}".format(t_uri))
os.remove(t_uri)
info = lt.torrent_info(t_raw)
rd = None
try:
- with open(os.path.join(data_dir, "{}.fastresume".format(info.info_hash())), "rb") as f:
+ with open(os.path.join(
+ data_dir, "{}.fastresume".format(info.info_hash())
+ ), "rb"
+ ) as f:
rd = lt.bdecode(f.read())
except:
try:
- with open(os.path.join(data_dir, "{}.fastresume".format(info.name())), "rb") as f:
+ with open(os.path.join(
+ data_dir, "{}.fastresume".format(info.name())
+ ), "rb"
+ ) as f:
rd = lt.bdecode(f.read())
except:
- log.debug("Invalid resume data")
+ self.log.debug("Invalid resume data")
- h = lt.session.add_torrent(self, info, storage_path, resume_data=rd)
- t_uri = self.parent.write_torrent(h)
+ h = lt.session.add_torrent(
+ self, info, storage_path, resume_data=rd)
+ t_uri = self.write_torrent(h)
else:
t_uri = urllib.unquote(t_uri)
t_uri = str(HTMLParser.HTMLParser().unescape(t_uri))
- h = lt.add_magnet_uri(self, t_uri, { "save_path": str(storage_path) })
+ h = lt.add_magnet_uri(
+ self, t_uri,
+ { "save_path": str(storage_path) }
+ )
if not h.is_valid():
- log.error("Invalid torrent handle")
+ self.log.error("Invalid torrent handle")
return
ihash = str(h.info_hash())
@@ -384,37 +333,70 @@ class Session(lt.session):
def remove_torrent(self, h, with_data=False):
ihash = str(h.info_hash())
- info = h.get_torrent_info()
- fr_path1 = os.path.join(data_dir, "{}.fastresume".format(info.info_hash()))
- fr_path2 = os.path.join(data_dir, "{}.fastresume".format(info.name()))
+ fr_path = os.path.join(
+ data_dir, "{}.fastresume".format(ihash)
+ )
t_path = self.torrents[ihash]
del self.torrents[ihash]
lt.session.remove_torrent(self, h, option=with_data)
- for p in fr_path1, fr_path2:
- try:
- with open(p): pass
- except IOError:
- log.debug("Could not remove fast resume data.")
- else:
- os.remove(p)
- break
+ try:
+ with open(fr_path): pass
+ except IOError:
+ self.log.debug("Could not remove fast resume data.")
+ else:
+ os.remove(fr_path)
try:
with open(t_path): pass
except IOError:
- log.debug("Could not remove torrent file.")
+ self.log.debug("Could not remove torrent file.")
else:
os.remove(t_path)
return ihash
+class AlertManager(object):
+
+ log = logging.getLogger("epour.alert")
+ update_interval = 0.2
+ alerts = {}
+
+ def __init__(self, session):
+ self.session = session
+
+ self.timer = Timer(self.update_interval, self.update)
+
+ def callback_add(self, alert_type, cb, *args, **kwargs):
+ if not self.alerts.has_key(alert_type):
+ self.alerts[alert_type] = []
+ self.alerts[alert_type].append((cb, args, kwargs))
+
+ def callback_del(self, alert_type, cb, *args, **kwargs):
+ for i, a in enumerate(self.alerts):
+ if a == (cb, args, kwargs):
+ del(self.alerts[alert_type][i])
+
+ def update(self):
+ while 1:
+ a = self.session.pop_alert()
+ if not a or not self.alerts.has_key(type(a)): break
+
+ for cb, args, kwargs in self.alerts[type(a)]:
+ try:
+ cb(a, *args, **kwargs)
+ except:
+ log.exception()
+
+ return True
+
class EpourDBus(dbus.service.Object):
def __init__(self, parent):
self.parent = parent
- dbus.service.Object.__init__(self, dbus.SessionBus(), "/net/launchpad/epour", "net.launchpad.epour")
+ dbus.service.Object.__init__(self, dbus.SessionBus(),
+ "/net/launchpad/epour", "net.launchpad.epour")
self.props = {
}
@@ -422,12 +404,9 @@ class EpourDBus(dbus.service.Object):
@dbus.service.method(dbus_interface='net.launchpad.epour',
in_signature='s', out_signature='')
def AddTorrent(self, f):
- log.info("Adding %s from dbus" % f)
+ self.log.info("Adding %s from dbus" % f)
self.parent.session.add_torrent(str(f))
if __name__ == "__main__":
- elm.init()
epour = Epour(sys.argv[1:])
- elm.run()
- elm.shutdown()
logging.shutdown()
diff --git a/epour/gui/Main.py b/epour/gui/Main.py
index 9a2d8bf..7e200b7 100644
--- a/epour/gui/Main.py
+++ b/epour/gui/Main.py
@@ -22,14 +22,22 @@
import os
from datetime import timedelta
+import libtorrent as lt
+
try:
from evas import EVAS_ASPECT_CONTROL_VERTICAL
- from elementary import Genlist, GenlistItemClass, StandardWindow, Icon, Box, \
- Label, Button, ELM_GENLIST_ITEM_FIELD_TEXT, ELM_GENLIST_ITEM_FIELD_CONTENT, \
- InnerWindow, Ctxpopup, Frame, Fileselector, Entry
+ from ecore import Timer
+ import elementary as elm
+ from elementary import Genlist, GenlistItemClass, StandardWindow, Icon, \
+ Box, Label, Button, ELM_GENLIST_ITEM_FIELD_TEXT, \
+ ELM_GENLIST_ITEM_FIELD_CONTENT, InnerWindow, Ctxpopup, Frame, \
+ Fileselector, Entry
except ImportError:
from efl.evas import EVAS_ASPECT_CONTROL_VERTICAL
- from efl.elementary.genlist import Genlist, GenlistItemClass, ELM_GENLIST_ITEM_FIELD_TEXT, ELM_GENLIST_ITEM_FIELD_CONTENT
+ from efl.ecore import Timer
+ from efl import elementary as elm
+ from efl.elementary.genlist import Genlist, GenlistItemClass, \
+ ELM_GENLIST_ITEM_FIELD_TEXT, ELM_GENLIST_ITEM_FIELD_CONTENT
from efl.elementary.window import StandardWindow
from efl.elementary.icon import Icon
from efl.elementary.box import Box
@@ -47,75 +55,13 @@ from Notify import ConfirmExit, Error, Information
from intrepr import intrepr
-class TorrentClass(GenlistItemClass):
-
- state_str = ['Queued', 'Checking', 'Downloading metadata', \
- 'Downloading', 'Finished', 'Seeding', 'Allocating', \
- 'Checking resume data']
-
- def text_get(self, obj, part, item_data):
- h = item_data
- name = h.get_torrent_info().name() if h.has_metadata() else "-"
-
- if part == "elm.text":
- return '%s' % (
- name
- )
- elif part == "elm.text.sub":
- s = h.status()
-
- return '{:.0%} complete, ETA: {} (Down: {}/s Up: {}/s Peers: {} Queue: {})'.format(
- s.progress,
- timedelta(seconds=self.get_eta(h)),
- intrepr(s.download_payload_rate, precision=0),
- intrepr(s.upload_payload_rate, precision=0),
- s.num_peers,
- h.queue_position(),
- )
-
- def content_get(self, obj, part, item_data):
- if part == "elm.swallow.icon":
- h = item_data
- s = h.status()
- ic = Icon(obj)
- if h.is_paused():
- ic.standard = "player_pause"
- elif h.is_seed():
- ic.standard = "up"
- else:
- ic.standard = "down"
- ic.tooltip_text_set(self.state_str[s.state])
- ic.size_hint_aspect_set(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1)
- return ic
-
- def get_eta(self, h):
- s = h.status()
- if False: #self.is_finished and self.options["stop_at_ratio"]:
- # We're a seed, so calculate the time to the 'stop_share_ratio'
- if not s.upload_payload_rate:
- return 0
- stop_ratio = self.options["stop_ratio"]
- return ((s.all_time_download * stop_ratio) - s.all_time_upload) / s.upload_payload_rate
-
- left = s.total_wanted - s.total_wanted_done
-
- if left <= 0 or s.download_payload_rate == 0:
- return 0
-
- try:
- eta = left / s.download_payload_rate
- except ZeroDivisionError:
- eta = 0
-
- return eta
-
class MainInterface(object):
def __init__(self, parent, session):
self.parent = parent
self.session = session
self.win = StandardWindow("epour", "Epour")
- self.win.callback_delete_request_add(self.quit)
+ self.win.callback_delete_request_add(lambda x: elm.exit())
self.torrentitems = {}
@@ -154,7 +100,8 @@ class MainInterface(object):
addbtn.show()
togglebtn = self.togglebtn = Button(self.win)
- togglebtn.text_set("Resume all" if parent.session.is_paused() else "Pause all")
+ togglebtn.text = "Resume all" if \
+ parent.session.is_paused() else "Pause all"
togglebtn.callback_clicked_add(self.toggle_paused_cb)
btnbox.pack_end(togglebtn)
togglebtn.show()
@@ -169,21 +116,39 @@ class MainInterface(object):
btnbox.show()
self.win.resize(480, 480)
+
+ for a in lt.state_changed_alert, lt.torrent_paused_alert, lt.torrent_resumed_alert:
+ session.alert_manager.callback_add(a, self.update_icon)
+
+ session.alert_manager.callback_add(lt.torrent_finished_alert, self.torrent_finished_cb)
+
+ def run(self):
self.win.show()
- def update_texts(self, session):
+ self.timer = Timer(1.0, self.update)
+ elm.run()
+ self.quit()
+
+ def update(self):
for v in self.torrentitems.itervalues():
v.fields_update("elm.text", ELM_GENLIST_ITEM_FIELD_TEXT)
v.fields_update("elm.text.sub", ELM_GENLIST_ITEM_FIELD_TEXT)
- s = session.status()
+ s = self.session.status()
self.status.text = "Down: {0}/s Up: {1}/s Peers: {2}".format(
intrepr(s.payload_download_rate),
intrepr(s.payload_upload_rate),
s.num_peers
)
+ return True
- def update_icon(self, ihash):
- self.torrentitems[ihash].fields_update("elm.swallow.icon", ELM_GENLIST_ITEM_FIELD_CONTENT)
+ def update_icon(self, a):
+ h = a.handle
+ if not h.is_valid(): return
+ ihash = str(h.info_hash())
+ if not self.torrentitems.has_key(ihash): return
+ self.torrentitems[ihash].fields_update(
+ "elm.swallow.icon", ELM_GENLIST_ITEM_FIELD_CONTENT
+ )
def select_torrent(self, btn):
sel = Fileselector(self.win)
@@ -274,10 +239,14 @@ class MainInterface(object):
self.resume_torrent_cb if h.is_paused() else self.pause_torrent_cb,
h
)
- cp.item_append("Remove torrent", None, self.remove_torrent_cb, item, h, False)
- cp.item_append("Remove torrent and files", None, self.remove_torrent_cb, item, h, True)
- cp.item_append("Force re-check", None, self.force_recheck, h)
- cp.item_append("Torrent preferences", None, self.torrent_preferences_cb, h)
+ cp.item_append("Remove torrent", None,
+ self.remove_torrent_cb, item, h, False)
+ cp.item_append("Remove torrent and files", None,
+ self.remove_torrent_cb, item, h, True)
+ cp.item_append("Force re-check", None,
+ self.force_recheck, h)
+ cp.item_append("Torrent preferences", None,
+ self.torrent_preferences_cb, h)
cp.pos = self.win.evas.pointer_canvas_xy_get()
cp.show()
@@ -309,12 +278,82 @@ class MainInterface(object):
def show_error(self, title, text):
Error(self.win, title, text)
- def show_information(self, text):
- Information(self.win, text)
+ def torrent_finished_cb(self, h):
+ msg = "Torrent {} has finished downloading.".format(
+ cgi.escape(h.name())
+ )
+ self.log.info(msg)
+
+ Information(self.win, msg)
def quit(self, *args):
if self.session.conf.getboolean("Settings", "confirmations"):
- ConfirmExit(self.win, self.parent.quit)
+ ConfirmExit(self.win, self.shutdown())
else:
- self.parent.quit()
+ self.shutdown()
+ def shutdown(self):
+ elm.shutdown()
+ self.parent.quit()
+
+class TorrentClass(GenlistItemClass):
+
+ state_str = ['Queued', 'Checking', 'Downloading metadata', \
+ 'Downloading', 'Finished', 'Seeding', 'Allocating', \
+ 'Checking resume data']
+
+ def text_get(self, obj, part, item_data):
+ h = item_data
+ name = h.get_torrent_info().name() if h.has_metadata() else "-"
+
+ if part == "elm.text":
+ return '%s' % (
+ name
+ )
+ elif part == "elm.text.sub":
+ s = h.status()
+
+ return '{:.0%} complete, ETA: {} (Down: {}/s Up: {}/s Peers: {} Queue: {})'.format(
+ s.progress,
+ timedelta(seconds=self.get_eta(h)),
+ intrepr(s.download_payload_rate, precision=0),
+ intrepr(s.upload_payload_rate, precision=0),
+ s.num_peers,
+ h.queue_position(),
+ )
+
+ def content_get(self, obj, part, item_data):
+ if part == "elm.swallow.icon":
+ h = item_data
+ s = h.status()
+ ic = Icon(obj)
+ if h.is_paused():
+ ic.standard = "player_pause"
+ elif h.is_seed():
+ ic.standard = "up"
+ else:
+ ic.standard = "down"
+ ic.tooltip_text_set(self.state_str[s.state])
+ ic.size_hint_aspect_set(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1)
+ return ic
+
+ def get_eta(self, h):
+ s = h.status()
+ if False: #self.is_finished and self.options["stop_at_ratio"]:
+ # We're a seed, so calculate the time to the 'stop_share_ratio'
+ if not s.upload_payload_rate:
+ return 0
+ stop_ratio = self.options["stop_ratio"]
+ return ((s.all_time_download * stop_ratio) - s.all_time_upload) / s.upload_payload_rate
+
+ left = s.total_wanted - s.total_wanted_done
+
+ if left <= 0 or s.download_payload_rate == 0:
+ return 0
+
+ try:
+ eta = left / s.download_payload_rate
+ except ZeroDivisionError:
+ eta = 0
+
+ return eta
diff --git a/epour/gui/Preferences.py b/epour/gui/Preferences.py
index aaaba5d..d0e1a32 100644
--- a/epour/gui/Preferences.py
+++ b/epour/gui/Preferences.py
@@ -70,10 +70,18 @@ class Preferences(InnerWindow):
lbl.text = "Click on a title to open/close configuration entry."
ports = ListenPorts(self, session)
- ul = LimitWidget(self, "Upload limit", session.upload_rate_limit, session.set_upload_rate_limit)
- dl = LimitWidget(self, "Download limit", session.download_rate_limit, session.set_download_rate_limit)
- lul = LimitWidget(self, "Upload limit for local connections", session.local_upload_rate_limit, session.set_local_upload_rate_limit)
- ldl = LimitWidget(self, "Download limit for local connections", session.local_download_rate_limit, session.set_local_download_rate_limit)
+ ul = LimitWidget(self, "Upload limit",
+ session.upload_rate_limit,
+ session.set_upload_rate_limit)
+ dl = LimitWidget(self, "Download limit",
+ session.download_rate_limit,
+ session.set_download_rate_limit)
+ lul = LimitWidget(self, "Upload limit for local connections",
+ session.local_upload_rate_limit,
+ session.set_local_upload_rate_limit)
+ ldl = LimitWidget(self, "Download limit for local connections",
+ session.local_download_rate_limit,
+ session.set_local_download_rate_limit)
pf = ProxyConfig(self, parent.win)
dlsel = DataStorageSelector(self, conf)
@@ -88,13 +96,15 @@ class Preferences(InnerWindow):
chk1.size_hint_align = 0.0, 0.0
chk1.text = "Delete original .torrent file when added"
chk1.state = conf.getboolean("Settings", "delete_original")
- chk1.callback_changed_add(lambda x: conf.set("Settings", "delete_original", str(bool(chk1.state))))
+ chk1.callback_changed_add(lambda x: conf.set("Settings",
+ "delete_original", str(bool(chk1.state))))
chk2 = Check(self)
chk2.size_hint_align = 0.0, 0.0
chk2.text = "Ask for confirmation on exit"
chk2.state = conf.getboolean("Settings", "confirmations")
- chk2.callback_changed_add(lambda x: conf.set("Settings", "confirmations", str(bool(chk2.state))))
+ chk2.callback_changed_add(lambda x: conf.set("Settings",
+ "confirmations", str(bool(chk2.state))))
sep2 = Separator(self)
sep2.horizontal = True
@@ -103,7 +113,8 @@ class Preferences(InnerWindow):
xbtn.text_set("Close")
xbtn.callback_clicked_add(lambda x: self.delete())
- for w in lbl, ports, ul, dl, lul, ldl, pf, dlsel, ses_set, pad, sep1, chk1, chk2, sep2, xbtn:
+ for w in lbl, ports, ul, dl, lul, ldl, pf, dlsel, ses_set, pad, \
+ sep1, chk1, chk2, sep2, xbtn:
w.show()
mbox.pack_end(w)
@@ -152,7 +163,8 @@ class DataStorageSelector(Frame):
return
if not os.path.exists(self.dlsel.path):
- p = Notify.Error(self, "Invalid storage path", "You have selected an invalid data storage path for torrents.")
+ p = Notify.Error(self, "Invalid storage path",
+ "You have selected an invalid data storage path for torrents.")
return
self.path_lbl.text = path
@@ -302,10 +314,14 @@ class ProxyConfig(Frame):
b = Box(parent)
proxies = [
- ["Proxy for torrent peer connections", session.peer_proxy, session.set_peer_proxy],
- ["Proxy for torrent web seed connections", session.web_seed_proxy, session.set_web_seed_proxy],
- ["Proxy for tracker connections", session.tracker_proxy, session.set_tracker_proxy],
- ["Proxy for DHT connections", session.dht_proxy, session.set_dht_proxy],
+ ["Proxy for torrent peer connections",
+ session.peer_proxy, session.set_peer_proxy],
+ ["Proxy for torrent web seed connections",
+ session.web_seed_proxy, session.set_web_seed_proxy],
+ ["Proxy for tracker connections",
+ session.tracker_proxy, session.set_tracker_proxy],
+ ["Proxy for DHT connections",
+ session.dht_proxy, session.set_dht_proxy],
]
for title, rfunc, wfunc in proxies:
@@ -423,8 +439,6 @@ class ProxyGroup(Frame):
# encryption: in policy, out policy, allowed enc level, prefer enc
-# session.settings
-
class SessionSettings(Frame):
def __init__(self, parent, session):
Frame.__init__(self, parent)
@@ -480,7 +494,6 @@ class SessionSettings(Frame):
f = Frame(parent)
f.size_hint_align = -1.0, 0.0
f.text = k
- #w.disabled = True
w.show()
widgets[k] = w
f.content = w
@@ -521,4 +534,3 @@ class SessionSettings(Frame):
session.set_settings(s)
Notify.Information(self.canvas, "Session settings saved.")
- #print(dir(lt.session_settings))
diff --git a/epour/gui/TorrentInfo.py b/epour/gui/TorrentInfo.py
index 5017718..628bbb5 100644
--- a/epour/gui/TorrentInfo.py
+++ b/epour/gui/TorrentInfo.py
@@ -39,8 +39,8 @@ except ImportError:
from efl.elementary.entry import Entry
else:
import ecore
- from elementary import Genlist, GenlistItemClass, InnerWindow, Button, Box, \
- Hoversel, Check, Label, ELM_WRAP_CHAR, ELM_WRAP_WORD, Entry
+ from elementary import Genlist, GenlistItemClass, InnerWindow, Button, \
+ Box, Hoversel, Check, Label, ELM_WRAP_CHAR, ELM_WRAP_WORD, Entry
from intrepr import intrepr
@@ -87,14 +87,16 @@ class TorrentInfo(InnerWindow):
if w:
l = Label(self)
l.ellipsis = True
- l.text = cgi.escape(w)
+ l.text = cgi.escape(str(w))
l.show()
box.pack_end(l)
tpriv = Check(self)
tpriv.size_hint_align = 0.0, 0.0
tpriv.text = "Private"
- tpriv.tooltip_text_set("Whether this torrent is private.
i.e., it should not be distributed on the trackerless network
(the kademlia DHT).")
+ tpriv.tooltip_text_set(
+ "Whether this torrent is private.
i.e., it should not be\
+ distributed on the trackerless network
(the kademlia DHT).")
tpriv.disabled = True
tpriv.state = i.priv()
@@ -107,7 +109,10 @@ class TorrentInfo(InnerWindow):
i = h.get_torrent_info()
files = i.files()
for n, file_entry in enumerate(files):
- filelist.item_append(FileSelectionClass(), (file_entry, progress[n], n, h), None, 0)
+ filelist.item_append(
+ FileSelectionClass(),
+ (file_entry, progress[n], n, h),
+ None, 0)
filelist.callback_activated_add(self.item_activated_cb)
@@ -142,4 +147,4 @@ class TorrentInfo(InnerWindow):
if sys.platform == 'linux2':
ecore.Exe("xdg-open '{0}'".format(path))
else:
- os.startfile(path)
\ No newline at end of file
+ os.startfile(path)
diff --git a/epour/gui/__init__.py b/epour/gui/__init__.py
index 2a58af6..a5e66da 100644
--- a/epour/gui/__init__.py
+++ b/epour/gui/__init__.py
@@ -1,2 +1,9 @@
from Main import MainInterface
from Preferences import Preferences
+
+try:
+ from efl import elementary
+except ImportError:
+ import elementary
+
+elementary.init()