o Ka<@sddlmZddlmZddlmZddlmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddlmZddl mZdd l mZGd d d e jjZGd d d eZGdddeZGdddeZe jdedS))print_function)division)old_div)input)strN)BackendException)config)logc@sXeZdZdZdZdZddZddZdd Zd d Z d d Z ddZ ddZ ddZ dS)OneDriveBackendz8Uses Microsoft OneDrive (formerly SkyDrive) for backups.z!https://graph.microsoft.com/v1.0/icCsltjj|||jd|_tj dd}d||jf|_ |jdkr't dt j dkr0t d|dS) N/ ONEDRIVE_ROOTz me/drive/rootz%s:/%s/zTYou did not specify a path. Please specify a path, e.g. onedrive://duplicity_backupsl zQYour --volsize is bigger than 10 GiB, which is the maximum file size on OneDrive.) duplicitybackendBackend__init__pathlstrip directoryosenvirongetdirectory_onedrive_pathrrvolsizeinitialize_oauth2_session)self parsed_url onedrive_rootrD/usr/lib/python3/dist-packages/duplicity/backends/onedrivebackend.pyr7s   zOneDriveBackend.__init__cCs@tjd}tjd}|r|rt|||_dSt|j|_dS)NOAUTH2_CLIENT_IDOAUTH2_REFRESH_TOKEN)rrrExternalOAuth2Session http_clientDefaultOAuth2SessionAPI_URI)r client_id refresh_tokenrrrrIs  z)OneDriveBackend.initialize_oauth2_sessioncCsg}|j|jdd} |j|}|jdkrn#||}d|vr,td|||d7}d|vr;|d}nnqdd |DS) Nr z :/childrenTvaluez-Malformed JSON: expected "value" member in %sz@odata.nextLinkcSsg|]}|dqS)namer).0xrrr fsz)OneDriveBackend._list..) r%rrstripr#r status_coderaise_for_statusjsonr)raccumnext_urlresponse responseJsonrrr_listQs(    zOneDriveBackend._listcCs|d}|d1}|jj|j|j|ddd}||jddD] }|r.||q%| WddS1s>wYdS)NUTF-8wbz :/contentT)streami) chunk_size) decodeopenr#rr%rr0 iter_contentwriteflush)rremote_filename local_pathfr4chunkrrr_geths    "zOneDriveBackend._getcCs|d}tj|j}t}|j|jd}| d| vrD| ddd}|rDt d|||krDt d|j||ft dt||}t}|j|j|d}|j|}| t |jd} d | vrt d ||jf| d } d } td |j} || |j} t| d krn3dt| d| | t| d|fd}t d||df|jj| || d}| | t| 7} qt dt|WddS1swYdS)Nr7zme/drive?$select=quotaquota remainingzBytes available: %dzWOut of space: trying to store "%s" (%d bytes), but only %d bytes available on OneDrive.zChecked quota in %fsz:/createUploadSession uploadUrlzAFile "%s" cannot be uploaded: could not create upload session: %sriTz%dzbytes %d-%d/%d)zContent-Length Content-Rangez PUT %s %srI)headersdatazPUT file in %fs)r;rrgetsizer*timer#rr%r0r1r Debugrr<rpostloadscontentrREQUIRED_FRAGMENT_SIZE_MULTIPLEreadlenput)r source_pathr@ source_sizestartr4 available source_fileurl response_jsonrGoffsetdesired_num_fragmentsrCrJrrr_putssf        "zOneDriveBackend._putcCsD|d}|j|j|j|}|jdkrtd||dS)Nr7r(z.File "%s" cannot be deleted: it does not exist)r;r#deleter%rr/rr0rr@r4rrr_deletes   zOneDriveBackend._deletecCs`|d}|j|j|j|}|jdkrddiSd|vr(td|d|diS)Nr7sizez,Malformed JSON: expected "size" member in %s)r;r#rr%rr/r1rrarrr_querys   zOneDriveBackend._querycCs |dSN)r)rrrr_retry_cleanups zOneDriveBackend._retry_cleanupN)__name__ __module__ __qualname____doc__r%rRrrr6rDr_rbrfrhrrrrr 0s 9 r c@s<eZdZdZdZddZddZddZd d Zd d Z d S)OneDriveOAuth2SessionzDA tiny wrapper for OAuth2Session that handles some OneDrive details.z(https://login.live.com/oauth20_token.srfc CsTdtjd<z ddlm}||_Wnty$}ztdt|d}~wwd|_dS)NTRUEOAUTHLIB_RELAX_TOKEN_SCOPEr) OAuth2SessionzeOneDrive backend requires python-requests-oauthlib to be installed. Please install it and try again. ) rrrequests_oauthlibrp session_class ImportErrorrrsession)rrperrrrs    zOneDriveOAuth2Session.__init__cO|jj|i|Srg)rtrrargskwargsrrrrzOneDriveOAuth2Session.getcOrvrg)rtrUrwrrrrUrzzOneDriveOAuth2Session.putcOrvrg)rtrOrwrrrrOrzzOneDriveOAuth2Session.postcOrvrg)rtr`rwrrrr`rzzOneDriveOAuth2Session.deleteN) rirjrkrlOAUTH_TOKEN_URIrrrUrOr`rrrrrms rmcsHeZdZdZejdZdZdZ dZ gdZ fddZ d d Z ZS) r$z?A possibly-interactive console session using a built-in API keyz%~/.duplicity_onedrive_oauthtoken.json000000004C12E85Dz,https://login.live.com/oauth20_authorize.srfz*https://login.live.com/oauth20_desktop.srf)z Files.ReadzFiles.ReadWritez User.Readoffline_accessc stt|d}zt|j }t|}Wdn1swYWnty>}z t d|WYd}~nd}~ww|j |j |j |j |d|j i|j|jd|_|dur_|j|j|j|d}|jdkrnd}|durtjr|tjstd|j|jj|jdd\}}ttd |ttd }|jj|j|d }|j|d}|z!t|jd }t ||WdWdS1swYWdSt!y}zt d |j|fWYd}~dSd}~wwdS)NzMCould not load OAuth2 token. Trying to create a new one. (original error: %s)r&)scope redirect_uritokenauto_refresh_kwargsauto_refresh_url token_updatermerczThe OAuth2 token could not be loaded from %s and you are not running duplicity interactively, so duplicity cannot possibly access OneDrive.touch)displayzIn order to authorize duplicity to access your OneDrive, please open %s in a browser and copy the URL of the blank page the dialog leads to.zURL of the blank page: )authorization_responsewzCould not save the OAuth2 token to %s. This means you need to do the OAuth2 authorization process on every start of duplicity. Original error: %s)"superr$rr<OAUTH_TOKEN_PATHr1loadIOErrorr Errorrr CLIENT_ID OAUTH_SCOPEOAUTH_REDIRECT_URIr{rrtr'rr/sysstdoutisattystdin FatalErrorauthorization_urlOAUTH_AUTHORIZE_URIprintrstrip fetch_tokenr0dump Exception) rapi_urirrBruuser_info_responserstate redirected_to __class__rrrsx      &zDefaultOAuth2Session.__init__c Cs~z!t|jd}t||WdWdS1swYWdSty>}ztd|j|fWYd}~dSd}~ww)NrzCould not save the OAuth2 token to %s. This means you may need to do the OAuth2 authorization process again soon. Original error: %s)r<rr1rrr r)rrrBrurrrrAs&z"DefaultOAuth2Session.token_updater)rirjrkrlrr expanduserrrrrrrr __classcell__rrrrr$s Dr$cs eZdZdZfddZZS)r"z?Caller is managing tokens and provides an active refresh token.csBtt|d|i}|j||d|i|jd|_|j|jdS)Nr'r&)rrr)rr"rrrr{rtr')rr&r'rrrrrOs zExternalOAuth2Session.__init__)rirjrkrlrrrrrrr"Msr"onedrive) __future__rr past.utilsrbuiltinsrrrMr1rrduplicity.backendrduplicity.errorsrrr rrr objectrmr$r"register_backendrrrrs&         *_