mirror of
https://github.com/9001/copyparty.git
synced 2026-06-21 05:32:25 -06:00
Prototype WOPI integration
This commit is contained in:
parent
2c778e0828
commit
70438b193b
|
|
@ -1568,6 +1568,12 @@ def add_opds(ap):
|
||||||
ap2.add_argument("--opds-exts", metavar="T,T", type=u, default="epub,cbz,pdf", help="file formats to list in OPDS feeds; leave empty to show everything (volflag=opds_exts)")
|
ap2.add_argument("--opds-exts", metavar="T,T", type=u, default="epub,cbz,pdf", help="file formats to list in OPDS feeds; leave empty to show everything (volflag=opds_exts)")
|
||||||
|
|
||||||
|
|
||||||
|
def add_wopi(ap):
|
||||||
|
ap2 = ap.add_argument_group("WOPI options")
|
||||||
|
ap2.add_argument("--wopi", action="store_true", help="enable WOPI -- allows for integrating with office suites (volflag=wopi)")
|
||||||
|
ap2.add_argument("--wopi-path", action="store_true", default="wopi", help="where to expose WOPI (needs to start with 'wopi'); defaults to <volname>/wopi/ (volflag=wopi-path)")
|
||||||
|
|
||||||
|
|
||||||
def add_handlers(ap):
|
def add_handlers(ap):
|
||||||
ap2 = ap.add_argument_group("handlers (see --help-handlers)")
|
ap2 = ap.add_argument_group("handlers (see --help-handlers)")
|
||||||
ap2.add_argument("--on404", metavar="PY", type=u, action="append", help="\033[34mREPEATABLE:\033[0m handle 404s by executing \033[33mPY\033[0m file")
|
ap2.add_argument("--on404", metavar="PY", type=u, action="append", help="\033[34mREPEATABLE:\033[0m handle 404s by executing \033[33mPY\033[0m file")
|
||||||
|
|
@ -2045,6 +2051,7 @@ def run_argparse(
|
||||||
add_tftp(ap)
|
add_tftp(ap)
|
||||||
add_smb(ap)
|
add_smb(ap)
|
||||||
add_opds(ap)
|
add_opds(ap)
|
||||||
|
add_wopi(ap)
|
||||||
add_safety(ap)
|
add_safety(ap)
|
||||||
add_salt(ap, fk_salt, dk_salt, ah_salt)
|
add_salt(ap, fk_salt, dk_salt, ah_salt)
|
||||||
add_optouts(ap)
|
add_optouts(ap)
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,7 @@ flagcats = {
|
||||||
"gz": "allows server-side gzip compression of uploads with ?gz",
|
"gz": "allows server-side gzip compression of uploads with ?gz",
|
||||||
"xz": "allows server-side lzma compression of uploads with ?xz",
|
"xz": "allows server-side lzma compression of uploads with ?xz",
|
||||||
"pk": "forces server-side compression, optional arg: xz,9",
|
"pk": "forces server-side compression, optional arg: xz,9",
|
||||||
|
"wopi": "enable WOPI support for integrating with online office suites",
|
||||||
},
|
},
|
||||||
"upload rules": {
|
"upload rules": {
|
||||||
"apnd_who=dw": "who can append? (aw/dw/w/no)",
|
"apnd_who=dw": "who can append? (aw/dw/w/no)",
|
||||||
|
|
|
||||||
|
|
@ -1413,6 +1413,8 @@ class HttpCli(object):
|
||||||
|
|
||||||
self.tx_404()
|
self.tx_404()
|
||||||
return False
|
return False
|
||||||
|
elif self.vpath.startswith("wopi"):
|
||||||
|
return self.tx_wopi()
|
||||||
|
|
||||||
if "cf_challenge" in self.uparam:
|
if "cf_challenge" in self.uparam:
|
||||||
self.reply(self.j2s("cf").encode("utf-8", "replace"))
|
self.reply(self.j2s("cf").encode("utf-8", "replace"))
|
||||||
|
|
@ -1526,6 +1528,47 @@ class HttpCli(object):
|
||||||
|
|
||||||
return self.tx_browser()
|
return self.tx_browser()
|
||||||
|
|
||||||
|
def tx_wopi(self) -> bool:
|
||||||
|
path = self.vpath.split('/')
|
||||||
|
full_path = "/mnt/tmp/" + path[2]
|
||||||
|
|
||||||
|
if self.do_log:
|
||||||
|
self.log("WOPI GET %s" % (path[2]))
|
||||||
|
|
||||||
|
if path[1] == "files":
|
||||||
|
if len(path) > 3 and path[3] == "contents":
|
||||||
|
return self.tx_file("oh_f", full_path)
|
||||||
|
else:
|
||||||
|
file_info = {
|
||||||
|
"BaseFileName": path[2],
|
||||||
|
"OwnerId": self.uname,
|
||||||
|
"Size": os.path.getsize(full_path),
|
||||||
|
"UserId": self.uname,
|
||||||
|
"UserFriendlyName": self.uname,
|
||||||
|
"UserCanWrite": True,
|
||||||
|
# "UserCanNotWriteRelative": False,
|
||||||
|
# "PostMessageOrigin": ,
|
||||||
|
# "HidePrintOption": ,
|
||||||
|
# "DisablePrint": ,
|
||||||
|
# "HideSaveOption": ,
|
||||||
|
# "HideExportOption": ,
|
||||||
|
# "HideRepairOption": ,
|
||||||
|
# "DisableExport": ,
|
||||||
|
# "DisableCopy": ,
|
||||||
|
"EnableOwnerTermination": True,
|
||||||
|
"LastModifiedTime":
|
||||||
|
time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(os.path.getmtime(full_path))),
|
||||||
|
# "IsUserLocked": ,
|
||||||
|
# "IsUserRestricted": ,
|
||||||
|
# "SupportsRename": True,
|
||||||
|
# "UserCanRename": True,
|
||||||
|
}
|
||||||
|
ret = json.dumps(file_info).encode("utf-8", "replace")
|
||||||
|
self.reply(ret, 200, "application/json; charset=utf-8")
|
||||||
|
return True
|
||||||
|
|
||||||
|
return self.tx_404(True)
|
||||||
|
|
||||||
def tx_rss(self) -> bool:
|
def tx_rss(self) -> bool:
|
||||||
if self.do_log:
|
if self.do_log:
|
||||||
self.log("RSS %s @%s" % (self.req, self.uname))
|
self.log("RSS %s @%s" % (self.req, self.uname))
|
||||||
|
|
@ -3149,6 +3192,9 @@ class HttpCli(object):
|
||||||
except:
|
except:
|
||||||
raise Pebkac(400, "you must supply a content-length for binary POST")
|
raise Pebkac(400, "you must supply a content-length for binary POST")
|
||||||
|
|
||||||
|
if self.vpath.startswith("wopi"):
|
||||||
|
return self.rx_wopi()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chashes = self.headers["x-up2k-hash"].split(",")
|
chashes = self.headers["x-up2k-hash"].split(",")
|
||||||
wark = self.headers["x-up2k-wark"]
|
wark = self.headers["x-up2k-wark"]
|
||||||
|
|
@ -3360,6 +3406,36 @@ class HttpCli(object):
|
||||||
self.reply(b"thank")
|
self.reply(b"thank")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def rx_wopi(self) -> bool:
|
||||||
|
path = self.vpath.split('/')
|
||||||
|
full_path = "/mnt/tmp/" + path[2]
|
||||||
|
|
||||||
|
if self.do_log:
|
||||||
|
self.log("WOPI POST %s" % (path[2]))
|
||||||
|
|
||||||
|
if path[1] == "files":
|
||||||
|
if len(path) > 3 and path[3] == "contents":
|
||||||
|
reader, _ = self.get_body_reader()
|
||||||
|
buf = b""
|
||||||
|
for rbuf in reader:
|
||||||
|
buf += rbuf
|
||||||
|
if not rbuf or len(buf) >= 32768:
|
||||||
|
break
|
||||||
|
|
||||||
|
if buf:
|
||||||
|
with open(full_path, "wb") as file:
|
||||||
|
file.write(buf)
|
||||||
|
|
||||||
|
mod_time = {
|
||||||
|
"LastModifiedTime":
|
||||||
|
time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(os.path.getmtime(full_path)))
|
||||||
|
}
|
||||||
|
ret = json.dumps(mod_time).encode("utf-8", "replace")
|
||||||
|
self.reply(ret, 200, "application/json; charset=utf-8")
|
||||||
|
return True
|
||||||
|
|
||||||
|
return self.tx_404(True)
|
||||||
|
|
||||||
def handle_chpw(self) -> bool:
|
def handle_chpw(self) -> bool:
|
||||||
assert self.parser # !rm
|
assert self.parser # !rm
|
||||||
if self.args.usernames:
|
if self.args.usernames:
|
||||||
|
|
|
||||||
|
|
@ -7665,7 +7665,10 @@ var treectl = (function () {
|
||||||
tn.href = addq(tn.href, 'v');
|
tn.href = addq(tn.href, 'v');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tn.lead == '-')
|
if (["ods", "odt", "odp"].includes(tn.ext)) {
|
||||||
|
tn.lead = '<a href="https://192.168.1.11:9980/browser/4610258811/cool.html?WOPISrc=https://192.168.1.11:3923/wopi/files/' +
|
||||||
|
bhref + '" rel="nofollow">📄</a>';
|
||||||
|
} else if (tn.lead == '-')
|
||||||
tn.lead = '<a href="?doc=' + bhref + '" id="t' + id +
|
tn.lead = '<a href="?doc=' + bhref + '" id="t' + id +
|
||||||
'" rel="nofollow" class="doc' + (lang ? ' bri' : '') +
|
'" rel="nofollow" class="doc' + (lang ? ' bri' : '') +
|
||||||
'" hl="' + id + '" name="' + hname + '">-txt-</a>';
|
'" hl="' + id + '" name="' + hname + '">-txt-</a>';
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue