mirror of
				https://github.com/9001/copyparty.git
				synced 2025-10-30 19:43:37 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 24a2f760b7 | ||
|  | 79bbd8fe38 | ||
|  | 35dce1e3e4 | ||
|  | f886fdf913 | ||
|  | 4476f2f0da | 
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							| @@ -127,6 +127,7 @@ summary: all planned features work! now please enjoy the bloatening | ||||
|   * ☑ basic: plain multipart, ie6 support | ||||
|   * ☑ up2k: js, resumable, multithreaded | ||||
|   * ☑ stash: simple PUT filedropper | ||||
|   * ☑ unpost: undo/delete accidental uploads | ||||
|   * ☑ symlink/discard existing files (content-matching) | ||||
| * download | ||||
|   * ☑ single files in browser | ||||
| @@ -215,10 +216,11 @@ example: | ||||
| ## tabs | ||||
|  | ||||
| * `[🔎]` search by size, date, path/name, mp3-tags ... see [searching](#searching) | ||||
| * `[🧯]` unpost: undo/delete accidental uploads | ||||
| * `[🚀]` and `[🎈]` are the uploaders, see [uploading](#uploading) | ||||
| * `[📂]` mkdir, create directories | ||||
| * `[📝]` new-md, create a new markdown document | ||||
| * `[📟]` send-msg, either to server-log or into textfiles if `--urlform save` | ||||
| * `[📂]` mkdir: create directories | ||||
| * `[📝]` new-md: create a new markdown document | ||||
| * `[📟]` send-msg: either to server-log or into textfiles if `--urlform save` | ||||
| * `[🎺]` audio-player config options | ||||
| * `[⚙️]` general client config options | ||||
|  | ||||
| @@ -312,8 +314,10 @@ you can also zip a selection of files or folders by clicking them in the browser | ||||
| ## uploading | ||||
|  | ||||
| two upload methods are available in the html client: | ||||
| * `🎈 bup`, the basic uploader, supports almost every browser since netscape 4.0 | ||||
| * `🚀 up2k`, the fancy one | ||||
| * `[🎈] bup`, the basic uploader, supports almost every browser since netscape 4.0 | ||||
| * `[🚀] up2k`, the fancy one | ||||
|  | ||||
| you can undo/delete uploads using `[🧯] unpost` if the server is running with `-e2d` | ||||
|  | ||||
| up2k has several advantages: | ||||
| * you can drop folders into the browser (files are added recursively) | ||||
|   | ||||
| @@ -13,6 +13,10 @@ | ||||
| #   But note that journalctl will get the timestamps wrong due to | ||||
| #   python disabling line-buffering, so messages are out-of-order: | ||||
| #   https://user-images.githubusercontent.com/241032/126040249-cb535cc7-c599-4931-a796-a5d9af691bad.png | ||||
| # | ||||
| # enable line-buffering for realtime logging (slight performance cost): | ||||
| #   modify ExecStart and prefix it with `/bin/stdbuf -oL` like so: | ||||
| #   ExecStart=/bin/stdbuf -oL /usr/bin/python3 [...] | ||||
|  | ||||
| [Unit] | ||||
| Description=copyparty file server | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| # coding: utf-8 | ||||
|  | ||||
| VERSION = (0, 12, 2) | ||||
| VERSION = (0, 12, 5) | ||||
| CODENAME = "fil\033[33med" | ||||
| BUILD_DT = (2021, 7, 29) | ||||
| BUILD_DT = (2021, 7, 30) | ||||
|  | ||||
| S_VERSION = ".".join(map(str, VERSION)) | ||||
| S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT) | ||||
|   | ||||
| @@ -401,17 +401,18 @@ class AuthSrv(object): | ||||
|         if uname == "": | ||||
|             uname = "*" | ||||
|  | ||||
|         if "r" in lvl: | ||||
|             axs.uread[uname] = 1 | ||||
|         for un in uname.split(","): | ||||
|             if "r" in lvl: | ||||
|                 axs.uread[un] = 1 | ||||
|  | ||||
|         if "w" in lvl: | ||||
|             axs.uwrite[uname] = 1 | ||||
|             if "w" in lvl: | ||||
|                 axs.uwrite[un] = 1 | ||||
|  | ||||
|         if "m" in lvl: | ||||
|             axs.umove[uname] = 1 | ||||
|             if "m" in lvl: | ||||
|                 axs.umove[un] = 1 | ||||
|  | ||||
|         if "d" in lvl: | ||||
|             axs.udel[uname] = 1 | ||||
|             if "d" in lvl: | ||||
|                 axs.udel[un] = 1 | ||||
|  | ||||
|     def _read_volflag(self, flags, name, value, is_list): | ||||
|         if name not in ["mtp"]: | ||||
|   | ||||
| @@ -182,7 +182,7 @@ class HttpCli(object): | ||||
|  | ||||
|         self.uparam = uparam | ||||
|         self.cookies = cookies | ||||
|         self.vpath = unquotep(vpath) | ||||
|         self.vpath = unquotep(vpath)  # not query, so + means + | ||||
|  | ||||
|         pwd = uparam.get("pw") | ||||
|         self.uname = self.asrv.iacct.get(pwd, "*") | ||||
| @@ -346,11 +346,36 @@ class HttpCli(object): | ||||
|             static_path = os.path.join(E.mod, "web/", self.vpath[5:]) | ||||
|             return self.tx_file(static_path) | ||||
|  | ||||
|         x = self.asrv.vfs.can_access(self.vpath, self.uname) | ||||
|         self.can_read, self.can_write, self.can_move, self.can_delete = x | ||||
|         if not self.can_read and not self.can_write: | ||||
|             if self.vpath: | ||||
|                 self.log("inaccessible: [{}]".format(self.vpath)) | ||||
|                 raise Pebkac(404) | ||||
|  | ||||
|             self.uparam["h"] = False | ||||
|  | ||||
|         if "tree" in self.uparam: | ||||
|             return self.tx_tree() | ||||
|  | ||||
|         if not self.vpath and "stack" in self.uparam: | ||||
|             return self.tx_stack() | ||||
|         if "delete" in self.uparam: | ||||
|             return self.handle_rm() | ||||
|  | ||||
|         if "move" in self.uparam: | ||||
|             return self.handle_mv() | ||||
|  | ||||
|         if "scan" in self.uparam: | ||||
|             return self.scanvol() | ||||
|  | ||||
|         if not self.vpath: | ||||
|             if "stack" in self.uparam: | ||||
|                 return self.tx_stack() | ||||
|  | ||||
|             if "ups" in self.uparam: | ||||
|                 return self.tx_ups() | ||||
|  | ||||
|             if "h" in self.uparam: | ||||
|                 return self.tx_mounts() | ||||
|  | ||||
|         # conditional redirect to single volumes | ||||
|         if self.vpath == "" and not self.ouparam: | ||||
| @@ -366,31 +391,6 @@ class HttpCli(object): | ||||
|                     self.redirect(vpath, flavor="redirecting to", use302=True) | ||||
|                     return True | ||||
|  | ||||
|         x = self.asrv.vfs.can_access(self.vpath, self.uname) | ||||
|         self.can_read, self.can_write, self.can_move, self.can_delete = x | ||||
|         if not self.can_read and not self.can_write: | ||||
|             if self.vpath: | ||||
|                 self.log("inaccessible: [{}]".format(self.vpath)) | ||||
|                 raise Pebkac(404) | ||||
|  | ||||
|             self.uparam = {"h": False} | ||||
|  | ||||
|         if "delete" in self.uparam: | ||||
|             return self.handle_rm() | ||||
|  | ||||
|         if "move" in self.uparam: | ||||
|             return self.handle_mv() | ||||
|  | ||||
|         if "scan" in self.uparam: | ||||
|             return self.scanvol() | ||||
|  | ||||
|         if not self.vpath: | ||||
|             if "h" in self.uparam: | ||||
|                 return self.tx_mounts() | ||||
|  | ||||
|             if "ups" in self.uparam: | ||||
|                 return self.tx_ups() | ||||
|  | ||||
|         return self.tx_browser() | ||||
|  | ||||
|     def handle_options(self): | ||||
| @@ -1310,11 +1310,9 @@ class HttpCli(object): | ||||
|         else: | ||||
|             fn = self.headers.get("host", "hey") | ||||
|  | ||||
|         afn = "".join( | ||||
|             [x if x in (string.ascii_letters + string.digits) else "_" for x in fn] | ||||
|         ) | ||||
|  | ||||
|         bascii = unicode(string.ascii_letters + string.digits).encode("utf-8") | ||||
|         safe = (string.ascii_letters + string.digits).replace("%", "") | ||||
|         afn = "".join([x if x in safe.replace('"', "") else "_" for x in fn]) | ||||
|         bascii = unicode(safe).encode("utf-8") | ||||
|         ufn = fn.encode("utf-8", "xmlcharrefreplace") | ||||
|         if PY2: | ||||
|             ufn = [unicode(x) if x in bascii else "%{:02x}".format(ord(x)) for x in ufn] | ||||
| @@ -1329,6 +1327,7 @@ class HttpCli(object): | ||||
|  | ||||
|         cdis = "attachment; filename=\"{}.{}\"; filename*=UTF-8''{}.{}" | ||||
|         cdis = cdis.format(afn, fmt, ufn, fmt) | ||||
|         self.log(cdis) | ||||
|         self.send_headers(None, mime=mime, headers={"Content-Disposition": cdis}) | ||||
|  | ||||
|         fgen = vn.zipgen(rem, items, self.uname, dots, not self.args.no_scandir) | ||||
| @@ -1621,6 +1620,9 @@ class HttpCli(object): | ||||
|         if not dst: | ||||
|             raise Pebkac(400, "need dst vpath") | ||||
|  | ||||
|         # x-www-form-urlencoded (url query part) uses | ||||
|         # either + or %20 for 0x20 so handle both | ||||
|         dst = unquotep(dst.replace("+", " ")) | ||||
|         x = self.conn.hsrv.broker.put( | ||||
|             True, "up2k.handle_mv", self.uname, self.vpath, dst | ||||
|         ) | ||||
|   | ||||
| @@ -1468,10 +1468,10 @@ var fileman = (function () { | ||||
| 		if (r.clip === null) | ||||
| 			r.clip = jread('fman_clip', []); | ||||
|  | ||||
| 		var sel = msel.getsel(); | ||||
| 		clmod(bren, 'en', sel.length == 1); | ||||
| 		clmod(bdel, 'en', sel.length); | ||||
| 		clmod(bcut, 'en', sel.length); | ||||
| 		var nsel = msel.getsel().length; | ||||
| 		clmod(bren, 'en', nsel == 1); | ||||
| 		clmod(bdel, 'en', nsel); | ||||
| 		clmod(bcut, 'en', nsel); | ||||
| 		clmod(bpst, 'en', r.clip && r.clip.length); | ||||
| 		bren.style.display = have_mv && has(perms, 'write') && has(perms, 'move') ? '' : 'none'; | ||||
| 		bdel.style.display = have_del && has(perms, 'delete') ? '' : 'none'; | ||||
| @@ -3367,8 +3367,13 @@ var msel = (function () { | ||||
| 		ev(e); | ||||
| 		var names = r.getsel(), | ||||
| 			arg = ebi('selzip').getAttribute('fmt'), | ||||
| 			txt = names.join('\n'), | ||||
| 			frm = mknod('form'); | ||||
| 			frm = mknod('form'), | ||||
| 			txt = []; | ||||
|  | ||||
| 		for (var a = 0; a < names.length; a++) | ||||
| 			txt.push(names[a].name); | ||||
|  | ||||
| 		txt = txt.join('\n'); | ||||
|  | ||||
| 		frm.setAttribute('action', '?' + arg); | ||||
| 		frm.setAttribute('method', 'post'); | ||||
|   | ||||
| @@ -44,7 +44,7 @@ avg() { awk 'function pr(ncsz) {if (nsmp>0) {printf "%3s %s\n", csz, sum/nsmp} c | ||||
| dirs=("$HOME/vfs/ほげ" "$HOME/vfs/ほげ/ぴよ" "$HOME/vfs/$(printf \\xed\\x91)" "$HOME/vfs/$(printf \\xed\\x91/\\xed\\x92)") | ||||
| mkdir -p "${dirs[@]}" | ||||
| for dir in "${dirs[@]}"; do for fn in ふが "$(printf \\xed\\x93)" 'qwe,rty;asd fgh+jkl%zxc&vbn <qwe>"rty'"'"'uio&asd fgh'; do echo "$dir" > "$dir/$fn.html"; done; done | ||||
|  | ||||
| # qw er+ty%20ui%%20op<as>df&gh&jk#zx'cv"bn`m=qw*er^ty?ui@op,as.df-gh_jk | ||||
|  | ||||
| ## | ||||
| ## upload mojibake | ||||
|   | ||||
		Reference in New Issue
	
	Block a user