Jellyfin Qt
QML Library for interacting with the Jellyfin multimedia server
Loading...
Searching...
No Matches
apiclient.h
Go to the documentation of this file.
1/*
2Sailfin: a Jellyfin client written using Qt
3Copyright (C) 2021 Chris Josten
4
5This library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Lesser General Public
7License as published by the Free Software Foundation; either
8version 2.1 of the License, or (at your option) any later version.
9
10This library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Lesser General Public License for more details.
14
15You should have received a copy of the GNU Lesser General Public
16License along with this library; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20#ifndef JELLYFIN_API_CLIENT
21#define JELLYFIN_API_CLIENT
22
23#include <QJsonArray>
24#include <QJsonDocument>
25#include <QJsonObject>
26#include <QJsonParseError>
27#include <QJsonValue>
28
29#include <QHostInfo>
30#include <QObject>
31#include <QQmlListProperty>
32#include <QQmlParserStatus>
33#include <QScopedPointer>
34#include <QString>
35#include <QSysInfo>
36#include <QtQml>
37#include <QUuid>
38
39#include <QNetworkReply>
40#include <QUrlQuery>
41
43#include "credentialmanager.h"
45#include "model/deviceprofile.h"
46#include "eventbus.h"
47
48namespace Jellyfin {
49class PlaybackManager;
50class WebSocket;
51
52namespace ViewModel {
53class Settings;
54}
55
56namespace DTO {
57 class UserItemDataDto; // Keep it as an opaque pointer
59}
60
61using namespace DTO;
62
64
90class ApiClient : public QObject, public QQmlParserStatus {
91 friend class WebSocket;
92 friend class PlaybackManager;
93 Q_OBJECT
94 Q_INTERFACES(QQmlParserStatus)
95 Q_DECLARE_PRIVATE(ApiClient);
96public:
97 explicit ApiClient(QObject *parent = nullptr);
98 virtual ~ApiClient();
99 Q_PROPERTY(QString baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
100 Q_PROPERTY(QString appName READ appName WRITE setAppName NOTIFY appNameChanged)
101 Q_PROPERTY(Jellyfin::Model::DeviceTypeClass::Value deviceType READ deviceType WRITE setDeviceType NOTIFY deviceTypeChanged)
102 Q_PROPERTY(bool authenticated READ authenticated WRITE setAuthenticated NOTIFY authenticatedChanged)
103 Q_PROPERTY(QString userId READ userId NOTIFY userIdChanged)
104 Q_PROPERTY(QJsonObject deviceProfile READ deviceProfileJson NOTIFY deviceProfileChanged)
105 Q_PROPERTY(QString version READ version)
106 Q_PROPERTY(Jellyfin::EventBus *eventbus READ eventbus FINAL)
107 Q_PROPERTY(Jellyfin::WebSocket *websocket READ websocket FINAL)
109 Q_PROPERTY(Jellyfin::ViewModel::Settings *settings READ settings NOTIFY settingsChanged)
116 Q_PROPERTY(bool online READ online NOTIFY onlineChanged)
117
118 bool authenticated() const;
119 void setBaseUrl(const QString &url);
120 void setAppName(const QString &appName);
121 void setDeviceType(Model::DeviceType deviceType);
122
123 QNetworkReply *get(const QString &path, const QUrlQuery &params = QUrlQuery());
124 QNetworkReply *post(const QString &path, const QJsonDocument &data, const QUrlQuery &params = QUrlQuery());
125 QNetworkReply *post(const QString &path, const QByteArray &data = QByteArray(), const QUrlQuery &params = QUrlQuery());
126
133 Q_ENUM(ApiError)
134
135 const QString &baseUrl() const;
136 const QString &appName() const;
137 const QString &userId() const;
138 const QString &deviceId() const;
150 QVariantList supportedCommands() const ;
151 void setSupportedCommands(QVariantList newSupportedCommands);
152 const QJsonObject deviceProfileJson() const;
153 QSharedPointer<DTO::DeviceProfile> deviceProfile() const;
154 const QJsonObject clientCapabilities() const;
159 const QString &token() const;
160 QString version() const;
161 bool online() const;
162
163 EventBus *eventbus() const;
164 WebSocket *websocket() const;
166
174 void setDefaultErrorHandler(QNetworkReply *rep) {
175#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
176 connect(rep, &QNetworkReply::errorOccurred, this, &ApiClient::defaultNetworkErrorHandler);
177#else
178 connect(rep, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
180#endif
181 }
182signals:
183 /*
184 * Emitted when the server requires authentication. Please authenticate your user via authenticate.
185 */
187
189
191 void connectionSuccess(QString loginMessage);
192 void networkError(QNetworkReply::NetworkError error);
193
195 void baseUrlChanged(const QString &baseUrl);
196 void appNameChanged(const QString &newAppName);
198
204
205 void userIdChanged(QString userId);
206
209
220
229 void userDataChanged(const QString &itemId, UserData *userData);
230
231public slots:
236 void restoreSavedSession();
237 /*
238 * Try to connect with the server. Tries to resolve redirects and retrieves information
239 * about the login procedure. Emits connectionSuccess on success, networkError or ConnectionFailed
240 * otherwise.
241 */
242 void setupConnection();
243 void authenticate(QString username, QString password, bool storeCredentials = false);
244 void submitQuickConnectCode(const QString &code);
245
249 void deleteSession();
250
254 void postCapabilities();
255 QString downloadUrl(const QString &itemId) const;
256
257protected slots:
258 void defaultNetworkErrorHandler(QNetworkReply::NetworkError error);
259 void onUserDataChanged(const QString &itemId, UserData *newData);
260 void credManagerServersListed(QStringList users);
261 void credManagerUsersListed(const QString &server, QStringList users);
262 void credManagerTokenRetrieved(const QString &server, const QString &user, const QString &token);
263
264 void classBegin() override;
265 void componentComplete() override;
266
267protected:
273 void addBaseRequestHeaders(QNetworkRequest &request, const QString &path, const QUrlQuery &params = QUrlQuery()) const;
274
279 void addTokenHeader(QNetworkRequest &request) const;
280
285
294
295
296private:
297 QScopedPointer<ApiClientPrivate> d_ptr;
298 QNetworkAccessManager m_naManager;
299 /*
300 * State information
301 */
302 /*
303 * Setters
304 */
305 void setAuthenticated(bool authenticated);
306 void setUserId(const QString &userId);
307
316 static inline int statusCode(QNetworkReply *rep) {
317 return rep->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
318 }
319
320};
321} // NS Jellyfin
322
323#endif // JELLYFIN_API_CLIENT
Definition apiclient.cpp:34
An Api client for Jellyfin. Handles requests and authentication.
Definition apiclient.h:90
QString appName
Definition apiclient.h:100
Jellyfin::ViewModel::Settings * settings
Definition apiclient.h:109
void authenticatedChanged(bool authenticated)
void setupConnection()
Definition apiclient.cpp:339
QString downloadUrl(const QString &itemId) const
Definition apiclient.cpp:469
void generateDeviceProfile()
Generates a profile, containing the name of the application, manufacturer and most importantly,...
Definition apiclient.cpp:474
void defaultNetworkErrorHandler(QNetworkReply::NetworkError error)
Definition apiclient.cpp:496
void addTokenHeader(QNetworkRequest &request) const
Adds the authorization to the header.
Definition apiclient.cpp:249
const QString & token() const
Retrieves the authentication token. Null QString if not authenticated.
Definition apiclient.cpp:169
ApiError
Definition apiclient.h:127
@ UNEXPECTED_REPLY
Definition apiclient.h:129
@ UNEXPECTED_STATUS
Definition apiclient.h:130
@ INVALID_PASSWORD
Definition apiclient.h:131
@ JSON_ERROR
Definition apiclient.h:128
void quickConnectRejected()
Emitted after submitQuickConnectCode failed.
void quickConnectAccepted()
Emitted after submitQuickConnectCode succeeded.
void credManagerTokenRetrieved(const QString &server, const QString &user, const QString &token)
Definition apiclient.cpp:330
void baseUrlChanged(const QString &baseUrl)
QVariantList supportedCommands
Definition apiclient.h:108
void setDefaultErrorHandler(QNetworkReply *rep)
Sets the error handler of a reply to this classes default error handler.
Definition apiclient.h:174
void componentComplete() override
Definition apiclient.cpp:225
virtual ~ApiClient()
Definition apiclient.cpp:86
void addBaseRequestHeaders(QNetworkRequest &request, const QString &path, const QUrlQuery &params=QUrlQuery()) const
Adds default headers to each request, like authentication headers etc.
Definition apiclient.cpp:239
QString baseUrl
Definition apiclient.h:99
void userDataChanged(const QString &itemId, UserData *userData)
onUserDataChanged Emitted when the user data of an item is changed on the server.
void appNameChanged(const QString &newAppName)
const QString & deviceId() const
Definition apiclient.cpp:135
QNetworkReply * get(const QString &path, const QUrlQuery &params=QUrlQuery())
Definition apiclient.cpp:262
void connectionFailed(ApiError error)
void restoreSavedSession()
Tries to access credentials and connect to a server. If nothing has been configured yet,...
Definition apiclient.cpp:298
QNetworkReply * post(const QString &path, const QJsonDocument &data, const QUrlQuery &params=QUrlQuery())
Definition apiclient.cpp:268
friend class PlaybackManager
Definition apiclient.h:92
void networkError(QNetworkReply::NetworkError error)
ApiClient(QObject *parent=nullptr)
Definition apiclient.cpp:70
Jellyfin::WebSocket * websocket
Definition apiclient.h:107
void supportedCommandsChanged()
void postCapabilities()
Shares the capabilities of this device to the server.
Definition apiclient.cpp:463
void setSupportedCommands(QVariantList newSupportedCommands)
Definition apiclient.cpp:189
void authenticationError(ApiError error)
void authenticate(QString username, QString password, bool storeCredentials=false)
Definition apiclient.cpp:395
void userIdChanged(QString userId)
void getBrandingConfiguration()
getBrandingConfiguration Gets the login message and custom CSS (which we ignore)
Definition apiclient.cpp:370
QString userId
Definition apiclient.h:103
Jellyfin::Model::DeviceTypeClass::Value deviceType
Definition apiclient.h:101
void setDeviceType(Model::DeviceType deviceType)
Definition apiclient.cpp:145
void classBegin() override
Definition apiclient.cpp:220
Jellyfin::EventBus * eventbus
Definition apiclient.h:106
bool online
Definition apiclient.h:116
void setupRequired()
Set-up is required. You'll need to manually set up the baseUrl-property, call setupConnection afterwa...
QJsonObject deviceProfile
Definition apiclient.h:104
void setAppName(const QString &appName)
Definition apiclient.cpp:114
void authenticationRequired()
QString version
Definition apiclient.h:105
bool authenticated
Definition apiclient.h:102
void submitQuickConnectCode(const QString &code)
Definition apiclient.cpp:432
void credManagerServersListed(QStringList users)
Definition apiclient.cpp:303
void deleteSession()
Logs the user out and clears the session.
Definition apiclient.cpp:452
void connectionSuccess(QString loginMessage)
const QJsonObject clientCapabilities() const
Definition apiclient.cpp:214
void onUserDataChanged(const QString &itemId, UserData *newData)
Definition apiclient.cpp:509
void credManagerUsersListed(const QString &server, QStringList users)
Definition apiclient.cpp:318
void setBaseUrl(const QString &url)
Definition apiclient.cpp:100
const QJsonObject deviceProfileJson() const
Definition apiclient.cpp:210
Definition useritemdatadto.h:49
"EventBus" object through which "events" are sent.
Definition eventbus.h:35
Value
Definition controllablesession.h:24
Definition settings.h:34
Keeps a connection with the Jellyfin server to receive real time updates.
Definition websocket.h:52
Jellyfin::DTO::UserItemDataDto UserItemDataDto
Definition useritemdatadto.h:207