o ~_O@sddlmZddlmZddlmZeddlmZddlmZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlmZdd lmZdd lmZddlZd Zd Ze d ZddZ dddZ!Gdddej"j#Z$ej"%de$dS))print_function)division)standard_library)input)strN)logconfig)progressBackendException)ConnectionErroriiz \([0-9]+\)\.[^\.]+$cCsZtd|ft}tj|d|d|D] }td|q| dS)NzException [%s]:)filerz| ) rErrorioStringIO traceback print_excseek readlinesrstripclose)efsr@/usr/lib/python3/dist-packages/duplicity/backends/dpbxbackend.py log_exception?s    rTcCs dd}|S)z6a decorator for handling authentication and exceptionscsfdd}j|_|S)Nc sxz |g|RWSty }z t|td|fd}~wty;}zt|td|ftjjd}~ww)Nzdpbx api error "%s"zdpbx code error "%s")ApiErrorrr Exceptionrr ErrorCodebackend_code_error)selfargsrrrrwrapperLsz*command..decorate..wrapper)__doc__)rr$rr#rdecorateKs  zcommand..decorater)login_requiredr&rrrcommandIsr(c@seZdZdZddZddZddZdd Zd d Zd d Z ddZ e ddZ ddZ ddZe ddZe ddZe ddZe ddZe ddZd d!Zd"S)# DPBXBackendz-Connect to remote store using Dr*pB*x servicec Cstjj||z*ddlmaddlmamam a ddl m a m a m a mamamamaddlmaWntyF}ztdt|d}~wwd|_d|_d|_|dS)Nr)Dropbox) AuthError BadInputErrorr)UploadSessionCursor CommitInfo WriteModeGetMetadataError DeleteErrorUploadSessionLookupErrorListFolderError)DropboxOAuth2FlowNoRedirectzvThis backend requires the dropbox package version 6.9.0 To install use "sudo pip install dropbox==6.9.0" Exception: %s) duplicitybackendBackend__init__dropboxr*dropbox.exceptionsr+r,r dropbox.filesr-r.r/r0r1r2r3 dropbox.oauthr4 ImportErrorr r api_account api_client auth_flowlogin)r! parsed_urlrrrrr8_s  $ zDPBXBackend.__init__cCs6z|j}td|WdStdYdS)NzUser authenticated as ,%sTzUser not authenticatedF)r?users_get_current_accountrDebug)r!accountrrruser_authenticated}s  zDPBXBackend.user_authenticatedcCstjddS)NDPBX_ACCESS_TOKEN)osenvirongetr!rrrload_access_tokenszDPBXBackend.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!rrrrrAs$      zDPBXBackend.logincCsvt|tr3|j}t|tr|r|rtjj SdSt|t r5| r7|j }|r9tjj SdSdSdSdSN) isinstancererrorr0is_pathget_path is_not_foundrrbackend_not_foundr1is_path_lookupget_path_lookup)r! operationrerrlookuprrr _error_codes   zDPBXBackend._error_codecCstj|jjd}dtj|| }tj |j }t d||tkr0|||}n|||}|j|krDtd|j|f|j|krRtd|j|fdS)N/rz-dpbx: result path mismatch: %s (expected: %s)z-dpbx: result size mismatch: %s (expected: %s))urllibparseunquoterBpathlstriprHjoindecodergetsizerdr report_transferDPBX_UPLOAD_CHUNK_SIZEput_file_smallput_file_chunked path_displayr size)r! source_pathremote_filename remote_dir remote_path file_size res_metadatarrr_puts     zDPBXBackend._putcCs|s|tj|j}|d}z,td||f|j j | |t j dddd}td|t|||W|S|w)Nrbz!dpbx,files_upload(%s, [%d bytes])FTmode autorenameclient_modifiedmutezdpbx,files_upload(): %s)rFrArHrwr{rdopenrrDr? files_uploadreadr/ overwriter r|r)r!rrrrrrrrr~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} | st |dkrWqXd} t} tj} | st |dksJt dt ||jf|j ||j|jnt d t ||jf|j |||} ||_t d |j|ft|j|Wnxty}z/|j}t|tr| r|!j"}t d |j|f| dur t#d |} WYd}~qXd}~wt$yR}z0t d || d8} |s2|| dkr8t %dt&'dtd} d} WYd}~qXd}~ww| r]| r]||krbt#dt d| t||| W|(S|(w)Nrz6dpbx,files_upload_session_start([%d bytes]), total: %dz%dpbx,files_upload_session_start(): %sFTrrz8dpbx,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: %sz'dpbx: sleeping a bit before chunk retryzdpbx: something wrongz'dpbx,files_upload_sesssion_finish(): %s))rFrArHrwr{rdrrr}rrDlenr?files_upload_session_startr- session_idtellr.r/rr r|r num_retriesoffsetrfiles_upload_session_appendfiles_upload_session_finishrrhrgr2is_incorrect_offsetget_incorrect_offsetcorrect_offsetr r rRtimesleepr)r!rrrrbuf upload_sid upload_cursor commit_inforrequested_offsetcurrent_chunk_size retry_numberis_eofrrh new_offsetrrrrs                    LzDPBXBackend.put_file_chunkedc Cs|s|tj|jjd}dtj ||  }t d||j|\}}t d|||f|j}d}td|z&|d}|tD]} || t||qOW|rf||n |rq||wtj|j} | |krtd| |f|dS)Nrszdpbx,files_download(%s)zdpbx,files_download(%s): %s, %srwbz(dpbx: wrong file size: %d (expected: %d))rFrArtrurvrBrwrxrHryrzrrrDr?files_downloadrr r|r iter_contentDPBX_DOWNLOAD_BUF_SIZEwriterrr{rdr setdata) r!r local_pathrrrhttp_fdrto_fdc local_sizerrr_getls<       zDPBXBackend._getc Cs|s|dtj|jjd}t d|g}z)|j |}t d||f | dd|jD|js@n|j |j}q1Wn/tyx}z#t|jtrm|jrm|jrmt d||fnWYd}~nd}~ww|||S)Nrszdpbx.files_list_folder(%s)zdpbx.list(%s): %sTcSsg|]}|jqSr)rd).0entryrrr sz%DPBXBackend._list..z)dpbx.list(%s): ignore missing folder (%s))rFrArtrurvrBrwrxrrrDr?files_list_folderextendentrieshas_morefiles_list_folder_continuecursorrrgrhr3rirjrkcheck_renamed_files)r!rresresprrrr_lists4    zDPBXBackend._listcCs^|s|tj|jjd}dtj ||  }t d||j|dS)Nrszdpbx.files_delete(%s))rFrArtrurvrBrwrxrHryrzrrrDr? files_delete)r!filenamerrrrr_deletes zDPBXBackend._deletecCstddS)z0close backend session? no! just "flush" the dataz dpbx.close():N)rrDrKrrr_closeszDPBXBackend._closecCsv|s|tj|jjd}dtj ||  }t d||j|}t d||fd|jiS)Nrszdpbx.files_get_metadata(%s)zdpbx.files_get_metadata(%s): %sr)rFrArtrurvrBrwrxrHryrzrrrDr?files_get_metadatar)r!rrrinforrr_querys  zDPBXBackend._querycCs|s|dd|D}t|dkrdStdtdtdtdtdtd tdtd td tdtd |D] }td |qPtdtdtddS)NcSsg|] }t|dur|qSrf)DPBX_AUTORENAMED_FILE_REsearch)rxrrrrsz3DPBXBackend.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.)rFrArrWarn)r! file_listbad_listrrrrrs*              zDPBXBackend.check_renamed_filesN)__name__ __module__ __qualname__r%r8rFrLrNrcrArrr(rr~rrrrrrrrrrrr)\s0  r "     r)dpbx)T)& __future__rrfuturerinstall_aliasesbuiltinsrrrrHrerSrrurllib.requestrt urllib.parse urllib.errorr5rrr duplicity.errorsr requests.exceptionsr duplicity.backendr}rcompilerrr(r6r7r)register_backendrrrrs<