o nD!a=@sddlmZeddlZddlZddlZddlZddlZddl Zddl Z ddl Z ddl mZddl mZddl mZddl mZGddde jjZe jd edS) )standard_libraryN)BackendException)config)log)utilc@seZdZdZgZiZegdZdZeddgZ dZ eddgZ dZ dZ ed d Zd d Zd dZddZddZddZddZddZddZddZdS) MultiBackendzStore files across multiple remote stores. URL is a path to a local file containing URLs/other config defining the remote store)modeonfailsubpathstripemirrorcontinueabortrc Cstj|}t|jdkrtSz tjj|jdd}Wnty;}zt t d|j|ft j t dd}~wwt}t|D]9\}}t|dkrat t d|j|ft j t d|tjvrxt t d |j|ft j t d|d||<qE|S) NrT)strict_parsingz2MultiBackend: Could not parse query string %s: %s zCould not parse query stringzAMultiBackend: Invalid query string %s: more than one value for %szInvalid query stringz;MultiBackend: Invalid query string %s: unknown parameter %s)urllibparseurlparsegeturllenquerydictparse_qs ValueErrorrLog_ERRORrlistitemsr#_MultiBackend__knownQueryParameters) parsed_url reparsed_urlqueryMultiDicte queryDictname valueListr(A/usr/lib/python3/dist-packages/duplicity/backends/multibackend.pyget_query_paramsWs@     zMultiBackend.get_query_paramsc CsZtjj||t|}d|vr|d|_d|vr|d|_|jtjvr7t t dd|jft j t d|jtjvrOt t dd|jft j t dd|vrX|d|_zt|j }t|}Wdn1snwYWn+ty}zt t d|t j t t d|j|ft j t d d}~ww|D]}|d |j}tjjd kr|d }t t d |t jd|vr|dD]}t t d|d|dft j|dtj|d<qtj|} |j| d|vr*|jdkrt d|dD]$} t t d| t j| |j vr"|j | | q| g|j | <qqdS)Nrr z&MultiBackend: illegal value for %s: %sz MultiBackend: invalid mode valuez"MultiBackend: invalid onfail valuer zMultiBackend: Url %sz0MultiBackend: Could not load config file %s: %s zCould not load config fileurlzutf-8zMultiBackend: use store %senvzMultiBackend: set env %s = %sr&valueprefixesr z=Multibackend: stripe mode not supported with prefix affinity.z-Multibackend: register affinity for prefix %s)! duplicitybackendBackend__init__rr*_MultiBackend__mode_MultiBackend__onfail_mode_MultiBackend__mode_allowedSetrrrrr%_MultiBackend__onfail_mode_allowedSet_MultiBackend__subpathopenpathjsonloadIOError strip_authsys version_infomajorencodeINFOosenviron get_backend_MultiBackend__storesappend_MultiBackend__affinities) selfr! queryParamsfconfigsr$rr+r-storeprefixr(r(r)r3vs                         zMultiBackend.__init__csFjr fddtjD}fdd|D}|r t|SjS)Ncs g|] }t|r|qSr()rfsdecode startswith).0k)filenamer(r)  z1MultiBackend._eligible_stores..cs h|] }j|D]}|q qSr()rI)rRrOrN)rJr(r) rVz0MultiBackend._eligible_stores..)rIrkeysrG)rJrTmatching_prefixesmatching_storesr()rTrJr)_eligible_storess zMultiBackend._eligible_storesc CsTd}||}|jdkrd|_|j} ||j}z=|jd}|t|dkr(d}ttd|j|jj ftj | ||d}||_|dkrLWdS|jdkrTWdSWnSt y}zGttd|j|jj ||ftj ||_|jd krttd |tjtd |j|kr|sttd |tjtd WYd}~nd}~wwq) NFr rTrz+MultiBackend: _put: write to store #%s (%s)r zGMultiBackend: failed to write to store #%s (%s), try #%s, Exception: %srz3MultiBackend: failed to write %s. Aborting process.zfailed to writezMMultiBackend: failed to write %s. Tried all backing stores and none succeeded)r[r4_MultiBackend__write_cursorrrrrr1r!r>DEBUGput ExceptionrCr5rr) rJ source_pathremote_filenamepassedstoresfirstrNnextr$r(r(r)_puts`           zMultiBackend._putcCsx||}|D]%}|}||vr|||dSttd|||jjftj qttd|tj t d)Nz,MultiBackend: failed to get %s to %s from %szKMultiBackend: failed to get %s. Tried all backing stores and none succeededz failed to get) r[rgetrrrr1r!r>rCrr)rJra local_pathrcsflistr(r(r)_gets"    zMultiBackend._getc Csg}|jD]E}dgftjd<|}ttd|jj t |ft |dkrEt jj rEt td|jj tt jj fdt j_ ||qtdd|D}ttd|tj|S) NFrzMultiBackend: %s: %d filesrzException during list of %s: %scSsh|] }|D]}|qqSr(r()rRsublistitemr(r(r)rW<sz%MultiBackend._list..zMultiBackend: combined list: %s)rGrare_errors_fatalrrNoticerr1r!r>rr0_last_exceptionWarnruexcrHrr])rJlistsrilresultr(r(r)_list.s,      zMultiBackend._listcCsd}||}|D],}|}||vr5t|jdr ||gn t|jdr+||d}|jdkr5dSq |sEtt d|tj dSdS)NF _delete_list_deleteTr NMultiBackend: failed to delete %s. Tried all backing stores and none succeeded) r[rhasattrr1_do_delete_list _do_deleter4rrrr)rJrTrbrcrirjr(r(r)rxBs(      zMultiBackend._deletecsd}|j}|D]5}|fdd|D}t|jdr"||nt|jdr2|D]}||q*d}|jdkr<dSq|sLtt d|tj dSdS) NFcsg|]}|vr|qSr(r()rRrLrjr(r)rUlsz-MultiBackend._delete_list..rwrxTr ry) rGrrzr1r{r|r4rrrr)rJ filenamesrbrcricleanedrTr(r}r)rw^s*      zMultiBackend._delete_listcCs(|jD]}t|jdr|j|qdS)Npre_process_download)rGrzr1r)rJrTrNr(r(r)r{s   z!MultiBackend.pre_process_downloadcCsJt|}|jD]}t|jdr"||}t|dkr"|j|qdS)Npre_process_download_batchr)setrGrzr1 intersectionrrr)rJr~ set_filesrNstore_files_to_downloadr(r(r)rs    z'MultiBackend.pre_process_download_batchN)__name__ __module__ __qualname____doc__rGrI frozensetr r4r6r5r7r8r\ staticmethodr*r3r[rfrkrvrxrwrrr(r(r(r)r+s8   e 2 rmulti)futurerinstall_aliasesrDos.pathr?urllib.requestr urllib.parse urllib.errorr;duplicity.backendr0duplicity.errorsrrrrr1r2rregister_backendr(r(r(r)s$     `