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.
|
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
|
import rtorrent
|
||||||
|
|
||||||
|
@ -10,7 +12,8 @@ app = Flask(__name__)
|
||||||
app.jinja_env.trim_blocks = True
|
app.jinja_env.trim_blocks = True
|
||||||
app.jinja_env.lstrip_blocks = True
|
app.jinja_env.lstrip_blocks = True
|
||||||
app.jinja_env.undefined = "StrictUndefined"
|
app.jinja_env.undefined = "StrictUndefined"
|
||||||
rtorrent.get_all()
|
rtorrent.init()
|
||||||
|
signal.signal(signal.SIGINT, rtorrent.stop_watch)
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
@ -18,5 +21,10 @@ def index():
|
||||||
torrents = rtorrent.get_active()
|
torrents = rtorrent.get_active()
|
||||||
return render_template("index.html", **locals())
|
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__":
|
if __name__ == "__main__":
|
||||||
app.run(host='0.0.0.0', port=5250)
|
app.run(host='0.0.0.0', port=5250)
|
||||||
|
|
87
rtorrent.py
87
rtorrent.py
|
@ -2,15 +2,21 @@
|
||||||
"""
|
"""
|
||||||
This module handles the interface with rTorrent via XMLRPC.
|
This module handles the interface with rTorrent via XMLRPC.
|
||||||
"""
|
"""
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
import xmlrpc.client
|
import xmlrpc.client
|
||||||
|
|
||||||
_s = xmlrpc.client.ServerProxy("http://localhost:8000/RPC0")
|
NUM_INST = 10
|
||||||
torrents = []
|
WATCH_HANDLE = None
|
||||||
|
sp = []
|
||||||
|
torrents = [[]] * NUM_INST
|
||||||
|
|
||||||
class Torrent:
|
class Torrent:
|
||||||
def __init__(self, raw):
|
def __init__(self, raw):
|
||||||
self.hash = raw[0]
|
self.hash = raw[0]
|
||||||
self.name = raw[1]
|
self.name = raw[1]
|
||||||
|
|
||||||
self.active = raw[2]
|
self.active = raw[2]
|
||||||
self.complete = raw[3]
|
self.complete = raw[3]
|
||||||
if not self.active:
|
if not self.active:
|
||||||
|
@ -19,13 +25,64 @@ class Torrent:
|
||||||
self.state = "seeding"
|
self.state = "seeding"
|
||||||
else:
|
else:
|
||||||
self.state = "leeching"
|
self.state = "leeching"
|
||||||
self.downrate = raw[4]
|
|
||||||
self.uprate = raw[5]
|
|
||||||
|
|
||||||
def get_all():
|
self.downrate = raw[4]
|
||||||
"""Gets all torrent information and stores it."""
|
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
|
global torrents
|
||||||
res = _s.d.multicall2('', 'main',
|
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.hash=',
|
||||||
'd.name=',
|
'd.name=',
|
||||||
'd.is_active=',
|
'd.is_active=',
|
||||||
|
@ -33,9 +90,21 @@ def get_all():
|
||||||
'd.down.rate=',
|
'd.down.rate=',
|
||||||
'd.up.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():
|
def get_active():
|
||||||
"""Returns all actively seeding or leeching torrents."""
|
"""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
|
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>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Aberrant</title>
|
<title>Aberrant</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='aberrant.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table>
|
<table id="torrents">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
@ -16,10 +17,10 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for torrent in torrents %}
|
{% for torrent in torrents %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ torrent.name }}</td>
|
<td class="name">{{ torrent.name }}</td>
|
||||||
<td>{{ torrent.state }}</td>
|
<td class="state">{{ torrent.state }}</td>
|
||||||
<td>{{ torrent.downrate }}</td>
|
<td class="downrate">{{ torrent.downrate_str }}</td>
|
||||||
<td>{{ torrent.uprate }}</td>
|
<td class="uprate">{{ torrent.uprate_str }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user