mirror of
				https://github.com/9001/copyparty.git
				synced 2025-10-30 20:22:20 -06:00 
			
		
		
		
	new flag nodupem: reject dupes on move; closes #742
This commit is contained in:
		
							parent
							
								
									9746b4e21e
								
							
						
					
					
						commit
						f55d8341f1
					
				|  | @ -1241,6 +1241,7 @@ def add_upload(ap): | ||||||
|     ap2.add_argument("--hardlink-only", action="store_true", help="do not fallback to symlinks when a hardlink cannot be made (volflag=hardlinkonly)") |     ap2.add_argument("--hardlink-only", action="store_true", help="do not fallback to symlinks when a hardlink cannot be made (volflag=hardlinkonly)") | ||||||
|     ap2.add_argument("--reflink", action="store_true", help="enable reflink-based dedup; will fallback on full copies when that is impossible (non-CoW filesystem) (volflag=reflink)") |     ap2.add_argument("--reflink", action="store_true", help="enable reflink-based dedup; will fallback on full copies when that is impossible (non-CoW filesystem) (volflag=reflink)") | ||||||
|     ap2.add_argument("--no-dupe", action="store_true", help="reject duplicate files during upload; only matches within the same volume (volflag=nodupe)") |     ap2.add_argument("--no-dupe", action="store_true", help="reject duplicate files during upload; only matches within the same volume (volflag=nodupe)") | ||||||
|  |     ap2.add_argument("--no-dupe-m", action="store_true", help="also reject dupes when moving a file into another volume (volflag=nodupem)") | ||||||
|     ap2.add_argument("--no-clone", action="store_true", help="do not use existing data on disk to satisfy dupe uploads; reduces server HDD reads in exchange for much more network load (volflag=noclone)") |     ap2.add_argument("--no-clone", action="store_true", help="do not use existing data on disk to satisfy dupe uploads; reduces server HDD reads in exchange for much more network load (volflag=noclone)") | ||||||
|     ap2.add_argument("--no-snap", action="store_true", help="disable snapshots -- forget unfinished uploads on shutdown; don't create .hist/up2k.snap files -- abandoned/interrupted uploads must be cleaned up manually") |     ap2.add_argument("--no-snap", action="store_true", help="disable snapshots -- forget unfinished uploads on shutdown; don't create .hist/up2k.snap files -- abandoned/interrupted uploads must be cleaned up manually") | ||||||
|     ap2.add_argument("--snap-wri", metavar="SEC", type=int, default=300, help="write upload state to ./hist/up2k.snap every \033[33mSEC\033[0m seconds; allows resuming incomplete uploads after a server crash") |     ap2.add_argument("--snap-wri", metavar="SEC", type=int, default=300, help="write upload state to ./hist/up2k.snap every \033[33mSEC\033[0m seconds; allows resuming incomplete uploads after a server crash") | ||||||
|  | @ -2079,7 +2080,7 @@ def main(argv: Optional[list[str]] = None) -> None: | ||||||
| 
 | 
 | ||||||
|     # propagate implications |     # propagate implications | ||||||
|     for k1, k2 in IMPLICATIONS: |     for k1, k2 in IMPLICATIONS: | ||||||
|         if getattr(al, k1): |         if getattr(al, k1, None): | ||||||
|             setattr(al, k2, True) |             setattr(al, k2, True) | ||||||
| 
 | 
 | ||||||
|     # propagate unplications |     # propagate unplications | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ def vf_bmap() -> dict[str, str]: | ||||||
|         "no_clone": "noclone", |         "no_clone": "noclone", | ||||||
|         "no_dirsz": "nodirsz", |         "no_dirsz": "nodirsz", | ||||||
|         "no_dupe": "nodupe", |         "no_dupe": "nodupe", | ||||||
|  |         "no_dupe_m": "nodupem", | ||||||
|         "no_forget": "noforget", |         "no_forget": "noforget", | ||||||
|         "no_pipe": "nopipe", |         "no_pipe": "nopipe", | ||||||
|         "no_robots": "norobots", |         "no_robots": "norobots", | ||||||
|  | @ -189,6 +190,7 @@ flagcats = { | ||||||
|         "safededup": "verify on-disk data before using it for dedup", |         "safededup": "verify on-disk data before using it for dedup", | ||||||
|         "noclone": "take dupe data from clients, even if available on HDD", |         "noclone": "take dupe data from clients, even if available on HDD", | ||||||
|         "nodupe": "rejects existing files (instead of linking/cloning them)", |         "nodupe": "rejects existing files (instead of linking/cloning them)", | ||||||
|  |         "nodupem": "rejects existing files during moves as well", | ||||||
|         "chmod_d=755": "unix-permission for new dirs/folders", |         "chmod_d=755": "unix-permission for new dirs/folders", | ||||||
|         "chmod_f=644": "unix-permission for new files", |         "chmod_f=644": "unix-permission for new files", | ||||||
|         "uid=573": "change owner of new files/folders to unix-user 573", |         "uid=573": "change owner of new files/folders to unix-user 573", | ||||||
|  |  | ||||||
|  | @ -4708,6 +4708,12 @@ class Up2k(object): | ||||||
|         if w: |         if w: | ||||||
|             assert c1  # !rm |             assert c1  # !rm | ||||||
|             if c2 and c2 != c1: |             if c2 and c2 != c1: | ||||||
|  |                 if "nodupem" in dvn.flags: | ||||||
|  |                     q = "select w from up where substr(w,1,16) = ?" | ||||||
|  |                     for (w2,) in c2.execute(q, (w[:16],)): | ||||||
|  |                         if w == w2: | ||||||
|  |                             t = "file exists in target volume, and dupes are forbidden in config" | ||||||
|  |                             raise Pebkac(400, t) | ||||||
|                 self._copy_tags(c1, c2, w) |                 self._copy_tags(c1, c2, w) | ||||||
| 
 | 
 | ||||||
|             xlink = bool(svn.flags.get("xlink")) |             xlink = bool(svn.flags.get("xlink")) | ||||||
|  |  | ||||||
|  | @ -358,6 +358,8 @@ IMPLICATIONS = [ | ||||||
|     ["hardlink_only", "hardlink"], |     ["hardlink_only", "hardlink"], | ||||||
|     ["hardlink", "dedup"], |     ["hardlink", "dedup"], | ||||||
|     ["tftpvv", "tftpv"], |     ["tftpvv", "tftpv"], | ||||||
|  |     ["nodupem", "nodupe"], | ||||||
|  |     ["no_dupe_m", "no_dupe"], | ||||||
|     ["smbw", "smb"], |     ["smbw", "smb"], | ||||||
|     ["smb1", "smb"], |     ["smb1", "smb"], | ||||||
|     ["smbvvv", "smbvv"], |     ["smbvvv", "smbvv"], | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ class Cfg(Namespace): | ||||||
|     def __init__(self, a=None, v=None, c=None, **ka0): |     def __init__(self, a=None, v=None, c=None, **ka0): | ||||||
|         ka = {} |         ka = {} | ||||||
| 
 | 
 | ||||||
|         ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only http_no_tcp ih ihead localtime log_badxml magic md_no_br nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_u2abrt no_zip no_zls nrand nsort nw og og_no_head og_s_title ohead opds q rand re_dirsz reflink rm_partial rmagic rss smb srch_dbg srch_excl srch_icase stats uqe usernames vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs" |         ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only http_no_tcp ih ihead localtime log_badxml magic md_no_br nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_dupe_m no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_u2abrt no_zip no_zls nrand nsort nw og og_no_head og_s_title ohead opds q rand re_dirsz reflink rm_partial rmagic rss smb srch_dbg srch_excl srch_icase stats uqe usernames vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs" | ||||||
|         ka.update(**{k: False for k in ex.split()}) |         ka.update(**{k: False for k in ex.split()}) | ||||||
| 
 | 
 | ||||||
|         ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump wram re_dhash see_dots plain_ip" |         ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump wram re_dhash see_dots plain_ip" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue