fourth commit
This commit is contained in:
parent
70c95d28af
commit
1d81c7fb63
12
aberrant.py
12
aberrant.py
|
@ -2,7 +2,9 @@
|
|||
"""
|
||||
The primary module for serving the Aberrant application.
|
||||
"""
|
||||
from flask import Flask, render_template
|
||||
import signal
|
||||
|
||||
from flask import Flask, render_template, send_from_directory
|
||||
|
||||
import rtorrent
|
||||
|
||||
|
@ -10,7 +12,8 @@ app = Flask(__name__)
|
|||
app.jinja_env.trim_blocks = True
|
||||
app.jinja_env.lstrip_blocks = True
|
||||
app.jinja_env.undefined = "StrictUndefined"
|
||||
rtorrent.get_all()
|
||||
rtorrent.init()
|
||||
signal.signal(signal.SIGINT, rtorrent.stop_watch)
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
|
@ -18,5 +21,10 @@ def index():
|
|||
torrents = rtorrent.get_active()
|
||||
return render_template("index.html", **locals())
|
||||
|
||||
@app.route("/static/<path:path>")
|
||||
def send_static(path):
|
||||
"""Sends static files."""
|
||||
return send_from_directory("static", path)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0', port=5250)
|
||||
|
|
89
rtorrent.py
89
rtorrent.py
|
@ -2,15 +2,21 @@
|
|||
"""
|
||||
This module handles the interface with rTorrent via XMLRPC.
|
||||
"""
|
||||
import re
|
||||
import time
|
||||
import threading
|
||||
import xmlrpc.client
|
||||
|
||||
_s = xmlrpc.client.ServerProxy("http://localhost:8000/RPC0")
|
||||
torrents = []
|
||||
NUM_INST = 10
|
||||
WATCH_HANDLE = None
|
||||
sp = []
|
||||
torrents = [[]] * NUM_INST
|
||||
|
||||
class Torrent:
|
||||
def __init__(self, raw):
|
||||
self.hash = raw[0]
|
||||
self.name = raw[1]
|
||||
|
||||
self.active = raw[2]
|
||||
self.complete = raw[3]
|
||||
if not self.active:
|
||||
|
@ -19,13 +25,64 @@ class Torrent:
|
|||
self.state = "seeding"
|
||||
else:
|
||||
self.state = "leeching"
|
||||
self.downrate = raw[4]
|
||||
self.uprate = raw[5]
|
||||
|
||||
def get_all():
|
||||
"""Gets all torrent information and stores it."""
|
||||
global torrents
|
||||
res = _s.d.multicall2('', 'main',
|
||||
self.downrate = raw[4]
|
||||
self.downrate_str = speedrate(self.downrate)
|
||||
self.uprate = raw[5]
|
||||
self.uprate_str = speedrate(self.uprate)
|
||||
|
||||
|
||||
class Watch(threading.Thread):
|
||||
"""A thread class that continously queries the rTorrent instances."""
|
||||
def __init__(self):
|
||||
super(Watch, self).__init__()
|
||||
self._stop_event = threading.Event()
|
||||
|
||||
def stop(self):
|
||||
self._stop_event.set()
|
||||
|
||||
def stopped(self):
|
||||
return self._stop_event.is_set()
|
||||
|
||||
def run(self):
|
||||
global torrents
|
||||
while not self.stopped():
|
||||
for n in range(NUM_INST):
|
||||
if self.stopped():
|
||||
break
|
||||
torrents[n] = get_all(n)
|
||||
self._stop_event.wait(2)
|
||||
|
||||
|
||||
def speedrate(rate):
|
||||
"""Helper to assign appropriate prefixes to speed rates."""
|
||||
unit = "B/s"
|
||||
if rate > 1024:
|
||||
rate /= 1024
|
||||
unit = "KiB/s"
|
||||
if rate > 1024:
|
||||
rate /= 1024
|
||||
unit = "MiB/s"
|
||||
rate = round(rate, 1)
|
||||
return str(rate) + unit
|
||||
|
||||
def all_torrents():
|
||||
"""Helper that returns a list of all torrents."""
|
||||
res = []
|
||||
for item in torrents:
|
||||
res += item
|
||||
return res
|
||||
|
||||
def open_proxy():
|
||||
"""Opens connections to all of the rtorrent instances."""
|
||||
global sp
|
||||
for n in range(NUM_INST):
|
||||
s = xmlrpc.client.ServerProxy(f"http://localhost:8000/RPC{n}")
|
||||
sp.append(s)
|
||||
|
||||
def get_all(n):
|
||||
"""Gets all torrent information from a instance and returns it."""
|
||||
res = sp[n].d.multicall2('', 'main',
|
||||
'd.hash=',
|
||||
'd.name=',
|
||||
'd.is_active=',
|
||||
|
@ -33,9 +90,21 @@ def get_all():
|
|||
'd.down.rate=',
|
||||
'd.up.rate=',
|
||||
)
|
||||
torrents = [Torrent(raw) for raw in res]
|
||||
return [Torrent(raw) for raw in res]
|
||||
|
||||
def init():
|
||||
"""Initializes the rTorrent interface."""
|
||||
global WATCH_HANDLE
|
||||
open_proxy()
|
||||
WATCH_HANDLE = Watch()
|
||||
WATCH_HANDLE.start()
|
||||
|
||||
def stop_watch(sig, frame):
|
||||
"""Stops the watch thread."""
|
||||
global WATCH_HANDLE
|
||||
WATCH_HANDLE.stop()
|
||||
|
||||
def get_active():
|
||||
"""Returns all actively seeding or leeching torrents."""
|
||||
active = [t for t in torrents if t.downrate or t.uprate]
|
||||
active = [t for t in all_torrents() if t.downrate or t.uprate]
|
||||
return active
|
||||
|
|
28
static/aberrant.css
Normal file
28
static/aberrant.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
#torrents {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
tr {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.name {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.state {
|
||||
text-align: center;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.downrate {
|
||||
text-align: center;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.uprate {
|
||||
text-align: center;
|
||||
width: 10%;
|
||||
}
|
|
@ -2,9 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Aberrant</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='aberrant.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<table id="torrents">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
|
@ -16,10 +17,10 @@
|
|||
<tbody>
|
||||
{% for torrent in torrents %}
|
||||
<tr>
|
||||
<td>{{ torrent.name }}</td>
|
||||
<td>{{ torrent.state }}</td>
|
||||
<td>{{ torrent.downrate }}</td>
|
||||
<td>{{ torrent.uprate }}</td>
|
||||
<td class="name">{{ torrent.name }}</td>
|
||||
<td class="state">{{ torrent.state }}</td>
|
||||
<td class="downrate">{{ torrent.downrate_str }}</td>
|
||||
<td class="uprate">{{ torrent.uprate_str }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
Loading…
Reference in New Issue
Block a user