毎日Learning

学んだことを共有します

vimからTwitterにつぶやくだけのクライアントアプリをOAuth認証に対応した

以前まで Twitter - Post to Twitter from Vim : vim online を使っていたが、Basic認証の終了に伴いつぶやけなくなっていた。

つぶやくだけの機能で良いので、OAuth認証で認証するようにだけ対応すれば良いやと思い、vimtwitter.vimのソースを見ながら、pythonスクリプトを呼び出すように変更し、pythonスクリプト内でtweepyを使ってOAuth認証するようにしてみた。

まずは、vimスクリプトだが、vimtwitter.vimをコピペして、pyvimtweet.vimというファイルにし、実際にツイートしている箇所を変更しただけ。

ソースは以下。

if !exists('g:pyvimtweet_key_file')
    let g:pyvimtweet_key_file = $HOME . "/pyvimtweet.dat"
endif

" Load pyvimtweet.py
if !exists("g:pyvimtweet_loaded_python_file")
    pyfile <sfile>:p:h/pyvimtweet.py
    python pyvimtweet = PyVimTweet()
    let g:pyvimtweet_loaded_python_file=1
endif

" Load this module only once.
if exists('loaded_pyvimtweet')
    finish
endif
let loaded_pyvimtweet = 1

" The extended character limit is 246. Twitter will display a tweet longer than
" 140 characters in truncated form with a link to the full tweet. If that is
" undesirable, set s:char_limit to 140.
let s:char_limit = 246

function! s:post_twitter(mesg)
    let mesg = a:mesg

    " Remove trailing newline. You see that when you visual-select an entire
    " line. Don't let it count towards the tweet length.
    let mesg = substitute(mesg, '\n$', '', "")

    " Convert internal newlines to spaces.
    let mesg = substitute(mesg, '\n', ' ', "g")

    " Check tweet length. Note that the tweet length should be checked before
    " URL-encoding the special characters because URL-encoding increases the
    " string length.
    if strlen(mesg) > s:char_limit
    echo "Your tweet has" strlen(mesg) - s:char_limit "too many characters. It was not sent."
    else
    " URL-encode some special characters so they show up verbatim.
    let mesg = substitute(mesg, '%', '%25', "g")
    let mesg = substitute(mesg, '"', '%22', "g")
    let mesg = substitute(mesg, '&', '%26', "g")

    "call system("curl ".s:proxy." ".s:login.' -d status="'.mesg.'" '.s:twupdate)
    python pyvimtweet.update_status()
    echo "Your tweet was sent. You used" strlen(mesg) "characters."
    endif
endfunction

function! s:CmdLine_Twitter()
    call inputsave()
    let mesg = input("Your Twitter: ")
    call inputrestore()
    call s:post_twitter(mesg)
endfunction

" Prompt user for tweet.
command! PosttoTwitter :call <SID>CmdLine_Twitter()

" Post current line to Twitter.
command! CPosttoTwitter :call <SID>post_twitter(getline('.'))

" Post entire buffer to Twitter.
command! BPosttoTwitter :call <SID>post_twitter(join(getline(1, "$")))

" Post visual selection to Twitter.
vmap T y:call <SID>post_twitter(@")<cr>

" vim:set tw=0:

で、このソース内で呼び出しているのが、pyvimtweet.pyで、そのソースが以下。

# -*- coding: utf-8 -*-

import os
import pickle
import tweepy
import vim

CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

class PyVimTweet():
    
    def __init__(self):
        self.key_file = vim.eval('g:pyvimtweet_key_file')

    def update_status(self):
        mesg = vim.eval('mesg')
        if os.path.isfile(self.key_file):
            access_token = pickle.load(open(self.key_file, "r"))
        else:
            self.auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
            vim.command('echo "%s"' % self.auth.get_authorization_url())
            vim.command('let oauth_verifier = input("What is the PIN ?: ")')
            oauth_verifier = vim.eval('oauth_verifier')
            access_token = self.auth.get_access_token(oauth_verifier)
            pickle.dump(access_token, open(self.key_file, "wb"))

        self.auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
        self.auth.set_access_token(access_token.key, access_token.secret)
        self.api = tweepy.API(auth_handler=self.auth)

        self.api.update_status(status=mesg)

で使い方は、vimのコマンドで、

「:PosttoTwitter」

を実行すると、

「Your Twitter: 」

と表示されるので、つぶやいてEnter。

初めてのつぶやきの時は、ログイン用のURLと、「What is the PIN ?:」というメッセージが表示される。

ログイン用のURLをコピーしてブラウザで開き、Twitterにログインし、クライアントでの使用を許可する。

許可すると、暗唱番号がブラウザに表示されるので、その番号をコピーしてvimにはっつけEnter。

これでつぶやきが投稿される。

以上。