
    h2                       d dl mZmZ 	 dZdZdZdZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZddlmZmZmZmZmZmZmZmZmZmZmZ dd	lm Z m!Z!m"Z" dd
l#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJ ereKZL	 e
j                  j                  d      r eO       dZPd dlQZQeZRg ZS ej                         j                  dd ZVe
j                  j                  dd      gZWeWd    seWj                           G d dej                        ZZ G d deZ      Z[ G d dej                  ej                        Z^d Z_d Z`d Zad Zbd Zcd Zdd  Zed! Zfd" Zgd# ZhdRd$Zid% Zjd& Zkd' Zld( Zmd) Znd* Zod+ Zpd, Zqd- Zrd. Zsd/ Ztd0 Zud1 Zvd2 Zwd3 Zxd4 Zyd5 Zzd6 Z{d7 Z|d8 Z}d9 Z~d: Zd; Zd< Zd= Zd> Zd? Zd@ ZdA ZdB ZdC ZdD ZdE ZdF ZdG ZdH ZdI ZdJ ZdK ZdL ZdM ZdN Z	 dSdOZdTdPZedQk(  r e        yy#  dZPY RxY w)U    )print_functionunicode_literalszed <copyparty@ocv.me>i  MITz"https://github.com/9001/copyparty/N   )ANYWINCORESEXEMACOSPY2PY36VT100WINDOWSE	EnvParamsunicode)CODENAME
S_BUILD_DT	S_VERSION)expand_config_filesplit_cfg_lnupgrade_cfg_fmt)flagcatsonedash)SvcHub)APPLESAN_TXTBAD_BOTSDEF_EXPDEF_MTEDEF_MTH	HAVE_IPV6IMPLICATIONS	JINJA_VERMIMESPARTFTPY_VERPY_DESC
PYFTPD_VER	RAM_AVAIL	RAM_TOTALRE_ANSI
SQLITE_VERUNPLICATIONSURL_BUGURL_PRJDaemon	align_tabb64encdedenthas_resourceload_resourcemin_expybin	read_utf8termsizewrapPRTY_NO_TLSTF   PRTY_CONFIG c                   6     e Zd Z fdZd Zd Zd Zd Z xZS )RiceFormatterc                 X    t         rt               d   |d<   t        t        |   |i | y )Nr   width)r   r7   superr>   __init__selfargskwargs	__class__s      G/jellyfin/media/venv/lib/python3.12/site-packages/copyparty/__main__.pyrB   zRiceFormatter.__init__`   s)    &jmF7OmT+T<V<    c                 <   d}t         sd}t        |j                        }d|vr[|j                  t        j
                  ur?t        j                  t        j                  g}|j                  s|j                  |v r||z  }t         st        j                  dd|      }|S )z{
        same as ArgumentDefaultsHelpFormatter(HelpFormatter)
        except the help += [...] line now has colors
        z*[36m (default: [35m%(default)s[36m)[0mz (default: %(default)s)z
%(default)z\[[0-9;]+mr<   )r   r   helpdefaultargparseSUPPRESSOPTIONALZERO_OR_MOREoption_stringsnargsresub)rD   actionfmtretdefaulting_nargss        rH   _get_help_stringzRiceFormatter._get_help_stringf   s    
 G+Cfkk"s"~~X%6%66$,$5$5x7L7L#M ((FLL<L,L3JC&&*B4C
rI   c                 T    dj                  fd|j                         D              S )z2same as RawDescriptionHelpFormatter(HelpFormatter)r<   c              3   .   K   | ]  }|z   d z     yw)
N ).0lineindents     rH   	<genexpr>z+RiceFormatter._fill_text.<locals>.<genexpr>}   s     Jv}t+Js   )join
splitlines)rD   textr@   r`   s      `rH   
_fill_textzRiceFormatter._fill_text{   s    wwJ8IJJJrI   c                     |rd|z  |z   S |S )N r]   )rD   idxiWSpacerd   s       rH   __add_whitespacezRiceFormatter.__add_whitespace   s    ),g%6$6rI   c           
         |j                         }t        j                  d      }t        |      D ]  \  }}|j	                  |      }|j                         sd||<   -|s0|j                         }t        t        |||dz
              D 	
cg c]  \  }	}
| j                  |	||
       }}	}
|||<    |D cg c]  }|D ]  }|  c}}S c c}
}	w c c}}w )Nz\s*[0-9\-]{0,}\.?\s*rg   r   )	rc   rS   compile	enumeratesearchstripendr8   _RiceFormatter__add_whitespace)rD   rd   r@   textRowsptnrh   r_   rn   lWSpaceixlinessublistitems                 rH   _split_lineszRiceFormatter._split_lines   s    ??$jj01"8, 
	&ICZZ%F::< # **, !*$tUEAI*F G1 ))!Wa8  !&
	& %-AAAAA Bs   C9C)	__name__
__module____qualname__rB   rY   re   rq   rz   __classcell__rG   s   @rH   r>   r>   _   s    =*K7BrI   r>   c                        e Zd Z fdZ xZS )
Dodge11874c                 6    d|d<   t        t        | 
  |i | y Ni+#  r@   )rA   r   rB   rC   s      rH   rB   zDodge11874.__init__   s     wj$($9&9rI   r{   r|   r}   rB   r~   r   s   @rH   r   r      s    : :rI   r   c                        e Zd Z fdZ xZS )BasicDodge11874c                 6    d|d<   t        t        | 
  |i | y r   )rA   r   rB   rC   s      rH   rB   zBasicDodge11874.__init__   s     wot-t>v>rI   r   r   s   @rH   r   r      s    ? ?rI   r   c                      |j                  dd      }dj                  d | D              |z   }t        j                  |       t        st        j                  d|      }t        |fddi| y )Nrp   r\   rg   c              3   2   K   | ]  }t        |        y wN)r   )r^   rv   s     rH   ra   zlprint.<locals>.<genexpr>   s     *1GAJ*   r<   )poprb   printedappendr   r)   rT   print)akaeoltxts       rH   lprintr      s\    
&&
C88***S0CNN3kk"c"	#2rI   c                 8    t        dj                  |              y )Nz[1mwarning:[0;33m {}[0m
)r   format)msgs    rH   warnr      s    
299#>?rI   c                    | }d }t         j                  j                  t         j                  j                  t                    |_        |j
                  j                  d      r.t         j                  j                  |j
                        |_        	 t         j                  j                  d      }|s
t               |j                  d      rt         j                  j                  |      }t         j                  j                  t         j                  j                  |            }t         j                  j                  |d      }t         j                  j                  |      st        j                  |       t        j                   |       |r||_        nt$        j&                  dk(  rlt         j                  j                  d      xs# t         j                  j                  d	      xs d
}t         j                  j)                  |dz         |_        nDt$        j&                  dk(  r%t         j                  j                  d      |_        n |       |_        |j"                  j+                  dd      |_        	 t        j,                  |j"                         y #  d}Y xY w#  t         j                  j                  |j"                        s Y y xY w)Nc                      t         j                  j                  dft         j                  j                  dft         j                  j                  dft         j                  j                  dft         j                  j                  dft
        dfg} g }t         j                  t         j                  fD ]  }t        |       D ]  \  }\  }}d}	  ||      }|r|j                  d      r(t         j                  j                  |      } ||       t         j                  j                  |d	      }t         j                  j                  |      st        j                  |       |d
kD  rd}|j                  ||fz         n|r|j                  d|d       |rt        dj                  |             |c c S   t        d      # t        $ r*}|r|dk  rd}|j                  |||fz         Y d }~6d }~ww xY w)NXDG_CONFIG_HOMEz	~/.configTMPDIRTEMPTMPz/tmpr<   ~	copypartyr   zUsing [%s] for config; filekeys/dirkeys will change on every restart. Consider setting XDG_CONFIG_HOME or giving the unix-user a ~/.config/zUsing [z	] insteadz.    z(Unable to store config in [%s] due to %rz)could not find a writable path for config)osenvirongetpath
expanduserr   listdirmkdirrm   
startswithnormpathrb   isdirr   r   	Exception)	pathserrschknpathpfpaptexs	            rH   get_unixdirzinit_E.<locals>.get_unixdir   s   ZZ^^./WW-ZZ^^X&ZZ^^V$ZZ^^U#f
 JJ) 	1C#,U#3 1xB12AS 1 ((+AFQ4A77==+qy jAH-A$?@TYYt_-H/1	1< CDD ! 1UQYFABK01s   G
*CG

	G=G88G=rB   r   r   r   r<   win32APPDATAr   .z
/copypartydarwinz~/Library/Preferences/copyparty\/)r   r   dirnamerealpath__file__modendswithr   r   r   r   r   abspathrb   r   r   r   cfgsysplatformr   replacemakedirs)EEr   r   r   bdirs        rH   init_Er      s    	A(ET GGOOBGG,,X67AEuu~~j!&JJNN,-+<<""1%AGGOOBGG,,Q/0GGLLK(ww}}QHHQK


1 			 zz~~i(IBJJNN6,BIc  !45		!""#DEEEMM$$AE
AEEww}}QUU# $s   D J$ J. $J+.,Kc                    	 t        t        j                               j                  d      d   }|dvr|S t        j
                  j                  t        j                  d      }| rt        dj                  |             	 t        d |d      j                         S #  d}Y rxY w#  d}d}t        |      |k  rt|t        j                  t	        j                   d	            d d
 j#                  d      j%                         z  }t'        j(                  dd|      d | }t        |      |k  rtt+        |d      5 }|j-                  |j/                  d      dz          d d d        n# 1 sw Y   nxY w|cY S xY w)Nr   r   r<   )r<   	localhostzname.txtzusing hostname from {}
T   r:      utf-8z	[234567=]wb   
)r   socketgethostnamesplitr   r   rb   r   r   r   r   r6   ro   lenbase64	b32encodeurandomdecodelowerrS   rT   openwriteencode)verboserW   fpnamelenfs        rH   get_srvnamer     sN   v))+,2237: ##
	aeeZ	(B)0045
r4(..00#h 6##BJJqM22A6==gFLLNNC&&b#.x8C #h  "d^ 	1qGGCJJw'%/0	1 	1 	1
s6   /B B& B#&BE7.E7:$E'	E7'E0	,	E7c                 t   t         j                  j                  t        j                  | d      }	 t        d |d      j                         S #  t        t        j                  |            }t        |d      5 }|j                  |dz          d d d        n# 1 sw Y   nxY w|j                  d      cY S xY w)Nz	-salt.txtTr   r   r   )r   r   rb   r   r   r6   ro   r0   r   r   r   r   )namenbytesr   rW   r   s        rH   get_saltr     s    	aeed4	5B#r4(..00#RZZ'("d^ 	!qGGC%K 	! 	! 	!zz'""s#   A ,B7:B	B7B!	B7c                     t         rt        ry d} | ddfD ]G  }	 t        j                  t        j                  |       || k7  rt        dj                  |              y  d}t        |j                  |              y #  Y kxY w)Nzen_US.UTF-8zEnglish_United States.UTF8zEnglish_United States.1252zLocale: {}
z9setlocale {} failed,
  sorting and dates might get funky
)r   r   locale	setlocaleLC_ALLr   r   r   )saferv   r   s      rH   ensure_localer   )  s    #D$$ 
	V]]A.Dy~,,Q/0 	FA$		s   AA<<B c                  Z    t        t        d      ry d} t        | t        t        fz         y )Nzweb/deps/mini-fa.woffav  could not find webdeps;
  if you are running the sfx, or exe, or pypi package, or docker image,
  then this is a bug! Please let me know so I can fix it, thanks :-)
  %s

  however, if you are a dev, or running copyparty from source, and you want
  full client functionality, you will need to build or obtain the webdeps:
  %s/blob/hovudstraum/docs/devnotes.md#building
    )r2   r   r   r,   r-   )r   s    rH   ensure_webdepsr   ?  s+    A./	A 	gw	 rI   c                 "   d }t        j                  d      } || j                        j                  d      }t        j
                  D cg c]  }|j                  |      s| }}d|v rY|D cg c]  } ||dd         }}dj                  t        |      dgz         }t        d|z          t        j                  d	       d	| _        d	| _        t        |      D ]L  }	 ||	dd        }
t        t        |	      }|
|v r| xj                  |z  c_        8| xj                  |z  c_        N |dgk(  r$| j                  }| j                  | _        || _        d
D ])  }t        | |      }t        dj                  ||             + y c c}w c c}w )Nc                 x    | j                         } dD ]  }| j                  |d      }  | j                  dd      S )N)_vr   r<   tls10tls1)r   r   )r   cs     rH   terse_sslverz'configure_ssl_ver.<locals>.terse_sslverP  s?    iik  	%A++a$C	% {{7F++rI   z^OP_NO_(TLS|SSL)v,rK      rg   allz
available ssl/tls versions:
  r   )ssl_flags_enssl_flags_dez{0}: {1:8x} ({1}))rS   rl   ssl_verr   ssl__dict__matchrb   sortedr   r   exitr   r   getattrr   )alr   rs   sslverkflagsrv   avail1availflagvernums               rH   configure_ssl_verr  O  sk   , **)
*C"**%++C0F51		!Q5E5/45!,qu%555'122U:;BOBOu #48$c4 &=OOs"OOOs"O# %OO//- 3b!n"))!S123/ 6 6s   F#F1Fc                    t        j                  t         j                  j                        }| j                  r?|xj
                  | j                   z  c_        |xj
                  | j                  z  c_        | j                  dk(  }| j                  r|s	 |j                  | j                         t        |d      st        d       nK|j                         D cg c]  }|d   	 }}t        dj                  dgt        |      z   dgz                |rt        j                   d	       y y #  t        d       Y xY wc c}w )
NrK   z"
[1;31mfailed to set ciphers[0m
get_ciphersz2cannot read cipher list: openssl or python too olddescriptionz
  z
enabled ciphers:r<   r   )r   create_default_contextPurposeCLIENT_AUTHr   optionsr   r   ciphersset_ciphersr   hasattrr  rb   r/   r   r  )r  ctxis_helprv   r  s        rH   configure_ssl_ciphersr  z  s    

$
$S[[%<%<
=C	zz''r&jjF"G	zz'	AOOBJJ' 3&CD-0__->?1]#??v{{01Ig4FF"MNO 	A?@
 @s   D. E .D=c                 D   g }t        d || d       t        d t        j                  d      |d      }g }d}|D ]  }|j	                  d      d   j                         }|j                  d      rd}|j                  d      rd}L|s"|j	                  d	      d   j                         sqt        |      j                         D ]X  \  }}|j                  d
      }|s|t        v rd
nd}|du r|j                  ||z          ?|j                  ||z   dz   |z          Z  |S )Nr<   F)vcTz  #r   [z[global]#-z--=)r   r   rM   	Namespacer   ro   r   r   itemslstripr   r   )	cfg_pathrw   rW   skiplnsnr  r   prefixs	            rH   args_from_cfgr(    s    EtUHb1D("4"4">rJECD 1XXe_Q%%'==D==$Drxx}Q'--/ $**, 	1DAqALSdFDy

6A:&

6A:+a/0	11& JrI   c                 V   dgdz  }t        j                         D ]a  }t        j                         |j                     }|j                  t        |             |j                  t        j                  |             c |j                  d       t        dj                  |             y )Nr<   r   r\   )	threadingrm   r   _current_framesidentr   strextend	tracebackformat_stackr   rb   )sigframer   thstks        rH   
sighandlerr5    s    $(C!!# 0!!#BHH-

3r7

9))#./0
 JJt	$))C.rI   c                    	
 dd l } dd l	ddlm 	fd}	j                  t	        d      d      
t
        r 	j                  j                        _        |
j                  _
        |
j                  _
        |
j                  _
        j                  j                  f
j                  _        j                  j                  f
j                  _        d	
fd	} |d      x}}d	}d
}||z   }||z  |k7  r#| j                  |d|        |d|| z  |z         t         r3 |d      x}}|dz  dk7  r | j                  |d|        |d|dz         y y y )Nr   )wintypesc                 R    | s#j                         }|rj                  |      |S r   )get_last_errorWinError)okfunrE   errctypess       rH   ecbzdisable_quickedit.<locals>.ecb  s+    ((*Cooc**rI   kernel32T)use_last_errorc                     j                  | rdnd      }|rj                  ||      S j                         }j                  |j	                  |             |j
                  S )Nii)GetStdHandleSetConsoleModeDWORDGetConsoleModebyrefvalue)outmodehcmoder>  k32r7  s       rH   rL  z disable_quickedit.<locals>.cmode  s\    CSS1%%a.. 1fll512{{rI   F@      r:   r   )atexitr>  r7  WinDLLr-  r   POINTERrE  LPDWORDrC  errcheckrF  rD  HANDLEargtypesregisterr   )rP  r?  rL  rJ  orig_in	quickeditextendedmaskorig_outr>  rM  r7  s            @@@rH   disable_quickeditr]    sC    --J-
=C
!>>(..9 #C"%C"%C#+??H4D4D"EC#+??HNN"CC 5\!D7IHxDd{hug.eTTE\H,- +%x!8q=OOE42$q!  rI   c                 .   t         j                  j                  d      ry | gt        j                  |       D cg c]0  \  }}}||z   D ]"  }t         j                  j                  ||      $ 2 c}}}}z   }	 t        t        j                               }t        |      D ]  }	 t        j                  |||f        t        j                  d       \c c}}}}w # t        $ r,}t        d|d|       |j                  |       Y d }~ld }~ww xY w)NPRTY_NO_TPOKEz	<TPOKE> [z] i+1 )r   r   r   walkr   rb   inttimelistutimer   r   removesleep)	topdpdddfr   filesr   r   r   s	            rH   	sfx_tpokerl    s    	zz~~o&E.0ggcl  *BBG?@R E 		e 	 A QF#	  	

5    Ar23Q s   5C'C	D("DDc                      	 t        t        d      5 } | j                         }d d d        rt        |j	                  dd             y t        d       y # 1 sw Y   3xY w#  d}Y <xY w)Nzres/COPYING.txtrI   r   r   z#no relevant license info to display)r3   r   readr   r   )r   bufs     rH   showlicrp    sc    1/0 	A&&(C	
 cjj),-34	 	s!   A! AA! AA! !A'c                  p   ddt        d      gddt        d      gddt        d	      j                         t               z   gd
dt        d      gddt        d      gddt        d      gddt        d      gddt        d      gddt        d      gddt        d      gdd t        d!      gd"d#t        d$      ggS )%Nbindzconfigure listeninga-  
            [33m-i[0m takes a comma-separated list of interfaces to listen on;
            IP-addresses, unix-sockets, and/or open file descriptors

            the default ([32m-i ::[0m) means all IPv4 and IPv6 addresses

            [32m-i 0.0.0.0[0m    listens on all IPv4 NICs/subnets
            [32m-i 127.0.0.1[0m  listens on IPv4 localhost only
            [32m-i 127.1[0m      listens on IPv4 localhost only
            [32m-i 127.1,192.168.123.1[0m = IPv4 localhost and 192.168.123.1

            [33m-p[0m takes a comma-separated list of tcp ports to listen on;
            the default is [32m-p 3923[0m but as root you can [32m-p 80,443,3923[0m

            when running behind a reverse-proxy, it's recommended to
            use unix-sockets for improved performance and security;

            [32m-i unix:770:www:[33m/dev/shm/party.sock[0m listens on
            [33m/dev/shm/party.sock[0m with permissions [33m0770[0m;
            only accessible to members of the [33mwww[0m group.
            This is the best approach. Alternatively,

            [32m-i unix:777:[33m/dev/shm/party.sock[0m sets perms [33m0777[0m so anyone
            can access it; bad unless it's inside a restricted folder

            [32m-i unix:[33m/dev/shm/party.sock[0m keeps umask-defined permission
            (usually [33m0600[0m) and the same user/group as copyparty

            [32m-i fd:[33m3[0m uses the socket passed to copyparty on file descriptor 3

            [33m-p[0m (tcp ports) is ignored for unix-sockets and FDs
            accountszaccounts and volumesa  
            -a takes username:password,
            -v takes src:dst:[33mperm[0m1:[33mperm[0m2:[33mperm[0mN:[32mvolflag[0m1:[32mvolflag[0m2:[32mvolflag[0mN:...
                * "[33mperm[0m" is "permissions,username1,username2,..."
                * "[32mvolflag[0m" is config flags to set on this volume

            --grp takes groupname:username1,username2,...
            and groupnames can be used instead of usernames in -v
            by prefixing the groupname with @

            list of permissions:
              "r" (read):   list folder contents, download files
              "w" (write):  upload files; need "r" to see the uploads
              "m" (move):   move files and folders; need "w" at destination
              "d" (delete): permanently delete files and folders
              "g" (get):    download files, but cannot see folder contents
              "G" (upget):  "get", but can see filekeys of their own uploads
              "h" (html):   "get", but folders return their index.html
              "." (dots):   user can ask to show dotfiles in listings
              "a" (admin):  can see uploader IPs, config-reload
              "A" ("all"):  same as "rwmda." (read/write/move/delete/admin/dotfiles)

            too many volflags to list here, see --help-flags

            example:[35m
              -a ed:hunter2 -v .::r:rw,ed -v ../inc:dump:w:rw,ed:c,nodupe  [36m
              mount current directory at "/" with
               * r (read-only) for everyone
               * rw (read+write) for ed
              mount ../inc at "/dump" with
               * w (write-only) for everyone
               * rw (read+write) for ed
               * reject duplicate files  [0m

            if no accounts or volumes are configured,
            current folder will be read/write for everyone

            consider the config file for more flexible account/volume management,
            including dynamic reload at runtime (and being more readable w)
            r  zlist of volflagsat  
            volflags are appended to volume definitions, for example,
            to create a write-only volume with the [33mnodupe[0m and [32mnosub[0m flags:
              [35m-v /mnt/inc:/inc:w[33m:c,nodupe[32m:c,nosub[0m

            if global config defines a volflag for all volumes,
            you can unset it for a specific volume with -flag
            handlersz$use plugins to handle certain eventsa9  
            usually copyparty returns a [33m404[0m if a file does not exist, and
            [33m403[0m if a user tries to access a file they don't have access to

            you can load a plugin which will be invoked right before this
            happens, and the plugin can choose to override this behavior

            load the plugin using --args or volflags; for example [36m
             --on404 ~/partyhandlers/not404.py
             -v .::r:c,on404=~/partyhandlers/not404.py
            [0m
            the file must define the function [35mmain(cli,vn,rem)[0m:
             [35mcli[0m: the copyparty HttpCli instance
             [35mvn[0m:  the VFS which overlaps with the requested URL
             [35mrem[0m: the remainder of the URL below the VFS mountpoint

            `main` must return a string; one of the following:

            > [32m"true"[0m: the plugin has responded to the request,
                and the TCP connection should be kept open

            > [32m"false"[0m: the plugin has responded to the request,
                and the TCP connection should be terminated

            > [32m"retry"[0m: the plugin has done something to resolve the 404
                situation, and copyparty should reattempt reading the file.
                if it still fails, a regular 404 will be returned

            > [32m"allow"[0m: should ignore the insufficient permissions
                and let the client continue anyways

            > [32m""[0m: the plugin has not handled the request;
                try the next plugin or return the usual 404 or 403

            [1;35mPS![0m the folder that contains the python file should ideally
              not contain many other python files, and especially nothing
              with filenames that overlap with modules used by copyparty
            hooksz,execute commands before/after various eventsu  
            execute a command (a program or script) before or after various events;
             [36mxbu[35m executes CMD before a file upload starts
             [36mxau[35m executes CMD after  a file upload finishes
             [36mxiu[35m executes CMD after  all uploads finish and volume is idle
             [36mxbc[35m executes CMD before a file copy
             [36mxac[35m executes CMD after  a file copy
             [36mxbr[35m executes CMD before a file rename/move
             [36mxar[35m executes CMD after  a file rename/move
             [36mxbd[35m executes CMD before a file delete
             [36mxad[35m executes CMD after  a file delete
             [36mxm[35m executes CMD on message
             [36mxban[35m executes CMD if someone gets banned
            [0m
            can be defined as --args or volflags; for example [36m
             --xau foo.py
             -v .::r:c,xau=bar.py
            [0m
            hooks specified as commandline --args are appended to volflags;
            each commandline --arg and volflag can be specified multiple times,
            each hook will execute in order unless one returns non-zero

            optionally prefix the command with comma-sep. flags similar to -mtp:

             [36mf[35m forks the process, doesn't wait for completion
             [36mc[35m checks return code, blocks the action if non-zero
             [36mj[35m provides json with info as 1st arg instead of filepath
             [36mwN[35m waits N sec after command has been started before continuing
             [36mtN[35m sets an N sec timeout before the command is abandoned
             [36miN[35m xiu only: volume must be idle for N sec (default = 5)

             [36mar[35m only run hook if user has read-access
             [36marw[35m only run hook if user has read-write-access
             [36marwmd[35m ...and so on... (doesn't work for xiu or xban)

             [36mkt[35m kills the entire process tree on timeout (default),
             [36mkm[35m kills just the main process
             [36mkn[35m lets it continue running until copyparty is terminated

             [36mc0[35m show all process output (default)
             [36mc1[35m show only stderr
             [36mc2[35m show only stdout
             [36mc3[35m mute all process otput
            [0m
            examples:

             [36m--xm some.py[35m runs [33msome.py msgtxt[35m on each 📟 message;
              [33mmsgtxt[35m is the message that was written into the web-ui

             [36m--xm j,some.py[35m runs [33msome.py jsontext[35m on each 📟 message;
              [33mjsontext[35m is the message info (ip, user, ..., msg-text)

             [36m--xm aw,j,some.py[35m requires user to have write-access

             [36m--xm aw,,notify-send,hey,--[35m shows an OS alert on linux;
              the [33m,,[35m stops copyparty from reading the rest as flags and
              the [33m--[35m stops notify-send from reading the message as args
              and the alert will be "hey" followed by the messagetext

             [36m--xau zmq:pub:tcp://*:5556[35m announces uploads on zeromq;
             [36m--xau t3,zmq:push:tcp://*:5557[35m also works, and you can
             [36m--xau t3,j,zmq:req:tcp://localhost:5555[35m too for example
            [0m
            each hook is executed once for each event, except for [36mxiu[0m
            which builds up a backlog of uploads, running the hook just once
            as soon as the volume has been idle for iN seconds (5 by default)

            [36mxiu[0m is also unique in that it will pass the metadata to the
            executed program on STDIN instead of as argv arguments, and
            it also includes the wark (file-id/hash) as a json property

            [36mxban[0m can be used to overrule / cancel a user ban event;
            if the program returns 0 (true/OK) then the ban will NOT happen

            effects can be used to redirect uploads into other
            locations, and to delete or index other files based
            on new uploads, but with certain limitations. See
            bin/hooks/reloc* and docs/devnotes.md#hook-effects

            except for [36mxm[0m, only one hook / one action can run at a time,
            so it's recommended to use the [36mf[0m flag unless you really need
            to wait for the hook to finish before continuing (without [36mf[0m
            the upload speed can easily drop to 10% for small files)urlformzhow to handle url-form POSTsa)  
            values for --urlform:
              [36mstash[35m dumps the data to file and returns length + checksum
              [36msave,get[35m dumps to file and returns the page like a GET
              [36mprint    [35m prints the data to log and returns an error
              [36mprint,xm [35m prints the data to log and returns --xm output
              [36mprint,get[35m prints the data to log and returns GET[0m

            note that the [35m--xm[0m hook will only run if [35m--urlform[0m is
              either [36mprint[0m or [36mprint,get[0m or the default [36mprint,xm[0m

            if an [35m--xm[0m hook returns text, then
              the response code will be HTTP 202;
              http/get responses will be HTTP 200

            if there are multiple [35m--xm[0m hooks defined, then
              the first hook that produced output is returned

            if there are no [35m--xm[0m hooks defined, then the default
              [36mprint,xm[0m behaves like [36mprint,get[0m (returning html)
            expztext expansiona  
            specify --exp or the "exp" volflag to enable placeholder expansions
            in README.md / PREADME.md / .prologue.html / .epilogue.html

            --exp-md (volflag exp_md) holds the list of placeholders which can be
            expanded in READMEs, and --exp-lg (volflag exp_lg) likewise for logues;
            any placeholder not given in those lists will be ignored and shown as-is

            the default list will expand the following placeholders:
            [36m{{self.ip}}     [35mclient ip
            [36m{{self.ua}}     [35mclient user-agent
            [36m{{self.uname}}  [35mclient username
            [36m{{self.host}}   [35mthe "Host" header, or the server's external IP otherwise
            [36m{{cfg.name}}    [35mthe --name global-config
            [36m{{cfg.logout}}  [35mthe --logout global-config
            [36m{{vf.scan}}     [35mthe "scan" volflag
            [36m{{vf.thsize}}   [35mthumbnail size
            [36m{{srv.itime}}   [35mserver time in seconds
            [36m{{srv.htime}}   [35mserver time as YY-mm-dd, HH:MM:SS (UTC)
            [36m{{hdr.cf_ipcountry}} [35mthe "CF-IPCountry" client header (probably blank)
            [0m
            so the following types of placeholders can be added to the lists:
            * any client header can be accessed through {{hdr.*}}
            * any variable in httpcli.py can be accessed through {{self.*}}
            * any global server setting can be accessed through {{cfg.*}}
            * any volflag can be accessed through {{vf.*}}

            remove vf.scan from default list using --exp-md /vf.scan
            add "accept" header to def. list using --exp-md +hdr.accept

            for performance reasons, expansion only happens while embedding
            documents into directory listings, and when accessing a ?doc=...
            link, but never otherwise, so if you click a -txt- link you'll
            have to refresh the page to apply expansion
            lszvolume inspectiona  
            [35m--ls USR,VOL,FLAGS
              [36mUSR[0m is a user to browse as; * is anonymous, ** is all users
              [36mVOL[0m is a single volume to scan, default is * (all vols)
              [36mFLAG[0m is flags;
                [36mv[0m in addition to realpaths, print usernames and vpaths
                [36mln[0m only prints symlinks leaving the volume mountpoint
                [36mp[0m exits 1 if any such symlinks are found
                [36mr[0m resumes startup after the listing

            examples:
              --ls '**'          # list all files which are possible to read
              --ls '**,*,ln'     # check for dangerous symlinks
              --ls '**,*,ln,p,r' # check, then start normally if safe
            dbdzdatabase durability profilesa  
            mainly affects uploads of many small files on slow HDDs; speeds measured uploading 520 files on a WD20SPZX (SMR 2.5" 5400rpm 4kb)

            [32macid[0m = extremely safe but slow; the old default. Should never lose any data no matter what

            [32mswal[0m = 2.4x faster uploads yet 99.9% as safe -- theoretical chance of losing metadata for the ~200 most recently uploaded files if there's a power-loss or your OS crashes

            [32mwal[0m = another 21x faster on HDDs yet 90% as safe; same pitfall as [33mswal[0m except more likely

            [32myolo[0m = another 1.5x faster, and removes the occasional sudden upload-pause while the disk syncs, but now you're at risk of losing the entire database in a powerloss / OS-crash

            profiles can be set globally (--dbd=yolo), or per-volume with volflags: -v ~/Music:music:r:c,dbd=acid
            chmodzfile/folder permissionsa)  
            global-option [33m--chmod-f[0m and volflag [33mchmod_f[0m specifies the unix-permission to use when creating a new file

            similarly, [33m--chmod-d[0m and [33mchmod_d[0m sets the directory/folder perm

            the value is a three-digit octal number such as [32m755[0m, [32m750[0m, [32m644[0m, etc.

            first digit = "User"; permission for the unix-user
            second digit = "Group"; permission for the unix-group
            third digit = "Other"; permission for all other users/groups

            for files:
            [32m0[0m = [35m---[0m = no access
            [32m1[0m = [35m--x[0m = can execute the file as a program
            [32m2[0m = [35m-w-[0m = can write
            [32m3[0m = [35m-wx[0m = can write and execute
            [32m4[0m = [35mr--[0m = can read
            [32m5[0m = [35mr-x[0m = can read and execute
            [32m6[0m = [35mrw-[0m = can read and write
            [32m7[0m = [35mrwx[0m = can read, write, execute

            for directories/folders:
            [32m0[0m = [35m---[0m = no access
            [32m1[0m = [35m--x[0m = can read files in folder but not list contents
            [32m2[0m = [35m-w-[0m = n/a
            [32m3[0m = [35m-wx[0m = can create files but not list
            [32m4[0m = [35mr--[0m = can list, but not read/write
            [32m5[0m = [35mr-x[0m = can list and read files
            [32m6[0m = [35mrw-[0m = n/a
            [32m7[0m = [35mrwx[0m = can read, write, list
            pwhashzpassword hashinga  
            when [36m--ah-alg[0m is not the default [[32mnone[0m], all account passwords must be hashed

            passwords can be hashed on the commandline with [36m--ah-gen[0m, but
            copyparty will also hash and print any passwords that are non-hashed
            (password which do not start with '+') and then terminate afterwards

            if you have enabled --usernames then the password
            must be provided as username:password for hashing

            [36m--ah-alg[0m specifies the hashing algorithm and a
               list of optional comma-separated arguments:

            [36m--ah-alg argon2[0m  # which is the same as:
            [36m--ah-alg argon2,3,256,4,19[0m
            use argon2id with timecost 3, 256 MiB, 4 threads, version 19 (0x13/v1.3)

            [36m--ah-alg scrypt[0m  # which is the same as:
            [36m--ah-alg scrypt,13,2,8,4,32[0m
            use scrypt with cost 2**13, 2 iterations, blocksize 8, 4 threads,
              and allow using up to 32 MiB RAM (ram=cost*blksz roughly)

            [36m--ah-alg sha2[0m  # which is the same as:
            [36m--ah-alg sha2,424242[0m
            use sha2-512 with 424242 iterations

            recommended: [32m--ah-alg argon2[0m
              (takes about 0.4 sec and 256M RAM to process a new password)

            argon2 needs python-package argon2-cffi,
            scrypt needs openssl,
            sha2 is always available
            zmzmDNS debuggingaG  
            the mDNS protocol is multicast-based, which means there are thousands
            of fun and interesting ways for it to break unexpectedly

            things to check if it does not work at all:

            * is there a firewall blocking port 5353 on either the server or client?
              (for example, clients may be able to send queries to copyparty,
               but the replies could get lost)

            * is multicast accidentally disabled on either the server or client?
              (look for mDNS log messages saying "new client on [...]")

            * the router/switch must be multicast and igmp capable

            things to check if it works for a while but then it doesn't:

            * is there a firewall blocking port 5353 on either the server or client?
              (copyparty may be unable to see the queries from the clients, but the
               clients may still be able to see the initial unsolicited announce,
               so it works for about 2 minutes after startup until TTL expires)

            * does the client have multiple IPs on its interface, and some of the
              IPs are in subnets which the copyparty server is not a member of?

            for both of the above intermittent issues, try --zm-spam 30
            (not spec-compliant but nothing will mind)
            )r1   rstripbuild_flags_descr]   rI   rH   	get_sectsr    sf    !!%	
N "')-	
^ 	 fh 
!	
  2%'+	
Z :RHTX	
t *	
8 "$(	
T 	
, *	
( % $	
L  "&	
P !	
CC CrI   c                      d} t        j                         D ]L  \  }}| d|z   z  } |j                         D ],  \  }}|j                  dd      }| dj                  ||      z  } . N | S )Nr<   z

[0mr\   z
    z
  [36m{}[35m {})r   r!  r   r   )rW   grpr  r  r   s        rH   r~  r~    sx    
Cnn& <
U}s""KKM 	<DAq		$)A.55a;;C	<< JrI   c                 (   | j                  d      }|j                  ddt        t        dd       |j                  ddt        |d	
       |j                  ddt        dd
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddd       |j                  ddd       |j                  dd t        d!d"
       |j                  d#d$t        d%d&
       |j                  d'd$t        |d(
       |j                  d)d*t        dd+       |j                  d,dd-       |j                  d.dd/       |j                  d0dd1       |j                  d2dd3       y )4Nzgeneral options-cPATHr   z$[34mREPEATABLE:[0m add config file)metavartyperL   rU   rK   z-ncNUMzmax num clientsr  r  rL   rK   z-jr   r   zmax num cpu cores, 0=allz-aACCTzY[34mREPEATABLE:[0m add account, [33mUSER[0m:[33mPASS[0m; example [[32med:wark[0m]r  r  rU   rK   z-vVOLz[34mREPEATABLE:[0m add volume, [33mSRC[0m:[33mDST[0m:[33mFLAG[0m; examples [[32m.::r[0m], [[32m/mnt/nas/music:/music:r:aed[0m], see --help-accountsz--grpzG:N,Nz~[34mREPEATABLE:[0m add group, [33mNAME[0m:[33mUSER1[0m,[33mUSER2[0m,[33m...[0m; example [[32madmins:ed,foo,bar[0m]z--usernames
store_truezArequire username and password for login; default is just passwordrU   rK   z-edzqenable the ?dots url parameter / client option which allows clients to see dotfiles / hidden files (volflag=dots)z	--urlformMODEzprint,xmz9how to handle url-form POSTs; see [33m--help-urlform[0mz
--wintitleTXTz
cpp @ $pubzHserver terminal title, for example [[32m$ip-10.1.2.[0m] or [[32m$ip-]--namez6server name (displayed topleft in browser and in mDNS)z--mimezEXT=MIMEzl[34mREPEATABLE:[0m map file [33mEXT[0mension to [33mMIME[0mtype, for example [[32mjpg=image/jpeg[0m]--mimesz&list default mimetype mapping and exitz--rmagiczdo expensive analysis to improve accuracy of returned mimetypes; will make file-downloads, rss, and webdav slower (volflag=rmagic)	--licensezshow licenses and exit	--versionzshow versions and exit)add_argument_groupadd_argumentuCFG_DEFra  )apncsrvnameap2s       rH   add_generalr    s   


 1
2CT678  [G  HUERFWXT7aF`aT6(  J}  ~T5q  IN  OWgAh  Nr  s]<  ?B  CU<  7j  k[&q*  TU  V\5q,  Vi  jXu1g  ME  FXz(  RX  YY|:bcZ  <@  A[<TU[<TUrI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  dd	t        d
d       |j                  ddt        d
d       |j                  ddt        |rdndd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       y )Nz
qr options--qrr  zshow http:// QR-code on startupr  z--qrsz show https:// QR-code on startupz--qrlr  r<   zGlocation to include in the url, for example [[32mpriv/?pw=hunter2[0m]r  z--qriPREFIXzxselect IP which starts with [33mPREFIX[0m; [[32m.[0m] to force default IP when mDNS URL would have been used insteadz--qr-fgCOLORr      z9foreground; try [[32m0[0m] if the qr-code is unreadablez--qr-bg   zbackground (white=255)z--qrpCELLSr:   z4padding (spec says 4 or more, but 1 is usually fine)z--qrzNzV[[32m1[0m]=1x, [[32m2[0m]=2x, [[32m0[0m]=auto (try [[32m2[0m] on broken fonts)r  r  r  ra  )r  ttyr  s      rH   add_qrr    s    



-CVL7XYW\8Z[Wf1b  HW  XWhQ  JP  QYc1QS  [\  ]Yc3MefWgCI  AWcQ  Fv  wrI   c                 
   | j                  d      }t        rdnd}|j                  ddt        |d       |j                  ddt        |d	       |j                  d
dt        dd       |j                  ddt        dd       y )Nzfilesystem optionsz15/0.1z0/0z
--rm-retryzT/Rzif a file cannot be deleted because it is busy, continue trying for [33mT[0m seconds, retry every [33mR[0m seconds; disable with 0/0 (volflag=rm_retry)r  z
--mv-retryzif a file cannot be renamed because it is busy, continue trying for [33mT[0m seconds, retry every [33mR[0m seconds; disable with 0/0 (volflag=mv_retry)z--iobufBYTES   zfile I/O buffer-size; if your volumes are on a network drive, try increasing to [32m524288[0m or even [32m4194304[0m (and let me know if that improves your performance)z
--mtab-ageSEC<   z{rebuild mountpoint cache every [33mSEC[0m to keep track of sparse-files support; keep low on servers with removable media)r  r   r  r  ra  )r  r  	rm_re_defs      rH   add_fsr     s    


 4
5C"I\5q)  S|  }\5q)  S|  }Yc8  SM  N\5sB  NQ  RrI   c                 z   t         j                  j                  t        j                  d      }| j                  d      }|j                  ddt        dd       |j                  dd	t        |d
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddd       y )Nz	shares.dbzshare-url optionsz--shrDIRr<   zOtoplevel virtual folder for shared files/folders, for example [[32m/share[0m]r  z--shr-dbFILEzdatabase to store shares inz	--shr-admU,Uz>comma-separated list of users allowed to view/delete any sharez--shr-rtMINi  zshares can be revived by their owner if they expired less than MIN minutes ago; [[32m60[0m]=hour, [[32m1440[0m]=day, [[32m10080[0m]=weekz--shr-vr  debugr  	r   r   rb   r   r   r  r  r  ra  r  db_pathr  s      rH   	add_sharer  	  s    ggll155+.G


 3
4CWe!R  G^  _ZaOlm[%a  KK  LZS$  Np  qY|'BrI   c                 6   | j                  d      }|j                  ddd       |j                  ddd       |j                  dd	t        d
d       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        d d!       |j                  d"dd#       |j                  d$dd%       |j                  d&d't        d(d)       |j                  d*d't        d+d,       |j                  d-dt        d.d/       |j                  d0dt        d.d1       |j                  d2dd3       |j                  d4dt        d5d6       |j                  d7dd8       |j                  d9dd:       |j                  d;dd<       |j                  d=dd>       |j                  d?dd@       |j                  dAddB       |j                  dCdt        ddD       |j                  dEdFt        dGdH       |j                  dId	t        dJdK       |j                  dLddM       |j                  dNdt        dOdP       |j                  dQddR       |j                  dSdTt        dUdV       |j                  dWdXt        dYdZ       |j                  d[d\t        d]d^       |j                  d_dt        d]d`       |j                  dadbt        dcdd       |j                  dedft        dgdh       |j                  didt        d]dj       |j                  dkd	t        dldm       |j                  dnddo       y )pNzupload optionsz	--dotpartr  zHdotfile incomplete uploads, hiding them from clients unless [33m-ed[0mr  z
--plain-ipzwhen avoiding filename collisions by appending the uploader's ip to the filename: append the plaintext ip instead of salting and hashing the ipz
--put-namer  zput-{now.6f}-{cip}.binzfilename for nameless uploads (when uploader doesn't provide a name); default is [[32mput-UNIXTIME-IP.bin[0m] (the [32m.6f[0m means six decimal places) (volflag=put_name)r  z--put-ckALGsha512zdefault checksum-hasher for PUT/WebDAV uploads: no / md5 / sha1 / sha256 / sha512 / b2 / blake2 / b2s / blake2s (volflag=put_ck)z--bup-ckzdefault checksum-hasher for bup/basic-uploader: no / md5 / sha1 / sha256 / sha512 / b2 / blake2 / b2s / blake2s (volflag=bup_ck)z--unpostr    zsgrace period where uploads can be deleted by the uploader, even without delete permissions; 0=disabled, default=12hz	--u2abortr  r   a=  clients can abort incomplete uploads by using the unpost tab (requires [33m-e2d[0m). [[32m0[0m] = never allowed (disable feature), [[32m1[0m] = allow if client has the same IP as the upload AND is using the same account, [[32m2[0m] = just check the IP, [[32m3[0m] = just check account-name (volflag=u2abort)z
--blank-wt,  zxfile write grace period (any client can write to a blank file last-modified more recently than [33mSEC[0m seconds ago)z	--reg-capr  i   zemax number of uploads to keep in memory when running without [33m-e2d[0m; roughly 1 MiB RAM per 600z
--no-fpoolzdisable file-handle pooling -- instead, repeatedly close and reopen files during upload (bad idea to enable this on windows and/or cow filesystems)z--use-fpoolz{force file-handle pooling, even when it might be dangerous (multiprocessing, filesystems lacking sparse-files support, ...)z	--chmod-fUGOr<   zunix file permissions to use when creating files; default is probably 644 (OS-decided), see --help-chmod. Examples: [[32m644[0m] = owner-RW + all-R, [[32m755[0m] = owner-RWX + all-RX, [[32m777[0m] = full-yolo (volflag=chmod_f)z	--chmod-d755zunix file permissions to use when creating directories; see --help-chmod. Examples: [[32m755[0m] = owner-RW + all-R, [[32m777[0m] = full-yolo (volflag=chmod_d)z--uidzVunix user-id to chown new files/folders to; default = -1 = do-not-change (volflag=uid)z--gidzWunix group-id to chown new files/folders to; default = -1 = do-not-change (volflag=gid)z--dedupz9enable symlink-based upload deduplication (volflag=dedup)z--safe-dedup2   zhow careful to be when deduplicating files; [[32m1[0m] = just verify the filesize, [[32m50[0m] = verify file contents have not been altered (volflag=safededup)z
--hardlinkzvenable hardlink-based dedup; will fallback on symlinks when that is impossible (across filesystems) (volflag=hardlink)--hardlink-onlyzQdo not fallback to symlinks when a hardlink cannot be made (volflag=hardlinkonly)z	--reflinkzwenable reflink-based dedup; will fallback on full copies when that is impossible (non-CoW filesystem) (volflag=reflink)z	--no-dupezZreject duplicate files during upload; only matches within the same volume (volflag=nodupe)z
--no-clonezdo not use existing data on disk to satisfy dupe uploads; reduces server HDD reads in exchange for much more network load (volflag=noclone)z	--no-snapzdisable snapshots -- forget unfinished uploads on shutdown; don't create .hist/up2k.snap files -- abandoned/interrupted uploads must be cleaned up manuallyz
--snap-wrizzwrite upload state to ./hist/up2k.snap every [33mSEC[0m seconds; allows resuming incomplete uploads after a server crashz--snap-dropr  g     @zmforget unfinished uploads after [33mMIN[0m minutes; impossible to resume them after that (360=6h, 1440=24h)z--u2tsr   zhow to timestamp uploaded files; [[32mc[0m]=client-last-modified, [[32mu[0m]=upload-time, [[32mfc[0m]=force-c, [[32mfu[0m]=force-u (volflag=u2ts)z--randzFforce randomized filenames, [33m--nrand[0m chars long (volflag=rand)z--nrand	   z+randomized filenames length (volflag=nrand)z--magicz=enable filetype detection on nameless uploads (volflag=magic)z--dfGiB0zensure [33mGiB[0m free disk space by rejecting upload requests; assumes gigabytes unless a unit suffix is given: [[32m256m[0m], [[32m4[0m], [[32m2T[0m] (volflag=df)z--sparseMiBr:   zbwindows-only: minimum size of incoming uploads through up2k before they are made into sparse filesz--turboLVLr   zconfigure turbo-mode in up2k client; [[32m-1[0m] = forbidden/always-off, [[32m0[0m] = default-off and warn if enabled, [[32m1[0m] = default-off, [[32m2[0m] = on, [[32m3[0m] = on and disable datecheckz
--nosubtleaQ  when to use a wasm-hasher instead of the browser's builtin; faster on chrome, but buggy in older chrome versions. [[32m0[0m] = only when necessary (non-https), [[32m1[0m] = always (all browsers), [[32m2[0m] = always on chrome/firefox, [[32m3[0m] = always on chrome, [[32mN[0m] = chrome-version N and newer (recommendation: 137)z--u2jJOBSr   zweb-client: number of file chunks to upload in parallel; 1 or 2 is good when latency is low (same-country), 2~4 for android-clients, 2~6 for cross-atlantic. Max is 6 in most browsers. Big values increase network-speed but may reduce HDD-speedz--u2szzN,N,Nz1,64,96aG  web-client: default upload chunksize (MiB); sets [33mmin,default,max[0m in the settings gui. Each HTTP POST will aim for [33mdefault[0m, and never exceed [33mmax[0m. Cloudflare max is 96. Big values are good for cross-atlantic but may increase HDD fragmentation on some FS. Disable this optimization with [[32m1,1,1[0m]z--u2owzweb-client: default setting for when to replace/overwrite existing files; [[32m0[0m]=never, [[32m1[0m]=if-client-newer, [[32m2[0m]=always (volflag=u2ow)--u2sortszupload order; [[32ms[0m]=smallest-first, [[32mn[0m]=alphabetical, [[32mfs[0m]=force-s, [[32mfn[0m]=force-n -- alphabetical is a bit slower on fiber/LAN but makes it easier to eyeball if everything went finez--write-uplogz4write POST reports to textfiles in working-directory)r  r  r  ra  floatr  r  s     rH   
add_uploadr    s   


 0
1C[  =M  N\,  >O  P\5qBZ  b^  _ZQ  PR  SZQ  PR  SZS'  QF  G[%c1  Li  j\5sC  OO  P[#C  N{  |\,  >S  T]<  ?|  }[%a  KG  H[%a  N  @WcR  G_  `WcR  G`  aY|:uv^SsB  N  @\,  >v  w&|  CV  W[  =v  w[  =Y  Z\,  >K  L[  =Z  [\5sC  OQ  R]Ev  UJ  KXu1c  I|  }Xl  :H  IYCIvwY|:yzVUC  GM  NZS!  Ko  pYC  J{  |\3S!  K|  }Wf3  I}  ~XwQ	  Qr  sXu3  I{  |ZQ  K{  |_\@vwrI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        d	d
       |j                  ddd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd        t        r|j                  d!dd"       nt
        s|j                  d#dd$       |j                  d%dt        dd&       |j                  d'dt        dd(       |j                  d)d*t        d+d,       |j                  d-d*t        d.d/       |j                  d0d1t        d2d3       |j                  d4d1t        d2d5       |j                  d6d*t        d7d8       |j                  d9d*t        d7d:       |j                  d;d*t        d7d<       y )=Nznetwork optionsz-iIP::zqIPs and/or unix-sockets to listen on (comma-separated list; see [33m--help-bind[0m). Default: all IPv4 and IPv6r  z-pPORT3923z:ports to listen on (comma/range); ignored for unix-socketsz--llr  ziinclude link-local IPv4/IPv6 in mDNS replies, even if the NIC has routable IPs (breaks some mDNS clients)r  z--rproxyDEPTHi zwhich ip to associate clients with; [[32m0[0m]=tcp, [[32m1[0m]=origin (first x-fwd, unsafe), [[32m-1[0m]=closest-proxy, [[32m-2[0m]=second-hop, [[32m-3[0m]=third-hopz	--xff-hdrNAMEzx-forwarded-forzGif reverse-proxied, which http header to read the client's real ip fromz	--xff-srcCIDRz127.0.0.0/8, ::1/128a  list of trusted reverse-proxy CIDRs (comma-separated); only accept the real-ip header ([33m--xff-hdr[0m) and IdP headers if the incoming connection is from an IP within either of these subnets. Specify [[32mlan[0m] to allow all LAN / private / non-internet IPs. Can be disabled with [[32many[0m] if you are behind cloudflare (or similar) and are using [32m--xff-hdr=cf-connecting-ip[0m (or similar)z--ipar<   zonly accept connections from IP-addresses inside [33mCIDR[0m (comma-separated); examples: [[32mlan[0m] or [[32m10.89.0.0/16, 192.168.33.0/24[0m]z--rp-locr  zif reverse-proxying on a location instead of a dedicated domain/subdomain, provide the base location here; example: [[32m/foo/bar[0m]z--reuseaddrzset reuseaddr on listening sockets on windows; allows rapid restart of copyparty at the expense of being able to accidentally start multiple instancesz
--freebindzallow listening on IPs which do not yet exist, for example if the network interfaces haven't finished going up. Only makes sense for IPs other than '0.0.0.0', '127.0.0.1', '::', and '::1'. May require running as root (unless net.ipv6.ip_nonlocal_bind)z
--wr-h-epsz^write list of listening-on ip:port to textfile at [33mPATH[0m when http-servers have startedz
--wr-h-aonz_write list of accessible-on ip:port to textfile at [33mPATH[0m when http-servers have startedz	--s-theadr  x   z$socket timeout (read request header)z	--s-tbodyg      `@zsocket timeout (read/write request/response bodies). Use 60 on fast servers (default is extremely safe). Disable with 0 if reverse-proxied for a 2%% speed boostz	--s-rd-szBr  z~socket read size in bytes (indirectly affects filesystem writes; recommendation: keep equal-to or lower-than [33m--iobuf[0m)z	--s-wr-szzsocket write size in bytesz
--s-wr-slp        z$debug: socket write delay in secondsz	--rsp-slpz debug: response delay in secondsz	--rsp-jtrz6debug: response delay, random duration 0..[33mSEC[0m)r  r  r  ra  r   r
   r  r  s     rH   add_networkr  =  se   


 1
2CT4a  E~  T66  IE  FVL  8c  dZsG  Sb  c[&qBS  [d  e[&qBX  `P  QWf1b  Hr  sZa  KZ  [|  C[  	\l  B  	@\62  Ms  t\62  Mt  u[%c3Mst[%eU  Rt  u[#C  QW  X[#CPlm\5ucPvw[%eSOqr[%eS  PN  OrI   c                 n   | j                  d      }|j                  ddd       |j                  ddd       |j                  dd	t        |d
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddd       |j                  dd	t        dd       y )NzSSL/TLS optionsz--http-onlyr  z"disable ssl/tls -- force plaintextr  z--https-onlyzdisable plaintext -- force tlsz--certr  zHpath to file containing a concatenation of TLS key and certificate chainr  z	--ssl-verLISTr<   zzset allowed ssl/tls versions; [[32mhelp[0m] shows available versions; default is what your python version considers safez	--cipherszDset allowed ssl/tls ciphers; [[32mhelp[0m] shows available ciphersz	--ssl-dbgzdump some tls infoz	--ssl-logz4log master secrets for later decryption in wiresharkr  r  r  )r  	cert_pathr  s      rH   add_tlsr  V  s    


 1
2C]<>bc^L?_`XvAy  PZ  [[&q"  LN  O[&q"  LX  Y[<PQ[&q"  LB  CrI   c                    t         j                  j                  |      }| j                  d      }|j	                  ddd       |j	                  ddt
        dd	
       |j	                  ddd       |j	                  ddd       |j	                  ddd       |j	                  ddd       |j	                  dd|d       |j	                  ddt        dd
       |j	                  ddt        dd
       |j	                  ddt
        d d!
       |j	                  d"dt
        dd#
       |j	                  d$dt
        d%d&
       |j	                  d'd(t        d)d*
       |j	                  d+d,t
        d-d.
       y )/Nz!TLS certificate generator optionsz--no-crtr  z&disable automatic certificate creationr  z--crt-nsN,Nr<   zCcomma-separated list of FQDNs (domains) to add into the certificater  z--crt-exactz6do not add wildcard entries for each [33m--crt-ns[0mz
--crt-noipz.do not add autodetected IP addresses into certz
--crt-noloz*do not add 127.0.0.1 / localhost into certz
--crt-nohnz*do not add mDNS names / hostname into certz	--crt-dirr  zwhere to save the CA certr  rL   rK   z--crt-cdaysDg     @z&ca-certificate expiration time in daysz--crt-sdaysg     v@z#server-cert expiration time in daysz--crt-cnr  partycozCA/server-cert common-namez	--crt-cnczoverride CA namez	--crt-cnsz--crt-cn cppzoverride server-cert namez
--crt-backHRSg      R@zbackdate in hoursz	--crt-algzS-Nz	ecdsa-256zIalgorithm and keysize; one of these: [32mecdsa-256 rsa-4096 rsa-2048[0m)r   r   r   r  r  r  r  )r  r  cert_dirr  s       rH   add_certr  a  s   wwy)H


 C
DCZ;cdZQ  JO  P]<>|}\,=mn\,=ij\,=ij[&(Ide]CeVRz{]CeUQvwZQ	Plm[%aRde[%aVqr\5udQde[%a  Te  frI   c                    t         j                  j                  t        j                  d      }t         j                  j                  t        j                  d      }| j                  d      }|j                  ddt        dd       |j                  d	dt        dd
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        |d       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  dd d!"       |j                  d#d d$"       |j                  d%dt        |d&       |j                  d'd(t        d)d*       |j                  d+d d,"       |j                  d-d.t        d/d01       y )2Nzidp.dbzsessions.dbz5IdP / identity provider / user authentication options--idp-h-usrHNr<   a=  bypass the copyparty authentication checks if the request-header [33mHN[0m contains a username to associate the request with (for use with authentik/oauth/...)
[1;31mWARNING:[0m if you enable this, make sure clients are unable to specify this header themselves; must be washed away and replaced by a reverse-proxyr  z--idp-h-grpzassume the request-header [33mHN[0m contains the groupname of the requesting user; can be referenced in config files for group-based access controlz--idp-h-keyzoptional but recommended safeguard; your reverse-proxy will insert a secret header named [33mHN[0m into all requests, and the other IdP headers will be ignored if this header is not present
--idp-gsepREz|:;+,zpif there are multiple groups in [33m--idp-h-grp[0m, they are separated by one of the characters in [33mRE[0mz--idp-dbr  zuwhere to store the known IdP users/groups (if you run multiple copyparty instances, make sure they use different DBs)z--idp-storer  r   aA  how to use [33m--idp-db[0m; [[32m0[0m] = entirely disable, [[32m1[0m] = write-only (effectively disabled), [[32m2[0m] = remember users, [[32m3[0m] = remember users and groups.
NOTE: Will remember and restore the IdP-volumes of all users for all eternity if set to 2 or 3, even when user is deleted from your IdPz	--idp-admr  zLcomma-separated list of users allowed to use /?idp (the cache management UI)z--idp-cookieSr   uT  generate a session-token for IdP users which is written to cookie [33mcppws[0m (or [33mcppwd[0m if plaintext), to reduce the load on the IdP server, lifetime [33mS[0m seconds.
 └─note: The expiration time is a client hint only; the actual lifetime of the session-token is infinite (until next restart with [33m--ses-db[0m wiped)z
--no-bauthr  zdisable basic-authentication support; do not accept passwords from the 'Authenticate' header at all. NOTE: This breaks support for the android appr  z--bauth-lastzpkeeps basic-authentication enabled, but only as a last-resort; if a cookie is also provided then the cookie winsz--ses-dbzpwhere to store the sessions database (if you run multiple copyparty instances, make sure they use different DBs)z	--ses-lenCHARS   z5session key length; default is 120 bits ((20//4)*4*6)z--no-sesz4disable sessions; use plaintext passwords in cookiesz--ipuzCIDR=USRr   z[34mREPEATABLE:[0m users with IP matching [33mCIDR[0m are auto-authenticated as username [33mUSR[0m; example: [[32m172.16.24.0/24=dave]r  r  )r  idp_dbses_dbr  s       rH   add_authr  t  s   WW\\!%%*FWW\\!%%/F


 W
XC]Dq"  LX  Y]Dq"  Li  j]Dq"  LS  T\4a  PN  OZa  OF  G]Cc1  Ln  o[%a  KY  Z^SsA  M|  }\,  >R  S^L  @r  sZa  OA  B['R  OF  GZ;qrWjq  Qv  wrI   c                 z   t         j                  j                  t        j                  d      }| j                  d      }|j                  ddd       |j                  ddt        d	d
       |j                  ddt        |d       |j                  ddt        dd       |j                  ddt        dd       y )Nz	chpw.jsonz!user-changeable passwords optionsz--chpwr  z)allow users to change their own passwordsr  z	--chpw-nozU,U,Ur   z][34mREPEATABLE:[0m do not allow password-changes for this comma-separated list of usernamesr  z	--chpw-dbr  zqwhere to store the passwords database (if you run multiple copyparty instances, make sure they use different DBs)r  z
--chpw-lenr     zminimum password lengthz--chpw-vr  r   zverbosity of summary on config load [[32m0[0m] = nothing at all, [[32m1[0m] = number of users, [[32m2[0m] = list users with default-pw, [[32m3[0m] = list all usersr  r  s      rH   add_chpwr    s    ggll155+.G


 C
DCXl9de['(  Rw  x[&q'  QD  E\3S!JcdZS!  KP  QrI   c                 F   | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddd       |j                  ddt        dd
       y )NzZeroconf optionsz-zr  z)enable all zeroconf backends (mdns, ssdp)r  z--z-onNETSr<   u   enable zeroconf ONLY on the comma-separated list of subnets and/or interface names/indexes
 └─example: [32meth0, wlo1, virhost0, 192.168.123.0/24, fd00:fda::/96[0mr  z--z-offzVdisable zeroconf on the comma-separated list of subnets and/or interface names/indexesz--z-chkr  
   z@check for network changes every [33mSEC[0m seconds (0=disable)z-zvzverbose all zeroconf backendsz--mc-hopr   u#  rejoin multicast groups every [33mSEC[0m seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [[32m300[0m] or [[32m180[0m]
 └─note: can be due to firewalls; make sure UDP port 5353 is open in both directions (on clients too)r  r  s     rH   add_zeroconfr    s    


 2
3CT,5`aXvAr  I{  |YQ  Jb  cYC  KS  TU<6UVZS!  KC  DrI   c                    | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt        dd
       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddt        dd 
       |j                  d!dt        dd"
       |j                  d#dt        dd$
       |j                  d%d&t        d'd(
       |j                  d)dd*       |j                  d+dd,       |j                  d-dd.       |j                  d/d0t        d1d2
       y )3Nz)Zeroconf-mDNS options; also see --help-zmz--zmr  zeannounce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...r  z--zm-onr  r<   zVenable mDNS ONLY on the comma-separated list of subnets and/or interface names/indexesr  z--zm-offzRdisable mDNS on the comma-separated list of subnets and/or interface names/indexesz--zm4z3IPv4 only -- try this if some clients can't connectz--zm6z	IPv6 onlyz--zmvzverbose mdnsz--zmvvzverboser mdnsz
--zm-no-pez2mute parser errors (invalid incoming MDNS packets)z
--zm-nwa-1zUdisable workaround for avahi-bug #379 (corruption in Avahi's mDNS reflection feature)z--zmsdhfzlist of services to announce -- d=webdav h=http f=ftp s=smb -- lowercase=plaintext uppercase=TLS -- default: all enabled services except http/https ([32mDdfs[0m if [33m--ftp[0m and [33m--smb[0m is set, [32mDd[0m otherwise)z--zm-ldr  z(link a specific folder for webdav sharesz--zm-lhz&link a specific folder for http sharesz--zm-lfz%link a specific folder for ftp sharesz--zm-lsz%link a specific folder for smb sharesz	--zm-fqdnFQDNz--name.localzfthe domain to announce; NOTE: using anything other than .local is nonstandard and could cause problemsz	--zm-mniczJmerge NICs which share subnets; assume that same subnet means same networkz	--zm-msubzmerge subnets on each NIC -- always enabled for ipv6 -- reduces network load, but gnome-gvfs clients may stop working, and clients cannot be in subnets that the server is notz
--zm-nonegzDdisable NSEC replies -- try this if some clients don't see copypartyz	--zm-spamr  r  zsend unsolicited announce every [33mSEC[0m; useful if clients have IPs in a subnet which doesn't overlap with the server, or to avoid some firewall issues)r  r  r  r  r  s     rH   add_zc_mdnsr    s   


 K
LCVL  8_  `YQ  Jb  cZa  K_  `W\8mnW\DW\GXlI\,=qr\,  >U  VWe!R  GG  HYQIstYQIqrYQIpqYQIpq[&q.  X@  A[  =I  J[  =m  n\,  >D  E[%eS  Pt  urI   c                 N   | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt        dd
       |j                  ddd       |j                  ddt        dd
       |j                  ddt        t        d
       y )NzZeroconf-SSDP optionsz--zsr  zCannounce the enabled protocols over SSDP -- compatible with Windowsr  z--zs-onr  r<   zVenable SSDP ONLY on the comma-separated list of subnets and/or interface names/indexesr  z--zs-offzRdisable SSDP on the comma-separated list of subnets and/or interface names/indexesz--zsvzverbose SSDPz--zslr  z/?hczlocation to include in the url (or a complete external URL), for example [[32mpriv/?pw=hunter2[0m] (goes directly to /priv/ with password hunter2) or [[32m?hc=priv&pw=hunter2[0m] (shows mounting options for /priv/ with password)z--zsidUUIDz#USN (device identifier) to announce)r  r  r  zsidr  s     rH   add_zc_ssdpr     s    


 7
8CVL7|}YQ  Jb  cZa  K_  `W\GWf1f  LB  CXvAtJoprI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        dd       |j                  d	d
d       |j                  dd
d       |j                  ddt        dd       |j                  dd
d       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       y )NzFTP options (TCP only)z--ftpr  r   z9enable FTP server on [33mPORT[0m, for example [32m3921r  z--ftpsz:enable FTPS server on [33mPORT[0m, for example [32m3990z--ftpvr  r   r  z--ftp4only listen on IPv4z	--ftp-ipar  r<   only accept connections from IP-addresses inside [33mCIDR[0m (comma-separated); specify [[32many[0m] to disable inheriting [33m--ipa[0m. Examples: [[32mlan[0m] or [[32m10.89.0.0/16, 192.168.33.0/24[0m]z--ftp-no-owz9if target file exists, reject upload instead of overwritez--ftp-wtr  r   zgrace period for resuming interrupted uploads (any client can write to any file last-modified more recently than [33mSEC[0m seconds ago)z	--ftp-natADDRz.the NAT address to use for passive connectionsz--ftp-prP-PzSthe range of TCP ports to use for passive connections, for example [32m12000-13000r  r  ra  r  r  s     rH   add_ftpr    s   


 8
9CWf3  IM  NXvC  JO  PXlCXl9NO[&q"  L  @]<>yzZS!  K]  ^[&q"K{|ZQ  Jb  crI   c                 "   | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       |j                  ddt        dd       y )NzWebDAV optionsz--dawr  a  enable full write support, even if client may not be webdav. [1;31mWARNING:[0m This has side-effects -- PUT-operations will now [1;31mOVERWRITE[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)r  z	--dav-infzallow depth:infinite requests (recursive file listing); extremely server-heavy but required for spec compliance -- luckily few clients rely on thisz	--dav-maczdisable apple-garbage filter -- allow macos to create junk files (._* and .DS_Store, .Spotlight-*, .fseventsd, .Trashes, .AppleDouble, __MACOS)z--dav-rtzyshow symlink-destination's lastmodified instead of the link itself; always enabled for recursive listings (volflag=davrt)z
--dav-authzkforce auth for all folders (required by davfs2 when only some folders are world-readable) (volflag=davauth)z	--dav-ua1PTNz kioworker/zcregex of tricky user-agents which expect 401 from GET requests; disable with [[32mno[0m] or blankr  r  r  s     rH   
add_webdavr
    s    


 0
1CW\  9y  z[  =R  S[  =N  OZ  <w  x\,  >k  l[%a  WB  CrI   c                    | j                  d      }|j                  ddt        dd       |j                  ddd	
       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  ddt        dd       |j                  ddd
       |j                  ddt        dd       |j                  ddt        dd       y )NzTFTP options (UDP only)z--tftpr  r   zIenable TFTP server on [33mPORT[0m, for example [32m69 [0mor [32m3969r  z--tftp4r  r  r  z--tftpvr   z--tftpvvverboserz--tftp-no-fastzdebug: disable optimizationsz
--tftp-lsfr	  z\.?(dir|ls)(\.txt)?zreturn a directory listing if a file with this name is requested and it does not exist; defaults matches .ls, dir, .dir.txt, ls.txt, ...z--tftp-nolszbif someone tries to download a directory, return an error instead of showing its directory listingz
--tftp-ipar  r<   r  z	--tftp-prr  zMthe range of UDP ports to use for data transfer, for example [32m12000-13000r  r  s     rH   add_tftpr    s   


 9
:CXvC  Jd  eY|:OPY|)DZ:F%lA_`\5qBY  ak  l]<  ?c  d\62  M@  A[%a  K]  ^rI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dt        dd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       y )NzSMB/CIFS optionsz--smbr  a  enable smb (read-only) -- this requires running copyparty as root on linux and macos unless [33m--smb-port[0m is set above 1024 and your OS does port-forwarding from 445 to that.
[1;31mWARNING:[0m this protocol is DANGEROUS and buggy! Never expose to the internet!r  z--smbwz"enable write support (please dont)z--smb1z'disable SMBv2, only enable SMBv1 (CIFS)z
--smb-portr  i  zoport to listen on -- if you change this value, you must NAT from TCP:445 to this port using iptables or similarr  z--smb-nwa-1zktruncate directory listings to 64kB (~400 files); avoids impacket-0.11 bug, fixes impacket-0.12 performancez--smb-nwa-2z.disable impacket workaround for filecopy globsz--smbazsmall performance boost: disable per-account permissions, enables account coalescing instead (if one user has write/delete-access, then everyone does)z--smbvr   z--smbvvr  z--smbvvv	verbosestr  r  ra  r  s     rH   add_smbr    s	   


 2
3CW\  9T  UXl9]^Xl9bc\6S  PA  B]<  ?l  m]<>noXl  :R  SXlCY|*EZ;GrI   c                     | j                  d      }|j                  ddt        dd       |j                  ddt        dd       |j                  d	d
d       y )Nzhandlers (see --help-handlers)z--on404PYr   z>[34mREPEATABLE:[0m handle 404s by executing [33mPY[0m filer  z--on403z>[34mREPEATABLE:[0m handle 403s by executing [33mPY[0m filez--hot-handlersr  zTrecompile handlers on each request -- expensive but convenient when hacking on stuffr  r  r  s     rH   add_handlersr    ss    


 @
ACY1X  MY  ZY1X  MY  Z%l  BX  YrI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        dd       |j                  d	dt        dd
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddd       y )Nzevent hooks (see --help-hooks)z--xbuCMDr   zE[34mREPEATABLE:[0m execute [33mCMD[0m before a file upload startsr  z--xauzG[34mREPEATABLE:[0m execute [33mCMD[0m after  a file upload finishesz--xiuzV[34mREPEATABLE:[0m execute [33mCMD[0m after  all uploads finish and volume is idlez--xbcz<[34mREPEATABLE:[0m execute [33mCMD[0m before a file copyz--xacz<[34mREPEATABLE:[0m execute [33mCMD[0m after  a file copyz--xbrzC[34mREPEATABLE:[0m execute [33mCMD[0m before a file move/renamez--xarzC[34mREPEATABLE:[0m execute [33mCMD[0m after  a file move/renamez--xbdz>[34mREPEATABLE:[0m execute [33mCMD[0m before a file deletez--xadz>[34mREPEATABLE:[0m execute [33mCMD[0m after  a file deletez--xmz4[34mREPEATABLE:[0m execute [33mCMD[0m on messagez--xbanzQ[34mREPEATABLE:[0m execute [33mCMD[0m if someone gets banned (pw/404/403/url)z--hook-vr  zverbose hooksr  r  r  s     rH   	add_hooksr    s   


 @
ACWe!H  L_  `We!H  La  bWe!H  Lp  qWe!H  LV  WWe!H  LV  WWe!H  L]  ^We!H  L]  ^We!H  LX  YWe!H  LX  YVU8  KM  NXu1X  Ml  mZ?KrI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       |j                  ddd       y )Nz#grafana/prometheus metrics endpointz--statsr  z6enable openmetrics at /.cpr/metrics for admin accountsr  z	--nos-hddz,disable disk-space metrics (used/free space)z	--nos-volzAdisable volume size metrics (num files, total bytes, vmaxb/vmaxn)z	--nos-vstz<disable volume state metrics (indexing, analyzing, activity)z	--nos-dupz1disable dupe-files metrics (good idea; very slow)z	--nos-unfz"disable unfinished-uploads metricsr  r  r  s     rH   	add_statsr    s    


 E
FCY|:rs[<jk[<  A[<z{[<op[<`arI   c                     | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       y )Nzyolo optionsz--allow-csrfr  z]disable csrf protections; let other domains/sites impersonate you through cross-site requestsr  z--cookie-laxzallow cookies from other domains (if you follow a link from another website into your server, you will arrive logged-in); this reduces protection against CSRFz
--no-fnuggz>disable the smoketest for caching-related issues in the web-UIz--getmodz%permit ?move=[...] and ?delete as GETz--wo-up-readmez~allow users with write-only access to upload logues and readmes without adding the _wo_ filename prefix (volflag=wo_up_readme)r  r  s     rH   add_yolor    s    



/C^L  @_  `^L  @`  a\,=}~Z;bc%l  BB  CrI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd       |j                  ddt        dd       |j                  d d!t        d"d#       |j                  d$dd%       |j                  d&d't        d(d)       |j                  d*d+t        t        d,       |j                  d-dd.       |j                  d/dd0       |j                  d1dd2       |j                  d3dd4       |j                  d5dd6       |j                  d7dd8       y )9Nzopt-outsz-nwr  z.never write anything to disk (debug/benchmark)r  z
--keep-qemzdo not disable quick-edit-mode on windows (it is disabled to avoid accidental text selection in the terminal window, as this would pause execution)z--no-davzdisable webdav supportz--no-delzdisable delete operationsz--no-mvzdisable move/rename operationsz--no-cpzdisable copy operationsz-nthz8no title hostname; don't show [33m--name[0m in <title>z-nihz$no info hostname -- don't show in UIz-nidz&no info disk-usage -- don't show in UIz-nbz&no powered-by-copyparty branding in UIz	--zipmaxnr  r  zreject download-as-zip if more than [33mN[0m files in total; optionally takes a unit suffix: [[32m256[0m], [[32m9K[0m], [[32m4G[0m] (volflag=zipmaxn)r  z	--zipmaxsSZzreject download-as-zip if total download size exceeds [33mSZ[0m bytes; optionally takes a unit suffix: [[32m256M[0m], [[32m4G[0m], [[32m2T[0m] (volflag=zipmaxs)z	--zipmaxtr  r<   zDcustom errormessage when download size exceeds max (volflag=zipmaxt)z	--zipmaxuz?authenticated users bypass the zip size limit (volflag=zipmaxu)z	--zip-whor     ak  who can download as zip/tar? [[32m0[0m]=nobody, [[32m1[0m]=admins, [[32m2[0m]=authenticated-with-read-access, [[32m3[0m]=everyone-with-read-access (volflag=zip_who)
[1;31mWARNING:[0m if a nested volume has a more restrictive value than a parent volume, then this will be [33mignored[0m if the download is initiated from the parent, more lenient volumez
--ua-nozipr	  z\regex of user-agents to reject from download-as-zip/tar; disable with [[32mno[0m] or blankz--no-zipz9disable download as zip/tar; same as [33m--zip-who=0[0mz--no-tarcmpzOdisable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)z--no-lifetimez^do not allow clients (or server config) to schedule an upload to be deleted after a given timez	--no-pipezfdisable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)z	--no-tailz=disable streaming a growing files with ?tail (volflag=notail)z
--no-db-ipzdo not write uploader-IP into the database; will also disable unpost, you may want [32m--forget-ip[0m instead (volflag=no_db_ip))r  r  r  ra  r   r  s     rH   add_optoutsr     sL   




+CU<6fg\,  >S  TZ;STZ;VWY|:Z[Y|:STVL7wxVL7]^VL7_`U<6^_[#As  JA  B[$Q  KM  N[%a  KQ  R[<}~[%c1  L^  _\5q(  Rv  wZ;|}]<  ?P  Q_\  Aa  b[  =e  f[<{|\,  >H  IrI   c                    | j                  d      }|j                  dddd       |j                  ddd	
       |j                  ddd
       |j                  ddt        dd       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  ddd
       |j                  d dd!
       |j                  d"dd#
       |j                  d$d%t        d&d'       |j                  d(d)t        d*d+       |j                  d,d)t        d-d.       |j                  d/d)t        d0d1       |j                  d2d)t        d3d4       |j                  d5d)t        d3d6       |j                  d7d)t        d3d8       |j                  d9d:t        d;d<       |j                  d=d:t        d>d?       |j                  d@ddA
       |j                  dBdCt        dDdE       |j                  dFdGt        dHdI       |j                  dJdKt        dLdM       |j                  dNdKt        dOdP       y )QNzsafety optionsz-scountr   u   increase safety: Disable thumbnails / potentially dangerous software (ffmpeg/pillow/vips), hide partial uploads, avoid crawlers.
 └─Alias of[32m --dotpart --no-thumb --no-mtag-ff --no-robots --force-jsrU   rL   rK   z-ssr  u   further increase safety: Prevent js-injection, accidental move/delete, broken symlinks, webdav, 404 on 403, ban on excessive 404s.
 └─Alias of[32m -s --unpost=0 --no-del --no-mv --hardlink --vague-403 -nihr  z-sssu   further increase safety: Enable logging to disk, scan for dangerous symlinks.
 └─Alias of[32m -ss --no-dav --no-logues --no-readme -lo=cpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz --ls=**,*,ln,p,rz--lsz	U[,V[,F]]r<   zdo a sanity/safety check of all volumes on startup; arguments [33mUSER[0m,[33mVOL[0m,[33mFLAGS[0m (see [33m--help-ls[0m); example [[32m**,*,ln,p,r[0m]r  z--xvolznever follow symlinks leaving the volume root, unless the link is into another volume where the user has similar access (volflag=xvol)z--xdevzstay within the filesystem of the volume root; do not descend into other devices (symlink or bind-mount to another HDD, ...) (volflag=xdev)z--no-dot-mvzQdisallow moving dotfiles; makes it impossible to move folders containing dotfilesz--no-dot-renzPdisallow renaming dotfiles; makes it impossible to turn something into a dotfilez--no-logueszBdisable rendering .prologue/.epilogue.html into directory listingsz--no-readmez;disable rendering readme/preadme.md into directory listingsz--vague-403zEsend 404 instead of 403 (security through ambiguity, very enterprise)z
--force-jszdon't send folder listings as HTML, force clients to use the embedded json instead -- slight protection against misbehaving search engines which ignore [33m--no-robots[0mz--no-robotszYadds http and html headers asking search engines to not index anything (volflag=norobots)z--logoutHg     @zlogout clients after [33mH[0m hours of inactivity; [[32m0.0028[0m]=10sec, [[32m0.1[0m]=6min, [[32m24[0m]=day, [[32m168[0m]=week, [[32m720[0m]=month, [[32m8760[0m]=year)z--ban-pwzN,W,Bz	9,60,1440zsmore than [33mN[0m wrong passwords in [33mW[0m minutes = ban for [33mB[0m minutes; disable with [[32mno[0m]z	--ban-pwcz	5,60,1440ztmore than [33mN[0m password-changes in [33mW[0m minutes = ban for [33mB[0m minutes; disable with [[32mno[0m]z	--ban-404z
50,60,1440zhitting more than [33mN[0m 404's in [33mW[0m minutes = ban for [33mB[0m minutes; only affects users who cannot see directory listings because their access is either g/G/hz	--ban-403z9,2,1440zhitting more than [33mN[0m 403's in [33mW[0m minutes = ban for [33mB[0m minutes; [[32m1440[0m]=day, [[32m10080[0m]=week, [[32m43200[0m]=monthz	--ban-422zhitting more than [33mN[0m 422's in [33mW[0m minutes = ban for [33mB[0m minutes (invalid requests, attempted exploits ++)z	--ban-urlzhitting more than [33mN[0m sus URL's in [33mW[0m minutes = ban for [33mB[0m minutes; applies only to permissions g/G/h (decent replacement for [33m--ban-404[0m if that can't be used)z
--sus-urlsRz(\.php$|(^|/)wp-(admin|content|includes)/zYURLs which are considered sus / eligible for banning; disable with blank or [[32mno[0m]z--nonsus-urlsz<^(favicon\.ico|robots\.txt)$|^apple-touch-icon|^\.well-knownzHharmless URLs ignored from 404-bans; disable with blank or [[32mno[0m]z--early-banzif a client is banned, reject its connection as soon as possible; not a good idea to enable when proxied behind cloudflare since it could ban your reverse-proxyz--acloser  r  zif a client maxes out the server connection limit, downgrade it from connection:keep-alive to connection:close for [33mMIN[0m minutes (and also kill its active connections) -- disable with 0z--lorisr  r  zif a client maxes out the server connection limit without sending headers, ban it for [33mB[0m minutes; disable with [[32m0[0m]z--acaozV[,V]*zAccess-Control-Allow-Origin; list of origins (domains/IPs without port) to accept requests from; [[32mhttps://1.2.3.4[0m]. Default [[32m*[0m] allows requests from all sites but removes cookies and http-auth; only ?pw=hunter2 survivesz--acamzGET,HEADzuAccess-Control-Allow-Methods; list of methods to accept from offsite ('*' behaves like [33m--acao[0m's description))r  r  r  r  ra  r  s     rH   
add_safetyr'  3  sP   


 0
1CT'1  <P  QU<  7O  PVL  8z  {V[q"  LL  MXl  :B  CXl  :G  H]<  ?R  S^L  @R  S]<  ?C  D]<>{|]<  ?F  G\,  >r  s]<  ?Z  [Z5&  Pr  sZq+  Ub  c[';  Vd  e['<  W[  \[':  UT  U[':  Uh  i[':  Um  n\3Q@k  sT  U_c  DC  JZ  []<  ?a  bZS"  LT  UY#r  IZ  [XwQ  KF  GXwQ
  RO  PrI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        |d	       |j                  d
dt        dd       |j                  ddd       |j                  ddt        |d       |j                  ddt        |d       |j                  ddt        dd       |j                  ddd       |j                  ddd       |j                  ddd       y )Nzsalting optionsz--ah-algr  nonezaccount-pw hashing algorithm; one of these, best to worst: [32margon2 scrypt sha2 none[0m (each optionally followed by alg-specific comma-sep. config)r  z	--ah-saltSALTz?account-pw salt; ignored if [33m--ah-alg[0m is none (default)z--ah-genPWr<   zegenerate hashed password for [33mPW[0m, or read passwords from STDIN if [33mPW[0m is [[32m-[0m]z--ah-clir  zllaunch an interactive shell which hashes passwords without ever storing or displaying the original passwordsr  z	--fk-saltzMper-file accesskey salt; used to generate unpredictable URLs for hidden filesz	--dk-saltzper-directory accesskey salt; used to generate unpredictable URLs to share folders with users who only have the 'get' permission
--warksalthunter2zeup2k file-hash salt; serves no purpose, no reason to change this (but delete all databases if you do)z--show-ah-saltzon startup, print the effective value of [33m--ah-salt[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)z--show-fk-saltzon startup, print the effective value of [33m--fk-salt[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)z--show-dk-saltzon startup, print the effective value of [33m--dk-salt[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)r  )r  fk_saltdk_saltah_saltr  s        rH   add_saltr1  R  sO   


 1
2CZQ  Nn  o[&q'  QX  YZAr  IB  CZ  <j  k[&q'  Q`  a[&q'  QS  T\69  T{  |%l  BN  O%l  BN  O%l  BN  OrI   c                     | j                  d      }|j                  ddd       |j                  ddd       |j                  dd	t        d
d       y )Nzshutdown options--ign-ebindr  zUcontinue running even if it's impossible to listen on some of the requested endpointsr  z--ign-ebind-allzFcontinue running even if it's impossible to receive connections at allz--exitWHENr<   zvshutdown after [33mWHEN[0m has finished; [[32mcfg[0m] config parsing, [[32midx[0m] volscan + multimedia indexingr  r  r  s     rH   add_shutdownr5  `  sn    


 2
3C]<  ?V  W&|  CK  LXvAr  IS  TrI   c                    | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt         d       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddd       |j                  ddd        |j                  d!d"t        d#d$%       |j                  d&d"t        d#d'%       |j                  d(d)t        d*d+
       y ),Nzlogging optionsz-qr  z#quiet; disable most STDOUT messagesr  z-lor  r<   zlogfile; use .txt for plaintext or .xz for compressed. Example: [32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz[0m (NB: some errors may appear on STDOUT only)r  z	--no-ansiz5disable colors; same as environment-variable NO_COLORr#  z--ansiz5force colors; overrides environment-variable NO_COLORz--no-logflushz9don't flush the logfile after each write; tiny bit fasterz--no-voldumpz.do not list volumes and permissions on startupz	--log-utczIdo not use local timezone; assume the TZ env-var is UTC (tiny bit faster)z
--log-tdecr  r  z3timestamp resolution / number of timestamp decimalsz--log-badpwdr   zBlog failed login attempt passwords: 0=terse, 1=plaintext, 2=hashedz
--log-connzdebug: print tcp-server msgsz	--log-htpz+debug: print http-server threadpool scalingz--iheadHEADERr   z/print request [33mHEADER[0m; [[32m*[0m]=allr  z--oheadz0print response [33mHEADER[0m; [[32m*[0m]=allz--lf-urlr  z5^/\.cpr/|[?&]th=[wjp]|/\.(_|ql_|DS_Store$|localized$)z(dont log URLs matching regex [33mRE[0m)r  r  r  r   ra  r  s     rH   add_loggingr8  g  s   


 1
2CT,5Z[UFB  Fb  c[5y  PG  HXl9pq_\@{|^L?op[  =H  I\3S!J  A^SsA  MQ  R\,=[\[<ijYq  QN  OYq  QO  PZA?w  o  prI   c                 ~   | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddd       y )Nzadmin panel optionsz--no-reloadr  zDdisable ?reload=cfg (reload users/volumes/volflags from config file)r  z--no-rescanz!disable ?scan (volume reindexing)z
--no-stackz disable ?stack (list all stacks)z--no-ups-pagez$disable ?ru (list of recent uploads)z--no-up-listz1don't show list of incoming files in controlpanelz	--dl-listr  r   zqwho can see active downloads in the controlpanel? [[32m0[0m]=nobody, [[32m1[0m]=admins, [[32m2[0m]=everyoner  z	--ups-whoz}who can see recent uploads on the ?ru page? [[32m0[0m]=nobody, [[32m1[0m]=admins, [[32m2[0m]=everyone (volflag=ups_who)z
--ups-whenzClet everyone see upload timestamps on the ?ru page, not just adminsr  r  s     rH   	add_adminr:  y  s    


 5
6C]<  ?E  F]<>ab\,=_`_\@fg^L?rs[%c1  LQ  R[%c1  L]  ^\,  >C  DrI   c                 N   t         xs
 t        xs ddz  }t        t        t	        |d      d      dz        dz  }| j                  d      }|j                  ddd	
       |j                  ddd
       |j                  ddd
       |j                  dddd       |j                  ddt        t        d       |j                  ddt        dd       |j                  ddt        |d       |j                  dd t        d!d"       |j                  d#d t        d$d%       |j                  d&d'd(d)       |j                  d*dd+
       |j                  d,dd-
       |j                  d.dd/
       |j                  d0dd1
       |j                  d2dt        d3d4       |j                  d5dt        d6d7       |j                  d8dt        d9d:       |j                  d;d<t        d=d>       |j                  d?d@t        dAdB       |j                  dCd@t        dDdE       |j                  dFd@t        dGdH       |j                  dId@t        dJdK       |j                  dLd@t        dMdN       |j                  dOdPt        dQdR       |j                  dSdTt        dUdV       y )WNr  g333333?r   g333333?r  zthumbnail optionsz
--no-thumbr  z'disable all thumbnails (volflag=dthumb)r  z--no-vthumbz*disable video thumbnails (volflag=dvthumb)z--no-athumbz9disable audio thumbnails (spectrograms) (volflag=dathumb)z	--th-sizeWxH320x256zthumbnail res (volflag=thsize)r  z--th-mtr   z.num cpu cores to use for generating thumbnailsr  z
--th-convtr  g      N@z-conversion timeout in seconds (volflag=convt)z--th-ram-maxGBzBmax memory usage (GiB) permitted by thumbnailer; not very accuratez	--th-cropr  yzcrop thumbnails to 4:3 or keep dynamic height; client can override in UI unless force. [[32my[0m]=crop, [[32mn[0m]=nocrop, [[32mfy[0m]=force-y, [[32mfn[0m]=force-n (volflag=crop)z--th-x3nzshow thumbs at 3x resolution; client can override in UI unless force. [[32my[0m]=yes, [[32mn[0m]=no, [[32mfy[0m]=force-yes, [[32mfn[0m]=force-no (volflag=th3x)z--th-decLIBSzvips,pil,ffz&image decoders, in order of preferencez--th-no-jpgzdisable jpg outputz--th-no-webpzdisable webp outputz--th-ff-jpgzGforce jpg output for video thumbs (avoids issues on some FFmpeg builds)z--th-ff-swrzmuse swresample instead of soxr for audio thumbs (faster, lower accuracy, avoids issues on some FFmpeg builds)z	--th-poker  zactivity labeling cooldown -- avoids doing keepalive pokes (updating the mtime) on thumbnail folders more often than [33mSEC[0m secondsz
--th-cleanr  zcleanup interval; 0=disabledz--th-maxagei:	 zmax folder age -- folders which haven't been poked for longer than [33m--th-poke[0m seconds will get deleted every [33m--th-clean[0m secondsz--th-coversr  z)folder.png,folder.jpg,cover.png,cover.jpgzfolder thumbnails to stat/look for; enabling [33m-e2d[0m will make these case-insensitive, and try them as dotfiles (.folder.jpg), and also automatically select thumbnails for all folders that contain pics, even if none match this patternz
--th-r-pilzT,Tzavif,avifs,blp,bmp,cbz,dcx,dds,dib,emf,eps,fits,flc,fli,fpx,gif,heic,heics,heif,heifs,icns,ico,im,j2p,j2k,jp2,jpeg,jpg,jpx,pbm,pcx,pgm,png,pnm,ppm,psd,qoi,sgi,spi,tga,tif,tiff,webp,wmf,xbm,xpmz$image formats to decode using pillowz--th-r-vipsz]avif,exr,fit,fits,fts,gif,hdr,heic,jp2,jpeg,jpg,jpx,jxl,nii,pfm,pgm,png,ppm,svg,tif,tiff,webpz$image formats to decode using pyvipsz
--th-r-ffizapng,avif,avifs,bmp,cbz,dds,dib,fit,fits,fts,gif,hdr,heic,heics,heif,heifs,icns,ico,jp2,jpeg,jpg,jpx,jxl,pbm,pcx,pfm,pgm,png,pnm,ppm,psd,qoi,sgi,tga,tif,tiff,webp,xbm,xpmz$image formats to decode using ffmpegz
--th-r-ffvz3gp,asf,av1,avc,avi,flv,h264,h265,hevc,m4v,mjpeg,mjpg,mkv,mov,mp4,mpeg,mpeg2,mpegts,mpg,mpg2,mts,nut,ogm,ogv,rm,ts,vob,webm,wmvz$video formats to decode using ffmpegz
--th-r-ffazaac,ac3,aif,aiff,alac,alaw,amr,apac,ape,au,bonk,dfpwm,dts,flac,gsm,ilbc,it,itgz,itxz,itz,m4a,mdgz,mdxz,mdz,mo3,mod,mp2,mp3,mpc,mptm,mt2,mulaw,oga,ogg,okt,opus,ra,s3m,s3gz,s3xz,s3z,tak,tta,ulaw,wav,wma,wv,xm,xmgz,xmxz,xmz,xpkz$audio formats to decode using ffmpegz--th-spec-cnvTzMit,itgz,itxz,itz,mdgz,mdxz,mdz,mo3,mod,s3m,s3gz,s3xz,s3z,xm,xmgz,xmxz,xmz,xpkzkaudio formats which provoke https://trac.ffmpeg.org/ticket/10797 (huge ram usage for s3xmodit spectrograms)z	--au-unpkzE=F.Czmdz=mod.zip, mdgz=mod.gz, mdxz=mod.xz, s3z=s3m.zip, s3gz=s3m.gz, s3xz=s3m.xz, xmz=xm.zip, xmgz=xm.gz, xmxz=xm.xz, itz=it.zip, itgz=it.gz, itxz=it.xz, cbz=jpg.cbzz:audio/image formats to decompress before passing to ffmpeg)
r'   r(   ra  maxminr  r  r   r  r  )r  th_ramr  s      rH   add_thumbnailrF    sI   )9)S0FS^S)B./"4F


 3
4C\,=fg]<>jk]<>yz[%IijYc5O  A\5ud  RA  B^Tv  UY  Z[%a  L`  aYAs  JK  LZMuv]<>RS^L?TU]<  ?H  I]<  ?n  o[%c3  N_  `\5sEPno]EV  Sq  r]ECn  vn  o \5q  CE  Lr  s]E  Dc  jP  Q\5q  Co  v\  ]\5q  CD  Kq  r\5q  Ce  lR  S_c  DS  ZG  H['  Dg  nj  krI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        d	d
       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd       y )Nztranscoding optionsz--q-opusKBPSrO  z8target bitrate for transcoding to opus; set 0 to disabler  z--q-mp3QUALITYq2ztarget quality for transcoding to mp3, for example [[32m192k[0m] (CBR) or [[32mq0[0m] (CQ/CRF, q0=maxquality, q9=smallest); set 0 to disablez--allow-wavr  z1allow transcoding to wav (lossless, uncompressed)r  z--allow-flacz0allow transcoding to flac (lossless, compressed)z--no-cafzKdisable transcoding to caf-opus (affects iOS v12~v17), will use mp3 insteadz--no-owazJdisable transcoding to webm-opus (iOS v18 and later), will use mp3 insteadz
--no-acodezdisable audio transcodingz--no-bacodez<disable batch audio transcoding by folder download (zip/tar)z--ac-maxager  iQ z9delete cached transcode output after [33mSEC[0m secondsr  r  s     rH   add_transcodingrK    s   


 5
6CZc3  NH  IY	4  Om  n]<>qr^L?qrZ  <I  JZ  <H  I\,=XY]<>|}]EU  RS  TrI   c                 ^   | j                  d      }|j                  ddt        dd       |j                  ddt        d	d
       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       y )Nz6tailing options (realtime streaming of a growing file)z
--tail-whor  r   zwho can tail? [[32m0[0m]=nobody, [[32m1[0m]=admins, [[32m2[0m]=authenticated-with-read-access, [[32m3[0m]=everyone-with-read-access (volflag=tail_who)r  z--tail-cmaxr  rN  zIdo not allow starting a new tail if more than [33mN[0m active downloadsz--tail-tmaxr  r   zWterminate connection after [33mSEC[0m seconds; [[32m0[0m]=never (volflag=tail_tmax)z--tail-rateg?zAcheck for new data every [33mSEC[0m seconds (volflag=tail_rate)z	--tail-kag      @zTsend a zerobyte if connection is idle for [33mSEC[0m seconds to prevent disconnectz	--tail-fdg      ?zVcheck if file was replaced (new fd) if idle for [33mSEC[0m seconds (volflag=tail_fd))r  r  ra  r  r  s     rH   add_tailrM    s    


 X
YC\5sA  ME  F]Cc2  M^  _]Eq  Pu  v]Es  R[  \[%eS  Pl  m[%eS  Pn  orI   c                     | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt        dd
       |j                  ddt        dd
       y )NzRSS optionsz--rssr  z.enable RSS output (experimental) (volflag=rss)r  z--rss-nfHITS   z2default number of files to return (url-param 'nf')r  z
--rss-fextzE,Er<   zHdefault list of file extensions to include (url-param 'fext'); blank=allz
--rss-sortORDmzdefault sort order (url-param 'sort'); [[32mm[0m]=last-modified [[32mu[0m]=upload-time [[32mn[0m]=filename [[32ms[0m]=filesize; Uppercase=oldest-first. Note that upload-time is 0 for non-uploaded filesr  r  s     rH   add_rssrS    s    



.CW\8hiZc3  NB  C\5q"  LV  W\5q#  Mx  yrI   c                    t         rt        nd}| j                  d      }|j                  ddd       |j                  ddd       |j                  d	dd
       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        |d       |j                  ddd       |j                  ddd       |j                  d dd!       |j                  d"dd#       |j                  d$dd%       |j                  d&d't
        d(d)       |j                  d*d+d,d-.       |j                  d/dd0       |j                  d1d2t
        |d3       |j                  d4d5t
        d(d6       |j                  d7d5t        d8d9       |j                  d:d5t
        d;d<       |j                  d=d>t
        d?d@       |j                  dAdt        ddB       |j                  dCddD       y )ENr<   zgeneral db optionsz-e2dr  zSenable up2k database; this enables file search, upload-undo, improves deduplicationr  z-e2dszBscan writable folders for new files on startup; sets [33m-e2d[0mz-e2dsaz1scans all folders on startup; sets [33m-e2ds[0mz-e2vz;verify file integrity; rehash all files and compare with dbz-e2vuz7on hash mismatch: update the database with the new hashz-e2vpz*on hash mismatch: panic and quit copypartyz--histr  zlwhere to store volume data (db, thumbs); default is a folder named ".hist" inside each volume (volflag=hist)r  z--dbpathzmoverride where the volume databases are to be placed; default is the same as [33m--hist[0m (volflag=dbpath)z	--no-hashr	  zregex: disable hashing of matching absolute-filesystem-paths during e2ds folder scans (must be specified as one big regex, not multiple times) (volflag=nohash)z--no-idxzregex: disable indexing of matching absolute-filesystem-paths during e2ds folder scan (must be specified as one big regex, not multiple times) (volflag=noidx)z
--no-dirszzsdo not show total recursive size of folders in listings, show inode size instead; slightly faster (volflag=nodirsz)z
--re-dirszzsif the directory-sizes in the UI are bonkers, use this along with [33m-e2dsa[0m to rebuild the index from scratchz
--no-dhashzzdisable rescan acceleration; do full database integrity check -- makes the db ~5%% smaller and bootup/rescans 3~10x slowerz
--re-dhashzeforce a cache rebuild on startup; enable this once if it gets out of sync (should never be necessary)z--no-forgetznever forget indexed files, even when deleted from disk -- makes it impossible to ever upload the same file twice -- only useful for offloading uploads to a cloud service or something (volflag=noforget)z--forget-ipr  r   zremove uploader-IP from database (and make unpost impossible) [33mMIN[0m minutes after upload, for GDPR reasons. Default [[32m0[0m] is never-forget. [[32m1440[0m]=day, [[32m10080[0m]=week, [[32m43200[0m]=month. (volflag=forget_ip)z--dbdPROFILEwalzrdatabase durability profile; sets the tradeoff between robustness and speed, see [33m--help-dbd[0m (volflag=dbd)r  z--xlinkzton upload: check all volumes for dupes, not just the target volume (probably buggy, not recommended) (volflag=xlink)z	--hash-mtr   zInum cpu cores to use for file hashing; set 0 or 1 for single-core hashingz--re-maxager  zNrescan filesystem for changes every [33mSEC[0m seconds; 0=off (volflag=scan)z--db-actg      $@zldefer any scheduled volume reindexing until [33mSEC[0m seconds after last db write (uploads, renames, ...)z--srch-time-   zPsearch deadline -- terminate searches running for more than [33mSEC[0m secondsz--srch-hitsr  i?  zQmax search results to allow clients to fetch; 125 results will be shown initiallyz--srch-exclzregex: exclude files from search results if the file-URL matches [33mPTN[0m (case-sensitive). Example: [[32mpassword|logs/[0-9][0m] any URL containing 'password' or 'logs/DIGIT' (volflag=srch_excl)z	--dotsrchz?show dotfiles in search results (volflags: dotsrch | nodotsrch))r
   r   r  r  r  ra  r  )r  hcoresnoidxr  s       rH   add_db_generalrZ    s   !LrE


 4
5CVL  8M  NW\  9C  DXl9rsVL7tuW\8qrW\8deXvAr  Iy  zZa  K@  A[%a  Kl  mZQ  Mm  n\,  >s  t\,  >y  z\,  >z  {\,  >e  f]<  ?K  L]EQ  N^  _Wi  F@  AY|  ;q  r['V  S^  _]EQ  Nd  eZUD  PD  E]ER  Og  h]Cc4  Ob  c]E2  Md  e[<}~rI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dd       |j                  ddd       |j                  ddt        dd       |j                  ddt        t        d       |j                  ddd       |j                  ddd       |j                  ddt        dd       |j                  dd t        d!t
        "       |j                  d#d t        d$t        "       |j                  d%d&t        dd'       y )(Nzmetadata db optionsz-e2tr  z[enable metadata indexing; makes it possible to search for artist/title/codec/resolution/...r  z-e2tszGscan newly discovered files for metadata on startup; sets [33m-e2t[0mz-e2tsrzEdelete all metadata from DB and do a full rescan; sets [33m-e2ts[0mz--no-mutagenz3use FFprobe for tags instead; will detect more tagsz--no-mtag-ffz2never use FFprobe as tag reader; is probably saferz	--mtag-tor  r  ztimeout for FFprobe tag-scanr  z	--mtag-mtr   z%num cpu cores to use for tag scanningz--mtag-vzAverbose tag scanning; print errors from mtp subprocesses and suchz	--mtag-vvz.debug mtp settings and mutagen/FFprobe parsersz-mtmzM=t,t,tr   z1[34mREPEATABLE:[0m add/replace metadata mappingr  z-mtezM,M,Mztags to index/display (comma-sep.); either an entire replacement list, or add/remove stuff on the default-list with +foo or /bar)r  r  rK   rL   z-mthzMtags to hide by default (comma-sep.); assign/add/remove same as [33m-mte[0mz-mtpz	M=[f,]BINzU[34mREPEATABLE:[0m read tag [33mM[0m using program [33mBIN[0m to parse the file)r  r  ra  r   r  r   r   r  s     rH   add_db_metadatar\    s   


 5
6CVL  8U  VW\  9H  IXl  :G  H^L?tu^L?st[%c2Ljk['UQxyZ;~[<lmVYQx  OH  IVW1  <~  HO  PVW1  <Q  [b  cV[q  Qz  {rI   c                    | j                  d      }|j                  ddt        dd       |j                  ddt        d	d
       |j                  ddt        dd       |j                  ddd       |j                  ddd       |j                  ddt        t        d       |j                  ddt        t        d       |j                  ddt        t
        d       y )Nztextfile optionsz	--md-histr  r  zwhere to store old version of markdown files; [[32ms[0m]=subfolder, [[32mv[0m]=volume-histpath, [[32mn[0m]=nope/disabled (volflag=md_hist)r  z	--txt-eolTYPEr<   zSenable EOL conversion when writing documents; supported: CRLF, LF (volflag=txt_eol)z-mcrr  r  zPthe textfile editor will check for serverside changes every [33mSEC[0m secondsz-empr  z;enable markdown plugins -- neat but dangerous, big XSS riskr  z--expz`enable textfile expansion -- replace {{self.ip}} and such; see [33m--help-exp[0m (volflag=exp)z--exp-mdzV,V,Vzcomma/space-separated list of placeholders to expand in markdown files; add/remove stuff on the default list with +hdr_foo or /vf.scan (volflag=exp_md)z--exp-lgz`comma/space-separated list of placeholders to expand in prologue/epilogue files (volflag=exp_lg)z
--ua-nodocr	  zmregex of user-agents to reject from viewing documents through ?doc=[...]; disable with [[32mno[0m] or blank)r  r  r  ra  r   r   r  s     rH   add_txtr_    s   


 2
3C[%a  Lp  q[&q"  La  bVUb  H`  aVL7tuW\  9a  bZq'  Qj  kZq'  Qs  t\5q(  RG  HrI   c                    | j                  d      }|j                  ddd       |j                  ddt        dd	
       |j                  ddt        dd
       |j                  ddd       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddt        dd
       |j                  ddt        dd
       |j                  d dd!       |j                  d"dt        dd#
       |j                  d$dt        dd%
       |j                  d&d't        d(d)
       |j                  d*dd+       y ),Nz'og / open graph / discord-embed optionsz--ogr  zdisable hotlinking and return an html document instead; this is required by open-graph, but can also be useful on its own (volflag=og)r  z--og-uar  r<   zgonly disable hotlinking / engage OG behavior if the useragent matches regex [33mRE[0m (volflag=og_ua)r  z--og-tplr  zdo not return the regular copyparty html, but instead load the jinja2 template at [33mPATH[0m (if path contains 'EXT' then EXT will be replaced with the requested file's extension) (volflag=og_tpl)z--og-no-headzdo not automatically add OG entries into <head> (useful if you're doing this yourself in a template or such) (volflag=og_no_head)z--og-thFMTjf3zbthumbnail format; j=jpeg, jf=jpeg-uncropped, jf3=jpeg-uncropped-large, w=webm, ... (volflag=og_th)z
--og-titler  zSfallback title if there is nothing in the [33m-e2t[0m database (volflag=og_title)z--og-title-arB  u   🎵 {{ artist }} - {{ title }}z?audio title format; takes any metadata key (volflag=og_title_a)z--og-title-vz{{ title }}z?video title format; takes any metadata key (volflag=og_title_v)z--og-title-iz?image title format; takes any metadata key (volflag=og_title_i)z--og-s-titlez?force default title; do not read from tags (volflag=og_s_title)z	--og-desczQdescription text; same for all files, disable with [[32m-[0m] (volflag=og_desc)z	--og-sitezRsitename; defaults to [33m--name[0m, disable with [[32m-[0m] (volflag=og_site)z--tcolorRGB333z_accent color (3 or 6 hex digits); may also affect safari and/or android-chrome (volflag=tcolor)z--uqezquery-string parceling; translate a request for [33m/foo/.uqe/BASE64[0m into [33m/foo?TEXT[0m, or [33m/foo/?TEXT[0m if the first character in [33mTEXT[0m is a slash. Automatically enabled for [33m--og[0mr  r  s     rH   add_ogre    s   


 I
JCVL  8@  AY1b  Hw  xZa  KZ  [^L  @C  DYAu  Lp  q\5q"  Lg  h^SqBc  kl  m^Sq-  WX  Y^Sq-  WX  Y^L  @A  B[%a  Kd  e[%a  Kk  lZQ  Mn  oW\  9n  orI   c           
         | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       |j                  d
dt        dd       |j                  ddt        dd       |j                  ddt        dd       |j                  ddt        dt	        dd      d       |j                  ddt        dd       |j                  d dd!       |j                  d"d#t        d$d%       |j                  d&dd'       |j                  d(d)t        d$d*       |j                  d+d,t        d-d.       |j                  d/d0t        |rd1nd2d3       |j                  d4d5t        d6d78       |j                  d9t        d-t
        j                  :       |j                  d;d0t        d<d=       |j                  d>d?t        d-d@       |j                  dAd?t        d-dB       |j                  dCd?t        d-dD       |j                  dEd0t        d-dF       |j                  dGddH       |j                  dIdJt        dKdL       |j                  dMdNt        dOdP       |j                  dQd0t        dRdS       |j                  dTd0t        dUdV       |j                  dWdXt        t        dY       |j                  dZdd[       |j                  d\dt        dd]       |j                  d^dt        dd_       |j                  d`dat        dbdc       |j                  dddet        dfdg       |j                  dhdet        dfdi       |j                  djd0t        d-dk       |j                  dld0t        d-dm       |j                  dnddo       |j                  dpddq       |j                  drdt
        j                         y )sNz
ui optionsz--gridr  z.show grid/thumbnails by default (volflag=grid)r  z--gselz1select files in grid by ctrl-click (volflag=gsel)z--localtimez(default to local timezone instead of UTCz--langLANGengz4language; one of the following: [32meng nor chi[0mr  z--themer  r   zdefault theme to use (0..7)z--themesr  znumber of themes installedz--au-volz0-100r  e   z"default audio/video volume percent)r  r  rL   choicesrK   z--sortzC,C,Chrefzdefault sort order, comma-separated column IDs (see header tooltips), prefix with '-' for descending. Examples: [32mhref -href ext sz ts tags/Album tags/.tn[0m (volflag=sort)z--nsortzMdefault-enable natural sort of filenames with leading numbers (volflag=nsort)z--hsortnr  r   zLnumber of sorting rules to include in media URLs by default (volflag=hsortn)z
--see-dotszWdefault-enable seeing dotfiles; only takes effect if user has the necessary permissionsz--qdelr  z;number of confirmations to show when deleting files (2/1/0)z--unlistREGEXr<   zdon't show files/folders matching [33mREGEX[0m in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [[32m\.(js|css)$[0m] (volflag=unlist)z--favicor  z
c 000 noneu   🎉 000 nonez[[33mfavicon-text[0m [ [33mforeground[0m [ [33mbackground[0m ] ], set blank to disablez--ext-thzE=VPr   z[34mREPEATABLE:[0m use thumbnail-image [33mVP[0m for file-extension [33mE[0m, example: [[32mexe=/.res/exe.png[0m] (volflag=ext_th)r  z--mpmc)r  rL   rK   z	--spinneru   🌲uG   [33memoji[0m or [33memoji,css[0m Example: [[32m🥖,padding:0[0m]z--css-browserLz8URL to additional CSS to include in the filebrowser htmlz--js-browserz7URL to additional JS to include in the filebrowser htmlz
--js-otherz2URL to additional JS to include in all other pagesz--html-headztext to append to the <head> of all HTML pages (except for basic-browser); can be @PATH to send the contents of a file at PATH, and/or begin with %% to render as jinja2 template (volflag=html_head)z--ihzif a folder contains index.html, show that instead of the directory listing by default (can be changed in the client settings UI, or add ?v to URL for override)z--textfilesCSVztxt,nfo,diz,cue,readmez'file extensions to present as plaintextz	--txt-maxKiBrN  zSmax size of embedded textfiles on ?doc= (anything bigger will be lazy-loaded by JS)z
--doctitlezcopyparty @ --namez.title / service-name to show in html documentsz--bnamer  z5server name (displayed in filebrowser document title)z--pb-urlURLz*powered-by link; disable with [33m-nb[0mz--verzBshow version on the control panel (incompatible with [33m-nb[0m)z--k304zconfigure the option to enable/disable k304 on the controlpanel (workaround for buggy reverse-proxies); [[32m0[0m] = hidden and default-off, [[32m1[0m] = visible and default-off, [[32m2[0m] = visible and default-onz--no304zconfigure the option to enable/disable no304 on the controlpanel (workaround for buggy caching in browsers); [[32m0[0m] = hidden and default-off, [[32m1[0m] = visible and default-off, [[32m2[0m] = visible and default-onz--ctl-rer  r   zTthe controlpanel Refresh-button will autorefresh every SEC; [[32m0[0m] = just oncez--md-sbfFLAGSz@downloads forms popups scripts top-navigation-by-user-activationzlist of capabilities to allow in the iframe 'sandbox' attribute for README.md docs (volflag=md_sbf); see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandboxz--lg-sbfzklist of capabilities to allow in the iframe 'sandbox' attribute for prologue/epilogue docs (volflag=lg_sbf)z--md-sbazpthe value of the iframe 'allow' attribute for README.md docs, for example [[32mfullscreen[0m] (volflag=md_sba)z--lg-sbazthe value of the iframe 'allow' attribute for prologue/epilogue docs (volflag=lg_sba); see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#iframesz
--no-sb-mdzFdon't sandbox README/PREADME.md documents (volflags: no_sb_md | sb_md)z
--no-sb-lgzYdon't sandbox prologue/epilogue docs (volflags: no_sb_lg | sb_lg); enables non-js supportz--have-unlistc)r  r  r  ra  rangerM   rN   r-   )r  retryr  s      rH   add_uirt    s   



-CXl9ijXl9lm]<>hiXvAu  LH  IYCIfgZS!JfgZsBPUVWY\P]  eI  JXwQ  NF  GY|  ;J  KZ3  IW  X\,  >W  XXu3  IF  GZq"  LQ  RZQPU[j  ra  bZa  Pt  uXAr8I8IJ[%a  Oj  k_c2  MG  H^Sq"  LE  F\3QI}~]E2  MT  UVL  8Z  []EC[  cL  M[%c2  Mb  c\5qBV  ^N  OYAx  OF  GZQ  OA  BW\  9C  DXu3  Iy  zYC  J  @ZS!  Kg  hZq  CE  L  @Zq  CE  Ly  zZQ  JB  CZQ  J{  |\,  >F  G\,  >Y  Z%lARARSrI   c                    | j                  d      }|j                  ddd       |j                  ddd       |j                  ddd	       t        t        d
      r|j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddt        dd       |j                  d d!t
        d"d#       |j                  d$d%t        dd&       |j                  d'dd(       |j                  d)d*t        d+d,       |j                  d-d.t        d/d0       |j                  d1d.t        dd2       |j                  d3dt        j                         y )4Nzdebug optionsz--vcr  z+verbose config file parser (explain config)r  z--cgenzFgenerate config file from current config (best-effort; probably buggy)z--depsz5list information about detected optional dependenciespollz	--no-pollzXkernel-bug workaround: disable poll; use select instead (limits max num clients to ~700)z--no-sendfilezRkernel-bug workaround: disable sendfile; do a safe and slow read-send-loop insteadz--no-scandirzPkernel-bug workaround: disable scandir; do a listdir + stat on each file insteadz--no-fastbootzEwait for initial filesystem indexing before accepting client requestsz--no-htpz?disable httpserver threadpool, create threads as-needed insteadz--rm-sckzYwhen listening on unix-sockets, do a basic delete+bind instead of the default atomic bindz
--srch-dbgzDexplain search processing, and do some extra expensive sanity checksz--rclone-mdnsz,use mdns-domain instead of server-ip on /?hcz
--stackmonzP,Sr<   ztwrite stacktrace to [33mP[0math every [33mS[0m second, for example --stackmon=[32m./st/%%Y-%%m/%%d/%%H%%M.xz,60r  z
--log-thrsr  r  z&list active threads every [33mSEC[0mz--log-fkrl  zglog filekey params for files where path matches [33mREGEX[0m; [[32m.[0m] (a single dot) = all filesz--bak-flipszy[up2k] if a client uploads a bitflipped/corrupted chunk, store a copy according to [33m--bf-nc[0m and [33m--bf-dir[0mz--bf-ncr     ztbak-flips: stop if there's more than [33mNUM[0m files at [33m--kf-dir[0m already; default: 6.3 GiB max (200*32M)z--bf-dirr  bfzmbak-flips: store corrupted chunks at [33mPATH[0m; default: folder named 'bf' wherever copyparty was startedz--bf-logz=bak-flips: log corruption info to a textfile at [33mPATH[0mz--no-cfg-cmt-warn)	r  r  r  selectr  r  ra  rM   rN   r  s     rH   	add_debugrz  =  s3   



0CVL7deXl  :B  CXl9pqvv\  A[  	\_\  AU  V^L  @R  S_\  AH  IZ;|}Z  <W  X\,  >D  E_\@no\5q"  LQ  R\5ucP~Zq"  LA  B]<  ?F  GYC  LN  OZa  MB  CZa  KP  Q(HDUDUVrI   c           	      j   t        j                  |t         j                  ddj                  t        t
                    }t        j                  j                  t        j                  d      }t        dd      }t        dd      }t        d	d      }	t        t        t        d
kD  rdnd      }
t        j                  j                  dd      j!                         dk(  }t#        |      }t%        |||       t'        |       t)        ||       t+        ||       t-        |       t/        |       t1        ||       t3        |       t5        |       t7        |       t9        |       t;        |       t=        |       t?        ||
       tA        |       tC        |       tE        |       tG        |       tI        |       tK        |       tM        |       tO        |       tQ        |       tS        ||||	       tU        |       tW        |       tY        |       t[        |       t]        |       t_        |       ta        |       tc        |       te        |       tg        ||       ti        |       tk        |       tm        |       |jo                  d      }tq               }|D ]  \  }}}|js                  d|z   d|        	 |s
tu               |jv                  D ]A  }|jx                  sddg}  |jx                  jz                  | j|                  | dz   |_<        C 	 |j                  | dd        }|D ]m  \  }}}d|j                  dd      z   }t        |      |   s+t        d|d|d       t        |j                         dz          t        j                  d       o |S #  Y xY w) Nr   zhttp file sharing hub v{} ({}))formatter_classusageprogr  zcert.pemfk   dk   ahr  r   r:   TERMr<   linuxzhelp sectionsz--help-r  r  asciir   z[0mr   )rE   help_r  r   z# z help page ()r   )FrM   ArgumentParserrN   r   r   r   r   r   rb   r   r   r   rD  r   r   r   r   r   r  r  r  r  r  r  r  r  r  r   r  r  r  rZ  r\  rF  rK  rS  r  r
  r  r  r'  r1  r   r5  r  r  r  r  r_  rM  re  rt  r:  r8  rz  r  r  r  r   _actionsrK   r   r   
parse_argsr   varsr   r}  r   r  )argv	formatterrs  r  r   r  r  r.  r/  r0  rX  r  r  r  sectsr  rK  r   rv   r   rW   r   k2s                          rH   run_argparser  X  s    
	 	 !4;;IzR	
B QUUJ/ItR GtR GtR G
 UQYA.F
**..
$
*
*
,
7C'"GB OB	RRLRL
2sOOO
2JbMrN2vB"BBKBKrNRLBKrNR'7+ORLbMbMBKRL
2J
2ubMObM



0CKE E1aQ|!DE+ 	>A66)$A-]QVV]]A&--q1I=AF	> --T!"X-
&C 1aqyyc**9R=Aq12188:	)*HHQK Js   AN. .N2c           
      *   t        j                  dd       t        rt        j                  d       t        t               | t        j                  } d}|j                  t        t        t        t        j                  dd      t        t         t"        t$              }t'        |       d| v rt        j(                  d       d	| v rt+                t        j(                  d       d
| v rQt-        dj/                  d t1        t3        j4                               D                     t        j(                  d       t6        r t-        dj                  t8              d       t;        |       D ]N  \  }}|j=                  d      st?        t@        d|jC                  dd      d   f       | jE                  |        n tG                tI                tJ        r#tM        tJ        d         }| jO                  |       tQ        | dd  | dd        D ]G  \  }}|dk(  st        jR                  jU                  |      s,tM        |      }| jO                  |       I | dd  D ]X  }|dd  }|j=                  d      s|st        jR                  jU                  |      s=tM        |      }| jO                  |       Z g d}|D ]  \  }}	d}
d}t;        |       D ]>  \  }}||k(  s|j=                  |dz         s |}
d|v s'd|jC                  dd      d   z   }@ |
dk  r\d}t'        |j                  ||	             |	|z   | |
<   t        jV                  d        tY        |       dk(  xr tJ         }	 |r?| jO                  dg       tZ        st        j\                         s| jO                  ddg       |r.d}t'        |j                  dj/                  | dd                     d}	 dd l/}|ja                  |jb                        \  }}|dkD  rte        |tg        |dz              }d!}th        th        tj        tl        fD ]!  }	 to        | |||      }to        g |||d!      } n 	 sJ sJ t        |_        jt                  rd!|_;        n|jv                  stx        |_:        t        r#|jz                  s|j|                  s	 t                |jt                  sd|_@        t        D ]  \  }}t        ||      st        ||d"       ! t        D ]  \  }}t        ||      st        ||d!       ! t        s|j                  d%k(  rd&|_F        |j                  jC                  d'      |_F        	 d(|j                  v rS|j                  jC                  d(      D cg c]  }tg        |       c}\  }}t        t        ||dz               |_G        n7|j                  jC                  d'      D cg c]  }tg        |       c}|_G        g d*fD ]K  \  }}}t        t        ||            }||jC                         vs/d+}t        |j                  |||             |j                  s)| D cg c]  }|j=                  d      s| c}rd"|_M        |j                  r-|j                  D cg c]  }|j                          c}|_N        |j                  r-|j                  D cg c]  }|j                          c}|_P        t        r/|j                  rt        |       |j                  rt        |       nt        d,       d"|_W        t        rt        r|j                  rt        d-       t        r|j                  rt-        d.       y t        sd"|_\        t        t        d/      sd"|_^        t        t        d0      sd"|_`        t        || dj/                  t                    j                          y #  Y @xY w#  d }Y xY w# tp        $ r   d"}t'        d#j                  |ts                            Y xY w#  t        j(                  d       Y xY w#  t'        d$ts               z   dz          Y xY wc c}w c c}w #  t        d)      xY wc c}w c c}w c c}w )1N19970815z%Y%m%dremzc[36mcopyparty v{} "[35m{}[36m" ({})
{}[0;36m
   sqlite {} | jinja {} | pyftpd {} | tftp {}
[0mr  z[90m[r  r   r  r  r\   c              3   2   K   | ]  \  }}|d d|  yw)z>8rg   Nr]   )r^   r  r   s      rH   ra   zmain.<locals>.<genexpr>  s     LdaAq)Lr   z
pybin: {}
r<   )rp   z--sfx-tpoke=z	sfx-tpoker  r   r   r  ))z--saltr,  )z--hdr-au-usrr  )z--idp-h-sepr  )z--th-no-cropz--th-crop=n)z--never-symlinkr  r  z\[1;31mWARNING:[0;1m
  {} [0;33mwas replaced with[0;1m {} [0;33mand will be removed
[0mr  z-p80,443,3923r3  z#no arguments provided; will use {}
rg   i   r:   i  FTz
[ {} ]:
{}
z$
failed to disable quick-edit-mode:
r  z0.0.0.0r   r  zinvalid value for -p)r  u2sortz	s n fs fnz0argument {} cannot be '{}'; try one of these: {}z.ssl module does not exist; cannot enable httpszewindows py2 cannot do unicode filenames with -e2d
  (if you crash with codec errors then that is why)zerror: python2 cannot --smbsendfilerv  )drb  strptimer   r   systemr   r   r   r  r   r   r   r   r%   r   r*   r"   r&   r$   r   r  rp  r   rb   r   r#   r!  r	   r5   rm   r   r.   rl  r   r   r   r   r  r(  r.  zipr   isfilerf  r   r   geteuidresource	getrlimitRLIMIT_NOFILErD  ra  r>   r   r   r  
SystemExitr4   ansino_ansir   keep_qemah_clir]  wintitler!   r  setattrr+   r    ru   r   rc  rr  r   r   qrsqriheadr   oheadHAVE_SSLr   r  r  r  r   	http_onlyr   e2dsmbr   
no_scandirr  no_sendfilery  no_pollr   r   run) r  r   r@  zssuppr  r   
deprecatedr  nkrh   ovr   dar   r  r  r   hardrs  fmtrr  dalk1r  rv   lohiargknameokaysvals                                    rH   mainr    s    MM*h'
		%
1I|xxA	[)		A 1Idd	DdiiLfU[[]6KLLM
m""5)r24 2==(9kBHHS!,<Q,?+ABHHQK	 OWQZ(DDHd12h' 19* #DKK
 !"X abE<<!q(9 #DKK	J  BdO 	2DAqBw!,,rCx0!8qwwsAq11B		2 7 Aszz"b!"GS	

1" 
Ta	'KBKK!RZZ\_m<= 
2qxxab*+,	B$$X%;%;<4!8RTAX'B Ez?K 	=	=dD%4Br4E:C		=	r
s 
ww
ZZr{{299	O 77  "B2r?BD!"
  #B2r?BE"# 44::c?BD0"$$;&(ddjjo6c!f6FBb"q&)*BD$&DDJJsO4qCF4BD BB 8UEgb%()ekkm#CBBIIc3677	8 66$?Q!,,v*>q?	xx')xx0!AGGI0	xx')xx0!AGGI0::b!::!"%=>
w266D	

 rvv+,2z"66"
 2sD"'''*+//1o  		=E$++D&(;<	O;fhFMN* 7 50.// @ 1 1s   *A_& ?_. 9_8`. 7
a !+a6 a,Aa6 a11a6 b3bbb&_+._580`+.aa),
a6 6b__main__)NN)Tr   )
__future__r   r   
__author____copyright____license____url__rM   r   r   r   rS   ry  r   r   r*  rb  r/  uuidrB   r   r   r	   r
   r   r   r   r   r   r   r   __version__r   r   r   authsrvr   r   r   r   r   r   svchubr   utilr   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   xrangerr  r   r   r   r  r   r  r   uuid4urnr  r  r   HelpFormatterr>   r   ArgumentDefaultsHelpFormatterRawDescriptionHelpFormatterr   r   r   r   r   r   r   r   r  r  r(  r5  r]  rl  rp  r  r~  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r
  r  r  r  r  r  r  r   r'  r1  r5  r8  r:  rF  rK  rM  rS  rZ  r\  r_  re  rt  rz  r  r  r{   r]   rI   rH   <module>r     s   8 0$

.    	 	   
        9 8 F F "        B E	zz~~m$kH tzz|::>>-,
-qzKKM3BH** 3Bl: :?**H,P,P?@Qh2#,! &3V0:-"`&DNV(	wRC'xTO2Cf&w(QDu.q
cC
^HYL bCI4P>OTp$	DkD
Toy<{"	Ho$'TTW8 -1YxT2n zF q9Hs   (H6 6H=