Commit MetaInfo

Revision5287b142b408e3775966fc60883a277fe0100654 (tree)
Time2010-02-11 21:50:53
Authornogu <nogu@user...>
Commiternogu

Log Message

Add BoardDatabase class

All the member functions in BoardManager are static
and it's hard to image what this class is doing from the name.
This commit replaces BoardManager with BoardDatabase

Change Summary

Incremental Difference

--- a/kita/src/bbsview.cpp
+++ b/kita/src/bbsview.cpp
@@ -35,7 +35,7 @@
3535
3636 #include "viewmediator.h"
3737 #include "kitaui/listviewitem.h"
38-#include "libkita/boardmanager.h"
38+#include "libkita/boarddatabase.h"
3939 #include "libkita/favoriteboards.h"
4040 #include "libkita/globalconfig.h"
4141 #include "libkita/kita_misc.h"
@@ -148,9 +148,9 @@ bool BBSView::downloadBoardList()
148148 QString boardUrl = *it2;
149149 QString boardName = category.boardNameList[ count ];
150150 QString oldUrl;
151- int ret = BoardManager::enrollBoard(
152- boardUrl, boardName, oldUrl, Board_Unknown,
153- true /* test only */);
151+ BoardDatabase db(boardUrl);
152+ int ret = db.enrollBoard(
153+ boardName, oldUrl, Board_Unknown, true /* test only */);
154154 if (ret == Board_enrollNew) {
155155 newBoards += boardName + " ( " + category.category_name
156156 + " ) " + boardUrl + '\n';
@@ -214,7 +214,8 @@ bool BBSView::downloadBoardList()
214214 QString newUrl = newUrls[ i ];
215215
216216 // qDebug("move %s -> %s", oldURL.latin1(), newURL.latin1());
217- BoardManager::moveBoard(oldUrl, newUrl);
217+ BoardDatabase db;
218+ db.moveBoard(oldUrl, newUrl);
218219 }
219220
220221 /* save config */
@@ -311,8 +312,9 @@ void BBSView::showBoardList()
311312 continue;
312313 }
313314 QString oldUrl;
314- BoardManager::enrollBoard(boardUrl, boardName, oldUrl);
315- BoardManager::loadBBSHistory(boardUrl);
315+ BoardDatabase db(boardUrl);
316+ db.enrollBoard(boardName, oldUrl);
317+ db.loadBBSHistory();
316318 previousBoard = new ListViewItem(categoryItem, previousBoard,
317319 QStringList() << boardName << boardUrl);
318320 }
@@ -323,7 +325,8 @@ void BBSView::showBoardList()
323325 QString boardName = i18nc("@item:inlistbox", "Kita Board");
324326 QString oldUrl;
325327 new ListViewItem(m_boardList, 0, QStringList() << boardName << boardUrl);
326- BoardManager::enrollBoard(boardUrl, boardName, oldUrl);
328+ BoardDatabase db(boardUrl);
329+ db.enrollBoard(boardName, oldUrl);
327330
328331 loadExtBoard();
329332 refreshFavoriteBoards();
@@ -359,8 +362,8 @@ void BBSView::loadExtBoard()
359362 QString oldUrl;
360363 int type = Board_Unknown;
361364 if (list.size() == 3) type = list[ 2 ].toInt();
362- BoardManager::enrollBoard(
363- board_url, board_title, oldUrl, type);
365+ BoardDatabase db(board_url);
366+ db.enrollBoard(board_title, oldUrl, type);
364367 }
365368 }
366369 }
@@ -424,7 +427,8 @@ void BBSView::refreshFavoriteBoards()
424427
425428 for (it = boards.begin(); it != boards.end(); ++it) {
426429 QString boardUrl = (*it).prettyUrl();
427- QString boardName = BoardManager::boardName(boardUrl);
430+ BoardDatabase db(boardUrl);
431+ QString boardName = db.boardName();
428432
429433 new ListViewItem(m_favorites, QStringList() << boardName << boardUrl);
430434 }
@@ -435,7 +439,8 @@ void BBSView::loadBoard(QTreeWidgetItem* item)
435439 if (! item) return ;
436440
437441 QString boardName = item->text(0);
438- QString boardUrl = BoardManager::boardUrl(item->text(1));
442+ BoardDatabase db(item->text(1));
443+ QString boardUrl = db.boardUrl();
439444
440445 if (boardUrl.isEmpty()) {
441446 return ;
@@ -482,7 +487,8 @@ void BBSView::contextMenuEvent(QContextMenuEvent* e)
482487
483488 QString boardName = item->text(0);
484489 KUrl boardUrl = item->text(1);
485- KUrl boardUrl_upToDate = BoardManager::boardUrl(boardUrl);
490+ BoardDatabase db(boardUrl);
491+ KUrl boardUrl_upToDate = db.boardUrl();
486492 QClipboard* clipboard = QApplication::clipboard();
487493
488494 QAction *action = popup.exec(point);
@@ -573,7 +579,8 @@ void BBSView::mousePressEvent(QMouseEvent *e)
573579 if (!item) return;
574580
575581 QString boardName = item->text(0);
576- QString boardUrl = BoardManager::boardUrl(item->text(1));
582+ BoardDatabase db(item->text(1));
583+ QString boardUrl = db.boardUrl();
577584 if (boardUrl.isEmpty()) {
578585 item->setExpanded(!item->isExpanded());
579586 return ;
--- a/kita/src/boardtabwidget.cpp
+++ b/kita/src/boardtabwidget.cpp
@@ -22,7 +22,7 @@
2222 #include "boardview.h"
2323 #include "favoritelistview.h"
2424 #include "viewmediator.h"
25-#include "libkita/boardmanager.h"
25+#include "libkita/boarddatabase.h"
2626
2727 using namespace Kita;
2828
@@ -57,7 +57,8 @@ void BoardTabWidget::updateBoardView(const KUrl& datUrl)
5757 void BoardTabWidget::loadBoard(const KUrl& boardUrl)
5858 {
5959 BoardView * view = findView(boardUrl);
60- QString boardName = BoardManager::boardName(boardUrl);
60+ BoardDatabase db(boardUrl);
61+ QString boardName = db.boardName();
6162 if (!view) {
6263 view = createView(boardName);
6364 }
@@ -232,7 +233,8 @@ void SubjectTabBar::showPopupMenu(int idx, const QPoint& global)
232233 } else if (action == m_openBrowserAct) {
233234 KRun::runUrl(subjectView->boardUrl(), "text/html", this);
234235 } else if (action == m_copyTitleAct) {
235- QString cliptxt = BoardManager::boardName(subjectView->boardUrl())
236+ BoardDatabase db(subjectView->boardUrl());
237+ QString cliptxt = db.boardName()
236238 + '\n' + subjectView->boardUrl().prettyUrl();
237239 clipboard->setText(cliptxt , QClipboard::Clipboard);
238240 clipboard->setText(cliptxt , QClipboard::Selection);
--- a/kita/src/boardview.cpp
+++ b/kita/src/boardview.cpp
@@ -24,7 +24,7 @@
2424 #include "threadlistheaderview.h"
2525 #include "threadlistviewitem.h"
2626 #include "viewmediator.h"
27-#include "libkita/boardmanager.h"
27+#include "libkita/boarddatabase.h"
2828 #include "libkita/datmanager.h"
2929 #include "libkita/globalconfig.h"
3030 #include "libkita/kita_misc.h"
@@ -122,8 +122,8 @@ void BoardView::loadBoard(const KUrl& url, bool online)
122122 /* get list of pointers of Thread classes */
123123 QList<Thread*> oldLogList;
124124 QList<Thread*> threadList;
125- BoardManager::getThreadList(
126- m_boardUrl, m_showOldLogs, online, threadList, oldLogList);
125+ BoardDatabase db(m_boardUrl);
126+ db.getThreadList(m_showOldLogs, online, threadList, oldLogList);
127127
128128 // reset list
129129 subjectList->clearContents();
--- a/kita/src/favoritelistview.cpp
+++ b/kita/src/favoritelistview.cpp
@@ -21,7 +21,7 @@
2121
2222 #include "threadlistviewitem.h"
2323 #include "viewmediator.h"
24-#include "libkita/boardmanager.h"
24+#include "libkita/boarddatabase.h"
2525 #include "libkita/datmanager.h"
2626 #include "libkita/favoritethreads.h"
2727 #include "libkita/kita_misc.h"
@@ -77,8 +77,8 @@ void FavoriteListView::refresh()
7777 int viewPos = datManager.getViewPos();
7878 int resNum = datManager.getResNum();
7979
80- subjectList->item(i, ColumnBoard)
81- ->setText(BoardManager::boardName(datUrl));
80+ BoardDatabase db(datUrl);
81+ subjectList->item(i, ColumnBoard)->setText(db.boardName());
8282 subjectList->item(i, ColumnSubject)
8383 ->setText(datManager.threadName());
8484 subjectList->item(i, ColumnReadNum)
@@ -131,7 +131,8 @@ void FavoriteListView::reload()
131131
132132 for (int i = 0; FavoriteThreads::count() > i; i++) {
133133 QString datUrl = FavoriteThreads::getDatUrl(i);
134- QString boardUrl = BoardManager::boardUrl(datUrl);
134+ BoardDatabase db(datUrl);
135+ QString boardUrl = db.boardUrl();
135136 if (boardList.contains(boardUrl) == 0) {
136137 boardList.append(boardUrl);
137138 }
@@ -142,6 +143,7 @@ void FavoriteListView::reload()
142143 bool online = true;
143144 QList<Thread*> threadList;
144145 QList<Thread*> tmpList;
145- BoardManager::getThreadList((*it), false, online, threadList, tmpList);
146+ BoardDatabase db((*it));
147+ db.getThreadList(false, online, threadList, tmpList);
146148 }
147149 }
--- a/kita/src/htmlpart.cpp
+++ b/kita/src/htmlpart.cpp
@@ -30,7 +30,7 @@
3030 #include "viewmediator.h"
3131 #include "kitaui/htmlview.h"
3232 #include "libkita/abone.h"
33-#include "libkita/boardmanager.h"
33+#include "libkita/boarddatabase.h"
3434 #include "libkita/colorconfig.h"
3535 #include "libkita/datmanager.h"
3636 #include "libkita/globalconfig.h"
@@ -883,8 +883,10 @@ void HTMLPart::khtmlMousePressEvent(khtml::MousePressEvent* e)
883883 emit mousePressed(); /* to ThreadView to focus this view. */
884884
885885 KUrl kurl;
886- if (!e->url().string().isEmpty())
887- kurl = KUrl(BoardManager::boardUrl(m_datUrl), e->url().string());
886+ if (!e->url().string().isEmpty()) {
887+ BoardDatabase db(m_datUrl);
888+ kurl = KUrl(db.boardUrl(), e->url().string());
889+ }
888890
889891 m_pushctrl = m_pushmidbt = m_pushrightbt = false;
890892 if (e->qmouseEvent() ->button() & Qt::RightButton) m_pushrightbt = true;
@@ -1553,7 +1555,8 @@ void HTMLPart::slotOnUrl(const QString& url)
15531555 if (datUrl.host() != m_datUrl.host() || datUrl.path() != m_datUrl.path()) {
15541556
15551557 /* get board name */
1556- QString boardName = BoardManager::boardName(datUrl);
1558+ BoardDatabase db(datUrl);
1559+ QString boardName = db.boardName();
15571560 if (!boardName.isEmpty()) innerHTML += '[' + boardName + "] ";
15581561
15591562 /* If idx file of datURL is not read, thread name cannot be obtained.
--- a/kita/src/libkita/CMakeLists.txt
+++ b/kita/src/libkita/CMakeLists.txt
@@ -7,6 +7,7 @@ set(kita_LIB_SRCS
77 access.cpp
88 account.cpp
99 bbs.cpp
10+ boarddatabase.cpp
1011 boardmanager.cpp
1112 cache.cpp
1213 datinfo.cpp
--- a/kita/src/libkita/access.cpp
+++ b/kita/src/libkita/access.cpp
@@ -22,7 +22,7 @@
2222 #include <kio/slaveconfig.h>
2323
2424 #include "account.h"
25-#include "boardmanager.h"
25+#include "boarddatabase.h"
2626 #include "cache.h"
2727 #include "config.h"
2828 #include "flashcgi.h"
@@ -44,7 +44,8 @@ void Access::init()
4444 {
4545 m_readNum = 0;
4646 m_lastLine.clear();
47- m_bbstype = BoardManager::type(m_datUrl);
47+ BoardDatabase db(m_datUrl);
48+ m_bbstype = db.type();
4849 m_header = "HTTP/1.1 200 "; /* dummy header */
4950 m_dataSize = 0;
5051 m_threadData.clear();
--- /dev/null
+++ b/kita/src/libkita/boarddatabase.cpp
@@ -0,0 +1,704 @@
1+/***************************************************************************
2+* Copyright (C) 2010 by Kita Developers *
3+* ikemo@users.sourceforge.jp *
4+* *
5+* This program is free software; you can redistribute it and/or modify *
6+* it under the terms of the GNU General Public License as published by *
7+* the Free Software Foundation; either version 2 of the License, or *
8+* (at your option) any later version. *
9+***************************************************************************/
10+#include "boarddatabase.h"
11+
12+#include <QtCore/QDateTime>
13+#include <QtCore/QDir>
14+#include <QtCore/QTextCodec>
15+#include <QtCore/QTextStream>
16+
17+#include <kfilterdev.h>
18+#include <kio/netaccess.h>
19+#include <kio/slaveconfig.h>
20+
21+#include "cache.h"
22+#include "config.h"
23+#include "favoriteboards.h"
24+#include "favoritethreads.h"
25+#include "thread.h"
26+#include "threadindex.h"
27+#include "threadinfo.h"
28+
29+using namespace Kita;
30+
31+BoardDataList BoardDatabase::m_boardDataList;
32+QTextCodec* BoardDatabase::m_cp932Codec = 0;
33+QTextCodec* BoardDatabase::m_eucJpCodec = 0;
34+BoardData* BoardDatabase::m_previousBoardData = 0;
35+QString BoardDatabase::m_previousBoardUrl;
36+
37+BoardDatabase::BoardDatabase(const KUrl& url) : m_url(url)
38+{
39+}
40+
41+void BoardDatabase::setUrl(const KUrl& url)
42+{
43+ m_url = url;
44+}
45+
46+/* (hostname)/(rootPath)/(bbsPath)/ */ /* public */
47+QString BoardDatabase::boardUrl()
48+{
49+ BoardData * bdata = getBoardData();
50+ return (bdata == 0) ? QString() : bdata->basePath();
51+}
52+
53+/* public */
54+QStringList BoardDatabase::allBoardUrlList()
55+{
56+ QStringList urlList;
57+
58+ BoardData *data;
59+ foreach (data, m_boardDataList)
60+ urlList += data->basePath();
61+ return urlList;
62+}
63+
64+/* (hostname)/(rootPath) */ /* public */
65+QString BoardDatabase::boardRoot()
66+{
67+ BoardData * bdata = getBoardData();
68+ return (bdata == 0) ? QString() : bdata->hostName() + bdata->rootPath();
69+}
70+
71+/* (bbspath) */ /* public */
72+QString BoardDatabase::boardPath()
73+{
74+ BoardData * bdata = getBoardData();
75+ return (bdata == 0) ? QString() : bdata->bbsPath();
76+}
77+
78+/* (ext) */ /* public */
79+QString BoardDatabase::ext()
80+{
81+ BoardData * bdata = getBoardData();
82+ return (bdata == 0) ? QString() : bdata->ext();
83+}
84+
85+/* ID of board for writing */ /* public */
86+QString BoardDatabase::boardId()
87+{
88+ BoardData * bdata = getBoardData();
89+ return (bdata == 0) ? QString() : bdata->bbsPath().mid(1); /* remove "/" */
90+}
91+
92+/* (hostname)/(rootPath)/(bbsPath)/subject.txt */ /* public */
93+QString BoardDatabase::subjectUrl()
94+{
95+ BoardData * bdata = getBoardData();
96+ return (bdata == 0) ? QString() : bdata->basePath() + "subject.txt";
97+}
98+
99+/* public */
100+QString BoardDatabase::boardName()
101+{
102+ BoardData * bdata = getBoardData();
103+ return (bdata == 0) ? QString() : bdata->boardName();
104+}
105+
106+/* public */
107+int BoardDatabase::type()
108+{
109+ BoardData * bdata = getBoardData();
110+ return (bdata == 0) ? Board_Unknown : bdata->type();
111+}
112+
113+/*---------------------------*/
114+/* ThreadList */
115+
116+
117+/* get list of pointers of Thread classes. */
118+/*
119+ Input:
120+
121+ oldLogs: If true, search cache and get list of pointer of old threads.
122+ online: online or offline mode.
123+
124+ Output:
125+
126+ threadList: list of pointers of Thread classes.
127+ oldLogList: list of pointers of old threads.
128+
129+ */ /* public */
130+void BoardDatabase::getThreadList(
131+
132+ /* input */
133+ bool oldLogs,
134+ bool online,
135+
136+ /* output */
137+ QList<Thread*>& threadList,
138+ QList<Thread*>& oldLogList)
139+{
140+ threadList.clear();
141+ oldLogList.clear();
142+
143+ /* get all obtained threads list from cache */
144+ if (m_url.prettyUrl() == "http://virtual/obtained/") {
145+
146+ QStringList bbslist = allBoardUrlList();
147+
148+ /* search all cache dirs */
149+ QString thread;
150+ foreach (thread, bbslist) {
151+ getCachedThreadList(thread, threadList);
152+ }
153+
154+ return ;
155+ }
156+
157+ /*-------------------------*/
158+
159+ BoardData* bdata = getBoardData();
160+ if (bdata == 0) return ;
161+
162+ /* download subject.txt */
163+ if (online) {
164+
165+ /* make directory */
166+ Cache cache(m_url);
167+ QString cacheDir = cache.getDirPath();
168+ if (!QDir::root().mkpath(cacheDir)) return;
169+
170+ KIO::SlaveConfig::self() ->setConfigData("http",
171+ m_url.host() ,
172+ "UserAgent",
173+ QString("Monazilla/1.00 (Kita/%1)").arg(VERSION));
174+ QString subjectPath = cache.getSubjectPath();
175+ KIO::NetAccess::download(subjectUrl(), subjectPath, 0);
176+ }
177+
178+ /* open and read subject.txt */
179+ readSubjectTxt(bdata, threadList);
180+
181+ /* get old logs */
182+ if (oldLogs) {
183+
184+ QList<Thread*> tmpList;
185+ tmpList.clear();
186+ getCachedThreadList(m_url, tmpList);
187+
188+ for (int i = 0; i < tmpList.count(); i++) {
189+ if (threadList.contains(tmpList.at(i)) == 0)
190+ oldLogList.append(tmpList.at(i));
191+ }
192+ }
193+}
194+
195+/* read the cache dir & get the list of all threads. */ /* private */
196+void BoardDatabase::getCachedThreadList(const KUrl& url,
197+ QList<Thread*>& threadList)
198+{
199+ Cache cache(url);
200+ QString cacheDir = cache.getDirPath();
201+ QDir d(cacheDir);
202+ if (d.exists()) {
203+
204+ /* get all file names */
205+ QString ext = getBoardData(url)->ext();
206+ QString boardUrl = getBoardData(url)->basePath();
207+ QStringList filter('*' + ext);
208+ QStringList flist = d.entryList(filter);
209+ QString file;
210+ foreach (file, flist) {
211+ if (file.isEmpty()) continue;
212+
213+ QString datUrl = boardUrl + "dat/" + file;
214+
215+ /* read idx file */
216+ Thread* thread = Thread::getByUrlNew(datUrl);
217+ if (thread == 0) {
218+
219+ thread = Thread::getByUrl(datUrl);
220+ if (thread == 0)
221+ continue;
222+ ThreadIndex threadIndex(datUrl);
223+ threadIndex.loadIndex(thread, false);
224+ }
225+
226+ if (thread != 0)
227+ threadList.append(thread);
228+ }
229+ }
230+}
231+
232+/* open subject.txt and get list of Thread classes */ /* private */
233+bool BoardDatabase::readSubjectTxt(BoardData* bdata, QList<Thread*>& threadList)
234+{
235+ /* get all names of cached files to read idx. */
236+ QStringList cacheList;
237+ if (!bdata->readIdx()) {
238+ Cache cache(m_url);
239+ QString cacheDir = cache.getDirPath();
240+ QDir d(cacheDir);
241+ if (d.exists()) {
242+ QString ext = getBoardData()->ext();
243+ QStringList filter('*' + ext);
244+ cacheList = d.entryList(filter);
245+ }
246+ }
247+
248+ /* open subject.txt */
249+ Cache cache(m_url);
250+ QString subjectPath = cache.getSubjectPath();
251+ QIODevice * device = KFilterDev::deviceForFile(subjectPath, "application/x-gzip");
252+ if (!device->open(QIODevice::ReadOnly))
253+ return false;
254+
255+ QTextStream stream(device);
256+
257+ if (type() == Board_JBBS) {
258+ if (!m_eucJpCodec) m_eucJpCodec = QTextCodec::codecForName("eucJP");
259+ stream.setCodec(m_eucJpCodec);
260+ } else {
261+ if (!m_cp932Codec) m_cp932Codec = QTextCodec::codecForName("Shift-JIS");
262+ stream.setCodec(m_cp932Codec);
263+ }
264+
265+ QRegExp regexp;
266+ switch (type()) {
267+
268+ case Board_MachiBBS:
269+ case Board_JBBS:
270+ regexp.setPattern("(\\d+\\.cgi),(.*)\\((\\d+)\\)");
271+ break;
272+
273+ default:
274+ regexp.setPattern("(\\d+\\.dat)<>(.*)\\((\\d+)\\)");
275+ break;
276+ }
277+ QString line;
278+
279+ while (!(line = stream.readLine()).isEmpty()) {
280+ int pos = regexp.indexIn(line);
281+ if (pos != -1) {
282+ QString fname = regexp.cap(1);
283+ QString subject = regexp.cap(2);
284+ QString num = regexp.cap(3);
285+
286+ /* get pointer of Thread class */
287+ QString datUrl = boardUrl() + "dat/" + fname;
288+ Thread* thread = Thread::getByUrl(datUrl);
289+ ThreadIndex threadIndex(datUrl);
290+ if (threadList.indexOf(thread) == -1) {
291+ threadList.append(thread);
292+ }
293+
294+ /* set thread name */
295+ thread->setThreadName(subject);
296+
297+ /* load index file */
298+ if (!bdata->readIdx()) {
299+
300+ if (cacheList.contains(fname)) {
301+ threadIndex.loadIndex(thread, false);
302+ }
303+ }
304+
305+ /* update res num */
306+ int newNum = num.toInt();
307+ if (thread->readNum()) { /* cache exists */
308+ int oldNum = thread->resNum();
309+
310+ if (newNum > oldNum) {
311+ threadIndex.setResNum(newNum);
312+ }
313+ }
314+ thread->setResNum(newNum);
315+ }
316+ }
317+
318+ device->close();
319+ bdata->setReadIdx(true); /* never read idx files again */
320+
321+ return true;
322+}
323+
324+/*---------------------------*/
325+/* BoardData */
326+
327+/* reset all BoardData */ /* public */
328+void BoardDatabase::clearBoardData()
329+{
330+ BoardData *data;
331+ foreach (data, m_boardDataList)
332+ delete data;
333+
334+ m_boardDataList.clear();
335+ m_previousBoardData = 0;
336+ m_previousBoardUrl.clear();
337+}
338+
339+/**
340+ *
341+ * @param[in] board
342+ * @param[in] boardName
343+ * @param[in] type
344+ * @param[in] test
345+ *
346+ * @param[out] oldURL
347+ *
348+ * @retval Board_enrollEnrolled if board is already enrolled. oldURL is QString().
349+ * @retval Board_enrollNew if board is new board. oldURL is QString().
350+ * @retval Board_enrollMoved if board is moved. oldURL is old URL.
351+ *
352+ * @note board is NOT enrolled when board is moved.
353+ * To enroll new URL, call BoardDatabase::moveBoard().
354+ *
355+ * "int type" is type of board. It could be "Board_Unknown". See also parseBoardURL().
356+ *
357+ * If "bool test" is true, this function just checks if the board is enrolled (never enroll board).
358+ *
359+ */
360+/* public */
361+int BoardDatabase::enrollBoard(const QString& boardName, QString& oldUrl, int type, bool test)
362+{
363+ QString hostname;
364+ QString rootPath;
365+ QString delimiter;
366+ QString bbsPath;
367+ QString ext;
368+ type = parseBoardUrl(type, hostname, rootPath, delimiter, bbsPath, ext);
369+ oldUrl.clear();
370+
371+ if (type == Board_Unknown) return Board_enrollFailed;
372+
373+ /* check if the board is enrolled or moved. */
374+ BoardData *data;
375+ foreach (data, m_boardDataList) {
376+
377+ if (data->boardName() == boardName
378+ && data->type() == type
379+ && data->bbsPath() == bbsPath) {
380+
381+ if (data->hostName() == hostname
382+ && data->rootPath() == rootPath) { /* enrolled */
383+ return Board_enrollEnrolled;
384+ } else { /* moved */
385+ oldUrl = data->basePath();
386+ return Board_enrollMoved;
387+ }
388+ }
389+ }
390+
391+ /* test only */
392+ if (test)
393+ return Board_enrollNew;
394+
395+ /* enroll new board */
396+ BoardData* bdata = new BoardData(boardName, hostname, rootPath, delimiter, bbsPath, ext, type);
397+ m_boardDataList.append(bdata);
398+
399+ return Board_enrollNew;
400+}
401+
402+/* parse board URL */
403+/* return board type. */ /* private */
404+int BoardDatabase::parseBoardUrl(
405+
406+ /* input */
407+ int type, /* If type = Board_Unknown, type will be decided according to url. */
408+
409+ /* output */
410+ QString& hostname,
411+ QString& rootPath,
412+ QString& delimiter,
413+ QString& bbsPath,
414+ QString& ext)
415+{
416+ hostname = m_url.protocol() + "://" + m_url.host();
417+ rootPath.clear();
418+ delimiter.clear();
419+ bbsPath.clear();
420+ ext.clear();
421+
422+ /* decide type */
423+ if (type == Board_Unknown) {
424+
425+ if (m_url.host().contains("machi.to"))
426+ type = Board_MachiBBS;
427+ else if (m_url.host().contains("jbbs.livedoor.jp"))
428+ type = Board_JBBS;
429+ else
430+ type = Board_2ch;
431+ }
432+
433+ /* parse */
434+ switch (type) {
435+
436+ case Board_MachiBBS: /* MACHI : http:// *.machi.to/(bbsPath)/ */
437+
438+ delimiter = "/bbs/read.pl";
439+ bbsPath = m_url.fileName();
440+ ext = ".cgi";
441+ break;
442+
443+ case Board_JBBS: /* JBBS : http://jbbs.livedoor.jp/(bbsPath)/ */
444+
445+ delimiter = "/bbs/read.cgi";
446+ bbsPath = m_url.prettyUrl().remove(hostname);
447+ type = Board_JBBS;
448+ ext = ".cgi";
449+ break;
450+
451+ case Board_FlashCGI: /* test for Flash CGI/Mini Thread */
452+
453+ delimiter = "/test/read.cgi";
454+ bbsPath = m_url.fileName();
455+ rootPath = m_url.prettyUrl().remove(hostname + '/').remove(bbsPath + '/');
456+ if (rootPath.length() == 0)
457+ rootPath.clear();
458+ ext = ".dat";
459+ break;
460+
461+ default: /* 2ch : http://(hostname)/(rootPath)/(bbsPath)/ */
462+
463+ delimiter = "/test/read.cgi";
464+ bbsPath = m_url.fileName();
465+ rootPath = m_url.prettyUrl().remove(hostname + '/').remove(bbsPath + '/');
466+ if (rootPath.length() == 0)
467+ rootPath.clear();
468+ ext = ".dat";
469+ type = Board_2ch;
470+ break;
471+ }
472+
473+ /* For example, if bbsPath = "linux/", then m_bbsPath = "/linux" */
474+ const QRegExp exp("/$");
475+ rootPath.remove(exp);
476+ bbsPath.remove(exp);
477+ if (!rootPath.isEmpty() && rootPath.at(0) != '/')
478+ rootPath = '/' + rootPath;
479+ if (!bbsPath.isEmpty() && bbsPath.at(0) != '/')
480+ bbsPath = '/' + bbsPath;
481+
482+ return type;
483+}
484+
485+/* public */
486+bool BoardDatabase::isEnrolled()
487+{
488+ return getBoardData() != 0;
489+}
490+
491+/* public */
492+BoardData* BoardDatabase::getBoardData(const KUrl& url)
493+{
494+ if (url.isEmpty())
495+ return 0;
496+ QString urlstr = url.prettyUrl();
497+
498+ /* cache */
499+ if (m_previousBoardData != 0 && m_previousBoardUrl == urlstr)
500+ return m_previousBoardData;
501+
502+ BoardData *data;
503+ foreach (data, m_boardDataList) {
504+
505+ int count = data->keyBasePathList().count();
506+ for (int i = 0; i < count ; ++i) {
507+ if (urlstr.contains(data->keyBasePathList()[i])
508+ || urlstr.contains(data->keyCgiBasePathList()[i])) {
509+
510+ /* cache */
511+ m_previousBoardData = data;
512+ m_previousBoardUrl = urlstr;
513+
514+ return data;
515+ }
516+ }
517+ }
518+ return 0;
519+}
520+
521+/* public */
522+BoardData* BoardDatabase::getBoardData()
523+{
524+ return getBoardData(m_url);
525+}
526+
527+/*--------------------------------*/
528+/* BBSHISTORY */
529+
530+
531+/* load the bbs history file (BBSHISTORY), and create keys of Data Base. */
532+/* Before calling this, enroll the board by enrollBoard(). */
533+/*
534+ ex) If the host of board moved like :
535+
536+ http:://aaa.com -> http://bbb.com -> http://ccc.com -> http://ddd.com
537+
538+ then, BBSHISTORY is
539+
540+ http://ccc.com
541+ http://bbb.com
542+ http://aaa.com
543+
544+*/ /* public */
545+bool BoardDatabase::loadBBSHistory()
546+{
547+ BoardData * bdata = getBoardData();
548+ if (bdata == 0)
549+ return false;
550+
551+ QStringList keyHosts(bdata->hostName());
552+
553+ Cache cache(m_url);
554+ QFile file(cache.getBBSHistoryPath());
555+ if (file.open(QIODevice::ReadOnly)) {
556+
557+ QTextStream ts(&file);
558+
559+ QString line;
560+ while (!ts.atEnd()) {
561+
562+ line = ts.readLine();
563+ keyHosts += line;
564+ }
565+
566+ bdata->createKeys(keyHosts);
567+ file.close();
568+
569+ return true;
570+ }
571+
572+ return false;
573+}
574+
575+/* public */
576+bool BoardDatabase::moveBoard(const KUrl& fromUrl, const KUrl& toUrl)
577+{
578+ QString oldhost = fromUrl.protocol() + "://" + fromUrl.host();
579+ QString newhost = toUrl.protocol() + "://" + toUrl.host();
580+
581+ const QRegExp exp("/$");
582+ QString oldUrl = fromUrl.prettyUrl();
583+ QString newUrl = toUrl.prettyUrl();
584+ oldUrl.remove(exp);
585+ newUrl.remove(exp);
586+ oldUrl += '/';
587+ newUrl += '/';
588+
589+ if (oldUrl == newUrl) return false;
590+
591+ /* Is oldURL enrolled? */
592+ BoardData* bdata = getBoardData(oldUrl);
593+ if (bdata == 0) {
594+
595+ /* Is newURL enrolled? */
596+ bdata = getBoardData(newUrl);
597+ if (bdata == 0) return false;
598+ }
599+
600+
601+ /*---------------------------*/
602+ /* update BoardData */
603+
604+ /* get the path of old cache */
605+ bdata->setHostName(oldhost);
606+ QStringList keyHosts = bdata->keyHostList();
607+ keyHosts.removeOne(oldhost);
608+ keyHosts.prepend(oldhost);
609+ bdata->createKeys(keyHosts);
610+ Cache cache(bdata->basePath());
611+ QString oldCachePath = cache.getDirPath();
612+
613+ /* update URL */
614+ bdata->setHostName(newhost);
615+
616+ /* update keys */
617+ /* The order of keyHosts will be like this:
618+
619+ newhost
620+ oldhost
621+ foohost1
622+ foohost2
623+
624+ */
625+ keyHosts = bdata->keyHostList();
626+ keyHosts.removeOne(oldhost);
627+ keyHosts.prepend(oldhost);
628+ keyHosts.removeOne(newhost);
629+ keyHosts.prepend(newhost);
630+ bdata->createKeys(keyHosts);
631+
632+ /* reset BoardData */
633+ bdata->setReadIdx(false);
634+ bdata->setSettingLoaded(false);
635+
636+
637+ /*---------------------------*/
638+ /* move cache dir */
639+
640+ QDir qdir;
641+ if (! qdir.exists(oldCachePath)) return true;
642+
643+ /* mkdir new server dir */
644+ Cache newCache(bdata->basePath());
645+ QString newCachePath = Cache::baseDir() + newCache.serverDir();
646+ QDir::root().mkpath(newCachePath);
647+
648+ /* backup old dir */
649+ newCachePath += newCache.boardDir();
650+ if (qdir.exists (newCachePath)) {
651+ QString bkupPath = newCachePath;
652+ bkupPath.truncate(bkupPath.length() - 1); /* remove '/' */
653+ bkupPath +=
654+ '.' + QString::number(QDateTime::currentDateTime().toTime_t());
655+ qdir.rename(newCachePath, bkupPath);
656+ }
657+
658+ /* move cache dir */
659+ if (qdir.exists(oldCachePath)) {
660+ qdir.rename(oldCachePath, newCachePath);
661+ } else
662+ QDir::root().mkpath(newCachePath);
663+
664+ /* make old dir */
665+ if (! qdir.exists(oldCachePath)) {
666+ QDir::root().mkpath(oldCachePath);
667+ /* create BBS_MOVED */
668+ QString movedPath = oldCachePath + "/BBS_MOVED";
669+ QFile file(movedPath);
670+ if (file.open(QIODevice::WriteOnly)) {
671+ QTextStream stream(&file);
672+ stream << newUrl << endl;
673+ }
674+ file.close();
675+ }
676+
677+ /*---------------------------*/
678+ /* update BBSHISTRY */
679+
680+ Cache historyCache(bdata->basePath());
681+ QFile file(historyCache.getBBSHistoryPath());
682+ if (file.open(QIODevice::WriteOnly)) {
683+
684+ QTextStream ts(&file);
685+
686+ keyHosts.removeOne(newhost);
687+ QString host;
688+ foreach (host, keyHosts) {
689+ ts << host << endl;
690+ }
691+
692+ file.close();
693+ }
694+
695+
696+ /*---------------------------*/
697+ /* update other information */
698+ FavoriteThreads::replace(oldUrl, newUrl);
699+ Thread::replace(oldUrl, newUrl);
700+ ThreadInfo::replace(oldUrl, newUrl);
701+ FavoriteBoards::replace(oldUrl, newUrl);
702+
703+ return true;
704+}
--- /dev/null
+++ b/kita/src/libkita/boarddatabase.h
@@ -0,0 +1,74 @@
1+/***************************************************************************
2+* Copyright (C) 2010 by Kita Developers *
3+* ikemo@users.sourceforge.jp *
4+* *
5+* This program is free software; you can redistribute it and/or modify *
6+* it under the terms of the GNU General Public License as published by *
7+* the Free Software Foundation; either version 2 of the License, or *
8+* (at your option) any later version. *
9+***************************************************************************/
10+#ifndef KITABOARDDATABASE_H
11+#define KITABOARDDATABASE_H
12+
13+#include "boardmanager.h"
14+
15+namespace Kita {
16+ class Thread;
17+
18+ class KDE_EXPORT BoardDatabase
19+ {
20+ static BoardDataList m_boardDataList;
21+ static BoardData* m_previousBoardData;
22+ static QString m_previousBoardUrl;
23+ static QTextCodec* m_cp932Codec;
24+ static QTextCodec* m_eucJpCodec;
25+ KUrl m_url;
26+
27+ public:
28+ explicit BoardDatabase(const KUrl& url = KUrl());
29+
30+ void setUrl(const KUrl& url);
31+ QString boardUrl();
32+ QStringList allBoardUrlList();
33+ QString boardRoot();
34+ QString boardPath();
35+ QString ext();
36+ QString boardId();
37+ QString subjectUrl();
38+ QString boardName();
39+ int type();
40+
41+ /* ThreadList */
42+ void getThreadList(bool oldLogs, bool online,
43+ QList<Thread*>& threadList, QList<Thread*>& oldLogList);
44+
45+ /* BoardData */
46+ void clearBoardData();
47+ int enrollBoard(const QString& boardName, QString& oldUrl,
48+ int type = Board_Unknown, bool test = false);
49+ bool isEnrolled();
50+ BoardData* getBoardData(const KUrl& url);
51+ BoardData* getBoardData();
52+
53+ /* BBSHISTORY */
54+ bool loadBBSHistory();
55+ bool moveBoard(const KUrl& fromUrl, const KUrl& toUrl);
56+
57+ private:
58+ /* BoardData */
59+ int parseBoardUrl(int type, QString& hostname,
60+ QString& rootPath, QString& delimiter,
61+ QString& bbsPath, QString& ext);
62+
63+
64+ /* ThreadList */
65+ void getCachedThreadList(const KUrl& url, QList<Thread*>& threadList);
66+ bool readSubjectTxt(BoardData* bdata, QList<Thread*>& threadList);
67+
68+
69+ /* SETTING.TXT */
70+ BoardData* openSettingTxt();
71+ };
72+}
73+
74+#endif
--- a/kita/src/libkita/boardmanager.cpp
+++ b/kita/src/libkita/boardmanager.cpp
@@ -10,29 +10,8 @@
1010
1111 #include "boardmanager.h"
1212
13-#include <QtCore/QDateTime>
14-#include <QtCore/QDir>
15-#include <QtCore/QFile>
16-#include <QtCore/QRegExp>
17-#include <QtCore/QTextCodec>
18-#include <QtCore/QTextStream>
19-
20-#include <kfilterdev.h>
21-#include <kio/netaccess.h>
22-#include <kio/slaveconfig.h>
23-
24-#include "cache.h"
25-#include "config.h"
26-#include "favoriteboards.h"
27-#include "favoritethreads.h"
28-#include "kita_misc.h"
29-#include "thread.h"
30-#include "threadindex.h"
31-#include "threadinfo.h"
32-
3313 using namespace Kita;
3414
35-
3615 /*---------------------------------------------------------*/
3716
3817 /* BoardData */
@@ -282,701 +261,3 @@ const QStringList& BoardData::keyCgiBasePathList() const
282261 {
283262 return m_keyCgiBasePathList;
284263 }
285-
286-
287-
288-
289-/*---------------------------------------------------------------*/
290-/*---------------------------------------------------------------*/
291-/*---------------------------------------------------------------*/
292-
293-/* BoardManager */
294-
295-QTextCodec* BoardManager::m_cp932Codec = 0;
296-QTextCodec* BoardManager::m_eucJpCodec = 0;
297-BoardDataList BoardManager::m_boardDataList;
298-BoardData* BoardManager::m_previousBoardData = 0;
299-QString BoardManager::m_previousBoardUrl;
300-
301-
302-BoardManager::BoardManager()
303-{
304- clearBoardData();
305-}
306-
307-
308-BoardManager::~BoardManager()
309-{
310- clearBoardData();
311-}
312-
313-/* (hostname)/(rootPath)/(bbsPath)/ */ /* public */ /* static */
314-const QString BoardManager::boardUrl(const KUrl& url)
315-{
316- BoardData * bdata = getBoardData(url);
317- if (bdata == 0) return QString();
318-
319- return bdata->basePath();
320-}
321-
322-/* public */ /* static */
323-const QStringList BoardManager::allBoardUrlList()
324-{
325- QStringList urlList;
326- urlList.clear();
327-
328- for (BoardDataList::Iterator it = m_boardDataList.begin(); it != m_boardDataList.end(); ++it)
329- urlList += (*it) ->basePath();
330-
331- return urlList;
332-}
333-
334-/* (hostname)/(rootPath) */ /* public */ /* static */
335-const QString BoardManager::boardRoot(const KUrl& url)
336-{
337- BoardData * bdata = getBoardData(url);
338- if (bdata == 0) return QString();
339-
340- return bdata->hostName() + bdata->rootPath();
341-}
342-
343-/* (bbspath) */ /* public */ /* static */
344-const QString BoardManager::boardPath(const KUrl& url)
345-{
346- BoardData * bdata = getBoardData(url);
347- if (bdata == 0) return QString();
348-
349- return bdata->bbsPath();
350-}
351-
352-/* (ext) */ /* public */ /* static */
353-const QString BoardManager::ext(const KUrl& url)
354-{
355- BoardData * bdata = getBoardData(url);
356- if (bdata == 0) return QString();
357-
358- return bdata->ext();
359-}
360-
361-/* ID of board for writing */ /* public */ /* static */
362-const QString BoardManager::boardId(const KUrl& url)
363-{
364- BoardData * bdata = getBoardData(url);
365- if (bdata == 0) return QString();
366-
367- return bdata->bbsPath().mid(1); /* remove "/" */
368-}
369-
370-
371-/* (hostname)/(rootPath)/(bbsPath)/subject.txt */ /* public */ /* static */
372-const QString BoardManager::subjectUrl(const KUrl& url)
373-{
374- BoardData * bdata = getBoardData(url);
375- if (bdata == 0) return QString();
376-
377- return bdata->basePath() + "subject.txt";
378-}
379-
380-
381-/* public */ /* static */
382-const QString BoardManager::boardName(const KUrl& url)
383-{
384- BoardData * bdata = getBoardData(url);
385- if (bdata == 0) return QString();
386-
387- return bdata->boardName();
388-}
389-
390-
391-/* public */ /* static */
392-int BoardManager::type(const KUrl& url)
393-{
394- BoardData * bdata = getBoardData(url);
395- if (bdata == 0) return Board_Unknown;
396-
397- return bdata->type();
398-}
399-
400-
401-/*---------------------------*/
402-/* ThreadList */
403-
404-
405-/* get list of pointers of Thread classes. */
406-/*
407- Input:
408-
409- url: URL of board.
410- oldLogs: If true, search cache and get list of pointer of old threads.
411- online: online or offline mode.
412-
413- Output:
414-
415- threadList: list of pointers of Thread classes.
416- oldLogList: list of pointers of old threads.
417-
418- */ /* public */ /* static */
419-void BoardManager::getThreadList(
420-
421- /* input */
422- const KUrl& url,
423- bool oldLogs,
424- bool online,
425-
426- /* output */
427- QList<Thread*>& threadList,
428- QList<Thread*>& oldLogList)
429-{
430- threadList.clear();
431- oldLogList.clear();
432-
433- /* get all obtained threads list from cache */
434- if (url.prettyUrl() == "http://virtual/obtained/") {
435-
436- QStringList bbslist = allBoardUrlList();
437-
438- /* search all cache dirs */
439- for (QStringList::iterator it = bbslist.begin() ; it != bbslist.end(); ++it) {
440-
441- getCachedThreadList((*it), threadList);
442- }
443-
444- return ;
445- }
446-
447- /*-------------------------*/
448-
449- BoardData* bdata = getBoardData(url);
450- if (bdata == 0) return ;
451-
452- /* download subject.txt */
453- if (online) {
454-
455- /* make directory */
456- Cache cache(url);
457- QString cacheDir = cache.getDirPath();
458- if (!QDir::root().mkpath(cacheDir)) return;
459-
460- KIO::SlaveConfig::self() ->setConfigData("http",
461- url.host() ,
462- "UserAgent",
463- QString("Monazilla/1.00 (Kita/%1)").arg(VERSION));
464- QString subjectPath = cache.getSubjectPath();
465- KIO::NetAccess::download(subjectUrl(url), subjectPath, 0);
466- }
467-
468- /* open and read subject.txt */
469- readSubjectTxt(bdata, url, threadList);
470-
471- /* get old logs */
472- if (oldLogs) {
473-
474- QList<Thread*> tmpList;
475- tmpList.clear();
476- getCachedThreadList(url, tmpList);
477-
478- for (int i = 0; i < tmpList.count(); i++) {
479- if (threadList.contains(tmpList.at(i)) == 0)
480- oldLogList.append(tmpList.at(i));
481- }
482- }
483-}
484-
485-
486-/* read the cache dir & get the list of all threads. */ /* private */ /* static */
487-void BoardManager::getCachedThreadList(const KUrl& url, QList<Thread*>& threadList)
488-{
489- Cache cache(url);
490- QString cacheDir = cache.getDirPath();
491- QDir d(cacheDir);
492- if (d.exists()) {
493-
494- /* get all file names */
495- QString ext = BoardManager::getBoardData(url) ->ext();
496- QString boardUrl = BoardManager::getBoardData(url) ->basePath();
497- QStringList filter('*' + ext);
498- QStringList flist = d.entryList(filter);
499-
500- for (QStringList::iterator it = flist.begin(); it != flist.end(); ++it) {
501- if ((*it).isEmpty()) continue;
502-
503- QString datUrl = boardUrl + "dat/" + (*it);
504-
505- /* read idx file */
506- Thread* thread = Thread::getByUrlNew(datUrl);
507- if (thread == 0) {
508-
509- thread = Thread::getByUrl(datUrl);
510- if (thread == 0)
511- continue;
512- ThreadIndex threadIndex(datUrl);
513- threadIndex.loadIndex(thread, false);
514- }
515-
516- if (thread != 0) threadList.append(thread);
517- }
518- }
519-}
520-
521-
522-
523-/* open subject.txt and get list of Thread classes */ /* private */ /* static */
524-bool BoardManager::readSubjectTxt(BoardData* bdata, const KUrl& url, QList<Thread*>& threadList)
525-{
526- /* get all names of cached files to read idx. */
527- QStringList cacheList;
528- if (!bdata->readIdx()) {
529- Cache cache(url);
530- QString cacheDir = cache.getDirPath();
531- QDir d(cacheDir);
532- if (d.exists()) {
533- QString ext = BoardManager::getBoardData(url) ->ext();
534- QStringList filter('*' + ext);
535- cacheList = d.entryList(filter);
536- }
537- }
538-
539- /* open subject.txt */
540- Cache cache(url);
541- QString subjectPath = cache.getSubjectPath();
542- QIODevice * device = KFilterDev::deviceForFile(subjectPath, "application/x-gzip");
543- if (!device->open(QIODevice::ReadOnly)) return false;
544-
545- QTextStream stream(device);
546-
547- if (BoardManager::type(url) == Board_JBBS) {
548- if (!m_eucJpCodec) m_eucJpCodec = QTextCodec::codecForName("eucJP");
549- stream.setCodec(m_eucJpCodec);
550- } else {
551- if (!m_cp932Codec) m_cp932Codec = QTextCodec::codecForName("Shift-JIS");
552- stream.setCodec(m_cp932Codec);
553- }
554-
555- QRegExp regexp;
556- switch (BoardManager::type(url)) {
557-
558- case Board_MachiBBS:
559- case Board_JBBS:
560- regexp.setPattern("(\\d+\\.cgi),(.*)\\((\\d+)\\)");
561- break;
562-
563- default:
564- regexp.setPattern("(\\d+\\.dat)<>(.*)\\((\\d+)\\)");
565- break;
566- }
567- QString line;
568-
569- while (!(line = stream.readLine()).isEmpty()) {
570- int pos = regexp.indexIn(line);
571- if (pos != -1) {
572- QString fname = regexp.cap(1);
573- QString subject = regexp.cap(2);
574- QString num = regexp.cap(3);
575-
576- /* get pointer of Thread class */
577- QString datUrl = boardUrl(url) + "dat/" + fname;
578- Thread* thread = Thread::getByUrl(datUrl);
579- ThreadIndex threadIndex(datUrl);
580- if (threadList.indexOf(thread) == -1) {
581- threadList.append(thread);
582- }
583-
584- /* set thread name */
585- thread->setThreadName(subject);
586-
587- /* load index file */
588- if (!bdata->readIdx()) {
589-
590- if (cacheList.contains(fname)) {
591- threadIndex.loadIndex(thread, false);
592- }
593- }
594-
595- /* update res num */
596- int newNum = num.toInt();
597- if (thread->readNum()) { /* cache exists */
598- int oldNum = thread->resNum();
599-
600- if (newNum > oldNum) {
601- threadIndex.setResNum(newNum);
602- }
603- }
604- thread->setResNum(newNum);
605- }
606- }
607-
608- device->close();
609- bdata->setReadIdx(true); /* never read idx files again */
610-
611- return true;
612-}
613-
614-/*---------------------------*/
615-/* BoardData */
616-
617-/* reset all BoardData */ /* public */ /* static */
618-void BoardManager::clearBoardData()
619-{
620- for (BoardDataList::Iterator it = m_boardDataList.begin(); it != m_boardDataList.end(); ++it)
621- delete(*it);
622-
623- m_boardDataList.clear();
624- m_previousBoardData = 0;
625- m_previousBoardUrl.clear();
626-}
627-
628-/**
629- *
630- * @param[in] board
631- * @param[in] boardName
632- * @param[in] type
633- * @param[in] test
634- *
635- * @param[out] oldURL
636- *
637- * @retval Board_enrollEnrolled if board is already enrolled. oldURL is QString().
638- * @retval Board_enrollNew if board is new board. oldURL is QString().
639- * @retval Board_enrollMoved if board is moved. oldURL is old URL.
640- *
641- * @note board is NOT enrolled when board is moved.
642- * To enroll new URL, call BoardManager::moveBoard().
643- *
644- * "int type" is type of board. It could be "Board_Unknown". See also parseBoardURL().
645- *
646- * If "bool test" is true, this function just checks if the board is enrolled (never enroll board).
647- *
648- */
649-/* public */ /* static */
650-int BoardManager::enrollBoard(const KUrl& url, const QString& boardName, QString& oldUrl, int type, bool test)
651-{
652- QString hostname;
653- QString rootPath;
654- QString delimiter;
655- QString bbsPath;
656- QString ext;
657- type = parseBoardUrl(url, type, hostname, rootPath, delimiter, bbsPath, ext);
658- oldUrl.clear();
659-
660- if (type == Board_Unknown) return Board_enrollFailed;
661-
662- /* check if the board is enrolled or moved. */
663- for (BoardDataList::Iterator it = m_boardDataList.begin(); it != m_boardDataList.end(); ++it) {
664-
665- if ((*it) ->boardName() == boardName
666- && (*it) ->type() == type
667- && (*it) ->bbsPath() == bbsPath) {
668-
669- if ((*it) ->hostName() == hostname
670- && (*it) ->rootPath() == rootPath) { /* enrolled */
671- return Board_enrollEnrolled;
672- } else { /* moved */
673- oldUrl = (*it) ->basePath();
674- return Board_enrollMoved;
675- }
676- }
677- }
678-
679- /* test only */
680- if (test) return Board_enrollNew;
681-
682- /* enroll new board */
683- BoardData* bdata = new BoardData(boardName, hostname, rootPath, delimiter, bbsPath, ext, type);
684- m_boardDataList.append(bdata);
685-
686- return Board_enrollNew;
687-}
688-
689-
690-/* parse board URL */
691-/* return board type. */ /* private */ /* static */
692-int BoardManager::parseBoardUrl(
693-
694- /* input */
695- const KUrl& url,
696- int type, /* If type = Board_Unknown, type will be decided according to url. */
697-
698- /* output */
699- QString& hostname,
700- QString& rootPath,
701- QString& delimiter,
702- QString& bbsPath,
703- QString& ext)
704-{
705- hostname = url.protocol() + "://" + url.host();
706- rootPath.clear();
707- delimiter.clear();
708- bbsPath.clear();
709- ext.clear();
710-
711- /* decide type */
712- if (type == Board_Unknown) {
713-
714- if (url.host().contains("machi.to")) type = Board_MachiBBS;
715- else if (url.host().contains("jbbs.livedoor.jp")) type = Board_JBBS;
716- else type = Board_2ch;
717- }
718-
719- /* parse */
720- switch (type) {
721-
722- case Board_MachiBBS: /* MACHI : http:// *.machi.to/(bbsPath)/ */
723-
724- delimiter = "/bbs/read.pl";
725- bbsPath = url.fileName();
726- ext = ".cgi";
727- break;
728-
729- case Board_JBBS: /* JBBS : http://jbbs.livedoor.jp/(bbsPath)/ */
730-
731- delimiter = "/bbs/read.cgi";
732- bbsPath = url.prettyUrl().remove(hostname);
733- type = Board_JBBS;
734- ext = ".cgi";
735- break;
736-
737- case Board_FlashCGI: /* test for Flash CGI/Mini Thread */
738-
739- delimiter = "/test/read.cgi";
740- bbsPath = url.fileName();
741- rootPath = url.prettyUrl().remove(hostname + '/').remove(bbsPath + '/');
742- if (rootPath.length() == 0) rootPath.clear();
743- ext = ".dat";
744- break;
745-
746- default: /* 2ch : http://(hostname)/(rootPath)/(bbsPath)/ */
747-
748- delimiter = "/test/read.cgi";
749- bbsPath = url.fileName();
750- rootPath = url.prettyUrl().remove(hostname + '/').remove(bbsPath + '/');
751- if (rootPath.length() == 0) rootPath.clear();
752- ext = ".dat";
753- type = Board_2ch;
754- break;
755- }
756-
757- /* For example, if bbsPath = "linux/", then m_bbsPath = "/linux" */
758- const QRegExp exp("/$");
759- rootPath.remove(exp);
760- bbsPath.remove(exp);
761- if (!rootPath.isEmpty() && rootPath.at(0) != '/') rootPath = '/' + rootPath;
762- if (!bbsPath.isEmpty() && bbsPath.at(0) != '/') bbsPath = '/' + bbsPath;
763-
764- return type;
765-}
766-
767-
768-/* public */ /* static */
769-bool BoardManager::isEnrolled(const KUrl& url)
770-{
771- if (getBoardData(url) == 0) return false;
772- return true;
773-}
774-
775-
776-/* public */ /* static */
777-BoardData* BoardManager::getBoardData(const KUrl& url)
778-{
779- if (url.isEmpty()) return 0;
780- QString urlstr = url.prettyUrl();
781-
782- /* cache */
783- if (m_previousBoardData != 0 && m_previousBoardUrl == urlstr) return m_previousBoardData;
784-
785- for (BoardDataList::Iterator it = m_boardDataList.begin(); it != m_boardDataList.end(); ++it) {
786-
787- int count = (*it) ->keyBasePathList().count();
788- for (int i = 0; i < count ; ++i) {
789- if (urlstr.contains((*it) ->keyBasePathList() [ i ])
790- || urlstr.contains((*it) ->keyCgiBasePathList() [ i ])) {
791-
792- /* cache */
793- m_previousBoardData = (*it);
794- m_previousBoardUrl = urlstr;
795-
796- return (*it);
797- }
798- }
799- }
800-
801- return 0;
802-}
803-
804-
805-
806-/*--------------------------------*/
807-/* BBSHISTORY */
808-
809-
810-/* load the bbs history file (BBSHISTORY), and create keys of Data Base. */
811-/* Before calling this, enroll the board by enrollBoard(). */
812-/*
813- ex) If the host of board moved like :
814-
815- http:://aaa.com -> http://bbb.com -> http://ccc.com -> http://ddd.com
816-
817- then, BBSHISTORY is
818-
819- http://ccc.com
820- http://bbb.com
821- http://aaa.com
822-
823-*/ /* public */ /* static */
824-bool BoardManager::loadBBSHistory(const KUrl& url)
825-{
826- BoardData * bdata = getBoardData(url);
827- if (bdata == 0) return false;
828-
829- QStringList keyHosts(bdata->hostName());
830-
831- Cache cache(url);
832- QFile file(cache.getBBSHistoryPath());
833- if (file.open(QIODevice::ReadOnly)) {
834-
835- QTextStream ts(&file);
836-
837- QString line;
838- while (!ts.atEnd()) {
839-
840- line = ts.readLine();
841- keyHosts += line;
842- }
843-
844- bdata->createKeys(keyHosts);
845- file.close();
846-
847- return true;
848- }
849-
850- return false;
851-}
852-
853-
854-/* public */ /* static */
855-bool BoardManager::moveBoard(const KUrl& fromUrl, const KUrl& toUrl)
856-{
857- QString oldhost = fromUrl.protocol() + "://" + fromUrl.host();
858- QString newhost = toUrl.protocol() + "://" + toUrl.host();
859-
860- const QRegExp exp("/$");
861- QString oldUrl = fromUrl.prettyUrl();
862- QString newUrl = toUrl.prettyUrl();
863- oldUrl.remove(exp);
864- newUrl.remove(exp);
865- oldUrl += '/';
866- newUrl += '/';
867-
868- if (oldUrl == newUrl) return false;
869-
870- /* Is oldURL enrolled? */
871- BoardData* bdata = getBoardData(oldUrl);
872- if (bdata == 0) {
873-
874- /* Is newURL enrolled? */
875- bdata = getBoardData(newUrl);
876- if (bdata == 0) return false;
877- }
878-
879-
880- /*---------------------------*/
881- /* update BoardData */
882-
883- /* get the path of old cache */
884- bdata->setHostName(oldhost);
885- QStringList keyHosts = bdata->keyHostList();
886- keyHosts.removeOne(oldhost);
887- keyHosts.prepend(oldhost);
888- bdata->createKeys(keyHosts);
889- Cache cache(bdata->basePath());
890- QString oldCachePath = cache.getDirPath();
891-
892- /* update URL */
893- bdata->setHostName(newhost);
894-
895- /* update keys */
896- /* The order of keyHosts will be like this:
897-
898- newhost
899- oldhost
900- foohost1
901- foohost2
902-
903- */
904- keyHosts = bdata->keyHostList();
905- keyHosts.removeOne(oldhost);
906- keyHosts.prepend(oldhost);
907- keyHosts.removeOne(newhost);
908- keyHosts.prepend(newhost);
909- bdata->createKeys(keyHosts);
910-
911- /* reset BoardData */
912- bdata->setReadIdx(false);
913- bdata->setSettingLoaded(false);
914-
915-
916- /*---------------------------*/
917- /* move cache dir */
918-
919- QDir qdir;
920- if (! qdir.exists(oldCachePath)) return true;
921-
922- /* mkdir new server dir */
923- Cache newCache(bdata->basePath());
924- QString newCachePath = Cache::baseDir() + newCache.serverDir();
925- QDir::root().mkpath(newCachePath);
926-
927- /* backup old dir */
928- newCachePath += newCache.boardDir();
929- if (qdir.exists (newCachePath)) {
930- QString bkupPath = newCachePath;
931- bkupPath.truncate(bkupPath.length() - 1); /* remove '/' */
932- bkupPath +=
933- '.' + QString::number(QDateTime::currentDateTime().toTime_t());
934- qdir.rename(newCachePath, bkupPath);
935- }
936-
937- /* move cache dir */
938- if (qdir.exists(oldCachePath)) {
939- qdir.rename(oldCachePath, newCachePath);
940- } else
941- QDir::root().mkpath(newCachePath);
942-
943- /* make old dir */
944- if (! qdir.exists(oldCachePath)) {
945- QDir::root().mkpath(oldCachePath);
946- /* create BBS_MOVED */
947- QString movedPath = oldCachePath + "/BBS_MOVED";
948- QFile file(movedPath);
949- if (file.open(QIODevice::WriteOnly)) {
950- QTextStream stream(&file);
951- stream << newUrl << endl;
952- }
953- file.close();
954- }
955-
956- /*---------------------------*/
957- /* update BBSHISTRY */
958-
959- Cache historyCache(bdata->basePath());
960- QFile file(historyCache.getBBSHistoryPath());
961- if (file.open(QIODevice::WriteOnly)) {
962-
963- QTextStream ts(&file);
964-
965- keyHosts.removeOne(newhost);
966- for (QStringList::iterator it = keyHosts.begin() ; it != keyHosts.end(); ++it) {
967- ts << (*it) << endl;
968- }
969-
970- file.close();
971- }
972-
973-
974- /*---------------------------*/
975- /* update other information */
976- FavoriteThreads::replace(oldUrl, newUrl);
977- Thread::replace(oldUrl, newUrl);
978- ThreadInfo::replace(oldUrl, newUrl);
979- FavoriteBoards::replace(oldUrl, newUrl);
980-
981- return true;
982-}
--- a/kita/src/libkita/boardmanager.h
+++ b/kita/src/libkita/boardmanager.h
@@ -15,13 +15,8 @@
1515
1616 #include <kurl.h>
1717
18-class QSjisCodec;
19-class QEucJpCodec;
20-
2118 namespace Kita
2219 {
23- class Thread;
24-
2520 /* type of board */
2621 enum {
2722 Board_MachiBBS,
@@ -116,63 +111,6 @@ namespace Kita
116111 /*--------------------------------------*/
117112
118113 typedef QList<BoardData*> BoardDataList;
119-
120- /**
121- @author Hideki Ikemoto
122- */
123- class KDE_EXPORT BoardManager
124- {
125- static BoardDataList m_boardDataList;
126- static BoardData* m_previousBoardData; /* used in getBoardData() */
127- static QString m_previousBoardUrl; /* used in getBoardData() */
128- static QTextCodec* m_cp932Codec;
129- static QTextCodec* m_eucJpCodec;
130-
131- public:
132- BoardManager();
133- ~BoardManager();
134-
135- static const QString boardUrl(const KUrl& url);
136- static const QStringList allBoardUrlList();
137- static const QString boardRoot(const KUrl& url);
138- static const QString boardPath(const KUrl& url);
139- static const QString ext(const KUrl& url);
140- static const QString boardId(const KUrl& url);
141- static const QString subjectUrl(const KUrl& url);
142- static const QString boardName(const KUrl& url);
143- static int type(const KUrl& url);
144-
145- /* ThreadList */
146- static void getThreadList(const KUrl& url, bool oldLogs, bool online,
147- QList<Thread*>& threadList, QList<Thread*>& oldLogList);
148-
149- /* BoardData */
150- static void clearBoardData();
151- static int enrollBoard(const KUrl& url, const QString& boardName, QString& oldUrl,
152- int type = Board_Unknown, bool test = false);
153- static bool isEnrolled(const KUrl& url);
154- static BoardData* getBoardData(const KUrl& url);
155-
156- /* BBSHISTORY */
157- static bool loadBBSHistory(const KUrl& url);
158- static bool moveBoard(const KUrl& fromUrl, const KUrl& toUrl);
159-
160- private:
161-
162- /* BoardData */
163- static int parseBoardUrl(const KUrl& url, int type, QString& hostname,
164- QString& rootPath, QString& delimiter,
165- QString& bbsPath, QString& ext);
166-
167-
168- /* ThreadList */
169- static void getCachedThreadList(const KUrl& url, QList<Thread*>& threadList);
170- static bool readSubjectTxt(BoardData* bdata, const KUrl& url, QList<Thread*>& threadList);
171-
172-
173- /* SETTING.TXT */
174- static BoardData* openSettingTxt(const KUrl& url);
175- };
176114 }
177115
178116 #endif
--- a/kita/src/libkita/cache.cpp
+++ b/kita/src/libkita/cache.cpp
@@ -12,7 +12,7 @@
1212 #include <kglobal.h>
1313 #include <kstandarddirs.h>
1414
15-#include "boardmanager.h"
15+#include "boarddatabase.h"
1616
1717 using namespace Kita;
1818
@@ -33,7 +33,8 @@ QString Cache::baseDir()
3333 QString Cache::serverDir() const
3434 {
3535 /* Is board enrolled ? */
36- BoardData * bdata = BoardManager::getBoardData(m_url);
36+ BoardDatabase db(m_url);
37+ BoardData * bdata = db.getBoardData();
3738 if (bdata == 0) return QString();
3839
3940 QString root = bdata->hostName() + bdata->rootPath();
@@ -45,7 +46,8 @@ QString Cache::serverDir() const
4546 QString Cache::boardDir() const
4647 {
4748 /* Is board enrolled ? */
48- BoardData * bdata = BoardManager::getBoardData(m_url);
49+ BoardDatabase db(m_url);
50+ BoardData * bdata = db.getBoardData();
4951 if (bdata == 0) return QString();
5052
5153 QString bbs = bdata->bbsPath();
--- a/kita/src/libkita/datmanager.cpp
+++ b/kita/src/libkita/datmanager.cpp
@@ -16,7 +16,7 @@
1616 #include <QtCore/QRegExp>
1717 #include <QtCore/QStringList>
1818
19-#include "boardmanager.h"
19+#include "boarddatabase.h"
2020 #include "cache.h"
2121 #include "datinfo.h"
2222 #include "kita_misc.h"
@@ -383,7 +383,8 @@ bool DatManager::isThreadEnrolled() const
383383 /* public */
384384 bool DatManager::is2chThread() const
385385 {
386- if (BoardManager::type(m_url) != Board_2ch)
386+ BoardDatabase db(m_url);
387+ if (db.type() != Board_2ch)
387388 return false;
388389 if (m_datUrl.isEmpty())
389390 return false;
--- a/kita/src/libkita/favoriteboards.cpp
+++ b/kita/src/libkita/favoriteboards.cpp
@@ -11,7 +11,7 @@
1111
1212 #include <QtXml/QDomDocument>
1313
14-#include "boardmanager.h"
14+#include "boarddatabase.h"
1515
1616 using namespace Kita;
1717
@@ -111,7 +111,8 @@ QString FavoriteBoards::toXML()
111111 board.appendChild(urlElement);
112112 urlElement.appendChild(document.createTextNode(boardUrl));
113113
114- QString boardName = BoardManager::boardName(boardUrl);
114+ BoardDatabase db(boardUrl);
115+ QString boardName = db.boardName();
115116 QDomElement nameElement = document.createElement("name");
116117 board.appendChild(nameElement);
117118 nameElement.appendChild(document.createTextNode(boardName));
--- a/kita/src/libkita/favoritethreads.cpp
+++ b/kita/src/libkita/favoritethreads.cpp
@@ -13,7 +13,7 @@
1313 #include <QtCore/QList>
1414 #include <QtXml/QDomDocument>
1515
16-#include "boardmanager.h"
16+#include "boarddatabase.h"
1717 #include "datmanager.h"
1818 #include "kita_misc.h"
1919 #include "thread.h"
@@ -154,12 +154,14 @@ const QString FavoriteThreads::toXML() const
154154 QDomElement board = document.createElementNS("http://kita.sourceforge.jp/ns/board", "board");
155155 threadElement.appendChild(board);
156156
157- QString boardUrl = BoardManager::boardUrl(datUrl);
157+ BoardDatabase db(datUrl);
158+ QString boardUrl = db.boardUrl();
158159 QDomElement boardUrlElement = document.createElement("url");
159160 board.appendChild(boardUrlElement);
160161 boardUrlElement.appendChild(document.createTextNode(boardUrl));
161162
162- QString boardName = BoardManager::boardName(boardUrl);
163+ BoardDatabase db2(boardUrl);
164+ QString boardName = db2.boardName();
163165 QDomElement boardNameElement = document.createElement("name");
164166 board.appendChild(boardNameElement);
165167 boardNameElement.appendChild(document.createTextNode(boardName));
--- a/kita/src/libkita/kita_misc.cpp
+++ b/kita/src/libkita/kita_misc.cpp
@@ -15,7 +15,7 @@
1515
1616 #include <kurl.h>
1717
18-#include "boardmanager.h"
18+#include "boarddatabase.h"
1919 #include "datmanager.h"
2020 #include "kita-utf16.h"
2121
@@ -60,15 +60,16 @@ QString Kita::getThreadUrl(const KUrl& url)
6060
6161 QString Kita::getWriteUrl(const KUrl& m_datUrl)
6262 {
63- int m_bbstype = BoardManager::type(m_datUrl);
63+ BoardDatabase db(m_datUrl);
64+ int m_bbstype = db.type();
6465 QString m_bbscgi;
6566
6667 /* set path of bbs.cgi */
6768 switch (m_bbstype) {
6869
6970 case Board_JBBS: {
70- QString cgipath = BoardManager::boardRoot(m_datUrl)
71- + "/bbs/write.cgi/" + BoardManager::boardId(m_datUrl) + '/';
71+ QString cgipath = db.boardRoot()
72+ + "/bbs/write.cgi/" + db.boardId() + '/';
7273
7374 cgipath += DatManager(m_datUrl).threadId() + '/';
7475
@@ -78,7 +79,7 @@ QString Kita::getWriteUrl(const KUrl& m_datUrl)
7879 break;
7980
8081 case Board_MachiBBS: {
81- QString cgipath = BoardManager::boardRoot(m_datUrl)
82+ QString cgipath = db.boardRoot()
8283 + "/bbs/write.cgi";
8384 m_bbscgi = cgipath;
8485 }
@@ -87,7 +88,7 @@ QString Kita::getWriteUrl(const KUrl& m_datUrl)
8788
8889 default:
8990
90- m_bbscgi = BoardManager::boardRoot(m_datUrl) + "/test/bbs.cgi";
91+ m_bbscgi = db.boardRoot() + "/test/bbs.cgi";
9192 }
9293
9394 return m_bbscgi;
@@ -145,7 +146,8 @@ QString Kita::convertUrl(
145146 }
146147
147148 /* Is board enrolled ? */
148- BoardData* bdata = BoardManager::getBoardData(url);
149+ BoardDatabase db(url);
150+ BoardData* bdata = db.getBoardData();
149151 if (bdata == 0) return QString();
150152
151153 QString urlstr = url.prettyUrl();
--- a/kita/src/threadview.cpp
+++ b/kita/src/threadview.cpp
@@ -26,7 +26,7 @@
2626 #include "htmlpart.h"
2727 #include "threadtabwidget.h"
2828 #include "viewmediator.h"
29-#include "libkita/boardmanager.h"
29+#include "libkita/boarddatabase.h"
3030 #include "libkita/datmanager.h"
3131 #include "libkita/favoritethreads.h"
3232 #include "libkita/kita_misc.h"
@@ -420,11 +420,9 @@ void ThreadView::slotUpdateInfo()
420420 m_serverTime = datManager.getServerTime();
421421
422422 /* uptate information */
423- setSubjectLabel(BoardManager::boardName(m_datUrl),
424- datManager.threadName()
425- + QString(" (%1)")
426- .arg(datManager.getReadNum()),
427- BoardManager::boardUrl(m_datUrl));
423+ BoardDatabase db(m_datUrl);
424+ setSubjectLabel(db.boardName(), datManager.threadName() + QString(" (%1)")
425+ .arg(datManager.getReadNum()), db.boardUrl());
428426 updateButton();
429427
430428 gotoCombo->clear();
--- a/kita/src/writetabwidget.cpp
+++ b/kita/src/writetabwidget.cpp
@@ -17,7 +17,7 @@
1717 #include <kmessagebox.h>
1818
1919 #include "writeview.h"
20-#include "libkita/boardmanager.h"
20+#include "libkita/boarddatabase.h"
2121 #include "libkita/datmanager.h"
2222 #include "libkita/kita_misc.h"
2323
@@ -47,7 +47,8 @@ void WriteTabWidget::openWriteView(const KUrl& url,
4747 const QString& resStr, const QString& subject)
4848 {
4949 // TODO: machiBBS kakiko support.
50- if (BoardManager::type(url) == Board_MachiBBS) {
50+ BoardDatabase db(url);
51+ if (db.type() == Board_MachiBBS) {
5152 // KMessageBox::sorry(this,
5253 // i18n("Can't write to machi BBS in this version."),
5354 // "<(_ _)>");
--- a/kita/src/writeview.cpp
+++ b/kita/src/writeview.cpp
@@ -22,7 +22,7 @@
2222 #include "libkita/account.h"
2323 #include "libkita/accountconfig.h"
2424 #include "libkita/asciiart.h"
25-#include "libkita/boardmanager.h"
25+#include "libkita/boarddatabase.h"
2626 #include "libkita/datmanager.h"
2727 #include "libkita/flashcgi.h"
2828 #include "libkita/globalconfig.h"
@@ -49,7 +49,8 @@ WriteView::WriteView(WriteTabWidget* parent, const KUrl& url)
4949 {
5050 setupUi(this);
5151 m_datUrl = getDatUrl(url);
52- m_bbstype = BoardManager::type(m_datUrl);
52+ BoardDatabase db(m_datUrl);
53+ m_bbstype = db.type();
5354 m_bbscgi = getWriteUrl(m_datUrl);
5455 m_parent = parent;
5556
@@ -79,7 +80,8 @@ void WriteView::initUI()
7980 bodyText->setFont(font);
8081 bodyText->setTabChangesFocus(true);
8182
82- boardNameLabel->setText(BoardManager::boardName(m_datUrl));
83+ BoardDatabase db(m_datUrl);
84+ boardNameLabel->setText(db.boardName());
8385
8486 // setup name field.
8587 nameLine->setText(WriteConfig::defaultName());
@@ -154,12 +156,14 @@ const QString WriteView::threadName() const
154156
155157 const QString WriteView::boardId() const
156158 {
157- return BoardManager::boardId(m_datUrl);
159+ BoardDatabase db(m_datUrl);
160+ return db.boardId();
158161 }
159162
160163 const QString WriteView::boardName() const
161164 {
162- return BoardManager::boardName(m_datUrl);
165+ BoardDatabase db(m_datUrl);
166+ return db.boardName();
163167 }
164168 /* public slot */ /* virtual */
165169 void WriteView::setFocus()
@@ -215,7 +219,8 @@ void WriteView::slotPostMessage()
215219 QString postStr = buildPostMessage();
216220
217221 /* referrer */
218- QString refStr = BoardManager::boardUrl(m_datUrl);
222+ BoardDatabase db(m_datUrl);
223+ QString refStr = db.boardUrl();
219224
220225 m_array.clear();
221226
Show on old repository browser