Java(with Twitter4J)でOAuth認証とpostだけするコード(その2)

※このコードを参考・使用して発生したいかなる損害にも、筆者(Atom)は一切の責任を負いません。自己責任でご使用ください。

前回作成した、
Java(with Twitter4J)でOAuth認証とpostだけするコード - FromAtoMemo
を少しだけ改善(改悪)しました。

【実装機能】

【使い方】
 javacでさくっとコンパイルしてください。もちろんTwitter4Jにクラスパスが通っていないとエラーが出ます。コンシューマーキーとコンシューマーシークレットは各自好きに取得して、テストすると良いと思います。

【各種コマンド解説】

  • -n:通常起動。好きなだけpost出来ます。(※APIの許す限り)
  • -t に書き込んだ内容をツイートして終了します。
  • -r:既に保存されているアクセストークン情報を削除します。使うアカウントを変えたい時に。

【注意点】
 Macで動かすと文字化けするらしい。そこらへんはMacユーザーさんが詳しいと思うので、各自直せると思います。(持ってないから分からない…。)

【反省点】

  • 認証部をclass分けした意味が全く無い。
  • オブジェクト……指向……?
  • コマンドライン引数をpostする機能が欲しかったならC言語で書けば良かった。
  • そもそもJavaで開発するメリット無かった。

以下ソースコードです。

import java.io.*;

import twitter4j.Twitter;
import twitter4j.Status;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

public class postit{
    static Twitter twitter;

    public static void main(String[] args){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        OAuthCert oauth = null;
        AccessToken accessToken = null;
        Status status;
        String username = "YAMADA"; //一応ユーザーネーム(この中では使ってない)
        
        try {
            if(args.length < 1){
                System.out.println("\t -n : boot normal mode");
                System.out.println("\t -r : reset your AccessToken (if you want to use other ID, use this.)");
                System.out.println("\t -t <tweet> : send <tweet>");
            }
            else{
                if(args[0].equals("-t") && args.length >= 2){
                    try {
                        oauth = new OAuthCert(username);
                        twitter = oauth.getTwitter();
                        status = twitter.updateStatus(args[1]); //引数に来た文字を投げる
                    } catch (TwitterException e) {
                        System.out.println("[ERROR!] Can't send tweet!");
                    }
                }
                else if(args[0].equals("-r")){
                    oauth.resetAccessToken();
                }
                else if(args[0].equals("-n")){
                    try {
                        oauth = new OAuthCert(username);
                        twitter = oauth.getTwitter();
                    } catch (TwitterException e) {
                        System.out.println("[ERROR!] Can't connect twitter!");
                    }
                    
                    //Tweetさせる部分。すさまじく愚直にはき出す。
                    while(true){
                        System.out.print("What's are you doing ? :");
                        String text = br.readLine();
                        if(text.equals("exit")) break;              //"exit"入力で終了

                        try {
                            status = twitter.updateStatus(text); //引数に来た文字を投げる
                        } catch (TwitterException e) {
                            System.out.println("[ERROR!] Can't send tweet!");
                        }
                }
                else{
                    System.out.println("\t -n : boot normal mode");
                    System.out.println("\t -r : reset your AccessToken (if you want to use other ID, use this.)");
                    System.out.println("\t -t <tweet> : send <tweet>");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//OAuth認証関連クラス
class OAuthCert {
    public static final String CONSUMER_KEY = "hogehoge";
    public static final String CONSUMER_SECRET = "piyopiyo";
    static TwitterFactory factory = new TwitterFactory();
    static Twitter twitter = factory.getInstance();
    static String filename = null;
    
    //OAuthログインする
    OAuthCert (String name) throws TwitterException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        RequestToken requestToken = twitter.getOAuthRequestToken();
        AccessToken accessToken = this.loadAccessToken(name); //ファイルからアクセストークン読み出し
        filename = name;
        
        if (accessToken != null) {
            // 保存されていたアクセストークンを使う
            twitter.setOAuthAccessToken(accessToken);
        }
        else {
            //ブラウザにURLを投げつけて開かせる
            try {
                throwURL(requestToken.getAuthorizationURL());
            } catch (URISyntaxException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            //PINコード打ち込んでもらう
            try {
                System.out.print("Prease enter the PIN:");
                String pin = br.readLine();
                
                if(pin.length() > 0){
                    accessToken = twitter.getOAuthAccessToken(requestToken, pin);
                }
                else{
                    accessToken = twitter.getOAuthAccessToken();
                }

            } catch (TwitterException te) {
                if(401 == te.getStatusCode()){
                    System.out.println("Unable to get the access token.");
                    System.exit(1);
                }
                else {
                    te.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            storeAccessToken(name, accessToken); //ファイルにアクセストークンを保存
        }
    }
    
    //アクセストークンを呼び出す
    private AccessToken loadAccessToken(String name) {
        File f = createAccessTokenFileName(name);
        
        ObjectInputStream is = null;
        try {
            is = new ObjectInputStream(new FileInputStream(f));
            AccessToken accessToken = (AccessToken) is.readObject();
            return accessToken;
        }
        catch (IOException e) {
            return null; //ファイルが読めない(存在しない)場合はnullを返す
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        finally {
            if (is != null) {
                try {
                    is.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //アクセストークンをファイルに保存する
    private void storeAccessToken(String name, AccessToken accessToken) {
        File f = createAccessTokenFileName(name);
        File d = f.getParentFile();
        if (!d.exists()) {
            d.mkdirs();
        }
        
        ObjectOutputStream os = null;
        try {
            os = new ObjectOutputStream(new FileOutputStream(f));
            os.writeObject(accessToken);
            
        } catch (IOException e) {
            e.printStackTrace();
            
        } finally {
            if (os != null) {
                try { os.close(); } catch (IOException e) { e.printStackTrace(); }
            }
        }
    }

    // アクセストークンを保存するファイル名を生成する
    /*ここで引数nameを使用してファイルを区別すれば複数アカウントを
      管理することが可能になると思います。*/
    static File createAccessTokenFileName(String name) {
        //カレントディレクトリに"userdata"というディレクトリを作り
        //その中にトークン情報を保存しています。

        String s = "./userdata/accessToken.dat";
        return new File(s);
    }

    //ブラウザにURLを投げつける
    private void throwURL(String url) throws URISyntaxException, IOException {
        Desktop desktop = Desktop.getDesktop();
        desktop.browse(new URI(url));
    }

    public Twitter getTwitter(){
        return twitter;
    }

    //アクセストークンファイルをリセットする
    public static void resetAccessToken(){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Do you want to delete your AccessToken? [Y/N] ->");
        String text = null;
        try {
            text = br.readLine();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        if((text.equals("Y"))||(text.equals("y"))){
            File resetfile = createAccessTokenFileName(filename);
            resetfile.delete();
            System.out.print("Your Access Token was deleted.");
        }
    }
}

以上になります。
おかしいところなどありましたら、お知らせ頂けると助かります。