fork download
  1. //【登録場所】お気に入り、ツールバー
  2. //【ラベル】検索キーワード名@板名 など
  3. //【コマンド】${SCRIPT:SFr} findThreadsMod.js $QUERY(検索用キーワード) $BOARD(板URL又は板key)
  4. //【アクション】スレ一覧で開く ←※忘れやすいんで設定し忘れに注意
  5. //【更新日】2013/02/02
  6. //例:${SCRIPT:SFr} findThreadsMod.js $QUERY(妹) $BOARD(http://h...content-available-to-author-only...h.net/news4vip/)
  7. //  ↑VIPの板・既得ログから"妹"と付くスレをスレ一覧に表示する
  8. //例:${SCRIPT:SFr} findThreadsMod.js $REGQUERY((V2C|Jane|2chブラウザ)) $BOARD(software) $KAKO
  9. //  ↑ソフトウェア板の板・既得ログ・過去ログ倉庫から"V2C"、Jane、2chブラウザのいずれかが付くスレをスレ一覧に表示する
  10. //【内容】 板・既得ログ・過去ログ倉庫からキーワードを含むスレを抽出してスレ一覧に表示
  11. // ${SCRIPT:SFr} findThreadsMod.js 引数1 引数2 引数3 ... (以下の引数を半角スペースを空けて連続して書く。)
  12. // $VIEWONLY = スレ一覧を更新しない
  13. // $BOARD(板URL又は板key) = 抽出対象の板の識別キー(news4vipみたいな)か、板URL(http://h...content-available-to-author-only...h.net/news4vip/みたいな) ※必須
  14. // $QUERY(検索用キーワード) = 抽出したいスレタイ ※QUERYかREGQUERYのいずれかが必須
  15. // $REGQUERY(検索用正規表現) = $QUERYの正規表現版
  16. // $KAKO = 過去ログ倉庫からも探してくる(遅い)
  17. //【スクリプト】
  18. function getThreads(cx) {
  19. //var startTime = new Date();
  20. if (!v2c.online) { cx.skip = true; return null; }
  21. var KAKO = false;
  22. var QUERY = null;
  23. var REGQUERY = null;
  24. var BOARD = null;
  25. var VIEWONLY = false;
  26. if (v2c.context.args.length > 0) {
  27. var tmp = String(v2c.context.argLine);
  28. var matches = [];
  29. KAKO = /^\$KAKO/i.test(tmp);
  30. VIEWONLY = /^\$VIEWONLY/i.test(tmp);
  31. if (matches = /\$QUERY\((.*)\) *\$|\$QUERY\((.*)\) *$/i.exec(tmp)) {
  32. if (matches[1].length == 0) { statusLog('$QUERY(スレタイ検索用キーワード)の「スレタイ検索キーワード」に何も入力されていません。'); return null; }
  33. QUERY = matches[1];
  34. }
  35. if (matches = /\$REGQUERY\((.*)\) *\$|\$REGQUERY\((.*)\) *$/i.exec(tmp)) {
  36. if (matches[1].length == 0) { statusLog('$QUERY(スレタイ検索用キーワード)の「スレタイ検索キーワード」に何も入力されていません。'); return null; }
  37. REGQUERY = new RegExp(matches[1]);
  38. }
  39. if (matches = /\$BOARD\((.*)\) *\$|\$BOARD\((.*)\) *$/i.exec(tmp)) {
  40. if (matches[2].length == 0) { statusLog('$BOARD(板URL又は板key)の「板URL又は板key」に何も入力されていません。'); return null; }
  41. BOARD = v2c.getBoard(matches[2]);
  42. if (!BOARD) {
  43. BOARD = v2c.bbs2ch.getBoard(matches[2]);
  44. }
  45. if (!BOARD) { statusLog('板オブジェクトの取得に失敗。({0})', BOARD); return null; }
  46. if (BOARD.twitter) { statusLog('Twitterは非サポートです。({0})', BOARD); return null; }
  47. }
  48. }
  49. if (!((QUERY || REGQUERY) && BOARD)) { statusLog('$QUERY(スレタイ検索用キーワード) と $BOARD(板URL又は板key) は必須です。'); return null; }
  50. var queryfunc = null;
  51. if (QUERY) {
  52. queryfunc = function(q) { return (q.indexOf(QUERY) != -1); };
  53. }
  54. if (REGQUERY) {
  55. queryfunc = function(q) { return REGQUERY.test(q); };
  56. }
  57. // 板欄の更新
  58. if (!VIEWONLY) {
  59. v2c.openURL(BOARD.url, true, true, true);
  60. }
  61. // 現板のsubject.txtと既得スレッド
  62. var sul = [], thluq = {};
  63. //var results = BOARD.threadsWithLog;
  64. var results = [], logs = BOARD.threadsWithLog;
  65. sul.push(BOARD.url + 'subject.txt');
  66. // 過去ログ倉庫のsubject.txt
  67. if (KAKO && BOARD.bbs.is2ch) {
  68. var su = BOARD.url + 'kako/';
  69. var sk = v2c.readURL(su);
  70. if (v2c.interrupted) { return null; }
  71. if (!sk) { statusLog('過去ログ倉庫の取得に失敗。({0})', su); return null; }
  72. var matches = [];
  73. while (matches = /<A HREF="(o\d+\/subject\.txt)">/gi.exec(sk)) { sul.push(su + matches[1]); }
  74. }
  75. // プログレスバーの設定
  76. cx.progress = 0;
  77. cx.maxProgress = 100000;
  78. var sulscore,thstscore;
  79. if (KAKO) {
  80. // kako付きならsubject.txtリスト50%,既得ログ50%ずつmaxProgressを割り振る
  81. sulscore = (cx.maxProgress / 2) / sul.length;
  82. thstscore = (cx.maxProgress / 2) / logs.length;
  83. } else {
  84. sulscore = thstscore = cx.maxProgress / (logs.length + sul.length);
  85. }
  86. // 既得スレッドからQUERYのスレを検索
  87. for (var i = logs.length - 1; i >= 0; i--) {
  88. if (queryfunc(logs[i].title)) {
  89. if ((!VIEWONLY) && logs[i].live && (logs[i].resCount - logs[i].localResCount) > 0) {
  90. logs[i].updateAndWait();
  91. }
  92. results.push(logs[i]);
  93. thluq[logs[i].key] = true;
  94. }
  95. cx.progress += thstscore;
  96. }
  97. // subject.txtからkeywordのスレを検索
  98. var sepStart = '<>', sepLast = ' (';
  99. if (BOARD.bbs.shitaraba || BOARD.bbs.match) {
  100. sepStart = ',';
  101. sepLast = '(';
  102. }
  103. for (var i = sul.length - 1; i >= 0; i--) {
  104. var ss=v2c.readURL(sul[i]);
  105. if (v2c.interrupted) { return null; }
  106. if (!ss) { statusLog('subject.txtの取得に失敗。({0})', sul[i]); return null; }
  107. var lines = ss.split('\n');
  108. var start, last, title, key, num, th;
  109. for (var n = lines.length - 1; n >= 0; n--) {
  110. key = lines[n].substring(0, lines[n].indexOf('.'));
  111. if (thluq[key]) { continue; }
  112. start = lines[n].indexOf(sepStart) + sepStart.length;
  113. last = lines[n].lastIndexOf(sepLast);
  114. title = lines[n].substring(start, last).split('&lt;').join('<').split('&gt;').join('>').split('&amp;').join('&');
  115. if (queryfunc(title)) {
  116. num = lines[n].substring(last + sepLast.length, lines[n].length() - 1);
  117. th = BOARD.getThread(key, BOARD.url, title, num);
  118. if (th) {
  119. if ((!VIEWONLY) && th.live && (th.resCount - th.localResCount) > 0) {
  120. th.updateAndWait();
  121. }
  122. results.push(th);
  123. thluq[key] = true;
  124. }
  125. }
  126. }
  127. cx.progress += sulscore;
  128. }
  129. // スレ立て降順にソート
  130. results.sort (
  131. function (a, b) {
  132. if (a.key < b.key) return 1;
  133. if (a.key > b.key) return -1;
  134. return 0;
  135. }
  136. );
  137. return results;
  138. }
  139. function statusLog(format /*, ...*/)
  140. {
  141. var args = arguments;
  142. var message = format.replace(/\{(\d)\}/g, function(m, c) { return args[parseInt(c) + 1] });
  143. v2c.context.setStatusBarText("[findThreadsMod.js] " + message);
  144. }
  145. function printlnLog(format /*, ...*/)
  146. {
  147. var args = arguments;
  148. var message = format.replace(/\{(\d)\}/g, function(m, c) { return args[parseInt(c) + 1] });
  149. v2c.println("[findThreadsMod.js] " + message);
  150. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty