mirror of
https://github.com/clementine-player/Clementine
synced 2025-02-03 04:37:33 +01:00
"Now listening" last.fm notifications
This commit is contained in:
parent
62dda6430c
commit
38feb17697
@ -39,5 +39,7 @@
|
||||
<file>last.fm/personal_radio.png</file>
|
||||
<file>last.fm/recommended_radio.png</file>
|
||||
<file>spinner.gif</file>
|
||||
<file>last.fm/ban.png</file>
|
||||
<file>last.fm/love.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
BIN
data/last.fm/ban.png
Normal file
BIN
data/last.fm/ban.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
data/last.fm/love.png
Normal file
BIN
data/last.fm/love.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -6,18 +6,24 @@
|
||||
#include <lastfm/ws.h>
|
||||
#include <lastfm/misc.h>
|
||||
#include <lastfm/XmlQuery>
|
||||
#include <lastfm/Audioscrobbler>
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
const char* LastFMService::kServiceName = "Last.fm";
|
||||
const char* LastFMService::kSettingsGroup = "Last.fm";
|
||||
const char* LastFMService::kAudioscrobblerClientId = "tng";
|
||||
const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09";
|
||||
const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70";
|
||||
|
||||
LastFMService::LastFMService(QObject* parent)
|
||||
: RadioService("Last.fm", parent),
|
||||
: RadioService(kServiceName, parent),
|
||||
tuner_(NULL),
|
||||
scrobbler_(NULL),
|
||||
initial_tune_(false)
|
||||
{
|
||||
lastfm::ws::ApiKey = "75d20fb472be99275392aefa2760ea09";
|
||||
lastfm::ws::SharedSecret = "d3072b60ae626be12be69448f5c46e70";
|
||||
lastfm::ws::ApiKey = kApiKey;
|
||||
lastfm::ws::SharedSecret = kSecret;
|
||||
|
||||
QSettings settings;
|
||||
settings.beginGroup(kSettingsGroup);
|
||||
@ -31,6 +37,10 @@ LastFMService::~LastFMService() {
|
||||
delete config_;
|
||||
}
|
||||
|
||||
bool LastFMService::IsAuthenticated() const {
|
||||
return !lastfm::ws::SessionKey.isEmpty();
|
||||
}
|
||||
|
||||
RadioItem* LastFMService::CreateRootItem(RadioItem* parent) {
|
||||
RadioItem* item = new RadioItem(this, RadioItem::Type_Service, "Last.fm", parent);
|
||||
item->icon = QIcon(":last.fm/as.png");
|
||||
@ -50,7 +60,7 @@ void LastFMService::LazyPopulate(RadioItem *item) {
|
||||
CreateStationItem(Type_MyNeighbourhood, "My Neighbourhood",
|
||||
":last.fm/neighbour_radio.png", item);
|
||||
|
||||
if (lastfm::ws::SessionKey.isEmpty())
|
||||
if (!IsAuthenticated())
|
||||
config_->show();
|
||||
break;
|
||||
|
||||
@ -106,6 +116,10 @@ void LastFMService::AuthenticateReplyFinished() {
|
||||
settings.setValue("username", lastfm::ws::Username);
|
||||
settings.setValue("session", lastfm::ws::SessionKey);
|
||||
|
||||
// Invalidate the scrobbler - it will get recreated later
|
||||
delete scrobbler_;
|
||||
scrobbler_ = NULL;
|
||||
|
||||
emit AuthenticationComplete(true);
|
||||
}
|
||||
|
||||
@ -142,7 +156,7 @@ QList<RadioItem::PlaylistData> LastFMService::DataForItem(RadioItem* item) {
|
||||
void LastFMService::StartLoading(const QUrl& url) {
|
||||
if (url.scheme() != "lastfm")
|
||||
return;
|
||||
if (lastfm::ws::SessionKey.isEmpty())
|
||||
if (!IsAuthenticated())
|
||||
return;
|
||||
|
||||
emit LoadingStarted();
|
||||
@ -158,18 +172,18 @@ void LastFMService::StartLoading(const QUrl& url) {
|
||||
}
|
||||
|
||||
void LastFMService::LoadNext(const QUrl &) {
|
||||
lastfm::Track track = tuner_->takeNextTrack();
|
||||
last_track_ = tuner_->takeNextTrack();
|
||||
|
||||
if (track.isNull()) {
|
||||
if (last_track_.isNull()) {
|
||||
emit StreamFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
emit StreamReady(last_url_, track.url());
|
||||
|
||||
Song metadata;
|
||||
metadata.InitFromLastFM(track);
|
||||
metadata.InitFromLastFM(last_track_);
|
||||
|
||||
emit StreamMetadataFound(last_url_, metadata);
|
||||
emit StreamReady(last_url_, last_track_.url());
|
||||
}
|
||||
|
||||
void LastFMService::TunerError(lastfm::ws::Error error) {
|
||||
@ -224,3 +238,60 @@ void LastFMService::TunerTrackAvailable() {
|
||||
initial_tune_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool LastFMService::InitScrobbler() {
|
||||
if (!IsAuthenticated())
|
||||
return false;
|
||||
|
||||
if (!scrobbler_) {
|
||||
scrobbler_ = new lastfm::Audioscrobbler(kAudioscrobblerClientId);
|
||||
connect(scrobbler_, SIGNAL(status(int)), SLOT(ScrobblerStatus(int)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
lastfm::Track LastFMService::TrackFromSong(const Song &song) const {
|
||||
qDebug() << song.title() << last_track_.title();
|
||||
qDebug() << song.artist() << last_track_.artist();
|
||||
qDebug() << song.album() << last_track_.album();
|
||||
qDebug() << last_track_.fingerprintId() << last_track_.mbid();
|
||||
|
||||
if (song.title() == last_track_.title() &&
|
||||
song.artist() == last_track_.artist() &&
|
||||
song.album() == last_track_.album())
|
||||
return last_track_;
|
||||
|
||||
lastfm::Track ret;
|
||||
song.ToLastFM(&ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void LastFMService::NowPlaying(const Song &song) {
|
||||
if (!InitScrobbler())
|
||||
return;
|
||||
|
||||
scrobbler_->nowPlaying(TrackFromSong(song));
|
||||
}
|
||||
|
||||
void LastFMService::Scrobble(const Song& song) {
|
||||
if (!InitScrobbler())
|
||||
return;
|
||||
|
||||
scrobbler_->cache(TrackFromSong(song));
|
||||
}
|
||||
|
||||
void LastFMService::Love(const Song& song) {
|
||||
lastfm::MutableTrack mtrack(TrackFromSong(song));
|
||||
mtrack.love();
|
||||
}
|
||||
|
||||
void LastFMService::Ban(const Song& song) {
|
||||
lastfm::MutableTrack mtrack(TrackFromSong(song));
|
||||
mtrack.ban();
|
||||
}
|
||||
|
||||
void LastFMService::ScrobblerStatus(int status) {
|
||||
qDebug() << static_cast<lastfm::Audioscrobbler::Status>(status);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define LASTFMSERVICE_H
|
||||
|
||||
#include "radioservice.h"
|
||||
#include "song.h"
|
||||
|
||||
#include <lastfm/RadioTuner>
|
||||
|
||||
@ -14,7 +15,11 @@ class LastFMService : public RadioService {
|
||||
LastFMService(QObject* parent = 0);
|
||||
~LastFMService();
|
||||
|
||||
static const char* kServiceName;
|
||||
static const char* kSettingsGroup;
|
||||
static const char* kAudioscrobblerClientId;
|
||||
static const char* kApiKey;
|
||||
static const char* kSecret;
|
||||
|
||||
enum ItemType {
|
||||
Type_MyRecommendations = 1000,
|
||||
@ -27,15 +32,19 @@ class LastFMService : public RadioService {
|
||||
RadioItem* CreateRootItem(RadioItem* parent);
|
||||
void LazyPopulate(RadioItem *item);
|
||||
QList<RadioItem::PlaylistData> DataForItem(RadioItem* item);
|
||||
|
||||
void StartLoading(const QUrl& url);
|
||||
void LoadNext(const QUrl& url);
|
||||
|
||||
bool IsPauseAllowed() const { return false; }
|
||||
bool ShowLastFmControls() const { return true; }
|
||||
|
||||
bool IsAuthenticated() const;
|
||||
void Authenticate(const QString& username, const QString& password);
|
||||
|
||||
void NowPlaying(const Song& song);
|
||||
void Scrobble(const Song& song);
|
||||
void Love(const Song& song);
|
||||
void Ban(const Song& song);
|
||||
|
||||
signals:
|
||||
void AuthenticationComplete(bool success);
|
||||
|
||||
@ -45,14 +54,21 @@ class LastFMService : public RadioService {
|
||||
void TunerTrackAvailable();
|
||||
void TunerError(lastfm::ws::Error error);
|
||||
|
||||
void ScrobblerStatus(int status);
|
||||
|
||||
private:
|
||||
RadioItem* CreateStationItem(ItemType type, const QString& name,
|
||||
const QString& icon, RadioItem* parent);
|
||||
QString ErrorString(lastfm::ws::Error error) const;
|
||||
bool InitScrobbler();
|
||||
lastfm::Track TrackFromSong(const Song& song) const;
|
||||
|
||||
private:
|
||||
LastFMConfig* config_;
|
||||
lastfm::RadioTuner* tuner_;
|
||||
lastfm::Audioscrobbler* scrobbler_;
|
||||
lastfm::Track last_track_;
|
||||
|
||||
LastFMConfig* config_;
|
||||
QUrl last_url_;
|
||||
bool initial_tune_;
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QCoreApplication::setApplicationName("Tangerine");
|
||||
QCoreApplication::setApplicationVersion("0.1");
|
||||
QCoreApplication::setOrganizationName("Tangerine");
|
||||
QCoreApplication::setOrganizationDomain("davidsansome.com");
|
||||
|
||||
|
@ -25,7 +25,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
radio_model_(new RadioModel(this)),
|
||||
playlist_(new Playlist(this)),
|
||||
player_(new Player(playlist_, this)),
|
||||
player_(new Player(playlist_, radio_model_->GetLastFMService(), this)),
|
||||
library_(new Library(player_->GetEngine(), this)),
|
||||
library_sort_model_(new QSortFilterProxyModel(this)),
|
||||
tray_icon_(new SystemTrayIcon(this))
|
||||
@ -36,6 +36,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
tray_icon_->show();
|
||||
|
||||
ui_.volume->setValue(player_->GetVolume());
|
||||
ui_.last_fm_controls->hide();
|
||||
|
||||
// Models
|
||||
library_sort_model_->setSourceModel(library_);
|
||||
@ -72,6 +73,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
ui_.back_button->setDefaultAction(ui_.action_previous_track);
|
||||
ui_.pause_play_button->setDefaultAction(ui_.action_play_pause);
|
||||
ui_.stop_button->setDefaultAction(ui_.action_stop);
|
||||
ui_.love_button->setDefaultAction(ui_.action_love);
|
||||
ui_.ban_button->setDefaultAction(ui_.action_ban);
|
||||
|
||||
// Stop actions
|
||||
QMenu* stop_menu = new QMenu(this);
|
||||
@ -151,6 +154,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
tray_menu->addAction(ui_.action_play_pause);
|
||||
tray_menu->addAction(ui_.action_stop);
|
||||
tray_menu->addAction(ui_.action_next_track);
|
||||
tray_menu->addAction(ui_.action_love);
|
||||
tray_menu->addAction(ui_.action_ban);
|
||||
tray_menu->addSeparator();
|
||||
tray_menu->addAction(ui_.action_quit);
|
||||
tray_icon_->setContextMenu(tray_menu);
|
||||
@ -209,6 +214,10 @@ void MainWindow::MediaStopped() {
|
||||
ui_.action_play_pause->setText("Play");
|
||||
|
||||
ui_.action_play_pause->setEnabled(true);
|
||||
|
||||
ui_.action_ban->setVisible(false);
|
||||
ui_.action_love->setVisible(false);
|
||||
ui_.last_fm_controls->hide();
|
||||
}
|
||||
|
||||
void MainWindow::MediaPaused() {
|
||||
@ -228,6 +237,11 @@ void MainWindow::MediaPlaying() {
|
||||
|
||||
ui_.action_play_pause->setEnabled(
|
||||
! playlist_->current_item_options() & PlaylistItem::PauseDisabled);
|
||||
|
||||
bool lastfm = playlist_->current_item_options() & PlaylistItem::LastFMControls;
|
||||
ui_.action_ban->setVisible(lastfm);
|
||||
ui_.action_love->setVisible(lastfm);
|
||||
ui_.last_fm_controls->setVisible(lastfm);
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent*) {
|
||||
|
@ -136,6 +136,51 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="last_fm_controls" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="love_button">
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="ban_button">
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="maximumSize">
|
||||
@ -489,6 +534,30 @@
|
||||
<string>Added this month</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_love">
|
||||
<property name="icon">
|
||||
<iconset resource="../data/data.qrc">
|
||||
<normaloff>:/last.fm/love.png</normaloff>:/last.fm/love.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Love</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_ban">
|
||||
<property name="icon">
|
||||
<iconset resource="../data/data.qrc">
|
||||
<normaloff>:/last.fm/ban.png</normaloff>:/last.fm/ban.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ban</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
@ -1,12 +1,14 @@
|
||||
#include "player.h"
|
||||
#include "playlist.h"
|
||||
#include "xine-engine.h"
|
||||
#include "lastfmservice.h"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
Player::Player(Playlist* playlist, QObject* parent)
|
||||
Player::Player(Playlist* playlist, LastFMService* lastfm, QObject* parent)
|
||||
: QObject(parent),
|
||||
playlist_(playlist),
|
||||
lastfm_(lastfm),
|
||||
engine_(new XineEngine)
|
||||
{
|
||||
if (!engine_->init()) {
|
||||
@ -119,8 +121,10 @@ void Player::PlayAt(int index) {
|
||||
|
||||
if (item->options() & PlaylistItem::SpecialPlayBehaviour)
|
||||
item->StartLoading();
|
||||
else
|
||||
else {
|
||||
engine_->play(item->Url());
|
||||
lastfm_->NowPlaying(item->Metadata());
|
||||
}
|
||||
}
|
||||
|
||||
void Player::StreamReady(const QUrl& original_url, const QUrl& media_url) {
|
||||
@ -133,4 +137,5 @@ void Player::StreamReady(const QUrl& original_url, const QUrl& media_url) {
|
||||
return;
|
||||
|
||||
engine_->play(media_url);
|
||||
lastfm_->NowPlaying(item->Metadata());
|
||||
}
|
||||
|
@ -8,12 +8,13 @@
|
||||
|
||||
class Playlist;
|
||||
class Settings;
|
||||
class LastFMService;
|
||||
|
||||
class Player : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Player(Playlist* playlist, QObject* parent = 0);
|
||||
Player(Playlist* playlist, LastFMService* lastfm, QObject* parent = 0);
|
||||
|
||||
EngineBase* GetEngine() { return engine_; }
|
||||
Engine::State GetState() const;
|
||||
@ -41,6 +42,7 @@ class Player : public QObject {
|
||||
|
||||
private:
|
||||
Playlist* playlist_;
|
||||
LastFMService* lastfm_;
|
||||
QSettings settings_;
|
||||
|
||||
EngineBase* engine_;
|
||||
|
@ -55,13 +55,14 @@ QVariant Playlist::data(const QModelIndex& index, int role) const {
|
||||
|
||||
case Qt::DisplayRole: {
|
||||
PlaylistItem* item = items_[index.row()];
|
||||
Song song = item->Metadata();
|
||||
|
||||
switch (index.column()) {
|
||||
case Column_Title: return item->Title();
|
||||
case Column_Artist: return item->Artist();
|
||||
case Column_Album: return item->Album();
|
||||
case Column_Length: return item->Length();
|
||||
case Column_Track: return item->Track();
|
||||
case Column_Title: return song.title();
|
||||
case Column_Artist: return song.artist();
|
||||
case Column_Album: return song.album();
|
||||
case Column_Length: return song.length();
|
||||
case Column_Track: return song.track();
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,11 +283,11 @@ bool Playlist::CompareItems(int column, Qt::SortOrder order,
|
||||
const PlaylistItem* b = order == Qt::AscendingOrder ? _b : _a;
|
||||
|
||||
switch (column) {
|
||||
case Column_Title: return a->Title() < b->Title();
|
||||
case Column_Artist: return a->Artist() < b->Artist();
|
||||
case Column_Album: return a->Album() < b->Album();
|
||||
case Column_Length: return a->Length() < b->Length();
|
||||
case Column_Track: return a->Track() < b->Track();
|
||||
case Column_Title: return a->Metadata().title() < b->Metadata().title();
|
||||
case Column_Artist: return a->Metadata().artist() < b->Metadata().artist();
|
||||
case Column_Album: return a->Metadata().album() < b->Metadata().album();
|
||||
case Column_Length: return a->Metadata().length() < b->Metadata().length();
|
||||
case Column_Track: return a->Metadata().track() < b->Metadata().track();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -38,11 +38,7 @@ class PlaylistItem {
|
||||
virtual void Save(QSettings& settings) const = 0;
|
||||
virtual void Restore(const QSettings& settings) = 0;
|
||||
|
||||
virtual QString Title() const = 0;
|
||||
virtual QString Artist() const = 0;
|
||||
virtual QString Album() const = 0;
|
||||
virtual int Length() const = 0;
|
||||
virtual int Track() const = 0;
|
||||
virtual Song Metadata() const = 0;
|
||||
|
||||
// If the item needs to do anything special before it can play (eg. start
|
||||
// streaming the radio stream), then it should implement StartLoading() and
|
||||
|
@ -111,3 +111,9 @@ QMimeData* RadioModel::mimeData(const QModelIndexList& indexes) const {
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
LastFMService* RadioModel::GetLastFMService() const {
|
||||
if (sServices.contains(LastFMService::kServiceName))
|
||||
return static_cast<LastFMService*>(sServices[LastFMService::kServiceName]);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "simpletreemodel.h"
|
||||
|
||||
class RadioService;
|
||||
class LastFMService;
|
||||
class Song;
|
||||
|
||||
class RadioModel : public SimpleTreeModel<RadioItem> {
|
||||
@ -22,6 +23,9 @@ class RadioModel : public SimpleTreeModel<RadioItem> {
|
||||
// Needs to be static for RadioPlaylistItem::restore
|
||||
static RadioService* ServiceByName(const QString& name);
|
||||
|
||||
// This is special because Player needs it for scrobbling
|
||||
LastFMService* GetLastFMService() const;
|
||||
|
||||
// QAbstractItemModel
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
|
@ -15,6 +15,7 @@ RadioPlaylistItem::RadioPlaylistItem(RadioService* service, const QUrl& url,
|
||||
url_(url),
|
||||
title_(title)
|
||||
{
|
||||
InitMetadata();
|
||||
}
|
||||
|
||||
void RadioPlaylistItem::Save(QSettings& settings) const {
|
||||
@ -27,35 +28,23 @@ void RadioPlaylistItem::Restore(const QSettings& settings) {
|
||||
service_ = RadioModel::ServiceByName(settings.value("service").toString());
|
||||
url_ = settings.value("url").toString();
|
||||
title_ = settings.value("title").toString();
|
||||
|
||||
InitMetadata();
|
||||
}
|
||||
|
||||
QString RadioPlaylistItem::Title() const {
|
||||
void RadioPlaylistItem::InitMetadata() {
|
||||
if (!service_)
|
||||
return "Radio service couldn't be loaded :-(";
|
||||
|
||||
if (metadata_.is_valid())
|
||||
return metadata_.title();
|
||||
|
||||
if (!title_.isEmpty())
|
||||
return title_;
|
||||
|
||||
return url_.toString();
|
||||
metadata_.set_title("Radio service couldn't be loaded :-(");
|
||||
else if (!title_.isEmpty())
|
||||
metadata_.set_title(title_);
|
||||
else
|
||||
metadata_.set_title(url_.toString());
|
||||
}
|
||||
|
||||
QString RadioPlaylistItem::Artist() const {
|
||||
return metadata_.is_valid() ? metadata_.artist() : QString::null;
|
||||
}
|
||||
|
||||
QString RadioPlaylistItem::Album() const {
|
||||
return metadata_.is_valid() ? metadata_.album() : QString::null;
|
||||
}
|
||||
|
||||
int RadioPlaylistItem::Length() const {
|
||||
return metadata_.is_valid() ? metadata_.length() : -1;
|
||||
}
|
||||
|
||||
int RadioPlaylistItem::Track() const {
|
||||
return metadata_.is_valid() ? metadata_.track() : -1;
|
||||
Song RadioPlaylistItem::Metadata() const {
|
||||
if (temp_metadata_.is_valid())
|
||||
return temp_metadata_;
|
||||
return metadata_;
|
||||
}
|
||||
|
||||
void RadioPlaylistItem::StartLoading() {
|
||||
@ -88,9 +77,9 @@ PlaylistItem::Options RadioPlaylistItem::options() const {
|
||||
}
|
||||
|
||||
void RadioPlaylistItem::SetTemporaryMetadata(const Song& metadata) {
|
||||
metadata_ = metadata;
|
||||
temp_metadata_ = metadata;
|
||||
}
|
||||
|
||||
void RadioPlaylistItem::ClearTemporaryMetadata() {
|
||||
metadata_ = Song();
|
||||
temp_metadata_ = Song();
|
||||
}
|
||||
|
@ -19,11 +19,7 @@ class RadioPlaylistItem : public PlaylistItem {
|
||||
void Save(QSettings& settings) const;
|
||||
void Restore(const QSettings& settings);
|
||||
|
||||
QString Title() const;
|
||||
QString Artist() const;
|
||||
QString Album() const;
|
||||
int Length() const;
|
||||
int Track() const;
|
||||
Song Metadata() const;
|
||||
|
||||
void StartLoading();
|
||||
QUrl Url();
|
||||
@ -33,12 +29,16 @@ class RadioPlaylistItem : public PlaylistItem {
|
||||
void SetTemporaryMetadata(const Song& metadata);
|
||||
void ClearTemporaryMetadata();
|
||||
|
||||
private:
|
||||
void InitMetadata();
|
||||
|
||||
private:
|
||||
RadioService* service_;
|
||||
QUrl url_;
|
||||
QString title_;
|
||||
|
||||
Song metadata_;
|
||||
Song temp_metadata_;
|
||||
};
|
||||
|
||||
#endif // RADIOPLAYLISTITEM_H
|
||||
|
10
src/song.cpp
10
src/song.cpp
@ -234,6 +234,16 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
#undef intval
|
||||
}
|
||||
|
||||
void Song::ToLastFM(lastfm::Track* track) const {
|
||||
lastfm::MutableTrack mtrack(*track);
|
||||
|
||||
mtrack.setArtist(artist_);
|
||||
mtrack.setAlbum(album_);
|
||||
mtrack.setTitle(title_);
|
||||
mtrack.setDuration(length_);
|
||||
mtrack.setTrackNumber(track_);
|
||||
}
|
||||
|
||||
QString Song::PrettyTitleWithArtist() const {
|
||||
QString title(title_);
|
||||
|
||||
|
@ -9,6 +9,7 @@ namespace lastfm {
|
||||
class Track;
|
||||
}
|
||||
|
||||
// TODO: QSharedData
|
||||
class Song {
|
||||
public:
|
||||
Song();
|
||||
@ -24,6 +25,7 @@ class Song {
|
||||
|
||||
// Save
|
||||
void BindToQuery(QSqlQuery* query) const;
|
||||
void ToLastFM(lastfm::Track* track) const;
|
||||
|
||||
// Simple accessors
|
||||
bool is_valid() const { return valid_; }
|
||||
@ -59,6 +61,7 @@ class Song {
|
||||
|
||||
// Setters
|
||||
void set_id(int id) { id_ = id; }
|
||||
void set_title(const QString& title) { title_ = title; }
|
||||
|
||||
// Comparison functions
|
||||
bool IsMetadataEqual(const Song& other) const;
|
||||
|
@ -24,26 +24,6 @@ void SongPlaylistItem::Restore(const QSettings& settings) {
|
||||
song_.InitFromFile(filename, directory_id);
|
||||
}
|
||||
|
||||
QString SongPlaylistItem::Title() const {
|
||||
return song_.PrettyTitle();
|
||||
}
|
||||
|
||||
QString SongPlaylistItem::Artist() const {
|
||||
return song_.artist();
|
||||
}
|
||||
|
||||
QString SongPlaylistItem::Album() const {
|
||||
return song_.album();
|
||||
}
|
||||
|
||||
int SongPlaylistItem::Length() const {
|
||||
return song_.length();
|
||||
}
|
||||
|
||||
int SongPlaylistItem::Track() const {
|
||||
return song_.track();
|
||||
}
|
||||
|
||||
QUrl SongPlaylistItem::Url() {
|
||||
QUrl ret(QUrl::fromLocalFile(song_.filename()));
|
||||
ret.setHost("localhost");
|
||||
|
@ -14,11 +14,7 @@ class SongPlaylistItem : public PlaylistItem {
|
||||
void Save(QSettings& settings) const;
|
||||
void Restore(const QSettings& settings);
|
||||
|
||||
QString Title() const;
|
||||
QString Artist() const;
|
||||
QString Album() const;
|
||||
int Length() const;
|
||||
int Track() const;
|
||||
Song Metadata() const { return song_; }
|
||||
|
||||
QUrl Url();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user