エキサイトブログとBloggerの記事を同期するプログラム - ExciteBlogToBloggerReplicator
概要
エキサイトブログとBloggerの記事を同期するためのJavaのプログラムを書きました。
エキサイトブログに記事を追加・更新・削除した後、このコードを実行すると、エキサイトブログでの編集内容がBloggerに反映されます。
起動方法
本プログラムを実行するには、ExciteBlogToBloggerReplicatorクラスをjavaコマンドで起動します。その際、引数にアカウントファイルのパス渡します。
以下、javaコマンドの実行例です。
java ExciteBlogToBloggerReplicator account.txt ※アカウントファイルのパスがC:\account.txtの場合
アカウントファイル
アカウントファイルには、エキサイトブログとBloggerへのログインに必要なアカウント情報を記載します。
以下、アカウントファイルの形式です。
ExciteBlogUser=エキサイトブログのユーザ ExciteBlogPassword=エキサイトブログのパスワード BloggerMail=Bloggerのメールアドレス BloggerPassword=Bloggerのパスワード
ExciteBlogToBloggerReplicatorクラスのソースコード
以下、ExciteBlogToBloggerReplicatorクラスのソースコードです。
import java.io.*; import java.util.*; /** * エキサイトブログからBloggerへの最新記事の複製 * @author nattou_curry */ public class ExciteBlogToBloggerReplicator { // アカウントファイルのエンコード private static final String ENCODING = "US-ASCII"; public static void main( String[] args ) { ///////////////////////////////////////////////////////////////////////////// // アカウントファイルからアカウント情報を取得する。 ///////////////////////////////////////////////////////////////////////////// // 引数からアカウントファイルを取得する。 if ( args.length < 1 ) { System.err.println( "引数にアカウントファイルを指定してください。" ); return; } String fileName = args[0]; File file = new File( fileName ); if ( ! file.exists() ) { System.err.println( "アカウントファイルが存在しません。ファイル名=[" + fileName + "]" ); return; } // アカウントファイルの内容をマップに格納する。 Map<String, String> accountInfo = new HashMap<String, String>(); BufferedReader reader = null; try { reader = new BufferedReader( new InputStreamReader( new FileInputStream( fileName ), ENCODING ) ); String line; while ( ( line = reader.readLine() ) != null ) { String[] tmp = line.split( "=", 2 ); if ( tmp.length < 2 ) { continue; } String key = tmp[0]; String value = tmp[1]; accountInfo.put( key, value ); } } catch ( IOException e ) { System.err.println( "アカウントファイルの読み込みに失敗しました。" ); e.printStackTrace(); } finally { if ( reader != null ) { try { reader.close(); } catch ( IOException e ) {} } } // マップから必要なアカウント情報を取得する。 String e_user = accountInfo.get( "ExciteBlogUser" ); String e_password = accountInfo.get( "ExciteBlogPassword" ); String b_mail = accountInfo.get( "BloggerMail" ); String b_password = accountInfo.get( "BloggerPassword" ); if ( e_user == null ) { System.err.println( "エキサイトブログのユーザが指定されていません。キー=[ExiciteBlogUser]" ); return; } if ( e_password == null ) { System.err.println( "エキサイトブログのパスワードが指定されていません。キー=[ExiciteBlogPassword]" ); return; } if ( b_mail == null ) { System.err.println( "Bloggerのメールアドレスが指定されていません。キー=[BloggerMail]" ); return; } if ( b_password == null ) { System.err.println( "Bloggerのパスワードが指定されていません。キー=[BloggerPassword]" ); return; } ///////////////////////////////////////////////////////////////////////////// // エキサイトブログの記事を取得する。 ///////////////////////////////////////////////////////////////////////////// // エキサイトブログにログインする(SSL)。 String e_cookie; try { e_cookie = ExciteBlogAccess.loginWithSSL( e_user, e_password ); } catch ( Exception e ) { System.err.println( "エキサイトブログへのログインでエラーが発生しました。" ); e.printStackTrace(); return; } // エキサイトブログのログイン情報を取得する。 Map<String, String> e_loginInfo; try { e_loginInfo = ExciteBlogAccess.getLoginInfo( e_cookie ); } catch ( Exception e ) { System.err.println( "エキサイトブログのログイン情報の取得でエラーが発生しました。" ); e.printStackTrace(); return; } // エキサイトブログの最新の記事情報の一覧を取得する。 List< Map<String, String>> e_articleList; try { e_articleList = ExciteBlogAccess.getArticleList( e_loginInfo ); } catch ( Exception e ) { System.err.println( "エキサイトブログの最新の記事情報の一覧取得でエラーが発生しました。" ); e.printStackTrace(); return; } // エキサイトブログの記事情報を投稿日でソートする。 Collections.sort( e_articleList, new Comparator<Map<String, String>>() { public int compare( Map<String, String> e_articleInfo1, Map<String, String> e_articleInfo2 ) { String e_pubDate1 = e_articleInfo1.get( "pubDate" ); String e_pubDate2 = e_articleInfo2.get( "pubDate" ); return e_pubDate1.compareTo( e_pubDate2 ); } } ); // 【デバッグ用】エキサイトブログの記事情報を表示 for ( int i = 0; i < e_articleList.size(); ++i ) { Map<String, String> e_articleInfo = e_articleList.get( i ); System.out.println( "[Excite] " + e_articleInfo.get( "pubDate" ) + " " + e_articleInfo.get( "title" ) ); } ///////////////////////////////////////////////////////////////////////////// // Bloggerの記事を取得する。 ///////////////////////////////////////////////////////////////////////////// // Bloggerにログインする(SSL)。 String b_cookie; try { b_cookie = BloggerAccess.loginWithSSL( b_mail, b_password ); } catch ( Exception e ) { System.err.println( "エキサイトブログへのログインでエラーが発生しました。" ); e.printStackTrace(); return; } // Bloggerにログイン情報を取得する。 Map<String, String> b_loginInfo; try { b_loginInfo = BloggerAccess.getLoginInfo( b_cookie ); } catch ( Exception e ) { System.err.println( "エキサイトブログのログイン情報の取得でエラーが発生しました。" ); e.printStackTrace(); return; } // Bloggerの最新の記事情報の一覧を取得する。 List< Map<String, String>> b_articleList; try { b_articleList = BloggerAccess.getArticleList( b_loginInfo ); } catch ( Exception e ) { System.err.println( "エキサイトブログの最新の記事情報の一覧取得でエラーが発生しました。" ); e.printStackTrace(); return; } // Bloggerの記事情報を投稿日でソートする。 Collections.sort( b_articleList, new Comparator<Map<String, String>>() { public int compare( Map<String, String> b_articleInfo1, Map<String, String> b_articleInfo2 ) { String b_pubDate1 = b_articleInfo1.get( "pubDate" ); String b_pubDate2 = b_articleInfo2.get( "pubDate" ); return b_pubDate1.compareTo( b_pubDate2 ); } } ); // 【デバッグ用】Bloggerの記事情報を表示 for ( int i = 0; i < b_articleList.size(); ++i ) { Map<String, String> b_articleInfo = b_articleList.get( i ); System.out.println( "[Blogger] " + b_articleInfo.get( "pubDate" ) + " " + b_articleInfo.get( "title" ) ); } ///////////////////////////////////////////////////////////////////////////// // 追加対象の記事(エキサイトブログに存在し、Bloggerに存在しない記事)を探す。 ///////////////////////////////////////////////////////////////////////////// List<Map<String, String>> add_ArticleList = new ArrayList<Map<String, String>>(); // 記事の比較のため、Bloggerの記事のハッシュテーブルを作成。 Map<Object, Map<String, String>> b_hashTable = new HashMap<Object, Map<String, String>>(); for ( int i = 0; i < b_articleList.size(); ++i ) { Map<String, String> b_articleInfo = b_articleList.get( i ); String b_title = b_articleInfo.get( "title" ); String b_pubDate = b_articleInfo.get( "pubDate" ); String b_content = b_articleInfo.get( "content" ); Object key = b_title + b_pubDate + b_content; b_hashTable.put( key, b_articleInfo ); } // 記事を比較し、追加対象の記事を決定する。 for ( int i = 0; i < e_articleList.size(); ++i ) { Map<String, String> e_articleInfo = e_articleList.get( i ); String e_title = e_articleInfo.get( "title" ); String e_pubDate = e_articleInfo.get( "pubDate" ); String e_content = e_articleInfo.get( "content" ); // エキサイトブログの記事とタイトル、投稿日、内容の全てが一致する記事が、Bloggerに存在しない場合、追加対象とする。 String key = e_title + e_pubDate + e_content; if ( ! b_hashTable.containsKey( key ) ) { add_ArticleList.add( e_articleInfo ); } } // 【デバッグ用】追加対象の記事を表示 for ( int i = 0; i < add_ArticleList.size(); ++i ) { Map<String, String> e_articleInfo = add_ArticleList.get( i ); String e_title = e_articleInfo.get( "title" ); String e_pubDate = e_articleInfo.get( "pubDate" ); System.out.println( "[ADD] " + e_title + " " + e_pubDate ); } ///////////////////////////////////////////////////////////////////////////// // 削除対象の記事(Bloggerに存在し、エキサイトブログに存在しない記事)を探す。 ///////////////////////////////////////////////////////////////////////////// List<Map<String, String>> delete_ArticleList = new ArrayList<Map<String, String>>(); // エキサイトブログの最古の投稿日を取得する。 String min_e_pubDate = "9999/99/99 99:99"; for ( int i = 0; i < e_articleList.size(); ++i ) { Map<String, String> e_articleInfo = e_articleList.get( i ); String e_pubDate = e_articleInfo.get( "pubDate" ); if ( min_e_pubDate.compareTo( e_pubDate ) > 0 ) { min_e_pubDate = e_pubDate; } } // 【デバッグ用】エキサイトブログの最古の投稿日を表示 System.out.println( "[Exciteの最古の投稿日] " + min_e_pubDate ); // 記事の比較のため、エキサイトブログの記事のハッシュテーブルを作成。 Map<Object, Map<String, String>> e_hashTable = new HashMap<Object, Map<String, String>>(); for ( int i = 0; i < e_articleList.size(); ++i ) { Map<String, String> e_articleInfo = e_articleList.get( i ); String e_title = e_articleInfo.get( "title" ); String e_pubDate = e_articleInfo.get( "pubDate" ); String e_content = e_articleInfo.get( "content" ); Object key = e_title + e_pubDate + e_content; e_hashTable.put( key, e_articleInfo ); } // 記事を比較し、削除対象の記事を決定する。 for ( int i = 0; i < b_articleList.size(); ++i ) { Map<String, String> b_articleInfo = b_articleList.get( i ); String b_title = b_articleInfo.get( "title" ); String b_pubDate = b_articleInfo.get( "pubDate" ); String b_content = b_articleInfo.get( "content" ); // エキサイトブログの最古の投稿日以前のBloggerの記事は無視する。 if ( b_pubDate.compareTo( min_e_pubDate ) < 0 ) { continue; } // Bloggerの記事とタイトル、投稿日、内容の全てが一致する記事が、エキサイトブログに存在しない場合、削除対象とする。 String key = b_title + b_pubDate + b_content; if ( ! e_hashTable.containsKey( key ) ) { delete_ArticleList.add( b_articleInfo ); } } // 【デバッグ用】削除対象の記事を表示 for ( int i = 0; i < delete_ArticleList.size(); ++i ) { Map<String, String> b_articleInfo = delete_ArticleList.get( i ); String b_title = b_articleInfo.get( "title" ); String b_pubDate = b_articleInfo.get( "pubDate" ); System.out.println( "[DELETE] " + b_title + " " + b_pubDate ); } ///////////////////////////////////////////////////////////////////////////// // 記事を追加する。 ///////////////////////////////////////////////////////////////////////////// String b_blogID = b_loginInfo.get( "blogID" ); String b_url = b_loginInfo.get( "url" ); for ( int i = 0; i < add_ArticleList.size(); ++i ) { Map<String, String> e_articleInfo = add_ArticleList.get( i ); String e_title = e_articleInfo.get( "title" ); String e_pubDate = e_articleInfo.get( "pubDate" ); String e_content = e_articleInfo.get( "content" ); Map<String, String> postInfo = new HashMap<String, String>(); postInfo.put( "blogID", b_blogID ); postInfo.put( "url", b_url ); postInfo.put( "title", e_title ); postInfo.put( "postBody", e_content ); postInfo.put( "pubDate", e_pubDate ); try { BloggerAccess.postNewEntry( b_cookie, postInfo ); } catch ( Exception e ) { System.err.println( "Blogerへの記事の追加でエラーが発生しました。タイトル=[" + e_title + "], 投稿日=[" + e_pubDate + "]" ); e.printStackTrace(); return; } } ///////////////////////////////////////////////////////////////////////////// // 記事を削除する。 ///////////////////////////////////////////////////////////////////////////// for ( int i = 0; i < delete_ArticleList.size(); ++i ) { Map<String, String> b_articleInfo = delete_ArticleList.get( i ); String b_title = b_articleInfo.get( "title" ); String b_pubDate = b_articleInfo.get( "pubDate" ); String b_postID = b_articleInfo.get( "postID" ); try { BloggerAccess.deleteEntry( b_cookie, b_blogID, b_postID ); } catch ( Exception e ) { System.err.println( "Blogerからの記事の削除でエラーが発生しました。タイトル=[" + b_title + "], 投稿日=[" + b_pubDate + "]" ); e.printStackTrace(); return; } } } }
依存するクラスのソースコード
ExciteBlogToBloggerReplicatorクラスは、エキサイトブログとBloggerへ接続するために以下のクラスを使用します。
- BloggerAccess (参考: Bloggerに接続するためのJavaコード)
- ExciteBlogAccess (参考: エキサイトブログに接続するためのJavaコード)