Add Dropbox service and settings page.

This commit is contained in:
John Maguire 2012-11-29 18:19:41 +01:00
parent b955da5f28
commit ea8655af83
18 changed files with 415 additions and 14 deletions

View File

@ -333,6 +333,7 @@
<file>schema/schema-39.sql</file>
<file>schema/schema-3.sql</file>
<file>schema/schema-40.sql</file>
<file>schema/schema-41.sql</file>
<file>schema/schema-4.sql</file>
<file>schema/schema-5.sql</file>
<file>schema/schema-6.sql</file>

48
data/schema/schema-41.sql Normal file
View File

@ -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;

View File

@ -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

View File

@ -37,7 +37,7 @@
#include <QVariant>
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;

View File

@ -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();

View File

@ -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<QString, QString> 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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -0,0 +1,86 @@
/* This file is part of Clementine.
Copyright 2012, 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/>.
*/
#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<DropboxService>())
{
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);
}

View File

@ -0,0 +1,53 @@
/* This file is part of Clementine.
Copyright 2012, 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 DROPBOXSETTINGSPAGE_H
#define DROPBOXSETTINGSPAGE_H
#include "ui/settingspage.h"
#include <QModelIndex>
#include <QWidget>
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

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DropboxSettingsPage</class>
<widget class="QWidget" name="GoogleDriveSettingsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>569</width>
<height>491</height>
</rect>
</property>
<property name="windowTitle">
<string>Google Drive</string>
</property>
<property name="windowIcon">
<iconset resource="../../data/data.qrc">
<normaloff>:/providers/dropbox.png</normaloff>:/providers/dropbox.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Clementine can play music that you have uploaded to Dropbox</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="LoginStateWidget" name="login_state" native="true"/>
</item>
<item>
<widget class="QWidget" name="login_container" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>28</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="login_button">
<property name="text">
<string>Login</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Clicking the Login button will open a web browser. You should return to Clementine after you have logged in.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>357</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LoginStateWidget</class>
<extends>QWidget</extends>
<header>widgets/loginstatewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../data/data.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -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) {

View File

@ -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_));

View File

@ -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);

View File

@ -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

View File

@ -68,6 +68,10 @@
# include "internet/ubuntuonesettingspage.h"
#endif
#ifdef HAVE_DROPBOX
# include "internet/dropboxsettingspage.h"
#endif
#include <QDesktopWidget>
#include <QPainter>
#include <QPushButton>
@ -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

View File

@ -78,6 +78,7 @@ public:
Page_Podcasts,
Page_GoogleDrive,
Page_UbuntuOne,
Page_Dropbox,
};
enum Role {