o ~_$@sddlmZddlmZeddlmZddlmZddlZ ddl Z ddl Z ddl Z ddlZ ddlZddlmZddlmZGdd d ejjZ ejd eejjd gdS) )print_function)standard_library)input)strN) __version__)BackendExceptionc@sTeZdZdZdZdZddZddZdd Zd d Z d d Z dddZ dddZ dS) GDocsBackendz>Connect to remote store using Google Google Documents List APIz folder%3Arootzapplication/binaryc CsZtjj||zddladdladdladdl aWnt y.}zt dt |d}~wwtj jjdtd|_d|j_d|jj_||jd|j|t|jddd }d}tj}|D]D}||d |}|durt|dkr{|d}nt|dkrtj jj d |d }|jj!||d }nd}|r|j"j#}qct d |t d|||_$dS)NrzGoogle Docs backend requires Google Data APIs Python Client Library (see http://code.google.com/p/gdata-python-client/). Exception: %s duplicity %s)sourceTF@/folder)typetitle) collectionz-Error while creating destination folder '%s'.z-Error while fetching destination folder '%s'.)% duplicitybackendBackend__init__ atom.dataatom gdata.clientgdatagdata.docs.clientgdata.docs.data ImportErrorrrdocsclient DocsClientrssl http_clientdebug _authorizeusernamehostname get_passwordstringsplitpathrROOT_FOLDER_ID_fetch_entrieslendataResourcecreate_resource resource_idtextr) self parsed_urle folder_names parent_folderparent_folder_id folder_nameentriesrr:A/usr/lib/python3/dist-packages/duplicity/backends/gdocsbackend.pyr+sB         zGDocsBackend.__init__cCs|||}tjj|j|tjtj |j tjjj tj j jd}|rPtj j jtj j|dd}|jjd}|j||d}|sOtd||jjjfn td||jjjf|rcJdS)N) chunk_size desired_class)r1)rz?convert=false)entryz0Failed to upload file '%s' to remote folder '%s'z>Failed to initialize upload of file '%s' to remote folder '%s')_deleteopenrrResumableUploaderrBACKUP_DOCUMENT_TYPEosr)getsizenameDEFAULT_CHUNK_SIZErr-r.rTitlerget_resumable_create_media_linkhref UploadFiler get_filenamerr1close)r2 source_pathremote_filenamefileuploaderr>urir:r:r;_putWs,  zGDocsBackend._putcCsT||jjjtj|}t|dkr|d}|j||j dSt d||jj jf)Nr rz.Failed to find file '%s' in remote folder '%s') r+rr0r1rrBr,rDownloadResourcerErr)r2rN local_pathr9r>r:r:r;_getqs   zGDocsBackend._getcCs"||jjjtj}dd|DS)NcSsg|]}|jjqSr:)rr1).0r>r:r:r; sz&GDocsBackend._list..)r+rr0r1rrB)r2r9r:r:r;_list|s zGDocsBackend._listcCs>||jjjtj|}|D]}|jj|j dddq dS)Nz ?delete=trueT)force) r+rr0r1rrBrdelete get_edit_linkrI)r2filenamer9r>r:r:r;r?s zGDocsBackend._deleteNc Csz|jj||dtd||dWdStjjyB}z#td|jd}|s.ttd}|r&| |||j |WYd}~dSd}~wtjj yNt dw)Nr writely)r service captcha_tokencaptcha_responsez.A captcha challenge in required. Please visit zAnswer to the challenge? akInvalid user credentials given. Be aware that accounts that use 2-step verification require creating an application specific access code for using this Duplicity backend. Follow the instruction in http://www.google.com/support/accounts/bin/static.py?page=guide.cs&guide=1056283&topic=1056286 and create your application-specific password to run duplicity backups.) r client_loginrrCaptchaChallengeprint captcha_urlevalrr#r_BadAuthenticationr)r2emailpasswordr_r` challengeanswerr:r:r;r#s*   zGDocsBackend._authorizec Csd|}|dkr |d7}n|tjkr|d7}n|d7}|r)|dtj|d7}|jj|d}|rg}|D]N}|}|rO|dkrF|dksO|tjkr|dkr|tjkrw| D]} |jj | j ddt j jjd } | ru| jj|kru||qXq6t| d kr||q6|S|}|S) Nz'/feeds/default/private/full/%s/contentsrz/-/folder?showfolders=truez?showfolders=falsez?showfolders=truez&title=z&title-exact=true)rQ)r=r)rrBurllibparsequoterget_all_resourcesget_resource_typer*in_collections get_entryrIrrr-r.r0r1appendr,) r2 folder_idrrrQr9resultr> resource_typelink folder_entryr:r:r;r+s>       zGDocsBackend._fetch_entries)NN)N) __name__ __module__ __qualname____doc__r*rBrrRrUrXr?r#r+r:r:r:r;r%s,  rz gdata+gdocs) __future__rfuturerinstall_aliasesbuiltinsrros.pathrCr'urllib.requestrk urllib.parse urllib.errorduplicity.backendrrduplicity.errorsrrrrregister_backend uses_netlocextendr:r:r:r;s$      "