2014-06-03 14:33:07 +02:00
|
|
|
/* Contacts (for explanations, congratulations, insults) :
|
|
|
|
* - <florian.bigard@gmail.com>
|
|
|
|
*
|
|
|
|
* Help :
|
|
|
|
* - The "path" variable has to end with "/".
|
2014-06-04 17:58:28 +02:00
|
|
|
* If we want to specify a filepath, the name of the variable has to be...
|
|
|
|
*filepath :)
|
|
|
|
* - Seafile stores files in libraries (or repositories) so variable with the
|
|
|
|
*name "library" corresponds to the
|
2014-06-03 14:33:07 +02:00
|
|
|
* Seafile library, not to the Clementine library
|
|
|
|
* - The authentification of Seafile's API is simply a token (REST API)
|
2014-06-04 17:58:28 +02:00
|
|
|
* - Seafile stores a hash for each entry. This hash changes when the entry is
|
|
|
|
*modified.
|
|
|
|
* This is the reason why we just have to compare the local hash with the
|
|
|
|
*server
|
2014-06-03 14:33:07 +02:00
|
|
|
* hash of a directory (for example) to know if the directory was modified.
|
|
|
|
* Libraries are an exception : Seafile stores a hash that never changes.
|
|
|
|
* This hash is called "id".
|
|
|
|
*
|
|
|
|
* Todo :
|
2014-06-04 17:58:28 +02:00
|
|
|
* - Add ssl certificate exception (for people who generate their own
|
|
|
|
*certificate on their Seafile server
|
2014-06-03 14:33:07 +02:00
|
|
|
* - Stop Tagreader when user changes the library
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SEAFILESERVICE_H
|
|
|
|
#define SEAFILESERVICE_H
|
|
|
|
|
|
|
|
#include "cloudfileservice.h"
|
|
|
|
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QMutex>
|
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
#include "seafiletree.h"
|
|
|
|
|
2014-06-03 14:33:07 +02:00
|
|
|
class QNetworkReply;
|
|
|
|
class QNetworkRequest;
|
|
|
|
|
|
|
|
// Interface between the seafile server and Clementine
|
|
|
|
class SeafileService : public CloudFileService {
|
2014-06-04 17:58:28 +02:00
|
|
|
Q_OBJECT
|
2014-06-03 14:33:07 +02:00
|
|
|
public:
|
2014-06-04 17:58:28 +02:00
|
|
|
enum ApiError { NO_ERROR = 200, NOT_FOUND = 404, TOO_MANY_REQUESTS = 429 };
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
SeafileService(Application* app, InternetModel* parent);
|
|
|
|
~SeafileService();
|
|
|
|
|
|
|
|
static const char* kServiceName;
|
|
|
|
static const char* kSettingsGroup;
|
|
|
|
|
2014-06-07 07:28:56 +02:00
|
|
|
bool has_credentials() const;
|
2014-06-04 17:58:28 +02:00
|
|
|
QUrl GetStreamingUrlFromSongId(const QString& library,
|
|
|
|
const QString& filepath);
|
2014-06-03 14:33:07 +02:00
|
|
|
// Get the token for an user (simple rest api)
|
2014-06-04 17:58:28 +02:00
|
|
|
bool GetToken(const QString& mail, const QString& password,
|
|
|
|
const QString& server);
|
2014-06-03 14:33:07 +02:00
|
|
|
// Get all the libraries available for the user. Will emit a signal
|
|
|
|
void GetLibraries();
|
2014-06-04 17:58:28 +02:00
|
|
|
void ChangeLibrary(const QString& new_library);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
void Connect();
|
|
|
|
void ForgetCredentials();
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void Connected();
|
|
|
|
// QMap, key : library's id, value : library's name
|
|
|
|
void GetLibrariesFinishedSignal(QMap<QString, QString>);
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
// Will emit the signal
|
2014-06-04 17:58:28 +02:00
|
|
|
void GetLibrariesFinished(QNetworkReply* reply);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
void FetchAndCheckFolderItemsFinished(QNetworkReply* reply,
|
|
|
|
const SeafileTree::Entry& library,
|
|
|
|
const QString& path);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
// Add recursively the content of a folder from a library
|
2014-06-04 17:58:28 +02:00
|
|
|
void AddRecursivelyFolderItemsFinished(QNetworkReply* reply,
|
|
|
|
const QString& library,
|
|
|
|
const QString& path);
|
2014-06-03 14:33:07 +02:00
|
|
|
// Get the url and try to add the file to the database
|
2014-06-04 17:58:28 +02:00
|
|
|
void FetchContentUrlForFileFinished(QNetworkReply* reply, const Song& song,
|
|
|
|
const QString& mime_type);
|
2014-06-03 14:33:07 +02:00
|
|
|
// Add the entry to the tree and maybe add this entry to the database
|
2014-06-04 17:58:28 +02:00
|
|
|
void AddEntry(const QString& library, const QString& path,
|
|
|
|
const SeafileTree::Entry& entry);
|
2014-06-03 14:33:07 +02:00
|
|
|
// Update the entry or check recursively the directories
|
2014-06-04 17:58:28 +02:00
|
|
|
void UpdateEntry(const QString& library, const QString& path,
|
|
|
|
const SeafileTree::Entry& entry);
|
|
|
|
// Delete the entry (eventually the files of its subdir) of the tree and the
|
|
|
|
// database
|
|
|
|
void DeleteEntry(const QString& library, const QString& path,
|
|
|
|
const SeafileTree::Entry& entry);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
void UpdateLibrariesInProgress(const QMap<QString, QString>& libraries);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
void MaybeAddFileEntryInProgress(QNetworkReply* reply, const QString& library,
|
|
|
|
const QString& path,
|
|
|
|
const QString& mime_type);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
void AddAuthorizationHeader(QNetworkRequest* request) const;
|
|
|
|
|
|
|
|
void UpdateLibraries();
|
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
void FetchAndCheckFolderItems(const SeafileTree::Entry& library,
|
|
|
|
const QString& path);
|
|
|
|
void AddRecursivelyFolderItems(const QString& library, const QString& path);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
QNetworkReply* PrepareFetchFolderItems(const QString& library,
|
|
|
|
const QString& path);
|
|
|
|
QNetworkReply* PrepareFetchContentForFile(const QString& library,
|
|
|
|
const QString& filepath);
|
|
|
|
QNetworkReply* PrepareFetchContentUrlForFile(const QString& library,
|
|
|
|
const QString& filepath);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
2014-06-04 17:58:28 +02:00
|
|
|
void MaybeAddFileEntry(const QString& entry_name, const QString& library,
|
|
|
|
const QString& path);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
// False if not 200 or 429
|
2014-06-04 17:58:28 +02:00
|
|
|
// If 429 (too many requests), re execute the request and put the reply in the
|
|
|
|
// argument
|
|
|
|
bool CheckReply(QNetworkReply** reply, int tries = 1);
|
2014-06-03 14:33:07 +02:00
|
|
|
|
|
|
|
SeafileTree tree_;
|
|
|
|
QString access_token_;
|
|
|
|
QString server_;
|
|
|
|
QString library_updated_;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SEAFILESERVICE_H
|