handle duplicates
This commit is contained in:
parent
293e083faf
commit
2099b337bc
|
@ -10,6 +10,7 @@ from dataclasses import dataclass, field
|
||||||
from deluge_client import DelugeRPCClient
|
from deluge_client import DelugeRPCClient
|
||||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||||
from mediaweb import shows
|
from mediaweb import shows
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
|
APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
|
||||||
|
@ -28,6 +29,12 @@ class Client:
|
||||||
pathmap: (str, str)
|
pathmap: (str, str)
|
||||||
|
|
||||||
|
|
||||||
|
class SortResult(Enum):
|
||||||
|
OK = 0
|
||||||
|
EXISTED = 1
|
||||||
|
FAIL = 2
|
||||||
|
|
||||||
|
|
||||||
class ClientCache(object):
|
class ClientCache(object):
|
||||||
def __init__(self, options, libpath):
|
def __init__(self, options, libpath):
|
||||||
self.options = options
|
self.options = options
|
||||||
|
@ -193,15 +200,16 @@ class MediaWeb(object):
|
||||||
thematch = m
|
thematch = m
|
||||||
break
|
break
|
||||||
|
|
||||||
self.execute_move(tkey, torrent, thematch)
|
result, reason = self.execute_move(tkey, torrent, thematch)
|
||||||
self.cache.refresh()
|
self.cache.refresh()
|
||||||
|
|
||||||
# TODO summary display
|
return self.render("sortform_done.html", success_torrents=[[torrent, result, reason]], failed_torrents=[])
|
||||||
return "OK"
|
|
||||||
|
|
||||||
return self.render("sortform.html", torrent=torrent, matches=matches, tkey=tkey, score=score)
|
return self.render("sortform.html", torrent=torrent, matches=matches, tkey=tkey, score=score)
|
||||||
|
|
||||||
def execute_move(self, tkey, torrent, match):
|
def execute_move(self, tkey, torrent, match):
|
||||||
|
result = SortResult.OK
|
||||||
|
|
||||||
# resolve the pathmap
|
# resolve the pathmap
|
||||||
thash, client = self.cache.client(tkey)
|
thash, client = self.cache.client(tkey)
|
||||||
|
|
||||||
|
@ -216,9 +224,21 @@ class MediaWeb(object):
|
||||||
local_torrent_path = os.path.join(pmap[1], client_full_path[len(pmap[0]):].lstrip("/")) # our perspective's path to the file
|
local_torrent_path = os.path.join(pmap[1], client_full_path[len(pmap[0]):].lstrip("/")) # our perspective's path to the file
|
||||||
local_library_path = os.path.join(self.options["library_path"], in_library_path) # where we will place the file in the library
|
local_library_path = os.path.join(self.options["library_path"], in_library_path) # where we will place the file in the library
|
||||||
|
|
||||||
# hard link into library
|
# check if the dest file already exists:
|
||||||
os.link(local_torrent_path, local_library_path)
|
if os.path.exists(local_library_path):
|
||||||
print(f"os.link('{local_torrent_path}', '{local_library_path}')")
|
# if the src and dest are already linked to the same file, this is a noop
|
||||||
|
if os.stat(local_torrent_path).st_ino == os.stat(local_library_path).st_ino:
|
||||||
|
result = SortResult.EXISTED
|
||||||
|
logging.info("dest exists, skipping linking %s -> %s", local_torrent_path, local_library_path)
|
||||||
|
else:
|
||||||
|
return SortResult.FAIL, "destination file already exists and has different contents"
|
||||||
|
else:
|
||||||
|
# hard link into library
|
||||||
|
showdir = os.path.dirname(local_library_path)
|
||||||
|
if not os.path.exists(showdir):
|
||||||
|
os.makedirs(showdir)
|
||||||
|
os.link(local_torrent_path, local_library_path)
|
||||||
|
logging.info("linking %s -> %s", local_torrent_path, local_library_path)
|
||||||
|
|
||||||
client_stashdir = os.path.join(pmap[0],
|
client_stashdir = os.path.join(pmap[0],
|
||||||
self.options["stashprefix"],
|
self.options["stashprefix"],
|
||||||
|
@ -230,20 +250,26 @@ class MediaWeb(object):
|
||||||
# label torrent as sorted
|
# label torrent as sorted
|
||||||
client.rpc.label.set_torrent(torrent["hash"], self.options["label_done"])
|
client.rpc.label.set_torrent(torrent["hash"], self.options["label_done"])
|
||||||
|
|
||||||
|
return result, None
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def autosort(self, tkeys):
|
def autosort(self, tkeys):
|
||||||
if not isinstance(tkeys, list):
|
if not isinstance(tkeys, list):
|
||||||
tkeys = [tkeys]
|
tkeys = [tkeys]
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
for tkey in tkeys:
|
for tkey in tkeys:
|
||||||
thash, client = self.cache.client(tkey)
|
thash, client = self.cache.client(tkey)
|
||||||
torrent = client.rpc.core.get_torrent_status(thash, []) # TODO reduce to needed fields
|
torrent = client.rpc.core.get_torrent_status(thash, []) # TODO reduce to needed fields
|
||||||
self.execute_move(tkey, torrent, self.cache.moves[tkey])
|
res = self.execute_move(tkey, torrent, self.cache.moves[tkey])
|
||||||
|
results.append([torrent, res[0], res[1]])
|
||||||
|
|
||||||
self.cache.refresh()
|
self.cache.refresh()
|
||||||
# TODO summary display of results
|
|
||||||
|
|
||||||
return f"autosorted: {repr(tkeys)}"
|
return self.render("sortform_done.html",
|
||||||
|
success_torrents=[r for r in results if r[1] != SortResult.FAIL],
|
||||||
|
failed_torrents=[r for r in results if r[1] == SortResult.FAIL])
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def modify(self, action, tkey):
|
def modify(self, action, tkey):
|
||||||
|
@ -321,7 +347,8 @@ def main():
|
||||||
tpl = Environment(loader=FileSystemLoader(tpl_dir),
|
tpl = Environment(loader=FileSystemLoader(tpl_dir),
|
||||||
autoescape=select_autoescape(['html', 'xml']))
|
autoescape=select_autoescape(['html', 'xml']))
|
||||||
tpl.filters.update(tsortbyname=tsortbyname,
|
tpl.filters.update(tsortbyname=tsortbyname,
|
||||||
len=len, )
|
len=len,
|
||||||
|
jsond=json.dumps)
|
||||||
|
|
||||||
def validate_password(realm, user, passw):
|
def validate_password(realm, user, passw):
|
||||||
return user == passw # lol
|
return user == passw # lol
|
||||||
|
|
|
@ -7,7 +7,6 @@ fuzzywuzzy==0.17.0
|
||||||
jaraco.functools==2.0
|
jaraco.functools==2.0
|
||||||
Jinja2==2.10.1
|
Jinja2==2.10.1
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
mediasortweb==0.0.0
|
|
||||||
more-itertools==7.2.0
|
more-itertools==7.2.0
|
||||||
portend==2.5
|
portend==2.5
|
||||||
pytz==2019.2
|
pytz==2019.2
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
{% extends "page.html" %}
|
||||||
|
{% block toolbar %}
|
||||||
|
<a class="nav-item is-active" href="/home">Home</a>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<header class="flex items-center py1 border-bottom">
|
||||||
|
<h1 class="m0">Sorted</h1>
|
||||||
|
</header>
|
||||||
|
<section class="mb3">
|
||||||
|
<h2>Success</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>torrent</th>
|
||||||
|
<th>result</th>
|
||||||
|
</tr>
|
||||||
|
{% for torrent, result, reason in success_torrents %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ torrent.name }}
|
||||||
|
<ul>
|
||||||
|
{% for f in torrent.files %}
|
||||||
|
<li>{{ f.path }} - {{ f.size }} B</li> <!-- TODO nice size formatting-->
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>{{ result }}{% if reason %} - {{ reason }}{% endif %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Failures</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>torrent</th>
|
||||||
|
<th>result</th>
|
||||||
|
</tr>
|
||||||
|
{% for torrent, result, reason in failed_torrents %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ torrent.name }}
|
||||||
|
<ul>
|
||||||
|
{% for f in torrent.files %}
|
||||||
|
<li>{{ f.path }} - {{ f.size }} B</li> <!-- TODO nice size formatting-->
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>{{ result }}{% if reason %} - {{ reason }}{% endif %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{% if not failed_torrents %}
|
||||||
|
<meta http-equiv="refresh" content="3;URL='/home'" />
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue