私もやりたい!芸能人ダイエット
V2C目当てで来た方はとりあえずwiki
このブログに書いてあることはほぼ網羅、かつコンパクトに纏められています。
その上で記事見る方はこちらへ。V2C関連全記事
Tipsを流し読みする感じをご要望ならこちらへ ちょっと便利な使い方

2011年11月17日

V2Cスクリプト作成メモ

2011/11/19更新

スクリプト作成に関するメモ。
自分がハマったり分からなかった事などを書いていきます。
「JavaScriptとか知らなかったけど、とりあえず基本的な事は理解してある程度は書けるようになったぜ!」というレベルの人向けです。
同じようなハマり方する人がいるかもしれないので、そんとき検索に引っかかってくれればいいなと。
書きたいことが増えたらそのまま追記してく予定です。更新日は本記事の最初に書くようにします。
本当はwikiに書きたいところだけど、こっちの方が気楽に書けるので・・・だもんでwikiへの転載は大歓迎。
後、もし嘘書いてたら教えてください。

参考サイト:V2Cスクリプトのリファレンス
http://v2c.s50.xrea.com/manual/script.html
最初何書いてるかほとんどわからなかったけど、スクリプトスレのサンプル弄りながらちょっとずつ勉強してったらわかるようになってきました。


注1:V2CのスクリプトはRhinoらしいですが、以降「JavaScript」と表現します。
注2:本記事に張り付けられているコードは基本的にスクリプトスレに貼られた物を流用させて頂いてます。


・thとかresってなんぞ?
V2C使用法では特に解説なく変数として出てきたりしますが、基本的に下記のものです。
  1. th:スレッドオブジェクト。v2c.context.threadやv2c.getThread(u)で取得できる。
  2. res:レスオブジェクト。v2c.context.resやth.getRes(i)で取得できる。
  3. bd:板オブジェクト。th.board等で取得できる。
他にもあると思いますが、よく出てくるのはこれくらい。
これらオブジェクトで何ができるかってのは、V2C使用法を「th」とか「res」で検索するといいかも。

また、これに加えてスクリプトスレでよく使われてる変数名としては
  1. u→URL(URI)
  2. vcx→v2c.context
  3. arg,args→v2c.args
これくらいですかね。
本記事でもこれ以降これら表現を使っています。

・V2Cが返す文字列はJavaScriptではなく、Javaの文字列らしい
「V2Cが返す文字列」とは、具体的にはv2c.context.res.messageとかv2c.context.thread.board.keyとか。
v2cが頭についてて文字列を返してくるものは大体あてはまるんじゃないかと。
単純に表示したりするだけなら同じものとして扱っても問題ないと思いますが、文字列の比較なんかは
if (th.board.key == 'software')
じゃなくて
if (th.board.key.equals('software'))
としなければいけないらしい。
見事にハマりました。(参考:http://www.tohoho-web.com/java/string.htm)

後、
var key = th.board.key + '';
if (key == 'software') {〜}
みたいにすると、keyにはJavaScriptの文字列で格納されるのでうまく判定できます。
スクリプトスレ見てると結構こう書いてある物があるんだけど、「なんの意味があるんだろ」とか思ってました。キャストの意味あいがあったんですね。

・res.id等、resの情報は必ず取得できるわけではない
res.idはIDがない板だと当然取得できないんですが、意外とそのことを忘れてコーディングしてしまったり。
注意しといた方がいいであろう仕様を、気づいた範囲で列挙してみると
  • IDがない板もある(res.idはnull)
  • IDはあるけどsageるとIDが???になる板もある
  • IDは携帯の"O"やPCの"0"等、通常のIDの末尾のみが表記される板もある
  • IDある板でもあぼーんされたレスはnullになる
てなのがあります。なので処理する場合は面倒でも
if (res.id) {〜}
みたいな感じで弾いた方が無難かも。「???」とか「末尾のみ」も弾くなら、
if (res.id && res.id.length() >= 8) {〜}
でいいのかな?8文字未満のIDがなければ、の話ですが。
(res.idは「Javaの文字列」なので文字列長はJavaScriptの文字列にある"length"というプロパティはなく、"length()"というメソッドで取得するようです)

ちなみに、あぼーんの時res.dateはどうなるんだろと思って試してみたら「あぼーん」が格納されてました。res.timeは0。
この辺りも注意しておく必要がありそう。

・resを処理するときは非表示(NG)レスのことも考えた方がいいと思う
レスを抽出したり数えたりしようとする場合
for (var i = 0;i < th.localResCount; i++) {
 var res = th.getRes(i);
 if (res) {
  ~~~~~
 }
}
みたいな処理をすることがほとんどだと思います。
で、自分はレスのNGってほとんど使わないので気づかなかったんですが、NGレスまで考慮する必要があるシーンてのはほとんどないと思うのです。
だもんで、例えばこの例だと
if (res) {
ではなく
if (res && !res.ng) { // resがNGされている場合、res.ngはtrueを返す
とした方がいいんじゃないか、という訳です。
まぁ「レスの中にはNGされてるものもある」ってのだけ覚えとけばいいでしょうかね。

・デバッグするとき
実行途中の変数の内容を覗き見たい、とかそういう場合は
var hoge = "テスト";
v2c.println(hoge);
みたいな感じで書けば、スクリプトコンソールに"テスト"と表示されます。
スクリプトコンソールはV2Cメニューの「表示」→「スクリプトコンソール」から表示できます。
当たり前のことかもしれませんが、自分はこれ知らなくて最初はv2c.alert(hoge)とかやってました。面倒くさいったらありゃしない。

・ファイルをv2c.readFile(s)等で読み込む場合の注意点
ファイル読み込みというか、ファイルパスを書く場合の注意点です。
var txt = v2c.saveDir+'\\script\\hissi_menu.txt'; 
のような書き方をすると、Windows以外の環境で実行されたときにエラーが出る可能性があります。
Windowsだとパスの区切りは\だけど、環境によってはそうとは限らないらしい。
この場合は、
var fs = java.io.File.separator; 
var txt = v2c.saveDir+fs+'script'+fs+'hissi_menu.txt';
または
var txt = new java.io.File(new java.io.File(v2c.saveDir,'script'),'hissi_menu.txt'); 
のような書き方をすれば回避できます。

ちなみに、元はスクリプトスレの作者殿のレスです。
http://yy61.60.kg/test/read.cgi/v2cj/1252074124/96

・prototypeは弄っちゃダメ?
wikiのスクリプトFAQでも触れられてますが、JREのVersion 6 Update 29から
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, "");
}
こういった記述をするとエラーが出るようになったようです。
まぁデバッグしてりゃ気づくとは思いますが・・・
書き換えるとしたら
function trimEx(s) {
return s.replace(/^\s+|\s+$/g, "");
}
として、使用部分ではs.trim()をtrimEx(s)に書き替える、くらいですかねぇ…

・外部サイトの情報を取得したい
twitterやyoutubeのURLからその内容をポップアップするといったタイプのスクリプトで主に使われている機能ですね。
外部サイトのhtmlを文字列として取得するだけなら簡単
var sr = v2c.readURL(u); //uはURL
if (!sr) {
v2c.alert('ページを取得できませんでした。');
}
でsrにhtmlが文字列として格納されます。

POSTしたり、レスポンスコード(404とか)も取得したいとなるとHttpRequestオブジェクトを使う必要があります。
細かいことは抜きにして使い方だけ。(細かいことはリファレンスに書いてあります。)
var hr = v2c.createHttpRequest(u);
var sr = hr.getContentsAsString();
if (!sr) {
  v2c.alert('ページの取得に失敗しました: '+hr.responseCode+' '+hr.responseMessage);
}
でsrにhtmlが文字列として格納されます。
404が返ってきたら、hr.responseCodeに"404"が入ってるはずです。503だったらメッセージを変える、みたいな処理がしたい場合はこちらを使うことになります。
1行目で格納されるのではなく、2行目のhr.getContextsAsString()を実行した後に格納されます。

ちなみに、元はスクリプトスレの作者殿のレスです。
http://yy61.60.kg/test/read.cgi/v2cj/1252074124/75

・JRE7では挙動が変わる?
細かいことはよく分かりませんが、あるみたいです。
まず、上の方で「V2Cが返す文字列はJavaScriptではなく、Javaの文字列らしい」と書きましたが、それは配列にも言えるようです。
具体的にはres.refResIndex(resを参照してるレスのインデックスが格納された配列)なんかがそうで、これで取得できるのはJavaのArrayのようです。
例えば、
var a = [1,2,3];
var l = res.refResIndex;
a.concat(l);
とすると、[1,2,3]の後ろに配列が連結されるのではなく、4番目にlという配列がそのまま格納されるようです。
なので、連結したい場合は
var l = res.refResIndex;
if (l) {
  for (var j=0; j<l.length; j++) {
     a.push(l[j]);
  }
}
のように書く必要があるようです。
将来的にJRE7に移行するでしょうし、素直にforループ使う方がよさそうです。

ちなみに、元はスクリプトスレの作者殿のレスです。
http://yy61.60.kg/test/read.cgi/v2cj/1304861674/197

・v2c.contextやcv2c.context.threadが取得できない場合もある?
きちんと調べた訳ではありませんが、システム系スクリプトでは使えなかったりするようです。
例えば、ステータスバーに文字列を表示させる場合
v2c.context.setStatusBarText(s)
を使いますが、システム系スクリプト内で使用するとエラーが出る場合があります。(v2c.contextがnullになる)
他にも、スクリプトによるポップアップ内の文字列を選択状態にし、その右クリックから起動したスクリプトでは、v2c.contextは取得できてもv2c.context.threadやv2c.context.resがnullになるといった仕様もあり、注意する必要があります。

・意外と簡単に使えるJavaのオブジェクト
V2CのスクリプトではJavaのオブジェクトが使えます。Javaなんぞ知らなくてもただコピペするだけで使えます。
JavaScriptだけだと面倒くさいコードを書く必要がある処理でも、Javaのオブジェクトを使うことによって楽に実装できたりします。
自分はJavaなんぞ知らないので、とりあえずスクリプトスレにあったものを紹介。

1.時刻を指定したフォーマットの文字列に変換する
細かいことは抜きにしてやり方。
var pd = new Date();
var jpd = java.text.SimpleDateFormat("現在の日付[yyyy/MM/dd] 時刻[HH:mm:ss]").format(pd);
こうするとpdには現在時刻が格納され、jpdには
"現在の日付[2011/02/10] 時刻[11:22:33]"
というような文字列が格納されます。
"現在の日付[yyyy/MM/dd] 時刻[HH:mm:ss]"
の個所を変更すれば好きなように書式を変更できます。
具体的にどう書けばどう変換されるんだってのは下記参照。
http://java.sun.com/javase/ja/6/docs/ja/api/java/text/SimpleDateFormat.html

ちなみに、元はスクリプトスレの作者殿のレスです。
http://yy61.60.kg/test/read.cgi/v2cj/1252074124/12

2.文字列の連結
文字列を連続して連結する場合、
var s = 'a';
s += 'b';
s +='c';
とするよりも、
var sb = new java.lang.StringBuilder();
sb.append('a');
sb.append('b');
sb.append('c');
とする方が速いらしい。
他にもいろいろ便利なメソッドがついてるのでこっちの方がいい気がします。
参考:http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/StringBuilder.html

3.GUIを付ける
javax.swing.JDialog等を利用して、GUI機能を付けたりすることも可能なようです。自分はjavaを全く知らんのでよく理解できておらず解説はできませんが、とりあえずサンプルみると雰囲気は掴めるんじゃないでしょうか。
wikiに登録されているスクリプトだとclock.jsがそうです。
http://www39.atwiki.jp/v2cwiki/pages/99.htmlからダウンロードどうぞ。

ちなみに、他のほとんどのスクリプトではこの方法は使わず、HTMLで画面を作って
v2c.context.setPopupHTML(s);
で表示し、ボタンが押されたらテキストボックスやチェックボックスの値を
formSubmitted(u, sm, sd)
で受け取る、という事をやっているようです。
Java知ってる人なら前者の方が楽そうに見えますが…部分的にはデザイナで設計できそうですし。(やったことないから分かんないですが)
posted by sarasate at 21:10 | Comment(1) | TrackBack(0) | V2C | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
ngfile.txtを共有しているようなスレってありますかね?
Posted by at 2012年05月23日 18:08
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/234332752

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。