From 05de0546f98b1184f71beaeae186cc1cb00fa602 Mon Sep 17 00:00:00 2001 From: janus_wel Date: Mon, 22 Sep 2008 20:49:22 +0000 Subject: import matanico.js, nicontroller.js, nnp_cooperation.js git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@19750 d0d07461-0603-4401-acd4-de1884942a52 --- matanico.js | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 matanico.js (limited to 'matanico.js') diff --git a/matanico.js b/matanico.js new file mode 100644 index 0000000..91b1e4d --- /dev/null +++ b/matanico.js @@ -0,0 +1,348 @@ +/* + * ==VimperatorPlugin== + * @name matanico.js + * @description update Twitter's status to current video name and comment + * @description-ja 今見てる動画のタイトルとコメントを Twitter に投稿する + * @author janus_wel + * @version 0.60 + * @minversion 1.1 + * ==VimperatorPlugin== + * + * LICENSE + * New BSD License + * + * USAGE + * :matanico [comment] + * Twitter に今見ている動画の情報をポストする。 comment はなくてもかまわない。 + * 動画ページではみている動画の情報を、タグ検索ページでは検索結果をポストする。 + * :matanico! [comment] + * Twitter に送られる文字列をクリップボードにコピーする。 twitter には送られない。 + * 動画ページではみている動画の情報を、タグ検索ページでは検索結果をコピーする。 + * + * VALIABLE + * g:matanico_status_format + * 動画閲覧ページで投稿する文章の書式設定。動画ページで適用される。以下の変数指定が可能。 + * $SERVICENAME : このプラグインが付加する文字列。 g:matanico_status_servicename で指定する。 + * $SUBJECT : 動画の名前。 + * $PLAYTIME : 再生時間。 + * $URL : 動画の URL。 + * $COMMENT : コメント。これがないとコメントを書いても反映されない。 + * default + * let g:matanico_status_format='$SERVICENAME : $SUBJECT($PLAYTIME) - $URL $COMMENT' + * + * g:matanico_status_servicename + * このプラグインが固定で付加する文字列。動画ページで適用される。 + * default + * let g:matanico_status_servicename='またニコニコ動画見てる' + * + * g:matanico_tag_format + * タグ検索ページで投稿する文章の書式設定。以下の変数指定が可能。 + * $SERVICENAME : このプラグインが付加する文字列。 g:matanico_tag_servicename で指定する。 + * $TAG : 検索したタグ。複数の場合は半角スペースで区切られる。 + * $NUMOFVIDEOS : 検索結果の件数。 + * $URL : 検索結果の URL。 + * $COMMENT : コメント。これがないとコメントを書いても反映されない。 + * default + * let g:matanico_tag_format='$SERVICENAME : $TAG($NUMOFVIDEOS件) - $URL $COMMENT' + * + * g:matanico_tag_servicename + * このプラグインが固定で付加する文字列。タグ検索ページで適用される。 + * default + * let g:matanico_tag_servicename='またニコニコタグ検索してる' + * + * g:matanico_related_tag_format + * キーワードによるタグ検索ページで投稿する文章の書式設定。以下の変数指定が可能。 + * $SERVICENAME : このプラグインが付加する文字列。 g:matanico_tag_servicename で指定する。 + * $KEYWORD : 検索したタグ。複数の場合は半角スペースで区切られる。 + * $NUMOFTAGS : 検索結果の件数。 + * $URL : 検索結果の URL。 + * $COMMENT : コメント。これがないとコメントを書いても反映されない。 + * default + * let g:matanico_related_tag_format='$SERVICENAME : $KEYWORD($NUMOFTAGS件) - $URL $COMMENT' + * + * g:matanico_tag_servicename + * このプラグインが固定で付加する文字列。キーワードによるタグ検索ページで適用される。 + * default + * let g:matanico_related_tag_servicename='またキーワードでニコニコタグ検索してる' + * + * HISTORY + * 2008/06/14 v0.10 initial written. + * 2008/06/27 v0.20 change replace argument to regexp with 'g' option. + * add matanico! command. + * refactoring + * display sended status if succeed. + * 2008/06/28 v0.21 change display strings, 'Yanked ' and 'Posted ' + * 2008/07/13 v0.30 change xpath function and xpath query + * 2008/07/14 v0.40 change url checking + * 2008/07/15 v0.50 make NicoScraper class + * add function to post tag page + * refer : http://nicovideo.g.hatena.ne.jp/koizuka/20080322/matanico_tag + * 2008/09/04 v0.60 add function to post related tag page + * */ + +(function(){ + +// information functions +// change XPath query when html changed. +function NicoScraper(){} +NicoScraper.prototype = { + constants: { + VERSION: '0.50', + WATCH_PAGE: 1, + WATCH_URL: '^http://www\.nicovideo\.jp/watch/[a-z][a-z]\\d+', + TAG_PAGE: 2, + TAG_URL: '^http://www\.nicovideo\.jp/tag/', + RELATED_TAG_PAGE: 3, + RELATED_TAG_URL: '^http://www\.nicovideo\.jp/related_tag/', + }, + + version: function(){ return this.constants.VERSION; }, + + pagecheck: function() { + if(this.getURL().match(this.constants.WATCH_URL)) return this.constants.WATCH_PAGE; + if(this.getURL().match(this.constants.TAG_URL)) return this.constants.TAG_PAGE; + if(this.getURL().match(this.constants.RELATED_TAG_URL)) return this.constants.RELATED_TAG_PAGE; + throw 'current tab is not nicovideo.jp'; + }, + + _flvplayer: function() { + if(this.pagecheck() === this.constants.WATCH_PAGE) { + var flvplayer = window.content.document.getElementById('flvplayer'); + if(! flvplayer) throw 'flvplayer is not found'; + + return flvplayer.wrappedJSObject ? flvplayer.wrappedJSObject : flvplayer ? flvplayer : null; + } + return null; + }, + + getURL: function() { + return liberator.buffer.URL; + }, + + getSubject: function() { + if(this.pagecheck() === this.constants.WATCH_PAGE) { + var subject = $f('//h1/a[contains(concat(" ",@class," "), " video ")]'); + return subject ? subject.text : null; + } + return null; + }, + + getPlaytime: function() { + var p = this._flvplayer(); + var playtime = p ? Math.round(p.ext_getTotalTime()) : null; + if(playtime) { + var min = Math.floor(playtime / 60); + var sec = playtime % 60; + if(sec < 10) sec = '0' + sec; + return playtime ? [min, sec].join(':') : null; + } + else return null; + }, + + getTagName: function() { + if(this.pagecheck() === this.constants.TAG_PAGE) { + var word_nodes = $s('id("search_words")/span[contains(concat(" ",@class," "), " search_word ")]'); + var words = []; + word_nodes.forEach(function(node) { words.push(node.textContent); }); + return words.length ? words.join(' ') : null; + } + return null; + }, + + getNumofVideos: function() { + if(this.pagecheck() === this.constants.TAG_PAGE) { + var numofVideos = $f('//strong[contains(concat(" ",@class," "), " result_total ")]'); + return numofVideos.textContent ? numofVideos.textContent : null; + } + return null; + }, + + getKeyword: function() { + if(this.pagecheck() === this.constants.RELATED_TAG_PAGE) { + var keyword = $f('//strong[contains(concat(" ",@class," "), " search_word ")]'); + return keyword.textContent ? keyword.textContent : null; + } + return null; + }, + + getNumofTags: function() { + if(this.pagecheck() === this.constants.RELATED_TAG_PAGE) { + var numofTags = $f('//strong[contains(concat(" ",@class," "), " result_total ")]'); + return numofTags.textContent ? numofTags.textContent : null; + } + return null; + }, +}; + +var scraper = new NicoScraper; + +liberator.commands.addUserCommand(['matanico'], "update Twitter's status to current video name and comment", + function(arg, special) { + try { + // build post string ----- + var post_string; + // domain check + switch(scraper.pagecheck()) { + // video page + case scraper.constants.WATCH_PAGE: + { + // get value from global variable or set default + var format = liberator.globalVariables.matanico_status_format || '$SERVICENAME : $SUBJECT($PLAYTIME) - $URL $COMMENT'; + var serviceName = liberator.globalVariables.matanico_status_servicename || 'またニコニコ動画見てる'; + + // expand variable ( evaluate variable ? ) + post_string = format.replace(/\$SERVICENAME/g, serviceName) + .replace(/\$SUBJECT/g, scraper.getSubject()) + .replace(/\$PLAYTIME/g, scraper.getPlaytime()) + .replace(/\$URL/g, scraper.getURL()) + .replace(/\$COMMENT/g, arg); + } + break; + + // tag search page + case scraper.constants.TAG_PAGE: + { + // get value from global variable or set default + var format = liberator.globalVariables.matanico_tag_format || '$SERVICENAME : $TAG($NUMOFVIDEOS件) - $URL $COMMENT'; + var serviceName = liberator.globalVariables.matanico_tag_servicename || 'またニコニコタグ検索してる'; + + // expand variable ( evaluate variable ? ) + post_string = format.replace(/\$SERVICENAME/g, serviceName) + .replace(/\$TAG/g, scraper.getTagName()) + .replace(/\$NUMOFVIDEOS/g, scraper.getNumofVideos()) + .replace(/\$URL/g, scraper.getURL()) + .replace(/\$COMMENT/g, arg); + } + break; + + // related_tag search page + case scraper.constants.RELATED_TAG_PAGE: + { + // get value from global variable or set default + var format = liberator.globalVariables.matanico_related_tag_format || '$SERVICENAME : $KEYWORD($NUMOFTAGS件) - $URL $COMMENT'; + var serviceName = liberator.globalVariables.matanico_related_tag_servicename || 'またキーワードでニコニコタグ検索してる'; + + // expand variable ( evaluate variable ? ) + post_string = format.replace(/\$SERVICENAME/g, serviceName) + .replace(/\$KEYWORD/g, scraper.getKeyword()) + .replace(/\$NUMOFTAGS/g, scraper.getNumofTags()) + .replace(/\$URL/g, scraper.getURL()) + .replace(/\$COMMENT/g, arg); + } + break; + + default: + throw 'current tab is not nicovideo.jp'; + break; + } + + // ':matanico!' display the evaluated format. + if(special) { + liberator.util.copyToClipboard(post_string, true); + return; + } + + // ready posting ----- + // URI encode + var parameter = 'status=' + encodeURIComponent(post_string); + + // twitter's URL to post + var domain = 'http://twitter.com/'; + var postURL = 'http://twitter.com/statuses/update.json'; + + // get user account for twitter + var [user, pass] = getUserAccount(domain, postURL, null); + + // send status + var req = new XMLHttpRequest(); + if(req) { + req.open('POST', postURL, true, user, pass); + req.onreadystatechange = function() { + if (req.readyState == 4) { + if(req.status == 200) liberator.echo('Posted ' + post_string) + else throw 'failure in posting status to Twitter. HTTP status code : ' + req.status; + } + } + req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + req.send(parameter); + } + } + catch(e) { + liberator.echoerr(e); + liberator.log(e); + } + }, + // complete logic is none. + {} +); + +// stuff functions +function $f(query, node) { + node = node || window.content.document; + var result = (node.ownerDocument || node).evaluate( + query, + node, + null, + XPathResult.FIRST_ORDERED_NODE_TYPE, + null + ); + return result.singleNodeValue ? result.singleNodeValue : null; +} + +function $s(query, node) { + node = node || window.content.document; + var result = (node.ownerDocument || node).evaluate( + query, + node, + null, + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, + null + ); + var nodes = []; + for(var i=0 ; i 0){ + [user, password] = [logins[0].username, logins[0].password]; + } else { + var promptUser = { value : '' }, promptPass = { value : '' }; + var promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"] + .getService(Ci.nsIPromptService); + + var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", + Ci.nsILoginInfo, + "init"); + + var ret = promptSvc.promptUsernameAndPassword( + window, form, 'Enter e-mail address and password.', + promptUser, promptPass, null, {} + ); + if(ret){ + [user, password] = [promptUser.value, promptPass.value]; + var formLoginInfo = new nsLoginInfo(form, + post, null, + user, password, '', ''); + passwordManager.addLogin(formLoginInfo); + } else { + liberator.echoerr("account not found - " + form); + } + } + } + catch(ex){ + liberator.echoerr("handled exception during getting username and password"); + liberator.log(ex); + } + return [user, password]; +} + +})(); +// vim:sw=4 ts=4 et: -- cgit v1.2.3