increase tolerance in detecting new songs if songid didn't change
[scrobby.git] / src / mpdpp.cpp
blobb11c1270d2d9838d8815e4048c322a2ded0075ad
1 /***************************************************************************
2 * Copyright (C) 2008-2009 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "mpdpp.h"
23 using std::string;
25 MPD::Connection::Connection() : isConnected(0),
26 itsErrorCode(0),
27 itsHost("localhost"),
28 itsPort(6600),
29 itsTimeout(15),
30 itsUpdater(0),
31 itsErrorHandler(0)
33 itsConnection = 0;
34 itsCurrentStatus = 0;
35 itsOldStatus = 0;
38 MPD::Connection::~Connection()
40 if (itsConnection)
41 mpd_closeConnection(itsConnection);
42 if (itsOldStatus)
43 mpd_freeStatus(itsOldStatus);
44 if (itsCurrentStatus)
45 mpd_freeStatus(itsCurrentStatus);
48 bool MPD::Connection::Connect()
50 if (!isConnected && !itsConnection)
52 itsConnection = mpd_newConnection(itsHost.c_str(), itsPort, itsTimeout);
53 isConnected = 1;
54 if (CheckForErrors())
55 return false;
56 if (!itsPassword.empty())
57 SendPassword();
58 return !CheckForErrors();
60 else
61 return true;
64 bool MPD::Connection::Connected() const
66 return isConnected;
69 void MPD::Connection::Disconnect()
71 if (itsConnection)
72 mpd_closeConnection(itsConnection);
73 if (itsOldStatus)
74 mpd_freeStatus(itsOldStatus);
75 if (itsCurrentStatus)
76 mpd_freeStatus(itsCurrentStatus);
77 itsConnection = 0;
78 itsCurrentStatus = 0;
79 itsOldStatus = 0;
80 isConnected = 0;
83 void MPD::Connection::SetHostname(const string &host)
85 size_t at = host.find("@");
86 if (at != string::npos)
88 itsPassword = host.substr(0, at);
89 itsHost = host.substr(at+1);
91 else
92 itsHost = host;
95 void MPD::Connection::SendPassword() const
97 mpd_sendPasswordCommand(itsConnection, itsPassword.c_str());
98 mpd_finishCommand(itsConnection);
101 void MPD::Connection::SetStatusUpdater(StatusUpdater updater, void *data)
103 itsUpdater = updater;
104 itsStatusUpdaterUserdata = data;
107 void MPD::Connection::SetErrorHandler(ErrorHandler handler, void *data)
109 itsErrorHandler = handler;
110 itsErrorHandlerUserdata = data;
113 void MPD::Connection::UpdateStatus()
115 if (!itsConnection)
116 return;
118 CheckForErrors();
120 if (!itsConnection)
121 return;
123 if (itsOldStatus)
124 mpd_freeStatus(itsOldStatus);
126 itsOldStatus = itsCurrentStatus;
127 itsCurrentStatus = 0;
129 mpd_sendStatusCommand(itsConnection);
130 itsCurrentStatus = mpd_getStatus(itsConnection);
132 if (CheckForErrors())
133 return;
135 if (itsCurrentStatus && itsUpdater)
137 if (itsOldStatus == NULL)
139 itsChanges.Playlist = 1;
140 itsChanges.SongID = 1;
141 itsChanges.ElapsedTime = 1;
142 itsChanges.State = 1;
144 else
146 itsChanges.Playlist = itsOldStatus->playlist != itsCurrentStatus->playlist;
147 itsChanges.SongID = itsOldStatus->songid != itsCurrentStatus->songid;
148 itsChanges.ElapsedTime = itsOldStatus->elapsedTime != itsCurrentStatus->elapsedTime;
149 itsChanges.State = itsOldStatus->state != itsCurrentStatus->state;
151 itsUpdater(this, itsChanges, itsErrorHandlerUserdata);
155 mpd_Song * MPD::Connection::CurrentSong() const
157 if (isConnected && (GetState() == psPlay || GetState() == psPause))
159 mpd_sendCurrentSongCommand(itsConnection);
160 mpd_InfoEntity *item = NULL;
161 item = mpd_getNextInfoEntity(itsConnection);
162 if (item)
164 mpd_Song *result = item->info.song;
165 item->info.song = 0;
166 mpd_freeInfoEntity(item);
167 return result;
169 mpd_finishCommand(itsConnection);
171 return NULL;
174 int MPD::Connection::CheckForErrors()
176 itsErrorCode = 0;
177 if (itsConnection->error)
179 itsErrorMessage = itsConnection->errorStr;
180 if (itsConnection->error == MPD_ERROR_ACK)
182 if (itsErrorHandler)
183 itsErrorHandler(this, itsConnection->errorCode, itsErrorMessage, itsErrorHandlerUserdata);
184 itsErrorCode = itsConnection->errorCode;
186 else
188 if (itsErrorHandler)
189 itsErrorHandler(this, itsConnection->error, itsErrorMessage, itsErrorHandlerUserdata);
190 itsErrorCode = itsConnection->error;
191 Disconnect(); // the rest of errors are fatal to connection
193 if (itsConnection)
194 mpd_clearError(itsConnection);
196 return itsErrorCode;