epour/epour/Epour.py

216 lines
6.6 KiB
Python

#!/usr/bin/python3
#
# Epour - A bittorrent client using EFL and libtorrent
#
# Copyright 2012-2017 Kai Huuhko <kai.huuhko@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
import sys
from argparse import ArgumentParser
parser = ArgumentParser(description="A BitTorrent client.")
parser.add_argument(
'-v', '--verbose', action="count", help="max is -vvv")
parser.add_argument(
'--disable-add-dialog', action="store_true",
help="Torrents to be added from arguments don't open a dialog")
parser.add_argument(
'torrents', nargs="*", help="file path, magnet uri, or info hash",
metavar="TORRENT")
args = parser.parse_args()
from efl.dbus_mainloop import DBusEcoreMainLoop
import dbus
ml = DBusEcoreMainLoop()
dbus.set_default_main_loop(ml)
import dbus.service
bus = dbus.SessionBus()
try:
dbo = bus.get_object("net.launchpad.epour", "/net/launchpad/epour")
except dbus.exceptions.DBusException:
pass
else:
for f in args.torrents:
print("Sending {0} via dbus".format(f))
if args.disable_add_dialog:
dbo.AddTorrentWithoutDialog(
f, dbus_interface="net.launchpad.epour")
else:
dbo.AddTorrent(f, dbus_interface="net.launchpad.epour")
sys.exit()
import os
if sys.hexversion >= 0x030000F0:
from configparser import ConfigParser as SafeConfigParser
else:
from ConfigParser import SafeConfigParser
import logging
from xdg.BaseDirectory import save_data_path, save_config_path, \
load_config_paths
from .session import Session
from .gui import MainInterface
class Epour(object):
def __init__(self):
self.log = self.setup_log()
self.log.debug("Logging started")
self.conf = self.setup_conf()
session = self.session = Session(self.conf, self._quit_cb)
session.load_state()
self.gui = MainInterface(self, session)
self.dbusname = dbus.service.BusName(
"net.launchpad.epour", dbus.SessionBus()
)
self.dbo = EpourDBus(session, self.gui, self.conf)
self.session.load_torrents()
for t in args.torrents:
if (not args.disable_add_dialog) and \
self.conf.getboolean("Settings", "add_dialog_enabled"):
self.gui.add_torrent(t)
else:
self.session.add_torrent_with_uri(t)
def setup_log(self):
log_level = logging.ERROR
if args.verbose:
log_level -= 10 * args.verbose
log = logging.getLogger("epour")
log.propagate = False
log.setLevel(log_level)
ch = logging.StreamHandler()
ch_formatter = logging.Formatter(
'%(name)s: [%(levelname)s] %(message)s (%(filename)s: %(lineno)d)')
ch.setFormatter(ch_formatter)
ch.setLevel(log_level)
log.addHandler(ch)
fh = logging.FileHandler(
os.path.join(save_data_path("epour"), "epour.log"))
fh_formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(fh_formatter)
fh.setLevel(logging.ERROR)
log.addHandler(fh)
return log
def setup_conf(self):
conf = SafeConfigParser({
"storage_path": os.path.expanduser(
os.path.join("~", "Downloads")
),
"move_completed_path": os.path.expanduser(
os.path.join("~", "Downloads")
),
"move_completed_enabled": str(False),
"confirm_exit": str(False),
"add_dialog_enabled": str(True),
"delete_original": str(False),
"listen_low": str(0),
"listen_high": str(0),
})
for p in load_config_paths("epour"):
if conf.read(os.path.join(p, "epour.conf")):
break
if not conf.has_section("Settings"):
conf.add_section("Settings")
return conf
def save_conf(self):
conf_path = os.path.join(save_config_path("epour"), "epour.conf")
if sys.hexversion >= 0x030000F0:
with open(conf_path, 'w') as configfile:
self.conf.write(configfile)
else:
with open(conf_path, 'wb') as configfile:
self.conf.write(configfile)
def _quit_cb(self):
self.gui.stop_mainloop()
class EpourDBus(dbus.service.Object):
log = logging.getLogger("epour.dbus")
def __init__(self, session, gui, conf):
self.session = session
self.gui = gui
self.conf = conf
dbus.service.Object.__init__(
self, dbus.SessionBus(),
"/net/launchpad/epour", "net.launchpad.epour")
self.props = {
}
@dbus.service.method(dbus_interface='net.launchpad.epour',
in_signature='s', out_signature='')
def AddTorrent(self, t):
self.log.info("Adding %s from dbus" % t)
try:
if self.conf.getboolean("Settings", "add_dialog_enabled"):
self.gui.add_torrent(t)
else:
self.session.add_torrent_with_uri(t)
except Exception:
self.log.exception("Error while adding torrent from dbus")
@dbus.service.method(dbus_interface='net.launchpad.epour',
in_signature='s', out_signature='')
def AddTorrentWithoutDialog(self, t):
self.log.info("Adding %s from dbus" % t)
try:
self.session.add_torrent_with_uri(t)
except Exception:
self.log.exception("Error while adding torrent from dbus")
if __name__ == "__main__":
efllog = logging.getLogger("efl")
efllog.setLevel(logging.INFO)
efllog_formatter = logging.Formatter(
'%(name)s: [%(levelname)s] %(message)s')
efllog_handler = logging.StreamHandler()
efllog_handler.setFormatter(efllog_formatter)
efllog.addHandler(efllog_handler)
epour = Epour()
epour.gui.run_mainloop()
try:
epour.save_conf()
except Exception:
epour.log.exception("Saving conf failed")
logging.shutdown()