// INFO {{{ let INFO = <> ninjatottori MIT License

コマンドラインからfacebookをあれこれするプラグインです。

Setup(初期設定)

:facebook -getAuth :facebook -setAccessToken :facebook -getAuth :facebook -setAccessToken

facebookアプリの認証を行います。 facebookにログインした状態で :fa -getAuth するとfacebookのアプリ認証ページに飛びます。 認証ページで承認を行うと結果ページが開きますので、そのままの状態で :fa -setAccessToken して下さい。 一度設定すれば以後は不要です。(自動的にサブコマンドから消えます)

Options(rcファイルへの設定)

g:facebook_auto_load let g:facebook_auto_load = 0 or 1

wallデータの自動更新を設定します。1で有効です。デフォルトは無効になっています。 取得したデータはキャッシュされて、コメントやいいねに利用されるので有効にしておく事をおすすめします。

g:facebook_auto_load_interval let g:facebook_auto_interval = msec

wallデータの自動更新間隔を設定します。デフォルトは60000(1分)です。

Post(投稿)

:facebook :facebook text -link url -group id

:fa hogehoge とするとfacebookへ「hogehoge」と投稿します。 -link オプションを選ぶと補完リストに開いているURLが出てくるので選択して投稿できます。 -group オプションを選ぶと補完リストにグループidが出てくるので選択して投稿するとそのグループにのみ投稿ができます。

Open

:facebook open :facebook open

選択されたアイテムをタブに開きます。 リンクが指定されていないデータ(単純なステータス表示など)はその投稿ページを開くだけです。

Get(ウォールデータのMOWへの出力)

:facebook get :facebook get

facebookのウォールデータを取得してMOWに出力します。 また、同時にlocal strage(デフォルトでは~/vimperator/info/default/facebook)にキャッシュを入れます。 後述するコメントやlike(いいね)はこのキャッシュされているデータにのみ行う仕様になっています。

Comment(コメントの投稿)

:facebook comment id text :facebook comment id text

:fa comment<Space>すると補完リストにキャッシュされているウォールデータが補完リストに表示されます。 <Tab>でidを補完してコメントを入力して実行すると対象にコメントを投稿します。

Like(いいねの投稿)

:facebook like id :facebook like id

:fa like<Space>すると補完リストにキャッシュされているウォールデータが補完リストに表示されます。 <Tab>でidを補完して実行すると対象にlike(いいね)をポストします。 また、現時点ではlikeの取り消しはできません。

Check In

:facebook checkin id text :facebook checkin id text

:fa checkin<Space>すると補完リストに最近チェックインした場所が表示されます。 <Tab>でidを補完して実行すると対象にチェックインします。 対象を選んだ後に<Space>textでチェックインコメントを投稿します。

; // }}} (function(){ function presetup(){ // access_token取得前 {{{ commands.addUserCommand(["facebook","fa"], "facebook util", function(args){ if (args["-getAuth"]) { FB.get_auth(); } else if (args["-setAccessToken"]) { FB.set_access_token(); } }, { options: [ [["-getAuth"], commands.OPTION_NOARG], [["-setAccessToken"], commands.OPTION_NOARG] ], }, true ); } // }}} function setup(){ // access_token取得後 {{{ FB.set_friends(); FB.set_groups(); commands.addUserCommand(["facebook","fa"], "facebook util", function(args){ if(args[0] || args["-link"])FB.post_to_wall(args); }, { options:[ [["-link","-l"],commands.OPTION_STRING,null,tablist], [["-group","-g"],commands.OPTION_STRING,null,grouplist], ], subCommands: [ new Command(["get"], "get walldata from facebook to MOW", function (args) { FB.view_wall_data(args) },{ literal:0, completer:friends_completer, } ), new Command(["checkin"], "check in", function (args) { FB.check_in(args); },{ literal:0, completer:checkins_completer, } ), new Command(["comment"], "comment", function (args) { FB.comment(args); },{ literal:0, completer:function(context){ feed_completer(context); context.completions = feed_complations(); }, } ), new Command(["like"], "like", function (args) { FB.like(args); },{ literal:0, completer:function(context){ feed_completer(context); context.completions = feed_complations(); }, } ), new Command(["open"], "open in background tab", function (args) { liberator.open(args[0],liberator.NEW_BACKGROUND_TAB) },{ literal:0, completer:function(context){ feed_completer(context); context.completions = feed_complations("open"); }, } ), ], }, true ); function checkins_completer(context){ context.title = ["id","name"] context.filters = [CompletionContext.Filter.textDescription]; context.compare = void 0; context.anchored = false; context.incomplete = true; let url = FB.graph + "me/checkins?access_token=" + FB.access_token; FB.request(url,function(data){ res = libly.$U.evalJson(data.responseText)["data"]; let checkins = []; for each(let l in res){ checkins.push([l["place"]["id"] + "," + l["place"]["location"]["latitude"] + "," + l["place"]["location"]["longitude"] ,l["place"]["name"] + " " + l["place"]["location"]["street"]]) } context.completions = checkins; context.incomplete = false; }); } function friends_completer(context){ context.title = ["id","name"] context.filters = [CompletionContext.Filter.textDescription]; context.compare = void 0; context.anchored = false; let store = storage.newMap("facebook",{store:true}).get("friends"); let friends = []; for (let d in store){ friends.push([store[d]["id"],store[d]["name"]]); } context.completions = friends; context.incomplete = false; } function feed_completer(context){ context.title = ["feed"]; context.filters = [statusObjectFilter]; context.compare = void 0; context.anchored = false; context.createRow = function(item, highlightGroup){ // タイトル if (highlightGroup === 'CompTitle') { return
  • {item}
  • ; } let [value, info] = item.item; return
  • {info.user_name} : {info.name} {info.story} {info.message} {info.link} {info.description} {info.likes} {info.comments}
  • ; }; context.incomplete = false; function statusObjectFilter(item) let (desc = item.description) (this.match(desc.user_name) || this.match(desc.message) || this.match(desc.link) || this.match(desc.description)); } function feed_complations(command) { let store = storage.newMap("facebook",{store:true}).get("feed_cache"); let feeds = []; for each(let d in store){ feeds.push([ (command === "open") ? (d["link"] || (d["actions"] ? d["actions"][0]["link"] : FB.www)) : d["id"] , { type:d["type"], icon:d["icon"], user_name:d["from"]["name"], message:(d["message"] || ''), user_icon:FB.graph + d["from"]["id"] + "/picture/" , link:(d["link"] || ''), likes:d["likes"] ? d["likes"]["count"] + ' likes' : '' , comments:(d["comments"]["count"] > 0) ? d["comments"]["count"] + ' comments' : '' , name:(d["name"] || ''), story:(d["story"] || ''), description:(d["description"] || ''), } ]); } return feeds; } function tablist(){ let tablist = []; for each([i,tab] in tabs.browsers){ tablist.push([tab.currentURI.spec,tabs.getTab(i).label]); } return tablist; } function grouplist(){ let store = storage.newMap("facebook",{store:true}).get("groups"); let grouplist = []; for each(let d in store){ grouplist.push([d["id"],d["name"]]) } return grouplist; } } // }}} let FB = { /// {{{ access_token : storage.newMap("facebook",{store:true}).get("access_token"), www : "http://www.facebook.com/", https_www : "https://www.facebook.com/", graph : "https://graph.facebook.com/", get_auth : function(){ // get_auth {{{ let app_id = "149105991809432"; let auth_url = this.https_www + "/dialog/oauth?" + "client_id=" + app_id + "&redirect_uri=https://www.facebook.com/connect/login_success.html" + "&scope=offline_access,publish_stream,read_stream,user_groups,user_checkins,friends_checkins,publish_checkins" + "&response_type=token"; liberator.open(auth_url,liberator.NEW_BACKGROUND_TAB); }, // }}} set_access_token : function(){ // set_access_token {{{ commandline.input("Paste URL", function(res){ let store = storage.newMap("facebook",{store:true}); let token = res.match(/^https:\/\/.*access_token\=(.*)\&.*$/)[1]; if(token){ store.set('access_token',token); store.save(); FB.access_token = token; e("[facebook.js]:set access_token!"); setup(); } },{ completer : function(context){ context.title = ['location', 'name street']; context.filters = [CompletionContext.Filter.textDescription]; context.completions = (function(){ let tablist = []; for each([,tab] in tabs.browsers){ if(tab.currentURI.host == "www.facebook.com" && tab.currentURI.path.match(/\/connect\/.*/)) tablist.push([tab.currentURI.spec,tab.currentURI.host]); } return tablist; })(); context.incomplete = false; }, } ); }, // }}} post_to_wall : function(data) { // post {{{ let url = this.graph + (data["-group"] || "me") + "/feed"; let post_data = getParameterMap({ access_token : this.access_token, message : data.join(' ') || '', link : data["-link"] || '', }); FB.request(url,function(data) echo("[facebook.js]:post success"),true,post_data); }, // }}} get_wall_data : function() { // set to local storage 'feed_cache' {{{ let url = FB.graph + "/me/home?access_token=" + FB.access_token; FB.request(url,function(data){ res = libly.$U.evalJson(data.responseText); let store = storage.newMap("facebook",{store:true}); store.set('feed_cache',res["data"]); store.save(); }); }, // }}} view_wall_data : function(data) { // view wall data on MOW {{{ let url = data[0] ? this.graph + data[0] + "/feed?access_token=" + this.access_token : this.graph + "/me/home?access_token=" + this.access_token; FB.request(url,function(data){ res = libly.$U.evalJson(data.responseText); let store = storage.newMap("facebook",{store:true}); store.set('feed_cache',res["data"]); store.save(); viewWallData(res); function viewWallData(data){ let buff = ""; for each(let d in data["data"]){ if(d["type"] == "status"){ buff +=
    {d["type"]}:{d["message"] || ''} {like_count(d)}{comment_count(d)}

    }else if(d["type"] == "link"){ buff +=
    {d["type"]}:{d["message"] || ''} {d["link"]} {like_count(d)}{comment_count(d)}

    }else if(d["type"] == "photo"){ buff +=
    {d["type"]}:{d["message"] || ''} {like_count(d)}{comment_count(d)}


    }else if(d["type"] == "checkin"){ buff +=
    {d["type"]}:{d["message"] || ''} {d["name"]} {like_count(d)}{comment_count(d)}

    ; }else{ buff +=
    unknown post : {d["type"]}
    } liberator.echo(buff); } function icon_path(data) FB.graph + data["from"]["id"] + "/picture/"; function comment_count(data) { if(!data["comments"]["data"]) return ""; return ({data["comments"]["count"]} comments) ; } function like_count(data) { if(!data["likes"]) return ""; return ({data["likes"]["count"]} Likes) ; } } }); }, // }}} set_friends : function(data) { // store friends data {{{ let url = this.graph + "/me/friends?access_token=" + this.access_token; FB.request(url,function(data){ res = libly.$U.evalJson(data.responseText) let store = storage.newMap("facebook",{store:true}); store.set('friends',res["data"]); store.save(); }) }, // }}} set_groups : function(data) { // store groups data {{{ let url = this.graph + "/me/groups?access_token=" + this.access_token; FB.request(url,function(data){ res = libly.$U.evalJson(data.responseText) let store = storage.newMap("facebook",{store:true}); store.set('groups',res["data"]); store.save(); }) }, // }}} request : function(url,callback,type,post_data){ // get or post requester. def:get {{{ let req = new libly.Request( url , //url null, //headers { // options asynchronous:true, postBody:post_data, } ); req.addEventListener("success",function(data){ callback(data); }); req.addEventListener("failure",function(data){ e(data.responseText) liberator.echoerr(data.responseText); }); req.addEventListener("exception",function(data){ e(data.responseText) liberator.echoerr(data.responseText); }); !type ? req.get() : req.post(); }, // }}} check_in : function(data){ // check in {{{ if(!data[0]) return; let url = this.graph + "me/checkins"; let p = data[0].split(' ')[0].split(','); let place_id = p[0]; let latitude = p[1]; let longitude = p[2]; let message = data[0].split(' ').slice(1,undefined).join(' '); let post_data = getParameterMap({ access_token : this.access_token, place:place_id, coordinates:'{"latitude":' + latitude + ',"longitude":"' + longitude + '"}', message : message || '' }); FB.request(url,function(data) echo("[facebook.js]:checkin success"),true,post_data); }, // }}} comment : function(data) { // comment {{{ if(!data[0]) return; let target = data[0].split(' ')[0]; let message = data[0].split(' ').slice(1,undefined).join(' '); let url = this.graph + target + "/comments"; let post_data = getParameterMap({ access_token : this.access_token, message : message }); FB.request(url,function(data) echo("[facebook.js]:post success"),true,post_data); }, // }}} like : function(data) { // like {{{ if(!data[0]) return; let url = this.graph + data[0] + "/likes"; let post_data = getParameterMap({ access_token : this.access_token, }); FB.request(url,function(data) echo("[facebook.js]:post success"),true,post_data); }, // }}} } /// }}} // wall data update timer let timer={id:0,active:false}; if(storage.newMap("facebook",{store:true}).get("access_token")){ setup(); if(liberator.globalVariables.facebook_auto_load == 1){ timer.id = setInterval(FB.get_wall_data,liberator.globalVariables.facebook_auto_load_interval || 60000); timer.active = true; e("[facebook.js]start getting wall data"); } }else{ presetup(); } function getParameterMap(parameters){ let map = ""; for (let key in parameters){ if (map) map += "&"; map += key + "=" + parameters[key]; } return map } // for debug {{{ function e(v,c){ if(c) util.copyToClipboard(v); liberator.log(v,-1) } function echo(v){ liberator.echo(v) } // }}} })();