o —~µ_½Oã@sddlmZddlmZddlmZe ¡ddlmZddlmZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlmZdd lmZdd lmZddlZd Zd Ze  d ¡Zdd„Z ddd„Z!Gdd„dej"j#ƒZ$ej" %de$¡dS)é)Úprint_function)Údivision)Ústandard_library)Úinput)ÚstrN)ÚlogÚconfig)Úprogress©ÚBackendException)ÚConnectionErroriiz \([0-9]+\)\.[^\.]+$cCsZt d|f¡t ¡}tj|d| d¡| ¡D] }t d| ¡¡q|  ¡dS)NzException [%s]:)Úfilerz| ) rÚErrorÚioÚStringIOÚ tracebackÚ print_excÚseekÚ readlinesÚrstripÚclose)ÚeÚfÚs©rú@/usr/lib/python3/dist-packages/duplicity/backends/dpbxbackend.pyÚ log_exception?s    rTcCs dd„}|S)z6a decorator for handling authentication and exceptionscs‡fdd„}ˆj|_|S)Nc sxz ˆ|g|¢RŽWSty }z t|ƒtd|fƒ‚d}~wty;}zt|ƒt d|ftjj¡‚d}~ww)Nzdpbx api error "%s"zdpbx code error "%s")ÚApiErrorrr Ú ExceptionrrÚ ErrorCodeÚbackend_code_error)ÚselfÚargsr©rrrÚwrapperLs€€ýz*command..decorate..wrapper)Ú__doc__)rr$rr#rÚdecorateKs  zcommand..decorater)Úlogin_requiredr&rrrÚcommandIsr(c@s´eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z e ƒdd„ƒZ dd„Z dd„Ze ƒdd„ƒZe ƒdd„ƒZe ƒdd„ƒZe ƒdd„ƒZe ƒdd„ƒZd d!„Zd"S)#Ú DPBXBackendz-Connect to remote store using Dr*pB*x servicec Cs¬tjj ||¡z*ddlmaddlmamam a ddl m a m a m a mamamamaddlmaWntyF}ztdt|ƒƒ‚d}~wwd|_d|_d|_| ¡dS)Nr)ÚDropbox)Ú AuthErrorÚ BadInputErrorr)ÚUploadSessionCursorÚ CommitInfoÚ WriteModeÚGetMetadataErrorÚ DeleteErrorÚUploadSessionLookupErrorÚListFolderError)ÚDropboxOAuth2FlowNoRedirectzvThis backend requires the dropbox package version 6.9.0 To install use "sudo pip install dropbox==6.9.0" Exception: %s)Ú duplicityÚbackendÚBackendÚ__init__Údropboxr*Údropbox.exceptionsr+r,rÚ dropbox.filesr-r.r/r0r1r2r3Ú dropbox.oauthr4Ú ImportErrorr rÚ api_accountÚ api_clientÚ auth_flowÚlogin)r!Ú parsed_urlrrrrr8_s  $ý€ÿ zDPBXBackend.__init__cCs6z|j ¡}t d|¡WdSt d¡YdS)NzUser authenticated as ,%sTzUser not authenticatedF)r?Úusers_get_current_accountrÚDebug)r!ÚaccountrrrÚuser_authenticated}s  zDPBXBackend.user_authenticatedcCstj dd¡S)NÚDPBX_ACCESS_TOKEN)ÚosÚenvironÚget©r!rrrÚload_access_token†szDPBXBackend.load_access_tokencCs td|ƒ‚)Nzdpbx: Authentication failed. Trying to obtain new access tokenz3dpbx: Please update DPBX_ACCESS_TOKEN and try againz&dpbx: Successfully authenticated as %s)rLrcr*r?r>rrDrCr,r+rRr ÚnameÚ display_name)r!rrrrrA¬s$    €ø  ÿzDPBXBackend.logincCsvt|tƒr3|j}t|tƒr| ¡r| ¡ ¡rtjj SdSt|t ƒr5|  ¡r7|j  ¡}| ¡r9tjj SdSdSdSdS©N) Ú isinstancerÚerrorr0Úis_pathÚget_pathÚ is_not_foundrrÚbackend_not_foundr1Úis_path_lookupÚget_path_lookup)r!Ú operationrÚerrÚlookuprrrÚ _error_codeÄs  ÿ ÷zDPBXBackend._error_codecCs¨tj |jj d¡¡}dtj || ¡¡  ¡}tj  |j ¡}t   d|¡|tkr0| ||¡}n| ||¡}|j|krDtd|j|fƒ‚|j|krRtd|j|fƒ‚dS)Nú/rz-dpbx: result path mismatch: %s (expected: %s)z-dpbx: result size mismatch: %s (expected: %s))ÚurllibÚparseÚunquoterBÚpathÚlstriprHÚjoinÚdecoderÚgetsizerdr Úreport_transferÚDPBX_UPLOAD_CHUNK_SIZEÚput_file_smallÚput_file_chunkedÚ path_displayr Úsize)r!Ú source_pathÚremote_filenameÚ remote_dirÚ remote_pathÚ file_sizeÚ res_metadatarrrÚ_putÐs    ÿ ÿÿzDPBXBackend._putcCsŒ| ¡s| ¡tj |j¡}| d¡}z,t d||f¡|j j |  ¡|t j dddd}t d|¡t ||¡|W| ¡S| ¡w)NÚrbz!dpbx,files_upload(%s, [%d bytes])FT©ÚmodeÚ autorenameÚclient_modifiedÚmutezdpbx,files_upload(): %s)rFrArHrwr{rdÚopenrrDr?Ú files_uploadÚreadr/Ú overwriter r|r)r!r‚r…r†rr‡rrrr~æs  ü zDPBXBackend.put_file_smallc Csú| ¡s| ¡tj |j¡}| d¡}zb| t¡}t   dt |ƒ|f¡|j   |¡}t   d|¡t|j| ¡ƒ}t|tjdddd}d} t | ¡|¡d} t} tj} d} | r]| sWz}| dure| |_| ¡|jkrr| |j¡| | ¡}| ¡|k} | s‡t |ƒdkr‡WqXd} t} tj} | s¯t |ƒdks˜J‚t   dt |ƒ|jf¡|j  ||j|j¡nt   d t |ƒ|jf¡|j  |||¡} | ¡|_t   d |j|f¡t |j|¡Wnxty}z/|j}t|tƒr|  ¡r| !¡j"}t   d |j|f¡| dur t#d ƒ‚|} WYd}~qX‚d}~wt$yR}z0t   d |¡| d8} | ¡s2| ¡| dkr8‚t  %d¡t& 'd¡td} d} WYd}~qXd}~ww| r]| r]| ¡|krbt#dƒ‚t   d| ¡t | ¡|¡| W| (¡S| (¡w)Nr‰z6dpbx,files_upload_session_start([%d bytes]), total: %dz%dpbx,files_upload_session_start(): %sFTrŠrz8dpbx,files_upload_sesssion_append([%d bytes], offset=%d)z8dpbx,files_upload_sesssion_finish([%d bytes], offset=%d)zprogress: %d of %dzEdpbx,files_upload_session_append: incorrect offset: %d (expected: %s)zdpbx: unable to chunk uploadz$dpbx,files_upload_session_append: %séz'dpbx: sleeping a bit before chunk retryéézdpbx: something wrongz'dpbx,files_upload_sesssion_finish(): %s))rFrArHrwr{rdrr‘r}rrDÚlenr?Úfiles_upload_session_startr-Ú session_idÚtellr.r/r’r r|rÚ num_retriesÚoffsetrÚfiles_upload_session_appendÚfiles_upload_session_finishrrhrgr2Úis_incorrect_offsetÚget_incorrect_offsetÚcorrect_offsetr r rRÚtimeÚsleepr)r!r‚r…r†rÚbufÚ upload_sidÚ upload_cursorÚ commit_infor‡Úrequested_offsetÚcurrent_chunk_sizeÚ retry_numberÚis_eofrrhÚ new_offsetrrrrús´   ÿ þ     ÿþ ÿþ  ÿ ÿ  €     €îÈLzDPBXBackend.put_file_chunkedc Cs| ¡s| ¡tj |jj d¡¡}dtj  ||  ¡¡  ¡}t   d|¡|j |¡\}}t   d|||f¡|j}d}t d|¡z&| d¡}| t¡D]} | | ¡t | ¡|¡qOW|rf| ¡| ¡n |rq| ¡| ¡wtj |j¡} | |kr‰td| |fƒ‚| ¡dS)Nrszdpbx,files_download(%s)zdpbx,files_download(%s): %s, %srÚwbz(dpbx: wrong file size: %d (expected: %d))rFrArtrurvrBrwrxrHryrzrrrDr?Úfiles_downloadrr r|rÚ iter_contentÚDPBX_DOWNLOAD_BUF_SIZEÚwriter™rr{rdr Úsetdata) r!rƒÚ local_pathr„r…r‡Úhttp_fdr†Úto_fdÚcÚ local_sizerrrÚ_getls< ÿ   þ þ ÿ zDPBXBackend._getc Cs| ¡s| ¡dtj |jj d¡¡ ¡}t   d|¡g}z)|j   |¡}t   d||f¡ |  dd„|jDƒ¡|js@n|j  |j¡}q1Wn/tyx}z#t|jtƒrm|j ¡rm|j ¡ ¡rmt   d||f¡n‚WYd}~nd}~ww| |¡|S)Nrszdpbx.files_list_folder(%s)zdpbx.list(%s): %sTcSsg|]}|j‘qSr)rd)Ú.0ÚentryrrrÚ sz%DPBXBackend._list..z)dpbx.list(%s): ignore missing folder (%s))rFrArtrurvrBrwrxrrrDr?Úfiles_list_folderÚextendÚentriesÚhas_moreÚfiles_list_folder_continueÚcursorrrgrhr3rirjrkÚcheck_renamed_files)r!r„ÚresÚresprrrrÚ_lists4 ü ÿ þ€ý zDPBXBackend._listcCs^| ¡s| ¡tj |jj d¡¡}dtj  ||  ¡¡  ¡}t   d|¡|j |¡dS)Nrszdpbx.files_delete(%s))rFrArtrurvrBrwrxrHryrzrrrDr?Ú files_delete)r!Úfilenamer„r…rrrÚ_delete­s zDPBXBackend._deletecCst d¡dS)z0close backend session? no! just "flush" the dataz dpbx.close():N)rrDrKrrrÚ_close¼szDPBXBackend._closecCsv| ¡s| ¡tj |jj d¡¡}dtj  ||  ¡¡  ¡}t   d|¡|j |¡}t   d||f¡d|jiS)Nrszdpbx.files_get_metadata(%s)zdpbx.files_get_metadata(%s): %sr)rFrArtrurvrBrwrxrHryrzrrrDr?Úfiles_get_metadatar)r!rÆr„r…ÚinforrrÚ_queryÁs  zDPBXBackend._querycCsÖ| ¡s| ¡dd„|Dƒ}t|ƒdkrdSt d¡t d¡t d¡t d¡t d¡t d ¡t d¡t d ¡t d ¡t d¡t d ¡|D] }t d |¡qPt d¡t d¡t d¡dS)NcSsg|] }t |¡dur|‘qSrf)ÚDPBX_AUTORENAMED_FILE_REÚsearch)r¸ÚxrrrrºÐsz3DPBXBackend.check_renamed_files..rrQzGWarning! It looks like there are automatically renamed files on backendzAThey were probably created when using older version of duplicity.ÚzIPlease check your backup consistency. Most likely you will need to choosezMlargest file from duplicity-* (number).gpg and remove brackets from its name.z?These files are not managed by duplicity at all and will not bezremoved/rotated automatically.zAffected files:z %sz.In any case it's better to create full backup.)rFrAr–rÚWarn)r!Ú file_listÚbad_listrÎrrrrÁÍs*              zDPBXBackend.check_renamed_filesN)Ú__name__Ú __module__Ú __qualname__r%r8rFrLrNrcrArrr(rˆr~rr·rÄrÇrÈrËrÁrrrrr)\s0  r "     r)Údpbx)T)&Ú __future__rrÚfuturerÚinstall_aliasesÚbuiltinsrrrrHÚrerSr¡rÚurllib.requestrtÚ urllib.parseÚ urllib.errorr5rrr Úduplicity.errorsr Úrequests.exceptionsr Úduplicity.backendr}r¯ÚcompilerÌrr(r6r7r)Úregister_backendrrrrÚs<