Add systemd start/stop for transmission.service
This commit is contained in:
parent
385694da91
commit
66acf6b421
7 changed files with 85 additions and 92 deletions
|
@ -1,7 +1,7 @@
|
|||
[project]
|
||||
name = "torrent-downloader"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
version = "0.1.1"
|
||||
description = "Web interface for searching and downloading torrents"
|
||||
authors = [
|
||||
{ name = "Vladan Popovic", email = "vladanovic@gmail.com" }
|
||||
]
|
||||
|
@ -12,6 +12,7 @@ dependencies = [
|
|||
"fastapi>=0.114.2",
|
||||
"jinja2>=3.1.4",
|
||||
"cinemagoer>=2023.5.1",
|
||||
"dbus-python>=1.3.2",
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">= 3.8"
|
||||
|
|
|
@ -11,92 +11,45 @@
|
|||
|
||||
-e file:.
|
||||
annotated-types==0.7.0
|
||||
# via pydantic
|
||||
anyio==4.4.0
|
||||
# via starlette
|
||||
asttokens==2.4.1
|
||||
# via stack-data
|
||||
certifi==2024.8.30
|
||||
# via requests
|
||||
charset-normalizer==3.3.2
|
||||
# via requests
|
||||
cinemagoer==2023.5.1
|
||||
# via torrent-downloader
|
||||
click==8.1.7
|
||||
# via uvicorn
|
||||
dbus-python==1.3.2
|
||||
decorator==5.1.1
|
||||
# via ipython
|
||||
executing==2.1.0
|
||||
# via stack-data
|
||||
fastapi==0.114.2
|
||||
# via torrent-downloader
|
||||
greenlet==3.1.0
|
||||
# via sqlalchemy
|
||||
h11==0.14.0
|
||||
# via uvicorn
|
||||
idna==3.8
|
||||
# via anyio
|
||||
# via requests
|
||||
ipython==8.27.0
|
||||
jedi==0.19.1
|
||||
# via ipython
|
||||
jinja2==3.1.4
|
||||
# via torrent-downloader
|
||||
lxml==5.3.0
|
||||
# via cinemagoer
|
||||
# via tpblite
|
||||
markupsafe==2.1.5
|
||||
# via jinja2
|
||||
matplotlib-inline==0.1.7
|
||||
# via ipython
|
||||
parso==0.8.4
|
||||
# via jedi
|
||||
pexpect==4.9.0
|
||||
# via ipython
|
||||
prompt-toolkit==3.0.47
|
||||
# via ipython
|
||||
ptyprocess==0.7.0
|
||||
# via pexpect
|
||||
pure-eval==0.2.3
|
||||
# via stack-data
|
||||
pydantic==2.8.2
|
||||
# via fastapi
|
||||
# via pydantic-settings
|
||||
pydantic-core==2.20.1
|
||||
# via pydantic
|
||||
pydantic-settings==2.4.0
|
||||
# via torrent-downloader
|
||||
pygments==2.18.0
|
||||
# via ipython
|
||||
python-dotenv==1.0.1
|
||||
# via pydantic-settings
|
||||
requests==2.32.3
|
||||
# via transmission-rpc
|
||||
six==1.16.0
|
||||
# via asttokens
|
||||
sniffio==1.3.1
|
||||
# via anyio
|
||||
sqlalchemy==2.0.34
|
||||
# via cinemagoer
|
||||
stack-data==0.6.3
|
||||
# via ipython
|
||||
starlette==0.38.5
|
||||
# via fastapi
|
||||
tpblite==0.8.0
|
||||
# via torrent-downloader
|
||||
traitlets==5.14.3
|
||||
# via ipython
|
||||
# via matplotlib-inline
|
||||
transmission-rpc==7.0.11
|
||||
# via torrent-downloader
|
||||
typing-extensions==4.12.2
|
||||
# via fastapi
|
||||
# via pydantic
|
||||
# via pydantic-core
|
||||
# via sqlalchemy
|
||||
# via transmission-rpc
|
||||
urllib3==2.2.2
|
||||
# via requests
|
||||
uvicorn==0.30.6
|
||||
wcwidth==0.2.13
|
||||
# via prompt-toolkit
|
||||
|
|
|
@ -11,55 +11,26 @@
|
|||
|
||||
-e file:.
|
||||
annotated-types==0.7.0
|
||||
# via pydantic
|
||||
anyio==4.4.0
|
||||
# via starlette
|
||||
certifi==2024.8.30
|
||||
# via requests
|
||||
charset-normalizer==3.3.2
|
||||
# via requests
|
||||
cinemagoer==2023.5.1
|
||||
# via torrent-downloader
|
||||
dbus-python==1.3.2
|
||||
fastapi==0.114.2
|
||||
# via torrent-downloader
|
||||
greenlet==3.1.0
|
||||
# via sqlalchemy
|
||||
idna==3.8
|
||||
# via anyio
|
||||
# via requests
|
||||
jinja2==3.1.4
|
||||
# via torrent-downloader
|
||||
lxml==5.3.0
|
||||
# via cinemagoer
|
||||
# via tpblite
|
||||
markupsafe==2.1.5
|
||||
# via jinja2
|
||||
pydantic==2.8.2
|
||||
# via fastapi
|
||||
# via pydantic-settings
|
||||
pydantic-core==2.20.1
|
||||
# via pydantic
|
||||
pydantic-settings==2.4.0
|
||||
# via torrent-downloader
|
||||
python-dotenv==1.0.1
|
||||
# via pydantic-settings
|
||||
requests==2.32.3
|
||||
# via transmission-rpc
|
||||
sniffio==1.3.1
|
||||
# via anyio
|
||||
sqlalchemy==2.0.34
|
||||
# via cinemagoer
|
||||
starlette==0.38.5
|
||||
# via fastapi
|
||||
tpblite==0.8.0
|
||||
# via torrent-downloader
|
||||
transmission-rpc==7.0.11
|
||||
# via torrent-downloader
|
||||
typing-extensions==4.12.2
|
||||
# via fastapi
|
||||
# via pydantic
|
||||
# via pydantic-core
|
||||
# via sqlalchemy
|
||||
# via transmission-rpc
|
||||
urllib3==2.2.2
|
||||
# via requests
|
||||
|
|
|
@ -3,12 +3,13 @@ import urllib.parse
|
|||
|
||||
import transmission_rpc
|
||||
from fastapi import Depends, FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from torrent_downloader.client import TorrentDownloader
|
||||
from torrent_downloader.imdb import search_string_from_url
|
||||
from torrent_downloader.systemd import Systemd
|
||||
|
||||
app = FastAPI()
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
@ -19,8 +20,16 @@ def get_downloader() -> TorrentDownloader:
|
|||
return TorrentDownloader()
|
||||
|
||||
|
||||
def get_active_torrents(downloader=get_downloader()) -> list[transmission_rpc.Torrent]:
|
||||
return [t for t in downloader.get_active_torrents() if t.format_eta() != "not available"]
|
||||
def get_systemd() -> Systemd:
|
||||
return Systemd()
|
||||
|
||||
|
||||
def get_active_torrents(
|
||||
downloader=get_downloader(),
|
||||
) -> list[transmission_rpc.Torrent]:
|
||||
return [
|
||||
t for t in downloader.get_active_torrents() if t.format_eta().lower() != "not available"
|
||||
]
|
||||
|
||||
|
||||
def hx(func):
|
||||
|
@ -41,13 +50,8 @@ def hx(func):
|
|||
|
||||
|
||||
@app.get("/")
|
||||
async def index(_: Request):
|
||||
return RedirectResponse("/search")
|
||||
|
||||
|
||||
@app.get("/search", response_class=HTMLResponse)
|
||||
@hx
|
||||
async def search_for_torrents(request: Request):
|
||||
async def index(request: Request):
|
||||
return templates.TemplateResponse(request=request, name="search.html")
|
||||
|
||||
|
||||
|
@ -70,7 +74,9 @@ async def download(request: Request, downloader=Depends(get_downloader)):
|
|||
downloader.download_magnet(magnet)
|
||||
active = downloader.get_active_torrents()
|
||||
return templates.TemplateResponse(
|
||||
request=request, name="active_torrents.html", context={"torrents": active}
|
||||
request=request,
|
||||
name="active_torrents.html",
|
||||
context={"torrents": active},
|
||||
)
|
||||
|
||||
|
||||
|
@ -78,5 +84,34 @@ async def download(request: Request, downloader=Depends(get_downloader)):
|
|||
@hx
|
||||
async def active(request: Request, active=Depends(get_active_torrents)):
|
||||
return templates.TemplateResponse(
|
||||
request=request, name="active_torrents.html", context={"torrents": active}
|
||||
request=request,
|
||||
name="active_torrents.html",
|
||||
context={"torrents": active},
|
||||
)
|
||||
|
||||
|
||||
@app.get("/transmission", response_class=HTMLResponse)
|
||||
@hx
|
||||
async def transmission_status(request: Request, systemd=Depends(get_systemd)):
|
||||
return templates.TemplateResponse(
|
||||
request=request,
|
||||
name="transmission.html",
|
||||
context={"is_active": systemd.service_is_active("transmission")},
|
||||
)
|
||||
|
||||
|
||||
@app.post("/transmission/{action}", response_class=HTMLResponse)
|
||||
@hx
|
||||
async def transmission_start(request: Request, action: str, systemd=Depends(get_systemd)):
|
||||
match action:
|
||||
case "start":
|
||||
systemd.service_start("transmission")
|
||||
case "stop":
|
||||
systemd.service_stop("transmission")
|
||||
case _:
|
||||
return 404
|
||||
return templates.TemplateResponse(
|
||||
request=request,
|
||||
name="transmission.html",
|
||||
context={"is_active": systemd.service_is_active("transmission")},
|
||||
)
|
||||
|
|
24
src/torrent_downloader/systemd.py
Normal file
24
src/torrent_downloader/systemd.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
import dbus
|
||||
|
||||
|
||||
class Systemd:
|
||||
def __init__(self):
|
||||
self.bus = dbus.SessionBus()
|
||||
self.systemd = self.bus.get_object(
|
||||
"org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1",
|
||||
)
|
||||
self.manager = dbus.Interface(self.systemd, "org.freedesktop.systemd1.Manager")
|
||||
|
||||
def service_start(self, service: str):
|
||||
return self.manager.StartUnit(f"{service}.service", "replace")
|
||||
|
||||
def service_stop(self, service: str):
|
||||
return self.manager.StopUnit(f"{service}.service", "replace")
|
||||
|
||||
def service_is_active(self, service: str):
|
||||
try:
|
||||
self.manager.GetUnit(service)
|
||||
return True
|
||||
except dbus.exceptions.DBusException:
|
||||
return False
|
|
@ -5,7 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Search and download torrents directly to mediacenter</title>
|
||||
<script src="https://unpkg.com/htmx.org@2.0.0" integrity="sha384-wS5l5IKJBvK6sPTKa2WZ1js3d947pvWXbPJ1OmWfEuxLgeHcEbjUUA5i9V5ZkpCw" crossorigin="anonymous"></script>
|
||||
<link href="{{ url_for('static', path='/style.css') }}" rel="stylesheet">
|
||||
<link href="/static/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<menu>
|
||||
|
|
9
templates/transmission.html
Normal file
9
templates/transmission.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% block content %}
|
||||
{% if is_active %}
|
||||
<h3>Transmission is running!</h3>
|
||||
<button hx-post="/transmission/stop" hx-target="#content">Stop now!</button>
|
||||
{% else %}
|
||||
<h3>Transmission is stopped!</h3>
|
||||
<button hx-post="/transmission/start" hx-target="#content">Start now!</button>
|
||||
{% endif %}
|
||||
{% endblock %}
|
Loading…
Add table
Reference in a new issue