svnno****@sourc*****
svnno****@sourc*****
2008年 1月 27日 (日) 19:53:41 JST
Revision: 339 http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=bbs2ch&view=rev&rev=339 Author: flyson Date: 2008-01-27 19:53:41 +0900 (Sun, 27 Jan 2008) Log Message: ----------- スレ一覧の Storage 化 Modified Paths: -------------- trunk/bbs2chreader/chrome/content/bbs2chreader/board/items.js trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.js trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.xul trunk/bbs2chreader/chrome/content/bbs2chreader/board/subscribe.js trunk/bbs2chreader/defaults/preferences/bbs2chreader-pref.js -------------- next part -------------- Modified: trunk/bbs2chreader/chrome/content/bbs2chreader/board/items.js =================================================================== --- trunk/bbs2chreader/chrome/content/bbs2chreader/board/items.js 2008-01-26 16:02:06 UTC (rev 338) +++ trunk/bbs2chreader/chrome/content/bbs2chreader/board/items.js 2008-01-27 10:53:41 UTC (rev 339) @@ -35,9 +35,6 @@ * * ***** END LICENSE BLOCK ***** */ - - - function Bbs2chBoardItems(aURLSpec){ this.init(aURLSpec); } @@ -119,8 +116,8 @@ init: function(aURLSpec){ - this._bbs2chService = Cc["@mozilla.org/bbs2ch-service;1"].getService(Ci.nsIBbs2chService); - this._ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + this._b2rService = XPC.getService("@bbs2ch.sourceforge.jp/b2r-global-service;1", "b2rIGlobalService"); + this._ioService = XPC.getService("@mozilla.org/network/io-service;1", "nsIIOService"); this._validURL = false; try{ @@ -128,20 +125,20 @@ this._subjectURL = this._ioService.newURI("subject.txt", null, this.url) .QueryInterface(Ci.nsIURL); - this._subjectFile = this._bbs2chService.getLogFileAtURL(this.subjectURL.spec); + this._subjectFile = this._b2rService.io.getLogFileAtURL(this.subjectURL.spec); this._settingURL = this._ioService.newURI("SETTING.TXT", null, this.url) .QueryInterface(Ci.nsIURL); - this._settingFile = this._bbs2chService.getLogFileAtURL(this.settingURL.spec); + this._settingFile = this._b2rService.io.getLogFileAtURL(this.settingURL.spec); }catch(ex){ - dump("Bbs2chBoardItems.init: " + ex + "\n"); + Components.utils.reportError(ex); return; } // 板のタイプをチェック。TYPE_PAGE は TYPE_2CH にする - this._type = this._bbs2chService.getBoardType(this.url.spec); - if(this._type == this._bbs2chService.BOARD_TYPE_PAGE) - this._type = this._bbs2chService.BOARD_TYPE_2CH; + this._type = this._b2rService.threadUtils.getBoardType(this.url); + if(this._type == this._b2rService.BOARD_TYPE_PAGE) + this._type = this._b2rService.BOARD_TYPE_2CH; this._items = new Array(); this._validURL = true; @@ -152,10 +149,10 @@ if(!this._settings){ this._settings = new Array(); if(this.settingFile.exists()){ - var fileLineIterator = this._getFileLineIterator(this.settingFile, this._getCharset()); - var regLine = /^([^=]+)=(.+)$/; - for(let[i, line] in fileLineIterator){ - if(regLine.test(line)) this._settings[RegExp.$1] = RegExp.$2; + var settingLines = this._b2rService.io.readFile(this.settingFile, this._getCharset()); + var regLine = /^(.+)=(.+)$/gm; + while(regLine.exec(settingLines)){ + this._settings[RegExp.$1] = RegExp.$2; } } } @@ -163,248 +160,143 @@ }, - _getFileLineIterator: function(aLocaFile, aCharset){ - const REPLACEMENT_CHARACTER = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER; - var fileInputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); - var converterInputStream = Cc["@mozilla.org/intl/converter-input-stream;1"] - .createInstance(Ci.nsIConverterInputStream).QueryInterface(Ci.nsIUnicharLineInputStream); - fileInputStream.init(aLocaFile, 0x01, 0666, 0); - converterInputStream.init(fileInputStream, aCharset, 1024, REPLACEMENT_CHARACTER); - var i=0; - try{ - while(true){ - var line = {}; - if(converterInputStream.readLine(line)){ - yield [i, line.value]; - i++; - }else{ - yield [i, line.value]; - break; - } - } - }finally{ - converterInputStream.close(); - fileInputStream.close(); - } - }, - _getCharset: function(){ var charset = "Shift_JIS"; switch(this.type){ - case this._bbs2chService.BOARD_TYPE_2CH: + case this._b2rService.BOARD_TYPE_2CH: charset = "Shift_JIS"; break; - case this._bbs2chService.BOARD_TYPE_BE2CH: - case this._bbs2chService.BOARD_TYPE_JBBS: - case this._bbs2chService.BOARD_TYPE_MACHI: + case this._b2rService.BOARD_TYPE_BE2CH: + case this._b2rService.BOARD_TYPE_JBBS: + case this._b2rService.BOARD_TYPE_MACHI: charset = "euc-jp"; break; } return charset; }, - /** - * Date オブジェクトからフォーマットされた日付文字列(短い形式)を返す - */ - _getFormatedDate: function(aDate){ - var fullYear = String(aDate.getFullYear()); - var month = String(aDate.getMonth() + 1); - if(month.length == 1) month = "0" + month; - var date = String(aDate.getDate()); - if(date.length == 1) date = "0" + date; - var hours = String(aDate.getHours()); - if(hours.length == 1) hours = "0" + hours; - var minutes = String(aDate.getMinutes()); - if(minutes.length == 1) minutes = "0" + minutes; - return [fullYear, month, date].join("/") + " " + [hours, minutes].join(":"); - }, - refresh: function(aFilterLimit, aShowDownedLogs){ - var startTime = new Date().getTime(); - const NS_BBS2CH = this._bbs2chService.nameSpace; - const STATUS_NEW = 5; const STATUS_UNREAD = 4; const STATUS_SUBSCRIBE = 3; const STATUS_NONE = 2; const STATUS_DOWN = 1; - this._items = new Array(); - this._lastItems = null; - - // subject.txt が無いときは終了 - if(!this.subjectFile.exists()) return; - - // subject.txt を読み込んで行ごとの配列にする。 - var subjectLines = this._bbs2chService.readFile(this.subjectFile.path); - subjectLines = this._bbs2chService.fromType(subjectLines, this.type); - subjectLines = subjectLines.split("\n"); - - // 行の解析に使う正規表現 - var regLine; - switch(this.type){ - case this._bbs2chService.BOARD_TYPE_2CH: - case this._bbs2chService.BOARD_TYPE_BE2CH: - regLine = /^(\d{9,10})\.dat<>(.+) ?\((\d{1,4})\)/; - break; - case this._bbs2chService.BOARD_TYPE_JBBS: - case this._bbs2chService.BOARD_TYPE_MACHI: - regLine = /^(\d{9,10})\.cgi,(.+) ?\((\d{1,4})\)/; - break; - } - // スレッドの URL var baseUrlSpec; var categoryPath; var threadUrlSpec; switch(this.type){ - case this._bbs2chService.BOARD_TYPE_2CH: - case this._bbs2chService.BOARD_TYPE_BE2CH: + case this._b2rService.BOARD_TYPE_2CH: + case this._b2rService.BOARD_TYPE_BE2CH: baseUrlSpec = this.url.resolve("../"); categoryPath = this.url.spec.substring(baseUrlSpec.length); threadUrlSpec = baseUrlSpec + "test/read.cgi/" + categoryPath; break; - case this._bbs2chService.BOARD_TYPE_JBBS: + case this._b2rService.BOARD_TYPE_JBBS: baseUrlSpec = this.url.resolve("../../"); categoryPath = this.url.spec.substring(baseUrlSpec.length); threadUrlSpec = baseUrlSpec + "bbs/read.cgi/" + categoryPath; break; - case this._bbs2chService.BOARD_TYPE_MACHI: + case this._b2rService.BOARD_TYPE_MACHI: categoryPath = this.url.directory.replace(/\//g, ""); baseUrlSpec = this.url.resolve("../"); threadUrlSpec = baseUrlSpec + "bbs/read.cgi?BBS=" + categoryPath; break; } - if(aFilterLimit == -1 ) aFilterLimit = subjectLines.length; - var logItemHash = this.getLogItemHash(threadUrlSpec); - // ぐるぐる - for(var i=0; i<subjectLines.length; i++){ - if(!regLine.test(subjectLines[i])) continue; + this._items = new Array(); + this._lastItems = null; - // フィルタ - if(!logItemHash.hasOwnProperty("item-" + RegExp.$1) && aFilterLimit<=i) - continue; + var b2rStorageService = XPC.getService("@bbs2ch.sourceforge.jp/b2r-storage-service;1", "b2rIStorageService"); + var pref = XPC.getService("@mozilla.org/preferences-service;1", "nsIPrefBranch"); - var item = {}; - item.datID = RegExp.$1; - item.id = "item-" + item.datID; - item.number = i + 1; - item.title = this.htmlToText(RegExp.$2); - item.count = Number(RegExp.$3); - item.read = 0; - item.unread = 0; - item.force = this.getThreadForce(item.datID, item.count); - item.makeDate = this._getFormatedDate(new Date(item.datID * 1000)); - item.url = threadUrlSpec + item.datID + "/"; - if(this.type == this._bbs2chService.BOARD_TYPE_MACHI){ - item.url = threadUrlSpec + "&KEY=" + item.datID; - } + var boardID = this._b2rService.threadUtils.getBoardID(this.url); - if(logItemHash.hasOwnProperty("item-" + item.datID)){ - var logItem = logItemHash["item-" + item.datID]; - var unread = item.count - logItem.read; - - item.read = logItem.read; - item.unread = (unread > 0) ? unread : 0; - - // ハッシュから削除し、残ったものは DAT 落ちとみなす - delete logItemHash["item-" + item.datID]; - } - - // ステータス - item.status = STATUS_NONE; - if(item.read > 0 && item.count > item.read){ - item.status = STATUS_UNREAD; // 未読あり - }else if(item.read > 0){ - item.status = STATUS_SUBSCRIBE; // 購読中 - } - - this._items.push(item); + var subscribedOnly = ""; + if(aFilterLimit==0){ + aFilterLimit = 2000; + subscribedOnly = "AND sd.line_count > 1"; } - // DAT 落ち - if(aShowDownedLogs){ - for(i in logItemHash){ - logItemHash[i].status = STATUS_DOWN; - this._items.push(logItemHash[i]); - } - } - }, + var database = b2rStorageService.database; + var sql = <> + SELECT + bs.ordinal + 1 AS number, + bs.dat_id AS dat_id, + bs.title AS title, + bs.line_count AS line_count, + IFNULL(sd.line_count, 0) AS read, + MAX(IFNULL(bs.line_count - sd.line_count, 0), 0) AS unread, + STRFTIME(?1, bs.dat_id, 'unixepoch', 'localtime') AS make_date + FROM board_subject AS bs LEFT OUTER JOIN thread_data AS sd + ON bs.board_id=sd.board_id AND bs.dat_id=sd.dat_id + WHERE bs.board_id=?2 {subscribedOnly} + LIMIT ?3; + </>.toString().replace(/\t/g, ""); + var statement = database.createStatement(sql); - htmlToText: function(aStr){ - if(aStr.indexOf("&") == -1) return aStr; - var fromStr = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); - fromStr.data = aStr; + database.beginTransaction(); try{ - var toStr = { value: null }; - var formatConverter = Cc["@mozilla.org/widget/htmlformatconverter;1"] - .createInstance(Ci.nsIFormatConverter); - formatConverter.convert("text/html", fromStr, fromStr.toString().length, - "text/unicode", toStr, {}); - }catch(e){ - return aStr; - } - if(toStr.value){ - toStr = toStr.value.QueryInterface(Ci.nsISupportsString); - return toStr.toString(); - } - return aStr; - }, + statement.bindStringParameter(0, pref.getCharPref("extensions.bbs2chreader.board_created_format")); + statement.bindStringParameter(1, boardID); + statement.bindInt32Parameter(2, aFilterLimit); + var now = Date.now() / 1000; + while(statement.executeStep()){ + let item = {}; + item.number = statement.getInt32(0); + item.datID = statement.getString(1); + item.id = "item-" + item.datID; + item.title = statement.getString(2); + item.count = statement.getInt32(3); + item.read = statement.getInt32(4); + item.unread = statement.getInt32(5); + item.force = this._getThreadForce(now, item.datID, item.count); + item.created = statement.getString(6); - /** - * b2rStorageService からログアイテムハッシュを作る - */ - getLogItemHash: function(aThreadUrlSpec){ - var b2rStorageService = Cc["@bbs2ch.sourceforge.jp/b2r-storage-service;1"].getService(Ci.b2rIStorageService); - var threadDataArray = b2rStorageService.getThreadDataArray(this._url); + item.url = threadUrlSpec + item.datID + "/"; + if(this.type == this._b2rService.BOARD_TYPE_MACHI){ + item.url = threadUrlSpec + "&KEY=" + item.datID; + } - var resultHash = new Array(); - for each(let threadData in threadDataArray){ - var cacheItem = {}; - cacheItem.datID = threadData.datID; - cacheItem.read = threadData.lineCount; - cacheItem.title = this.htmlToText(threadData.title); - cacheItem.id = "item-" + cacheItem.datID; - cacheItem.url = aThreadUrlSpec + cacheItem.datID + "/"; - if(this.type == this._bbs2chService.BOARD_TYPE_MACHI){ - cacheItem.url = aThreadUrlSpec + "&KEY=" + item.datID; + // ステータス + item.status = STATUS_NONE; + if(item.read > 0 && item.count > item.read){ + item.status = STATUS_UNREAD; // 未読あり + }else if(item.read > 0){ + item.status = STATUS_SUBSCRIBE; // 購読中 + } + + this._items.push(item); } - resultHash[cacheItem.id] = cacheItem; + statement.reset(); + }catch(ex){ + Components.utils.reportError(ex); + }finally{ + database.commitTransaction(); } - return resultHash; }, + _getThreadForce: function(aNow, aDatID, aCount){ + // スレッド作成日から現在までの秒数 + var progress = aNow - aDatID; + // 86400000 = 一日/秒 (24 * 60 * 60) + progress = progress / 86400; - /** - * スレッドの勢いを返す - * - * @param aDatID number スレッドの ID - * @param aCount number 今ままでのレス数 - * @return number スレッドの平均書き込み数/一日 - */ - getThreadForce: function(aDatID, aCount){ - // スレッド作成日から現在までのミリ数 - var progress = Date.now() - aDatID * 1000; - // 86400000 = 一日/ミリ秒 (24 * 60 * 60 * 1000) - progress = progress / 86400000; - var force = parseInt((aCount / progress)); if(isNaN(force)) return 0; if(force < 0) return 0; return force; }, - search: function(aSearchString){ if(!this._lastItems) this._lastItems = this.items.concat(); - var unicodeNormalizer = Cc["@mozilla.org/intl/unicodenormalizer;1"] - .createInstance(Ci.nsIUnicodeNormalizer); + var unicodeNormalizer = XPC.createInstance("@mozilla.org/intl/unicodenormalizer;1", "nsIUnicodeNormalizer"); var normalizedStr = {}; var searchString = aSearchString.toLowerCase(); Modified: trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.js =================================================================== --- trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.js 2008-01-26 16:02:06 UTC (rev 338) +++ trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.js 2008-01-27 10:53:41 UTC (rev 339) @@ -503,7 +503,7 @@ } var b2rStorageService = Cc["@bbs2ch.sourceforge.jp/b2r-storage-service;1"].getService(Ci.b2rIStorageService); - b2rStorageService.boardSubjectUpdate(gBoardItems.url, gBoardItems.type, gBoardItems.subjectFile); + b2rStorageService.boardSubjectUpdate(gBoardItems.url, gBoardItems.type, gBoardItems.subjectFile.clone()); if(!gBoardItems.settingFile.exists() || gBoardItems.settingFile.fileSize==0){ settingUpdate(); Modified: trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.xul =================================================================== --- trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.xul 2008-01-26 16:02:06 UTC (rev 338) +++ trunk/bbs2chreader/chrome/content/bbs2chreader/board/page.xul 2008-01-27 10:53:41 UTC (rev 339) @@ -87,7 +87,7 @@ <label value="フィルタ: "/> <menulist id="mlstFilterLimit" value="-1" persist2="value" oncommand="initTreeSubject()"> <menupopup> - <menuitem label="すべて" value="-1"/> + <menuitem label="すべて" value="2000"/> <menuitem label="トップ 200" value="200"/> <menuitem label="トップ 400" value="400"/> <menuitem label="購読中" value="0"/> @@ -134,8 +134,8 @@ property="force" cellType="int" persist2="hidden width sortActive sortDirection"/> <splitter class="tree-splitter"/> - <treecol id="colMakeDate" label="作成日" flex="1" - property="makeDate" cellType="str" + <treecol id="colCreated" label="作成日" flex="1" + property="created" cellType="str" persist2="hidden width sortActive sortDirection"/> </treecols> <treechildren/> Modified: trunk/bbs2chreader/chrome/content/bbs2chreader/board/subscribe.js =================================================================== --- trunk/bbs2chreader/chrome/content/bbs2chreader/board/subscribe.js 2008-01-26 16:02:06 UTC (rev 338) +++ trunk/bbs2chreader/chrome/content/bbs2chreader/board/subscribe.js 2008-01-27 10:53:41 UTC (rev 339) @@ -395,7 +395,7 @@ setBoardState(boardItmes.url.spec, "Updated"); var b2rStorageService = Cc["@bbs2ch.sourceforge.jp/b2r-storage-service;1"].getService(Ci.b2rIStorageService); - b2rStorageService.boardSubjectUpdate(boardItmes.url, boardItmes.type, boardItmes.subjectFile); + b2rStorageService.boardSubjectUpdate(boardItmes.url, boardItmes.type, boardItmes.subjectFile.clone()); }else{ setBoardState(boardItmes.url.spec, "Normal"); Modified: trunk/bbs2chreader/defaults/preferences/bbs2chreader-pref.js =================================================================== --- trunk/bbs2chreader/defaults/preferences/bbs2chreader-pref.js 2008-01-26 16:02:06 UTC (rev 338) +++ trunk/bbs2chreader/defaults/preferences/bbs2chreader-pref.js 2008-01-27 10:53:41 UTC (rev 339) @@ -39,6 +39,7 @@ pref("extensions.bbs2chreader.board_middle_click_action", 2); pref("extensions.bbs2chreader.board_update_interval_limit", 120); pref("extensions.bbs2chreader.board_thread_view_limit", 50); +pref("extensions.bbs2chreader.board_created_format", "%Y-%m-%d %H:%M:%S"); pref("extensions.bbs2chreader.thread_skin", ""); pref("extensions.bbs2chreader.thread_font_name", "sans-serif");