KCDDB

client.cpp
1/*
2 SPDX-FileCopyrightText: 2002 Rik Hemsley (rikkus) <rik@kde.org>
3 SPDX-FileCopyrightText: 2002-2005 Benjamin C. Meyer <ben at meyerhome dot net>
4 SPDX-FileCopyrightText: 2003 Richard Lärkäng <nouseforaname@home.se>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "client.h"
10
11#include "asynccddbplookup.h"
12#include "asynchttplookup.h"
13#include "asynchttpsubmit.h"
14#include "cache.h"
15#include "logging.h"
16#include "lookup.h"
17#include "synccddbplookup.h"
18#include "synchttplookup.h"
19#include "synchttpsubmit.h"
20
21#include "config-musicbrainz.h"
22#ifdef HAVE_MUSICBRAINZ5
23#include "musicbrainz/musicbrainzlookup.h"
24#include "musicbrainz/asyncmusicbrainzlookup.h"
25#endif
26
27namespace KCDDB
28{
29 class Client::Private
30 {
31 public:
32
33 Private()
34 : cdInfoLookup(nullptr),
35 cdInfoSubmit(nullptr),
36 block( true )
37 {}
38
39 ~Private()
40 {
41 delete cdInfoLookup;
42 delete cdInfoSubmit;
43 qDeleteAll(pendingLookups);
44 }
45
46 Lookup * cdInfoLookup;
47 Submit * cdInfoSubmit;
48
49 Config config;
50 CDInfoList cdInfoList;
51 TrackOffsetList trackOffsetList;
52 QList<Lookup *> pendingLookups;
53 bool block;
54 };
55
57 : d(new Private)
58 {
59 d->config.load();
60 }
61
62 Client::~Client()
63 {
64 delete d;
65 }
66
67 Config &
68 Client::config() const
69 {
70 return d->config;
71 }
72
73 void
74 Client::setBlockingMode( bool enable )
75 {
76 d->block = enable;
77 }
78
79 bool
80 Client::blockingMode() const
81 {
82 return d->block;
83 }
84
85 CDInfoList
87 {
88 return d->cdInfoList;
89 }
90
91 Result
92 Client::lookup(const TrackOffsetList & trackOffsetList)
93 {
94 d->cdInfoList.clear();
95 d->trackOffsetList = trackOffsetList;
96
97 if ( trackOffsetList.count() <= 1 )
98 {
99 qCDebug(LIBKCDDB) << "Lookup called with empty offset list";
100 return NoRecordFound;
101 }
102
103 if ( d->config.cacheLookupEnabled() )
104 {
105 d->cdInfoList = Cache::lookup( trackOffsetList, config() );
106
107 qCDebug(LIBKCDDB) << "Found " << d->cdInfoList.count() << " hit(s)";
108
109 if ( !d->cdInfoList.isEmpty() )
110 {
111 if ( !blockingMode() )
112 Q_EMIT finished( Success );
113
114 return Success;
115 }
116 }
117
118 Result r = NoRecordFound;
119
120 // just in case we have an info lookup hanging around, prevent mem leakage
121 delete d->cdInfoLookup;
122 d->cdInfoLookup = nullptr;
123 qDeleteAll(d->pendingLookups);
124 d->pendingLookups.clear();
125
126 if ( blockingMode() )
127 {
128#ifdef HAVE_MUSICBRAINZ5
129 if ( d->config.musicBrainzLookupEnabled() )
130 {
131 d->cdInfoLookup = new MusicBrainzLookup();
132
133 r = d->cdInfoLookup->lookup( d->config.hostname(),
134 d->config.port(), trackOffsetList );
135
136 if ( Success == r )
137 {
138 d->cdInfoList = d->cdInfoLookup->lookupResponse();
139 Cache::store( d->trackOffsetList, d->cdInfoList, config() );
140
141 return r;
142 }
143
144 delete d->cdInfoLookup;
145 d->cdInfoLookup = nullptr;
146 }
147#endif
148
149 if ( d->config.freedbLookupEnabled() )
150 {
151 Lookup::Transport t = ( Lookup::Transport )d->config.freedbLookupTransport();
152 if( Lookup::CDDBP == t )
153 d->cdInfoLookup = new SyncCDDBPLookup();
154 else
155 d->cdInfoLookup = new SyncHTTPLookup();
156
157 r = d->cdInfoLookup->lookup( d->config.hostname(),
158 d->config.port(), trackOffsetList );
159
160 if ( Success == r )
161 {
162 d->cdInfoList = d->cdInfoLookup->lookupResponse();
163 Cache::store( d->trackOffsetList, d->cdInfoList, config() );
164
165 return r;
166 }
167
168 delete d->cdInfoLookup;
169 d->cdInfoLookup = nullptr;
170 }
171
172 return r;
173 }
174 else
175 {
176#ifdef HAVE_MUSICBRAINZ5
177 if ( d->config.musicBrainzLookupEnabled() )
178 {
179 AsyncMusicBrainzLookup* lookup = new AsyncMusicBrainzLookup();
180
181 connect( lookup, &AsyncMusicBrainzLookup::finished,
182 this, &Client::slotFinished );
183 d->pendingLookups.append( lookup );
184 }
185#endif
186
187 if ( d->config.freedbLookupEnabled() )
188 {
189 Lookup::Transport t = ( Lookup::Transport )d->config.freedbLookupTransport();
190
191 if( Lookup::CDDBP == t )
192 {
193 AsyncCDDBPLookup* lookup = new AsyncCDDBPLookup();
194
195 connect( lookup, &AsyncCDDBPLookup::finished,
196 this, &Client::slotFinished );
197 d->pendingLookups.append( lookup );
198 }
199 else
200 {
201 AsyncHTTPLookup* lookup = new AsyncHTTPLookup();
202
203 connect( lookup, &AsyncHTTPLookup::finished,
204 this, &Client::slotFinished );
205 d->pendingLookups.append( lookup );
206 }
207 }
208
209 return runPendingLookups();
210 }
211 }
212
213 void
215 {
216 if ( d->cdInfoLookup && Success == r )
217 {
218 d->cdInfoList = d->cdInfoLookup->lookupResponse();
219 Cache::store( d->trackOffsetList, d->cdInfoList, config() );
220 }
221 else
222 d->cdInfoList.clear();
223
224 if ( d->cdInfoLookup ) // in case someone called lookup() while finished() was being processed, and deleted cdInfoLookup.
225 {
226 d->cdInfoLookup->deleteLater();
227 d->cdInfoLookup = nullptr;
228 }
229
230 if ( Success == r )
231 {
232 Q_EMIT finished( r );
233 qDeleteAll( d->pendingLookups );
234 d->pendingLookups.clear();
235 }
236 else
237 {
238 runPendingLookups();
239 }
240 }
241
242 void
244 {
245 Q_EMIT finished( r );
246
247 d->cdInfoSubmit->deleteLater();
248 d->cdInfoSubmit=nullptr;
249 }
250
251 Result
252 Client::submit(const CDInfo &cdInfo, const TrackOffsetList& offsetList)
253 {
254 // Check if it's valid
255
256 if (!cdInfo.isValid())
257 return CannotSave;
258
259 uint last=0;
260 for (int i=0; i < offsetList.count(); i++)
261 {
262 if(last >= offsetList[i])
263 return CannotSave;
264 last = offsetList[i];
265 }
266
267 //TODO Check that it is edited
268
269 // just in case we have a cdInfoSubmit, prevent memory leakage
270 delete d->cdInfoSubmit;
271
272 QString from = d->config.emailAddress();
273
274 QString hostname = d->config.httpSubmitServer();
275 uint port = d->config.httpSubmitPort();
276
277 if ( blockingMode() )
278 d->cdInfoSubmit = new SyncHTTPSubmit(from, hostname, port);
279 else
280 {
281 d->cdInfoSubmit = new AsyncHTTPSubmit(from, hostname, port);
282 connect( static_cast<AsyncHTTPSubmit *>( d->cdInfoSubmit ),
283 &AsyncHTTPSubmit::finished,
285 }
286
287 Result r = d->cdInfoSubmit->submit( cdInfo, offsetList );
288
289 if ( blockingMode() )
290 {
291 delete d->cdInfoSubmit;
292 d->cdInfoSubmit = nullptr;
293 }
294
295 return r;
296 }
297
298 Result
299 Client::runPendingLookups()
300 {
301 if (!d->pendingLookups.empty())
302 {
303 d->cdInfoLookup = d->pendingLookups.takeFirst();
304
305 Result r = d->cdInfoLookup->lookup( d->config.hostname(),
306 d->config.port(), d->trackOffsetList );
307
308 if ( Success != r )
309 {
310 delete d->cdInfoLookup;
311 d->cdInfoLookup = nullptr;
312 }
313
314 return r;
315 }
316 else
317 {
318 Q_EMIT finished( NoRecordFound );
319 return NoRecordFound;
320 }
321 }
322
323 void
324 Client::store(const CDInfo &cdInfo, const TrackOffsetList& offsetList)
325 {
326 Cache::store(offsetList, cdInfo, config());
327 }
328}
329
330#include "moc_client.cpp"
331
332// vim:tabstop=2:shiftwidth=2:expandtab:cinoptions=(s,U1,m1
Information about a CD.
Definition cdinfo.h:105
bool isValid() const
Definition cdinfo.cpp:538
Client()
Uses settings read from config.
Definition client.cpp:56
CDInfoList lookupResponse() const
Definition client.cpp:86
void finished(KCDDB::Result result)
emitted when not blocking and lookup() finished.
void slotFinished(KCDDB::Result result)
Called when the lookup is finished with the result.
Definition client.cpp:214
void store(const CDInfo &cdInfo, const TrackOffsetList &trackOffsetList)
Stores the CD-information in the local cache.
Definition client.cpp:324
Result submit(const CDInfo &cdInfo, const TrackOffsetList &trackOffsetList)
Definition client.cpp:252
Result lookup(const TrackOffsetList &trackOffsetList)
Searches the database for entries matching the offset list.
Definition client.cpp:92
void slotSubmitFinished(KCDDB::Result result)
Called when the submit is finished with the result.
Definition client.cpp:243
void append(QList< T > &&value)
void clear()
qsizetype count() const const
bool empty() const const
bool isEmpty() const const
value_type takeFirst()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:58 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.