Add a generic class for the "cached list of stuff" pattern used by last.fm and di.fm/sky.fm for keeping friend lists or stream lists around and refreshing them after a certain length of time

This commit is contained in:
David Sansome 2011-11-05 22:56:10 +00:00
parent 1f0c2333d0
commit 8c69094931
9 changed files with 184 additions and 149 deletions

92
src/core/cachedlist.h Normal file
View File

@ -0,0 +1,92 @@
/* This file is part of Clementine.
Copyright 2011, David Sansome <me@davidsansome.com>
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CACHEDLIST_H
#define CACHEDLIST_H
#include <QDateTime>
#include <QSettings>
template <typename T>
class CachedList {
public:
typedef QList<T> ListType;
typedef typename ListType::const_iterator const_iterator;
CachedList(const char* settings_group, const QString& name,
int cache_duration_secs)
: settings_group_(settings_group),
name_(name),
cache_duration_secs_(cache_duration_secs) {
}
void Load() {
QSettings s;
s.beginGroup(settings_group_);
last_updated_ = s.value("last_refreshed_" + name_).toDateTime();
data_.clear();
const int count = s.beginReadArray(name_ + "_data");
for (int i=0 ; i<count ; ++i) {
s.setArrayIndex(i);
data_ << s.value("value").value<T>();
}
s.endArray();
}
void Save() const {
QSettings s;
s.beginGroup(settings_group_);
s.setValue("last_refreshed_" + name_, last_updated_);
s.beginWriteArray(name_ + "_data", data_.size());
for (int i=0 ; i<data_.size() ; ++i) {
s.setArrayIndex(i);
s.setValue("value", QVariant::fromValue(data_[i]));
}
s.endArray();
}
void Update(const ListType& data) {
data_ = data;
last_updated_ = QDateTime::currentDateTime();
Save();
}
bool IsStale() const {
return last_updated_.isNull() ||
last_updated_.secsTo(QDateTime::currentDateTime()) > cache_duration_secs_;
}
const ListType& Data() const { return data_; }
operator ListType() const { return data_; }
const_iterator begin() const { return data_.begin(); }
const_iterator end() const { return data_.end(); }
private:
const char* settings_group_;
const QString name_;
const int cache_duration_secs_;
QDateTime last_updated_;
ListType data_;
};
#endif // CACHEDLIST_H

View File

@ -137,18 +137,20 @@ DigitallyImportedClient::ParseChannelList(QNetworkReply* reply) const {
return ret;
}
void DigitallyImportedClient::Channel::Load(const QSettings& s) {
art_url_ = s.value("art_url").toUrl();
director_ = s.value("director").toString();
description_ = s.value("description").toString();
name_ = s.value("name").toString();
key_ = s.value("key").toString();
QDataStream& operator<<(QDataStream& out, const DigitallyImportedClient::Channel& channel) {
out << channel.art_url_
<< channel.director_
<< channel.description_
<< channel.name_
<< channel.key_;
return out;
}
void DigitallyImportedClient::Channel::Save(QSettings* s) const {
s->setValue("art_url", art_url_);
s->setValue("director", director_);
s->setValue("description", description_);
s->setValue("name", name_);
s->setValue("key", key_);
QDataStream& operator>>(QDataStream& in, DigitallyImportedClient::Channel& channel) {
in >> channel.art_url_
>> channel.director_
>> channel.description_
>> channel.name_
>> channel.key_;
return in;
}

View File

@ -59,9 +59,6 @@ public:
QString name_;
QString key_;
void Save(QSettings* s) const;
void Load(const QSettings& s);
bool operator <(const Channel& other) const { return name_ < other.name_; }
};
typedef QList<Channel> ChannelList;
@ -81,4 +78,8 @@ private:
QString service_name_;
};
QDataStream& operator<<(QDataStream& out, const DigitallyImportedClient::Channel& channel);
QDataStream& operator>>(QDataStream& in, DigitallyImportedClient::Channel& channel);
Q_DECLARE_METATYPE(DigitallyImportedClient::Channel)
#endif // DIGITALLYIMPORTEDCLIENT_H

View File

@ -56,6 +56,7 @@ DigitallyImportedServiceBase::DigitallyImportedServiceBase(
premium_audio_type_(2),
root_(NULL),
context_item_(NULL),
saved_channels_(kSettingsGroup, api_service_name, kStreamsCacheDurationSecs),
api_client_(new DigitallyImportedClient(api_service_name, this))
{
model->player()->RegisterUrlHandler(url_handler_);
@ -112,14 +113,13 @@ void DigitallyImportedServiceBase::RefreshStreamsFinished(QNetworkReply* reply,
model()->task_manager()->SetTaskFinished(task_id);
reply->deleteLater();
saved_channels_ = api_client_->ParseChannelList(reply);
// Parse the list and sort by name
DigitallyImportedClient::ChannelList channels = api_client_->ParseChannelList(reply);
qSort(channels);
// Sort by name
qSort(saved_channels_);
saved_channels_.Update(channels);
SaveChannels(saved_channels_);
PopulateStreams();
emit StreamsChanged();
}
@ -161,8 +161,7 @@ void DigitallyImportedServiceBase::ReloadSettings() {
premium_audio_type_ = s.value("premium_audio_type", 2).toInt();
username_ = s.value("username").toString();
listen_hash_ = s.value("listen_hash").toString();
last_refreshed_channels_ = s.value("last_refreshed_" + api_service_name_).toDateTime();
saved_channels_ = LoadChannels();
saved_channels_.Load();
}
void DigitallyImportedServiceBase::ShowContextMenu(
@ -210,48 +209,6 @@ void DigitallyImportedServiceBase::ShowSettingsDialog() {
emit OpenSettingsAtPage(SettingsDialog::Page_DigitallyImported);
}
DigitallyImportedClient::ChannelList DigitallyImportedServiceBase::LoadChannels() const {
DigitallyImportedClient::ChannelList ret;
QSettings s;
s.beginGroup(kSettingsGroup);
int count = s.beginReadArray(api_service_name_);
for (int i=0 ; i<count ; ++i) {
s.setArrayIndex(i);
DigitallyImportedClient::Channel channel;
channel.Load(s);
ret << channel;
}
s.endArray();
return ret;
}
void DigitallyImportedServiceBase::SaveChannels(
const DigitallyImportedClient::ChannelList& channels) {
QSettings s;
s.beginGroup(kSettingsGroup);
s.beginWriteArray(api_service_name_, channels.count());
for (int i=0 ; i<channels.count() ; ++i) {
s.setArrayIndex(i);
channels[i].Save(&s);
}
s.endArray();
last_refreshed_channels_ = QDateTime::currentDateTime();
s.setValue("last_refreshed_" + api_service_name_, last_refreshed_channels_);
}
bool DigitallyImportedServiceBase::IsChannelListStale() const {
return last_refreshed_channels_.isNull() ||
last_refreshed_channels_.secsTo(QDateTime::currentDateTime()) >
kStreamsCacheDurationSecs;
}
DigitallyImportedClient::ChannelList DigitallyImportedServiceBase::Channels() {
if (IsChannelListStale()) {
metaObject()->invokeMethod(this, "ForceRefreshStreams", Qt::QueuedConnection);

View File

@ -20,6 +20,7 @@
#include "digitallyimportedclient.h"
#include "internetservice.h"
#include "core/cachedlist.h"
#include <boost/scoped_ptr.hpp>
@ -59,7 +60,7 @@ public:
const QString& service_description() const { return service_description_; }
const QString& api_service_name() const { return api_service_name_; }
bool IsChannelListStale() const;
bool IsChannelListStale() const { return saved_channels_.IsStale(); }
DigitallyImportedClient::ChannelList Channels();
void SongFromChannel(const DigitallyImportedClient::Channel& channel,
Song* song) const;
@ -80,8 +81,6 @@ private slots:
private:
void PopulateStreams();
DigitallyImportedClient::ChannelList LoadChannels() const;
void SaveChannels(const DigitallyImportedClient::ChannelList& streams);
void LoadStation(const QString& key);
@ -108,8 +107,7 @@ private:
boost::scoped_ptr<QMenu> context_menu_;
QStandardItem* context_item_;
DigitallyImportedClient::ChannelList saved_channels_;
QDateTime last_refreshed_channels_;
CachedList<DigitallyImportedClient::Channel> saved_channels_;
DigitallyImportedClient* api_client_;
};

View File

@ -87,6 +87,7 @@ LastFMService::LastFMService(InternetModel* parent)
custom_list_(NULL),
friends_list_(NULL),
neighbours_list_(NULL),
friend_names_(kSettingsGroup, "friend_names", kFriendsCacheDurationSecs),
connection_problems_(false)
{
//we emit the signal the first time to be sure the buttons are in the right state
@ -130,9 +131,7 @@ void LastFMService::ReloadSettings() {
scrobbling_enabled_ = settings.value("ScrobblingEnabled", true).toBool();
buttons_visible_ = settings.value("ShowLoveBanButtons", true).toBool();
scrobble_button_visible_ = settings.value("ShowScrobbleButton", true).toBool();
last_refreshed_friends_ = settings.value("LastRefreshedFriends").toDateTime();
friend_names_ = settings.value("FriendNames").toStringList();
friend_names_.Load();
//avoid emitting signal if it's not changed
if(scrobbling_enabled_old != scrobbling_enabled_)
@ -281,16 +280,13 @@ void LastFMService::SignOut() {
lastfm::ws::Username.clear();
lastfm::ws::SessionKey.clear();
friend_names_ = QStringList();
last_refreshed_friends_ = QDateTime();
friend_names_.Update(QStringList());
QSettings settings;
settings.beginGroup(kSettingsGroup);
settings.setValue("Username", QString());
settings.setValue("Session", QString());
settings.setValue("FriendNames", friend_names_);
settings.setValue("LastRefreshedFriends", last_refreshed_friends_);
}
void LastFMService::AuthenticateReplyFinished() {
@ -589,20 +585,12 @@ void LastFMService::ShowContextMenu(const QModelIndex& index, const QPoint &glob
context_menu_->popup(global_pos);
}
bool LastFMService::IsFriendsListStale() const {
return last_refreshed_friends_.isNull() ||
last_refreshed_friends_.secsTo(QDateTime::currentDateTime()) >
kFriendsCacheDurationSecs;
}
QStringList LastFMService::FriendNames() {
// Update the list for next time, in the main thread.
if (IsFriendsListStale())
metaObject()->invokeMethod(this, "RefreshFriends", Qt::QueuedConnection);
QSettings s;
s.beginGroup(LastFMService::kSettingsGroup);
return s.value("FriendNames").toStringList();
return friend_names_.Data();
}
static QStringList SavedArtistOrTagRadioNames(const QString& name) {
@ -682,20 +670,14 @@ void LastFMService::RefreshFriendsFinished() {
return;
}
last_refreshed_friends_ = QDateTime::currentDateTime();
friend_names_ = QStringList();
QStringList names;
foreach (const lastfm::User& f, friends) {
friend_names_ << f.name();
names << f.name();
}
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("FriendNames", friend_names_);
s.setValue("LastRefreshedFriends", last_refreshed_friends_);
friend_names_.Update(names);
PopulateFriendsList();
emit SavedItemsChanged();
}

View File

@ -33,6 +33,7 @@ uint qHash(const lastfm::Track& track);
#include "internetmodel.h"
#include "internetservice.h"
#include "lastfmstationdialog.h"
#include "core/cachedlist.h"
#include "core/song.h"
#include "playlist/playlistitem.h"
@ -111,7 +112,7 @@ class LastFMService : public InternetService {
PlaylistItemPtr PlaylistItemForUrl(const QUrl& url);
bool IsFriendsListStale() const;
bool IsFriendsListStale() const { return friend_names_.IsStale(); }
// Thread safe
QStringList FriendNames();
@ -225,8 +226,7 @@ class LastFMService : public InternetService {
QHash<lastfm::Track, QString> art_urls_;
QStringList friend_names_;
QDateTime last_refreshed_friends_;
CachedList<QString> friend_names_;
// Useful to inform the user that we can't scrobble right now
bool connection_problems_;

View File

@ -44,6 +44,7 @@
#include "covers/coverproviders.h"
#include "engines/enginebase.h"
#include "globalsearch/globalsearch.h"
#include "internet/digitallyimportedclient.h"
#include "internet/internetmodel.h"
#include "library/directory.h"
#include "playlist/playlist.h"
@ -227,6 +228,8 @@ int main(int argc, char *argv[]) {
qRegisterMetaType<QList<QNetworkCookie> >("QList<QNetworkCookie>");
qRegisterMetaType<SearchProvider::Result>("SearchProvider::Result");
qRegisterMetaType<SearchProvider::ResultList>("SearchProvider::ResultList");
qRegisterMetaType<DigitallyImportedClient::Channel>("DigitallyImportedClient::Channel");
qRegisterMetaTypeStreamOperators<DigitallyImportedClient::Channel>("DigitallyImportedClient::Channel");
qRegisterMetaType<GstBuffer*>("GstBuffer*");
qRegisterMetaType<GstElement*>("GstElement*");

View File

@ -589,7 +589,7 @@ msgstr ""
msgid "An error occurred writing metadata to '%1'"
msgstr ""
#: internet/lastfmservice.cpp:918
#: internet/lastfmservice.cpp:900
#, qt-format
msgid "An unknown last.fm error occurred: %1"
msgstr ""
@ -646,7 +646,7 @@ msgstr ""
msgid "Artist info"
msgstr ""
#: internet/lastfmservice.cpp:190
#: internet/lastfmservice.cpp:189
msgid "Artist radio"
msgstr ""
@ -667,7 +667,7 @@ msgid "Authenticating..."
msgstr ""
#: internet/digitallyimportedsettingspage.cpp:82
#: internet/magnatunesettingspage.cpp:113 internet/lastfmservice.cpp:434
#: internet/magnatunesettingspage.cpp:113 internet/lastfmservice.cpp:430
#: internet/lastfmsettingspage.cpp:79 remote/remotesettingspage.cpp:113
msgid "Authentication failed"
msgstr ""
@ -987,7 +987,7 @@ msgstr ""
msgid "Configure Grooveshark..."
msgstr ""
#: internet/lastfmservice.cpp:108
#: internet/lastfmservice.cpp:109
msgid "Configure Last.fm..."
msgstr ""
@ -1007,7 +1007,7 @@ msgstr ""
msgid "Configure library..."
msgstr ""
#: internet/digitallyimportedservicebase.cpp:181
#: internet/digitallyimportedservicebase.cpp:180
#: ../bin/src/ui_globalsearchsettingspage.h:167
msgid "Configure..."
msgstr ""
@ -1071,7 +1071,7 @@ msgid ""
"plugins installed"
msgstr ""
#: internet/lastfmservice.cpp:915
#: internet/lastfmservice.cpp:897
msgid "Couldn't load the last.fm radio station"
msgstr ""
@ -1204,7 +1204,7 @@ msgstr ""
msgid "Custom message settings"
msgstr ""
#: internet/lastfmservice.cpp:198
#: internet/lastfmservice.cpp:197
msgid "Custom radio"
msgstr ""
@ -1606,7 +1606,7 @@ msgstr ""
msgid "Error loading %1"
msgstr ""
#: internet/digitallyimportedservicebase.cpp:203
#: internet/digitallyimportedservicebase.cpp:202
#: internet/digitallyimportedurlhandler.cpp:73
msgid "Error loading di.fm playlist"
msgstr ""
@ -1829,7 +1829,7 @@ msgstr ""
msgid "Frames per buffer"
msgstr ""
#: internet/lastfmservice.cpp:206
#: internet/lastfmservice.cpp:205
msgid "Friends"
msgstr ""
@ -1867,7 +1867,7 @@ msgstr ""
msgid "Getting channels"
msgstr ""
#: internet/digitallyimportedservicebase.cpp:103
#: internet/digitallyimportedservicebase.cpp:104
msgid "Getting streams"
msgstr ""
@ -2080,31 +2080,31 @@ msgstr ""
msgid "Internet providers"
msgstr ""
#: internet/lastfmservice.cpp:440
#: internet/lastfmservice.cpp:436
msgid "Invalid API key"
msgstr ""
#: internet/lastfmservice.cpp:435
#: internet/lastfmservice.cpp:431
msgid "Invalid format"
msgstr ""
#: internet/lastfmservice.cpp:433
#: internet/lastfmservice.cpp:429
msgid "Invalid method"
msgstr ""
#: internet/lastfmservice.cpp:436
#: internet/lastfmservice.cpp:432
msgid "Invalid parameters"
msgstr ""
#: internet/lastfmservice.cpp:437
#: internet/lastfmservice.cpp:433
msgid "Invalid resource specified"
msgstr ""
#: internet/lastfmservice.cpp:432
#: internet/lastfmservice.cpp:428
msgid "Invalid service"
msgstr ""
#: internet/lastfmservice.cpp:439
#: internet/lastfmservice.cpp:435
msgid "Invalid session key"
msgstr ""
@ -2198,25 +2198,25 @@ msgstr ""
msgid "Last.fm Custom Radio: %1"
msgstr ""
#: internet/lastfmservice.cpp:237 internet/lastfmservice.cpp:709
#: internet/lastfmservice.cpp:744
#: internet/lastfmservice.cpp:236 internet/lastfmservice.cpp:691
#: internet/lastfmservice.cpp:726
#, qt-format
msgid "Last.fm Library - %1"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:69 internet/lastfmservice.cpp:239
#: internet/lastfmservice.cpp:242
#: globalsearch/lastfmsearchprovider.cpp:69 internet/lastfmservice.cpp:238
#: internet/lastfmservice.cpp:241
#, qt-format
msgid "Last.fm Mix Radio - %1"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:71 internet/lastfmservice.cpp:244
#: internet/lastfmservice.cpp:247
#: globalsearch/lastfmsearchprovider.cpp:71 internet/lastfmservice.cpp:243
#: internet/lastfmservice.cpp:246
#, qt-format
msgid "Last.fm Neighbor Radio - %1"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:67 internet/lastfmservice.cpp:234
#: globalsearch/lastfmsearchprovider.cpp:67 internet/lastfmservice.cpp:233
#, qt-format
msgid "Last.fm Radio Station - %1"
msgstr ""
@ -2231,7 +2231,7 @@ msgstr ""
msgid "Last.fm Tag Radio: %1"
msgstr ""
#: internet/lastfmservice.cpp:444
#: internet/lastfmservice.cpp:440
msgid "Last.fm is currently busy, please try again in a few minutes"
msgstr ""
@ -2320,7 +2320,7 @@ msgstr ""
msgid "Load playlist..."
msgstr ""
#: internet/lastfmservice.cpp:928
#: internet/lastfmservice.cpp:910
msgid "Loading Last.fm radio"
msgstr ""
@ -2449,7 +2449,7 @@ msgstr ""
msgid "Make playlist available offline"
msgstr ""
#: internet/lastfmservice.cpp:451
#: internet/lastfmservice.cpp:447
msgid "Malformed response"
msgstr ""
@ -2549,35 +2549,35 @@ msgstr ""
msgid "Mute"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:45 internet/lastfmservice.cpp:177
#: globalsearch/lastfmsearchprovider.cpp:45 internet/lastfmservice.cpp:176
msgid "My Last.fm Library"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:47 internet/lastfmservice.cpp:182
#: globalsearch/lastfmsearchprovider.cpp:47 internet/lastfmservice.cpp:181
msgid "My Last.fm Mix Radio"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:49 internet/lastfmservice.cpp:187
#: globalsearch/lastfmsearchprovider.cpp:49 internet/lastfmservice.cpp:186
msgid "My Last.fm Neighborhood"
msgstr ""
#: globalsearch/lastfmsearchprovider.cpp:43 internet/lastfmservice.cpp:172
#: globalsearch/lastfmsearchprovider.cpp:43 internet/lastfmservice.cpp:171
msgid "My Last.fm Recommended Radio"
msgstr ""
#: internet/lastfmservice.cpp:179
#: internet/lastfmservice.cpp:178
msgid "My Mix Radio"
msgstr ""
#: internet/lastfmservice.cpp:184
#: internet/lastfmservice.cpp:183
msgid "My Neighborhood"
msgstr ""
#: internet/lastfmservice.cpp:174
#: internet/lastfmservice.cpp:173
msgid "My Radio Station"
msgstr ""
#: internet/lastfmservice.cpp:169
#: internet/lastfmservice.cpp:168
msgid "My Recommendations"
msgstr ""
@ -2597,7 +2597,7 @@ msgstr ""
msgid "Narrow band (NB)"
msgstr ""
#: internet/lastfmservice.cpp:211
#: internet/lastfmservice.cpp:210
msgid "Neighbors"
msgstr ""
@ -2689,19 +2689,19 @@ msgstr ""
msgid "Not connected"
msgstr ""
#: internet/lastfmservice.cpp:446
#: internet/lastfmservice.cpp:442
msgid "Not enough content"
msgstr ""
#: internet/lastfmservice.cpp:448
#: internet/lastfmservice.cpp:444
msgid "Not enough fans"
msgstr ""
#: internet/lastfmservice.cpp:447
#: internet/lastfmservice.cpp:443
msgid "Not enough members"
msgstr ""
#: internet/lastfmservice.cpp:449
#: internet/lastfmservice.cpp:445
msgid "Not enough neighbors"
msgstr ""
@ -2750,7 +2750,7 @@ msgstr ""
msgid "Only show the first"
msgstr ""
#: internet/digitallyimportedservicebase.cpp:174
#: internet/digitallyimportedservicebase.cpp:173
#, qt-format
msgid "Open %1 in browser"
msgstr ""
@ -2794,7 +2794,7 @@ msgstr ""
msgid "Open..."
msgstr ""
#: internet/lastfmservice.cpp:438
#: internet/lastfmservice.cpp:434
msgid "Operation failed"
msgstr ""
@ -2893,7 +2893,7 @@ msgstr ""
msgid "Play Artist or Tag"
msgstr ""
#: internet/lastfmservice.cpp:100
#: internet/lastfmservice.cpp:101
msgid "Play artist radio..."
msgstr ""
@ -2901,7 +2901,7 @@ msgstr ""
msgid "Play count"
msgstr ""
#: internet/lastfmservice.cpp:104
#: internet/lastfmservice.cpp:105
msgid "Play custom radio..."
msgstr ""
@ -2926,7 +2926,7 @@ msgstr ""
msgid "Play last.fm tag radio"
msgstr ""
#: internet/lastfmservice.cpp:102
#: internet/lastfmservice.cpp:103
msgid "Play tag radio..."
msgstr ""
@ -3152,7 +3152,7 @@ msgstr ""
msgid "Refresh channels"
msgstr ""
#: internet/lastfmservice.cpp:106
#: internet/lastfmservice.cpp:107
msgid "Refresh friends list"
msgstr ""
@ -3160,7 +3160,7 @@ msgstr ""
msgid "Refresh station list"
msgstr ""
#: internet/digitallyimportedservicebase.cpp:177
#: internet/digitallyimportedservicebase.cpp:176
msgid "Refresh streams"
msgstr ""
@ -3180,7 +3180,7 @@ msgstr ""
msgid "Remote Control"
msgstr ""
#: internet/savedradio.cpp:94 internet/lastfmservice.cpp:97
#: internet/savedradio.cpp:94 internet/lastfmservice.cpp:98
#: ../bin/src/ui_queuemanager.h:135 ../bin/src/ui_searchtermwidget.h:282
#: ../bin/src/ui_transcodedialog.h:207
msgid "Remove"
@ -3445,7 +3445,7 @@ msgstr ""
msgid "Serial number"
msgstr ""
#: internet/lastfmservice.cpp:441
#: internet/lastfmservice.cpp:437
msgid "Service offline"
msgstr ""
@ -3828,7 +3828,7 @@ msgstr ""
msgid "Tag fetcher"
msgstr ""
#: internet/lastfmservice.cpp:194
#: internet/lastfmservice.cpp:193
msgid "Tag radio"
msgstr ""
@ -3967,7 +3967,7 @@ msgid ""
"want to continue?"
msgstr ""
#: internet/lastfmservice.cpp:442
#: internet/lastfmservice.cpp:438
msgid "This stream is for paid subscribers only"
msgstr ""
@ -4085,7 +4085,7 @@ msgstr ""
msgid "Unknown"
msgstr ""
#: internet/digitallyimportedclient.cpp:68 internet/lastfmservice.cpp:455
#: internet/digitallyimportedclient.cpp:68 internet/lastfmservice.cpp:451
msgid "Unknown error"
msgstr ""