mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-03 21:43:12 +00:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					dcadf2b11c | ||
| 
						 | 
					37a690a4c3 | ||
| 
						 | 
					87ad23fb93 | ||
| 
						 | 
					5f54d534e3 | 
@@ -177,7 +177,7 @@ recommended additional steps on debian  which enable audio metadata and thumbnai
 | 
			
		||||
* browser
 | 
			
		||||
  * ☑ [navpane](#navpane) (directory tree sidebar)
 | 
			
		||||
  * ☑ file manager (cut/paste, delete, [batch-rename](#batch-rename))
 | 
			
		||||
  * ☑ audio player (with OS media controls and opus transcoding)
 | 
			
		||||
  * ☑ audio player (with [OS media controls](https://user-images.githubusercontent.com/241032/215347492-b4250797-6c90-4e09-9a4c-721edf2fb15c.png) and opus transcoding)
 | 
			
		||||
  * ☑ image gallery with webm player
 | 
			
		||||
  * ☑ textfile browser with syntax hilighting
 | 
			
		||||
  * ☑ [thumbnails](#thumbnails)
 | 
			
		||||
@@ -693,7 +693,7 @@ using arguments or config files, or a mix of both:
 | 
			
		||||
 | 
			
		||||
## zeroconf
 | 
			
		||||
 | 
			
		||||
announce enabled services on the LAN  if you specify the `-z` option, which enables [mdns](#mdns) and [ssdp](#ssdp)
 | 
			
		||||
announce enabled services on the LAN ([pic](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png))  -- `-z` enables both [mdns](#mdns) and [ssdp](#ssdp)
 | 
			
		||||
 | 
			
		||||
* `--z-on` / `--z-off`' limits the feature to certain networks
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@ these programs either take zero arguments, or a filepath (the affected file), or
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# after upload
 | 
			
		||||
* [notify.py](notify.py) shows a desktop notification
 | 
			
		||||
* [discord-announce.py](discord-announce.py) announces new uploads on discord using webhooks
 | 
			
		||||
* [notify.py](notify.py) shows a desktop notification ([example](https://user-images.githubusercontent.com/241032/215335767-9c91ed24-d36e-4b6b-9766-fb95d12d163f.png))
 | 
			
		||||
* [discord-announce.py](discord-announce.py) announces new uploads on discord using webhooks ([example](https://user-images.githubusercontent.com/241032/215304439-1c1cb3c8-ec6f-4c17-9f27-81f969b1811a.png))
 | 
			
		||||
* [reject-mimetype.py](reject-mimetype.py) rejects uploads unless the mimetype is acceptable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								bin/hooks/discord-announce.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bin/hooks/discord-announce.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										30
									
								
								bin/hooks/notify.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										30
									
								
								bin/hooks/notify.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,20 +1,24 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
import subprocess as sp
 | 
			
		||||
from plyer import notification
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_ = r"""
 | 
			
		||||
show os notification on upload; works on windows, linux, macos
 | 
			
		||||
show os notification on upload; works on windows, linux, macos, android
 | 
			
		||||
 | 
			
		||||
depdencies:
 | 
			
		||||
    python3 -m pip install --user -U plyer
 | 
			
		||||
    windows: python3 -m pip install --user -U plyer
 | 
			
		||||
    linux:   python3 -m pip install --user -U plyer
 | 
			
		||||
    macos:   python3 -m pip install --user -U plyer pyobjus
 | 
			
		||||
    android: just termux and termux-api
 | 
			
		||||
 | 
			
		||||
example usage as global config:
 | 
			
		||||
example usages; either as global config (all volumes) or as volflag:
 | 
			
		||||
    --xau f,bin/hooks/notify.py
 | 
			
		||||
 | 
			
		||||
example usage as a volflag (per-volume config):
 | 
			
		||||
    -v srv/inc:inc:c,xau=f,bin/hooks/notify.py
 | 
			
		||||
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
parameters explained,
 | 
			
		||||
    xau = execute after upload
 | 
			
		||||
@@ -23,7 +27,21 @@ parameters explained,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    notification.notify(title="new file uploaded", message=sys.argv[1], timeout=10)
 | 
			
		||||
    dp, fn = os.path.split(sys.argv[1])
 | 
			
		||||
    msg = "🏷️ {}\n📁 {}".format(fn, dp)
 | 
			
		||||
    title = "File received"
 | 
			
		||||
 | 
			
		||||
    if "com.termux" in sys.executable:
 | 
			
		||||
        sp.run(["termux-notification", "-t", title, "-c", msg])
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    icon = "emblem-documents-symbolic" if sys.platform == "linux" else ""
 | 
			
		||||
    notification.notify(
 | 
			
		||||
        title=title,
 | 
			
		||||
        message=msg,
 | 
			
		||||
        app_icon=icon,
 | 
			
		||||
        timeout=10,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								bin/hooks/reject-extension.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bin/hooks/reject-extension.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								bin/hooks/reject-mimetype.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bin/hooks/reject-mimetype.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								bin/hooks/wget.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bin/hooks/wget.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
VERSION = (1, 6, 1)
 | 
			
		||||
VERSION = (1, 6, 2)
 | 
			
		||||
CODENAME = "cors k"
 | 
			
		||||
BUILD_DT = (2023, 1, 29)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -605,12 +605,12 @@ class HttpCli(object):
 | 
			
		||||
        if self.is_rclone:
 | 
			
		||||
            return ""
 | 
			
		||||
 | 
			
		||||
        cmap = {"pw": "cppwd"}
 | 
			
		||||
        kv = {
 | 
			
		||||
            k: zs
 | 
			
		||||
            for k, zs in self.uparam.items()
 | 
			
		||||
            if k not in rm and self.cookies.get(cmap.get(k, k)) != zs
 | 
			
		||||
        }
 | 
			
		||||
        kv = {k: zs for k, zs in self.uparam.items() if k not in rm}
 | 
			
		||||
        if "pw" in kv:
 | 
			
		||||
            pw = self.cookies.get("cppws") or self.cookies.get("cppwd")
 | 
			
		||||
            if kv["pw"] == pw:
 | 
			
		||||
                del kv["pw"]
 | 
			
		||||
 | 
			
		||||
        kv.update(add)
 | 
			
		||||
        if not kv:
 | 
			
		||||
            return ""
 | 
			
		||||
@@ -1909,9 +1909,7 @@ class HttpCli(object):
 | 
			
		||||
        self.parser.drop()
 | 
			
		||||
 | 
			
		||||
        self.out_headerlist = [
 | 
			
		||||
            x
 | 
			
		||||
            for x in self.out_headerlist
 | 
			
		||||
            if x[0] != "Set-Cookie" or "cppwd" != x[1][:5]
 | 
			
		||||
            x for x in self.out_headerlist if x[0] != "Set-Cookie" or "cppw" != x[1][:4]
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        dst = self.args.SRS
 | 
			
		||||
@@ -1943,12 +1941,12 @@ class HttpCli(object):
 | 
			
		||||
        if pwd == "x":
 | 
			
		||||
            # reset both plaintext and tls
 | 
			
		||||
            # (only affects active tls cookies when tls)
 | 
			
		||||
            for k in ("cppwd", "cppws") if self.tls else ("cppwd",):
 | 
			
		||||
            for k in ("cppwd", "cppws") if self.is_https else ("cppwd",):
 | 
			
		||||
                ck = gencookie(k, pwd, self.args.R, False, dur)
 | 
			
		||||
                self.out_headerlist.append(("Set-Cookie", ck))
 | 
			
		||||
        else:
 | 
			
		||||
            k = "cppws" if self.tls else "cppwd"
 | 
			
		||||
            ck = gencookie(k, pwd, self.args.R, self.tls, dur)
 | 
			
		||||
            k = "cppws" if self.is_https else "cppwd"
 | 
			
		||||
            ck = gencookie(k, pwd, self.args.R, self.is_https, dur)
 | 
			
		||||
            self.out_headerlist.append(("Set-Cookie", ck))
 | 
			
		||||
 | 
			
		||||
        return msg
 | 
			
		||||
 
 | 
			
		||||
@@ -1562,7 +1562,7 @@ def gencookie(k: str, v: str, r: str, tls: bool, dur: Optional[int]) -> str:
 | 
			
		||||
    else:
 | 
			
		||||
        exp = "Fri, 15 Aug 1997 01:00:00 GMT"
 | 
			
		||||
 | 
			
		||||
    return "{}={}; Path=/{}; Expires={}; HttpOnly{}; SameSite=Lax".format(
 | 
			
		||||
    return "{}={}; Path=/{}; Expires={}{}; SameSite=Lax".format(
 | 
			
		||||
        k, v, r, exp, "; Secure" if tls else ""
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -692,7 +692,9 @@ function noq_href(el) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function get_pwd() {
 | 
			
		||||
    var pwd = ('; ' + document.cookie).split('; cppwd=');
 | 
			
		||||
    var k = HTTPS ? 's=' : 'd=',
 | 
			
		||||
        pwd = ('; ' + document.cookie).split('; cppw' + k);
 | 
			
		||||
 | 
			
		||||
    if (pwd.length < 2)
 | 
			
		||||
        return null;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -182,13 +182,14 @@ symbol legend,
 | 
			
		||||
| mojibake filenames      | █ |   |   | • | • | █ | █ | • | • | • |   |
 | 
			
		||||
| undecodable filenames   | █ |   |   | • | • | █ |   | • | • |   |   |
 | 
			
		||||
 | 
			
		||||
* `zeroconf` = the server announces itself on the LAN, automatically appearing on other zeroconf-capable devices
 | 
			
		||||
* `webdav` = protocol convenient for mounting a remote server as a local filesystem; see zeroconf:
 | 
			
		||||
* `zeroconf` = the server announces itself on the LAN, [automatically appearing](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png) on other zeroconf-capable devices
 | 
			
		||||
* `mojibake filenames` = filenames decoded with the wrong codec and then reencoded (usually to utf-8), so `宇多田ヒカル` might look like `ëFæ╜ôcâqâJâï`
 | 
			
		||||
* `undecodable filenames` = pure binary garbage which cannot be parsed as utf-8
 | 
			
		||||
  * you can successfully play `$'\355\221'` with mpv through mounting a remote copyparty server with rclone, pog
 | 
			
		||||
* `a`/copyparty remarks:
 | 
			
		||||
  * extremely minimal samba/cifs server
 | 
			
		||||
  * netscape 4 / ie6 support is mostly listed as a joke altho some people have actually found it useful
 | 
			
		||||
  * netscape 4 / ie6 support is mostly listed as a joke altho some people have actually found it useful ([ie4 tho](https://user-images.githubusercontent.com/241032/118192791-fb31fe00-b446-11eb-9647-898ea8efc1f7.png))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## server configuration
 | 
			
		||||
@@ -249,12 +250,13 @@ symbol legend,
 | 
			
		||||
* `file action event hooks` = run script before/after upload, move, rename, ...
 | 
			
		||||
* `one-way folder sync` = like rsync, optionally deleting unexpected files at target
 | 
			
		||||
* `full sync` = stateful, dropbox-like sync
 | 
			
		||||
* `curl-friendly ls` = returns a plaintext folder listing when curled
 | 
			
		||||
* `curl-friendly ls` = returns a [sortable plaintext folder listing](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png) when curled
 | 
			
		||||
* `curl-friendly upload` = uploading with curl is just `curl -T some.bin http://.../`
 | 
			
		||||
* `a`/copyparty remarks:
 | 
			
		||||
  * one-way folder sync from local to server can be done efficiently with [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py), or with webdav and conventional rsync
 | 
			
		||||
  * can hot-reload config files (with just a few exceptions)
 | 
			
		||||
  * can set per-folder permissions if that folder is made into a separate volume, so there is configuration overhead
 | 
			
		||||
  * [event hooks](https://github.com/9001/copyparty/tree/hovudstraum/bin/hooks) ([discord](https://user-images.githubusercontent.com/241032/215304439-1c1cb3c8-ec6f-4c17-9f27-81f969b1811a.png), [desktop](https://user-images.githubusercontent.com/241032/215335767-9c91ed24-d36e-4b6b-9766-fb95d12d163f.png)) inspired by filebrowser, as well as the more complex [media parser](https://github.com/9001/copyparty/tree/hovudstraum/bin/mtag) alternative
 | 
			
		||||
  * upload history can be visualized using [partyjournal](https://github.com/9001/copyparty/blob/hovudstraum/bin/partyjournal.py)
 | 
			
		||||
* `k`/filegator remarks:
 | 
			
		||||
  * `per-* permissions` -- can limit a user to one folder and its subfolders
 | 
			
		||||
@@ -304,7 +306,8 @@ symbol legend,
 | 
			
		||||
| copy files              |   |   |   |   | █ |   |   |   | █ | █ | █ |
 | 
			
		||||
 | 
			
		||||
* `single-page app` = multitasking; possible to continue navigating while uploading
 | 
			
		||||
* `audio player » os-integration` = use the lockscreen to play/pause, prev/next song
 | 
			
		||||
* `audio player » os-integration` = use the [lockscreen](https://user-images.githubusercontent.com/241032/142711926-0700be6c-3e31-47b3-9928-53722221f722.png) or [media hotkeys](https://user-images.githubusercontent.com/241032/215347492-b4250797-6c90-4e09-9a4c-721edf2fb15c.png) to play/pause, prev/next song
 | 
			
		||||
* `search by custom tags` = ability to tag files through the UI and search by those
 | 
			
		||||
* `find local file` = drop a file into the browser to see if it exists on the server
 | 
			
		||||
* `a`/copyparty has teeny-tiny skips playing gapless albums depending on audio codec (opus best)
 | 
			
		||||
* `b`/hfs2 has a very basic directory tree view, not showing sibling folders
 | 
			
		||||
@@ -324,7 +327,7 @@ symbol legend,
 | 
			
		||||
| sharex                  | █ |   |   | █ |   | █ | ╱ | █ |   |   |   |
 | 
			
		||||
| flameshot               |   |   |   |   |   | █ |   |   |   |   |   |
 | 
			
		||||
 | 
			
		||||
* sharex ╱ = yes, but does not provide example sharex config
 | 
			
		||||
* sharex `╱` = yes, but does not provide example sharex config
 | 
			
		||||
* `a`/copyparty remarks:
 | 
			
		||||
  * `OS alert on upload` available as [a plugin](https://github.com/9001/copyparty/blob/hovudstraum/bin/hooks/notify.py)
 | 
			
		||||
  * `discord » announce uploads` available as [a plugin](https://github.com/9001/copyparty/blob/hovudstraum/bin/hooks/discord-announce.py)
 | 
			
		||||
@@ -353,7 +356,7 @@ symbol legend,
 | 
			
		||||
| linx               | go     | ░ gpl3 |  20 MB |
 | 
			
		||||
 | 
			
		||||
* `size` = binary (if available) or installed size of program and its dependencies
 | 
			
		||||
  * copyparty size is for the standalone python file; the windows exe is **6 MiB**
 | 
			
		||||
  * copyparty size is for the [standalone python](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) file; the [windows exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) is **6 MiB**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# reviews
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user