File indexing completed on 2024-04-28 08:46:51

0001 /*
0002     SPDX-FileCopyrightText: 2002 Rik Hemsley (rikkus) <rik@kde.org>
0003     SPDX-FileCopyrightText: 2002 Benjamin Meyer <ben-devel@meyerhome.net>
0004     SPDX-FileCopyrightText: 2005 Richard Lärkäng <nouseforaname@home.se>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "synccddbplookup.h"
0010 #include "logging.h"
0011 
0012 #include <QStringList>
0013 
0014 namespace KCDDB
0015 {
0016   SyncCDDBPLookup::SyncCDDBPLookup()
0017     : CDDBPLookup()
0018   {
0019   }
0020 
0021   SyncCDDBPLookup::~SyncCDDBPLookup()
0022   {
0023     // Empty.
0024   }
0025 
0026     Result
0027   SyncCDDBPLookup::lookup
0028   (
0029     const QString         & hostName,
0030     uint                    port,
0031     const TrackOffsetList & trackOffsetList
0032   )
0033   {
0034     trackOffsetList_ = trackOffsetList;
0035 
0036     socket_ = new QTcpSocket;
0037     socket_->connectToHost(hostName, port);
0038 
0039     if ( !socket_->waitForConnected(30000) )
0040     {
0041       qCDebug(LIBKCDDB) << "Couldn't connect to " << socket_->peerName() << ":" << socket_->peerPort();
0042       qCDebug(LIBKCDDB) << "Socket error: " << socket_->errorString();
0043       const auto socketError = socket_->error();
0044       if ( socketError == QAbstractSocket::HostNotFoundError )
0045         return HostNotFound;
0046       else if ( socketError == QAbstractSocket::SocketTimeoutError )
0047         return NoResponse;
0048       else
0049         return UnknownError;
0050     }
0051 
0052     Result result;
0053 
0054     // Try a handshake.
0055     result = shakeHands();
0056     if ( Success != result )
0057       return result;
0058 
0059     // Run a query.
0060     result = runQuery();
0061     if ( Success != result )
0062       return result;
0063 
0064     if (matchList_.isEmpty())
0065       return NoRecordFound;
0066 
0067     qCDebug(LIBKCDDB) << matchList_.count() << " matches found.";
0068 
0069     // For each match, read the cd info from the server and save it to
0070     // cdInfoList.
0071     CDDBMatchList::ConstIterator matchIt = matchList_.constBegin();
0072 
0073     while ( matchIt != matchList_.constEnd() )
0074     {
0075       CDDBMatch match( *matchIt );
0076       result = matchToCDInfo( match );
0077       ++matchIt;
0078     }
0079 
0080     sendQuit();
0081 
0082     close();
0083 
0084     return Success;
0085   }
0086 
0087     Result
0088   SyncCDDBPLookup::shakeHands()
0089   {
0090     QString line = readLine();
0091 
0092     if ( !parseGreeting( line ) )
0093       return ServerError;
0094 
0095     sendHandshake();
0096 
0097     line = readLine();
0098 
0099     if ( !parseHandshake( line ) )
0100       return ServerError;
0101 
0102     sendProto();
0103 
0104     // Ignore the response for now
0105     readLine();
0106 
0107     return Success;
0108   }
0109 
0110     Result
0111   SyncCDDBPLookup::runQuery()
0112   {
0113     Result result;
0114 
0115     sendQuery();
0116 
0117     QString line = readLine();
0118     result = parseQuery( line );
0119 
0120     if ( ServerError == result )
0121       return ServerError;
0122 
0123     if ( MultipleRecordFound == result )
0124     {
0125       // We have multiple matches
0126       line = readLine();
0127 
0128       while (!line.startsWith(QLatin1String( "." )) && !line.isNull() )
0129       {
0130         parseExtraMatch( line );
0131         line = readLine();
0132       }
0133     }
0134 
0135     return Success;
0136   }
0137 
0138     Result
0139   SyncCDDBPLookup::matchToCDInfo( const CDDBMatch & match )
0140   {
0141     sendRead( match );
0142 
0143     QString line = readLine();
0144 
0145     Result result = parseRead( line );
0146     if ( Success != result )
0147       return result;
0148 
0149     QStringList lineList;
0150     line = readLine();
0151 
0152     while ( !line.startsWith(QLatin1String( "." )) && !line.isNull() )
0153     {
0154       lineList.append( line );
0155       line = readLine();
0156     }
0157 
0158     CDInfo info;
0159 
0160     if ( info.load( lineList ) )
0161     {
0162       info.set( QLatin1String( "category" ), category_ );
0163       info.set( QLatin1String( "discid" ), discid_ );
0164       info.set( QLatin1String( "source" ), QLatin1String( "freedb" ) );
0165       cdInfoList_.append( info );
0166     }
0167 
0168     return Success;
0169   }
0170 
0171     QString
0172   SyncCDDBPLookup::readLine()
0173   {
0174     if ( !isConnected() )
0175     {
0176       qCDebug(LIBKCDDB) << "socket status: " << socket_->state();
0177       return QString();
0178     }
0179 
0180     if (!socket_->canReadLine())
0181     {
0182       if (!socket_->waitForReadyRead(-1))
0183         return QString();
0184     }
0185 
0186     return QString::fromUtf8(socket_->readLine());
0187   }
0188 }
0189 
0190 // vim:tabstop=2:shiftwidth=2:expandtab:cinoptions=(s,U1,m1