vimからgoogle docsを操作したい 〜その2〜
出来ました。
gdata-python-client v2.0.17 使ってます。↓
http://code.google.com/p/gdata-python-client/downloads/list
■Pythonモジュール #encoding=utf-8 import os from gdata.docs.service import DocsService from gdata.data import MediaSource from common.mys import mylogger, S, U, BT email = 'hogehoge@gmail.com' password = 'hagehage' cash_f = 'c:\\myresource\\gc.dat' # テキストふぃあるをutf-8に変換 def dumpUtf8(file_path): with open(file_path, 'r') as fp: root, ext = os.path.splitext(file_path) out_path = root + '_utf8' + ext with open(out_path, 'w') as fp_utf8: fp_utf8.write(S(fp.read(), 'utf-8')) return out_path class MGoogle: def __init__(self, email, password): self.email = email self.password = password self.client = self.connect() self.docs_dict = {} # Google認証 def connect(self): try: client = DocsService() client.ClientLogin(self.email, self.password) mylogger.info('Authentication succeeded %s' % repr(client)) except Exception, e: mylogger.error(U(BT())) client = None return client # テキストファイルのアップロード def uploadTxt(self, file_path, title=u'memo', entry_doc=None, content_type='text/plain'): upload_file = dumpUtf8(file_path) src = MediaSource(file_path=upload_file, content_type=content_type) try: # TODO 返ってくるentryの型がちげえw # ホントはentryをreturnしたい if entry_doc == None: # gdata.docs.DocumentListEntry entry = self.client.Upload(src, title) else: # gdata.GDataEntry entry = self.client.Put(entry_doc, entry_doc.GetEditLink().href, media_source=src) mylogger.info(type(entry)) mylogger.info(entry) except Exception, e: mylogger.error(U(BT())) # ダウンロード def downloadTxt(self, resource_id): for entry in self.client.GetDocumentListFeed().entry: if entry.resourceId.text == resource_id: out_path = U(entry.title.text) + '.txt' self.client.Export(entry, out_path) mylogger.info('Completed downloading %s. ' % entry.title) break mylogger.info(entry.resourceId.text) # ローカルにドキュメント情報をcash def updateResourceCash(self, cash_file=cash_f): with open(cash_file, 'w') as fp: s = u'' for entry in self.client.GetDocumentListFeed().entry: s += U(entry.resourceId.text) s += '\t' s += U(entry.title.text) s += '\n' fp.write(S(s, 'utf-8')) mylogger.info('Updated cash file [%s]' % cash_file) # cashをロード def loadResourceCash(self, cash_file=cash_f): with open(cash_file, 'r') as fp: self.docs_dict = {} for line in fp: resourceId, title = U(line).strip().split('\t') self.docs_dict[resourceId] = title # ドキュメントタイトルからリソースID取得 def getResourceId(self, title): for k, v in self.docs_dict.items(): if U(v) == U(title): return k return 'None' # ドキュメントの存在チェック def findDoc(self, resourceId): for entry in self.client.GetDocumentListFeed().entry: if U(entry.resourceId.text) == U(resourceId): mylogger.debug('Entry exists: %s' % repr(entry)) return entry return None if __name__ == '__main__': import unittest class Tests(unittest.TestCase): def setup(self): pass @unittest.skip('') def testUpload(self): g = MGoogle(email, password) entry = g.uploadTxt('memo.txt') mylogger.info(entry) #@unittest.skip('') def testUpdate(self): g = MGoogle(email, password) entry = g.findDoc('document:xxxxxxxxxxxxx') entry_after = g.uploadTxt('gdocs.vim', entry_doc=entry) @unittest.skip('') def testDownload(self): g = MGoogle(email, password) g.downloadTxt('document:xxxxxxxxxxxxx') @unittest.skip('') def testCash(self): g = MGoogle(email, password) g.updateResourceCash() @unittest.skip('') def testCashLoad(self): g = MGoogle(email, password) g.loadResourceCash() @unittest.skip('') def testConvert(self): dumpUtf8('memo.txt') unittest.main(verbosity=2)
■vimモジュール command! -nargs=* MGoogleLogin :call s:LoginMGoogle() command! -nargs=* MGoogleList :call s:ListMGoogleDocs( ) command! -nargs=* MGoogleListUpdate :call s:UpdateListMGoogleDocs( ) command! -nargs=* MGoogleUpload :call s:UploadDoc( ) let s:buffer_name = '__mgoogle__' python << EOF import vim import os from gdoc.gdocs import MGoogle mGoogle = None EOF " -------------------------------------------- " Google認証 function! s:LoginMGoogle() if !exists('g:mgoogle_login') let g:mgoogle_login = input('Email >> ') let g:mgoogle_password = inputsecret('Password >> ') endif python << EOF mGoogle = MGoogle( vim.eval('g:mgoogle_login'), vim.eval('g:mgoogle_password') ) EOF endfunction " -------------------------------------------- " ドキュメントの一覧 function! s:ListMGoogleDocs() let auth_done = 0 python << EOF if mGoogle == None: print '認証してくだちゃい! --> :MGoogleLogin' vim.command('let auth_done = -1') EOF if auth_done == 0 silent execute 'e ' . s:buffer_name silent execute 'set buftype=nofile' nmap :call DownloadDoc(getline('.')) python << EOF mGoogle.loadResourceCash() for k, v in mGoogle.docs_dict.items(): vim.current.buffer.append(k.encode('cp932') + '\t' + v.encode('cp932')) EOF endif endfunction " -------------------------------------------- " ドキュメントの一覧のキャッシュ更新 function! s:UpdateListMGoogleDocs() python mGoogle.updateResourceCash() endfunction " -------------------------------------------- " 一覧で1つ指定して キー 押してダウンロード function! s:DownloadDoc(line_text) let doc_info = split(a:line_text, "\t") python << EOF mGoogle.downloadTxt(vim.eval('doc_info[0]')) EOF echo "ダウンロードしました -> [" . doc_info[1] . "]" endfunction " -------------------------------------------- " 現在編集中のバッファをgoogle docsにアップロード function! s:UploadDoc() let abs_path = expand('%:p') let filename = expand('%') python << EOF filename = vim.eval('filename') path = vim.eval('abs_path') title, ext = os.path.splitext(filename) resourceId = mGoogle.getResourceId(title) # ファイル名からリソースID entry_doc = mGoogle.findDoc(resourceId) # 既存entry取得 (なければNone) mGoogle.uploadTxt(path, title, entry_doc) # 新規投稿 or 更新 EOF endfunction