summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2023-02-24 23:45:53 +0000
committerCalum Lind <calumlind+deluge@gmail.com>2023-02-27 17:38:58 +0000
commit253eb2240bd33cdedac53eb19eecc9de53f57d8a (patch)
treedd4ed7ebe75aceb71e23e74826c48c2a1b2a5942
parent6c924e61284f943fff90d9c14c9826008459b329 (diff)
downloaddeluge-253eb2240bd33cdedac53eb19eecc9de53f57d8a.tar.gz
deluge-253eb2240bd33cdedac53eb19eecc9de53f57d8a.tar.bz2
deluge-253eb2240bd33cdedac53eb19eecc9de53f57d8a.zip
[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.
-rw-r--r--deluge/ui/console/main.py175
1 files changed, 68 insertions, 107 deletions
diff --git a/deluge/ui/console/main.py b/deluge/ui/console/main.py
index 31d1db177..e52d87116 100644
--- a/deluge/ui/console/main.py
+++ b/deluge/ui/console/main.py
@@ -18,8 +18,7 @@ from twisted.internet import defer, error, reactor
import deluge.common
import deluge.component as component
from deluge.configmanager import ConfigManager
-from deluge.decorators import overrides
-from deluge.error import DelugeError
+from deluge.decorators import maybe_coroutine, overrides
from deluge.ui.client import client
from deluge.ui.console.modes.addtorrents import AddTorrents
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)
- def quit(self):
+ @maybe_coroutine
+ async def quit(self):
if client.connected():
+ await client.disconnect()
- def on_disconnect(result):
- reactor.stop()
-
- return client.disconnect().addCallback(on_disconnect)
- else:
- try:
- reactor.stop()
- except error.ReactorNotRunning:
- pass
+ try:
+ reactor.stop()
+ except error.ReactorNotRunning:
+ pass
- def exec_args(self, options):
+ @maybe_coroutine
+ async def exec_args(self, options):
"""Execute console commands from command line."""
from deluge.ui.console.cmdline.command import Commander
commander = Commander(self._commands)
-
- def on_connect(result):
- def on_components_started(result):
- 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()
+ try:
+ if not self.interactive and options.parsed_cmds[0].command == 'connect':
+ await commander.exec_command(options.parsed_cmds.pop(0))
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(
'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')
- d = None
- if not self.interactive and options.parsed_cmds[0].command == 'connect':
- d = commander.exec_command(options.parsed_cmds.pop(0))
- else:
- log.info(
- 'connect: host=%s, port=%s, username=%s, password=%s',
- options.daemon_addr,
- options.daemon_port,
- options.daemon_user,
- options.daemon_pass,
- )
- 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
+ await self.start_console()
+ # Wait for RPCs in start() to finish before processing commands.
+ await self.started_deferred
+
+ for cmd in options.parsed_cmds:
+ if cmd.command in ('quit', 'exit'):
+ break
+ await commander.exec_command(cmd)
+
+ commander.do_command('quit')
def run(self, stdscr):
"""This method is called by the curses.wrapper to start the mainloop and screen.
@@ -353,61 +324,51 @@ deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
def is_active_mode(self, mode):
return mode == self.active_mode
- def start_components(self):
- def on_started(result):
- component.pause(
- [
- 'TorrentList',
- 'EventView',
- 'AddTorrents',
- 'TorrentDetail',
- 'Preferences',
- ]
- )
-
- if self.interactive:
- d = component.start().addCallback(on_started)
- else:
- d = component.start(['SessionProxy', 'ConsoleUI', 'CoreConfig'])
- return d
+ @maybe_coroutine
+ async def start_components(self):
+ if not self.interactive:
+ return await component.start(['SessionProxy', 'ConsoleUI', 'CoreConfig'])
+
+ await component.start()
+ component.pause(
+ [
+ 'TorrentList',
+ 'EventView',
+ 'AddTorrents',
+ 'TorrentDetail',
+ 'Preferences',
+ ]
+ )
- def start_console(self):
- # Maintain a list of (torrent_id, name) for use in tab completion
+ @maybe_coroutine
+ async def start_console(self):
self.started_deferred = defer.Deferred()
- if not self.initialized:
- self.initialized = True
- d = self.start_components()
+ if self.initialized:
+ await component.stop(['SessionProxy'])
+ await component.start(['SessionProxy'])
else:
+ self.initialized = True
+ await self.start_components()
- def on_stopped(result):
- return component.start(['SessionProxy'])
-
- d = component.stop(['SessionProxy']).addCallback(on_stopped)
- return d
-
- def start(self):
- def on_session_state(result):
- self.torrents = []
- self.events = []
-
- def on_torrents_status(torrents):
- for torrent_id, status in torrents.items():
- self.torrents.append((torrent_id, status['name']))
- self.started_deferred.callback(True)
+ @maybe_coroutine
+ async def start(self):
+ result = await client.core.get_session_state()
+ # Maintain a list of (torrent_id, name) for use in tab completion
+ self.torrents = []
+ self.events = []
- client.core.get_torrents_status({'id': result}, ['name']).addCallback(
- on_torrents_status
- )
+ torrents = await client.core.get_torrents_status({'id': result}, ['name'])
+ for torrent_id, status in torrents.items():
+ self.torrents.append((torrent_id, status['name']))
- d = client.core.get_session_state().addCallback(on_session_state)
+ self.started_deferred.callback(True)
# 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(
'TorrentRemovedEvent', self.on_torrent_removed_event
)
- return d
def on_torrent_added_event(self, event, from_state=False):
def on_torrent_status(status):