mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-27 10:44:33 +00:00
deluge: Fix app installation on Debian testing
Closes: #2322. On Debian stable, mark deluge app as not available because deluge-web is not working in this distribution. - Default deluged configuration directory location changed. I didn't do migration from the old location because deluge app hasn't been working on Debian stable. - Make deluge-web systemd service start after deluged service to prevent Connection Manager popup in deluge-web after system reboot. Tests performed: - On Debian stable: - Deluge app is not installable from the app page. - All functional tests are skipped. - On Debian testing: - All tests pass. - After reboot, deluge-web service started after deluge service and there is no Connection Manager popup in deluge web UI. - Changing torrent download directory works. Signed-off-by: Veiko Aasa <veiko17@disroot.org> [sunil: Add type signature to an overridden method] Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
41675eec39
commit
85b6e00001
@ -11,6 +11,7 @@ from plinth.modules.apache.components import Webserver
|
|||||||
from plinth.modules.backups.components import BackupRestore
|
from plinth.modules.backups.components import BackupRestore
|
||||||
from plinth.modules.firewall.components import (Firewall,
|
from plinth.modules.firewall.components import (Firewall,
|
||||||
FirewallLocalProtection)
|
FirewallLocalProtection)
|
||||||
|
from plinth.modules.upgrades import get_current_release
|
||||||
from plinth.modules.users import add_user_to_share_group
|
from plinth.modules.users import add_user_to_share_group
|
||||||
from plinth.modules.users.components import UsersAndGroups
|
from plinth.modules.users.components import UsersAndGroups
|
||||||
from plinth.package import Packages
|
from plinth.package import Packages
|
||||||
@ -26,12 +27,26 @@ _description = [
|
|||||||
SYSTEM_USER = 'debian-deluged'
|
SYSTEM_USER = 'debian-deluged'
|
||||||
|
|
||||||
|
|
||||||
|
class DelugePackages(Packages):
|
||||||
|
"""Mark deluge app as not available in Debian Bookworm.
|
||||||
|
|
||||||
|
deluge-web is broken in Debian Bookworm. Related bug report:
|
||||||
|
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1031593
|
||||||
|
"""
|
||||||
|
|
||||||
|
def has_unavailable_packages(self) -> bool | None:
|
||||||
|
if get_current_release()[1] == 'bookworm':
|
||||||
|
return True
|
||||||
|
|
||||||
|
return super().has_unavailable_packages()
|
||||||
|
|
||||||
|
|
||||||
class DelugeApp(app_module.App):
|
class DelugeApp(app_module.App):
|
||||||
"""FreedomBox app for Deluge."""
|
"""FreedomBox app for Deluge."""
|
||||||
|
|
||||||
app_id = 'deluge'
|
app_id = 'deluge'
|
||||||
|
|
||||||
_version = 8
|
_version = 9
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Create components for the app."""
|
"""Create components for the app."""
|
||||||
@ -64,7 +79,7 @@ class DelugeApp(app_module.App):
|
|||||||
allowed_groups=list(groups))
|
allowed_groups=list(groups))
|
||||||
self.add(shortcut)
|
self.add(shortcut)
|
||||||
|
|
||||||
packages = Packages('packages-deluge', ['deluged', 'deluge-web'])
|
packages = DelugePackages('packages-deluge', ['deluged', 'deluge-web'])
|
||||||
self.add(packages)
|
self.add(packages)
|
||||||
|
|
||||||
dropin_configs = DropinConfigs(
|
dropin_configs = DropinConfigs(
|
||||||
|
|||||||
@ -13,7 +13,7 @@ clients = [{
|
|||||||
|
|
||||||
backup = {
|
backup = {
|
||||||
'config': {
|
'config': {
|
||||||
'directories': ['/var/lib/deluged/.config']
|
'directories': ['/var/lib/deluged/config']
|
||||||
},
|
},
|
||||||
'services': ['deluged', 'deluge-web']
|
'services': ['deluged', 'deluge-web']
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,10 @@ from plinth.actions import privileged
|
|||||||
from plinth.modules.deluge.utils import Config
|
from plinth.modules.deluge.utils import Config
|
||||||
|
|
||||||
DELUGED_DEFAULT_FILE = '/etc/default/deluged'
|
DELUGED_DEFAULT_FILE = '/etc/default/deluged'
|
||||||
DELUGE_CONF_DIR = pathlib.Path('/var/lib/deluged/.config/deluge/')
|
DELUGE_CONF_DIR = pathlib.Path('/var/lib/deluged/config/')
|
||||||
|
|
||||||
DELUGE_WEB_SYSTEMD_SERVICE_PATH = '/etc/systemd/system/deluge-web.service'
|
DELUGE_WEB_SYSTEMD_SERVICE_PATH = '/etc/systemd/system/deluge-web.service'
|
||||||
DELUGE_WEB_SYSTEMD_SERVICE = '''
|
DELUGE_WEB_SYSTEMD_SERVICE = f'''
|
||||||
#
|
#
|
||||||
# This file is managed and overwritten by Plinth. If you wish to edit
|
# This file is managed and overwritten by Plinth. If you wish to edit
|
||||||
# it, disable Deluge in Plinth, remove this file and manage it manually.
|
# it, disable Deluge in Plinth, remove this file and manage it manually.
|
||||||
@ -25,9 +25,10 @@ DELUGE_WEB_SYSTEMD_SERVICE = '''
|
|||||||
Description=Deluge Web Interface
|
Description=Deluge Web Interface
|
||||||
Documentation=man:deluge-web(1)
|
Documentation=man:deluge-web(1)
|
||||||
After=network.target
|
After=network.target
|
||||||
|
After=deluged.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=bash -c "/usr/bin/deluge-web --base=deluge $(/usr/bin/deluge-web --version | grep deluge-web | cut -f2 -d' ' | grep -q '^1.' && echo '' || echo '--do-not-daemonize')"
|
ExecStart=/usr/bin/deluge-web --config {DELUGE_CONF_DIR} --base=deluge --do-not-daemonize
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
User=debian-deluged
|
User=debian-deluged
|
||||||
Group=debian-deluged
|
Group=debian-deluged
|
||||||
|
|||||||
@ -35,14 +35,12 @@ class TestDelugeApp(functional.BaseAppTests):
|
|||||||
'nogroupuser')
|
'nogroupuser')
|
||||||
assert not functional.is_available(session_browser, 'deluge')
|
assert not functional.is_available(session_browser, 'deluge')
|
||||||
|
|
||||||
functional.login(session_browser)
|
|
||||||
|
|
||||||
def test_upload_torrent(self, session_browser):
|
def test_upload_torrent(self, session_browser):
|
||||||
"""Test uploading a torrent."""
|
"""Test uploading a torrent."""
|
||||||
functional.app_enable(session_browser, 'deluge')
|
functional.app_enable(session_browser, 'deluge')
|
||||||
_remove_all_torrents(session_browser)
|
_remove_all_torrents(session_browser)
|
||||||
_upload_sample_torrent(session_browser)
|
_upload_sample_torrent(session_browser)
|
||||||
assert _get_number_of_torrents(session_browser) == 1
|
assert len(_get_torrents(session_browser)) == 1
|
||||||
|
|
||||||
@pytest.mark.backups
|
@pytest.mark.backups
|
||||||
def test_backup_restore(self, session_browser):
|
def test_backup_restore(self, session_browser):
|
||||||
@ -55,7 +53,7 @@ class TestDelugeApp(functional.BaseAppTests):
|
|||||||
_remove_all_torrents(session_browser)
|
_remove_all_torrents(session_browser)
|
||||||
functional.backup_restore(session_browser, 'deluge', 'test_deluge')
|
functional.backup_restore(session_browser, 'deluge', 'test_deluge')
|
||||||
assert functional.service_is_running(session_browser, 'deluge')
|
assert functional.service_is_running(session_browser, 'deluge')
|
||||||
assert _get_number_of_torrents(session_browser) == 1
|
assert len(_get_torrents(session_browser)) == 1
|
||||||
|
|
||||||
|
|
||||||
def _get_active_window_title(browser):
|
def _get_active_window_title(browser):
|
||||||
@ -81,49 +79,30 @@ def _ensure_logged_in(browser):
|
|||||||
# After a backup restore, service may not be available immediately
|
# After a backup restore, service may not be available immediately
|
||||||
functional.eventually(service_is_available)
|
functional.eventually(service_is_available)
|
||||||
|
|
||||||
time.sleep(1) # Wait for Ext.js application in initialize
|
functional.eventually(browser.is_element_present_by_id, ['add'])
|
||||||
|
|
||||||
if _get_active_window_title(browser) != 'Login':
|
def logged_in():
|
||||||
return
|
active_window_title = _get_active_window_title(browser)
|
||||||
|
|
||||||
browser.find_by_id('_password').first.fill('deluge')
|
# Change Default Password window appears once.
|
||||||
_click_active_window_button(browser, 'Login')
|
if active_window_title == 'Change Default Password':
|
||||||
|
_click_active_window_button(browser, 'No')
|
||||||
|
|
||||||
assert functional.eventually(
|
if active_window_title == 'Login':
|
||||||
lambda: _get_active_window_title(browser) != 'Login')
|
browser.find_by_id('_password').first.fill('deluge')
|
||||||
functional.eventually(browser.is_element_not_present_by_css,
|
_click_active_window_button(browser, 'Login')
|
||||||
args=['#add.x-item-disabled'], timeout=0.3)
|
|
||||||
|
|
||||||
|
return browser.is_element_not_present_by_css('#add .x-item-disabled')
|
||||||
|
|
||||||
def _open_connection_manager(browser):
|
functional.eventually(logged_in)
|
||||||
"""Open the connection manager dialog if not already open."""
|
|
||||||
title = 'Connection Manager'
|
|
||||||
if _get_active_window_title(browser) == title:
|
|
||||||
return
|
|
||||||
|
|
||||||
browser.find_by_css('button.x-deluge-connection-manager').first.click()
|
|
||||||
functional.eventually(lambda: _get_active_window_title(browser) == title)
|
|
||||||
|
|
||||||
|
|
||||||
def _ensure_connected(browser):
|
|
||||||
"""Type the connection password if required and start Deluge daemon."""
|
|
||||||
_ensure_logged_in(browser)
|
|
||||||
|
|
||||||
# Change Default Password window appears once.
|
|
||||||
if _get_active_window_title(browser) == 'Change Default Password':
|
|
||||||
_click_active_window_button(browser, 'No')
|
|
||||||
|
|
||||||
assert functional.eventually(browser.is_element_not_present_by_css,
|
|
||||||
args=['#add.x-item-disabled'])
|
|
||||||
|
|
||||||
|
|
||||||
def _remove_all_torrents(browser):
|
def _remove_all_torrents(browser):
|
||||||
"""Remove all torrents from deluge."""
|
"""Remove all torrents from deluge."""
|
||||||
_ensure_connected(browser)
|
_ensure_logged_in(browser)
|
||||||
|
|
||||||
while browser.find_by_css('#torrentGrid .torrent-name'):
|
|
||||||
browser.find_by_css('#torrentGrid .torrent-name').first.click()
|
|
||||||
|
|
||||||
|
for torrent in _get_torrents(browser):
|
||||||
|
torrent.click()
|
||||||
# Click remove toolbar button
|
# Click remove toolbar button
|
||||||
browser.find_by_id('remove').first.click()
|
browser.find_by_id('remove').first.click()
|
||||||
|
|
||||||
@ -155,9 +134,9 @@ def _click_active_window_button(browser, button_text):
|
|||||||
|
|
||||||
def _upload_sample_torrent(browser):
|
def _upload_sample_torrent(browser):
|
||||||
"""Upload a sample torrent into deluge."""
|
"""Upload a sample torrent into deluge."""
|
||||||
_ensure_connected(browser)
|
_ensure_logged_in(browser)
|
||||||
|
|
||||||
number_of_torrents = _get_number_of_torrents(browser)
|
number_of_torrents = len(_get_torrents(browser))
|
||||||
|
|
||||||
# Click add toolbar button
|
# Click add toolbar button
|
||||||
browser.find_by_id('add').first.click()
|
browser.find_by_id('add').first.click()
|
||||||
@ -168,35 +147,20 @@ def _upload_sample_torrent(browser):
|
|||||||
|
|
||||||
file_path = os.path.join(os.path.dirname(__file__), 'data',
|
file_path = os.path.join(os.path.dirname(__file__), 'data',
|
||||||
'sample.torrent')
|
'sample.torrent')
|
||||||
|
browser.attach_file('file', file_path)
|
||||||
if browser.find_by_id('fileUploadForm'): # deluge-web 2.x
|
|
||||||
browser.attach_file('file', file_path)
|
|
||||||
else: # deluge-web 1.x
|
|
||||||
browser.find_by_css('button.x-deluge-add-file').first.click()
|
|
||||||
|
|
||||||
# Add from file window appears
|
|
||||||
functional.eventually(
|
|
||||||
lambda: _get_active_window_title(browser) == 'Add from File')
|
|
||||||
|
|
||||||
# Attach file
|
|
||||||
browser.attach_file('file', file_path)
|
|
||||||
|
|
||||||
# Click Add
|
|
||||||
_click_active_window_button(browser, 'Add')
|
|
||||||
|
|
||||||
functional.eventually(
|
|
||||||
lambda: _get_active_window_title(browser) == 'Add Torrents')
|
|
||||||
|
|
||||||
# Click Add
|
# Click Add
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
_click_active_window_button(browser, 'Add')
|
_click_active_window_button(browser, 'Add')
|
||||||
|
|
||||||
functional.eventually(
|
functional.eventually(
|
||||||
lambda: _get_number_of_torrents(browser) > number_of_torrents)
|
lambda: len(_get_torrents(browser)) > number_of_torrents)
|
||||||
|
|
||||||
|
|
||||||
def _get_number_of_torrents(browser):
|
def _get_torrents(browser):
|
||||||
"""Return the number torrents currently in deluge."""
|
"""Return list of torrents currently in deluge."""
|
||||||
_ensure_connected(browser)
|
_ensure_logged_in(browser)
|
||||||
|
# wait until torrent list is loaded
|
||||||
|
functional.eventually(browser.is_element_present_by_css, ['.x-deluge-all'])
|
||||||
|
|
||||||
return len(browser.find_by_css('#torrentGrid .torrent-name'))
|
return browser.find_by_css('#torrentGrid .torrent-name')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user