Cache di.fm and sky.fm streams for 2 weeks
This commit is contained in:
parent
e1529cc5bb
commit
e7ab192361
@ -30,6 +30,8 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
const char* DigitallyImportedServiceBase::kSettingsGroup = "digitally_imported";
|
const char* DigitallyImportedServiceBase::kSettingsGroup = "digitally_imported";
|
||||||
|
const int DigitallyImportedServiceBase::kStreamsCacheDurationSecs =
|
||||||
|
60 * 60 * 24 * 14; // 2 weeks
|
||||||
|
|
||||||
|
|
||||||
DigitallyImportedServiceBase::DigitallyImportedServiceBase(
|
DigitallyImportedServiceBase::DigitallyImportedServiceBase(
|
||||||
@ -72,6 +74,15 @@ void DigitallyImportedServiceBase::LazyPopulate(QStandardItem* parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DigitallyImportedServiceBase::RefreshStreams() {
|
void DigitallyImportedServiceBase::RefreshStreams() {
|
||||||
|
if (IsStreamListStale()) {
|
||||||
|
ForceRefreshStreams();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PopulateStreams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitallyImportedServiceBase::ForceRefreshStreams() {
|
||||||
if (task_id_ != -1) {
|
if (task_id_ != -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -105,7 +116,7 @@ void DigitallyImportedServiceBase::RefreshStreamsFinished() {
|
|||||||
"\"name\":\"([^\"]+)\","
|
"\"name\":\"([^\"]+)\","
|
||||||
"\"description\":\"([^\"]+)\"");
|
"\"description\":\"([^\"]+)\"");
|
||||||
|
|
||||||
QList<Stream> streams;
|
saved_streams_.clear();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while (pos >= 0) {
|
while (pos >= 0) {
|
||||||
@ -120,14 +131,22 @@ void DigitallyImportedServiceBase::RefreshStreamsFinished() {
|
|||||||
stream.key_ = re.cap(2).replace("\\/", "/");
|
stream.key_ = re.cap(2).replace("\\/", "/");
|
||||||
stream.name_ = re.cap(3).replace("\\/", "/");
|
stream.name_ = re.cap(3).replace("\\/", "/");
|
||||||
stream.description_ = re.cap(4).replace("\\/", "/");
|
stream.description_ = re.cap(4).replace("\\/", "/");
|
||||||
streams << stream;
|
saved_streams_ << stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by name
|
// Sort by name
|
||||||
qSort(streams);
|
qSort(saved_streams_);
|
||||||
|
|
||||||
|
SaveStreams(saved_streams_);
|
||||||
|
PopulateStreams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitallyImportedServiceBase::PopulateStreams() {
|
||||||
|
if (root_->hasChildren())
|
||||||
|
root_->removeRows(0, root_->rowCount());
|
||||||
|
|
||||||
// Add each stream to the model
|
// Add each stream to the model
|
||||||
foreach (const Stream& stream, streams) {
|
foreach (const Stream& stream, saved_streams_) {
|
||||||
Song song;
|
Song song;
|
||||||
song.set_title(stream.name_);
|
song.set_title(stream.name_);
|
||||||
song.set_artist(service_description_);
|
song.set_artist(service_description_);
|
||||||
@ -153,6 +172,8 @@ void DigitallyImportedServiceBase::ReloadSettings() {
|
|||||||
audio_type_ = s.value("audio_type", 0).toInt();
|
audio_type_ = s.value("audio_type", 0).toInt();
|
||||||
username_ = s.value("username").toString();
|
username_ = s.value("username").toString();
|
||||||
password_ = s.value("password").toString();
|
password_ = s.value("password").toString();
|
||||||
|
last_refreshed_streams_ = s.value("last_refreshed_" + url_scheme_).toDateTime();
|
||||||
|
saved_streams_ = LoadStreams();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DigitallyImportedServiceBase::ShowContextMenu(
|
void DigitallyImportedServiceBase::ShowContextMenu(
|
||||||
@ -165,7 +186,7 @@ void DigitallyImportedServiceBase::ShowContextMenu(
|
|||||||
this, SLOT(Homepage()));
|
this, SLOT(Homepage()));
|
||||||
context_menu_->addAction(IconLoader::Load("view-refresh"),
|
context_menu_->addAction(IconLoader::Load("view-refresh"),
|
||||||
tr("Refresh streams"),
|
tr("Refresh streams"),
|
||||||
this, SLOT(RefreshStreams()));
|
this, SLOT(ForceRefreshStreams()));
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
context_menu_->addAction(IconLoader::Load("configure"),
|
context_menu_->addAction(IconLoader::Load("configure"),
|
||||||
tr("Configure..."),
|
tr("Configure..."),
|
||||||
@ -219,3 +240,58 @@ void DigitallyImportedServiceBase::LoadPlaylistFinished() {
|
|||||||
void DigitallyImportedServiceBase::ShowSettingsDialog() {
|
void DigitallyImportedServiceBase::ShowSettingsDialog() {
|
||||||
emit OpenSettingsAtPage(SettingsDialog::Page_DigitallyImported);
|
emit OpenSettingsAtPage(SettingsDialog::Page_DigitallyImported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DigitallyImportedServiceBase::StreamList DigitallyImportedServiceBase::LoadStreams() const {
|
||||||
|
StreamList ret;
|
||||||
|
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
int count = s.beginReadArray(url_scheme_);
|
||||||
|
for (int i=0 ; i<count ; ++i) {
|
||||||
|
s.setArrayIndex(i);
|
||||||
|
|
||||||
|
Stream stream;
|
||||||
|
stream.id_ = s.value("id").toInt();
|
||||||
|
stream.key_ = s.value("key").toString();
|
||||||
|
stream.name_ = s.value("name").toString();
|
||||||
|
stream.description_ = s.value("description").toString();
|
||||||
|
ret << stream;
|
||||||
|
}
|
||||||
|
s.endArray();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitallyImportedServiceBase::SaveStreams(const StreamList& streams) {
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
s.beginWriteArray(url_scheme_, streams.count());
|
||||||
|
for (int i=0 ; i<streams.count() ; ++i) {
|
||||||
|
const Stream& stream = streams[i];
|
||||||
|
s.setArrayIndex(i);
|
||||||
|
s.setValue("id", stream.id_);
|
||||||
|
s.setValue("key", stream.key_);
|
||||||
|
s.setValue("name", stream.name_);
|
||||||
|
s.setValue("description", stream.description_);
|
||||||
|
}
|
||||||
|
s.endArray();
|
||||||
|
|
||||||
|
last_refreshed_streams_ = QDateTime::currentDateTime();
|
||||||
|
s.setValue("last_refreshed_" + url_scheme_, last_refreshed_streams_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DigitallyImportedServiceBase::IsStreamListStale() const {
|
||||||
|
return last_refreshed_streams_.isNull() ||
|
||||||
|
last_refreshed_streams_.secsTo(QDateTime::currentDateTime()) >
|
||||||
|
kStreamsCacheDurationSecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
DigitallyImportedServiceBase::StreamList DigitallyImportedServiceBase::Streams() {
|
||||||
|
if (IsStreamListStale()) {
|
||||||
|
metaObject()->invokeMethod(this, "ForceRefreshStreams", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saved_streams_;
|
||||||
|
}
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
~DigitallyImportedServiceBase();
|
~DigitallyImportedServiceBase();
|
||||||
|
|
||||||
static const char* kSettingsGroup;
|
static const char* kSettingsGroup;
|
||||||
|
static const int kStreamsCacheDurationSecs;
|
||||||
|
|
||||||
QStandardItem* CreateRootItem();
|
QStandardItem* CreateRootItem();
|
||||||
void LazyPopulate(QStandardItem* parent);
|
void LazyPopulate(QStandardItem* parent);
|
||||||
@ -49,6 +50,20 @@ public:
|
|||||||
bool is_premium_stream_selected() const;
|
bool is_premium_stream_selected() const;
|
||||||
bool is_premium_account() const;
|
bool is_premium_account() const;
|
||||||
|
|
||||||
|
// Public for the global search provider.
|
||||||
|
struct Stream {
|
||||||
|
int id_;
|
||||||
|
QString key_;
|
||||||
|
QString name_;
|
||||||
|
QString description_;
|
||||||
|
|
||||||
|
bool operator <(const Stream& other) const { return name_ < other.name_; }
|
||||||
|
};
|
||||||
|
typedef QList<Stream> StreamList;
|
||||||
|
|
||||||
|
bool IsStreamListStale() const;
|
||||||
|
StreamList Streams();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Playlist {
|
struct Playlist {
|
||||||
Playlist(bool premium, const QString& url_template)
|
Playlist(bool premium, const QString& url_template)
|
||||||
@ -69,6 +84,7 @@ protected slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void Homepage();
|
void Homepage();
|
||||||
|
void ForceRefreshStreams();
|
||||||
void RefreshStreams();
|
void RefreshStreams();
|
||||||
void RefreshStreamsFinished();
|
void RefreshStreamsFinished();
|
||||||
void ShowSettingsDialog();
|
void ShowSettingsDialog();
|
||||||
@ -86,14 +102,9 @@ protected:
|
|||||||
QList<Playlist> playlists_;
|
QList<Playlist> playlists_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Stream {
|
void PopulateStreams();
|
||||||
int id_;
|
StreamList LoadStreams() const;
|
||||||
QString key_;
|
void SaveStreams(const StreamList& streams);
|
||||||
QString name_;
|
|
||||||
QString description_;
|
|
||||||
|
|
||||||
bool operator <(const Stream& other) const { return name_ < other.name_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Set by subclasses through the constructor
|
// Set by subclasses through the constructor
|
||||||
@ -108,6 +119,9 @@ private:
|
|||||||
|
|
||||||
QMenu* context_menu_;
|
QMenu* context_menu_;
|
||||||
QStandardItem* context_item_;
|
QStandardItem* context_item_;
|
||||||
|
|
||||||
|
QList<Stream> saved_streams_;
|
||||||
|
QDateTime last_refreshed_streams_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DIGITALLYIMPORTEDSERVICEBASE_H
|
#endif // DIGITALLYIMPORTEDSERVICEBASE_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user