File indexing completed on 2024-03-24 04:57:11
0001 /* 0002 SPDX-FileCopyrightText: 2002 Rik Hemsley (rikkus) <rik@kde.org> 0003 SPDX-FileCopyrightText: 2002-2005 Benjamin C. Meyer <ben at meyerhome dot net> 0004 SPDX-FileCopyrightText: 2003 Richard Lärkäng <nouseforaname@home.se> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "client.h" 0010 0011 #include "asynccddbplookup.h" 0012 #include "asynchttplookup.h" 0013 #include "asynchttpsubmit.h" 0014 #include "cache.h" 0015 #include "logging.h" 0016 #include "lookup.h" 0017 #include "synccddbplookup.h" 0018 #include "synchttplookup.h" 0019 #include "synchttpsubmit.h" 0020 0021 #include "config-musicbrainz.h" 0022 #ifdef HAVE_MUSICBRAINZ5 0023 #include "musicbrainz/musicbrainzlookup.h" 0024 #include "musicbrainz/asyncmusicbrainzlookup.h" 0025 #endif 0026 0027 namespace KCDDB 0028 { 0029 class Client::Private 0030 { 0031 public: 0032 0033 Private() 0034 : cdInfoLookup(nullptr), 0035 cdInfoSubmit(nullptr), 0036 block( true ) 0037 {} 0038 0039 ~Private() 0040 { 0041 delete cdInfoLookup; 0042 delete cdInfoSubmit; 0043 qDeleteAll(pendingLookups); 0044 } 0045 0046 Lookup * cdInfoLookup; 0047 Submit * cdInfoSubmit; 0048 0049 Config config; 0050 CDInfoList cdInfoList; 0051 TrackOffsetList trackOffsetList; 0052 QList<Lookup *> pendingLookups; 0053 bool block; 0054 }; 0055 0056 Client::Client() 0057 : d(new Private) 0058 { 0059 d->config.load(); 0060 } 0061 0062 Client::~Client() 0063 { 0064 delete d; 0065 } 0066 0067 Config & 0068 Client::config() const 0069 { 0070 return d->config; 0071 } 0072 0073 void 0074 Client::setBlockingMode( bool enable ) 0075 { 0076 d->block = enable; 0077 } 0078 0079 bool 0080 Client::blockingMode() const 0081 { 0082 return d->block; 0083 } 0084 0085 CDInfoList 0086 Client::lookupResponse() const 0087 { 0088 return d->cdInfoList; 0089 } 0090 0091 Result 0092 Client::lookup(const TrackOffsetList & trackOffsetList) 0093 { 0094 d->cdInfoList.clear(); 0095 d->trackOffsetList = trackOffsetList; 0096 0097 if ( trackOffsetList.count() <= 1 ) 0098 { 0099 qCDebug(LIBKCDDB) << "Lookup called with empty offset list"; 0100 return NoRecordFound; 0101 } 0102 0103 if ( d->config.cacheLookupEnabled() ) 0104 { 0105 d->cdInfoList = Cache::lookup( trackOffsetList, config() ); 0106 0107 qCDebug(LIBKCDDB) << "Found " << d->cdInfoList.count() << " hit(s)"; 0108 0109 if ( !d->cdInfoList.isEmpty() ) 0110 { 0111 if ( !blockingMode() ) 0112 Q_EMIT finished( Success ); 0113 0114 return Success; 0115 } 0116 } 0117 0118 Result r = NoRecordFound; 0119 0120 // just in case we have an info lookup hanging around, prevent mem leakage 0121 delete d->cdInfoLookup; 0122 d->cdInfoLookup = nullptr; 0123 qDeleteAll(d->pendingLookups); 0124 d->pendingLookups.clear(); 0125 0126 if ( blockingMode() ) 0127 { 0128 #ifdef HAVE_MUSICBRAINZ5 0129 if ( d->config.musicBrainzLookupEnabled() ) 0130 { 0131 d->cdInfoLookup = new MusicBrainzLookup(); 0132 0133 r = d->cdInfoLookup->lookup( d->config.hostname(), 0134 d->config.port(), trackOffsetList ); 0135 0136 if ( Success == r ) 0137 { 0138 d->cdInfoList = d->cdInfoLookup->lookupResponse(); 0139 Cache::store( d->trackOffsetList, d->cdInfoList, config() ); 0140 0141 return r; 0142 } 0143 0144 delete d->cdInfoLookup; 0145 d->cdInfoLookup = nullptr; 0146 } 0147 #endif 0148 0149 if ( d->config.freedbLookupEnabled() ) 0150 { 0151 Lookup::Transport t = ( Lookup::Transport )d->config.freedbLookupTransport(); 0152 if( Lookup::CDDBP == t ) 0153 d->cdInfoLookup = new SyncCDDBPLookup(); 0154 else 0155 d->cdInfoLookup = new SyncHTTPLookup(); 0156 0157 r = d->cdInfoLookup->lookup( d->config.hostname(), 0158 d->config.port(), trackOffsetList ); 0159 0160 if ( Success == r ) 0161 { 0162 d->cdInfoList = d->cdInfoLookup->lookupResponse(); 0163 Cache::store( d->trackOffsetList, d->cdInfoList, config() ); 0164 0165 return r; 0166 } 0167 0168 delete d->cdInfoLookup; 0169 d->cdInfoLookup = nullptr; 0170 } 0171 0172 return r; 0173 } 0174 else 0175 { 0176 #ifdef HAVE_MUSICBRAINZ5 0177 if ( d->config.musicBrainzLookupEnabled() ) 0178 { 0179 AsyncMusicBrainzLookup* lookup = new AsyncMusicBrainzLookup(); 0180 0181 connect( lookup, &AsyncMusicBrainzLookup::finished, 0182 this, &Client::slotFinished ); 0183 d->pendingLookups.append( lookup ); 0184 } 0185 #endif 0186 0187 if ( d->config.freedbLookupEnabled() ) 0188 { 0189 Lookup::Transport t = ( Lookup::Transport )d->config.freedbLookupTransport(); 0190 0191 if( Lookup::CDDBP == t ) 0192 { 0193 AsyncCDDBPLookup* lookup = new AsyncCDDBPLookup(); 0194 0195 connect( lookup, &AsyncCDDBPLookup::finished, 0196 this, &Client::slotFinished ); 0197 d->pendingLookups.append( lookup ); 0198 } 0199 else 0200 { 0201 AsyncHTTPLookup* lookup = new AsyncHTTPLookup(); 0202 0203 connect( lookup, &AsyncHTTPLookup::finished, 0204 this, &Client::slotFinished ); 0205 d->pendingLookups.append( lookup ); 0206 } 0207 } 0208 0209 return runPendingLookups(); 0210 } 0211 } 0212 0213 void 0214 Client::slotFinished( Result r ) 0215 { 0216 if ( d->cdInfoLookup && Success == r ) 0217 { 0218 d->cdInfoList = d->cdInfoLookup->lookupResponse(); 0219 Cache::store( d->trackOffsetList, d->cdInfoList, config() ); 0220 } 0221 else 0222 d->cdInfoList.clear(); 0223 0224 if ( d->cdInfoLookup ) // in case someone called lookup() while finished() was being processed, and deleted cdInfoLookup. 0225 { 0226 d->cdInfoLookup->deleteLater(); 0227 d->cdInfoLookup = nullptr; 0228 } 0229 0230 if ( Success == r ) 0231 { 0232 Q_EMIT finished( r ); 0233 qDeleteAll( d->pendingLookups ); 0234 d->pendingLookups.clear(); 0235 } 0236 else 0237 { 0238 runPendingLookups(); 0239 } 0240 } 0241 0242 void 0243 Client::slotSubmitFinished( Result r ) 0244 { 0245 Q_EMIT finished( r ); 0246 0247 d->cdInfoSubmit->deleteLater(); 0248 d->cdInfoSubmit=nullptr; 0249 } 0250 0251 Result 0252 Client::submit(const CDInfo &cdInfo, const TrackOffsetList& offsetList) 0253 { 0254 // Check if it's valid 0255 0256 if (!cdInfo.isValid()) 0257 return CannotSave; 0258 0259 uint last=0; 0260 for (int i=0; i < offsetList.count(); i++) 0261 { 0262 if(last >= offsetList[i]) 0263 return CannotSave; 0264 last = offsetList[i]; 0265 } 0266 0267 //TODO Check that it is edited 0268 0269 // just in case we have a cdInfoSubmit, prevent memory leakage 0270 delete d->cdInfoSubmit; 0271 0272 QString from = d->config.emailAddress(); 0273 0274 QString hostname = d->config.httpSubmitServer(); 0275 uint port = d->config.httpSubmitPort(); 0276 0277 if ( blockingMode() ) 0278 d->cdInfoSubmit = new SyncHTTPSubmit(from, hostname, port); 0279 else 0280 { 0281 d->cdInfoSubmit = new AsyncHTTPSubmit(from, hostname, port); 0282 connect( static_cast<AsyncHTTPSubmit *>( d->cdInfoSubmit ), 0283 &AsyncHTTPSubmit::finished, 0284 this, &Client::slotSubmitFinished ); 0285 } 0286 0287 Result r = d->cdInfoSubmit->submit( cdInfo, offsetList ); 0288 0289 if ( blockingMode() ) 0290 { 0291 delete d->cdInfoSubmit; 0292 d->cdInfoSubmit = nullptr; 0293 } 0294 0295 return r; 0296 } 0297 0298 Result 0299 Client::runPendingLookups() 0300 { 0301 if (!d->pendingLookups.empty()) 0302 { 0303 d->cdInfoLookup = d->pendingLookups.takeFirst(); 0304 0305 Result r = d->cdInfoLookup->lookup( d->config.hostname(), 0306 d->config.port(), d->trackOffsetList ); 0307 0308 if ( Success != r ) 0309 { 0310 delete d->cdInfoLookup; 0311 d->cdInfoLookup = nullptr; 0312 } 0313 0314 return r; 0315 } 0316 else 0317 { 0318 Q_EMIT finished( NoRecordFound ); 0319 return NoRecordFound; 0320 } 0321 } 0322 0323 void 0324 Client::store(const CDInfo &cdInfo, const TrackOffsetList& offsetList) 0325 { 0326 Cache::store(offsetList, cdInfo, config()); 0327 } 0328 } 0329 0330 #include "moc_client.cpp" 0331 0332 // vim:tabstop=2:shiftwidth=2:expandtab:cinoptions=(s,U1,m1