[Console] Refactor main to use async instead of callbacks
Use the new maybe_coroutine decorator to replace callbacks with inline async/await for cleaner code.
This commit is contained in:
parent
6c924e6128
commit
253eb2240b
|
@ -18,8 +18,7 @@ from twisted.internet import defer, error, reactor
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
from deluge.decorators import overrides
|
from deluge.decorators import maybe_coroutine, overrides
|
||||||
from deluge.error import DelugeError
|
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
from deluge.ui.console.modes.addtorrents import AddTorrents
|
from deluge.ui.console.modes.addtorrents import AddTorrents
|
||||||
from deluge.ui.console.modes.basemode import TermResizeHandler
|
from deluge.ui.console.modes.basemode import TermResizeHandler
|
||||||
|
@ -160,82 +159,54 @@ deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
|
||||||
|
|
||||||
wrapper(self.run)
|
wrapper(self.run)
|
||||||
|
|
||||||
def quit(self):
|
@maybe_coroutine
|
||||||
|
async def quit(self):
|
||||||
if client.connected():
|
if client.connected():
|
||||||
|
await client.disconnect()
|
||||||
|
|
||||||
def on_disconnect(result):
|
|
||||||
reactor.stop()
|
|
||||||
|
|
||||||
return client.disconnect().addCallback(on_disconnect)
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
except error.ReactorNotRunning:
|
except error.ReactorNotRunning:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exec_args(self, options):
|
@maybe_coroutine
|
||||||
|
async def exec_args(self, options):
|
||||||
"""Execute console commands from command line."""
|
"""Execute console commands from command line."""
|
||||||
from deluge.ui.console.cmdline.command import Commander
|
from deluge.ui.console.cmdline.command import Commander
|
||||||
|
|
||||||
commander = Commander(self._commands)
|
commander = Commander(self._commands)
|
||||||
|
try:
|
||||||
def on_connect(result):
|
if not self.interactive and options.parsed_cmds[0].command == 'connect':
|
||||||
def on_components_started(result):
|
await commander.exec_command(options.parsed_cmds.pop(0))
|
||||||
def on_started(result):
|
|
||||||
def do_command(result, cmd):
|
|
||||||
return commander.do_command(cmd)
|
|
||||||
|
|
||||||
def exec_command(result, cmd):
|
|
||||||
return commander.exec_command(cmd)
|
|
||||||
|
|
||||||
d = defer.succeed(None)
|
|
||||||
for command in options.parsed_cmds:
|
|
||||||
if command.command in ('quit', 'exit'):
|
|
||||||
break
|
|
||||||
d.addCallback(exec_command, command)
|
|
||||||
d.addCallback(do_command, 'quit')
|
|
||||||
return d
|
|
||||||
|
|
||||||
# We need to wait for the rpcs in start() to finish before processing
|
|
||||||
# any of the commands.
|
|
||||||
self.started_deferred.addCallback(on_started)
|
|
||||||
return self.started_deferred
|
|
||||||
|
|
||||||
d = self.start_console()
|
|
||||||
d.addCallback(on_components_started)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def on_connect_fail(reason):
|
|
||||||
if reason.check(DelugeError):
|
|
||||||
rm = reason.getErrorMessage()
|
|
||||||
else:
|
else:
|
||||||
rm = reason.value.message
|
daemon_options = (
|
||||||
|
options.daemon_addr,
|
||||||
|
options.daemon_port,
|
||||||
|
options.daemon_user,
|
||||||
|
options.daemon_pass,
|
||||||
|
)
|
||||||
|
log.info(
|
||||||
|
'Connect: host=%s, port=%s, username=%s',
|
||||||
|
*daemon_options[0:3],
|
||||||
|
)
|
||||||
|
await client.connect(*daemon_options)
|
||||||
|
except Exception as reason:
|
||||||
print(
|
print(
|
||||||
'Could not connect to daemon: %s:%s\n %s'
|
'Could not connect to daemon: %s:%s\n %s'
|
||||||
% (options.daemon_addr, options.daemon_port, rm)
|
% (options.daemon_addr, options.daemon_port, reason)
|
||||||
)
|
)
|
||||||
commander.do_command('quit')
|
commander.do_command('quit')
|
||||||
|
|
||||||
d = None
|
await self.start_console()
|
||||||
if not self.interactive and options.parsed_cmds[0].command == 'connect':
|
# Wait for RPCs in start() to finish before processing commands.
|
||||||
d = commander.exec_command(options.parsed_cmds.pop(0))
|
await self.started_deferred
|
||||||
else:
|
|
||||||
log.info(
|
for cmd in options.parsed_cmds:
|
||||||
'connect: host=%s, port=%s, username=%s, password=%s',
|
if cmd.command in ('quit', 'exit'):
|
||||||
options.daemon_addr,
|
break
|
||||||
options.daemon_port,
|
await commander.exec_command(cmd)
|
||||||
options.daemon_user,
|
|
||||||
options.daemon_pass,
|
commander.do_command('quit')
|
||||||
)
|
|
||||||
d = client.connect(
|
|
||||||
options.daemon_addr,
|
|
||||||
options.daemon_port,
|
|
||||||
options.daemon_user,
|
|
||||||
options.daemon_pass,
|
|
||||||
)
|
|
||||||
d.addCallback(on_connect)
|
|
||||||
d.addErrback(on_connect_fail)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def run(self, stdscr):
|
def run(self, stdscr):
|
||||||
"""This method is called by the curses.wrapper to start the mainloop and screen.
|
"""This method is called by the curses.wrapper to start the mainloop and screen.
|
||||||
|
@ -353,8 +324,12 @@ deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
|
||||||
def is_active_mode(self, mode):
|
def is_active_mode(self, mode):
|
||||||
return mode == self.active_mode
|
return mode == self.active_mode
|
||||||
|
|
||||||
def start_components(self):
|
@maybe_coroutine
|
||||||
def on_started(result):
|
async def start_components(self):
|
||||||
|
if not self.interactive:
|
||||||
|
return await component.start(['SessionProxy', 'ConsoleUI', 'CoreConfig'])
|
||||||
|
|
||||||
|
await component.start()
|
||||||
component.pause(
|
component.pause(
|
||||||
[
|
[
|
||||||
'TorrentList',
|
'TorrentList',
|
||||||
|
@ -365,49 +340,35 @@ deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.interactive:
|
@maybe_coroutine
|
||||||
d = component.start().addCallback(on_started)
|
async def start_console(self):
|
||||||
else:
|
|
||||||
d = component.start(['SessionProxy', 'ConsoleUI', 'CoreConfig'])
|
|
||||||
return d
|
|
||||||
|
|
||||||
def start_console(self):
|
|
||||||
# Maintain a list of (torrent_id, name) for use in tab completion
|
|
||||||
self.started_deferred = defer.Deferred()
|
self.started_deferred = defer.Deferred()
|
||||||
|
|
||||||
if not self.initialized:
|
if self.initialized:
|
||||||
self.initialized = True
|
await component.stop(['SessionProxy'])
|
||||||
d = self.start_components()
|
await component.start(['SessionProxy'])
|
||||||
else:
|
else:
|
||||||
|
self.initialized = True
|
||||||
|
await self.start_components()
|
||||||
|
|
||||||
def on_stopped(result):
|
@maybe_coroutine
|
||||||
return component.start(['SessionProxy'])
|
async def start(self):
|
||||||
|
result = await client.core.get_session_state()
|
||||||
d = component.stop(['SessionProxy']).addCallback(on_stopped)
|
# Maintain a list of (torrent_id, name) for use in tab completion
|
||||||
return d
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
def on_session_state(result):
|
|
||||||
self.torrents = []
|
self.torrents = []
|
||||||
self.events = []
|
self.events = []
|
||||||
|
|
||||||
def on_torrents_status(torrents):
|
torrents = await client.core.get_torrents_status({'id': result}, ['name'])
|
||||||
for torrent_id, status in torrents.items():
|
for torrent_id, status in torrents.items():
|
||||||
self.torrents.append((torrent_id, status['name']))
|
self.torrents.append((torrent_id, status['name']))
|
||||||
|
|
||||||
self.started_deferred.callback(True)
|
self.started_deferred.callback(True)
|
||||||
|
|
||||||
client.core.get_torrents_status({'id': result}, ['name']).addCallback(
|
|
||||||
on_torrents_status
|
|
||||||
)
|
|
||||||
|
|
||||||
d = client.core.get_session_state().addCallback(on_session_state)
|
|
||||||
|
|
||||||
# Register event handlers to keep the torrent list up-to-date
|
# Register event handlers to keep the torrent list up-to-date
|
||||||
client.register_event_handler('TorrentAddedEvent', self.on_torrent_added_event)
|
client.register_event_handler('TorrentAddedEvent', self.on_torrent_added_event)
|
||||||
client.register_event_handler(
|
client.register_event_handler(
|
||||||
'TorrentRemovedEvent', self.on_torrent_removed_event
|
'TorrentRemovedEvent', self.on_torrent_removed_event
|
||||||
)
|
)
|
||||||
return d
|
|
||||||
|
|
||||||
def on_torrent_added_event(self, event, from_state=False):
|
def on_torrent_added_event(self, event, from_state=False):
|
||||||
def on_torrent_status(status):
|
def on_torrent_status(status):
|
||||||
|
|
Loading…
Reference in New Issue