mirror of
https://github.com/9001/copyparty.git
synced 2025-10-24 00:24:04 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab09927e7b | ||
|
|
779437db67 | ||
|
|
28cbdb652e | ||
|
|
2b2415a7d8 | ||
|
|
746a8208aa | ||
|
|
a2a041a98a | ||
|
|
10b436e449 | ||
|
|
4d62b34786 | ||
|
|
0546210687 | ||
|
|
f8c11faada | ||
|
|
16d6e9be1f | ||
|
|
aff8185f2e | ||
|
|
217d15fe81 | ||
|
|
171e93c201 | ||
|
|
acc1d2e9e3 | ||
|
|
49c2f37154 | ||
|
|
69e54497aa | ||
|
|
9aa1885669 | ||
|
|
4418508513 |
10
.vscode/launch.py
vendored
10
.vscode/launch.py
vendored
@@ -5,6 +5,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
|
||||
@@ -16,9 +17,16 @@ with open(".vscode/launch.json", "r") as f:
|
||||
|
||||
oj = jstyleson.loads(tj)
|
||||
argv = oj["configurations"][0]["args"]
|
||||
|
||||
try:
|
||||
sargv = " ".join([shlex.quote(x) for x in argv])
|
||||
print(sys.executable + " -m copyparty " + sargv + "\n")
|
||||
except:
|
||||
pass
|
||||
|
||||
argv = [os.path.expanduser(x) if x.startswith("~") else x for x in argv]
|
||||
try:
|
||||
copyparty(argv)
|
||||
copyparty(["a"] + argv)
|
||||
except SystemExit as ex:
|
||||
if ex.code:
|
||||
raise
|
||||
|
||||
@@ -111,6 +111,8 @@ the browser has the following hotkeys
|
||||
* `I/K` prev/next folder
|
||||
* `P` parent folder
|
||||
|
||||
you can link a particular timestamp in an audio file by adding it to the URL, such as `&20` / `&20s` / `&1m20` / `&1:20` after the `.../#af-c8960dab`
|
||||
|
||||
|
||||
## zip downloads
|
||||
|
||||
@@ -339,7 +341,6 @@ in the `scripts` folder:
|
||||
|
||||
roughly sorted by priority
|
||||
|
||||
* audio link with timestamp
|
||||
* separate sqlite table per tag
|
||||
* audio fingerprinting
|
||||
* readme.md as epilogue
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# coding: utf-8
|
||||
|
||||
VERSION = (0, 10, 8)
|
||||
VERSION = (0, 10, 12)
|
||||
CODENAME = "zip it"
|
||||
BUILD_DT = (2021, 4, 11)
|
||||
BUILD_DT = (2021, 4, 19)
|
||||
|
||||
S_VERSION = ".".join(map(str, VERSION))
|
||||
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
|
||||
|
||||
@@ -111,7 +111,27 @@ class VFS(object):
|
||||
if rem:
|
||||
rp += "/" + rem
|
||||
|
||||
return fsdec(os.path.realpath(fsenc(rp)))
|
||||
try:
|
||||
return fsdec(os.path.realpath(fsenc(rp)))
|
||||
except:
|
||||
if not WINDOWS:
|
||||
raise
|
||||
|
||||
# cpython bug introduced in 3.8, still exists in 3.9.1;
|
||||
# some win7sp1 and win10:20H2 boxes cannot realpath a
|
||||
# networked drive letter such as b"n:" or b"n:\\"
|
||||
#
|
||||
# requirements to trigger:
|
||||
# * bytestring (not unicode str)
|
||||
# * just the drive letter (subfolders are ok)
|
||||
# * networked drive (regular disks and vmhgfs are ok)
|
||||
# * on an enterprise network (idk, cannot repro with samba)
|
||||
#
|
||||
# hits the following exceptions in succession:
|
||||
# * access denied at L601: "path = _getfinalpathname(path)"
|
||||
# * "cant concat str to bytes" at L621: "return path + tail"
|
||||
#
|
||||
return os.path.realpath(rp)
|
||||
|
||||
def ls(self, rem, uname, scandir, lstat=False):
|
||||
"""return user-readable [fsdir,real,virt] items at vpath"""
|
||||
|
||||
@@ -101,17 +101,18 @@ class Up2k(object):
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
|
||||
thr = threading.Thread(target=self._tagger)
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
|
||||
thr = threading.Thread(target=self._hasher)
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
|
||||
thr = threading.Thread(target=self._run_all_mtp)
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
if self.mtag:
|
||||
thr = threading.Thread(target=self._tagger)
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
|
||||
thr = threading.Thread(target=self._run_all_mtp)
|
||||
thr.daemon = True
|
||||
thr.start()
|
||||
|
||||
def log(self, msg, c=0):
|
||||
self.log_func("up2k", msg + "\033[K", c)
|
||||
@@ -1068,6 +1069,8 @@ class Up2k(object):
|
||||
with self.mutex:
|
||||
job = self.registry[ptop].get(wark, None)
|
||||
if not job:
|
||||
known = " ".join([x for x in self.registry[ptop].keys()])
|
||||
self.log("unknown wark [{}], known: {}".format(wark, known))
|
||||
raise Pebkac(400, "unknown wark")
|
||||
|
||||
if chash not in job["need"]:
|
||||
|
||||
@@ -284,7 +284,7 @@ a, #files tbody div a:last-child {
|
||||
line-height: 1em;
|
||||
}
|
||||
#wtoggle.sel {
|
||||
width: 6em;
|
||||
width: 6.4em;
|
||||
}
|
||||
#wtoggle.sel #wzip {
|
||||
display: inline-block;
|
||||
@@ -685,3 +685,173 @@ input[type="checkbox"]:checked+label {
|
||||
font-family: monospace, monospace;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
html.light {
|
||||
color: #333;
|
||||
background: #eee;
|
||||
text-shadow: none;
|
||||
}
|
||||
html.light #ops,
|
||||
html.light .opbox,
|
||||
html.light #srch_form {
|
||||
background: #f7f7f7;
|
||||
box-shadow: 0 0 .3em #ddd;
|
||||
border-color: #f7f7f7;
|
||||
}
|
||||
html.light #ops a.act {
|
||||
box-shadow: 0 .2em .2em #ccc;
|
||||
background: #f7f7f7;
|
||||
border-color: #07a;
|
||||
padding-top: .4em;
|
||||
}
|
||||
html.light #op_cfg h3 {
|
||||
border-color: #ccc;
|
||||
}
|
||||
html.light .tglbtn,
|
||||
html.light #tree > a + a {
|
||||
color: #666;
|
||||
background: #ddd;
|
||||
box-shadow: none;
|
||||
}
|
||||
html.light .tglbtn:hover,
|
||||
html.light #tree > a + a:hover {
|
||||
background: #caf;
|
||||
}
|
||||
html.light .tglbtn.on,
|
||||
html.light #tree > a + a.on {
|
||||
background: #4a0;
|
||||
color: #fff;
|
||||
}
|
||||
html.light #srv_info {
|
||||
color: #c83;
|
||||
text-shadow: 1px 1px 0 #fff;
|
||||
}
|
||||
html.light #srv_info span {
|
||||
color: #000;
|
||||
}
|
||||
html.light #treeul a+a {
|
||||
background: inherit;
|
||||
color: #06a;
|
||||
}
|
||||
html.light #treeul a.hl {
|
||||
background: #07a;
|
||||
color: #fff;
|
||||
}
|
||||
html.light #tree li {
|
||||
border-color: #ddd #fff #f7f7f7 #fff;
|
||||
}
|
||||
html.light #tree ul {
|
||||
border-color: #ccc;
|
||||
}
|
||||
html.light a,
|
||||
html.light #ops a,
|
||||
html.light #files tbody div a:last-child {
|
||||
color: #06a;
|
||||
}
|
||||
html.light #files tbody {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
html.light #files {
|
||||
box-shadow: 0 0 .3em #ccc;
|
||||
}
|
||||
html.light #files thead th {
|
||||
background: #eee;
|
||||
}
|
||||
html.light #files tr+tr td {
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
html.light #files td {
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
}
|
||||
html.light #files tbody tr:last-child td {
|
||||
border-bottom: .2em solid #ccc;
|
||||
}
|
||||
html.light #files td:nth-child(2n) {
|
||||
color: #d38;
|
||||
}
|
||||
html.light #files tr:hover td {
|
||||
background: #fff;
|
||||
}
|
||||
html.light #files tbody a.play {
|
||||
color: #c0f;
|
||||
}
|
||||
html.light tr.play td {
|
||||
background: #fc5;
|
||||
}
|
||||
html.light tr.play a {
|
||||
color: #406;
|
||||
}
|
||||
html.light #files > thead > tr > th.min span {
|
||||
background: linear-gradient(90deg, rgba(68,68,68,0), rgba(68,68,68,0.2) 70%, rgba(68,68,68,0.5));
|
||||
}
|
||||
html.light #blocked {
|
||||
background: #eee;
|
||||
}
|
||||
html.light #blk_play a,
|
||||
html.light #blk_abrt a {
|
||||
background: #fff;
|
||||
box-shadow: 0 .2em .4em #ddd;
|
||||
}
|
||||
html.light #widget a {
|
||||
color: #fc5;
|
||||
}
|
||||
html.light #files tr.sel:hover td {
|
||||
background: #c37;
|
||||
}
|
||||
html.light #files tr.sel td {
|
||||
color: #fff;
|
||||
}
|
||||
html.light #files tr.sel a {
|
||||
color: #fff;
|
||||
}
|
||||
html.light input[type="checkbox"] + label {
|
||||
color: #333;
|
||||
}
|
||||
html.light .opview input[type="text"] {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
box-shadow: 0 0 2px #888;
|
||||
border-color: #38d;
|
||||
}
|
||||
html.light #ops:hover #opdesc {
|
||||
background: #fff;
|
||||
box-shadow: 0 .3em 1em #ccc;
|
||||
}
|
||||
html.light #opdesc code {
|
||||
background: #060;
|
||||
color: #fff;
|
||||
}
|
||||
html.light #u2tab a>span,
|
||||
html.light #files td div span {
|
||||
color: #000;
|
||||
}
|
||||
html.light #path {
|
||||
background: #f7f7f7;
|
||||
text-shadow: none;
|
||||
box-shadow: 0 0 .3em #bbb;
|
||||
}
|
||||
html.light #path a {
|
||||
color: #333;
|
||||
}
|
||||
html.light #path a:not(:last-child)::after {
|
||||
border-color: #ccc;
|
||||
background: none;
|
||||
border-width: .1em .1em 0 0;
|
||||
margin: -.2em .3em -.2em -.3em;
|
||||
}
|
||||
html.light #path a:hover {
|
||||
background: none;
|
||||
color: #60a;
|
||||
}
|
||||
html.light #files tbody div a {
|
||||
color: #d38;
|
||||
}
|
||||
html.light #files a:hover,
|
||||
html.light #files tr.sel a:hover {
|
||||
color: #000;
|
||||
background: #fff;
|
||||
}
|
||||
@@ -13,8 +13,8 @@
|
||||
<body>
|
||||
<div id="ops">
|
||||
<a href="#" data-dest="" data-desc="close submenu">---</a>
|
||||
<a href="#" data-perm="read" data-dest="search" data-desc="search for files by attributes, path/name, music tags, or any combination of those.<br /><br /><code>foo bar</code> = must contain both foo and bar,<br /><code>foo -bar</code> = must contain foo but not bar,<br /><code>^yana .opus$</code> = must start with yana and have the opus extension">🔎</a>
|
||||
{%- if have_up2k_idx %}
|
||||
<a href="#" data-perm="read" data-dest="search" data-desc="search for files by attributes, path/name, music tags, or any combination of those.<br /><br /><code>foo bar</code> = must contain both foo and bar,<br /><code>foo -bar</code> = must contain foo but not bar,<br /><code>^yana .opus$</code> = must start with yana and have the opus extension">🔎</a>
|
||||
<a href="#" data-dest="up2k" data-desc="up2k: upload files (if you have write-access) or toggle into the search-mode and drag files onto the search button to see if they exist somewhere on the server">🚀</a>
|
||||
{%- else %}
|
||||
<a href="#" data-perm="write" data-dest="up2k" data-desc="up2k: upload files with resume support (close your browser and drop the same files in later)">🚀</a>
|
||||
@@ -39,14 +39,17 @@
|
||||
{%- include 'upload.html' %}
|
||||
|
||||
<div id="op_cfg" class="opview opbox">
|
||||
<h3>key notation</h3>
|
||||
<div id="key_notation"></div>
|
||||
<h3>switches</h3>
|
||||
<div>
|
||||
<a id="tooltips" class="tglbtn" href="#">tooltips</a>
|
||||
<a id="lightmode" class="tglbtn" href="#">lightmode</a>
|
||||
</div>
|
||||
{%- if have_zip %}
|
||||
<h3>folder download</h3>
|
||||
<div id="arc_fmt"></div>
|
||||
{%- endif %}
|
||||
<h3>tooltips</h3>
|
||||
<div><a id="tooltips" class="tglbtn" href="#">enable</a></div>
|
||||
<h3>key notation</h3>
|
||||
<div id="key_notation"></div>
|
||||
</div>
|
||||
|
||||
<h1 id="path">
|
||||
@@ -117,8 +120,8 @@
|
||||
<a href="#" id="selall">sel.<br />all</a>
|
||||
<a href="#" id="selinv">sel.<br />inv.</a>
|
||||
<a href="#" id="selzip">zip</a>
|
||||
</span>
|
||||
<a href="#" id="wtico">♫</a>
|
||||
</span><a
|
||||
href="#" id="wtico">♫</a>
|
||||
</div>
|
||||
<div id="widgeti">
|
||||
<div id="pctl"><a href="#" id="bprev">⏮</a><a href="#" id="bplay">▶</a><a href="#" id="bnext">⏭</a></div>
|
||||
|
||||
@@ -314,8 +314,8 @@ function seek_au_sec(seek) {
|
||||
|
||||
mp.au.currentTime = seek;
|
||||
|
||||
// ogv.js breaks on .play() during playback
|
||||
if (mp.au === mp.au_native)
|
||||
// hack: ogv.js breaks on .play() during playback
|
||||
mp.au.play();
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ catch (ex) { }
|
||||
|
||||
|
||||
// plays the tid'th audio file on the page
|
||||
function play(tid, call_depth) {
|
||||
function play(tid, seek, call_depth) {
|
||||
if (mp.order.length == 0)
|
||||
return alert('no audio found wait what');
|
||||
|
||||
@@ -449,7 +449,7 @@ function play(tid, call_depth) {
|
||||
}
|
||||
|
||||
// ogv.js breaks on .play() unless directly user-triggered
|
||||
var hack_attempt_play = true;
|
||||
var attempt_play = true;
|
||||
|
||||
var url = mp.tracks[tid];
|
||||
if (need_ogv && /\.(ogg|opus)$/i.test(url)) {
|
||||
@@ -458,7 +458,7 @@ function play(tid, call_depth) {
|
||||
}
|
||||
else if (window['OGVPlayer']) {
|
||||
mp.au = mp.au_ogvjs = new OGVPlayer();
|
||||
hack_attempt_play = false;
|
||||
attempt_play = false;
|
||||
mp.au.addEventListener('error', evau_error, true);
|
||||
mp.au.addEventListener('progress', pbar.drawpos, false);
|
||||
widget.open();
|
||||
@@ -470,7 +470,7 @@ function play(tid, call_depth) {
|
||||
show_modal('<h1>loading ogv.js</h1><h2>thanks apple</h2>');
|
||||
|
||||
import_js('/.cpr/deps/ogv.js', function () {
|
||||
play(tid, 1);
|
||||
play(tid, seek, 1);
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -498,21 +498,26 @@ function play(tid, call_depth) {
|
||||
ebi(oid).parentElement.parentElement.className += ' play';
|
||||
|
||||
try {
|
||||
if (hack_attempt_play)
|
||||
if (attempt_play)
|
||||
mp.au.play();
|
||||
|
||||
if (mp.au.paused)
|
||||
autoplay_blocked();
|
||||
autoplay_blocked(seek);
|
||||
else if (seek) {
|
||||
seek_au_sec(seek);
|
||||
}
|
||||
|
||||
var o = ebi(oid);
|
||||
o.setAttribute('id', 'thx_js');
|
||||
if (window.history && history.replaceState) {
|
||||
hist_replace(document.location.pathname + '#' + oid);
|
||||
if (!seek) {
|
||||
var o = ebi(oid);
|
||||
o.setAttribute('id', 'thx_js');
|
||||
if (window.history && history.replaceState) {
|
||||
hist_replace(document.location.pathname + '#' + oid);
|
||||
}
|
||||
else {
|
||||
document.location.hash = oid;
|
||||
}
|
||||
o.setAttribute('id', oid);
|
||||
}
|
||||
else {
|
||||
document.location.hash = oid;
|
||||
}
|
||||
o.setAttribute('id', oid);
|
||||
|
||||
pbar.drawbuf();
|
||||
return true;
|
||||
@@ -576,7 +581,7 @@ function unblocked() {
|
||||
|
||||
|
||||
// show ui to manually start playback of a linked song
|
||||
function autoplay_blocked() {
|
||||
function autoplay_blocked(seek) {
|
||||
show_modal(
|
||||
'<div id="blk_play"><a href="#" id="blk_go"></a></div>' +
|
||||
'<div id="blk_abrt"><a href="#" id="blk_na">Cancel<br />(show file list)</a></div>');
|
||||
@@ -592,6 +597,8 @@ function autoplay_blocked() {
|
||||
if (e) e.preventDefault();
|
||||
unblocked();
|
||||
mp.au.play();
|
||||
if (seek)
|
||||
seek_au_sec(seek);
|
||||
};
|
||||
na.onclick = unblocked;
|
||||
}
|
||||
@@ -600,8 +607,20 @@ function autoplay_blocked() {
|
||||
// autoplay linked track
|
||||
(function () {
|
||||
var v = location.hash;
|
||||
if (v && v.length == 12 && v.indexOf('#af-') === 0)
|
||||
play(v.slice(2));
|
||||
if (v && v.indexOf('#af-') === 0) {
|
||||
var id = v.slice(2).split('&');
|
||||
if (id[0].length != 10)
|
||||
return;
|
||||
|
||||
if (id.length == 1)
|
||||
return play(id[0]);
|
||||
|
||||
var m = /^[Tt=0]*([0-9]+[Mm:])?0*([0-9]+)[Ss]?$/.exec(id[1]);
|
||||
if (!m)
|
||||
return play(id[0]);
|
||||
|
||||
return play(id[0], parseInt(m[1] || 0) * 60 + parseInt(m[2] || 0));
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
@@ -1549,8 +1568,11 @@ function addcrc() {
|
||||
ebi('unsearch') ? 'div>a:last-child' : 'a'));
|
||||
|
||||
for (var a = 0, aa = links.length; a < aa; a++)
|
||||
if (!links[a].getAttribute('id'))
|
||||
links[a].setAttribute('id', 'f-' + crc32(links[a].textContent || links[a].innerText));
|
||||
if (!links[a].getAttribute('id')) {
|
||||
var crc = crc32(links[a].textContent || links[a].innerText);
|
||||
crc = ('00000000' + crc).slice(-8);
|
||||
links[a].setAttribute('id', 'f-' + crc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1577,6 +1599,24 @@ function addcrc() {
|
||||
})();
|
||||
|
||||
|
||||
(function () {
|
||||
var light = bcfg_get('lightmode', false);
|
||||
|
||||
function freshen() {
|
||||
document.documentElement.setAttribute("class", light ? "light" : "");
|
||||
}
|
||||
|
||||
ebi('lightmode').onclick = function (e) {
|
||||
ev(e);
|
||||
light = !light;
|
||||
bcfg_set('lightmode', light);
|
||||
freshen();
|
||||
};
|
||||
|
||||
freshen();
|
||||
})();
|
||||
|
||||
|
||||
var arcfmt = (function () {
|
||||
if (!ebi('arc_fmt'))
|
||||
return { "render": function () { } };
|
||||
|
||||
@@ -138,10 +138,10 @@ var md_opt = {
|
||||
document.documentElement.setAttribute("class", dark ? "dark" : "");
|
||||
btn.innerHTML = "go " + (dark ? "light" : "dark");
|
||||
if (window.localStorage)
|
||||
localStorage.setItem('darkmode', dark ? 1 : 0);
|
||||
localStorage.setItem('lightmode', dark ? 0 : 1);
|
||||
};
|
||||
btn.onclick = toggle;
|
||||
if (window.localStorage && localStorage.getItem('darkmode') == 1)
|
||||
if (window.localStorage && localStorage.getItem('lightmode') != 1)
|
||||
toggle();
|
||||
})();
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ var md_opt = {
|
||||
|
||||
var lightswitch = (function () {
|
||||
var fun = function () {
|
||||
var dark = !!!document.documentElement.getAttribute("class");
|
||||
var dark = !document.documentElement.getAttribute("class");
|
||||
document.documentElement.setAttribute("class", dark ? "dark" : "");
|
||||
if (window.localStorage)
|
||||
localStorage.setItem('darkmode', dark ? 1 : 0);
|
||||
localStorage.setItem('lightmode', dark ? 0 : 1);
|
||||
};
|
||||
if (window.localStorage && localStorage.getItem('darkmode') == 1)
|
||||
if (window.localStorage && localStorage.getItem('lightmode') != 1)
|
||||
fun();
|
||||
|
||||
return fun;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</div>
|
||||
<script>
|
||||
|
||||
if (window.localStorage && localStorage.getItem('darkmode') == 1)
|
||||
if (window.localStorage && localStorage.getItem('lightmode') != 1)
|
||||
document.documentElement.setAttribute("class", "dark");
|
||||
|
||||
</script>
|
||||
|
||||
@@ -132,6 +132,283 @@ function up2k_flagbus() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
function U2pvis(act, btns) {
|
||||
this.act = act;
|
||||
this.ctr = { "ok": 0, "ng": 0, "bz": 0, "q": 0 };
|
||||
this.tab = [];
|
||||
this.head = 0;
|
||||
this.tail = -1;
|
||||
this.wsz = 3;
|
||||
|
||||
this.addfile = function (entry, sz) {
|
||||
this.tab.push({
|
||||
"hn": entry[0],
|
||||
"ht": entry[1],
|
||||
"hp": entry[2],
|
||||
"in": 'q',
|
||||
"nh": 0, //hashed
|
||||
"nd": 0, //done
|
||||
"cb": [], // bytes done in chunk
|
||||
"bt": sz, // bytes total
|
||||
"bd": 0, // bytes done
|
||||
"bd0": 0 // upload start
|
||||
});
|
||||
this.ctr["q"]++;
|
||||
this.drawcard("q");
|
||||
if (this.act == "q") {
|
||||
this.addrow(this.tab.length - 1);
|
||||
}
|
||||
if (this.act == "bz") {
|
||||
this.bzw();
|
||||
}
|
||||
};
|
||||
|
||||
this.is_act = function (card) {
|
||||
if (this.act == "done")
|
||||
return card == "ok" || card == "ng";
|
||||
|
||||
return this.act == card;
|
||||
}
|
||||
|
||||
this.seth = function (nfile, field, html) {
|
||||
var fo = this.tab[nfile];
|
||||
field = ['hn', 'ht', 'hp'][field];
|
||||
if (fo[field] === html)
|
||||
return;
|
||||
|
||||
fo[field] = html;
|
||||
if (!this.is_act(fo.in))
|
||||
return;
|
||||
|
||||
var obj = ebi('f{0}{1}'.format(nfile, field.slice(1)));
|
||||
obj.innerHTML = html;
|
||||
if (field == 'hp') {
|
||||
obj.style.color = '';
|
||||
obj.style.background = '';
|
||||
}
|
||||
};
|
||||
|
||||
this.setab = function (nfile, nblocks) {
|
||||
var t = [];
|
||||
for (var a = 0; a < nblocks; a++)
|
||||
t.push(0);
|
||||
|
||||
this.tab[nfile].cb = t;
|
||||
};
|
||||
|
||||
this.setat = function (nfile, blocktab) {
|
||||
this.tab[nfile].cb = blocktab;
|
||||
|
||||
var bd = 0;
|
||||
for (var a = 0; a < blocktab.length; a++)
|
||||
bd += blocktab[a];
|
||||
|
||||
this.tab[nfile].bd = bd;
|
||||
this.tab[nfile].bd0 = bd;
|
||||
};
|
||||
|
||||
this.perc = function (bd, bd0, sz, t0) {
|
||||
var td = new Date().getTime() - t0,
|
||||
p = bd * 100.0 / sz,
|
||||
nb = bd - bd0,
|
||||
spd = nb / (td / 1000),
|
||||
eta = (sz - bd) / spd;
|
||||
|
||||
return [p, s2ms(eta), spd / (1024 * 1024)];
|
||||
};
|
||||
|
||||
this.hashed = function (fobj) {
|
||||
var fo = this.tab[fobj.n];
|
||||
var nb = fo.bt * (++fo.nh / fo.cb.length);
|
||||
var p = this.perc(nb, 0, fobj.size, fobj.t1);
|
||||
fo.hp = '{0}%, {1}, {2} MB/s'.format(
|
||||
p[0].toFixed(2), p[1], p[2].toFixed(2)
|
||||
);
|
||||
if (!this.is_act(fo.in))
|
||||
return;
|
||||
|
||||
var obj = ebi('f{0}p'.format(fobj.n));
|
||||
obj.innerHTML = fo.hp;
|
||||
obj.style.color = '#fff';
|
||||
var o1 = p[0] - 2, o2 = p[0] - 0.1, o3 = p[0];
|
||||
obj.style.background = 'linear-gradient(90deg, #025, #06a ' + o1 + '%, #09d ' + o2 + '%, #333 ' + o3 + '%, #333 99%, #777)';
|
||||
};
|
||||
|
||||
this.prog = function (fobj, nchunk, cbd) {
|
||||
var fo = this.tab[fobj.n];
|
||||
var delta = cbd - fo.cb[nchunk];
|
||||
fo.cb[nchunk] = cbd;
|
||||
fo.bd += delta;
|
||||
|
||||
var p = this.perc(fo.bd, fo.bd0, fo.bt, fobj.t3);
|
||||
fo.hp = '{0}%, {1}, {2} MB/s'.format(
|
||||
p[0].toFixed(2), p[1], p[2].toFixed(2)
|
||||
);
|
||||
|
||||
if (!this.is_act(fo.in))
|
||||
return;
|
||||
|
||||
var obj = ebi('f{0}p'.format(fobj.n));
|
||||
obj.innerHTML = fo.hp;
|
||||
obj.style.color = '#fff';
|
||||
var o1 = p[0] - 2, o2 = p[0] - 0.1, o3 = p[0];
|
||||
obj.style.background = 'linear-gradient(90deg, #050, #270 ' + o1 + '%, #4b0 ' + o2 + '%, #333 ' + o3 + '%, #333 99%, #777)';
|
||||
};
|
||||
|
||||
this.move = function (nfile, newcat) {
|
||||
var fo = this.tab[nfile],
|
||||
oldcat = fo.in,
|
||||
bz_act = this.act == "bz";
|
||||
|
||||
if (oldcat == newcat) {
|
||||
throw 42;
|
||||
}
|
||||
|
||||
fo.in = newcat;
|
||||
this.ctr[oldcat]--;
|
||||
this.ctr[newcat]++;
|
||||
this.drawcard(oldcat);
|
||||
this.drawcard(newcat);
|
||||
if (this.is_act(newcat)) {
|
||||
this.tail++;
|
||||
if (!ebi('f' + nfile))
|
||||
this.addrow(nfile);
|
||||
}
|
||||
else if (this.is_act(oldcat)) {
|
||||
this.head++;
|
||||
if (!bz_act) {
|
||||
var tr = ebi("f" + nfile);
|
||||
tr.parentNode.removeChild(tr);
|
||||
}
|
||||
}
|
||||
if (bz_act) {
|
||||
this.bzw();
|
||||
}
|
||||
};
|
||||
|
||||
this.bzw_log = function (first, last) {
|
||||
console.log("first %d head %d tail %d last %d", first, this.head, this.tail, last);
|
||||
var trs = document.querySelectorAll('#u2tab>tbody>tr'), msg = [];
|
||||
for (var a = 0; a < trs.length; a++)
|
||||
msg.push(trs[a].getAttribute('id'));
|
||||
|
||||
console.log(msg.join(' '));
|
||||
}
|
||||
|
||||
this.bzw = function () {
|
||||
var first = document.querySelector('#u2tab>tbody>tr:first-child');
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
var last = document.querySelector('#u2tab>tbody>tr:last-child');
|
||||
first = parseInt(first.getAttribute('id').slice(1));
|
||||
last = parseInt(last.getAttribute('id').slice(1));
|
||||
//this.bzw_log(first, last);
|
||||
|
||||
while (this.head - first > this.wsz) {
|
||||
var obj = ebi('f' + (first++));
|
||||
obj.parentNode.removeChild(obj);
|
||||
}
|
||||
while (last - this.tail < this.wsz && last < this.tab.length - 2) {
|
||||
var obj = ebi('f' + (++last));
|
||||
if (!obj)
|
||||
this.addrow(last);
|
||||
}
|
||||
//this.bzw_log(first, last);
|
||||
//console.log('--');
|
||||
};
|
||||
|
||||
this.drawcard = function (cat) {
|
||||
var cards = document.querySelectorAll('#u2cards>a>span');
|
||||
|
||||
if (cat == "q") {
|
||||
cards[4].innerHTML = this.ctr[cat];
|
||||
return;
|
||||
}
|
||||
if (cat == "bz") {
|
||||
cards[3].innerHTML = this.ctr[cat];
|
||||
return;
|
||||
}
|
||||
|
||||
cards[2].innerHTML = this.ctr["ok"] + this.ctr["ng"];
|
||||
|
||||
if (cat == "ng") {
|
||||
cards[1].innerHTML = this.ctr[cat];
|
||||
}
|
||||
if (cat == "ok") {
|
||||
cards[0].innerHTML = this.ctr[cat];
|
||||
}
|
||||
};
|
||||
|
||||
this.changecard = function (card) {
|
||||
this.act = card;
|
||||
var html = [];
|
||||
this.head = -1;
|
||||
this.tail = -1;
|
||||
for (var a = 0; a < this.tab.length; a++) {
|
||||
var rt = this.tab[a].in;
|
||||
if (this.is_act(rt)) {
|
||||
html.push(this.genrow(a, true));
|
||||
|
||||
this.tail = a;
|
||||
if (this.head == -1)
|
||||
this.head = a;
|
||||
}
|
||||
}
|
||||
if (this.head == -1) {
|
||||
this.head = this.tab.length;
|
||||
this.tail = this.head - 1;
|
||||
}
|
||||
if (card == "bz") {
|
||||
for (var a = this.head - 1; a >= this.head - this.wsz && a >= 0; a--) {
|
||||
html.unshift(this.genrow(a, true).replace(/><td>/, "><td>a "));
|
||||
}
|
||||
for (var a = this.tail + 1; a <= this.tail + this.wsz && a < this.tab.length; a++) {
|
||||
html.push(this.genrow(a, true).replace(/><td>/, "><td>b "));
|
||||
}
|
||||
}
|
||||
ebi('u2tab').tBodies[0].innerHTML = html.join('\n');
|
||||
};
|
||||
|
||||
this.genrow = function (nfile, as_html) {
|
||||
var r = this.tab[nfile],
|
||||
td1 = '<td id="f' + nfile,
|
||||
td = '</td>' + td1,
|
||||
ret = td1 + 'n">' + r.hn +
|
||||
td + 't">' + r.ht +
|
||||
td + 'p" class="prog">' + r.hp + '</td>';
|
||||
|
||||
if (as_html)
|
||||
return '<tr id="f' + nfile + '">' + ret + '</tr>';
|
||||
|
||||
var obj = document.createElement('tr');
|
||||
obj.setAttribute('id', 'f' + nfile);
|
||||
obj.innerHTML = ret;
|
||||
return obj;
|
||||
};
|
||||
|
||||
this.addrow = function (nfile) {
|
||||
var tr = this.genrow(nfile);
|
||||
ebi('u2tab').tBodies[0].appendChild(tr);
|
||||
};
|
||||
|
||||
var that = this;
|
||||
btns = document.querySelectorAll(btns + '>a[act]');
|
||||
for (var a = 0; a < btns.length; a++) {
|
||||
btns[a].onclick = function (e) {
|
||||
ev(e);
|
||||
var newtab = this.getAttribute('act');
|
||||
for (var b = 0; b < btns.length; b++) {
|
||||
btns[b].className = (
|
||||
btns[b].getAttribute('act') == newtab) ? 'act' : '';
|
||||
}
|
||||
that.changecard(newtab);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function up2k_init(have_crypto) {
|
||||
//have_crypto = false;
|
||||
var need_filereader_cache = undefined;
|
||||
@@ -216,10 +493,6 @@ function up2k_init(have_crypto) {
|
||||
var flag_en = bcfg_get('flag_en', false);
|
||||
var fsearch = bcfg_get('fsearch', false);
|
||||
|
||||
var col_hashing = '#00bbff';
|
||||
var col_hashed = '#004466';
|
||||
var col_uploading = '#ffcc44';
|
||||
var col_uploaded = '#00bb00';
|
||||
var fdom_ctr = 0;
|
||||
var st = {
|
||||
"files": [],
|
||||
@@ -239,6 +512,8 @@ function up2k_init(have_crypto) {
|
||||
}
|
||||
};
|
||||
|
||||
var pvis = new U2pvis("bz", '#u2cards');
|
||||
|
||||
var bobslice = null;
|
||||
if (window.File)
|
||||
bobslice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
|
||||
@@ -413,12 +688,12 @@ function up2k_init(have_crypto) {
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
var tr = document.createElement('tr');
|
||||
tr.innerHTML = '<td id="f{0}n"></td><td id="f{0}t">hashing</td><td id="f{0}p" class="prog"></td>'.format(st.files.length);
|
||||
tr.getElementsByTagName('td')[0].innerHTML = fsearch ? esc(entry.name) : linksplit(
|
||||
esc(uricom_dec(entry.purl)[0] + entry.name)).join(' ');
|
||||
ebi('u2tab').appendChild(tr);
|
||||
|
||||
pvis.addfile([
|
||||
fsearch ? esc(entry.name) : linksplit(
|
||||
esc(uricom_dec(entry.purl)[0] + entry.name)).join(' '),
|
||||
'📐 hash',
|
||||
''
|
||||
], fobj.size);
|
||||
st.files.push(entry);
|
||||
st.todo.hash.push(entry);
|
||||
}
|
||||
@@ -439,7 +714,10 @@ function up2k_init(have_crypto) {
|
||||
for (var a = 0; a < st.files.length; a++) {
|
||||
var t = st.files[a];
|
||||
if (t.done && t.name) {
|
||||
var tr = ebi('f{0}p'.format(t.n)).parentNode;
|
||||
var tr = ebi('f' + t.n);
|
||||
if (!tr)
|
||||
continue;
|
||||
|
||||
tr.parentNode.removeChild(tr);
|
||||
t.name = undefined;
|
||||
}
|
||||
@@ -462,7 +740,8 @@ function up2k_init(have_crypto) {
|
||||
function hashing_permitted() {
|
||||
if (multitask) {
|
||||
var ahead = st.bytes.hashed - st.bytes.uploaded;
|
||||
return ahead < 1024 * 1024 * 128;
|
||||
return ahead < 1024 * 1024 * 1024 * 4 &&
|
||||
st.todo.handshake.length + st.busy.handshake.length < 16;
|
||||
}
|
||||
return handshakes_permitted() && 0 ==
|
||||
st.todo.handshake.length +
|
||||
@@ -695,13 +974,8 @@ function up2k_init(have_crypto) {
|
||||
if (!need_filereader_cache)
|
||||
subchunks = 1;
|
||||
|
||||
var pb_html = '';
|
||||
var pb_perc = 99.9 / nchunks;
|
||||
for (var a = 0; a < nchunks; a++)
|
||||
pb_html += '<div id="f{0}p{1}" style="width:{2}%"><div></div></div>'.format(
|
||||
t.n, a, pb_perc);
|
||||
|
||||
ebi('f{0}p'.format(t.n)).innerHTML = pb_html;
|
||||
pvis.setab(t.n, nchunks);
|
||||
pvis.move(t.n, 'bz');
|
||||
|
||||
var reader = new FileReader();
|
||||
|
||||
@@ -719,8 +993,6 @@ function up2k_init(have_crypto) {
|
||||
|
||||
reader.readAsArrayBuffer(
|
||||
bobslice.call(t.fobj, car, cdr));
|
||||
|
||||
prog(t.n, nchunk, col_hashing);
|
||||
};
|
||||
|
||||
var segm_load = function (e) {
|
||||
@@ -764,9 +1036,8 @@ function up2k_init(have_crypto) {
|
||||
var b64str = buf2b64(hslice).replace(/=$/, '');
|
||||
t.hash.push(b64str);
|
||||
|
||||
prog(t.n, nchunk, col_hashed);
|
||||
pvis.hashed(t);
|
||||
if (++nchunk < nchunks) {
|
||||
prog(t.n, nchunk, col_hashing);
|
||||
return segm_next();
|
||||
}
|
||||
|
||||
@@ -776,13 +1047,14 @@ function up2k_init(have_crypto) {
|
||||
alert('{0} ms, {1} MB/s\n'.format(t.t2 - t.t1, spd.toFixed(3)) + t.hash.join('\n'));
|
||||
}
|
||||
|
||||
ebi('f{0}t'.format(t.n)).innerHTML = 'connecting';
|
||||
pvis.seth(t.n, 2, 'hashing done');
|
||||
pvis.seth(t.n, 1, '📦 wait');
|
||||
st.busy.hash.splice(st.busy.hash.indexOf(t), 1);
|
||||
st.todo.handshake.push(t);
|
||||
};
|
||||
|
||||
var segm_err = function () {
|
||||
alert('y o u b r o k e i t\n\n(was that a folder? just files please)');
|
||||
alert('y o u b r o k e i t\nerror: ' + reader.error);
|
||||
};
|
||||
|
||||
segm_next();
|
||||
@@ -821,8 +1093,9 @@ function up2k_init(have_crypto) {
|
||||
|
||||
msg += '<br /><small>' + tr + ' (srv), ' + tu + ' (You), ' + sdiff + '</span></span>';
|
||||
}
|
||||
ebi('f{0}p'.format(t.n)).innerHTML = msg;
|
||||
ebi('f{0}t'.format(t.n)).innerHTML = smsg;
|
||||
pvis.seth(t.n, 2, msg);
|
||||
pvis.seth(t.n, 1, smsg);
|
||||
pvis.move(t.n, smsg == '404' ? 'ng' : 'ok');
|
||||
st.busy.handshake.splice(st.busy.handshake.indexOf(t), 1);
|
||||
st.bytes.uploaded += t.size;
|
||||
t.done = true;
|
||||
@@ -833,7 +1106,15 @@ function up2k_init(have_crypto) {
|
||||
if (response.name !== t.name) {
|
||||
// file exists; server renamed us
|
||||
t.name = response.name;
|
||||
ebi('f{0}n'.format(t.n)).innerHTML = linksplit(esc(t.purl + t.name)).join(' ');
|
||||
pvis.seth(t.n, 0, linksplit(esc(t.purl + t.name)).join(' '));
|
||||
}
|
||||
|
||||
var chunksize = get_chunksize(t.size);
|
||||
var cdr_idx = Math.ceil(t.size / chunksize) - 1;
|
||||
var cdr_sz = (t.size % chunksize) || chunksize;
|
||||
var cbd = [];
|
||||
for (var a = 0; a <= cdr_idx; a++) {
|
||||
cbd.push(a == cdr_idx ? cdr_sz : chunksize);
|
||||
}
|
||||
|
||||
t.postlist = [];
|
||||
@@ -846,10 +1127,11 @@ function up2k_init(have_crypto) {
|
||||
missing[a], JSON.stringify(t)));
|
||||
|
||||
t.postlist.push(idx);
|
||||
cbd[idx] = 0;
|
||||
}
|
||||
for (var a = 0; a < t.hash.length; a++)
|
||||
prog(t.n, a, (t.postlist.indexOf(a) == -1)
|
||||
? col_uploaded : col_hashed);
|
||||
|
||||
pvis.setat(t.n, cbd);
|
||||
pvis.prog(t, 0, cbd[0]);
|
||||
|
||||
var done = true;
|
||||
var msg = '🎷🐛';
|
||||
@@ -863,7 +1145,7 @@ function up2k_init(have_crypto) {
|
||||
msg = 'uploading';
|
||||
done = false;
|
||||
}
|
||||
ebi('f{0}t'.format(t.n)).innerHTML = msg;
|
||||
pvis.seth(t.n, 1, msg);
|
||||
st.busy.handshake.splice(st.busy.handshake.indexOf(t), 1);
|
||||
|
||||
if (done) {
|
||||
@@ -871,8 +1153,9 @@ function up2k_init(have_crypto) {
|
||||
st.bytes.uploaded += t.size - t.bytes_uploaded;
|
||||
var spd1 = (t.size / ((t.t2 - t.t1) / 1000.)) / (1024 * 1024.);
|
||||
var spd2 = (t.size / ((t.t4 - t.t3) / 1000.)) / (1024 * 1024.);
|
||||
ebi('f{0}p'.format(t.n)).innerHTML = 'hash {0}, up {1} MB/s'.format(
|
||||
spd1.toFixed(2), spd2.toFixed(2));
|
||||
pvis.seth(t.n, 2, 'hash {0}, up {1} MB/s'.format(
|
||||
spd1.toFixed(2), spd2.toFixed(2)));
|
||||
pvis.move(t.n, 'ok');
|
||||
}
|
||||
else t.t4 = undefined;
|
||||
|
||||
@@ -899,18 +1182,19 @@ function up2k_init(have_crypto) {
|
||||
}
|
||||
}
|
||||
if (err != "") {
|
||||
ebi('f{0}t'.format(t.n)).innerHTML = "ERROR";
|
||||
ebi('f{0}p'.format(t.n)).innerHTML = err;
|
||||
pvis.seth(t.n, 1, "ERROR");
|
||||
pvis.seth(t.n, 2, err);
|
||||
pvis.move(t.n, 'ng');
|
||||
|
||||
st.busy.handshake.splice(st.busy.handshake.indexOf(t), 1);
|
||||
tasker();
|
||||
return;
|
||||
}
|
||||
alert("server broke (error {0}):\n\"{1}\"\n".format(
|
||||
xhr.status,
|
||||
(xhr.response && xhr.response.err) ||
|
||||
(xhr.responseText && xhr.responseText) ||
|
||||
"no further information"));
|
||||
alert("server broke; hs-err {0} on file [{1}]:\n".format(
|
||||
xhr.status, t.name) + (
|
||||
(xhr.response && xhr.response.err) ||
|
||||
(xhr.responseText && xhr.responseText) ||
|
||||
"no further information"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -939,8 +1223,10 @@ function up2k_init(have_crypto) {
|
||||
|
||||
var npart = upt.npart;
|
||||
var t = st.files[upt.nfile];
|
||||
if (!t.t3)
|
||||
t.t3 = new Date().getTime();
|
||||
|
||||
prog(t.n, npart, col_uploading);
|
||||
pvis.seth(t.n, 1, "🚀 send");
|
||||
|
||||
var chunksize = get_chunksize(t.size);
|
||||
var car = npart * chunksize;
|
||||
@@ -948,73 +1234,40 @@ function up2k_init(have_crypto) {
|
||||
if (cdr >= t.size)
|
||||
cdr = t.size;
|
||||
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onerror = function () {
|
||||
alert('y o u b r o k e i t\n\n(was that a folder? just files please)');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.onprogress = function (xev) {
|
||||
pvis.prog(t, npart, xev.loaded);
|
||||
};
|
||||
|
||||
reader.onload = function (e) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.onprogress = function (xev) {
|
||||
var perc = xev.loaded / (cdr - car) * 100;
|
||||
prog(t.n, npart, '', perc);
|
||||
};
|
||||
xhr.onload = function (xev) {
|
||||
if (xhr.status == 200) {
|
||||
prog(t.n, npart, col_uploaded);
|
||||
st.bytes.uploaded += cdr - car;
|
||||
t.bytes_uploaded += cdr - car;
|
||||
st.busy.upload.splice(st.busy.upload.indexOf(upt), 1);
|
||||
t.postlist.splice(t.postlist.indexOf(npart), 1);
|
||||
if (t.postlist.length == 0) {
|
||||
t.t4 = new Date().getTime();
|
||||
ebi('f{0}t'.format(t.n)).innerHTML = 'verifying';
|
||||
st.todo.handshake.unshift(t);
|
||||
}
|
||||
tasker();
|
||||
xhr.onload = function (xev) {
|
||||
if (xhr.status == 200) {
|
||||
pvis.prog(t, npart, cdr - car);
|
||||
st.bytes.uploaded += cdr - car;
|
||||
t.bytes_uploaded += cdr - car;
|
||||
st.busy.upload.splice(st.busy.upload.indexOf(upt), 1);
|
||||
t.postlist.splice(t.postlist.indexOf(npart), 1);
|
||||
if (t.postlist.length == 0) {
|
||||
t.t4 = new Date().getTime();
|
||||
pvis.seth(t.n, 1, 'verifying');
|
||||
st.todo.handshake.unshift(t);
|
||||
}
|
||||
else
|
||||
alert("server broke (error {0}):\n\"{1}\"\n".format(
|
||||
xhr.status,
|
||||
tasker();
|
||||
}
|
||||
else
|
||||
alert("server broke; cu-err {0} on file [{1}]:\n".format(
|
||||
xhr.status, t.name) + (
|
||||
(xhr.response && xhr.response.err) ||
|
||||
(xhr.responseText && xhr.responseText) ||
|
||||
"no further information"));
|
||||
};
|
||||
xhr.open('POST', t.purl + 'chunkpit.php', true);
|
||||
//xhr.setRequestHeader("X-Up2k-Hash", t.hash[npart].substr(1) + "x");
|
||||
xhr.setRequestHeader("X-Up2k-Hash", t.hash[npart]);
|
||||
xhr.setRequestHeader("X-Up2k-Wark", t.wark);
|
||||
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
|
||||
if (xhr.overrideMimeType)
|
||||
xhr.overrideMimeType('Content-Type', 'application/octet-stream');
|
||||
|
||||
xhr.responseType = 'text';
|
||||
xhr.send(e.target.result);
|
||||
|
||||
if (!t.t3)
|
||||
t.t3 = new Date().getTime();
|
||||
};
|
||||
xhr.open('POST', t.purl + 'chunkpit.php', true);
|
||||
xhr.setRequestHeader("X-Up2k-Hash", t.hash[npart]);
|
||||
xhr.setRequestHeader("X-Up2k-Wark", t.wark);
|
||||
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
|
||||
if (xhr.overrideMimeType)
|
||||
xhr.overrideMimeType('Content-Type', 'application/octet-stream');
|
||||
|
||||
reader.readAsArrayBuffer(bobslice.call(t.fobj, car, cdr));
|
||||
}
|
||||
|
||||
/////
|
||||
////
|
||||
/// progress bar
|
||||
//
|
||||
|
||||
function prog(nfile, nchunk, color, percent) {
|
||||
var n1 = ebi('f{0}p{1}'.format(nfile, nchunk));
|
||||
var n2 = n1.getElementsByTagName('div')[0];
|
||||
if (percent === undefined) {
|
||||
n1.style.background = color;
|
||||
n2.style.display = 'none';
|
||||
}
|
||||
else {
|
||||
n2.style.width = percent + '%';
|
||||
n2.style.display = 'block';
|
||||
}
|
||||
xhr.responseType = 'text';
|
||||
xhr.send(bobslice.call(t.fobj, car, cdr));
|
||||
}
|
||||
|
||||
/////
|
||||
@@ -1035,6 +1288,7 @@ function up2k_init(have_crypto) {
|
||||
if (btn.parentNode !== parent) {
|
||||
parent.appendChild(btn);
|
||||
ebi('u2conf').setAttribute('class', wide ? 'has_btn' : '');
|
||||
ebi('u2cards').setAttribute('class', wide ? 'w' : '');
|
||||
}
|
||||
}
|
||||
window.addEventListener('resize', onresize);
|
||||
@@ -1070,14 +1324,14 @@ function up2k_init(have_crypto) {
|
||||
|
||||
var obj = ebi('nthread');
|
||||
if (dir.target) {
|
||||
obj.style.background = '#922';
|
||||
clmod(obj, 'err', 1);
|
||||
var v = Math.floor(parseInt(obj.value));
|
||||
if (v < 1 || v > 8 || v !== v)
|
||||
return;
|
||||
|
||||
parallel_uploads = v;
|
||||
swrite('nthread', v);
|
||||
obj.style.background = '#444';
|
||||
clmod(obj, 'err');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
margin: -1.5em 0;
|
||||
padding: .8em 0;
|
||||
width: 100%;
|
||||
max-width: 12em;
|
||||
display: inline-block;
|
||||
}
|
||||
#u2conf #u2btn_cw {
|
||||
text-align: right;
|
||||
}
|
||||
#u2notbtn {
|
||||
display: none;
|
||||
@@ -72,6 +77,7 @@
|
||||
}
|
||||
#u2tab td:nth-child(2) {
|
||||
width: 5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#u2tab td:nth-child(3) {
|
||||
width: 40%;
|
||||
@@ -83,6 +89,35 @@
|
||||
#u2tab tr+tr:hover td {
|
||||
background: #222;
|
||||
}
|
||||
#u2cards {
|
||||
margin: 2.5em auto -2.5em auto;
|
||||
text-align: center;
|
||||
}
|
||||
#u2cards.w {
|
||||
width: 45em;
|
||||
text-align: left;
|
||||
}
|
||||
#u2cards a {
|
||||
padding: .2em 1em;
|
||||
border: 1px solid #777;
|
||||
border-width: 0 0 1px 0;
|
||||
background: linear-gradient(to bottom, #333, #222);
|
||||
}
|
||||
#u2cards a:first-child {
|
||||
border-radius: .4em 0 0 0;
|
||||
}
|
||||
#u2cards a:last-child {
|
||||
border-radius: 0 .4em 0 0;
|
||||
}
|
||||
#u2cards a.act {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-radius: .3em .3em 0 0;
|
||||
margin-left: -1px;
|
||||
background: transparent;
|
||||
}
|
||||
#u2cards span {
|
||||
color: #fff;
|
||||
}
|
||||
#u2conf {
|
||||
margin: 1em auto;
|
||||
width: 30em;
|
||||
@@ -106,6 +141,9 @@
|
||||
font-size: 1.2em;
|
||||
padding: .15em 0;
|
||||
}
|
||||
#u2conf .txtbox.err {
|
||||
background: #922;
|
||||
}
|
||||
#u2conf a {
|
||||
color: #fff;
|
||||
background: #c38;
|
||||
@@ -193,24 +231,6 @@
|
||||
.prog {
|
||||
font-family: monospace;
|
||||
}
|
||||
.prog>div {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 1.1em;
|
||||
margin-bottom: -.15em;
|
||||
box-shadow: -1px -1px 0 inset rgba(255,255,255,0.1);
|
||||
}
|
||||
.prog>div>div {
|
||||
width: 0%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: #0a0;
|
||||
}
|
||||
#u2tab a>span {
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
@@ -221,3 +241,35 @@
|
||||
float: right;
|
||||
margin-bottom: -.3em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
html.light #u2btn {
|
||||
box-shadow: .4em .4em 0 #ccc;
|
||||
}
|
||||
html.light #u2cards span {
|
||||
color: #000;
|
||||
}
|
||||
html.light #u2cards a {
|
||||
background: linear-gradient(to bottom, #eee, #fff);
|
||||
}
|
||||
html.light #u2cards a.act {
|
||||
background: inherit;
|
||||
}
|
||||
html.light #u2conf .txtbox {
|
||||
background: #fff;
|
||||
color: #444;
|
||||
}
|
||||
html.light #u2conf .txtbox.err {
|
||||
background: #f96;
|
||||
color: #300;
|
||||
}
|
||||
html.light #u2cdesc {
|
||||
background: #fff;
|
||||
border: none;
|
||||
}
|
||||
html.light #op_up2k.srch #u2btn {
|
||||
border-color: #a80;
|
||||
}
|
||||
@@ -79,12 +79,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="u2cards">
|
||||
<a href="#" act="ok">ok <span>0</span></a><a
|
||||
href="#" act="ng">ng <span>0</span></a><a
|
||||
href="#" act="done">done <span>0</span></a><a
|
||||
href="#" act="bz" class="act">busy <span>0</span></a><a
|
||||
href="#" act="q">que <span>0</span></a>
|
||||
</div>
|
||||
|
||||
<table id="u2tab">
|
||||
<tr>
|
||||
<td>filename</td>
|
||||
<td>status</td>
|
||||
<td>progress<a href="#" id="u2cleanup">cleanup</a></td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>filename</td>
|
||||
<td>status</td>
|
||||
<td>progress<a href="#" id="u2cleanup">cleanup</a></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<p id="u2foot"></p>
|
||||
|
||||
Reference in New Issue
Block a user