OSDN Git Service

refactoring.
[kita/kita.git] / kita / src / libkita / datmanager.cpp
1 /**************************************************************************
2 *   Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421                 *
3 *   ikemo@wakaba.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 #include <qobject.h>
12 #include <qmutex.h>
13 #include <qstringlist.h>
14 #include <qregexp.h>
15
16 #include "thread.h"
17 #include "threadinfo.h"
18 #include "parsemisc.h"
19 #include "datmanager.h"
20 #include "datinfo.h"
21 #include "board.h"
22 #include "cache.h"
23 #include "kita_misc.h"
24 #include "kita-utf8.h"
25 #include "kita-utf16.h"
26
27 using namespace Kita;
28
29 #define DMANAGER_MAXQUEUE 16
30
31 /*-------------------------------------------------*/
32 /* DatManager manages all information about *.dat. */
33
34 DatInfoList DatManager::m_datInfo;
35 QMutex DatManager::m_mutex;
36
37 /* This function searches instance of DatInfo specified by url.
38    If instance does not exist, create instance.  */  /* private */
39 DatInfo* DatManager::getDatInfo( const KURL& url )
40 {
41     if ( url.isEmpty() ) {
42         return NULL;
43     }
44
45     int i = 0;
46     DatInfoList::Iterator it;
47     DatInfo* datInfo;
48
49     KURL inurl = Kita::ParseMisc::parseURLonly( url );
50
51     /* Is this url registered thread ? */
52     // if( !Board::boardExists( inurl ) ) return NULL;
53     QRegExp threadcheck( "\\d+.dat" );
54     if( inurl.filename().find( threadcheck ) == -1 ) return NULL;
55     
56     /* search */
57     if ( m_datInfo.count() ) {
58         for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it, i++ ) {
59
60             datInfo = ( *it );
61
62             if ( inurl == datInfo->url() ) {
63
64                 /* LRU */
65                 if ( i ) {
66                     m_datInfo.remove( it );
67                     m_datInfo.prepend( datInfo );
68                 }
69
70                 return datInfo;
71             }
72         }
73     }
74
75     /* not found */
76
77     /*create new DatInfo and insert it into list. */
78     KURL daturl = url.protocol() + "://" + url.host() + url.path();
79
80     datInfo = new DatInfo( daturl );
81     if ( datInfo->getRawDat() == QString::null ) { /* cache does not exist */
82         delete( datInfo );
83
84         return NULL;
85     }
86
87     m_datInfo.prepend( datInfo );
88
89     /* delete the last items of list */
90     if ( m_datInfo.count() > DMANAGER_MAXQUEUE ) {
91
92         /* collect unlocked datInfos */
93         typedef QValueList<KURL> DELETELIST;
94         DELETELIST deleteList;
95
96         for ( it = m_datInfo.at( DMANAGER_MAXQUEUE ); it != m_datInfo.end(); ++it )
97             if ( ! ( *it ) ->isLocked() ) deleteList += ( *it ) ->url();
98
99         /* delete unlocked datInfos */
100         for ( DELETELIST::Iterator itdel = deleteList.begin(); itdel != deleteList.end(); ++itdel )
101             deleteDatInfoPrivate( ( *itdel ) );
102     }
103
104     return datInfo;
105 }
106
107
108 /* get pointer of DatInfo */
109
110 /*    !!!  NOTICE  !!!   */
111 /* It is very dangerous to access to DatInfo directly. */
112 /* Usually, access to it through DatManager.           */ /* public */
113 DatInfo * DatManager::getDatInfoPointer( const KURL& url )
114 {
115     QMutexLocker locker( &m_mutex );
116
117     return getDatInfo( url );
118 }
119
120
121
122 /* public */
123 void DatManager::deleteDatInfo( const KURL& url )
124 {
125     QMutexLocker locker( &m_mutex );
126
127     deleteDatInfoPrivate( url );
128 }
129
130
131 /* private */
132 void DatManager::deleteDatInfoPrivate( const KURL& url )
133 {
134
135     DatInfoList::Iterator it;
136
137     for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it ) {
138         if ( url == ( *it ) ->url() ) {
139
140             if ( ! ( *it ) ->isLocked() ) {
141                 m_datInfo.remove( it );
142                 delete( *it );
143             }
144
145             return ;
146         }
147     }
148
149 }
150
151
152
153
154 /*-------------------------------------------------------------*/
155
156
157
158 /*--------------------------------------*/
159 /* update cache, then return new lines  */
160
161 /* If cache does not exist, then create
162    the new instance.                    */ /* public */
163 bool DatManager::updateCache( const KURL& url , const QObject* parent )
164 {
165     QMutexLocker locker( &m_mutex );
166
167     DatInfo * datInfo = getDatInfo( url );
168
169     /* create new DatInfo */
170     if ( datInfo == NULL ) {
171         datInfo = new DatInfo( url );
172         m_datInfo.prepend( datInfo );
173     }
174
175     return datInfo->updateCache( parent );
176 }
177
178
179 /* public */
180 int DatManager::getResponseCode( const KURL& url )
181 {
182     QMutexLocker locker( &m_mutex );
183
184     DatInfo * datInfo = getDatInfo( url );
185     if ( datInfo == NULL ) return 0;
186
187     return datInfo->getResponseCode();
188 }
189
190 /* public */
191 int DatManager::getServerTime( const KURL& url )
192 {
193     QMutexLocker locker( &m_mutex );
194
195     DatInfo * datInfo = getDatInfo( url );
196     if ( datInfo == NULL ) return 0;
197
198     return datInfo->getServerTime();
199 }
200
201
202 /* public */
203 bool DatManager::deleteCache( const KURL& url )
204 {
205     QMutexLocker locker( &m_mutex );
206
207     DatInfo * datInfo = getDatInfo( url );
208     if ( datInfo == NULL ) return FALSE;
209
210     return datInfo->deleteCache();
211 }
212
213
214 /* public */
215 bool DatManager::isLoadingNow( const KURL& url )
216 {
217     QMutexLocker locker( &m_mutex );
218
219     DatInfo * datInfo = getDatInfo( url );
220     if ( datInfo == NULL ) return FALSE;
221
222     return datInfo->isLoadingNow();
223 }
224
225
226 /* public */
227 void DatManager::stopLoading( const KURL& url )
228 {
229
230     /* Don't use QMutexLocker here !!
231        It will cause deadlock , because
232        Kita::Access::stopJob() calls KitaThreadView::slotFinishLoad() back.  */
233     m_mutex.lock();
234     DatInfo * datInfo = getDatInfo( url );
235     m_mutex.unlock();
236     if ( datInfo == NULL ) return ;
237
238     return datInfo->stopLoading();
239 }
240
241
242
243 /*----------------------*/
244 /* lock, unlock DatInfo */
245
246 /* If cache does not exist, then create
247    the new instance and lock it. 
248  
249    Don't forget to unlock it. */  /* public */
250
251 void DatManager::lock ( const KURL& url )
252 {
253     QMutexLocker locker( &m_mutex );
254
255     DatInfo * datInfo = getDatInfo( url );
256
257     /* create new DatInfo */
258     if ( datInfo == NULL ) {
259         datInfo = new DatInfo( url );
260         m_datInfo.prepend( datInfo );
261     }
262
263     datInfo->lock ();
264 }
265
266 void DatManager::unlock( const KURL& url )
267 {
268     QMutexLocker locker( &m_mutex );
269
270     DatInfo * datInfo = getDatInfo( url );
271     if ( datInfo == NULL ) return ;
272
273     datInfo->unlock();
274 }
275
276
277 /*--------------------------------------*/
278 /* string data */
279
280 /* public */
281 const QString& DatManager::getRawDat( const KURL& url )
282 {
283     QMutexLocker locker( &m_mutex );
284
285     DatInfo * datInfo = getDatInfo( url );
286     if ( datInfo == NULL ) return QString::null;
287
288     return datInfo->getRawDat();
289 }
290
291
292 /* public */
293 const QString& DatManager::getDat( const KURL& url, int num )
294 {
295     QMutexLocker locker( &m_mutex );
296
297     DatInfo * datInfo = getDatInfo( url );
298     if ( datInfo == NULL ) return QString::null;
299
300     return datInfo->getDat( num );
301 }
302
303
304
305 /* public */
306 const QString& DatManager::getId( const KURL& url, int num )
307 {
308     QMutexLocker locker( &m_mutex );
309
310     DatInfo * datInfo = getDatInfo( url );
311     if ( datInfo == NULL ) return QString::null;
312
313     return datInfo->getId( num );
314 }
315
316
317 /* public */
318 const QString& DatManager::getName( const KURL& url, int num )
319 {
320     QMutexLocker locker( &m_mutex );
321
322     DatInfo * datInfo = getDatInfo( url );
323     if ( datInfo == NULL ) return QString::null;
324
325     return datInfo->getName( num );
326 }
327
328
329 /* public */
330 const QString& DatManager::getBody( const KURL& url, int num )
331 {
332     QMutexLocker locker( &m_mutex );
333
334     DatInfo * datInfo = getDatInfo( url );
335     if ( datInfo == NULL ) return QString::null;
336
337     return datInfo->getBody( num );
338 }
339
340
341 /* public */
342 QString DatManager::getPlainName( const KURL& url, int num )
343 {
344     QMutexLocker locker( &m_mutex );
345
346     DatInfo * datInfo = getDatInfo( url );
347     if ( datInfo == NULL ) return QString::null;
348
349     return datInfo->getPlainName( num );
350 }
351
352
353 /* public */
354 QString DatManager::getPlainBody( const KURL& url, int num )
355 {
356     QMutexLocker locker( &m_mutex );
357
358     DatInfo * datInfo = getDatInfo( url );
359     if ( datInfo == NULL ) return QString::null;
360
361     return datInfo->getPlainBody( num );
362 }
363
364
365 /* public */
366 QString DatManager::getPlainTitle( const KURL& url, int num )
367 {
368     QMutexLocker locker( &m_mutex );
369
370     DatInfo * datInfo = getDatInfo( url );
371     if ( datInfo == NULL ) return QString::null;
372
373     return datInfo->getPlainTitle( num );
374 }
375
376
377 /* get URL of thread from URL of dat file. */ /* public */
378 const QString DatManager::threadURL( const KURL& url )
379 {
380     QMutexLocker locker( &m_mutex );
381
382     KURL datURL = Kita::ParseMisc::parseURLonly( url );
383     return Kita::datToThread( datURL.prettyURL() );
384 }
385
386
387 /* get name (i.e. subject ) of thread from URL of dat file. */ /* public */
388 const QString& DatManager::threadName( const KURL& url )
389 {
390     QMutexLocker locker( &m_mutex );
391
392     KURL datURL = Kita::ParseMisc::parseURLonly( url );
393     Kita::Thread* thread = Kita::Thread::getByURLNew( datURL );
394
395     if ( thread == NULL ) {
396
397         /* get subject from DatInfo */
398         DatInfo * datInfo = getDatInfo( url );
399         if ( datInfo == NULL ) return QString::null;
400         return datInfo->getSubject();
401     }
402
403     return Kita::Thread::getName( datURL );
404 }
405
406
407 /* public */
408 const QString DatManager::threadID( const KURL& url )
409 {
410     QMutexLocker locker( &m_mutex );
411
412     KURL datURL = Kita::ParseMisc::parseURLonly( url );
413     return datURL.filename().section( ".", 0, 0 );
414 }
415
416
417 /* get URL of board from URL of dat file. */ /* public */
418 const QString DatManager::boardURL( const KURL& url )
419 {
420     QMutexLocker locker( &m_mutex );
421
422     KURL datURL = Kita::ParseMisc::parseURLonly( url );
423     return Kita::datToBoard( datURL.prettyURL() );
424 }
425
426
427 /* get root URL of board from URL of dat file. */
428 /* ex.) If datURL = "http://pc5.2ch.net/linux/dat/1089905503/",
429    then "http://pc5.2ch.net/" is returned.                      */ /* public */
430 const QString DatManager::boardRoot( const KURL& url )
431 {
432     QMutexLocker locker( &m_mutex );
433
434     KURL datURL = Kita::ParseMisc::parseURLonly( url );
435     datURL.cd( "../../../" );
436     return datURL.prettyURL();
437 }
438
439
440 /* get name of board from URL of dat file. */ /* public */
441 const QString& DatManager::boardName( const KURL& url )
442 {
443     QMutexLocker locker( &m_mutex );
444
445     KURL datURL = Kita::ParseMisc::parseURLonly( url );
446     QString bdURL = Kita::datToBoard( datURL.prettyURL() );
447     return Kita::Board::getName( bdURL );
448 }
449
450
451 /* public */
452 const QString DatManager::boardID( const KURL& url )
453 {
454     QMutexLocker locker( &m_mutex );
455
456     KURL datURL = Kita::ParseMisc::parseURLonly( url );
457     return KURL( Kita::datToBoard( datURL.prettyURL() ) ).fileName();
458 }
459
460 const QString DatManager::getCachePath( const KURL& url )
461 {
462     QMutexLocker locker( &m_mutex );
463
464     KURL datURL = Kita::ParseMisc::parseURLonly( url );
465     return Kita::Cache::getPath( datURL );
466 }
467
468 const QString DatManager::getCacheIndexPath( const KURL& url )
469 {
470     QMutexLocker locker( &m_mutex );
471
472     KURL datURL = Kita::ParseMisc::parseURLonly( url );
473     return Kita::Cache::getIndexPath( datURL );
474 }
475
476 /*---------------------------------------*/
477 /* HTML data */
478
479 /* public */
480 QString DatManager::getHtml( const KURL& url, int startnum, int endnum )
481 {
482     QMutexLocker locker( &m_mutex );
483
484     DatInfo * datInfo = getDatInfo( url );
485     if ( datInfo == NULL ) return QString::null;
486
487     return datInfo->getHtml( startnum, endnum );
488 }
489
490
491
492 /* public */
493 QString DatManager::getHtmlByID( const KURL& url, const QString& strid, int &count )
494 {
495     QMutexLocker locker( &m_mutex );
496
497     DatInfo* datInfo = getDatInfo( url );
498     if ( datInfo == NULL ) return QString::null;
499
500     return datInfo->getHtmlByID( strid, count );
501 }
502
503
504
505 /* Get HTML document of res tree.*/ /* public */
506 QString DatManager::getTreeByRes( const KURL& url, const int rootnum, int &count )
507 {
508     QMutexLocker locker( &m_mutex );
509
510     DatInfo* datInfo = getDatInfo( url );
511     if ( datInfo == NULL ) return QString::null;
512
513     return datInfo->getTreeByRes( rootnum, count );
514 }
515
516 /* Get HTML document of reverse res tree.*/ /* public */
517 QString DatManager::getTreeByResReverse( const KURL& url, const int rootnum, int &count )
518 {
519     QMutexLocker locker( &m_mutex );
520
521     DatInfo* datInfo = getDatInfo( url );
522     if ( datInfo == NULL ) return QString::null;
523
524     return datInfo->getTreeByResReverse( rootnum, count );
525 }
526
527 /* Get DOM element */ /* public */
528 bool DatManager::getDomElement( const KURL& url, int num, DOM::HTMLDocument& hdoc, DOM::Element& retelm )
529 {
530     QMutexLocker locker( &m_mutex );
531
532     DatInfo* datInfo = getDatInfo( url );
533     if ( datInfo == NULL ) return FALSE;
534
535     return datInfo->getDomElement( num, hdoc, retelm );
536 }
537
538
539 /* public */
540 int DatManager::getResNum( const KURL& url )
541 {
542     QMutexLocker locker( &m_mutex );
543
544     DatInfo* datInfo = getDatInfo( url );
545     if ( datInfo == NULL ) return 0;
546
547     return datInfo->getResNum();
548 }
549
550
551 /* public */
552 int DatManager::getReadNum( const KURL& url )
553 {
554     QMutexLocker locker( &m_mutex );
555
556     DatInfo * datInfo = getDatInfo( url );
557     if ( datInfo == NULL ) return 0;
558
559     return datInfo->getReadNum();
560 }
561
562
563 /* public */
564 int DatManager::getKokoyonNum( const KURL& url )
565 {
566     QMutexLocker locker( &m_mutex );
567
568     DatInfo * datInfo = getDatInfo( url );
569     if ( datInfo == NULL ) return 0;
570
571     return datInfo->getKokoyonNum();
572 }
573
574
575 /* public */
576 void DatManager::setKokoyonNum( const KURL& url , int num )
577 {
578     QMutexLocker locker( &m_mutex );
579
580     DatInfo * datInfo = getDatInfo( url );
581     if ( datInfo == NULL ) return ;
582
583     return datInfo->setKokoyonNum( num );
584 }
585
586
587 /* public */
588 int DatManager::getDatSize( const KURL& url )
589 {
590     QMutexLocker locker( &m_mutex );
591
592     DatInfo * datInfo = getDatInfo( url );
593     if ( datInfo == NULL ) return 0;
594
595     return datInfo->getDatSize();
596 }
597
598 /* public */
599 int DatManager::getNumByID( const KURL& url, const QString& strid )
600 {
601     QMutexLocker locker( &m_mutex );
602
603     DatInfo * datInfo = getDatInfo( url );
604     if ( datInfo == NULL ) return 0;
605
606     return datInfo->getNumByID( strid );
607 }
608
609
610 /* public */
611 QString DatManager::getBBSDefaultName( const KURL& url )
612 {
613     QMutexLocker locker( &m_mutex );
614
615     KURL datURL = Kita::ParseMisc::parseURLonly( url );
616     QString name = "(default name)";
617
618     if( datURL.prettyURL().contains( "http://ex7.2ch.net/morningcoffee/" ) ) name = "fusianasan";
619     
620     return name;
621 }
622
623
624 /* public */
625 int DatManager::getBBSMaxLine( const KURL& url )
626 {
627     QMutexLocker locker( &m_mutex );
628
629     KURL datURL = Kita::ParseMisc::parseURLonly( url );
630     int linenum = 64;
631
632     if( datURL.prettyURL().contains( "http://pc5.2ch.net/linux/" ) ) linenum = 32;
633     
634     return linenum;
635 }
636
637
638
639 /* public */
640 bool DatManager::is2chThread( const KURL& url )
641 {
642     QMutexLocker locker( &m_mutex );
643
644     KURL datURL = Kita::ParseMisc::parseURLonly( url );
645
646     QRegExp threadcheck( "\\d+.dat" );
647     if( datURL.filename().find( threadcheck ) == -1 ) return FALSE;
648     
649     return Kita::is2ch( datURL );
650 }
651
652
653 /* public */
654 bool DatManager::isResValid( const KURL& url, int num )
655 {
656     QMutexLocker locker( &m_mutex );
657
658     DatInfo * datInfo = getDatInfo( url );
659     if ( datInfo == NULL ) return FALSE;
660
661     return datInfo->isResValid( num );
662 }
663
664
665 /* public */
666 bool DatManager::isBroken( const KURL& url )
667 {
668     QMutexLocker locker( &m_mutex );
669
670     DatInfo * datInfo = getDatInfo( url );
671     if ( datInfo == NULL ) return FALSE;
672
673     return datInfo->isBroken();
674 }
675
676 /* public */
677 bool DatManager::isResBroken( const KURL& url, int num )
678 {
679     QMutexLocker locker( &m_mutex );
680
681     DatInfo * datInfo = getDatInfo( url );
682     if ( datInfo == NULL ) return FALSE;
683
684     return datInfo->isResBroken( num );
685 }
686
687
688
689 /* public */
690 bool DatManager::checkID( const KURL& url, const QString& strid, int num )
691 {
692     QMutexLocker locker( &m_mutex );
693
694     DatInfo* datInfo = getDatInfo( url );
695     if ( datInfo == NULL ) return FALSE;
696
697     return datInfo->checkID( strid, num );
698 }
699
700
701 /* check keywords */ /* public */
702 bool DatManager::checkWord( const KURL& url,
703                             QStringList& strlist, int num,
704                             bool checkOR /* AND or OR search */
705                           )
706 {
707     QMutexLocker locker( &m_mutex );
708
709     DatInfo* datInfo = getDatInfo( url );
710     if ( datInfo == NULL ) return FALSE;
711
712     return datInfo->checkWord( strlist, num, checkOR );
713 }
714
715
716 /* public */
717 bool DatManager::isMarked( const KURL& url, int num )
718 {
719     QMutexLocker locker( &m_mutex );
720
721     DatInfo * datInfo = getDatInfo( url );
722     if ( datInfo == NULL ) return FALSE;
723
724     return datInfo->isMarked( num );
725 }
726
727
728 /* public */
729 void DatManager::setMark( const KURL& url, int num, bool mark )
730 {
731     QMutexLocker locker( &m_mutex );
732
733     DatInfo * datInfo = getDatInfo( url );
734     if ( datInfo == NULL ) return ;
735
736     datInfo->setMark( num, mark );
737 }
738
739
740 /* public */
741 bool DatManager::checkAbone( const KURL& url, int num )
742 {
743     QMutexLocker locker( &m_mutex );
744
745     DatInfo* datInfo = getDatInfo( url );
746     if ( datInfo == NULL ) return FALSE;
747
748     return datInfo->checkAbone( num );
749 }
750
751
752 /* public */
753 void DatManager::resetAbone( const KURL& url )
754 {
755     QMutexLocker locker( &m_mutex );
756
757     DatInfo* datInfo = getDatInfo( url );
758     if ( datInfo == NULL ) return ;
759
760     datInfo->resetAbone();
761 }