fork(3) download
  1. //【登録場所】 "V2C\script\system\getdat.js"
  2. //【内容】 スレッドのログが取得出来ない場合、指定するURLから過去ログを取得する。
  3. // 1. http://m...content-available-to-author-only...n.to/ のhtmltodat 0.10.2(925k byte)をダウンロードする
  4. // 2. ダウンロードした圧縮ファイルを解凍して、フォルダ名を「htmltodat0.9.0」に変更する
  5. // 3. フォルダごとV2Cのログ・設定保存用フォルダにコピーする。保存用フォルダの場所がわからなければV2C起動して 設定→ランチャー(L)… を見ればわかる
  6. //【コマンド】外部コマンドの設定→スクリプト→getdat.jsのパーミッションを初期値の「S」から「SF」に変更する
  7. //【更新日時】2013/11/26 ログ速の仕様変更への対応
  8. // TIPS: ふたばdatのスレ移動リンクはReplaceStr.txtに
  9. // <rx2>http://(\w+)\.2chan\.net/(\w+)/res/(\d+)\.htm $0<br>└( http://$1.2chan.net/test/read.cgi/$2/$3/ ) msg
  10. // の1行追加で移動できるようになります
  11. //【スクリプト】
  12. (function() { this.HTMLtoDAT = _HTMLtoDAT; this.LOGSOKUtoDAT = _LOGSOKUtoDAT; this.FUTABAtoDAT = _FUTABAtoDAT;
  13.  
  14. // -----------------------------設定項目-----------------------------------
  15. // htmltodatのフォルダパスを指定 (フォルダの区切りは「 \\ 」ではなく「 / 」で、末尾のも「 / 」を記入すること)
  16. var htmltodatDir = v2c.saveDir + '/htmltodat0.9.0/';
  17. // DAT変換定義 (name = 表示名, src = 2chスレURLへの正規表現, dst = srcの正規表現の置換パターン, obj: DAT変換用のクラス(HTMLtoDAT or HTMLtoDAT互換モード or LOGSOKUtoDAT))
  18. // 全部使うと遅いので必要な項目だけコメント(行頭の//のこと)を外すこと
  19. this.services = [
  20. { name: 'FUTABAtoDAT', obj: new FUTABAtoDAT()},
  21. { name: 'offlaw2', src: new RegExp("^^http://([^/]+)/test/[^/]+/(\\w+)/(\\d+).*"), dst: "http://$1/test/offlaw2.so?shiro=kuma&bbs=$2&key=$3" },
  22. { name: 'mimizun', src: new RegExp("^http://([^/]+)/test/[^/]+/(\\w+)/(\\d+).*"), dst: "http://m...content-available-to-author-only...n.com/log/2ch/$2/$3.dat" },
  23. { name: 'logsoku (LOGSOKUtoDAT)', obj: new LOGSOKUtoDAT() },
  24. // { name: 'unkar' , src: new RegExp("^http://([^/]+)/test/[^/]+/(\\w+)/(\\d+).*"), dst: "http://u...content-available-to-author-only...r.org/convert.php/$2/$3/" },
  25. // {name: 'ヴァルタ', src: new RegExp("^http://([^/]+)/test/[^/]+/(\\w+)/(((\\d+)\\d)\\d{5}).*"), dst: "http://v...content-available-to-author-only...2.com/log/2ch/$2/$1/$2/kako/$5/$4/$3.dat" },
  26. // { name: 'logsoku (htmltodat CompatibleMode)', obj: new HTMLtoDAT(htmltodatDir + 'ログ速.prm', true) },
  27. // { name: 'logsoku (htmltodat)', obj: new HTMLtoDAT(htmltodatDir + 'ログ速.prm') },
  28. // { name: '暇つぶし2ch', obj: new HTMLtoDAT(htmltodatDir + '暇つぶし2ch.prm', true) },
  29. ];
  30. // -----------------------------設定項目ここまで---------------------------
  31.  
  32. // getdat.jsの設定用サブフォルダ(V2C/script/system/getdat/)取得用
  33. //フォルダパス取得の為のダミーなのでdummy.txtは実際に存在しなくても問題ない
  34. var SubFile = v2c.getScriptSubFile('dummy.txt');
  35. if (!SubFile.exists()) {
  36. v2c.writeStringToFile(SubFile, 'dummy');
  37. }
  38. var scriptSubDir = SubFile.getParent();
  39.  
  40. function _FUTABAtoDAT()
  41. {
  42. this.getURL = function(thread)
  43. {
  44. return thread.url.toString().replaceAll('^http:\\/\\/(.+\\.2chan\\.net)\\/test\\/read.cgi\\/(\\w+)\\/(\\d+).*', 'http://$1/$2/res/$3.htm');
  45. };
  46.  
  47. this.exec = function(thread)
  48. {
  49. var url = this.getURL(thread);
  50. if (url.toString().indexOf('2chan') < 0) { printlnLog('ふたばURLではないのでスキップします。'); return false; }
  51. var html = null;
  52. html = getThreadLog(url);
  53. if (!html) { printlnLog('ふたば☆ちゃんねるログが取得できませんでした。'); return ''; }
  54.  
  55. var dat = new java.lang.StringBuilder();
  56. var parser = new HTMLParser(String(html));
  57. var matches = [];
  58.  
  59. // タイトルの抽出
  60. var title = '';
  61. if (!(title = parser.Parse('<title>', ' - '))) {
  62. title = 'タイトルなし';
  63. }
  64. // レス部分のみ抽出
  65. var cutkey = {start:'</iframe></div>画像ファイル名:', end:'<div style="clear:left"></div>'};
  66. parser.Cut(cutkey.start, cutkey.end);
  67.  
  68. // スレ立て画像の取得
  69. var thImgKey = {start:'<a href="', end:'" target='};
  70. var thImg = parser.Parse(thImgKey.start, thImgKey.end);
  71.  
  72. // 1のレスの取得
  73. var artkey = {start:'value=delete id=delcheck', end:'</blockquote></td></tr></table>'};
  74. var infoKey = {start: 'value=delete id=delcheck', end:'</blockquote>'};
  75. var idRegex = new RegExp('(\\d+/\\d+/\\d+\\(.\\)\\d+:\\d+:\\d+)(?:<!--[^>]+>)? ((?:(?:ID|IP):[^ ]+ )?No\\.\\d+)', 'i');
  76. var titleRegex = new RegExp('<font color=\'#cc1105\'><b>([^<]+)</b>', 'i');
  77. var nameRegex = new RegExp('<font color=\'#117743\'><b>([^<]+)</b>', 'i');
  78. var mailRegex = new RegExp('<a href="mailto:([^"]+)">', 'i');
  79. var mesRegex = new RegExp('<blockquote[^>]*>(.*)</blockquote>', 'i');
  80. var imgRegex = new RegExp('<a href="([^"]+)" target=["\']_blank["\']>', 'i');
  81.  
  82. {
  83. var rName = '', rMail = '', rId = '', rDate = '', rMes = '';
  84.  
  85. var tmp = parser.Parse(infoKey.start, infoKey.end, true, true);
  86. if (matches = idRegex.exec(tmp)) {
  87. rDate = (matches[1]) ? '20' + matches[1] : '';
  88. rDate = rDate.split(')').join(') ');
  89. rId = matches[2];
  90. }
  91. rName = (matches = nameRegex.exec(tmp)) ? matches[1] : '';
  92. rMail = (matches = mailRegex.exec(tmp)) ? matches[1] : '';
  93. rMes = (matches = mesRegex.exec(tmp)) ? matches[1] : '';
  94.  
  95. dat.append(rName + '<>' + rMail + '<>' + rDate + ' ' + rId + '<> ' + rMes + ' <br> ' + thImg + ' <>'+title+'\n');
  96. }
  97. // それ以降のレスの取得
  98. while (parser.MoveNext(artkey.start, artkey.end, true, false)) {
  99. var rName = '', rMail = '', rId = '', rDate = '', rMes = '', rImg = '';
  100.  
  101. var tmp = parser.Parse(infoKey.start, infoKey.end, true, true);
  102. if (matches = idRegex.exec(tmp)) {
  103. rDate = (matches[1]) ? '20' + matches[1] : '';
  104. rDate = rDate.split(')').join(') ');
  105. rId = matches[2];
  106. }
  107. rName = (matches = nameRegex.exec(tmp)) ? matches[1] : '';
  108. rMail = (matches = mailRegex.exec(tmp)) ? matches[1] : '';
  109. rMes = (matches = mesRegex.exec(tmp)) ? matches[1] : '';
  110. rImg = (matches = imgRegex.exec(tmp)) ? matches[1] : '';
  111.  
  112. if (rImg) {
  113. rMes += ' <br> ' + rImg;
  114. }
  115. dat.append(rName + '<>' + rMail + '<>' + rDate + ' ' + rId + '<> ' + rMes + ' <>\n');
  116. }
  117.  
  118. return dat.toString();
  119. };
  120. }
  121.  
  122. function _HTMLtoDAT(prm /* CompatibleMode = false */)
  123. {
  124. var prmFile = new java.io.File(prm);
  125. if (!prmFile.exists()) {
  126. printlnLog('ファイルが見つかりません。 ({0})', prmFile.getPath());
  127. return false;
  128. }
  129. var CompatibleMode = (arguments.length > 1) ? arguments[1] : false;
  130. var prmPath = prm;
  131. var prmBuffer = v2c.readLinesFromFile(prmFile);
  132. var URLRegex = PropertyGenerate('URLの変換', ''); // prmファイルフォーマットは複数行だけど1行しか使わないっぽいのでこれで
  133. var BeforeRegexArr = ConvertRegex(PropertyGenerate('前処理', '', true));
  134. var AfterRegexArr = ConvertRegex(PropertyGenerate('後処理', '', true));
  135. var MatchString = PropertyGenerate('変換結果式', '');
  136. var ResRegex = ConvertRegex(PropertyGenerate('正規表現', ''));
  137.  
  138. /* CompatibleMode用 以下のプロパティはとりあえず非対応。必要に応じて対応 */
  139. /*
  140. var isProxy = PropertyGenerate('Proxyを使う', false);
  141. var ProxyAddress = PropertyGenerate('Proxyアドレス', '');
  142. var AdditionalHTTPHeaderArr = PropertyGenerate('HTTPヘッダの追加', '', true);
  143. var Server = PropertyGenerate('$server', '');
  144. var Board = PropertyGenerate('$board', '');
  145. var isConvertDisabled = PropertyGenerate('dat変換をしない', '');
  146. var isAnchorRemoved = PropertyGenerate('アンカー削除', '');
  147. var isBECodeRemoved = PropertyGenerate('beコード削除', '');
  148. var isAboneReplaced = PropertyGenerate('透明あぼーんを補う', '');
  149. */
  150. this.getURL = function(thread)
  151. {
  152. var arr = URLRegex.split('#');
  153. return thread.url.toString().replaceAll(arr[1], arr[2]);
  154. };
  155. this.CompatibleExec = function(thread)
  156. {
  157. var logsoku_url = this.getURL(thread);
  158. if (logsoku_url === String(thread.url.toString())) return '';
  159. var html = '';
  160. var local = (arguments.length > 1) ? arguments[1] : false;
  161. if (local) {
  162. html = local;
  163. } else {
  164. html = getThreadLog(logsoku_url);
  165. }
  166. if (!html) return '';
  167. html = String(html).split('\r\n').join('').split('\n').join('');
  168. //前変換
  169. for (var i = 0; i < BeforeRegexArr.length; i++) {
  170. html = html.replace(BeforeRegexArr[i].regex, BeforeRegexArr[i].match);
  171. }
  172. var title = /<title>(.*?)<\/title>/i.exec(html)[1];
  173. //DAT変換
  174. var dat = [];
  175. var resre = new RegExp(ResRegex[0].regex.source, "ig");
  176. var item;
  177. while ((item = resre.exec(html)) !== null) {
  178. var tmp = MatchString;
  179. for (var i = 1; i < item.length; i++) {
  180. tmp = tmp.replace('$'+ i.toString(), (item[i])? item[i] : '');
  181. }
  182. if (title) {
  183. tmp += title;
  184. title = '';
  185. }
  186. dat.push(tmp);
  187. }
  188. dat = dat.join('\n');
  189. dat += '\n';
  190. //後変換
  191. for (var i = 0; i < AfterRegexArr.length; i++) {
  192. dat = dat.replace(AfterRegexArr[i].regex, AfterRegexArr[i].match);
  193. }
  194. return new java.lang.String(dat);
  195. };
  196. this.exec = function(thread)
  197. {
  198. var OS = java.lang.System.getProperty("os.name").toLowerCase();
  199. if (OS.indexOf('win') < 0) {
  200. printlnLog('HTMLtoDATはWindows以外では動きません。HTMLtoDATCompatibleを使用します。');
  201. return this.CompatibleExec(thread);
  202. }
  203.  
  204. // V2Cログ・設定保存用フォルダにhtmltodat0.9.0フォルダを入れる。フォルダ名等が違う場合は便宜変更。
  205. var exe = htmltodatDir + 'htmltodat.exe';
  206.  
  207. if (!(new java.io.File(exe)).exists()) {
  208. printlnLog('htmltodat.exeがなかったので実行できませんでした。({0})',exe);
  209. return '';
  210. }
  211.  
  212. var tmpPath = scriptSubDir + '/tmp_' + Math.floor(Math.random() * 1000).toString() + (new Date()).getTime().toString() + '.dat';
  213.  
  214. if (!URLRegex) {
  215. var endl = java.lang.System.getProperty("line.separator");
  216. printlnLog('prmファイルにURLの変換を記述して下さい。以下はログ速の場合の記述例です。');
  217. v2c.println('URLの変換:' + endl + 's#http://(.+?)/test/read\\.cgi/(.+?)/(\\d+)/?.*#http://l...content-available-to-author-only...u.com/thread/$1/$2/$3/#' + endl + '[ここに空行を1行必ず入れること]');
  218. return '';
  219. }
  220. v2c.println(exe + " " + prmPath + " " + tmpPath);
  221. v2c.exec([exe, thread.url.toString(), prmPath, tmpPath]);
  222. java.lang.Thread.sleep(300);
  223. while (isProcessRunning('htmltodat.exe')) {
  224. java.lang.Thread.sleep(1000);
  225. }
  226. var f = new java.io.File(tmpPath);
  227. var dat = v2c.readStringFromFile(f);
  228. f["delete"]();
  229. return dat;
  230. };
  231.  
  232. if (CompatibleMode) {
  233. this.exec = this.CompatibleExec;
  234. }
  235.  
  236. function ConvertRegex(regexes)
  237. {
  238. var ret = [];
  239. var regs = regexes;
  240. if (!(regexes instanceof Array)) {
  241. regs = (String(regexes)).replace(/\r\n?/g, '\n').split('\n');
  242. }
  243.  
  244. for (var i = 0; i < regs.length; i++) {
  245. var arr = (String(regs[i])).split('#');
  246. var opt = '';
  247. var num = (arr[0] === 'm')? 2 : 3;
  248. if (arr[num]) {
  249. if (arr[num].indexOf('g') >= 0) opt += 'g';
  250. if (arr[num].indexOf('i') >= 0) opt += 'i';
  251. if (arr[num].indexOf('m') >= 0) opt += 'm';
  252. }
  253. var re = new RegExp(arr[1], opt);
  254. ret.push({regex: re, match: arr[2]});
  255. }
  256. return ret;
  257. }
  258.  
  259. function PropertyGenerate(propName, initValue /* isMultiLine = false */)
  260. {
  261. var isMultiLine = (arguments.length > 2) ? arguments[2] : false;
  262. var fileext = (arguments.length > 3) ? arguments[3] : false;
  263.  
  264. var ret = [];
  265. var idx = -1;
  266. var p = java.util.regex.Pattern.compile('^'+propName+'.*?');
  267. for (var i = 0; i < prmBuffer.length; i++) {
  268. if (prmBuffer[i].length() > 0) {
  269. if (p.matcher(prmBuffer[i]).matches()) {
  270. idx = i;
  271. break;
  272. }
  273. }
  274. }
  275. if (idx < 0) { return initValue; }
  276.  
  277. var idx2 = 0;
  278. if (-1 != (idx2 = prmBuffer[idx].indexOf('='))) {
  279. // 外部ファイル指定された場合 ログ・設定保存用フォルダ/htmltodat0.9.0/フォルダ内のファイルを読み込む
  280. ret = prmBuffer[idx].substring(idx2 + 1);
  281. switch (propName) {
  282. case '変換結果式' : ret += '.cvr'; break;
  283. case '後処理' : ret += '.acv'; break;
  284. case '前処理' : ret += '.bcv'; break;
  285. case 'URLの変換' : ret += '.ucv'; break;
  286. case 'HTTPヘッダの追加' : ret += '.hdr'; break;
  287. case 'Proxyアドレス' : ret += '.txt'; break;
  288. default: break;
  289. }
  290. var f = new java.io.File(htmltodatDir + ret);
  291. if (!f.exists()) {
  292. printlnLog('ファイルが見つかりません。 ({0})', f.getPath());
  293. }
  294. ret = v2c.readLinesFromFile(f);
  295. if ((ret instanceof Array) && ret.length == 1) {
  296. ret = ret[0];
  297. }
  298. }
  299. else {
  300. // prmファイルに記述されてる場合
  301. idx++;
  302. while (prmBuffer[idx].length() <= 0) { idx++; }
  303. while ((idx < prmBuffer.length) && (prmBuffer[idx].length() > 0)) {
  304. if (isMultiLine) {
  305. ret.push(prmBuffer[idx++]);
  306. } else {
  307. ret = prmBuffer[idx];
  308. break;
  309. }
  310. }
  311. }
  312.  
  313. if (ret instanceof Array) {
  314. for (var i = 0; i < ret.length; i++) {
  315. if (ret[i].charAt(0) === '#'.charCodeAt(0)) {
  316. ret.splice(i--, 1);
  317. }
  318. }
  319. }
  320. if (ret.length == 0) {
  321. ret = initValue;
  322. }
  323.  
  324. return ret;
  325. }
  326. }
  327.  
  328. function HTMLParser(html)
  329. {
  330. var doc = html;
  331. this.index = 0;
  332. this.endIndex = doc.length;
  333.  
  334. this.getHtml = function() { return doc; };
  335. this.Parse = function(startkey, endkey /* isStartKey = false, isEndKey = false */)
  336. {
  337. var ret = '';
  338. var ix1,ix2;
  339. var isStartKey = (arguments.length > 2) ? arguments[2] : false;
  340. var isEndKey = (arguments.length > 3) ? arguments[3] : false;
  341.  
  342. if (-1 == (ix1 = doc.indexOf(startkey, this.index)))
  343. return ret;
  344. if (!isStartKey)
  345. ix1 += startkey.length;
  346.  
  347. if (-1 == (ix2 = doc.indexOf(endkey, ix1)))
  348. return ret;
  349.  
  350. if (isEndKey)
  351. ix2 += endkey.length;
  352.  
  353. if (ix2 > this.endIndex)
  354. return ret;
  355.  
  356. ret = doc.substring(ix1, ix2);
  357. this.index = ix2;
  358. return ret;
  359. };
  360. this.ParseLine = function()
  361. {
  362. var ret = '';
  363. var end = doc.indexOf('\n', this.index);
  364. if ((end > 0) && (end <= this.endIndex)) {
  365. ret = doc.substring(this.index, end);
  366. this.index = end;
  367. }
  368. return ret;
  369. };
  370. this.ParseShift = function(startkey, endkey)
  371. {
  372. var ret = this.Parse(startkey, endkey);
  373. this.Shift();
  374. return ret;
  375. };
  376. this.Shift = function()
  377. {
  378. doc = doc.substr(this.index);
  379. this.endIndex -= this.index;
  380. this.index = 0;
  381. };
  382. this.MoveNext = function(key, endIdxKey /* isStartKey = false, isEndKey = false */)
  383. {
  384. var isStartKey = (arguments.length > 2) ? arguments[2] : false;
  385. var isEndKey = (arguments.length > 3) ? arguments[3] : false;
  386. var ix1, ix2;
  387. if ((ix1 = doc.indexOf(key, this.index)) == -1)
  388. return false;
  389. if (!isStartKey)
  390. ix1 += key.length;
  391. if ((ix2 = doc.indexOf(endIdxKey, ix1)) == -1)
  392. return false;
  393. if (ix1 == ix2)
  394. return false;
  395.  
  396. this.index = ix1;
  397. if (isEndKey)
  398. this.endIndex = ix2;
  399. return this.index;
  400. };
  401. this.Cut = function(startkey, endkey)
  402. {
  403. this.index = doc.indexOf(startkey, this.index) + startkey.length;
  404. doc = doc.substring(this.index, doc.lastIndexOf(endkey));
  405. this.index = 0;
  406. this.endIndex = doc.length;
  407. return doc;
  408. };
  409. }
  410.  
  411. // 仕様:
  412. // 以下のログ速の仕様のためオリジナルdatとのバイナリ一致は不可能
  413. // >1などアンカミスを>>1にしてしまう
  414. // 2chURLが全てrogsokuのURLに置換されてるのでh抜き等に対応できない(全てhttp://で書きだす)
  415. // また同様に2chURLのホスト名が不明なので現サーバーのホスト名で2chURLを生成している(ログ速のapiを叩けば拾えるがdat生成が遅くなるのと相手先に負荷がかかるため実装しない)
  416. function _LOGSOKUtoDAT()
  417. {
  418. this.getURL = function(thread)
  419. {
  420. return thread.url.toString().replaceAll('^http:\\/\\/(.+\\.2ch\\.net)\\/test\\/read[^/]+\\/(.+?)\\/(\\d+).*', 'http://l...content-available-to-author-only...u.com/thread/$1/$2/$3/');
  421. };
  422.  
  423. this.exec = function(thread)
  424. {
  425. var logsoku_url = this.getURL(thread);
  426. if (logsoku_url === String(thread.url.toString()) || logsoku_url.indexOf('bbspink') != -1) {
  427. printlnLog("指定されたスレッドはログ速が非対応のBBSPINKのスレッドなので取得できませんでした。");
  428. return '';
  429. }
  430. if (logsoku_url.toString().indexOf('2chan') >= 0) { printlnLog('ログ速が非対応なふたばスレッドのURLなのでスキップします。'); return false; }
  431. var html = '';
  432. var local = (arguments.length > 1) ? arguments[1] : false;
  433. if (local) {
  434. html = local;
  435. } else {
  436. html = getThreadLog(logsoku_url);
  437. }
  438. if (!html) {
  439. printlnLog("ログ速のHTMLが取得できませんでした。");
  440. return '';
  441. }
  442. var dat = new java.lang.StringBuilder();
  443. var title = '';
  444. var parser = new HTMLParser(String(html));
  445. // タイトルの取得
  446. var keyword = {start :'og:title" content="', end :' | ログ速"/>'};
  447. if (!(title = parser.Parse(keyword.start, keyword.end))) {
  448. printlnLog("ログ速のHTMLからスレッドタイトルが取得できませんでした。(仕様変更?)");
  449. return '';
  450. }
  451. // レス部分だけ抜き出し
  452. keyword.start = '<div id="comments">';
  453. keyword.end = '</div> <hr class="divider"';
  454. parser.Cut(keyword.start, keyword.end);
  455.  
  456. var nkey = {start :'em"> <b>', end :'</b></span>'}; // 名前欄
  457. var mkey = {start :'[', end :']'}; // メール欄
  458. var tkey = {start :'投稿日:', end :' <a href="/id/'}; // 日時
  459. var idkey = {start : '<a href="/id/', end :'<div class="comment">'}; // ID
  460. var meskey = {start :'<div class="comment"> ', end :'</div>'}; // 本文欄
  461. var artkey = {start :'<div id="', end :'</div> </div>'}; // 単レスのタグ範囲指定
  462. var bdkey = thread.board.key;
  463. var thkey = thread.key;
  464.  
  465. var thumbRegex = /<br\/><(iframe|img class).+<br\/>/g; // ニコニコとYoutubeのサムネ用のタグ削除
  466. var tagRegex = /(<|(\[))("[^"]*"|'[^']*'|[^'">])*[>\])]/g; // ID,BE,株主らへんのタグ削除+発言回数削除
  467. var kabRegex = /^ (.+?) /; // 株の1文字表記のみリンク化
  468. var ssspRegex = /<img src="http:\/\/cdn\.logsoku\.com\/(.+)">/g; // BEアイコンのURL修正及びタグ削除
  469. var linkRegex = /<a href[^>]+target="_blank"[^>]*>(.+?)<\/a>/g; // その他リンクタグ削除
  470. var thLinkRegex= /<a href="\/r\/[^>]+>http:\/\/www\.logsoku\.com\/r\/([^\/]+)\/([^<]+)<\/a>/g; // 他スレッドへのリンクタグを平文に置換
  471. var anchorRegex= /<a href=".*data-pop-res="(\d+)"[^>]*>/g; // アンカーのURL修正
  472. var playerRegex = /<\/?(div|img)[^>]*>/g; // Youtubeプレイヤーの除去
  473.  
  474. while (parser.MoveNext(artkey.start, artkey.end)) {
  475.  
  476. var name = parser.Parse(nkey.start, nkey.end);
  477. var mail = parser.Parse(mkey.start, mkey.end);
  478. var date = parser.Parse(tkey.start, tkey.end);
  479. parser.index++; // 日時とIDの間の半角スペースを飛ばす
  480. var mes = '';
  481. if (date) {
  482. var idset = parser.Parse(idkey.start, idkey.end, true, false);
  483. if (idset) {
  484. idset = idset.replace(tagRegex, '');
  485. idset = idset.replace(kabRegex, ' <a href="http://2...content-available-to-author-only...h.se/">$1</a> ');
  486. date += ' ' + idset;
  487. }
  488.  
  489. mes = parser.Parse(meskey.start, meskey.end);
  490. mes = mes.replace(thumbRegex, '');
  491. if (mes.indexOf('<') >= 0) {
  492. mes = mes.replace(ssspRegex, 'sssp://$1');
  493. mes = mes.replace(linkRegex, '$1');
  494. mes = mes.replace(anchorRegex, '<a href="../test/read.cgi/'+ bdkey + '/' + thkey + '/$1" target="_blank">');
  495. mes = mes.replace(thLinkRegex, function(whole, m1, m2) {
  496. return 'http://' + v2c.bbs2ch.getBoard(m1).url.host + '/test/read.cgi/' + m1 + '/' + m2;
  497. });
  498. mes = mes.replace(playerRegex, '');
  499. }
  500. mes = mes.split("<br/>").join('<br>');
  501. } else {
  502. date = 'Over 1000 Thread';
  503.  
  504. var mArr = parser.Parse(meskey.start, meskey.end).split("<br/>"); // <br/> → <br>にするついでに<br>以外のタグを削除
  505. for (var i = 0; i < mArr.length; i++) {
  506. mArr[i] = mArr[i].replace(/<.+?>/g, '');
  507. }
  508. mes = mArr.join('<br>');
  509. mes = mes.split('&gt;').join('>').split('&lt;').join('<').split('&quot;').join('"'); // 1001ではHTMLエンコードされないようだ
  510. }
  511.  
  512. if (dat.length() == 0) {
  513. dat.append(name + '<>' + mail + '<>' + date + '<> ' + mes + ' <>'+title+'\n');
  514. } else {
  515. dat.append(name + '<>' + mail + '<>' + date + '<> ' + mes + ' <>\n');
  516. }
  517. }
  518. return dat.toString();
  519. };
  520. }
  521.  
  522. this.isProcessRunning = function(processName)
  523. {
  524. var cnt = 0;
  525. try {
  526. var runtime = java.lang.Runtime.getRuntime();
  527. var p;
  528. var OS = java.lang.System.getProperty("os.name").toLowerCase();
  529. if (OS.indexOf('win') >= 0) {
  530. p = runtime.exec(['cmd.exe', '/c', 'tasklist | findstr "' +processName + '"']);
  531. } else {
  532. p = runtime.exec(['/bin/sh', '-c', 'ps ux | pgrep -lf "' + processName + '"']);
  533. }
  534. var is = p.getInputStream();
  535. var isr = new java.io.InputStreamReader(is);
  536. var br = new java.io.BufferedReader(isr);
  537. while (br.readLine()) { cnt++; }
  538.  
  539. br.close();
  540. isr.close();
  541. is.close();
  542. } catch (e) {
  543. if (e.javaException) {
  544. printlnLog('プロセス名の取得に失敗しました。 ({0})', e.javaException);
  545. } else {
  546. printlnLog('プロセス名の取得に失敗しました。 (e={0})', e);
  547. }
  548. }
  549. return (cnt)? true : false;
  550. };
  551.  
  552. this.getThreadLog = function(url)
  553. {
  554. var req = v2c.createHttpRequest(url);
  555. req.setRequestProperty('Accept-Encoding', 'gzip');
  556. var content = req.getContentsAsString();
  557. if (req.responseCode==200 || req.responseCode==302) {
  558. if (req.responseCode == 302) {
  559. var newUrl = req.getResponseHeader('Location');
  560. content = v2c.readURL(newUrl);
  561. }
  562. } else {
  563. return null;
  564. }
  565.  
  566. if(!content) {
  567. return null;
  568. }
  569.  
  570. return content;
  571. };
  572.  
  573. this.printlnLog = function(format /*, ...*/)
  574. {
  575. var args = arguments;
  576. var message = format.replace(/\{(\d)\}/g, function(m, c) { return args[parseInt(c) + 1]; });
  577.  
  578. v2c.println("[getdat.js] " + message);
  579. };
  580. this.getFormatString = function(/*format, ...*/)
  581. {
  582. var args = (arguments[0] instanceof Array)? arguments[0] : arguments;
  583. return String(args[0]).replace(/\{(\d)\}/g, function(m, c) { return args[parseInt(c) + 1]; });
  584. }
  585. })();
  586.  
  587. function getDat(thread)
  588. {
  589. if (!(thread.bbs.is2ch || (thread.url.toString().indexOf('2chan') >= 0))) {
  590. return null;
  591. }
  592. var retrievedResCount = thread.localResCount;
  593. var dat = null;
  594. for(var i = 0; retrievedResCount < 1001 && i < services.length; i++)
  595. {
  596. v2c.setStatus("過去ログを取得中........( ´∀`)つ旦 " + services[i].name);
  597. var content = '';
  598. var url = '';
  599. if (services[i].obj) {
  600. url = services[i].obj.getURL(thread);
  601. content = services[i].obj.exec(thread);
  602. } else if (services[i].src && services[i].dst) {
  603. url = (String(thread.url.toString())).replace(services[i].src, services[i].dst);
  604. content = getThreadLog(url);
  605. }
  606. if (v2c.interupted) { return null; }
  607. if(!content)
  608. continue;
  609.  
  610. var resCount = content.split("\n").length;
  611. if ((resCount == 1) && (content.split("\n")[0].match(/unkar\.org/))) continue;
  612.  
  613. printlnLog("{0} ({1}): {2}", services[i].name, resCount, url);
  614.  
  615. if(retrievedResCount < resCount)
  616. {
  617. dat = { service: services[i], content: content };
  618. retrievedResCount = resCount;
  619. }
  620. }
  621.  
  622. var found = dat ? "retrieved from " + dat.service.name : "not found";
  623. printlnLog("{0}: {1} (+{2})", found, thread.title, retrievedResCount - thread.localResCount);
  624.  
  625. return dat ? dat.content : null;
  626. }
  627.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty