EmEditorでブログ書きたい!!そんな欲望に流されました。
ブログかいてるとさ、ブラウザの戻るでフォームでうっかり消しちゃったり、アレコレ面倒なんだよね。コピーペーストも面倒だし、範囲選択が面倒だし。ソースコードのために、エスケープやら・・・面倒。
以前から、EmEditorでXmlHTTPが動いてどうなんだ?と思ってて、良い機会だ。BloggerAPIをXMLRPC呼び出してみよう。
とりあえず、ココログで動作するようにしてみた。
EmEditor用マクロというより、WSH用スクリプトだろ。といわれたら否定できないが。
以下ソース
/** * Emeditorでブログ投稿マクロ。 * * 対応XML-RPC API は Blogger APIです。 * BloggerAPIに対応しているブログなら投稿できるはずです * 動作確認: * ニフティ ココログ * 動作報告、不具合、改良をお待ちしています。 * 報告先 * @ref http://d.hatena.ne.jp/takuya_1st/20061013/1160753654 * @author takuya_1st * @modified 06/10/14 * @version 1.0 RC1.0 */ ///////////////////////////////////////////////// //////以下の項目を書き換えて使ってください // //ユーザーID // //パスワード // //エンドポイント(ブログの投稿用URL) // ///////////////////////////////////////////////// var pwd = "**********"; var usr = "**********"; var url = "http://app.f.cocolog-nifty.com/t/api"; ///////////////////////////////////////////////// ///////////////////////////////////////////////// var BlogInfo = { getUsersBlogs : "" +'<?xml version="1.0"?>' +'<methodCall>' +' <methodName>blogger.getUsersBlogs</methodName>' +' <params>' +' <param><value><string></string></value></param>' +' <param><value><string>'+usr+'</string></value></param>' +' <param><value><string>'+pwd+'</string></value></param>' +' </params>' +'</methodCall>', id : "", blogURL : "", title : "", check : function (){ var req = XMLHttpRequest(); req.open("post", url , false); req.onreadystatechange = function() { if (req.readyState==4){ xDoc = req.responseXML; nodes = xDoc.getElementsByTagName("string"); BlogInfo.title = nodes[0].firstChild.nodeValue; BlogInfo.blogURL = nodes[1].firstChild.nodeValue; BlogInfo.id = nodes[2].firstChild.nodeValue; } } req.setRequestHeader("Content-Type","text/xml; charset=UTF-8"); req.send( this.getUsersBlogs ); } } function XMLHttpRequest(){ return new ActiveXObject("Microsoft.XMLHTTP"); } var NewEntry = function( BlogId ){ this.id = BlogId; this.xml = function(){ newPost = "" +"<?xml version=\"1.0\"?>" +"<methodCall>" +" <methodName>blogger.newPost</methodName>" +" <params>" +" <param><value><string>C6CE3FFB31</string></value></param>" +" <param><value><string>"+this.id+"</string></value></param>" +" <param><value><string>"+usr +"</string></value></param>" +" <param><value><string>"+pwd +"</string></value></param>" +" <param><value><string>"+this.content+"</string></value></param>" +" <param><value><boolean>false</boolean></value></param> " +" </params>" +"</methodCall>"; return newPost; } this.content = ""; this.post = function(){ var req = XMLHttpRequest(); req.open("post", url , false); req.onreadystatechange = function() { if (req.readyState==4){ xDoc = req.responseXML; if( xDoc.getElementsByTagName("string").length > 0 ){ nodes = xDoc.getElementsByTagName("string"); alert( "エントリを投稿しました\n" +"エントリのIdは " +nodes[0].firstChild.nodeValue +" です" ); var his = new PostHistory(); his.push( nodes[0].firstChild.nodeValue ); his.saveHistory(); } else if( xDoc.getElementsByTagName("boolean").length > 0 && xDoc.getElementsByTagName("boolean")[0].firstChild.nodeValue ==1 ) { alert( "エントリを更新しました\n"); } else { alert("エントリの投稿に失敗しました"); } } } req.setRequestHeader("Content-Type", "text/xml; charset=UTF-8"); req.send( this.xml() ); } } var EditEntry = function( PostID ){ this.id = PostID; this.xml = function(){ editPost = "" +"<?xml version=\"1.0\"?>" +"<methodCall>" +" <methodName>blogger.editPost</methodName>" +" <params>" +" <param><value><string>C6CE3FFB3174106</string></value></param>" +" <param><value><string>"+this.id+"</string></value></param>" +" <param><value><string>"+usr+"</string></value></param>" +" <param><value><string>"+pwd+"</string></value></param>" +" <param><value><string>"+this.content+"</string></value></param>" +" <param><value><boolean>false</boolean></value></param> " +" </params>" +"</methodCall>" return editPost; } } EditEntry.prototype = new NewEntry; //投稿履歴の管理 var PostHistory = function(){ this.log = Window.ScriptFullName + ".history"; this.loadFile = function( name ){ var fs = new ActiveXObject("Scripting.FileSystemObject"); var p =fs.OpenTextFile( name , 1, true,fs.TristateUseDefault ); var str = p.ReadAll(); p.Close(); return str; } this.loadHistory = function (){ try{ var array_str = this.loadFile( this.log ); var src = "this.history = [" + array_str + "];"; eval(src);//英数字以外はエラーになる }catch(e){ this.history = new Array(); } } this.saveHistory = function(){ var str = this.history.toString(); var fs = new ActiveXObject("Scripting.FileSystemObject"); var p = fs.OpenTextFile( this.log , 2, true, fs.TristateUseDefault ); p.write( str ); p.Close(); } this.push = function( code ){ for( i in this.history ){ if( i == code ){ return; } } this.history.unshift(code); return; } //init this.loadHistory(); this.HistoryMenu = function(){ menu = Window.CreatePopupMenu(); for( i in this.history ){ menu.add( this.history[i], i+100 ); } return menu; } } var EditMenu = function(){ this.client = null; this.type = "new"; this.menu = function(){ history = new PostHistory(); submenu = history.HistoryMenu(); menu = Window.CreatePopupMenu(); menu.Add("新規投稿", 1); menu.Add( "", 0, eeMenuSeparator ); menu.AddPopup( "更新", submenu); return menu; } this.showMenu = function(){ m = this.menu(); result = m.Track(0); if( result >= 100 ){ this.client = new EditEntry( m.GetText(result) ); }else{ BlogInfo.check(); this.client = new NewEntry( BlogInfo.id ); } this.postEntry(); } this.postEntry = function(){ ret = Window.confirm("BlogをPOSTします。\n" +"準備は良いでしょうか?"); if(ret){ Window.document.selection.SelectAll(); var entry = Window.document.selection.Text; Window.document.selection.Collapse(); this.client.content = entry; this.client.post(); } } } mainMenu = new EditMenu(); mainMenu.showMenu();
これで、仕事さぼって、ブログ更新しててもバレないよね(違
PythonでAtomPPとかXMLRPCしてるコードと、HTTPのヘッダをキャプチャを参考にしながら、JavaScriptで書き直してみた。2時間ほどでパパっと、書いたからバグあるかも。また週末にデバッグしつつバージョンアップしていくとしましょう。EmEditorのPythonマクロのままでもよかったけれど、Pythonはまだまだマイナーなので。
しかし、エディタからXmlHttpは便利だな。
モードレスダイアログがあれば、スペルチェックも出来そうですね。
URL上にカーソルきたら、iframeを描画するとか。
WebDAVと連携したら、subversionそのままいじれるかも。
[ctrl+S]でFTP送信とか出来るとよいな。EmFTPをActiveXObjectで呼べたらできるなぁ。
ActiveXで使えるFTPライブラリないのかな。[Ctrl+S]で保存&FTP更新&IEリロードを、1アクションで呼べたら最高。XmlHttpとAtomPPでFTPライブラリがなくともサーバへへPushできるから、意外と実現可能かも?