diff --git a/data/data.qrc b/data/data.qrc index 334f7a62e..973c81c58 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -333,6 +333,7 @@ schema/schema-39.sql schema/schema-3.sql schema/schema-40.sql + schema/schema-41.sql schema/schema-4.sql schema/schema-5.sql schema/schema-6.sql diff --git a/data/schema/schema-41.sql b/data/schema/schema-41.sql new file mode 100644 index 000000000..8e0d20752 --- /dev/null +++ b/data/schema/schema-41.sql @@ -0,0 +1,48 @@ +CREATE TABLE dropbox_songs( + title TEXT, + album TEXT, + artist TEXT, + albumartist TEXT, + composer TEXT, + track INTEGER, + disc INTEGER, + bpm REAL, + year INTEGER, + genre TEXT, + comment TEXT, + compilation INTEGER, + + length INTEGER, + bitrate INTEGER, + samplerate INTEGER, + + directory INTEGER NOT NULL, + filename TEXT NOT NULL, + mtime INTEGER NOT NULL, + ctime INTEGER NOT NULL, + filesize INTEGER NOT NULL, + sampler INTEGER NOT NULL DEFAULT 0, + art_automatic TEXT, + art_manual TEXT, + filetype INTEGER NOT NULL DEFAULT 0, + playcount INTEGER NOT NULL DEFAULT 0, + lastplayed INTEGER, + rating INTEGER, + forced_compilation_on INTEGER NOT NULL DEFAULT 0, + forced_compilation_off INTEGER NOT NULL DEFAULT 0, + effective_compilation NOT NULL DEFAULT 0, + skipcount INTEGER NOT NULL DEFAULT 0, + score INTEGER NOT NULL DEFAULT 0, + beginning INTEGER NOT NULL DEFAULT 0, + cue_path TEXT, + unavailable INTEGER DEFAULT 0, + effective_albumartist TEXT, + etag TEXT +); + +CREATE VIRTUAL TABLE dropbox_songs_fts USING fts3 ( + ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment, + tokenize=unicode +); + +UPDATE schema_version SET version=41; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 611952420..824b561c5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1058,8 +1058,14 @@ optional_source(HAVE_UBUNTU_ONE optional_source(HAVE_DROPBOX SOURCES internet/dropboxauthenticator.cpp + internet/dropboxservice.cpp + internet/dropboxsettingspage.cpp HEADERS internet/dropboxauthenticator.h + internet/dropboxservice.h + internet/dropboxsettingspage.h + UI + internet/dropboxsettingspage.ui ) # Hack to add Clementine to the Unity system tray whitelist diff --git a/src/core/database.cpp b/src/core/database.cpp index a8862d3b4..58d410fe9 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -37,7 +37,7 @@ #include const char* Database::kDatabaseFilename = "clementine.db"; -const int Database::kSchemaVersion = 40; +const int Database::kSchemaVersion = 41; const char* Database::kMagicAllSongsTables = "%allsongstables"; int Database::sNextConnectionId = 1; diff --git a/src/internet/cloudfileservice.h b/src/internet/cloudfileservice.h index 060f84829..b0ca7af7a 100644 --- a/src/internet/cloudfileservice.h +++ b/src/internet/cloudfileservice.h @@ -34,7 +34,7 @@ class CloudFileService : public InternetService { virtual bool has_credentials() const = 0; virtual void Connect() = 0; - private slots: + protected slots: void ShowCoverManager(); void AddToPlaylist(QMimeData* mime); void ShowSettingsDialog(); diff --git a/src/internet/dropboxauthenticator.cpp b/src/internet/dropboxauthenticator.cpp index e31277a6a..fdd9730c3 100644 --- a/src/internet/dropboxauthenticator.cpp +++ b/src/internet/dropboxauthenticator.cpp @@ -35,7 +35,7 @@ DropboxAuthenticator::DropboxAuthenticator(QObject* parent) network_(new NetworkAccessManager(this)) { } -void DropboxAuthenticator::StartAuthorisation(const QString& email) { +void DropboxAuthenticator::StartAuthorisation() { QUrl url(kRequestTokenEndpoint); typedef QPair Param; @@ -194,4 +194,5 @@ void DropboxAuthenticator::RequestAccountInformationFinished(QNetworkReply* repl QJson::Parser parser; QVariantMap response = parser.parse(reply).toMap(); name_ = response["display_name"].toString(); + emit Finished(); } diff --git a/src/internet/dropboxauthenticator.h b/src/internet/dropboxauthenticator.h index ca1ddc96f..add3a45ef 100644 --- a/src/internet/dropboxauthenticator.h +++ b/src/internet/dropboxauthenticator.h @@ -11,7 +11,15 @@ class DropboxAuthenticator : public QObject { Q_OBJECT public: explicit DropboxAuthenticator(QObject* parent = 0); - void StartAuthorisation(const QString& email); + void StartAuthorisation(); + + const QString& access_token() const { return access_token_; } + const QString& access_token_secret() const { return access_token_secret_; } + const QString& uid() const { return uid_; } + const QString& name() const { return name_; } + + signals: + void Finished(); private slots: void RequestTokenFinished(QNetworkReply* reply); diff --git a/src/internet/dropboxservice.cpp b/src/internet/dropboxservice.cpp new file mode 100644 index 000000000..1e853f8ab --- /dev/null +++ b/src/internet/dropboxservice.cpp @@ -0,0 +1,49 @@ +#include "dropboxservice.h" + +#include "internet/dropboxauthenticator.h" + +const char* DropboxService::kServiceName = "Dropbox"; +const char* DropboxService::kSettingsGroup = "Dropbox"; + +namespace { + +static const char* kServiceId = "dropbox"; + +} // namespace + +DropboxService::DropboxService(Application* app, InternetModel* parent) + : CloudFileService( + app, parent, + kServiceName, kServiceId, + QIcon(":/providers/dropbox.png"), + SettingsDialog::Page_Dropbox) { +} + +bool DropboxService::has_credentials() const { + return !access_token_.isEmpty(); +} + +void DropboxService::Connect() { + if (!has_credentials()) { + DropboxAuthenticator* authenticator = new DropboxAuthenticator; + authenticator->StartAuthorisation(); + NewClosure(authenticator, SIGNAL(Finished()), + this, SLOT(AuthenticationFinished(DropboxAuthenticator*)), + authenticator); + } else { + ShowSettingsDialog(); + } +} + +void DropboxService::AuthenticationFinished(DropboxAuthenticator* authenticator) { + authenticator->deleteLater(); + + QSettings settings; + settings.beginGroup(kSettingsGroup); + + settings.setValue("access_token", authenticator->access_token()); + settings.setValue("access_token_secret", authenticator->access_token_secret()); + settings.setValue("name", authenticator->name()); + + emit Connected(); +} diff --git a/src/internet/dropboxservice.h b/src/internet/dropboxservice.h new file mode 100644 index 000000000..66947693e --- /dev/null +++ b/src/internet/dropboxservice.h @@ -0,0 +1,34 @@ +#ifndef DROPBOXSERVICE_H +#define DROPBOXSERVICE_H + +#include "internet/cloudfileservice.h" + +#include "core/tagreaderclient.h" + +class DropboxAuthenticator; + +class DropboxService : public CloudFileService { + Q_OBJECT + public: + DropboxService(Application* app, InternetModel* parent); + + static const char* kServiceName; + static const char* kSettingsGroup; + + virtual bool has_credentials() const; + + signals: + void Connected(); + + public slots: + void Connect(); + + private slots: + void AuthenticationFinished(DropboxAuthenticator* authenticator); + + private: + QString access_token_; + QString access_token_secret_; +}; + +#endif // DROPBOXSERVICE_H diff --git a/src/internet/dropboxsettingspage.cpp b/src/internet/dropboxsettingspage.cpp new file mode 100644 index 000000000..9b99d0857 --- /dev/null +++ b/src/internet/dropboxsettingspage.cpp @@ -0,0 +1,86 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + 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 . +*/ + +#include "dropboxsettingspage.h" +#include "ui_dropboxsettingspage.h" + +#include "core/application.h" +#include "internet/dropboxservice.h" +#include "internet/internetmodel.h" +#include "ui/settingsdialog.h" + +DropboxSettingsPage::DropboxSettingsPage(SettingsDialog* parent) + : SettingsPage(parent), + ui_(new Ui::DropboxSettingsPage), + service_(dialog()->app()->internet_model()->Service()) +{ + ui_->setupUi(this); + ui_->login_state->AddCredentialGroup(ui_->login_container); + + connect(ui_->login_button, SIGNAL(clicked()), SLOT(LoginClicked())); + connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(LogoutClicked())); + connect(service_, SIGNAL(Connected()), SLOT(Connected())); + + dialog()->installEventFilter(this); +} + +DropboxSettingsPage::~DropboxSettingsPage() { + delete ui_; +} + +void DropboxSettingsPage::Load() { + QSettings s; + s.beginGroup(DropboxService::kSettingsGroup); + + const QString user_email = s.value("user_email").toString(); + + if (!user_email.isEmpty()) { + ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, user_email); + } +} + +void DropboxSettingsPage::Save() { + QSettings s; + s.beginGroup(DropboxService::kSettingsGroup); +} + +void DropboxSettingsPage::LoginClicked() { + service_->Connect(); + ui_->login_button->setEnabled(false); +} + +bool DropboxSettingsPage::eventFilter(QObject* object, QEvent* event) { + if (object == dialog() && event->type() == QEvent::Enter) { + ui_->login_button->setEnabled(true); + return false; + } + + return SettingsPage::eventFilter(object, event); +} + +void DropboxSettingsPage::LogoutClicked() { + ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedOut); +} + +void DropboxSettingsPage::Connected() { + QSettings s; + s.beginGroup(DropboxService::kSettingsGroup); + + const QString user_email = s.value("user_email").toString(); + + ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, user_email); +} diff --git a/src/internet/dropboxsettingspage.h b/src/internet/dropboxsettingspage.h new file mode 100644 index 000000000..d4285fed3 --- /dev/null +++ b/src/internet/dropboxsettingspage.h @@ -0,0 +1,53 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + 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 . +*/ + +#ifndef DROPBOXSETTINGSPAGE_H +#define DROPBOXSETTINGSPAGE_H + +#include "ui/settingspage.h" + +#include +#include + +class DropboxService; +class Ui_DropboxSettingsPage; + +class DropboxSettingsPage : public SettingsPage { + Q_OBJECT + +public: + DropboxSettingsPage(SettingsDialog* parent = 0); + ~DropboxSettingsPage(); + + void Load(); + void Save(); + + // QObject + bool eventFilter(QObject* object, QEvent* event); + +private slots: + void LoginClicked(); + void LogoutClicked(); + void Connected(); + +private: + Ui_DropboxSettingsPage* ui_; + + DropboxService* service_; +}; + +#endif // DROPBOXSETTINGSPAGE_H diff --git a/src/internet/dropboxsettingspage.ui b/src/internet/dropboxsettingspage.ui new file mode 100644 index 000000000..dbb7bf05a --- /dev/null +++ b/src/internet/dropboxsettingspage.ui @@ -0,0 +1,110 @@ + + + DropboxSettingsPage + + + + 0 + 0 + 569 + 491 + + + + Google Drive + + + + :/providers/dropbox.png:/providers/dropbox.png + + + + + + Clementine can play music that you have uploaded to Dropbox + + + true + + + + + + + + + + + 28 + + + 0 + + + 0 + + + + + + + Login + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Clicking the Login button will open a web browser. You should return to Clementine after you have logged in. + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 357 + + + + + + + + + LoginStateWidget + QWidget +
widgets/loginstatewidget.h
+ 1 +
+
+ + + + +
diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp index 771e97ff8..17f382a3e 100644 --- a/src/internet/internetmodel.cpp +++ b/src/internet/internetmodel.cpp @@ -48,6 +48,9 @@ #ifdef HAVE_UBUNTU_ONE #include "ubuntuoneservice.h" #endif +#ifdef HAVE_DROPBOX + #include "dropboxservice.h" +#endif using smart_playlists::Generator; using smart_playlists::GeneratorMimeData; @@ -91,6 +94,9 @@ InternetModel::InternetModel(Application* app, QObject* parent) #ifdef HAVE_UBUNTU_ONE AddService(new UbuntuOneService(app, this)); #endif +#ifdef HAVE_DROPBOX + AddService(new DropboxService(app, this)); +#endif } void InternetModel::AddService(InternetService *service) { diff --git a/src/internet/ubuntuoneservice.cpp b/src/internet/ubuntuoneservice.cpp index 544fc57af..dac0dd303 100644 --- a/src/internet/ubuntuoneservice.cpp +++ b/src/internet/ubuntuoneservice.cpp @@ -233,10 +233,6 @@ QUrl UbuntuOneService::GetStreamingUrlFromSongId(const QString& song_id) { return url; } -void UbuntuOneService::ShowSettingsDialog() { - app_->OpenSettingsDialogAtPage(SettingsDialog::Page_UbuntuOne); -} - void UbuntuOneService::ShowCoverManager() { if (!cover_manager_) { cover_manager_.reset(new AlbumCoverManager(app_, library_backend_)); diff --git a/src/internet/ubuntuoneservice.h b/src/internet/ubuntuoneservice.h index 6519a04d5..d3dab1451 100644 --- a/src/internet/ubuntuoneservice.h +++ b/src/internet/ubuntuoneservice.h @@ -23,7 +23,6 @@ class UbuntuOneService : public CloudFileService { void FileListRequestFinished(QNetworkReply* reply); void ReadTagsFinished( TagReaderClient::ReplyType* reply, const QVariantMap& file, const QUrl& url); - void ShowSettingsDialog(); void ShowCoverManager(); void AddToPlaylist(QMimeData* mime); void VolumeListRequestFinished(QNetworkReply* reply); diff --git a/src/main.cpp b/src/main.cpp index 1061c3f30..61397080c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -110,8 +110,6 @@ using boost::scoped_ptr; Q_IMPORT_PLUGIN(qsqlite) #endif -#include "internet/dropboxauthenticator.h" - void LoadTranslation(const QString& prefix, const QString& path, const QString& override_language = QString()) { #if QT_VERSION < 0x040700 @@ -449,9 +447,6 @@ int main(int argc, char *argv[]) { } #endif - DropboxAuthenticator authenticator; - authenticator.StartAuthorisation("foo"); - // Window MainWindow w(&app, tray_icon.get(), &osd); #ifdef Q_OS_DARWIN diff --git a/src/ui/settingsdialog.cpp b/src/ui/settingsdialog.cpp index 97a74147b..9f51feb68 100644 --- a/src/ui/settingsdialog.cpp +++ b/src/ui/settingsdialog.cpp @@ -68,6 +68,10 @@ # include "internet/ubuntuonesettingspage.h" #endif +#ifdef HAVE_DROPBOX +# include "internet/dropboxsettingspage.h" +#endif + #include #include #include @@ -156,6 +160,10 @@ SettingsDialog::SettingsDialog(Application* app, BackgroundStreams* streams, QWi AddPage(Page_UbuntuOne, new UbuntuOneSettingsPage(this), providers); #endif +#ifdef HAVE_DROPBOX + AddPage(Page_Dropbox, new DropboxSettingsPage(this), providers); +#endif + #ifdef HAVE_SPOTIFY AddPage(Page_Spotify, new SpotifySettingsPage(this), providers); #endif diff --git a/src/ui/settingsdialog.h b/src/ui/settingsdialog.h index 0e8d19498..643a225eb 100644 --- a/src/ui/settingsdialog.h +++ b/src/ui/settingsdialog.h @@ -78,6 +78,7 @@ public: Page_Podcasts, Page_GoogleDrive, Page_UbuntuOne, + Page_Dropbox, }; enum Role {