SHOW:
|
|
- or go back to the newest paste.
1 | /********************************************************************/ | |
2 | - | /* gethtmldat.js : ver.0.73 2017/10/04 */ |
2 | + | /* gethtmldat.js : ver.0.33 2015/05/17 */ |
3 | /********************************************************************/ | |
4 | // | |
5 | // Jane2ch.exeでhtmlから過去ログを取得しdat形式に変換してLogsフォルダに格納する | |
6 | - | // htmltodat-convert2.wsf+htmltodat.exeと同じような機能を果たす |
6 | + | // htmltodat-convert2.wsf+htmltodat.exeと同じ機能を果たす |
7 | // htmltodat-convert2.wsfとGetLog.wsfからコードを盗用してます(許して) | |
8 | // | |
9 | - | //============================================================== |
9 | + | //-------------------------------------------------------------------- |
10 | // ※ 重要 ※ | |
11 | - | // なお、このスクリプトはpastbinのサイトから download するのではなく、 |
11 | + | // なお、このスクリプトはこのサイトから DOWNLOAD するのではなく、RAW で表示したものか又はRAW Paste Data から、 |
12 | - | // RAW( http://pastebin.com/raw.php?i=3EZzrsxY )で表示したものか 又は |
12 | + | // コピー&ペースト(CTRL+A,CTRL+C,CTRL+V)で、テキストエディタに貼り付け、gethtmldat.js という名前で |
13 | - | // 下の方にある RAW Paste Data から、コピー&ペースト(CTRL+A,CTRL+C 及び CTRL+V)で、 |
13 | + | // Shift-JISコード(メモ帳ではANSI)で保存し、Jane2ch.exe のあるフォルダに格納してください |
14 | - | // テキストエディタに貼り付け、gethtmldat.js という名前でShift-JISコード(メモ帳ではANSI) |
14 | + | // ※重要※ DOWNLOADすると、文字コードがUTF-8となり実行できなくなるので注意してください |
15 | - | // で保存し、Jane2ch.exe のあるフォルダに格納してください |
15 | + | //-------------------------------------------------------------------- |
16 | - | // ※注意※ DOWNLOADすると、文字コードがUTF-8となり実行できません |
16 | + | |
17 | - | // また、行番号付きでコピー&ペーストしても実行できません |
17 | + | |
18 | - | //============================================================== |
18 | + | |
19 | // コマンド内容 - wscript "$BASEPATHgethtmldat.js" $LINK$URL | |
20 | // を入力して、追加、OKします | |
21 | // ※ なお、Jane直下フォルダでは無い場合はパスをフルパスで指定してください | |
22 | // jane styleの下のscriptフォルダに入れた場合は、wscript "$BASEPATHscript\gethtmldat.js" $LINK$URL | |
23 | // | |
24 | // コマンド登録時のパラメタに /w 又は /w:999(待ち時間) を追加するとキー送信(CTL+W)により、スレを閉じて再度開く動作をします | |
25 | - | // jane styleの下のscriptフォルダに入れた場合は、 |
25 | + | // wscript "$BASEPATHgethtmldat.js" $LINK$URL /w |
26 | - | // wscript "$BASEPATHscript\gethtmldat.js" $LINK$URL |
26 | + | // ※注意※ 当該スレが開く前にキー送信がなされると現在開いている別スレが閉じてしまいます |
27 | // | |
28 | // 起動オプション: 順不同 | |
29 | - | // 起動オプション: 順不同 []内は省略可 |
29 | + | // http://~ url指定 |
30 | - | // [+]http://~ url指定 |
30 | + | |
31 | - | // (先頭に+を付けるとdatにURL末尾の指定範囲のレス部分だけ上書きする /aは無効) |
31 | + | |
32 | // /w[:999] スレを指定時間待って閉じ、開き直す(数値省略時 1200ms) | |
33 | // /-w スレを閉じない(デフォルト) | |
34 | // /a[ppend] 差分のみ取得(管理人削除などで既存のログとサーバー上のデータに違いがあっても関知しない) | |
35 | - | // 当該スレが開く前にキー送信がなされると現在開いている別スレが閉じてしまいます |
35 | + | // /b[ak][1] バックアップを取る(Logs\bak\の下に既存のdatファイルをコピーする) /b1 は1回限りで上書きしない |
36 | - | // /a[ppend] 差分のみ取得 |
36 | + | // /redraw[:999] 再描画 スレを開いた後、指定時間待ってからキーコード('ALT','T','G','0')を送る (数値省略時 1200ms) |
37 | - | // (管理人削除などで既存のログとサーバー上のデータに違いがあっても関知しない) |
37 | + | |
38 | - | // /b[ak][1] バックアップを取る(Logs\bak\の下に既存のdatファイルをコピーする) |
38 | + | |
39 | - | // /b1 にするとバックアップファイルが存在しているとコピーしない |
39 | + | // SQLite3 ODBC Driver : http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe をダウンロード・インストール |
40 | - | // /redraw[:999] 再描画 スレを開いた後、指定時間待ってからキーコード('ALT','T','G','0')を送る |
40 | + | // (インストールは上記exeを実行し、Next,I Agree,Next,Install,Finishボタンで進める) |
41 | - | // (数値省略時 1200ms) |
41 | + | // sqlite3.exe : http://www.sqlite.org/download.html から、sqlite-shell-win32-x86-3080900.zip |
42 | // をダウンロード・解凍し、本スクリプトと同じフォルダに格納する | |
43 | // /log[:][path] トレースログを指定のファイルに追加書き込みします(ファイルパス名省略時は %temp%\gethtmldat.log) | |
44 | - | // SQLite3 ODBC Driver : http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe |
44 | + | |
45 | - | // をインストール(exeを実行し、デフォルトなりで進める) |
45 | + | |
46 | - | // sqlite3.exe : http://www.sqlite.org/download.html から、 |
46 | + | // Jane Styleで、過去ログを開いた(空白の)レス表示欄で、 |
47 | - | // sqlite-shell-win32-x86-3080900.zip をダウンロード・ |
47 | + | // 又は、別スレに書かれているリンクを、 |
48 | - | // 解凍し、本スクリプトと同じフォルダに格納する |
48 | + | // 又は、書き込みウィンドウ、メモ欄にURLを書き込みプレビューで現れるリンクを、 |
49 | - | // "/log[:path]" トレースログを指定のファイルに追加書き込みします |
49 | + | // 右クリックして上で登録したコマンドを選択する |
50 | - | // (ファイルパス名省略時は %temp%\スクリプト名.log) |
50 | + | // レスが表示・認識されない場合は、再描画、スレを閉じリンククリックで開き直す、>>1などのリンクをクリックなどしてください |
51 | - | // /keep_kako 渡された過去ログURLをそのまま処理する(したらば、next2ch、machi以外で有効) |
51 | + | //-------------------------------------------------------------------------------- |
52 | - | // /proxy:server:port PROXYサーバー経由でアクセスする場合に指定する |
52 | + | |
53 | - | // /cfg[:path] カスタマイズ用定義ファイルの読み込み(path省略はスクリプトフォルダ\スクリプト名.cfg) |
53 | + | |
54 | - | // 内容は、JScriptの文法で記述する |
54 | + | |
55 | @set @EnabledTest2chJSON = false; // =true で2chで最初にJSONでの取得を試みる(お遊び機能:仕様等一切不明、過去ログは無理) | |
56 | @*/ | |
57 | - | // 以下のa)~c)のいずれかで右クリックして上記登録したコマンドを選択する |
57 | + | |
58 | - | // a) Jane Styleで、過去ログを開いたレス表示欄 |
58 | + | |
59 | - | // (2chでサーバーの移転があった場合は板一覧にある最新の移転先URLが受け渡されるので注意) |
59 | + | // "If-Modified-Since" : "Thu, 01 Jun 1970 00:00:00 GMT" |
60 | - | // b) 別スレに書かれているリンク |
60 | + | // ,"Content-Type" : "application/x-www-form-urlencoded" |
61 | - | // c) 書き込みウィンドウ、メモ欄にURLを書き込みプレビューで現れるリンク |
61 | + | // ,"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;)" |
62 | }; | |
63 | - | // TIPS : |
63 | + | var HTTP_TIMEOUT = 10 * 1000; |
64 | - | // ●★「過去ログ」と表示されている場合は、メニュー(スレッド)から「強制過去ログ化」のチェック |
64 | + | |
65 | - | // (又はスレッドツールバーのゴミ箱アイコンをクリックして「強制過去ログ化」) |
65 | + | var JBBS_ABN_STR = "透明あぼーん<><> <><>"; |
66 | - | // を外すか又は、一旦ログを削除後にリンクから再取得してください |
66 | + | |
67 | - | // ●レスが表示されない場合は、スレッドツールバーの「表示レス数/スレの再描画」アイコンを |
67 | + | |
68 | - | // 右クリックしてください |
68 | + | |
69 | - | // ●レス内容が「スレの再描画」でも変わらない場合は、 |
69 | + | |
70 | - | // (「お気に入り」を「更新チェック」後に、その中のスレを本スクリプトで取得した場合などが相当) |
70 | + | |
71 | - | // スレ一覧画面の「お気に入りグループ名」タブを閉じてから「スレの再描画」をしてみてください |
71 | + | var http; try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0"); } catch(e){} |
72 | - | // また「検索結果」「ログ一覧」「最近読込」「最近書込」「OpenThreads」の場合も同様です |
72 | + | if (!http) try { http = new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e){} |
73 | - | // ●未読状態が既読状態にならない場合やレス番リンクのポップアップが表示されなかったり |
73 | + | if (!http) { http = new ActiveXObject("Msxml2.XMLHTTP.3.0"); } |
74 | - | // ID抽出回数が0回になる場合は |
74 | + | |
75 | - | // 1)ステータスが過去ログ以外の時、所属する板を開いてスレ一覧更新をして、 |
75 | + | |
76 | - | // 又は、スレを開きなおして、最新レス末尾までスクロールさせる |
76 | + | |
77 | - | // 2)過去ログの場合、上記「強制過去ログ化」のチェックを外した後、 |
77 | + | shell.CurrentDirectory = JANE_PATH; |
78 | - | // 又は、>>999 などの未読状態のレスを指すリンクをクリックする |
78 | + | |
79 | - | // 又は、名前欄1001をクリックする |
79 | + | |
80 | - | // 又はアドレスバーに「スレURL/999」のようなレス番付きで入力する |
80 | + | |
81 | - | // 「最後までスクロールしたスレを既読にする」「再描画する」の場合は、末尾までスクロールさせる |
81 | + | |
82 | - | // ★なお、新着チェックができる(ボタンが押せる)のなら新着チェックでよい |
82 | + | |
83 | - | // ●2ch.netでftp://問題により520エラー又はデータが途切れてしまう場合の部分的な救済方法 |
83 | + | |
84 | - | // webブラウザで問題となるレス番をtrial and errorで目星をつけて、それを避けるように |
84 | + | |
85 | - | // 範囲指定してデータを取得する |
85 | + | |
86 | - | // 例えば、レス番50が引っ掛かっている場合は、-49 と 51- の2回に分けて取得する |
86 | + | |
87 | - | // コマンド登録時には、+$LINK$URLとし、URL末尾に範囲指定付きのリンクから使うか |
87 | + | //-------------------------------------------------------------------------------- |
88 | - | // /f も追加して、実行時にURL末尾にレス番範囲を追加で入力する |
88 | + | |
89 | String.prototype.convDontUseStr = function() { | |
90 | - | // 修正履歴: |
90 | + | |
91 | - | // http://pastebin.com/my14uCkr を参照 |
91 | + | |
92 | - | //============================================================== |
92 | + | var s = this; |
93 | for(var i in tbl0) { s=s.replace( new RegExp("^"+i+"$","i") , tbl0[i]); } | |
94 | return s.replace(/[\\/:*?]/g, function (w){return tbl1[w];}); | |
95 | } | |
96 | - | // 以下をtrueにすると2chで最初にJSONでの取得を試みる(お遊び機能:仕様等一切不明) |
96 | + | function Err(s,t) { s=ErrMsg(s,t); trace("---- "+s+" ----",2); throw new Error(s); } |
97 | - | @set @EnabledTest2chJSON = false; |
97 | + | |
98 | - | //漢字コード変換にbasp21.dllを使う |
98 | + | |
99 | - | // http://www.hi-ho.ne.jp/babaq/basp21.htmlのBASP21-2003-0211.exeのインストールが必要 |
99 | + | |
100 | - | @set @EnabledBASP21 = false; |
100 | + | |
101 | ||
102 | var ERROR_MSG = { | |
103 | "E_already_there" : "このスレは既に取得しています" | |
104 | - | "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" |
104 | + | |
105 | ,"E_remained_garbage" : "レスデータのみの抽出に失敗しました" | |
106 | - | var HTTP_TIMEOUT = 120 * 1000; |
106 | + | |
107 | ,"E_title_not_found" : "スレタイトルが見つかりません" | |
108 | - | var ABN_MSG = "透明あぼ~ん<>透明あぼ~ん<>透明あぼ~ん ID:DELETED<>透明あぼ~ん<>透明あぼ~ん"; |
108 | + | |
109 | - | var ABN_MSG_PINK = "うふ~ん<>うふ~ん<>うふ~ん ID:DELETED<>うふ~ん<>うふ~ん"; |
109 | + | |
110 | - | var NOT_GET_MSG = "未取得<>未取得<>未取得 ID:NONE<>未取得<>"; |
110 | + | ,"E_stop" : "処理を中止しました" |
111 | ,"E_no_data" : "取得データはありません" | |
112 | ,"E_http_timeout" : "受信タイムアウト" | |
113 | ,"E_http_recieve" : "http受信エラー" | |
114 | ,"E_bbs_not_found" : "掲示板番号が不正です" | |
115 | ,"E_key_not_found" :"スレッド番号が不正です" | |
116 | - | var http; |
116 | + | |
117 | - | var USED_WINHTTP = true; |
117 | + | |
118 | - | try { http = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); } catch(e){} |
118 | + | ,"E_unmatched_res_count" : "抽出したレス数が合いません" |
119 | - | if (!http) try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0"); } catch(e){} |
119 | + | |
120 | - | if (!http) try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.3.0"); } catch(e){} |
120 | + | |
121 | - | if (!http) var USED_WINHTTP = false; |
121 | + | |
122 | - | if (!http) try { http = new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e){} |
122 | + | |
123 | - | if (!http) { http = new ActiveXObject("Msxml2.XMLHTTP.3.0"); } |
123 | + | |
124 | - | var basp; /*@if (@EnabledBASP21) try { basp = new ActiveXObject("basp21"); } catch(e){} @end @*/ |
124 | + | |
125 | f.prototype = o; | |
126 | n = new f; | |
127 | for (i=1, len=arguments.length; i<len; ++i) for (prop in arguments[i]) n[prop] = arguments[i][prop]; | |
128 | - | //shell.CurrentDirectory = JANE_PATH; |
128 | + | |
129 | } | |
130 | object.f = function(){}; | |
131 | //--- http://with-love-from-siberia.blogspot.jp/2009/12/msgbox-inputbox-in-jscript.html ----------- | |
132 | var vb = {}; | |
133 | vb.Function = function(func) { return function() { return vb.Function.eval.call(this, func, arguments); }; }; | |
134 | vb.Function.eval = function(func) { | |
135 | var args = Array.prototype.slice.call(arguments[1]); | |
136 | for (var i = 0; i < args.length; i++) { | |
137 | if ( typeof args[i] != 'string' ) { continue; } | |
138 | - | //カスタマイズ用定義ファイル指定(この指定より引数/cfg:での指定の方が優先される) |
138 | + | |
139 | - | var CFG_FILE = SCRIPT_PATH + MY_NAME + ".cfg"; |
139 | + | |
140 | var vbe; | |
141 | - | //欠落しているレス番をあぼーんメッセージで補う(2ch互換BBSのみ) |
141 | + | |
142 | - | // +URL指定時は無効で元のレスのままかあるいは未取得メッセージで穴埋めされる |
142 | + | |
143 | - | var FILL_ABONE = 0; //0:問い合わせる 1:常に穴埋めする 2:常に詰める |
143 | + | |
144 | - | //既存のdatファイルよりレス数が大きくない場合にdatファイルを上書きするかどうか(差分/aの場合は無効) |
144 | + | |
145 | - | var REWRITE_DAT = 0; //0:問い合わせる 1:上書きする 2:一致の場合は中止する 3:常に中止する |
145 | + | |
146 | var MsgBox = vb.Function('MsgBox'); | |
147 | - | //BEアイコン以外の<img>タグ(現状はお絵かきのみ)を変換するときのスキームを指定する ("http" or "sssp") |
147 | + | //-------------------------------------------------------------------------------- |
148 | - | var IMG_TO = "sssp:"; |
148 | + | |
149 | var args = parmParse(WScript.Arguments); | |
150 | - | //bakusai用 |
150 | + | |
151 | - | var OPT_BBS = { |
151 | + | var WMI = (function () { |
152 | - | "//bakusai.com": [thread_bakusai, "【仮想板:爆サイ】", /\/\/(bakusai\.com[^\/]*)/ ] |
152 | + | |
153 | var services = locator.ConnectServer(null, "root\\CIMV2"); | |
154 | - | var MAX_READ_PAGES_OF_THREAD_LIST_CREATE = 3; //subject.txt作成時 |
154 | + | |
155 | - | var MAX_READ_PAGES_OF_THREAD_LIST_UPDATE = 1; //subject.txt更新時 |
155 | + | |
156 | - | var BROWSER_PATH = ""; |
156 | + | |
157 | var query = "SELECT * FROM Win32_Process WHERE name='"+pName+"'"; | |
158 | - | //============================================================== |
158 | + | |
159 | for (var i=0, status=false; i<props.length; i++) { if(props[i].ExecutablePath == pPath) {status = true;} } | |
160 | return status; | |
161 | } | |
162 | ,wmiProps : | |
163 | function (query) { | |
164 | var result = []; | |
165 | try { | |
166 | - | var s = this.replace(/[. ]+$/,""); |
166 | + | |
167 | var e = new Enumerator(set); | |
168 | while (!e.atEnd()) { result.push(e.item()); e.moveNext(); } | |
169 | } catch (e) { throw e; } | |
170 | - | var trace = function(){}; |
170 | + | |
171 | - | function Err(s,t) {s=ErrMsg(s,t); trace("---- "+s+" ----",2); throw new Error(s);} |
171 | + | |
172 | ,getProcessID : | |
173 | function (pName, pPath) { | |
174 | - | var ERROR_MSG_STOP = "処理を中止しました"; |
174 | + | |
175 | do { | |
176 | var props = this.wmiProps(query); | |
177 | for (var i=0,c=0,pid; i<props.length; i++) { | |
178 | if (props[i].ExecutablePath == pPath) { c++; pid=props[i].ProcessID; } | |
179 | } | |
180 | } while (c>1); | |
181 | return pid; | |
182 | } | |
183 | - | ,"E_stop" : ERROR_MSG_STOP |
183 | + | |
184 | })(); | |
185 | ||
186 | var URL_2ch = { | |
187 | RE_SITE : new RegExp("^http://\\w+\\.(?:2ch\\.net|bbspink\\.com|2ch\\.sc)/") //この定義は未使用 | |
188 | ,RE_URL : new RegExp("^http://((\\w+)(\\.(\\w+).+?))/(?:test/.+?/)?(\\w+)/(?:kako/.+?/)?(((\\d+)\\d)\\d{5})(/|\\.html|\\.dat(?:\\.gz)?)?") | |
189 | ,setInfo : function(url) { | |
190 | this.kako = /\/kako\//.test(url); | |
191 | this.prm = url.match(this.RE_URL) || Err("E_illegal_url"); | |
192 | this.url = this.prm[0]; | |
193 | - | ,"E_not_suported_proxy" : "PROXY指定はできません(IEの設定が使われます)" |
193 | + | |
194 | - | ,"E_data_error" : "レスデータの抽出で異常を検出しました" |
194 | + | if (!this.kako) { this.url2 += (args.opt_n) ? args.opt_n : (url.match(/\/n?(\d+)[^\/]*$/)||[])[1]||"";} |
195 | - | ,"E_data_not_found" : "データがみつかりません" |
195 | + | else { delete args.append; } |
196 | - | ,"E_no_support" : "この機能はサポートしません" |
196 | + | this.site = this.prm[1]; |
197 | this.category = ""; | |
198 | this.brdID = this.prm[5]; | |
199 | this.thrID = this.prm[6]; | |
200 | } | |
201 | } | |
202 | var URL_jbbs = { | |
203 | RE_SITE : new RegExp("^http://jbbs\\.(?:shitaraba|livedoor)\\.(?:net|jp|com)/") | |
204 | ,RE_URL : new RegExp("^http://(jbbs\\.shitaraba\\.net)/bbs/\\w+\\.cgi/(\\w+)/(\\d+)/(\\d+)/?") | |
205 | ,setInfo : function(url) { | |
206 | // this.kako = /\/(storage|read_archive\.cgi)\//.test(url); | |
207 | this.prm = url.match(this.RE_URL) || Err("E_illegal_url"); | |
208 | this.url = this.prm[0]; | |
209 | this.url2 = this.prm[0] + (args.opt_n || (url.match(/\/n?(\d+)[^\/]*$/)||[])[1]||""); | |
210 | this.site = this.prm[1]; | |
211 | this.category = this.prm[2]; | |
212 | this.brdID = this.prm[3]; | |
213 | this.thrID = this.prm[4]; | |
214 | } | |
215 | } | |
216 | var URL = URL_2ch; | |
217 | ||
218 | var Jane_2ch = { | |
219 | ini : loadFile(JANE_INI) | |
220 | ,brd : "" | |
221 | ,LogBasePath : "" | |
222 | ,init : function() { this._setLogBasePath(); this._loadBRD(); } | |
223 | ,getINI : function(p) { var m=this._search(this.ini, this._re_ini, p); return m && m[1] || p[3]; } | |
224 | - | //============================================================== |
224 | + | |
225 | var m = this._search(this.brd, this._re_brd, p); | |
226 | return (m) ? m[1].convDontUseStr()+"\\"+m[2].convDontUseStr()+"\\" : null; | |
227 | } | |
228 | ,_re_ini : "^\\[$1\\]\\r\\n(?:.*\\r\\n)*?(?:$2=(.*)|\\[.*\\])\\r\\n" | |
229 | - | RE_HOST : new RegExp("^http://\\w+\\.(?:[25]ch\\.net|bbspink\\.com)/") //この定義はdat取得できないサイトの判別に使う |
229 | + | ,_re_brd : "^(\\S+).*\\r\\n(?:\\t.*\\r\\n)*?\\t\\w+$3\\t$5\\t(\\S+)\\r\\n" |
230 | - | ,RE_URL : new RegExp("^http://((\\w+(?=\\.\\w+\\.))?(\\.?(\\w+)[^\\/]+?))/(?:(?:test|bbs)/.+?/)?(\\w+)/(?:kako/.+?/)?(((\\d+)\\d)\\d{5})(/|\\.html|\\.dat(?:\\.gz)?)?") |
230 | + | ,_search : function(f,s,p) { var re,x,y; re=new RegExp(this._expand(s,p),"img"); while(x=re.exec(f)) {y=x;} return y; } |
231 | - | ,range : "" |
231 | + | |
232 | - | ,set_prm : function(url) { this._set_prm(url, 1, null, 5, 6); this.kako = /\/kako\//.test(url) && delete args.append; } |
232 | + | ,_setLogBasePath : function() { this.LogBasePath = this.getINI([,"PATH","LogBasePath",""]); } |
233 | - | ,otherURLType : 0 |
233 | + | ,_loadBRD : function() { this.brd = loadFile(this.LogBasePath + JANE_BRD); } |
234 | - | ,otherURL : "" |
234 | + | |
235 | - | ,_set_prm: function(url,p1,p2,p3,p4) { |
235 | + | |
236 | - | var r; |
236 | + | _re_brd : "^(\\S+).*\\r\\n(?:\\t.*\\r\\n)*?\\t$1/$2\\t$3\\t(\\S+)\\r\\n" |
237 | }); | |
238 | - | if(/\d$/.test(this.prm[0])) this.prm[0] += "/"; |
238 | + | |
239 | Jane.init(); | |
240 | ||
241 | - | switch(this.otherURLType) { |
241 | + | |
242 | - | case 1: this.url = this.otherURL+this.url; break; |
242 | + | |
243 | - | case 2: this.url = this.otherURL; break; |
243 | + | |
244 | - | default: break; |
244 | + | |
245 | this.dat = dat; | |
246 | - | this._setRange(url); |
246 | + | |
247 | - | this.site = this.prm[p1]; |
247 | + | |
248 | - | this.category = (p2) ? this.prm[p2] : ""; |
248 | + | |
249 | - | this.brdID = this.prm[p3]; |
249 | + | var s = loadFile2(dat); |
250 | - | this.thrID = this.prm[p4]; |
250 | + | this.cnt = s.replace(/^.*$/mg,"").length; |
251 | this.title = (s.match(/<>((?:(?!<>).)*)$/m)||[])[1]; | |
252 | - | ,_setRange : function(url) { |
252 | + | |
253 | - | var range; |
253 | + | |
254 | - | if(this.prm[0].slice(-1)=="/") { |
254 | + | |
255 | - | range = url.match(/\/n?((\d*)n?(-?)[^\/]*)$/)||[]; |
255 | + | |
256 | - | this.url2 += (args.opt_n||range[2]||""); |
256 | + | |
257 | - | if(range[3]) this.range = ((range[2]?"":"1")+range[1]||"").replace(/n/ig,""); |
257 | + | |
258 | - | else if(range[2]) this.range = range[2] + "-" + range[2]; |
258 | + | |
259 | } | |
260 | - | } |
260 | + | |
261 | - | ,appendRange : function(top) { |
261 | + | |
262 | - | if (args.overwrite) this.url += this.range; |
262 | + | |
263 | - | else this.url += ((args.append && top) ? top+"-n" : ""); |
263 | + | |
264 | } | |
265 | - | ,getUrl2 : function() { return this.url2; } |
265 | + | |
266 | - | ,entryCheck : function(url) { |
266 | + | |
267 | - | var r,i; |
267 | + | var Trace = function() { |
268 | - | |
268 | + | |
269 | - | var ptn=[ |
269 | + | |
270 | - | [ /^https?((?::\/\/www\.google\.co\.jp\/url\?q=https?)?:\/\/webcache\.googleusercontent\.com\/search(?:\?q=|%3Fq%3D)cache:.+?:.*https?:\/\/([^+&%]+).*=(?:(?!http).)+)/ , 1] |
270 | + | |
271 | - | ,[ /^https?(:\/\/webcache\.googleusercontent\.com\/search\?q=cache:.+?:([^+&%]+).*=(?:(?!http).)+)/ ,2 ] |
271 | + | |
272 | - | ,[ /^https?(:\/\/cache\.yahoofs\.jp\/search\/cache\?.*&u=([^&]+)(?:&.*=(?:(?!http).)+)?)/ ,2 ] |
272 | + | |
273 | - | ,[ /http:(\/\/(bakusai\.com(?:\.[^\/]+)?\/thr_(?:res|tl)\/acode=\d+\/ctgid=\d+(?:\/test\/read\.cgi)?(?:\/(?:\w+=)?[\d-]+)+\/))/ , 3 ] |
273 | + | |
274 | - | ]; |
274 | + | var env = new ENV(); |
275 | - | |
275 | + | |
276 | - | for(i=0;i<ptn.length;i++) { |
276 | + | var f = fso.CreateTextFile(logfile); |
277 | - | r = url.match(ptn[i][0]); |
277 | + | f.WriteLine("["+MY_NAME+"]"); |
278 | - | if(r) { |
278 | + | f.WriteLine("Jane Type = "+chkJaneProg()+"\t"+fso.GetFileVersion(JANE_PATH+JANE_EXE)); |
279 | - | this.otherURLType=ptn[i][1]; |
279 | + | f.WriteLine("current path = "+JANE_PATH); |
280 | - | switch(this.otherURLType) { |
280 | + | f.WriteLine("Logs path = "+Jane.LogBasePath+JANE_LOGS); |
281 | - | case 1: this.otherURL = r[1]; return "http"+r[2]; |
281 | + | f.WriteLine("script path = "+SCRIPT_PATH); |
282 | - | case 2: this.otherURL = "http"+r[1]; return "http://"+r[2].replace(/%2F/ig,"/"); |
282 | + | f.WriteLine("UAC = "+env.UAC); |
283 | - | case 3: this.otherURL = r[0]; return "http://"+r[2]; |
283 | + | f.WriteLine("64bit? = "+env.PROCESSOR_ARCHITECTURE+"\t"+env.PROCESSOR_ARCHITEW6432); |
284 | f.WriteLine("----------------------------------------------------------------------"); | |
285 | - | } |
285 | + | f.Close(); |
286 | - | } |
286 | + | } catch(e) {flag=false; if(f) f.Close();} |
287 | - | return url.replace(/^https?(:.+?)(?:http.+)?$/,"http$1"); |
287 | + | env = null; |
288 | - | } |
288 | + | |
289 | - | ,isOPT_BBS : function(url) { |
289 | + | |
290 | - | var i,r; |
290 | + | |
291 | - | for(i in OPT_BBS) { if(url.indexOf(i)>0) r=i; } |
291 | + | |
292 | - | this.optItem = r; |
292 | + | |
293 | - | return r; |
293 | + | |
294 | - | } |
294 | + | |
295 | if(!s) { t[n] = new Date();} | |
296 | - | var URL_jbbs = object(URL_2ch,{ |
296 | + | |
297 | - | RE_HOST : new RegExp("^http://jbbs\\.(?:shitaraba|livedoor)\\.(?:net|jp|com)/") |
297 | + | |
298 | } catch(e) {if(f) f.Close();} | |
299 | - | ,set_prm : function(url) { this._set_prm(url,1,2,3,4); } |
299 | + | |
300 | } | |
301 | - | var URL_machi = object(URL_2ch,{ |
301 | + | |
302 | - | RE_HOST : new RegExp("^http://(?:\\w+\\.)?machi\\.to/") |
302 | + | |
303 | - | ,RE_URL : new RegExp("^http://((?:\\w+\\.)?machi\\.to)/bbs/\\w+\\.cgi/2/(\\w+)/(\\d+)/?") |
303 | + | |
304 | - | ,set_prm : function(url) { this._set_prm(url,1,null,2,3); } |
304 | + | |
305 | - | ,getUrl2 : function() { return this.url2.replace(/\/offlaw\.cgi\/2\//,"/read.cgi/"); } |
305 | + | |
306 | , "/" , ("0"+d.getDate()).slice(-2) | |
307 | , "(" , "日月火水木金土".substr(d.getDay(),1) | |
308 | , ") " , ("0"+d.getHours()).slice(-2) | |
309 | , ":" , ("0"+d.getMinutes()).slice(-2) | |
310 | - | ini : loadFile2(JANE_INI) |
310 | + | |
311 | , "." , ("00"+parseInt(d.getMilliseconds(),10)+" ").slice(-4,n-4) | |
312 | ].join(""); | |
313 | } | |
314 | - | ,getINI : function(p) { var m=this._search(this.ini, this._re_ini, p); return m && RegExp.$1 || p[3]; } |
314 | + | |
315 | return (" "+d).slice(-n); | |
316 | - | var m = this._search(this.brd |
316 | + | |
317 | - | , (/\.[25]ch\.net/.test(p[3]))?this._re_brd2:this._re_brd |
317 | + | |
318 | - | , p); |
318 | + | |
319 | - | var b1=RegExp.$1, b2=RegExp.$4; |
319 | + | |
320 | - | var host2=RegExp.$3, host1=RegExp.$2; |
320 | + | |
321 | - | return (m) ? [b1.convDontUseStr()+"\\"+b2.convDontUseStr()+"\\",host1,host2] : null; |
321 | + | |
322 | return this; | |
323 | } | |
324 | - | ,_re_brd : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*\\t(\\w*)($3)\\t$5\\t([^\\t\\r\\n]+?) *\\r\\n" |
324 | + | if (args.trace !== void 0) { trace = new Trace(); } else { trace = function(){}; } |
325 | - | ,_re_brd2 : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*\\t(\\w+)\\.([25]ch\\.net)\\t$5\\t([^\\t\\r\\n]+?) *\\r\\n" |
325 | + | |
326 | - | ,_search : function(f,s,p) { return f.match(new RegExp(this._expand(s,p),"img")); } |
326 | + | //-------------------------------------------------------------------------------- |
327 | ||
328 | - | ,_setLogBasePath : function() { this.LogBasePath = this.getINI([,"PATH","LogBasePath",""]).replace(/[^\\]$/,"$&\\");} |
328 | + | |
329 | - | ,_loadBRD : function() { this.brd = loadFile2(this.LogBasePath + JANE_BRD); } |
329 | + | re_thr : /^[\s\S]*?<dl[^>]*>\s*(?:<font[^>]*>.*<\/font>.*\s*)?((?:<dt>.+?<dd>.+\n?)+)(\s*<\/dl>)?/i |
330 | ,re_msg : /<dt.*?>([0-9]+).+?(?:"mailto:(.+?)">)?<b[^>]*>(.*?)<\/b>(?:<\/font>|<\/a>)?(?: ?投稿日)? ?:(.*?)<dd>(.*?)(?:<br>)*(?=<dt.*?>|$)/img | |
331 | ,msg : "" | |
332 | - | _re_brd : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*?\\t(($1/$2))\\t$3\\t([^\\t\\r\\n]+?) *\\r\\n" |
332 | + | ,isExistAbn : false |
333 | ,init : function() {} | |
334 | - | var Jane_machi = object(Jane_2ch,{ |
334 | + | |
335 | - | _re_brd : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*?\\t(($1))\\t$2\\t([^\\t\\r\\n]+?) *\\r\\n" |
335 | + | |
336 | ,mainReplace : function() { this.msg = this.msg.replace(this.re_msg, "$3<>$2<>$4<>$5<>"); } | |
337 | ,postReplace : function() {} | |
338 | ,createBrdFolder : function() { return null;} | |
339 | ,urlAppendFirstNum : function(u) { return u + ((args.append && DatInfo.cnt) ? DatInfo.cnt + "n-" : ""); } | |
340 | ,getTBlock : function() { this.msg = (this.msg.match(this.re_thr,"$1")||[])[1]; } | |
341 | - | if (args.trace !== void 0) { trace = new Trace(); } |
341 | + | ,getTitle : function(s) { this.title = (s.match(/<title>(.*?)<\/title>/i)||[])[1]; } |
342 | - | trace("--- start --- "+args.url,1);trace("",1) |
342 | + | ,readHTTP : function(url) { this.msg = readHTTP(url); this.getTitle(this.msg); this.getTBlock(); return true; } |
343 | ,getFirst : function() { return parseInt((this.msg.match(/^<dt[^>]*>(\d+)/i)||[])[1],10); } | |
344 | - | //---------------------- |
344 | + | ,getLast : function() { return parseInt((this.msg.match(/<dt[^>]*>(\d+).*<dd>.*\n$/i)||[])[1],10); } |
345 | ,delContents : function(s) { return s.replace(/^(?:(?:(?!<>).)*<>){4}.*$/mg, ""); } | |
346 | ,checkData : function(s) { | |
347 | var ln = this.checkData0(s); | |
348 | - | ,offset : 0 |
348 | + | if (this.last-this.first+1 != ln.length) |
349 | {Err("E_unmatched_res_count"," 先頭=$1 末尾=$2 レス数=$3".expand([,this.first,this.last,ln.length]));} | |
350 | - | ,msg : (args.overwrite) ? [] : "" |
350 | + | |
351 | ,checkData0 : function(s) { | |
352 | var ln = this.delContents(s); | |
353 | if (ln.replace(/\n/g,"").length > 0) Err("E_remained_garbage"); | |
354 | return ln; | |
355 | } | |
356 | - | trace(); |
356 | + | |
357 | - | var msg = loadFile(dat); |
357 | + | |
358 | - | this.cnt = msg.split("\n").length-1; |
358 | + | if ((this.msg.match(/^<dt[^>]*>(\d+)/i)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); } |
359 | - | this.title = (msg.match(/^(?:(?:(?:(?!<>).)*)<>|(?:[^,]*),){4}(.*)$/m)||[])[1]; |
359 | + | |
360 | - | if (args.overwrite) { this.msg = msg.slice(0,-1).split("\n"); } |
360 | + | ,delBeforeFirstData : function() {} |
361 | - | else this.msg=""; |
361 | + | ,insertAbn : function() {} |
362 | - | trace("load file "+dat.replace(/^.*\\(\d+\.dat)/,"$1")+" : "+this.title+" lines="+this.cnt); |
362 | + | |
363 | trace("--- start --- "+args.url,1);trace("",1) | |
364 | this.init(); | |
365 | URL.setInfo(this.urlReplace(args.url)); | |
366 | var brd = Jane.getBRD(URL.prm); | |
367 | if (!brd) brd = this.createBrdFolder(); | |
368 | if (!brd) Err("E_brditem_not_found"); | |
369 | var dat = Jane.LogBasePath + JANE_LOGS + brd + URL.thrID + ".dat"; | |
370 | var bak = Jane.LogBasePath + JANE_BAK + brd + URL.thrID + ".dat"; | |
371 | DatInfo.setInfo(dat, bak, brd); | |
372 | URL.url = this.urlAppendFirstNum(URL.url); | |
373 | if (trace()|this.readHTTP(URL.url)|trace("HTTP total read time")) { | |
374 | if (!this.msg) Err("E_block_not_found"); | |
375 | if (!this.title) Err("E_title_not_found"); | |
376 | - | ,update : function(msgs) { |
376 | + | this.preReplace(); |
377 | - | this.msg = msgs; |
377 | + | |
378 | - | this.cnt = this.msg.length; |
378 | + | |
379 | if(this.msg=="") Err("E_already_there"); | |
380 | } | |
381 | this.first = this.getFirst(); | |
382 | - | //================================================================================ |
382 | + | |
383 | trace(); this.mainReplace(); trace("html->dat main replace time"); | |
384 | this.checkData(this.msg); | |
385 | if (this.first==1) { this.addTitle(); } | |
386 | - | re_sel : -1 |
386 | + | if(this.isExistAbn) { trace(); this.insertAbn(); trace("透明abnレス挿入"); } |
387 | - | ,REG_PATTERN : [ {} ] |
387 | + | this.postReplace(); |
388 | } | |
389 | - | ,bin : null |
389 | + | trace("スレタイトル:"+this.title+"\tレス数:"+this.last+"\tサイズ:"+this.msg.length,9); |
390 | - | ,resNo : [] |
390 | + | saveDat(dat, this.msg); |
391 | - | ,resNo_offset : 0 |
391 | + | |
392 | - | ,requireFillAbn : false |
392 | + | |
393 | - | ,prepare : function() {} |
393 | + | invokeJaneStyle(URL.url2); |
394 | trace("---- end ----",1); | |
395 | } | |
396 | - | ,mainReplace : function() { this.msg = this.msg.replace(this.REG_PATTERN[this.re_sel].msg, this.REG_PATTERN[this.re_sel].rep); } |
396 | + | |
397 | ||
398 | var Thread_2ch = object(Thread,{ | |
399 | - | ,testTBlock : function() { |
399 | + | preReplace : function() { this.msg = this.msg.replace(/(<a href=)"\/cdn-cgi\/l\/(email-protection\#.*?">)/ig,'$1"mailto:$2'); } |
400 | - | var i,rc,ss; |
400 | + | ,postReplace : function() { |
401 | - | for(i=0; i<this.REG_PATTERN.length; i++) { |
401 | + | this.msg = this.msg.replace(/<a href="http.*?>(.*?)<\/a>/ig, "$1") |
402 | - | if(ss=this.msg.match(this.REG_PATTERN[i].thr)) {this.re_sel =i; break;} |
402 | + | .replace(/<a href="javascript:be\((\d+?)\)[^>]*>\?(.*?)<\/a>/ig, "BE:$1-$2") |
403 | - | } |
403 | + | .replace(/<img src="http:\/\/(img\.2ch\.net\/.+?)">/ig, "sssp://$1"); |
404 | - | rc = ss ? true : false; |
404 | + | |
405 | - | return rc; |
405 | + | |
406 | - | } |
406 | + | |
407 | - | ,setTBlock : function() { |
407 | + | |
408 | - | var s; |
408 | + | |
409 | - | if(this.re_sel>=0) { |
409 | + | |
410 | - | s=this.msg.match(this.REG_PATTERN[this.re_sel].thr); |
410 | + | |
411 | - | if(s) { this.msg=s[1]||""; s=s[2]; } |
411 | + | |
412 | return url; | |
413 | - | return s; |
413 | + | |
414 | - | } |
414 | + | |
415 | - | ,getTitle : function(s) { this.title = (s.match(/<title>(.*?)\n*<\/title>/i)||[])[1]; } |
415 | + | |
416 | - | ,readHTTP : function(url) { |
416 | + | /*@if (@EnabledTest2chJSON) |
417 | - | trace("try URL="+url,9); |
417 | + | o("1st try json"); |
418 | - | this.msg = readHTTP(url)[0]; |
418 | + | this.msg = get2chJSON(); |
419 | - | this.testTBlock(); //re_selの設定 |
419 | + | if(this.msg=="") Err("E_already_there"); |
420 | - | this.preReplace(); |
420 | + | if(this.msg) return false; |
421 | - | this.getTitle(this.msg); |
421 | + | o("2nd try html"); |
422 | - | if (this.re_sel<0) Err("E_block_not_found","\n\nTITLE="+this.title+"\n文字数="+this.msg.length); |
422 | + | @end @*/ |
423 | - | this.setTBlock(); |
423 | + | this.kakoUrl = this._getKakoUrl(); |
424 | - | return true; |
424 | + | if(URL.kako) if(!this.readHTTP2(this.kakoUrl)) return false; |
425 | - | } |
425 | + | |
426 | - | ,getFirst : function() { return (args.overwrite) ? parseInt(URL.range,10) : (args.append) ? DatInfo.cnt + 1 : 1; } |
426 | + | this.msg = readHTTP(url); |
427 | - | ,getLast : function() { return parseInt((this.msg.match(/(?:^|\n)(\d+).+\n$/i)||[])[1],10)-this.resNo_offset; } |
427 | + | var ss = this.msg.match(this.re_thr,"$1"); |
428 | - | ,delContents : function(s) { return s.replace(/^(?:(?:(?!<>).)*<>|(?:[^,]*,)){4}.*$/mg, ""); } |
428 | + | |
429 | var u = this.kakoUrl.replace(/\.dat\.gz$/,".html"); | |
430 | if (u!=url) { | |
431 | - | if(FILL_ABONE==2) return; |
431 | + | switch(this.readHTTP3(u)) { |
432 | - | var resTbl=this.msg.match(/^(\d+)/mg)||[]; |
432 | + | case 0: return false; |
433 | - | for(var i=1; i<resTbl.length; i++) { |
433 | + | case 1: url=u; ss=this.msg.match(this.re_thr,"$1"); break; |
434 | - | if(args.overwrite && i==1 |
434 | + | default: break // case -1 |
435 | - | && parseInt(resTbl[1],10)==this.first && parseInt(resTbl[0],10)==1) continue; |
435 | + | |
436 | - | if(parseInt(resTbl[i],10)!=parseInt(resTbl[i-1],10)+1) { |
436 | + | |
437 | - | this.requireFillAbn = true; |
437 | + | |
438 | - | break; |
438 | + | |
439 | if(!ss) { | |
440 | ss = "<URL>="+url+"\n<TITLE>="+this.title+"\n<メッセージ長>="+this.msg.length+"\n\n"; | |
441 | - | if (FILL_ABONE==0 && this.requireFillAbn) { |
441 | + | |
442 | - | switch(shell.Popup("抽出したレス数が合いません。" |
442 | + | |
443 | - | +"(先頭="+this.first+" 末尾="+this.last+" レス数="+ln.length+")" |
443 | + | |
444 | - | +"\n抜けているレス番を穴埋めしますか? [はい] [いいえ]" |
444 | + | || "不明"; |
445 | - | +"\n又は、ここで処理を中断するなら [キャンセル]" |
445 | + | |
446 | - | +"\nを選択してください。", 0, MY_NAME, 3+48)) { |
446 | + | |
447 | - | case 6: this.requireFillAbn = true; break; |
447 | + | if (!ss[2]) { |
448 | - | case 7: this.requireFillAbn = false; break; |
448 | + | if (MsgBox("途中でデータが途切れているようですが続行しますか?",4+48,MY_NAME)!=6) Err("E_stop"); |
449 | - | default: Err("E_stop"); //case 2 |
449 | + | |
450 | var s = ss[1] || ""; | |
451 | if (s.substr(s.length-1)!="\n") s += "\n"; | |
452 | this.msg = s; | |
453 | return true; | |
454 | } | |
455 | ,readHTTP2 : | |
456 | function(url) { | |
457 | var re = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(.*)\s*$/m; | |
458 | trace("try URL="+url,9); | |
459 | var s = readHTTP(url); //9999999999.dat.gz | |
460 | - | if ((this.msg.match(/^(\d+)/i)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); } |
460 | + | var r = s.match(re); |
461 | if(!r) {url=url.replace(/\.gz$/,""); trace("try URL="+url,9); s=readHTTP(url); r=s.match(re); } | |
462 | - | ,fillAbn : function() { |
462 | + | |
463 | - | // 透明あぼーんレスを挿入する |
463 | + | this.msg = s; |
464 | - | var d = [], n = this.first, m; |
464 | + | this.last = this.checkData0(s).replace(/^.*$/m,"").length; |
465 | - | var s = this.msg.split("\n"); |
465 | + | |
466 | - | for (var i=0; i<s.length; i++) { |
466 | + | |
467 | - | m = parseInt(s[i].replace(/^(\d+).+$/, "$1"),10); |
467 | + | |
468 | - | if(n>m) continue; //レス番重複または逆転時はスキップ |
468 | + | |
469 | - | for (var j=n; j<m; j++) { |
469 | + | |
470 | - | d.push(j+"<>"+(/\.bbspink\.com$/.test(URL.site)?ABN_MSG_PINK:ABN_MSG)); |
470 | + | |
471 | - | n++; |
471 | + | |
472 | ,readHTTP3 : | |
473 | - | d.push(s[i]); n++; |
473 | + | |
474 | var title=((this.msg.match(/<title>(.*)<\/title>/im)||[])[1]||""); | |
475 | - | this.msg = d.join("\n"); |
475 | + | |
476 | if (/error/i.test(title)) { | |
477 | - | ,delResNo : function() { this.msg = this.msg.replace(/^\d+<>/mg, ""); } |
477 | + | if(!this.readHTTP2(this.kakoUrl)) return 0; //最初に/kako/.../9999999999.dat.gzを試す |
478 | - | ,overwriteMsg : function() { |
478 | + | |
479 | - | var data = this.msg.split("\n"); |
479 | + | var s = readHTTP(url); //9999999999.html |
480 | - | var msg = DatInfo.msg; |
480 | + | |
481 | - | var i; |
481 | + | |
482 | - | for (i=0; i<data.length; i++) msg[parseInt(data[i],10)-1] = data[i].replace(/^\d+<>/,""); |
482 | + | |
483 | - | for (i=0; i<msg.length; i++) if(!msg[i]) msg[i] = NOT_GET_MSG; |
483 | + | |
484 | - | this.msg = msg.join("\n"); |
484 | + | |
485 | - | if(this.msg.slice(-1)!="\n") this.msg += "\n"; |
485 | + | |
486 | - | } |
486 | + | |
487 | - | ,rebuildSubject : function() { Err("E_no_support"); } |
487 | + | |
488 | } | |
489 | - | this.prepare(); |
489 | + | |
490 | - | URL.set_prm(this.urlReplace(args.url)); |
490 | + | |
491 | - | var brd, m = Jane.getBRD(URL.prm); |
491 | + | |
492 | - | if(/^(\w+)\.[25]ch\.net/.test(URL.site)) { |
492 | + | init : function() { Jane=Jane_jbbs; URL=URL_jbbs; } |
493 | - | // URLをbrdの登録されているHOST名に置換する(2ch/5ch対策) |
493 | + | ,re_thr : {} |
494 | - | if(RegExp.$1=="itest") { URL.set_prm(URL.url.replace(/\w+\.[25]ch\.net/,m[1]+"."+m[2])); } |
494 | + | ,re_msg : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img |
495 | - | else { URL.set_prm(URL.url.replace(/[25]ch\.net/,m[2])); } |
495 | + | |
496 | //したらばの事前URL変換:旧site名、/storage/ URLを現在のURLに置換 | |
497 | - | if (m) brd = m[0]; |
497 | + | return u.replace(URL.RE_SITE,"http://jbbs.shitaraba.net/") |
498 | .replace( /\/\w+\.cgi\//, "/read.cgi/") | |
499 | .replace(/^(http:\/\/[^\/]+\/)([^\/]+\/)([^\/]+\/)storage\/(\d+).*$/,"$1bbs/read.cgi/$2$3$4/"); | |
500 | } | |
501 | // ,preReplace : function() { | |
502 | // s = s.replace(/^\s*$/mg,""); | |
503 | - | if (args.subject) { this.rebuildSubject(); return; } |
503 | + | // s = s.replace(/\n\n/g,"\n"); |
504 | - | if (args.browser) { invokeBrowser(URL.url); return; } |
504 | + | // s = s.replace(/\s*<div[^>]+>(?:(?!<\/div>)[\s\S])*<\/div>\s*/ig,"\n"); //100レス毎に入る公告を除去 |
505 | - | URL.appendRange(DatInfo.cnt); |
505 | + | // } |
506 | ,delDupData : function() { //わざと重複して要求した先頭レス番データ削除 | |
507 | - | if(!this.msg) Err("E_block_not_found","\n\nTITLE="+this.title); |
507 | + | if ((this.msg.match(/^(\d+)/)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); } |
508 | - | if (!this.noChkTitle && !this.title) Err("E_title_not_found"); |
508 | + | |
509 | - | trace(); this.mainReplace(); trace("html->dat main Replace"); |
509 | + | |
510 | function() { | |
511 | this.msg = this.msg.replace(/^(\d+<>.*?<>.*?<>.*?)(<>.*<>)((?:(?!<>).)*)$/mg, function($0,$1,$2,$3) {return ($3)?$1+" ID:"+$3+$2:$0;}); | |
512 | } | |
513 | ,createBrdFolder : | |
514 | function() { | |
515 | var s = readHTTP( URL.url.replace( /\/\w+\.cgi(\/\w+\/\w+\/).*$/, "/api/setting.cgi$1") ); | |
516 | var bbs_title = (s.match(/^BBS_TITLE=(.*)$/m)||[])[1]; | |
517 | var category = (s.match(/^CATEGORY=(.*)$/m)||[])[1]; | |
518 | - | if(this.requireFillAbn) { trace(); this.fillAbn(); trace("透明abnレス挿入"); } |
518 | + | |
519 | - | trace(); this.postReplace(); trace("post Replace"); |
519 | + | |
520 | - | if(args.overwrite) this.overwriteMsg(); |
520 | + | |
521 | - | else this.delResNo(); |
521 | + | |
522 | } | |
523 | - | trace("スレタイトル:"+this.title+"\tレス数:"+this.last,9); |
523 | + | ,getFirst : function() { return (args.append) ? DatInfo.cnt + 1 : 1; } |
524 | - | saveDat(dat, this.msg, this.bin); |
524 | + | ,getLast : function() { return parseInt((this.msg.match(/(\d+).*\n$/)||[])[1],10); } |
525 | ,checkData : | |
526 | function(s) { | |
527 | - | invokeJaneStyle(URL.getUrl2()); |
527 | + | |
528 | this.isExistAbn = true; | |
529 | // 末尾のIDを削除 | |
530 | this.msg = s.replace(/^(.*?)<>((?!<>).)*$/mg, "$1"); | |
531 | } else { | |
532 | // 先頭のレス番と末尾のIDを削除 | |
533 | - | read_cgi_ver : "" |
533 | + | this.msg = s.replace(/^\d+<>(.*?)<>((?!<>).)*$/mg, "$1"); |
534 | - | ,REG_PATTERN : [ |
534 | + | |
535 | - | // ver 07.0.0 / ver.07.0.1 |
535 | + | |
536 | - | { "thr" : /<div class="thread">(<div class="post"[^>]*><div class="meta">[\s\S]+<\/span><\/div><\/div>)((?:<br>)?<\/div>|[\s\S]*?$)/i |
536 | + | |
537 | - | ,"msg" : /[\s\S]*?<div class="post"[^>]*>(?:<[^>]*?>)*<span class="number">(\d+).+?<span class="name"><b>(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/span><span class="date">(.*?)<\/span>(<span class="be[^>]*><a[^>]*>[^<]*<\/a><\/span>)?<\/div><div class="message"><span class="escaped">(.*?)<\/span><\/div><\/div>/ig |
537 | + | |
538 | - | ,"rep" : "$1<>$3<>$2<>$4$5<>$6<>\n" |
538 | + | |
539 | - | ,"preReplace" : [ [/(?:<div class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<div class="post"|(?:<br>)?<\/div><div class="push">|$)/ig,""] |
539 | + | |
540 | - | ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ] |
540 | + | |
541 | - | ,"postReplace" : [ [/<span class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a><\/span>/ig," BE:$1-$2"] |
541 | + | ,insertAbn : |
542 | - | ,[/^(\d+<>.*?<>.*?<>.*? BE:\d+-[^ <]+) BE:\d+-[^ <]+/mg,"$1"] |
542 | + | |
543 | - | ,[/<\/span><span class="uid"[^>]*>/ig, " "] |
543 | + | // 透明あぼーんレスを挿入する |
544 | - | ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"] |
544 | + | var d = []; |
545 | - | ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ] |
545 | + | n = this.first; |
546 | - | } |
546 | + | var s = this.msg.split("\n"); |
547 | for (var i=0; i<s.length; i++) { | |
548 | - | // ver 06.0.0 |
548 | + | for (var j=n; j<parseInt(s[i].replace(/^(\d+).+$/, "$1"),10); j++) { d.push(JBBS_ABN_STR); n++; } |
549 | - | ,{ "thr" : /<div class="thread"[^>]*>((?:<div class="post".+?<\/div><\/div>)+)(<\/div>)?/i |
549 | + | d.push(s[i].replace(/^\d+<>(.+)$/, "$1")); n++; |
550 | - | ,"msg" : /.*?<div class="number">(\d+).+?<\/div><div class="name"><b>(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/div><div class="date">(.*?)<\/div><div class="message">(.*?)<\/div><\/div>(?=<div class="post"|$)/ig |
550 | + | |
551 | - | ,"rep" : "$1<>$3<>$2<>$4<>$5<>\n" |
551 | + | this.msg = d.join("\n"); |
552 | - | ,"preReplace" : [ [/(?:<div class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<div class="post"|<\/div><div class="cLength"|$)/ig,""] |
552 | + | |
553 | - | ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ] |
553 | + | |
554 | - | ,"postReplace" : [ [/<\/div><div class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a>/ig," BE:$1-$2"] |
554 | + | |
555 | - | ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"] |
555 | + | |
556 | - | ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ] |
556 | + | |
557 | - | } |
557 | + | |
558 | var s = readHTTP( raw_url, true); | |
559 | - | // ver 06.0.0 ppspink |
559 | + | |
560 | - | ,{ "thr" : /(<section class="thread"[\s\S]+<\/dd><\/dl>)(<\/section>)/i |
560 | + | |
561 | - | ,"msg" : /[\s\S]*?<dl class="post"[^>]*>(?:<[^>]*?>)*<span class="number">(\d+).+?<span class="name"><b>.*?(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/span><span class="date">(.*?)<\/span>(<div class="be[^>]*><a[^>]*>[^<]*<\/a><\/div>)?<\/dt><dd class="thread_in">(.*?)(?:<\/dd><\/dl>|$)/ig |
561 | + | |
562 | - | ,"rep" : "$1<>$3<>$2<>$4$5<>$6<>\n" |
562 | + | |
563 | - | ,"preReplace" : [ [/(?:<dl class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<section|<dl class="post"|$)/ig,""] |
563 | + | |
564 | - | ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ] |
564 | + | |
565 | - | ,"postReplace" : [ [/<div class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a><\/div>/ig," BE:$1-$2"] |
565 | + | this.getLast = this.getLast2; |
566 | - | ,[/^(\d+<>)<font color="green">(.*?)<\/font>(?=<>)/img, "$1$2"] |
566 | + | |
567 | - | ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"] |
567 | + | this.mainReplace = this.mainReplace2; |
568 | - | ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ] |
568 | + | |
569 | - | } |
569 | + | this.readHTTP2(URL.prm[0]); |
570 | delete this.addTitle; | |
571 | - | // ver 05.02.02 |
571 | + | |
572 | - | ,{ "thr" : /^[\s\S]*?<dl[^>]*>\s*(?:<font[^>]*>.*<\/font>.*\s*)?((?:\s*<dt[^>]*>.+?<dd>.+\r?\n?)+)(\s*<)?/i |
572 | + | |
573 | - | ,"msg" : /[ \t]*<dt.*?>([0-9]+).+?(?:"mailto:(.+?)">)?<b[^>]*>(.*?)<\/b>(?:<\/font>|<\/a>)?(?: ?投稿日)? ?:(.*?)<dd>(.*?)(?:<br>)*(?=<dt.*?>|$)/img |
573 | + | |
574 | - | ,"rep" : "$1<>$3<>$2<>$4<>$5<>" |
574 | + | |
575 | - | ,"preReplace" : [ [/(?:<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<dt|<\/dl>|$)/ig,""] |
575 | + | |
576 | - | ,[/<a href="(?:https?:)?\/\/.*?>([^<]*)<\/a>/ig, "$1"] |
576 | + | |
577 | - | ,[/(<a href=)"\/cdn-cgi\/l\/(email-protection\#.*?">)/ig,'$1"mailto:$2'] ] |
577 | + | |
578 | - | ,"postReplace" : [ [/<a href="javascript:be\(([^\)]+?)\)[^>]*>\?(.*?)<\/a>/ig, "BE:$1-$2"] |
578 | + | |
579 | - | ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"] |
579 | + | |
580 | - | ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ] |
580 | + | |
581 | - | ,"ln_terminate" : true |
581 | + | |
582 | - | } |
582 | + | |
583 | - | ] |
583 | + | |
584 | - | ,urlReplace : |
584 | + | //-- 2nd try : read html text -- |
585 | trace("try URL="+url,9); | |
586 | - | url = url.replace(/^http:\/\/(?:mattari\.plusvip\.jp|jane\.s28\.xrea\.com)\/test\/\w+\.cgi\/(?:jane2ch|bbs)\//, "http://jane2ch.net/test/read.cgi/community/") |
586 | + | this.msg = readHTTP(url); //途中からデータを取ることができない |
587 | - | .replace(/^(http:\/\/next2ch\.net\/)(\w+\/)(?:kako\/\d{3,4}\/(?:\d{5}\/)?)?(\d+)(?:\/|\.html)?$/,"$1test/read.cgi/$2$3/") |
587 | + | |
588 | - | .replace(/\/read\.cgi\?(?=.*?bbs=(\w+))(?=.*?key=(\d+))(?=.*?st=(\d+))?(?=.*?to=(\d+))?.*$/i, "/read.cgi/$1/$2/$3-$4").replace(/\/-$/,"/") |
588 | + | var re_thr1 = /^[\s\S]*?<dl\s+(?:class|id)="thread[^>]*?>\s*(<dt>(?:(?!<\/dl>)[\s\S])*?\s*)<\/dl>[\s\S]*$/i |
589 | - | .replace(/^(.*?)itest(\.[25]ch\.net)\/(\w+)(?=\/test\/read\.cgi\/)/,"$1$3$2"); |
589 | + | var re_thr2 = /^[\s\S]*?<dl[^>]*?>(?:(?!<dt>)[\s\S])*(<dt>(?:(?!<\/dl>)[\s\S])*)<\/dl>[\s\S]*$/i |
590 | - | if(!args.keep_kako) |
590 | + | if (re_thr1.test(this.msg) != 0) { this.re_thr = re_thr1 } |
591 | - | url=url.replace(/^(.*?\/)(\w+\/)kako\/\d{3,4}\/(?:\d{5}\/)?(\d+)\.html$/,"$1test/read.cgi/$2$3/"); |
591 | + | else if (re_thr2.test(this.msg) != 0) { this.re_thr = re_thr2; } |
592 | this.getTBlock(); | |
593 | } | |
594 | - | ,preReplace : |
594 | + | ,getLast2 : function() { return parseInt((this.msg.match(/<dt><a[^>]*?>(\d+).*<dd>.*\n$/i)||[])[1],10); } |
595 | - | function() { |
595 | + | ,getTitle2 : function(s) { |
596 | - | var i,list; |
596 | + | this.title = (s.match(/<h1 class="thread-title">(.*?)<\/h1>/i)||[])[1] |
597 | - | if(this.re_sel==-1) this.testTBlock(); //re_selの設定 |
597 | + | || (s.match(/<title>(.*?)<\/title>/i)||[])[1] || ""; |
598 | - | if(this.re_sel>=0) { |
598 | + | |
599 | - | trace(""); |
599 | + | ,delDupData2 : |
600 | - | list = this.REG_PATTERN[this.re_sel].preReplace; |
600 | + | |
601 | - | for(i=0;i<list.length; i++) { |
601 | + | //append時、既存のレス数分データを読み飛ばす |
602 | - | this.msg = this.msg.replace(list[i][0],list[i][1]); |
602 | + | while( (this.msg.match(/^<dt><a[^>]*?>(\d+)/i)||[])[1] < DatInfo.cnt+1) { this.msg = this.msg.replace(/^.*\n/m,""); } |
603 | } | |
604 | - | trace("pre Replace"); |
604 | + | ,mainReplace2 : function() { this.msg = this.msg.replace(this.re_msg, "$1<>$3<>$2<>$4<>$5<>"); } |
605 | ,checkData2 : | |
606 | function(s) { | |
607 | - | ,postReplace : |
607 | + | var ln = this.checkData0(s); |
608 | - | function() { |
608 | + | if (this.last-this.first+1 != ln.length) { |
609 | - | var i,list; |
609 | + | this.isExistAbn = true; |
610 | - | list = this.REG_PATTERN[this.re_sel].postReplace; |
610 | + | } else { |
611 | - | for(i=0;i<list.length; i++) { |
611 | + | // 先頭のレス番を削除 |
612 | - | this.msg = this.msg.replace(list[i][0],list[i][1]); |
612 | + | this.msg = s.replace(/^\d+<>/mg, ""); |
613 | } | |
614 | } | |
615 | }); | |
616 | ||
617 | //------------------------------------------------------------------------------- | |
618 | function loadFile(f) { | |
619 | var s; | |
620 | try { | |
621 | strm.Type = 2; | |
622 | strm.Charset = 'shift_jis'; | |
623 | strm.Open(); | |
624 | strm.loadFromFile(f); | |
625 | s = strm.ReadText(-1); | |
626 | - | var s,ss,u,msgLength; |
626 | + | |
627 | - | if(!URL.otherURLType) { |
627 | + | |
628 | - | if(!URL.kako && !URL.RE_HOST.test(url)) { |
628 | + | |
629 | - | if(!this.readHTTP0(url)) return false; //dat取得 |
629 | + | |
630 | function loadFile2(f) { | |
631 | - | /*@if (@EnabledTest2chJSON) |
631 | + | var s; |
632 | - | o("1st try json"); |
632 | + | |
633 | - | this.msg = get2chJSON(); |
633 | + | |
634 | - | if(this.msg=="") Err("E_already_there"); |
634 | + | |
635 | - | if(this.msg) return false; |
635 | + | |
636 | - | o("2nd try html"); |
636 | + | } catch(e) { if(file) file.close(); Err("E_loadfile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f); } |
637 | - | @end @*/ |
637 | + | |
638 | - | this.kakoUrl = this._getKakoUrl(); |
638 | + | |
639 | - | // keep_kakoオプションによるkako形式のURIが受け渡される場合には最初に .dat.gz/.dat のアクセスを試行する |
639 | + | |
640 | - | if(URL.kako) if(!this.readHTTP2(this.kakoUrl)) return false; |
640 | + | function saveFile(f,s) { |
641 | strm.Type = 2; | |
642 | strm.Charset = 'shift_jis'; | |
643 | - | this.msg = readHTTP(url)[0]; |
643 | + | |
644 | - | this.read_cgi_ver = (this.msg.match(/>read\.cgi ver ([\d.]+)/)||[])[1]; |
644 | + | if (args.append) { try {strm.loadFromFile(f); strm.Position = strm.Size;} catch(e){} } |
645 | - | this.preReplace(); |
645 | + | |
646 | try { strm.Savetofile(f, 2); } | |
647 | - | msgLength = this.msg.length; |
647 | + | |
648 | - | ss = this.setTBlock(); |
648 | + | |
649 | - | if (ss==null && !URL.otherURLType) { |
649 | + | |
650 | - | u = this.kakoUrl.replace(/\.dat\.gz$/,".html"); |
650 | + | function saveFile2(f,s) { |
651 | - | switch(this.readHTTP3(u)) { |
651 | + | |
652 | - | case 0: return false; |
652 | + | var file = fso.OpenTextFile( f, (args.append)?8:2 , true, 0); |
653 | - | case 1: url=u; ss=this.setTBlock(); break; |
653 | + | |
654 | - | default: break // case -1 |
654 | + | |
655 | } catch(e) { if(file) file.Close(); Err("E_savefile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f); } | |
656 | } | |
657 | - | if(ss==null) { |
657 | + | |
658 | - | ss = "<URL>="+url+"\n<TITLE>="+this.title+"\n<文字数>="+msgLength+"\n\n"; |
658 | + | function readHTTP(u, withHeaders) { |
659 | var s="", r=""; | |
660 | http.open("GET", u, true); | |
661 | for(var i in HTTP_HEADERS) { http.setRequestHeader(i, HTTP_HEADERS[i]); } | |
662 | - | || this.msg.substr(0,(msgLength>100)?100:msgLength-1).replace(/<br.*?>/g,"\n"); |
662 | + | |
663 | for (var t0=new Date(); http.readyState<4; ) { | |
664 | if (new Date() - t0 > HTTP_TIMEOUT) { http.abort(); Err("E_http_timeout"); } | |
665 | WScript.Sleep(50); | |
666 | - | if (shell.Popup("途中でデータが途切れているようですが続行しますか?",0,MY_NAME,4+48)!=6) Err("E_stop"); |
666 | + | |
667 | if (http.status != 200 && !http.status==0) Err("E_http_recieve", " status="+http.status); | |
668 | - | if(this.REG_PATTERN[this.re_sel].ln_terminate && this.msg && this.msg.slice(-1)!='\n') this.msg += '\n'; |
668 | + | |
669 | if (withHeaders) r = http.getAllResponseHeaders(); | |
670 | s = http.responseText; | |
671 | if (!/charset=/i.test(header)) { | |
672 | if(http.responseBody !== void 0) { | |
673 | - | var re1 = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*).*\s*$/m; |
673 | + | trace("HTTP文字コード変換開始",9); |
674 | - | var re2 = /^(?:[^,]*),(?:[^,]*),(?:[^,]*),(?:[^,]*),(.*)$/m; |
674 | + | |
675 | strm.Type = 1; | |
676 | - | var s="",r=""; |
676 | + | strm.Open(); |
677 | - | try { s=readHTTP(url); r=s[0].match(re1); if(!r) r=s[0].match(re2); }catch(e){} //9999999999.dat.gz |
677 | + | strm.Write(http.responseBody); |
678 | - | if(!r) { |
678 | + | strm.Position = 0; |
679 | - | url=url.replace(/\.gz$/,""); |
679 | + | strm.Type = 2; |
680 | strm.Charset = cs; | |
681 | - | try{ s=readHTTP(url); r=s[0].match(re1); if(!r) r=s[0].match(re2); }catch(e){} //9999999999.dat |
681 | + | s = strm.ReadText(-1); |
682 | strm.Close(); | |
683 | } | |
684 | - | this.msg = s[0]; |
684 | + | |
685 | - | this.bin = s[2]; |
685 | + | |
686 | - | this.last = this.checkData0(s[0]).replace(/^.*$/m,"").length; |
686 | + | |
687 | return withHeaders ? [s,r] : s; | |
688 | } | |
689 | ||
690 | function saveDat(dat,s) { | |
691 | if (args.append) { | |
692 | if(s=="") Err("E_already_there"); | |
693 | } else { | |
694 | if(s.match(/\n/g)==null) Err("E_no_data"); | |
695 | if(DatInfo.cnt>=s.match(/\n/g).length) { | |
696 | if (MsgBox("既存のスレデータの方が同じか又は大きいですが、置換を続行しますか?",4+32+256,MY_NAME) != 6){ | |
697 | Err("E_stop"); | |
698 | - | if (/error|隊長|過去ログ倉庫/i.test(title)) { |
698 | + | |
699 | - | if(!URL.kako && !this.readHTTP2(this.kakoUrl)) return 0; //最初に/kako/.../9999999999.dat.gzを試す |
699 | + | |
700 | } | |
701 | - | var s = ""; try{ s=readHTTP(url)[0]; }catch(e){} //9999999999.html |
701 | + | |
702 | trace(); saveFile2(path(dat), s); trace("save file:"+dat); | |
703 | - | this.title = (s.match(/<title>(.*)<\/title>/im)||[])[1]||""; |
703 | + | |
704 | ||
705 | - | this.preReplace(); |
705 | + | |
706 | shell.Exec(JANE_EXE + " " + url); | |
707 | if(args.sendkey && args.sendkey > 0) { | |
708 | WScript.Sleep(args.sendkey); | |
709 | shell.SendKeys('^(w)'); | |
710 | WScript.Sleep(200); | |
711 | shell.Exec(JANE_EXE + " " + url); | |
712 | } | |
713 | if(args.redraw) { | |
714 | - | ,readHTTP0 : |
714 | + | |
715 | shell.SendKeys('%'); | |
716 | - | var re = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*).*\s*$/m; |
716 | + | |
717 | - | var s; |
717 | + | |
718 | - | url = "http://"+URL.site+"/"+URL.brdID+"/dat/"+URL.thrID+".dat"; |
718 | + | |
719 | shell.SendKeys('G'); | |
720 | - | try { s=readHTTP(url); } catch(e) {} |
720 | + | |
721 | - | if(s) { |
721 | + | |
722 | - | this.msg = s[0]; |
722 | + | |
723 | - | this.title = (s[0].match(re)||[])[1]; |
723 | + | |
724 | - | if(this.title===void 0||/[25]ちゃんねる専用ブラウザをご利用の皆さまへ/.test(this.title)) return true; |
724 | + | |
725 | - | this.bin = s[2]; |
725 | + | |
726 | - | this.last = this.checkData0(s[0]).replace(/^.*$/m,"").length; |
726 | + | |
727 | WScript.Sleep(200); | |
728 | shell.SendKeys("%({F4})"); | |
729 | do { | |
730 | var cnt=20; | |
731 | while(cnt && WMI.isAliveProcess(JANE_EXE, JANE_PATH+JANE_EXE)) { WScript.Sleep(100); cnt--;} | |
732 | if(!cnt) { WScript.Echo(JANE_EXE+"を終了させてください"); } | |
733 | } while(!cnt); | |
734 | } | |
735 | - | prepare : function() { Jane=Jane_jbbs; URL=URL_jbbs; } |
735 | + | |
736 | - | ,REG_PATTERN : [ |
736 | + | function saveIdx(boardUrl) { |
737 | - | { "thr" : /^[\s\S]*?<dl\s+(?:class|id)="thread[^>]*?>\s*(<dt>(?:(?!<\/dl>)[\s\S])*?\s*)<\/dl>[\s\S]*$/i |
737 | + | var i,s,r; |
738 | - | ,"msg" : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(.*?)(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img |
738 | + | |
739 | - | ,"rep" : "$1<>$3$4<>$2<>$5<>$6<>" |
739 | + | |
740 | - | } |
740 | + | |
741 | - | ,{ "thr" : /^[\s\S]*?<dl[^>]*?>(?:(?!<dt>)[\s\S])*(<dt>(?:(?!<\/dl>)[\s\S])*)<\/dl>[\s\S]*$/i |
741 | + | |
742 | - | ,"msg" : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(.*?)(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img |
742 | + | |
743 | - | ,"rep" : "$1<>$3$4<>$2<>$5<>$6<>" |
743 | + | |
744 | - | } |
744 | + | |
745 | - | ] |
745 | + | var state = (DatInfo.lines>=maxRes) ? 0 : IDX_STATE[ (URL===URL_2ch) ? "2ch" : "jbbs" ]; |
746 | if (URL.kako) state = 10; | |
747 | ||
748 | - | return u.replace(URL.RE_HOST,"http://jbbs.shitaraba.net/") |
748 | + | |
749 | - | .replace(/\/bbs\/lite\//,"/bbs/") |
749 | + | var idx = [ datName,DatInfo.title,'',DatInfo.lines,'0','',boardUrl,state,DatInfo.lines,'','','0',last_got,'0','0' ]; |
750 | - | .replace(/\/\w+\.cgi\//, "/read.cgi/") |
750 | + | |
751 | - | .replace(/^(http:\/\/[^\/]+\/)([^\/]+\/)([^\/]+\/)storage\/(\d+).*$/,"$1bbs/read.cgi/$2$3$4/") |
751 | + | |
752 | - | .replace(/\/([^\/]+)\/bbs\/read\.cgi\?(?=.*?bbs=(\d+))(?=.*?key=(\d+))(?=.*?start=(\d+))?(?=.*?end=(\d+))?.*$/i, "/bbs/read.cgi/$1/$2/$3/$4-$5").replace(/\/-$/,"/"); |
752 | + | |
753 | + 'INSERT OR IGNORE INTO "tableversion" VALUES(' + "'board_db','00000001');" | |
754 | - | ,preReplace : function() { |
754 | + | |
755 | - | if(URL.otherURLType==1) { // archive.org |
755 | + | |
756 | - | this.msg = this.msg.replace(/<a href="\/web\/\d+\//g,'<a href="'); |
756 | + | |
757 | + " uri TEXT, state TEXT,new_lines TEXT, write_name TEXT, write_mail TEXT," | |
758 | - | if(URL.otherURLType && /<dl.*?>\s+<dt>\s+<a/.test(this.msg)) { |
758 | + | |
759 | - | //1と100レス毎に入る公告を除去 |
759 | + | |
760 | - | this.msg = this.msg.replace(/^\s*(.*?)\s*\n/mg,"$1") |
760 | + | |
761 | - | .replace(/<!--.*?-->/g,"") |
761 | + | var SQL_CMD_3 = "update idxlist set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,DatInfo.lines]); |
762 | - | .replace(/<br>(?:<\/dd>)?<div[^>]*>.*?<\/div>(?=<dt>|<\/dl>)/ig,"") |
762 | + | |
763 | - | .replace(/<table.*?>(?:(?!<dt>).)*?<\/table>(?=<dt>|<\/dl>)/ig,"") |
763 | + | |
764 | - | .replace(/<br>\s*<br>(?:<\/dd>)?(?=<dt>|<\/dl>)/ig,"<br><br>\n") |
764 | + | |
765 | - | ; |
765 | + | |
766 | var sql = new Sql(); | |
767 | - | } |
767 | + | |
768 | sql.isSqlite_ODBC || sql.isSqlite_exe || Err("E_require_sqlite"); | |
769 | } | |
770 | if(args.restart) terminateJaneExe(); | |
771 | ||
772 | if (use_db && args.restart) { | |
773 | switch(chkJaneProg()) { | |
774 | - | var s = readHTTP( URL.url.replace( /\/\w+\.cgi(\/\w+\/\w+\/).*$/, "/api/setting.cgi$1") )[0]; |
774 | + | |
775 | case 'Style?': | |
776 | shell.CurrentDirectory = dir; | |
777 | r=sql.exec("BoardDB.db",SQL_CMD_1+SQL_CMD_2+SQL_CMD_3+SQL_CMD_4); | |
778 | break; | |
779 | case 'Xeno': | |
780 | case 'Xeno?': | |
781 | var qmerge3 = Jane.LogBasePath+JANE_LOGS+"qmerge3.db"; | |
782 | if(!fso.FileExists(qmerge3)) break; | |
783 | idx.splice(14,1,last_got); | |
784 | idxText = []; | |
785 | - | this.requireFillAbn = true; |
785 | + | |
786 | var brd=DatInfo.brd.slice(0,-1); | |
787 | - | // 末尾のIDを削除 |
787 | + | |
788 | - | this.msg = s.replace(/^(.*?)<>((?!<>).)*$/mg, "$1"); |
788 | + | |
789 | var SQL_CMD_XENO3 = "select board_id from thread where board_id=$1 and datname='"+datName+"';"; | |
790 | var SQL_CMD_XENO4 = "insert into thread values($1,"+idxText.join(",")+");"; | |
791 | var SQL_CMD_XENO5 = "update thread set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,DatInfo.lines]); | |
792 | var SQL_CMD_XENO6 = "update thread set lines=" + idxText[3] + ",uri=" + idxText[6] + ",title=" + idxText[1] | |
793 | + ",state=" + idxText[7] + ",last_got=" + idxText[12] + " where datname=" + idxText[0] + ";"; | |
794 | var board_id = sql.select(qmerge3,SQL_CMD_XENO1); | |
795 | board_id = (board_id[0].match(/^(\d+)/)||[])[1]; | |
796 | if (!board_id) { sql.exec(qmerge3, SQL_CMD_XENO2); board_id=((sql.select(qmerge3,SQL_CMD_XENO1))[0].match(/^(\d+)/)||[])[1]; } | |
797 | - | // web.archive/google cacheからの取得 |
797 | + | |
798 | - | if(URL.otherURLType) { |
798 | + | |
799 | - | this.getTitle = this.getTitle2; |
799 | + | |
800 | - | this.delDupData = this.delDupData2 |
800 | + | |
801 | - | this.checkData = this.checkData2; |
801 | + | |
802 | - | Thread.readHTTP.call(this, url); |
802 | + | |
803 | - | delete this.mainReplace; |
803 | + | |
804 | - | delete this.addTitle; |
804 | + | |
805 | - | return true; |
805 | + | |
806 | } | |
807 | ||
808 | // idxファイルの更新 | |
809 | shell.CurrentDirectory = dir; | |
810 | - | var s = readHTTP(raw_url); |
810 | + | |
811 | if(fso.FileExists(datName+".idx")) { | |
812 | s = loadFile(datName+".idx").replace(/\r/g,"").split("\n"); | |
813 | if(s.length>=12) { | |
814 | isExistIdx = true; | |
815 | s[7] = "" + (parseInt(s[7],10) + DatInfo.lines - parseInt(s[2],10)); | |
816 | s[2] = "" + idx[3]; | |
817 | s[5] = idx[6]; | |
818 | s[6] = "" + idx[7]; | |
819 | - | Thread.readHTTP.call(this, URL.prm[0]); |
819 | + | |
820 | - | delete this.mainReplace; |
820 | + | |
821 | } | |
822 | } | |
823 | if(!isExistIdx) { | |
824 | s = idx; | |
825 | s.splice(0,1); | |
826 | s.push(""); | |
827 | } | |
828 | s = s.join("\r\n"); | |
829 | try { saveFile(datName+".idx", s); } catch(e) {} | |
830 | ||
831 | // subject.txtの更新 | |
832 | if(fso.FileExists("subject.txt")) { | |
833 | - | ,getTitle2 : |
833 | + | var re = new RegExp("^"+datName+"\\..*\\((\\d+)\\)(\\s*)$", "m"); |
834 | - | function(s) { this.title = (s.match(/<h1 class="thread-title">(.*?)<\/h1>/i)||[])[1] |
834 | + | s = loadFile("subject.txt"); |
835 | - | || (s.match(/<title>(.*?)<\/title>/i)||[])[1] || ""; |
835 | + | |
836 | if(r) { | |
837 | - | ,delDupData2 : //append時、既存のレス数分データを読み飛ばす |
837 | + | s = s.replace(re, r[0].replace(/\((\d+)\)(\s*)$/,"("+DatInfo.lines+")$2")); |
838 | - | function() { while( (this.msg.match(/^(\d+)/i)||[])[1] < DatInfo.cnt+1) |
838 | + | |
839 | - | { this.msg = this.msg.replace(/^.*\n/m,""); } |
839 | + | |
840 | - | } |
840 | + | |
841 | shell.CurrentDirectory = basedir; | |
842 | - | function(s) { var ln = this.checkData0(s); |
842 | + | |
843 | - | if (this.last-this.first+1 != ln.length) { this.requireFillAbn = true; } |
843 | + | |
844 | function Sql(){ | |
845 | var DRIVER = "DRIVER=SQLite3 ODBC Driver;"; | |
846 | var db = new ActiveXObject("ADODB.Connection"); | |
847 | - | var Thread_machi = object(Thread,{ |
847 | + | |
848 | - | prepare : function() { Jane=Jane_machi; URL=URL_machi; } |
848 | + | |
849 | - | ,noChkTitle : true |
849 | + | |
850 | - | ,REG_PATTERN : [ |
850 | + | |
851 | - | { "thr" : /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*)<>((?:(?!<>).)*).*\s*$/m |
851 | + | |
852 | - | ,"msg" : /^((?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*)(<>(?:(?!<>).)*<>(?:(?!<>).)*)<>((?:(?!<>).)*)(?:<>)?(.*\s*)$/mg |
852 | + | |
853 | - | ,"rep" : "$1 [ $3 ]$2$4" |
853 | + | |
854 | - | } |
854 | + | |
855 | - | ] |
855 | + | |
856 | db.Open(DRIVER+"Database="+dbFile); | |
857 | - | if(URL.otherURLType) Err("E_illegal_url"); |
857 | + | |
858 | - | u=u.replace(/\/test\/(?=read)/,"/bbs/") |
858 | + | |
859 | - | .replace(/\/read\.cgi\//,"/offlaw.cgi/2/"); |
859 | + | |
860 | - | trace("replace url="+u,9); |
860 | + | |
861 | - | return u; |
861 | + | |
862 | - | } |
862 | + | |
863 | - | ,getTitle : function(s) { this.title = (s.match(this.REG_PATTERN[this.re_sel].thr)||[])[1] || DatInfo.title; } |
863 | + | |
864 | var rs = new ActiveXObject("ADODB.Recordset"); | |
865 | - | if(!/^\d+<>.*?<>.+?<>.*?<>.*$/m.test(s)) Err("E_remained_garbage"); |
865 | + | |
866 | - | if (this.last-this.first+1 != s.replace(/^.*$/mg,"").length) { this.requireFillAbn = true; } |
866 | + | |
867 | rs.Open(sql,db); | |
868 | - | ,delDupData : function() {} |
868 | + | |
869 | var rr=[]; | |
870 | - | ,setTBlock : function() {} |
870 | + | |
871 | r += rr.join("|")+"\n"; | |
872 | rs.MoveNext(); | |
873 | - | //============================================================== |
873 | + | |
874 | } catch(e) { s = e.message; } | |
875 | - | var s=""; |
875 | + | |
876 | try { db.Close(); } catch(e) { s += " | Connection Close:"+e.message; } | |
877 | rs = null; | |
878 | return [r, s]; | |
879 | } | |
880 | function exec_exe(dbFile,sql) { return select_exe(dbFile, sql); } | |
881 | function select_exe(dbFile, sql) { | |
882 | var sqlite = shell.Exec(SCRIPT_PATH + "sqlite3.exe"); | |
883 | sqlite.StdIn.WriteLine(".open '"+ dbFile+ "'"); | |
884 | sqlite.StdIn.WriteLine(sql); | |
885 | sqlite.StdIn.WriteLine(".quit"); | |
886 | return [ sqlite.StdOut.ReadAll(), sqlite.StdErr.ReadAll() ]; | |
887 | - | var s=""; |
887 | + | |
888 | } | |
889 | ||
890 | function getBrdCustomizeIni(brdurl) { | |
891 | if(!fso.FileExists(JANE_BRDCUSTOMIZE_INI)) return null; | |
892 | - | } catch(e) { |
892 | + | |
893 | - | if(file) file.close(); |
893 | + | |
894 | - | s = loadFile(f); |
894 | + | |
895 | if (r = s.match(new RegExp("^\\[$1/?\\]\\s+MaxResNum=(\\d+)".expand([,"http://"+brdurl]),"im"))) break; | |
896 | u = brdurl.split(/\/(?=[^\/]+$)/); | |
897 | brdurl =u[0]; | |
898 | } while(u[1]) | |
899 | - | function saveFile(f,s,add) { |
899 | + | |
900 | } | |
901 | ||
902 | function chkJaneProg() { | |
903 | - | if (add) { try {strm.loadFromFile(f); strm.Position = strm.Size;} catch(e){} } |
903 | + | var i,n1=0,n2=0; |
904 | var folder=sha.Namespace(JANE_PATH); | |
905 | var items=folder.Items(); | |
906 | for(i=0; i<items.Count-1;i++) { | |
907 | if(folder.GetDetailsOf(items, i) == '説明') { n1=i; } | |
908 | if(folder.GetDetailsOf(items, i) == '製品名') { n2=i; } | |
909 | - | function saveFile2(f,s,add) { |
909 | + | |
910 | if(n1>0) var description = folder.GetDetailsOf(folder.ParseName("Jane2ch.exe"),n1); | |
911 | - | var file = fso.OpenTextFile( f, (add)?8:2 , true, 0); |
911 | + | if(n2>0) var productname = folder.GetDetailsOf(folder.ParseName("Jane2ch.exe"),n2); |
912 | if (description=="JaneXeno") return "Xeno"; | |
913 | if (description=="JaneView") return "View"; | |
914 | - | } catch(e) { |
914 | + | |
915 | - | if(file) file.Close(); |
915 | + | |
916 | - | saveFile(f,s,add); |
916 | + | |
917 | if (fileversion<1.0) return "Xeno?"; | |
918 | return "Unknown"; | |
919 | } | |
920 | - | function saveBinaryFile(f,b) { |
920 | + | //-------------------------------------------------------------------------------- |
921 | - | strm.Type = 1; |
921 | + | |
922 | var d = p.match(/[^\\]+\\/g), e = ""; | |
923 | - | strm.Write(b); |
923 | + | for (var i = 0; d[i]; i++) fso.FolderExists(e += d[i]) || fso.CreateFolder(e); |
924 | return p; | |
925 | - | catch(e) { strm.Close(); Err("E_savefile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f+" (binary)"); } |
925 | + | |
926 | ||
927 | function parmParse(args) { | |
928 | var ptn = [ "^(?:/n:)?(\\d+)", "^/f", "^http://", "^/w:?(-?\\d+)?$", "^/-w", "^/a(?:ppend)?" | |
929 | - | function readHTTP(u) { |
929 | + | , "^/b(?:ak)?(1)?", "^/z", "^/redraw:?(\\d+)?$", "/log:?(.*)$" ]; |
930 | - | var s="", r="", b; |
930 | + | var p = {}; |
931 | - | if(args.proxy) { |
931 | + | for (var i=0; i<args.length; i++) { |
932 | - | if(USED_WINHTTP) { http.setProxy(2, args.proxy, ""); } |
932 | + | for (var j=0,n=-1; j<ptn.length;j++) {if ((new RegExp(ptn[j],"i")).test(args(i))) { n=j; break;} } |
933 | - | else Err("E_not_suported_proxy"); |
933 | + | switch (n) { |
934 | case 0: p["opt_n"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||""); | |
935 | break; | |
936 | case 1: p["url"] = InputBox("URLを指定してください",MY_NAME) || ""; | |
937 | break; | |
938 | case 2: p["url"] = args(i); | |
939 | - | var t0=new Date(); |
939 | + | |
940 | - | while( (USED_WINHTTP) ? !http.waitForResponse(0) : http.readyState<4 ) { |
940 | + | case 3: p["sendkey"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||1200); |
941 | break; | |
942 | case 4: p["sendkey"] = -1; | |
943 | break; | |
944 | - | // if (http.status != 200 && !http.status==0) Err("E_http_recieve", " status="+http.status); |
944 | + | case 5: p["append"] = true; |
945 | break; | |
946 | - | b = http.responseBody; |
946 | + | case 6: p["bak"] = -1; |
947 | - | r = http.getAllResponseHeaders(); |
947 | + | if ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]) { p["bak"] = 1; } |
948 | - | try {s = http.responseText;} catch(e) {} |
948 | + | |
949 | case 7: p["restart"] = true; | |
950 | - | if(b !== void 0) { |
950 | + | |
951 | case 8: p["redraw"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||1200); | |
952 | - | if(cs=="x-sjis") cs="shift-jis"; |
952 | + | |
953 | - | if(basp) { |
953 | + | case 9: p["trace"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||""); |
954 | - | trace("文字コード変換開始 with basp21",9); |
954 | + | |
955 | - | s = basp.Kconv(b,4,cs=="shift-jis"?1:0); |
955 | + | default: break; |
956 | } | |
957 | - | trace("文字コード変換開始",9); |
957 | + | |
958 | - | strm.Type = 1; |
958 | + | if (!("url" in p)) p["url"] = InputBox("URLを指定してください",MY_NAME) || ""; |
959 | - | strm.Open(); |
959 | + | p.url = p.url.replace(/^(http:\/\/.*?)http:\/\/.*$/, "$1") |
960 | - | strm.Write(b); |
960 | + | |
961 | - | strm.Position = 0; |
961 | + | |
962 | - | strm.Type = 2; |
962 | + | |
963 | - | strm.Charset = cs; |
963 | + | //-------------------------------------------------------------------------------- |
964 | - | s = strm.ReadText(-1); |
964 | + | |
965 | - | strm.Close(); |
965 | + | |
966 | if (URL_jbbs.RE_SITE.test(args.url)) Thread_jbbs.proc(); | |
967 | else Thread_2ch.proc(); | |
968 | } | |
969 | ||
970 | /*@if (@DEBUG) | |
971 | - | return [s,r,b]; |
971 | + | |
972 | @else @*/ | |
973 | try {main();} catch (e) {WScript.Echo(e.message);} | |
974 | - | function saveDat(dat,s,b,add,latest) { |
974 | + | |
975 | - | var cnt; |
975 | + | |
976 | //-------------------------------------------------------------------------------- | |
977 | /*@if (@EnabledTest2chJSON) | |
978 | function get2chJSON() { | |
979 | var urlJSON = "http://itest.2ch.net/public/newapi/client.php?subdomain=$2&board=$5&dat=$6".expand(URL.prm); | |
980 | - | cnt = s.match(/\n/g).length+DatInfo.offset; |
980 | + | |
981 | - | if(!args.overwrite) { |
981 | + | var s = readHTTP(urlJSON); |
982 | - | if(DatInfo.cnt>=cnt && (latest==null || latest==true)) { |
982 | + | |
983 | - | if(REWRITE_DAT==3 || (REWRITE_DAT==2 && DatInfo.cnt==cnt)) Err("E_stop"); |
983 | + | |
984 | - | if (REWRITE_DAT==0 |
984 | + | var thread = s.match(/"thread":\[(\d+),(\d+),("[^"]*"),("[^"]*"),("[^"]*"),("[^"]*")\]/); |
985 | - | && shell.Popup("新規のレスが無いようですが置換を続行しますか? (" |
985 | + | var comments = (s.match(/"comments":\[((?:\[(\d+),("[^"]*"),("[^"]*"),(\d+),("[^"]*"),("[^"]*"),("[^"]*")\],?)+)\]/)||[])[1]; |
986 | - | +DatInfo.cnt+" -->"+cnt+")",0,MY_NAME,4+32+256) != 6){ |
986 | + | |
987 | - | Err("E_stop"); |
987 | + | |
988 | comments = comments.replace(/(\[(?:\d+),(?:"[^"]*"),(?:"[^"]*"),(?:\d+),(?:"[^"]*"),(?:"[^"]*"),(?:"[^"]*")\]),/g,"$1\n").split("\n"); | |
989 | Thread_2ch.title = title; | |
990 | Thread_2ch.last = comments.length; | |
991 | if(args.append && DatInfo.cnt>0) { comments.splice(0,DatInfo.cnt); } | |
992 | for(var i=0; i<comments.length; i++) { | |
993 | - | // if((!args.append&&add==0)||args.overwrite) { |
993 | + | |
994 | - | // saveFile(path(dat),""); trace("create file:"+dat,9); //既存のdatを削除 |
994 | + | |
995 | - | // } |
995 | + | res = res.match(/^(\d+),("[^"]*"),("[^"]*"),(\d+),("[^"]*"),("[^"]*"),("[^"]*")$/); |
996 | - | if(b===null) { trace(); saveFile2(path(dat), s, args.append||(!args.overwrite&&add) ); trace("save file:"+dat); } |
996 | + | var name = eval(res[2]).replace(/(◆.+)$/,"</b>$1<b>").replace(/(転載ダメ©2ch\.net)/,"<small>$1</small>"); |
997 | - | else { trace(); saveBinaryFile(path(dat), b); trace("save binary file:"+dat); } |
997 | + | |
998 | d = new Date( (res[4]<365*24*60*60*1000) ? res[4]*1000 : res[4] ); | |
999 | d = formatDate(d,2); | |
1000 | if (res[5]!='""') id = " ID:" + eval(res[5]); | |
1001 | if (res[6]!='""') be = " BE:" + eval(res[6]); | |
1002 | comments[i] = [ name, eval(res[3]), d + id + be, eval(res[7]), ].join("<>"); | |
1003 | } | |
1004 | s = ""; | |
1005 | if(comments.length>0) { | |
1006 | if(!args.append || !DatInfo.cnt) { comments[0] += title; } | |
1007 | s = comments.join("\n") + "\n"; | |
1008 | } | |
1009 | return s; | |
1010 | } | |
1011 | @end @*/ | |
1012 | ||
1013 | //-------------------------------------------------------------------- | |
1014 | // History : | |
1015 | // v.0.1 2015/03/26 created | |
1016 | // v.0.2 2015/03/27 fixed | |
1017 | // email-protection から mailto: へ置換を追加 | |
1018 | // v.0.3 2015/03/27 fixed | |
1019 | // スレッドデータ抽出判定を変更 | |
1020 | // v.0.4 2015/03/27 added | |
1021 | - | var wmi; try { wmi = new WMI(); } catch(e) { wmi=null; } |
1021 | + | // スレッドデータ抽出できなかった場合のエラーチェックを追加 |
1022 | // v.0.5 2015/03/28 | |
1023 | // 試験的に「したらば」の過去ログ取得をサポート(ほぼ未検証) | |
1024 | // 通信が非同期になってなかったのを修正 | |
1025 | - | if(!wmi) { WScript.Sleep(4000);} |
1025 | + | // bbspink.comの場合も2ch.netの処理に飛ぶようにした |
1026 | - | else { |
1026 | + | // スレッドデータからレスを正常に抽出できない場合のチェックを追加 |
1027 | - | do { |
1027 | + | // 既存のdatがあった場合に、レス数が大きくない場合は置換するかどうか問い合わせするようにした |
1028 | - | var cnt=40; |
1028 | + | // v.0.6 2015/03/28 |
1029 | - | while(cnt && wmi.isAliveProcess(JANE_EXE, JANE_PATH+JANE_EXE)) { WScript.Sleep(100); cnt--;} |
1029 | + | // dat格納場所が見つからない場合のチェックを追加 |
1030 | - | if(!cnt) { WScript.Echo(JANE_EXE+"を終了させてください"); } |
1030 | + | // URLにレス番の指定が無い場合レス番1をURLに追加し、スレの先頭から表示されるようにした |
1031 | - | } while(!cnt); |
1031 | + | // 一度スレを閉じるための"ALT","T","C","C"のキーを送る時に適当にウェイトを入れた |
1032 | // v.0.7 2015/03/29 | |
1033 | // キー送信のウェイトを再度調整 300ms->600ms | |
1034 | // (メニューが残るのは最初の起動で開く処理がキー操作の途中にくるタイミングなのでキー送信を全体に遅らせた) | |
1035 | - | function saveIdx(boardUrl,force) { |
1035 | + | // 既存のdatが存在した場合は、現在のレス位置とし、再度開く時にスレの先頭に移動しないようにした |
1036 | - | var i,s,r,lines=Math.max(DatInfo.cnt,DatInfo.lines); |
1036 | + | // v.0.8 2015/03/29 |
1037 | // LogsファイルをJane Style直下のフォルダ以外に移動している場合、brdファイル読み込みエラーになるのを修正 | |
1038 | // 起動パラメタ(オプション指定)を追加しました | |
1039 | // パラメタなし : urlを問い合わせる(対話型) | |
1040 | // 第1パラメタ : URL | |
1041 | // 第2パラメタ以降 : | |
1042 | // http://~ 第1パラメタを無視してこちらをurlとして優先する | |
1043 | // /f 第1パラメタのurlを無視してurlを問い合わせる | |
1044 | - | var state = (lines>=maxRes) ? 0 : IDX_STATE[ (URL===URL_jbbs) ? "jbbs" : "2ch" ]; |
1044 | + | // /n:999 レス番を指定(そのレス番に飛ぶ) |
1045 | // コマンド登録時に、wscript "$BASEPATHgethttpdat.js" "$LINK$URL" $INPUT としておくと動的にオプションを指定できます | |
1046 | // v.0.9 2015/03/30 | |
1047 | // 【したらば】の過去ログ取得を拡張 | |
1048 | - | var idx = [ datName,DatInfo.title,'',lines,'0','',boardUrl,state,lines,'','','0',last_got,'0','0' ]; |
1048 | + | // ・/bbs/read.cgi/ 以外、/bbs/read_archive.cgi/ でも取得する |
1049 | // ・まず rawmode.cgi での取得を試みる | |
1050 | // ・事前にカテゴリ/板を開いたことが無いスレでも取得できるようにした(スレ一覧も開きます) | |
1051 | // パラメタのレス番指定は、/n:を省略可能 数字のみでよい | |
1052 | // v.0.10 2015/03/30 | |
1053 | // 【したらば】のスレデータ受信時予期せぬエラーの場合正常としていたのを修正 | |
1054 | // v.0.11 2015/03/31 | |
1055 | // 板一覧(Jane2ch.brd)に複数の板識別子が存在する場合、最後のものを採用するように変更 | |
1056 | // 【したらば】過去ログで、 | |
1057 | // 透明あぼーん(番号が飛んでいる)の場合に「透明あぼーん」を追加しレス番ずれを防止 | |
1058 | // スレデータを抽出できない場合があったのを修正 | |
1059 | // v.0.12 2015/03/31 | |
1060 | - | var SQL_CMD_3 = "update idxlist set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,lines]); |
1060 | + | // 2chのデータの中に<a href="mailto:xxx"></a>が無い場合や最後に<br><br>が付いてない場合も抽出できるようにした |
1061 | // ( [ここ壊れてます]のようなデータのこと) | |
1062 | // スレ抽出できない場合サーバーメッセージらしきものをエラーメッセージに追加?(datが存在しません/人大杉) | |
1063 | // したらばのrawmodeで取得したデータでの透明あぼーん処理を追加 | |
1064 | // 引数追加とデフォルト動作変更 | |
1065 | // /w スレを閉じて開きなおす(600ms) | |
1066 | // /w:999 スレを閉じて開きなおす(wait指定) | |
1067 | // /-w スレを閉じない(デフォルト) | |
1068 | // v.0.13 2015/04/03 | |
1069 | // 2chのデータの中に名前が無い(<font.*><b></b></font>)場合に抽出できなかったのを修正 | |
1070 | // 引数の指定を順不同にし、以下を追加 | |
1071 | // /a, /append 既存のデータに追加する(差分のみ取得) | |
1072 | // /b, /bak 保存前に既存のdatファイルが存在した場合は、Logs\bak\フォルダにバックアップコピーする | |
1073 | // したらばの透明あぼーん補正処理は必要のない場合スキップする | |
1074 | // 2chのサーバーエラーメッセージで"LoadAverage ="が抜けていたのを修正 | |
1075 | // v.0.14 2015/04/04 | |
1076 | // /a 指定時、したらばの過去ログを正常に追加できていなかったのを修正(したらばは過去ログの部分取得が無理なため) | |
1077 | // v.0.15 2015/04/12 | |
1078 | // レス数を正しく認識できない場合があった(レス番抽出正規表現の間違い)のを修正 | |
1079 | // /a 指定時、2chのdatが無い場合、先頭レス番1が消えるのを修正 | |
1080 | // v.0.16 2015/04/16 | |
1081 | // 2chでデータが途中で途切れている場合のチェックを追加 | |
1082 | // (ftp:// のようなデータがある場合、現状では、エラーにならず途切れていることがある) | |
1083 | // v.0.17 2015/04/17 | |
1084 | // 考えを変えて、データが途中で途切れている場合も取得したところまでで処理を続行するように変更した | |
1085 | // オプションに、/b1, /bak1 を追加(bakupは1回限りでファイルが存在していたら上書きしない) | |
1086 | // v.0.18 2015/04/21 | |
1087 | // オプション /z を追加(Jane2ch.exeを終了させて、db、idx、subject.txtに情報を設定し、再起動する) | |
1088 | // (なお、高速Merge有効時にはsqlite3.exeが必要) | |
1089 | // (stateは=3(dat落ち)に設定) ※本来の処理としては、レス数1000(10000)以上では=0のままで良く、未満時は=10(過去ログ)? | |
1090 | - | var SQL_CMD_XENO5 = "update thread set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,lines]); |
1090 | + | // v.0.19 2015/04/21 |
1091 | // 引数にurlが含まれていない場合、url入力ボックスが出ずにエラーになってたのを修正 | |
1092 | // v.0.20 2015/04/27 | |
1093 | // したらばの旧過去ログURL(http://[したらばsite]/[カテゴリ]/[掲示板番号]/storage/[スレッド番号].html)もサポート | |
1094 | // /z オプション時、高速Merge無効時の処理を修正 | |
1095 | // 高速Merge有効時、sqlite3.exeに加えてSQLite3 ODBC Driverもサポート(どちらか一方があればよい) | |
1096 | // db,idxのstate値は、=0(brdcustomize.iniの設定値又は1000以上の時)、それ以外は =3(dat落ち) にする | |
1097 | // v.0.21 2015/04/27 | |
1098 | // /z オプション時、高速Merge有効時、sqlite3.exeとSQLite3 ODBC Driverの両方とも無い場合エラーになってたのを修正 | |
1099 | // v.0.22 2015/04/29 | |
1100 | // 2chの過去ログURL形式(/[板識別子]/kako/[スレID(3or4)桁]/([スレID5桁]/)[スレID].html 又は.dat)をサポート | |
1101 | // ただし、サーバー移転等でURLのサーバー名と過去ログ倉庫が不一致の場合は不可 | |
1102 | // kako形式の場合には/nオプションや/aオプションは無効となる | |
1103 | // /z 時のdb,idxのstate値は=10に設定される | |
1104 | // それと関連して、通常URLでメッセージ「error 4002」が返ってきた場合は、URLをkako形式に変えて再トライする | |
1105 | // また、「error 3001」(datが無い)が返ってきた場合はkako形式のURLに変えて実行すると取得できるかもしれない | |
1106 | // v.0.23 2015/04/29 | |
1107 | // 2chでURLにレス番指定(/l50,/-n10)がくっ付いている場合、正常に処理できなくなっていたのを修正 | |
1108 | // v.0.24 2015/04/29 | |
1109 | // 2chで/a指定時、既存のdatファイルが存在していると正常に処理できなくなっていたのを修正 | |
1110 | // v.0.25 2015/04/29 | |
1111 | // したらばで、カテゴリ名に / が含まれている場合に正常に処理できなくなってたのを修正 | |
1112 | // v.0.26 2015/05/04 | |
1113 | // /b オプションが正常に処理できなくなっていたのを修正 | |
1114 | - | s[7] = "" + (parseInt(s[7],10) + lines - parseInt(s[2],10)); |
1114 | + | // (また、Logsフォルダを指定してない場合 /b を付けて無くてもバックアップされてしまっていた) |
1115 | // Jane2ch.exeに送るキーコードを変更(/wの時 CTL+w でスレを閉じる, /z の時 ALT+F4 で終了する) | |
1116 | // v.0.27 2015/05/04 | |
1117 | // ファイル読み書きエラー時、付随情報としてカレントパス、ファイル名を正常に出力するするように修正 | |
1118 | // /redraw (/redraw:999) オプション追加 (スレを開いた後キーコード('T','G','0')を送る) | |
1119 | // Xenoでは/zオプション時sqlite3.exeは弾くようにした(dbがutf16の場合、日本語が化けるため)、またタイトルも書き換える | |
1120 | // v.0.28 2015/05/04 | |
1121 | // /redraw 'ALT'を送るのが抜けていたのを修正 | |
1122 | // v.0.29 2015/05/07 | |
1123 | // brdファイル検索時の正規表現文字列の生成(ピリオドが曖昧にマッチしていた)を修正 | |
1124 | // (具体的には、xxx.2ch.netとnext2ch.netの両方が存在していると、後ろのnext2chの方にdatファイルが作成されていた) | |
1125 | // v.0.30 2015/05/17 | |
1126 | // オプション /log[:][path] を追加 path名の指定には環境変数が使えます(path省略時 %temp%\gethtmldat.log) | |
1127 | // /w, /redraw のデフォルトのwaitを1200msに変更 | |
1128 | // 2ch - .dat.gz/.dat read追加,URL変換は「error 4002」に限定しない | |
1129 | // jbbs - board_info.cgi->/api/setting.cgiに変更 | |
1130 | // v.0.31 2015/05/17 | |
1131 | - | var re = new RegExp("^"+datName+"\\..*\\((\\d+)\\)(\\s*)$", "m"); |
1131 | + | // 一部のエラーメッセージがきちんと表示されないのを修正 |
1132 | - | s=""; |
1132 | + | // jbbs - 現役のスレ(rawmode.cgi)でスレタイトルとIDが異常になるのを修正、dat落ち扱いしないように修正 |
1133 | - | r=0; |
1133 | + | // ファイルアクセスを、ADODB StreamからFileSystemObjectに変更(read速度が大幅に改善) |
1134 | - | if(fso.FileExists("subject.txt")) try{s=loadFile("subject.txt"); r=1;} catch(e){r=-1;} |
1134 | + | // v.0.32 2015/05/17 |
1135 | - | if(force) { |
1135 | + | // 2ch - URL変換再試行時もエラーの場合、最初のエラー内容を表示するように修正 |
1136 | - | s = s.replace(re,""); |
1136 | + | // v.0.33 2015/05/17 |
1137 | - | s = datName+".dat<>"+DatInfo.title+"("+lines+")\r\n" + s; |
1137 | + | // 2ch - URL変換再試行は「error」に限定(人大杉/LoadAverageは除外) |
1138 | - | try {saveSubjectTxt("subject.txt", s, force);} |
1138 | + | //-------------------------------------------------------------------- |