OSDN Git Service

>>596
[kita/kita.git] / kita / src / libkita / datmanager.cpp
1 /***************************************************************************
2 *   Copyright (C) 2004 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
11 /* DatManager manages all information about thread */
12
13 #include <qobject.h>
14 #include <qmutex.h>
15 #include <qstringlist.h>
16 #include <qregexp.h>
17 #include <qfile.h>
18
19 #include "thread.h"
20 #include "threadinfo.h"
21 #include "datmanager.h"
22 #include "datinfo.h"
23 #include "cache.h"
24 #include "kita_misc.h"
25 #include "kita-utf8.h"
26 #include "kita-utf16.h"
27 #include "threadindex.h"
28 #include "boardmanager.h"
29
30 using namespace Kita;
31
32 #define DMANAGER_MAXQUEUE 16
33
34 DatInfoList DatManager::m_datInfoList;
35 QMutex DatManager::m_mutex;
36
37
38 /*-----------------------------------------------------------------------*/
39
40
41 /* create DatInfo explicitly.                    */
42 /* Usually, DatInfo is NOT created
43    if cache does not exist( i.e. ReadNum == 0 ). */ /* public */
44 bool DatManager::createDatInfo( const KURL& url )
45 {
46     if( getDatInfo( url,
47                     FALSE /* don't check the existence of cache */
48             ) == NULL ) return FALSE;
49     return TRUE;
50 }
51
52
53 /* get pointer of DatInfo */
54
55 /*    !!!  NOTICE  !!!   */
56 /* It is very dangerous to access to DatInfo directly. */
57 /* Usually, access to it through DatManager.           */ /* public */
58 DatInfo * DatManager::getDatInfoPointer( const KURL& url )
59 {
60     return getDatInfo( url );
61 }
62
63
64 /*------------------------------------------------------------------------*/
65
66
67 /* This function searches instance of DatInfo in m_datInfoList.
68
69    If cache exists, create DatInfo and return its pointer.
70
71    If checkCached == TRUE and cache does not exist, return NULL.
72
73    If checkCached == FALSE and cache does not exist,
74    create DatInfo and return its pointer anyway.
75
76    see also DatManager::searchDatInfo() and DatManager::createDatInfo() */ /* private */
77
78 DatInfo* DatManager::getDatInfo( const KURL& url, bool checkCached )
79 {
80     /* search */
81     DatInfo* datInfo = searchDatInfo( url );
82     if( datInfo != NULL ) return datInfo;
83
84     /* create and enroll instance */
85     return enrollDatInfo( url, checkCached );
86 }
87
88
89 /* This function just searches instance of DatInfo specified by datURL
90    without creating instance.  */ /* private */
91 DatInfo* DatManager::searchDatInfo( const KURL& url )
92 {
93     QMutexLocker locker( &m_mutex );
94     
95     KURL datURL = Kita::getDatURL( url );
96     if ( datURL.isEmpty() ) return NULL; /* This url is not enrolled in BoardManager. */
97     if ( m_datInfoList.count() == 0 ) return NULL;
98
99     int i = 0;
100     DatInfoList::Iterator it;
101     DatInfo* datInfo;
102     
103     for ( it = m_datInfoList.begin(); it != m_datInfoList.end(); ++it, i++ ) {
104
105         datInfo = ( *it );
106
107         if ( datURL == datInfo->url() ) {
108
109             /* LRU */
110             if ( i ) {
111                 m_datInfoList.remove( it );
112                 m_datInfoList.prepend( datInfo );
113             }
114
115             return datInfo;
116         }
117     }
118
119     return NULL;
120 }
121
122
123 /* create and enroll the instance of DatInfo and delete old instances. 
124    Note that DatInfo::DatInfo() opens cached data and reads it. */  /* private */
125 DatInfo* DatManager::enrollDatInfo( const KURL& url, bool checkCached )
126 {
127     QMutexLocker locker( &m_mutex );
128     
129     KURL datURL = Kita::getDatURL( url );
130     if( datURL.isEmpty() ) return NULL; /* This url is not enrolled in BoardManager. */
131
132     /* create DatInfo & read cached data */
133     DatInfo* datInfo = new DatInfo( datURL );
134
135     /* Does cache exist ? */
136     /* If cache does not exist, delete DatInfo here. */
137     if( checkCached && datInfo->getReadNum() == 0 ){
138         delete datInfo;
139         return NULL;
140     }
141
142     m_datInfoList.prepend( datInfo );
143
144     /* delete the all old instances ( LRU algorithm )*/
145     if ( m_datInfoList.count() > DMANAGER_MAXQUEUE ) {
146
147         DatInfoList::Iterator it;
148         for ( it = m_datInfoList.at( DMANAGER_MAXQUEUE ); it != m_datInfoList.end(); ++it ){
149
150             if( ( *it ) == NULL ) continue;
151             DatInfo* deleteInfo = ( *it );
152             
153             if ( ! deleteInfo->isLocked() ){
154                 m_datInfoList.remove( it );
155                 --it;
156                 deleteInfo->wait(); /* wait until DatInfo::m_mutex is released. */
157                 delete deleteInfo;
158             }
159         }
160     }
161
162     return datInfo;
163 }
164
165
166 /* public */
167 void DatManager::deleteAllDatInfo()
168 {
169     DatInfoList::Iterator it;
170     for ( it = m_datInfoList.begin(); it != m_datInfoList.end(); ++it ){
171
172         if( ( *it ) == NULL ) continue;
173         ( *it )->wait();
174         delete ( *it );
175     }
176 }
177
178
179
180 /*-------------------------------------------------------------*/
181
182
183
184 /* update cache */   /* public */
185 bool DatManager::updateCache( const KURL& url , const QObject* parent )
186 {
187     DatInfo * datInfo = getDatInfo( url );
188     if ( datInfo == NULL ) return FALSE;
189
190     return datInfo->updateCache( parent );
191 }
192
193
194 /* public */
195 int DatManager::getResponseCode( const KURL& url )
196 {
197     DatInfo * datInfo = getDatInfo( url );
198     if ( datInfo == NULL ) return 0;
199
200     return datInfo->getResponseCode();
201 }
202
203 /* public */
204 int DatManager::getServerTime( const KURL& url )
205 {
206     DatInfo * datInfo = getDatInfo( url );
207     if ( datInfo == NULL ) return 0;
208
209     return datInfo->getServerTime();
210 }
211
212
213 /* public */
214 bool DatManager::deleteCache( const KURL& url )
215 {
216     KURL datURL = Kita::getDatURL( url );
217     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
218     if( thread == NULL ) return FALSE;
219     if( thread->readNum() == 0 ) return FALSE;
220
221     /* init DatInfo */
222     DatInfo * datInfo = searchDatInfo( datURL );
223     if( datInfo ){
224         if( !datInfo->deleteCache() ) return FALSE;
225     }
226
227     /* reset readNum & veiwPos */
228     thread->setReadNum( 0 );
229     thread->setViewPos( 0 );
230
231     /* delete cache */
232     QString cachePath = Kita::Cache::getPath( datURL );
233     QString indexPath = Kita::Cache::getIndexPath( datURL );
234     QFile::remove( indexPath );
235     QFile::remove( cachePath );
236
237     /* delete log from "cache" */
238     KitaThreadInfo::removeThreadInfo( datURL.prettyURL() );
239     return TRUE;
240 }
241
242
243 /* public */
244 bool DatManager::isLoadingNow( const KURL& url )
245 {
246     DatInfo * datInfo = searchDatInfo( url );
247     if ( datInfo == NULL ) return FALSE;
248
249     return datInfo->isLoadingNow();
250 }
251
252
253 /* public */
254 void DatManager::stopLoading( const KURL& url )
255 {
256     DatInfo * datInfo = searchDatInfo( url );
257     if ( datInfo == NULL ) return ;
258
259     return datInfo->stopLoading();
260 }
261
262
263
264 /*----------------------*/
265 /* lock, unlock DatInfo */
266
267 /* public */
268 void DatManager::lock( const KURL& url )
269 {
270     DatInfo * datInfo = getDatInfo( url );
271     if( datInfo == NULL ) return;
272
273     datInfo->lock ();
274 }
275
276 /* public */
277 void DatManager::unlock( const KURL& url )
278 {
279     DatInfo * datInfo = searchDatInfo( url );
280     if ( datInfo == NULL ) return ;
281
282     datInfo->unlock();
283 }
284
285
286 /*--------------------------------------*/
287 /* string data */
288
289 /* public */
290 const QString& DatManager::getRawDat( const KURL& url )
291 {
292     DatInfo * datInfo = getDatInfo( url );
293     if ( datInfo == NULL ) return QString::null;
294
295     return datInfo->getRawDat();
296 }
297
298
299 /* public */
300 const QString& DatManager::getDat( const KURL& url, int num )
301 {
302     DatInfo * datInfo = getDatInfo( url );
303     if ( datInfo == NULL ) return QString::null;
304
305     return datInfo->getDat( num );
306 }
307
308
309
310 /* public */
311 const QString& DatManager::getId( const KURL& url, int num )
312 {
313     DatInfo * datInfo = getDatInfo( url );
314     if ( datInfo == NULL ) return QString::null;
315
316     return datInfo->getId( num );
317 }
318
319
320 /* public */
321 const QString& DatManager::getName( const KURL& url, int num )
322 {
323     DatInfo * datInfo = getDatInfo( url );
324     if ( datInfo == NULL ) return QString::null;
325
326     return datInfo->getName( num );
327 }
328
329
330 /* public */
331 const QString& DatManager::getBody( const KURL& url, int num )
332 {
333     DatInfo * datInfo = getDatInfo( url );
334     if ( datInfo == NULL ) return QString::null;
335
336     return datInfo->getBody( num );
337 }
338
339
340 /* public */
341 QString DatManager::getPlainName( const KURL& url, int num )
342 {
343     DatInfo * datInfo = getDatInfo( url );
344     if ( datInfo == NULL ) return QString::null;
345
346     return datInfo->getPlainName( num );
347 }
348
349
350 /* public */
351 QString DatManager::getPlainBody( const KURL& url, int num )
352 {
353     DatInfo * datInfo = getDatInfo( url );
354     if ( datInfo == NULL ) return QString::null;
355
356     return datInfo->getPlainBody( num );
357 }
358
359
360 /* public */
361 QString DatManager::getPlainTitle( const KURL& url, int num )
362 {
363     DatInfo * datInfo = getDatInfo( url );
364     if ( datInfo == NULL ) return QString::null;
365
366     return datInfo->getPlainTitle( num );
367 }
368
369
370 /* get name (i.e. subject ) of thread from URL of dat file. */ /* public */
371 const QString DatManager::threadName( const KURL& url )
372 {
373     KURL datURL = Kita::getDatURL( url );
374     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
375     if( thread != NULL ) return thread->threadName();
376
377     return QString::null;
378 }
379
380
381 /* public */
382 const QString DatManager::threadID( const KURL& url )
383 {
384     KURL datURL = Kita::getDatURL( url );
385     return datURL.filename().section( ".", 0, 0 );
386 }
387
388
389 const QString DatManager::getCachePath( const KURL& url )
390 {
391     return Kita::Cache::getPath( url );
392 }
393
394 const QString DatManager::getCacheIndexPath( const KURL& url )
395 {
396     return Kita::Cache::getIndexPath( url );
397 }
398
399 /*---------------------------------------*/
400 /* HTML data */
401
402 /* public */
403 QString DatManager::getHtml( const KURL& url, int startnum, int endnum )
404 {
405     DatInfo * datInfo = getDatInfo( url );
406     if ( datInfo == NULL ) return QString::null;
407
408     return datInfo->getHtml( startnum, endnum );
409 }
410
411
412
413 /* public */
414 QString DatManager::getHtmlByID( const KURL& url, const QString& strid, int &count )
415 {
416     DatInfo* datInfo = getDatInfo( url );
417     if ( datInfo == NULL ) return QString::null;
418
419     return datInfo->getHtmlByID( strid, count );
420 }
421
422
423
424 /* Get HTML document of res tree.*/ /* public */
425 QString DatManager::getTreeByRes( const KURL& url, const int rootnum, int &count )
426 {
427     DatInfo* datInfo = getDatInfo( url );
428     if ( datInfo == NULL ) return QString::null;
429
430     return datInfo->getTreeByRes( rootnum, count );
431 }
432
433 /* Get HTML document of reverse res tree.*/ /* public */
434 QString DatManager::getTreeByResReverse( const KURL& url, const int rootnum, int &count )
435 {
436     DatInfo* datInfo = getDatInfo( url );
437     if ( datInfo == NULL ) return QString::null;
438
439     return datInfo->getTreeByResReverse( rootnum, count );
440 }
441
442 /* Get DOM element */ /* public */
443 bool DatManager::getDomElement( const KURL& url, int num, DOM::HTMLDocument& hdoc, DOM::Element& retelm )
444 {
445     DatInfo* datInfo = getDatInfo( url );
446     if ( datInfo == NULL ) return FALSE;
447
448     return datInfo->getDomElement( num, hdoc, retelm );
449 }
450
451
452 /* public */
453 int DatManager::getResNum( const KURL& url )
454 {
455     KURL datURL = Kita::getDatURL( url );
456     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
457     if( thread != NULL ) return thread->resNum();
458
459     return 0;
460 }
461
462
463 /* public */
464 int DatManager::getReadNum( const KURL& url )
465 {
466     KURL datURL = Kita::getDatURL( url );
467     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
468     if( thread != NULL ) return thread->readNum();
469
470     return 0;
471 }
472
473
474 /* public */
475 int DatManager::getViewPos( const KURL& url )
476 {
477     KURL datURL = Kita::getDatURL( url );
478     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
479     if( thread != NULL ) return thread->viewPos();
480
481     return 0;
482 }
483
484
485 /* public */
486 void DatManager::setViewPos( const KURL& url , int num )
487 {
488     KURL datURL = Kita::getDatURL( url );
489     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
490     if( thread != NULL ) thread->setViewPos( num );
491
492     /* save idx */
493     Kita::ThreadIndex::setViewPos( url, num );
494
495     /* save "cache" */
496     KitaThreadInfo::setReadNum( datURL.prettyURL(), num );
497 }
498
499
500 /* public */
501 int DatManager::getDatSize( const KURL& url )
502 {
503     DatInfo * datInfo = getDatInfo( url );
504     if ( datInfo == NULL ) return 0;
505
506     return datInfo->getDatSize();
507 }
508
509 /* get number of responses which have same ID. */ /* public */
510 int DatManager::getNumByID( const KURL& url, const QString& strid )
511 {
512     DatInfo * datInfo = getDatInfo( url );
513     if ( datInfo == NULL ) return 0;
514
515     return datInfo->getNumByID( strid );
516 }
517
518
519 /* public */
520 bool DatManager::isThreadEnrolled( const KURL& url )
521 {
522     if( Kita::getDatURL( url ).isEmpty() ) return FALSE;
523
524     return TRUE;
525 }
526
527
528 /* public */
529 bool DatManager::is2chThread( const KURL& url )
530 {
531     if( BoardManager::type( url ) != Board_2ch ) return FALSE;
532     if( Kita::getDatURL( url ).isEmpty() ) return FALSE;
533     
534     QRegExp url_2ch( ".*\\.2ch\\.net" );
535     QRegExp url_bbspink( ".*\\.bbspink\\.com" );
536     
537     if ( url_2ch.search( url.host() ) != -1
538          || url_bbspink.search( url.host() ) != -1 ) return TRUE;
539     
540     return FALSE;
541 }
542
543
544 /* public */
545 bool DatManager::isResValid( const KURL& url, int num )
546 {
547     DatInfo * datInfo = getDatInfo( url );
548     if ( datInfo == NULL ) return FALSE;
549
550     return datInfo->isResValid( num );
551 }
552
553
554 /* public */
555 bool DatManager::isBroken( const KURL& url )
556 {
557     DatInfo * datInfo = getDatInfo( url );
558     if ( datInfo == NULL ) return FALSE;
559
560     return datInfo->isBroken();
561 }
562
563 /* public */
564 bool DatManager::isResBroken( const KURL& url, int num )
565 {
566     DatInfo * datInfo = getDatInfo( url );
567     if ( datInfo == NULL ) return FALSE;
568
569     return datInfo->isResBroken( num );
570 }
571
572
573
574 /* check if ID == strid  */ /* public */
575 bool DatManager::checkID( const KURL& url, const QString& strid, int num )
576 {
577     DatInfo* datInfo = getDatInfo( url );
578     if ( datInfo == NULL ) return FALSE;
579
580     return datInfo->checkID( strid, num );
581 }
582
583
584 /* check if keywords are included */ /* public */
585 bool DatManager::checkWord( const KURL& url,
586                             QStringList& strlist, int num,
587                             bool checkOR /* AND or OR search */
588                           )
589 {
590     DatInfo* datInfo = getDatInfo( url );
591     if ( datInfo == NULL ) return FALSE;
592
593     return datInfo->checkWord( strlist, num, checkOR );
594 }
595
596
597 /* public */
598 bool DatManager::isMarked( const KURL& url, int num )
599 {
600     DatInfo * datInfo = getDatInfo( url );
601     if ( datInfo == NULL ) return FALSE;
602
603     return datInfo->isMarked( num );
604 }
605
606
607 /* public */
608 void DatManager::setMark( const KURL& url, int num, bool mark )
609 {
610     DatInfo * datInfo = getDatInfo( url );
611     if ( datInfo == NULL ) return ;
612
613     datInfo->setMark( num, mark );
614 }
615
616
617 /* public */
618 bool DatManager::checkAbone( const KURL& url, int num )
619 {
620     DatInfo* datInfo = getDatInfo( url );
621     if ( datInfo == NULL ) return FALSE;
622
623     return datInfo->checkAbone( num );
624 }
625
626
627 /* public */
628 void DatManager::resetAbone( const KURL& url )
629 {
630     DatInfo* datInfo = getDatInfo( url );
631     if ( datInfo == NULL ) return ;
632
633     datInfo->resetAbone();
634 }
635
636
637 /* check if the thread is shown on the main thread tab. */ /* public */
638 bool DatManager::isMainThreadOpened( const KURL& url )
639 {
640     KURL datURL = Kita::getDatURL( url ).prettyURL();
641     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
642     if( thread == NULL ) return FALSE;
643
644     return thread->isOpened();
645 }
646
647 void DatManager::setMainThreadOpened( const KURL& url, bool isOpened )
648 {
649     KURL datURL = Kita::getDatURL( url ).prettyURL();
650     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
651     if( thread != NULL ) thread->setIsOpened( isOpened );
652 }
653
654
655 /*--------------------------*/
656 /* obsolete */
657
658 /* public */
659 const QString DatManager::threadURL( const KURL& url )
660 {
661     return Kita::getThreadURL( url );
662 }
663