mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
more status on admin panel
This commit is contained in:
parent
081d2cc5d7
commit
88ce008e16
|
@ -1373,11 +1373,13 @@ class HttpCli(object):
|
||||||
for y in [self.rvol, self.wvol, self.avol]
|
for y in [self.rvol, self.wvol, self.avol]
|
||||||
]
|
]
|
||||||
|
|
||||||
vstate = {}
|
|
||||||
if self.avol and not self.args.no_rescan:
|
if self.avol and not self.args.no_rescan:
|
||||||
x = self.conn.hsrv.broker.put(True, "up2k.get_volstate")
|
x = self.conn.hsrv.broker.put(True, "up2k.get_state")
|
||||||
vstate = json.loads(x.get())
|
vs = json.loads(x.get())
|
||||||
vstate = {("/" + k).rstrip("/") + "/": v for k, v in vstate.items()}
|
vstate = {("/" + k).rstrip("/") + "/": v for k, v in vs["volstate"].items()}
|
||||||
|
else:
|
||||||
|
vstate = {}
|
||||||
|
vs = {"scanning": None, "hashq": None, "tagq": None}
|
||||||
|
|
||||||
html = self.j2(
|
html = self.j2(
|
||||||
"splash",
|
"splash",
|
||||||
|
@ -1386,6 +1388,9 @@ class HttpCli(object):
|
||||||
wvol=wvol,
|
wvol=wvol,
|
||||||
avol=avol,
|
avol=avol,
|
||||||
vstate=vstate,
|
vstate=vstate,
|
||||||
|
scanning=vs["scanning"],
|
||||||
|
hashq=vs["hashq"],
|
||||||
|
tagq=vs["tagq"],
|
||||||
url_suf=suf,
|
url_suf=suf,
|
||||||
)
|
)
|
||||||
self.reply(html.encode("utf-8"), headers=NO_STORE)
|
self.reply(html.encode("utf-8"), headers=NO_STORE)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -61,6 +61,8 @@ class Up2k(object):
|
||||||
self.mutex = threading.Lock()
|
self.mutex = threading.Lock()
|
||||||
self.hashq = Queue()
|
self.hashq = Queue()
|
||||||
self.tagq = Queue()
|
self.tagq = Queue()
|
||||||
|
self.n_hashq = 0
|
||||||
|
self.n_tagq = 0
|
||||||
self.volstate = {}
|
self.volstate = {}
|
||||||
self.registry = {}
|
self.registry = {}
|
||||||
self.entags = {}
|
self.entags = {}
|
||||||
|
@ -129,8 +131,14 @@ class Up2k(object):
|
||||||
def log(self, msg, c=0):
|
def log(self, msg, c=0):
|
||||||
self.log_func("up2k", msg + "\033[K", c)
|
self.log_func("up2k", msg + "\033[K", c)
|
||||||
|
|
||||||
def get_volstate(self):
|
def get_state(self):
|
||||||
return json.dumps(self.volstate, indent=4)
|
ret = {
|
||||||
|
"volstate": self.volstate,
|
||||||
|
"scanning": hasattr(self, "pp"),
|
||||||
|
"hashq": self.n_hashq,
|
||||||
|
"tagq": self.n_tagq,
|
||||||
|
}
|
||||||
|
return json.dumps(ret, indent=4)
|
||||||
|
|
||||||
def rescan(self, all_vols, scan_vols):
|
def rescan(self, all_vols, scan_vols):
|
||||||
if hasattr(self, "pp"):
|
if hasattr(self, "pp"):
|
||||||
|
@ -1233,6 +1241,7 @@ class Up2k(object):
|
||||||
|
|
||||||
if "e2t" in self.flags[ptop]:
|
if "e2t" in self.flags[ptop]:
|
||||||
self.tagq.put([ptop, wark, rd, fn])
|
self.tagq.put([ptop, wark, rd, fn])
|
||||||
|
self.n_tagq += 1
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -1410,7 +1419,13 @@ class Up2k(object):
|
||||||
prev[ptop] = etag
|
prev[ptop] = etag
|
||||||
|
|
||||||
def _tagger(self):
|
def _tagger(self):
|
||||||
|
with self.mutex:
|
||||||
|
self.n_tagq += 1
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
with self.mutex:
|
||||||
|
self.n_tagq -= 1
|
||||||
|
|
||||||
ptop, wark, rd, fn = self.tagq.get()
|
ptop, wark, rd, fn = self.tagq.get()
|
||||||
if "e2t" not in self.flags[ptop]:
|
if "e2t" not in self.flags[ptop]:
|
||||||
continue
|
continue
|
||||||
|
@ -1441,8 +1456,16 @@ class Up2k(object):
|
||||||
self.log("tagged {} ({}+{})".format(abspath, ntags1, len(tags) - ntags1))
|
self.log("tagged {} ({}+{})".format(abspath, ntags1, len(tags) - ntags1))
|
||||||
|
|
||||||
def _hasher(self):
|
def _hasher(self):
|
||||||
|
with self.mutex:
|
||||||
|
self.n_hashq += 1
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
with self.mutex:
|
||||||
|
self.n_hashq -= 1
|
||||||
|
# self.log("hashq {}".format(self.n_hashq))
|
||||||
|
|
||||||
ptop, rd, fn = self.hashq.get()
|
ptop, rd, fn = self.hashq.get()
|
||||||
|
# self.log("hashq {} pop {}/{}/{}".format(self.n_hashq, ptop, rd, fn))
|
||||||
if "e2d" not in self.flags[ptop]:
|
if "e2d" not in self.flags[ptop]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -1458,6 +1481,8 @@ class Up2k(object):
|
||||||
with self.mutex:
|
with self.mutex:
|
||||||
self.register_vpath(ptop, flags)
|
self.register_vpath(ptop, flags)
|
||||||
self.hashq.put([ptop, rd, fn])
|
self.hashq.put([ptop, rd, fn])
|
||||||
|
self.n_hashq += 1
|
||||||
|
# self.log("hashq {} push {}/{}/{}".format(self.n_hashq, ptop, rd, fn))
|
||||||
|
|
||||||
|
|
||||||
def up2k_chunksize(filesize):
|
def up2k_chunksize(filesize):
|
||||||
|
|
|
@ -26,10 +26,20 @@ a {
|
||||||
border-radius: .2em;
|
border-radius: .2em;
|
||||||
padding: .2em .8em;
|
padding: .2em .8em;
|
||||||
}
|
}
|
||||||
td, th {
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.vols td,
|
||||||
|
.vols th {
|
||||||
padding: .3em .6em;
|
padding: .3em .6em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
.num td {
|
||||||
|
padding: .1em .7em .1em 0;
|
||||||
|
}
|
||||||
|
.num td:first-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
.btns {
|
.btns {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,24 @@
|
||||||
|
|
||||||
{%- if avol %}
|
{%- if avol %}
|
||||||
<h1>admin panel:</h1>
|
<h1>admin panel:</h1>
|
||||||
<table>
|
<table><tr><td> <!-- hehehe -->
|
||||||
<thead><tr><th>vol</th><th>action</th><th>status</th></tr></thead>
|
<table class="num">
|
||||||
<tbody>
|
<tr><td>scanning</td><td>{{ scanning }}</td></tr>
|
||||||
{% for mp in avol %}
|
<tr><td>hash-q</td><td>{{ hashq }}</td></tr>
|
||||||
{%- if mp in vstate and vstate[mp] %}
|
<tr><td>tag-q</td><td>{{ tagq }}</td></tr>
|
||||||
<tr><td><a href="{{ mp }}{{ url_suf }}">{{ mp }}</a></td><td><a href="{{ mp }}?scan">rescan</a></td><td>{{ vstate[mp] }}</td></tr>
|
</table>
|
||||||
{%- endif %}
|
</td><td>
|
||||||
{% endfor %}
|
<table class="vols">
|
||||||
</tbody>
|
<thead><tr><th>vol</th><th>action</th><th>status</th></tr></thead>
|
||||||
</table>
|
<tbody>
|
||||||
|
{% for mp in avol %}
|
||||||
|
{%- if mp in vstate and vstate[mp] %}
|
||||||
|
<tr><td><a href="{{ mp }}{{ url_suf }}">{{ mp }}</a></td><td><a href="{{ mp }}?scan">rescan</a></td><td>{{ vstate[mp] }}</td></tr>
|
||||||
|
{%- endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td></tr></table>
|
||||||
<div class="btns">
|
<div class="btns">
|
||||||
<a href="{{ avol[0] }}?stack">dump stack</a>
|
<a href="{{ avol[0] }}?stack">dump stack</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,10 +3,13 @@ set -ex
|
||||||
|
|
||||||
pids=()
|
pids=()
|
||||||
for py in python{2,3}; do
|
for py in python{2,3}; do
|
||||||
$py -m unittest discover -s tests >/dev/null &
|
nice $py -m unittest discover -s tests >/dev/null &
|
||||||
pids+=($!)
|
pids+=($!)
|
||||||
done
|
done
|
||||||
|
|
||||||
|
python3 scripts/test/smoketest.py &
|
||||||
|
pids+=($!)
|
||||||
|
|
||||||
for pid in ${pids[@]}; do
|
for pid in ${pids[@]}; do
|
||||||
wait $pid
|
wait $pid
|
||||||
done
|
done
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import signal
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
|
import signal
|
||||||
import tempfile
|
import tempfile
|
||||||
import requests
|
import requests
|
||||||
import threading
|
import threading
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
|
|
||||||
|
|
||||||
|
CPP = []
|
||||||
|
|
||||||
|
|
||||||
class Cpp(object):
|
class Cpp(object):
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
args = [sys.executable, "-m", "copyparty"] + args
|
||||||
|
print(" ".join([shlex.quote(x) for x in args]))
|
||||||
|
|
||||||
self.ls_pre = set(list(os.listdir()))
|
self.ls_pre = set(list(os.listdir()))
|
||||||
self.p = sp.Popen([sys.executable, "-m", "copyparty"] + args)
|
self.p = sp.Popen(args)
|
||||||
# , stdout=sp.PIPE, stderr=sp.PIPE)
|
# , stdout=sp.PIPE, stderr=sp.PIPE)
|
||||||
|
|
||||||
self.t = threading.Thread(target=self._run)
|
self.t = threading.Thread(target=self._run)
|
||||||
|
@ -23,10 +30,11 @@ class Cpp(object):
|
||||||
self.so, self.se = self.p.communicate()
|
self.so, self.se = self.p.communicate()
|
||||||
|
|
||||||
def stop(self, wait):
|
def stop(self, wait):
|
||||||
# self.p.kill()
|
|
||||||
os.kill(self.p.pid, signal.SIGINT)
|
|
||||||
if wait:
|
if wait:
|
||||||
self.t.join()
|
os.kill(self.p.pid, signal.SIGINT)
|
||||||
|
self.t.join(timeout=2)
|
||||||
|
else:
|
||||||
|
self.p.kill() # macos py3.8
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
t = os.listdir()
|
t = os.listdir()
|
||||||
|
@ -34,6 +42,22 @@ class Cpp(object):
|
||||||
if f not in self.ls_pre and f.startswith("up."):
|
if f not in self.ls_pre and f.startswith("up."):
|
||||||
os.unlink(f)
|
os.unlink(f)
|
||||||
|
|
||||||
|
def await_idle(self, ub, timeout):
|
||||||
|
req = ["scanning</td><td>False", "hash-q</td><td>0", "tag-q</td><td>0"]
|
||||||
|
u = ub + "?h"
|
||||||
|
for _ in range(timeout * 10):
|
||||||
|
try:
|
||||||
|
time.sleep(0.1)
|
||||||
|
r = requests.get(u, timeout=0.1)
|
||||||
|
for x in req:
|
||||||
|
if x not in r.text:
|
||||||
|
print("ST: miss " + x)
|
||||||
|
raise Exception()
|
||||||
|
print("ST: idle")
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def tc1():
|
def tc1():
|
||||||
ub = "http://127.0.0.1:4321/"
|
ub = "http://127.0.0.1:4321/"
|
||||||
|
@ -61,10 +85,10 @@ def tc1():
|
||||||
ovid = f.read()
|
ovid = f.read()
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
"-p",
|
"-p4321",
|
||||||
"4321",
|
|
||||||
"-e2dsa",
|
"-e2dsa",
|
||||||
"-e2tsr",
|
"-e2tsr",
|
||||||
|
"--no-mutagen",
|
||||||
"--th-ff-jpg",
|
"--th-ff-jpg",
|
||||||
"--hist",
|
"--hist",
|
||||||
os.path.join(td, "dbm"),
|
os.path.join(td, "dbm"),
|
||||||
|
@ -89,30 +113,24 @@ def tc1():
|
||||||
|
|
||||||
hp = None
|
hp = None
|
||||||
if pd.endswith("st/a"):
|
if pd.endswith("st/a"):
|
||||||
hp = os.path.join(td, "db1")
|
hp = hpaths[ud] = os.path.join(td, "db1")
|
||||||
elif pd[:-1].endswith("a/j/"):
|
elif pd[:-1].endswith("a/j/"):
|
||||||
hp = os.path.join(td, "dbm")
|
hpaths[ud] = os.path.join(td, "dbm")
|
||||||
|
hp = None
|
||||||
else:
|
else:
|
||||||
hp = "-"
|
hp = "-"
|
||||||
|
hpaths[ud] = os.path.join(pd, ".hist")
|
||||||
|
|
||||||
hpaths[ud] = os.path.join(pd, ".hist") if hp == "-" else hp
|
arg = "{}:{}:{}".format(pd, ud, p, hp)
|
||||||
args += ["-v", "{}:{}:{}:chist={}".format(pd, ud, p, hp)]
|
if hp:
|
||||||
|
arg += ":chist=" + hp
|
||||||
|
|
||||||
|
args += ["-v", arg]
|
||||||
|
|
||||||
# print(repr(args))
|
|
||||||
# return
|
# return
|
||||||
cpp = Cpp(args)
|
cpp = Cpp(args)
|
||||||
|
CPP.append(cpp)
|
||||||
up = False
|
cpp.await_idle(ub, 3)
|
||||||
for n in range(30):
|
|
||||||
try:
|
|
||||||
time.sleep(0.1)
|
|
||||||
requests.get(ub + "?h", timeout=0.1)
|
|
||||||
up = True
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert up
|
|
||||||
|
|
||||||
for d in udirs:
|
for d in udirs:
|
||||||
vid = ovid + "\n{}".format(d).encode("utf-8")
|
vid = ovid + "\n{}".format(d).encode("utf-8")
|
||||||
|
@ -147,6 +165,7 @@ def tc1():
|
||||||
raise Exception("thumb {} with perm {} at {}".format(ok, p, u))
|
raise Exception("thumb {} with perm {} at {}".format(ok, p, u))
|
||||||
|
|
||||||
# check tags
|
# check tags
|
||||||
|
cpp.await_idle(ub, 5)
|
||||||
for d, p in zip(udirs, perms):
|
for d, p in zip(udirs, perms):
|
||||||
u = "{}{}?ls".format(ub, d)
|
u = "{}{}?ls".format(ub, d)
|
||||||
r = requests.get(u)
|
r = requests.get(u)
|
||||||
|
@ -163,7 +182,7 @@ def tc1():
|
||||||
raise Exception("ls {} with perm {} at {}".format(ok, p, u))
|
raise Exception("ls {} with perm {} at {}".format(ok, p, u))
|
||||||
|
|
||||||
if (tag and p != "a") or (not tag and p == "a"):
|
if (tag and p != "a") or (not tag and p == "a"):
|
||||||
raise Exception("tag {} with perm {} at {}".format(ok, p, u))
|
raise Exception("tag {} with perm {} at {}".format(tag, p, u))
|
||||||
|
|
||||||
if tag is not None and tag != "48x32":
|
if tag is not None and tag != "48x32":
|
||||||
raise Exception("tag [{}] at {}".format(tag, u))
|
raise Exception("tag [{}] at {}".format(tag, u))
|
||||||
|
@ -171,8 +190,18 @@ def tc1():
|
||||||
cpp.stop(True)
|
cpp.stop(True)
|
||||||
|
|
||||||
|
|
||||||
|
def run(tc):
|
||||||
|
try:
|
||||||
|
tc()
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
CPP[0].stop(False)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
tc1()
|
run(tc1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue