migrate
This commit is contained in:
+62
-41
@@ -1,52 +1,73 @@
|
||||
# C++ objects and libs
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.la
|
||||
*.lai
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*.dll
|
||||
*.dylib
|
||||
|
||||
# Qt-es
|
||||
object_script.*.Release
|
||||
object_script.*.Debug
|
||||
*_plugin_import.cpp
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
*.pro.user
|
||||
*.pro.user.*
|
||||
*.qbs.user
|
||||
*.qbs.user.*
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
*.qmlc
|
||||
*.jsc
|
||||
Makefile*
|
||||
*build-*
|
||||
*.qm
|
||||
*.prl
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
|
||||
# QtCreator
|
||||
*.autosave
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# QtCreator Qml
|
||||
*.qmlproject.user
|
||||
*.qmlproject.user.*
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# QtCreator CMake
|
||||
CMakeLists.txt.user*
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# QtCreator 4.8< compilation database
|
||||
compile_commands.json
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
# QtCreator local machine specific files for imported projects
|
||||
*creator.user*
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "cmainwindow.h"
|
||||
#include "ui_cmainwindow.h"
|
||||
|
||||
#include "csubsonic.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
|
||||
cMainWindow::cMainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::cMainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
cSubsonic* subsonic = new cSubsonic("https://music.windesign.at", "birkeh", "WeissIchNicht8");
|
||||
|
||||
bool licenseValid;
|
||||
QString licenseEmail;
|
||||
QDateTime licenseExpires;
|
||||
QMap<qint32, QString> musicFolders;
|
||||
QMap<qint32, QString> shortcuts;
|
||||
QStringList indexes;
|
||||
QMap<qint32, INDEX> indexArtists;
|
||||
|
||||
QString artistName;
|
||||
qint32 artistPlayCount;
|
||||
QMap<qint32, ALBUM> albums;
|
||||
|
||||
qint32 albumParent;
|
||||
QString albumName;
|
||||
qint32 albumPlayCount;
|
||||
QMap<qint32, TRACK> tracks;
|
||||
|
||||
QMap<QString, GENRE> genres;
|
||||
|
||||
QMap<qint32, ARTIST> artists;
|
||||
|
||||
subsonic->getLicense(licenseValid, licenseEmail, licenseExpires);
|
||||
subsonic->getMusicFolders(musicFolders);
|
||||
subsonic->getIndexes(shortcuts, indexes, indexArtists);
|
||||
subsonic->getMusicDirectory(230, artistName, artistPlayCount, albums);
|
||||
subsonic->getMusicDirectory(885, albumParent, albumName, albumPlayCount, tracks);
|
||||
subsonic->getGenres(genres);
|
||||
subsonic->getArtists(indexes, artists);
|
||||
|
||||
delete subsonic;
|
||||
}
|
||||
|
||||
cMainWindow::~cMainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef CMAINWINDOW_H
|
||||
#define CMAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class cMainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class cMainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
cMainWindow(QWidget *parent = nullptr);
|
||||
~cMainWindow();
|
||||
|
||||
private:
|
||||
Ui::cMainWindow *ui;
|
||||
};
|
||||
#endif // CMAINWINDOW_H
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>cMainWindow</class>
|
||||
<widget class="QMainWindow" name="cMainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>cMainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar"/>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
#include "csubsonic.h"
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QEventLoop>
|
||||
#include <QUrl>
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
cSubsonic::cSubsonic() :
|
||||
m_server(""),
|
||||
m_user(""),
|
||||
m_password(""),
|
||||
m_version("1.15.0")
|
||||
{
|
||||
verify();
|
||||
}
|
||||
|
||||
cSubsonic::cSubsonic(const QString& server, const QString& user, const QString& password) :
|
||||
m_server(server),
|
||||
m_user(user),
|
||||
m_password(password),
|
||||
m_version("1.15.0")
|
||||
{
|
||||
verify();
|
||||
}
|
||||
|
||||
void cSubsonic::setServer(const QString& server)
|
||||
{
|
||||
m_server = server;
|
||||
}
|
||||
|
||||
QString cSubsonic::server()
|
||||
{
|
||||
return(m_server);
|
||||
}
|
||||
|
||||
void cSubsonic::setUser(const QString& user)
|
||||
{
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
QString cSubsonic::user()
|
||||
{
|
||||
return(m_user);
|
||||
}
|
||||
|
||||
void cSubsonic::setPassword(const QString& password)
|
||||
{
|
||||
m_password = password;
|
||||
}
|
||||
|
||||
bool cSubsonic::verify()
|
||||
{
|
||||
QDomElement element;
|
||||
|
||||
if(!sendRequest("ping.view", element))
|
||||
{
|
||||
m_version = element.attribute("version");
|
||||
|
||||
if(!sendRequest("ping.view", element))
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getLicense(bool& valid, QString& email, QDateTime& licenseExpires)
|
||||
{
|
||||
QDomElement element;
|
||||
|
||||
if(!sendRequest("getLicense", element, "license"))
|
||||
return(false);
|
||||
|
||||
valid = element.attribute("valid") == "true";
|
||||
email = element.attribute("email");
|
||||
licenseExpires = QDateTime::fromString(element.attribute("licenseExpires"), "yyyy-MM-ddThh:mm:ss.zzzZ");
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getMusicFolders(QMap<qint32, QString>& folders)
|
||||
{
|
||||
QDomElement element;
|
||||
|
||||
if(!sendRequest("getMusicFolders", element, "musicFolders"))
|
||||
return(false);
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
qint32 id;
|
||||
QString name;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("musicFolder"))
|
||||
{
|
||||
id = childElement.attribute("id").toInt();
|
||||
name = childElement.attribute("name");
|
||||
folders.insert(id, name);
|
||||
}
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getIndexes(QMap<qint32, QString>& shortcuts, QStringList& indexes, QMap<qint32, INDEX> &artists, const qint32 id, const QDate& modifiedSince)
|
||||
{
|
||||
QMap<QString, QString> parameter;
|
||||
QDomElement element;
|
||||
|
||||
if(id != -1)
|
||||
parameter.insert("musicFolderId", QString::number(id));
|
||||
|
||||
if(modifiedSince.isValid())
|
||||
parameter.insert("ifModifiedSince", QString::number(QDateTime(modifiedSince, QTime(0, 0)).toMSecsSinceEpoch()));
|
||||
|
||||
if(!sendRequest("getIndexes", element, "indexes", parameter))
|
||||
return(false);
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
QDomElement artistElement;
|
||||
|
||||
qint32 shortcutID;
|
||||
QString shortcutName;
|
||||
QString indexName;
|
||||
qint32 artistID;
|
||||
QString artistName;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("shortcut"))
|
||||
{
|
||||
shortcutID = childElement.attribute("id").toInt();
|
||||
shortcutName = childElement.attribute("name");
|
||||
shortcuts.insert(shortcutID, shortcutName);
|
||||
}
|
||||
else if(!childElement.tagName().compare("index"))
|
||||
{
|
||||
indexName = childElement.attribute("name");
|
||||
indexes.append(indexName);
|
||||
|
||||
QDomNode artistChild = childElement.firstChild();
|
||||
|
||||
while(!artistChild.isNull())
|
||||
{
|
||||
artistElement = artistChild.toElement();
|
||||
|
||||
if(!artistElement.tagName().compare("artist"))
|
||||
{
|
||||
artistID = artistElement.attribute("id").toInt();
|
||||
artistName = artistElement.attribute("name");
|
||||
|
||||
INDEX artist = { indexName, artistName, -1 };
|
||||
artists.insert(artistID, artist);
|
||||
}
|
||||
|
||||
artistChild = artistChild.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getMusicDirectory(const qint32 id, QString &name, qint32 &playCount, QMap<qint32, ALBUM>& albums)
|
||||
{
|
||||
QMap<QString, QString> parameter;
|
||||
QDomElement element;
|
||||
|
||||
parameter.insert("id", QString::number(id));
|
||||
|
||||
if(!sendRequest("getMusicDirectory", element, "directory", parameter))
|
||||
return(false);
|
||||
|
||||
name = element.attribute("name");
|
||||
playCount = element.attribute("playCount").toInt();
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
QDomElement artistElement;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("child"))
|
||||
{
|
||||
if(!childElement.hasAttribute("contentType"))
|
||||
{
|
||||
ALBUM album;
|
||||
qint32 albumID;
|
||||
|
||||
albumID = childElement.attribute("id").toInt();
|
||||
album.parent = childElement.attribute("parent").toInt();
|
||||
album.title = childElement.attribute("title");
|
||||
album.album = childElement.attribute("album");
|
||||
album.artist = childElement.attribute("artist");
|
||||
album.year = childElement.attribute("year").toInt();
|
||||
album.genre = childElement.attribute("genre");
|
||||
album.coverArt = childElement.attribute("coverArt").toInt();
|
||||
album.playCount = childElement.attribute("playCount").toInt();
|
||||
album.created = QDateTime::fromString(childElement.attribute("created"), "yyyy-MM-ddThh:mm:ss.zzzZ");
|
||||
|
||||
albums.insert(albumID, album);
|
||||
}
|
||||
}
|
||||
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getMusicDirectory(const qint32 id, qint32& parent, QString& name, qint32& playCount, QMap<qint32, TRACK>& tracks)
|
||||
{
|
||||
QMap<QString, QString> parameter;
|
||||
QDomElement element;
|
||||
|
||||
parameter.insert("id", QString::number(id));
|
||||
|
||||
if(!sendRequest("getMusicDirectory", element, "directory", parameter))
|
||||
return(false);
|
||||
|
||||
parent = element.attribute("parent").toInt();
|
||||
name = element.attribute("name");
|
||||
playCount = element.attribute("playCount").toInt();
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
QDomElement artistElement;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("child"))
|
||||
{
|
||||
if(childElement.hasAttribute("contentType"))
|
||||
{
|
||||
TRACK track;
|
||||
qint32 trackID;
|
||||
|
||||
trackID = childElement.attribute("id").toInt();
|
||||
track.parent = childElement.attribute("parent").toInt();
|
||||
track.title = childElement.attribute("title");
|
||||
track.album = childElement.attribute("album");
|
||||
track.artist = childElement.attribute("artist");
|
||||
track.track = childElement.attribute("track");
|
||||
track.year = childElement.attribute("year").toInt();
|
||||
track.genre = childElement.attribute("genre");
|
||||
track.coverArt = childElement.attribute("coverArt").toInt();
|
||||
track.size = childElement.attribute("size").toInt();
|
||||
track.contentType = childElement.attribute("contentType");
|
||||
track.suffix = childElement.attribute("suffix");
|
||||
track.duration = childElement.attribute("duration").toInt();
|
||||
track.bitRate = childElement.attribute("duration").toInt();
|
||||
track.path = childElement.attribute("path");
|
||||
track.isVideo = childElement.attribute("isVideo") == "true";
|
||||
track.playCount = childElement.attribute("playCount").toInt();
|
||||
track.discNumber = childElement.attribute("discNumber");
|
||||
track.created = QDateTime::fromString(childElement.attribute("created"), "yyyy-MM-ddThh:mm:ss.zzzZ");
|
||||
track.albumID = childElement.attribute("albumID").toInt();
|
||||
track.artistID = childElement.attribute("artistID").toInt();
|
||||
track.type = childElement.attribute("type");
|
||||
|
||||
tracks.insert(trackID, track);
|
||||
}
|
||||
}
|
||||
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getGenres(QMap<QString, GENRE>& genres)
|
||||
{
|
||||
QDomElement element;
|
||||
|
||||
if(!sendRequest("getGenres", element, "genres"))
|
||||
return(false);
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("genre"))
|
||||
{
|
||||
GENRE genre;
|
||||
QString name;
|
||||
|
||||
genre.songCount = childElement.attribute("songCount").toInt();
|
||||
genre.albumCount = childElement.attribute("albumCount").toInt();
|
||||
name = childElement.text();
|
||||
|
||||
genres.insert(name, genre);
|
||||
}
|
||||
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cSubsonic::getArtists(QStringList& indexes, QMap<qint32, ARTIST>& artists, const qint32 id)
|
||||
{
|
||||
QMap<QString, QString> parameter;
|
||||
QDomElement element;
|
||||
|
||||
if(id != -1)
|
||||
parameter.insert("musicFolderId", QString::number(id));
|
||||
|
||||
if(!sendRequest("getArtists", element, "artists", parameter))
|
||||
return(false);
|
||||
|
||||
QDomNode child = element.firstChild();
|
||||
QDomElement childElement;
|
||||
QDomElement artistElement;
|
||||
|
||||
QString index;
|
||||
|
||||
while(!child.isNull())
|
||||
{
|
||||
childElement = child.toElement();
|
||||
|
||||
if(!childElement.tagName().compare("index"))
|
||||
{
|
||||
index = childElement.attribute("name");
|
||||
indexes.append(index);
|
||||
|
||||
QDomNode artistChild = childElement.firstChild();
|
||||
|
||||
while(!artistChild.isNull())
|
||||
{
|
||||
artistElement = artistChild.toElement();
|
||||
|
||||
if(!artistElement.tagName().compare("artist"))
|
||||
{
|
||||
ARTIST artist;
|
||||
|
||||
artist.index = index;
|
||||
artist.name = artistElement.attribute("name");
|
||||
artist.coverArt = artistElement.attribute("coverArt");
|
||||
artist.albumCount = artistElement.attribute("albumCount").toInt();
|
||||
|
||||
artists.insert(artistElement.attribute("id").toInt(), artist);
|
||||
}
|
||||
|
||||
artistChild = artistChild.nextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
QString cSubsonic::randomString()
|
||||
{
|
||||
const QString possibleCharacters("abcdef0123456789");
|
||||
const int randomStringLength = 6;
|
||||
|
||||
QString randomString;
|
||||
|
||||
for(int i = 0; i < randomStringLength; ++i)
|
||||
{
|
||||
int index = rand() % possibleCharacters.length();
|
||||
QChar nextChar = possibleCharacters.at(index);
|
||||
randomString.append(nextChar);
|
||||
}
|
||||
return(randomString);
|
||||
}
|
||||
|
||||
bool cSubsonic::sendRequest(const QString& request, QDomElement& element, const QString& verify, const QMap<QString, QString>& parameter)
|
||||
{
|
||||
QNetworkAccessManager networkManager;
|
||||
QString salt = randomString();
|
||||
QString token = QCryptographicHash::hash(QString(m_password+salt).toUtf8(), QCryptographicHash::Md5).toHex();
|
||||
QString strRequest = QString("%1/rest/%2?u=%3&t=%4&s=%5&v=%6&c=subJuke").arg(m_server, request, m_user, token, salt, m_version);
|
||||
|
||||
if(parameter.count())
|
||||
{
|
||||
QString param;
|
||||
|
||||
QMapIterator<QString, QString> i(parameter);
|
||||
while(i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
param.append(QString("&%1=%2").arg(i.key(), i.value()));
|
||||
}
|
||||
|
||||
strRequest.append(param);
|
||||
}
|
||||
|
||||
// qDebug() << strRequest;
|
||||
|
||||
QUrl url(strRequest);
|
||||
QNetworkRequest networkRequest(url);
|
||||
QNetworkReply* reply = networkManager.get(networkRequest);
|
||||
QEventLoop loop;
|
||||
|
||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
if(reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QDomDocument doc;
|
||||
QString errorStr;
|
||||
int errorLine;
|
||||
int errorColumn;
|
||||
if(!doc.setContent(reply->readAll(), false, &errorStr, &errorLine, &errorColumn))
|
||||
return(false);
|
||||
|
||||
// qDebug() << doc.toString();
|
||||
element = doc.documentElement();
|
||||
if(element.tagName().compare("subsonic-response"))
|
||||
return(false);
|
||||
|
||||
QString status = element.attribute("status");
|
||||
if(status == "failed")
|
||||
return(false);
|
||||
|
||||
if(verify.isEmpty())
|
||||
{
|
||||
if(element.isNull())
|
||||
return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
element = element.firstChild().toElement();
|
||||
if(element.isNull())
|
||||
return(false);
|
||||
|
||||
if(element.tagName().compare(verify))
|
||||
return(false);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug() << reply->errorString();
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#ifndef CSUBSONIC_H
|
||||
#define CSUBSONIC_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QDomElement>
|
||||
#include <QMap>
|
||||
#include <QDate>
|
||||
|
||||
|
||||
typedef struct tagINDEX
|
||||
{
|
||||
QString index;
|
||||
QString name;
|
||||
qint32 playCount;
|
||||
} INDEX;
|
||||
|
||||
typedef struct tagALBUM
|
||||
{
|
||||
qint32 parent;
|
||||
QString title;
|
||||
QString album;
|
||||
QString artist;
|
||||
qint16 year;
|
||||
QString genre;
|
||||
qint32 coverArt;
|
||||
qint32 playCount;
|
||||
QDateTime created;
|
||||
} ALBUM;
|
||||
|
||||
typedef struct tagTRACK
|
||||
{
|
||||
qint32 parent;
|
||||
QString title;
|
||||
QString album;
|
||||
QString artist;
|
||||
QString track;
|
||||
qint16 year;
|
||||
QString genre;
|
||||
qint32 coverArt;
|
||||
qint32 size;
|
||||
QString contentType;
|
||||
QString suffix;
|
||||
qint32 duration;
|
||||
qint32 bitRate;
|
||||
QString path;
|
||||
bool isVideo;
|
||||
qint32 playCount;
|
||||
QString discNumber;
|
||||
QDateTime created;
|
||||
qint32 albumID;
|
||||
qint32 artistID;
|
||||
QString type;
|
||||
} TRACK;
|
||||
|
||||
typedef struct tagGENRE
|
||||
{
|
||||
qint32 songCount;
|
||||
qint32 albumCount;
|
||||
} GENRE;
|
||||
|
||||
typedef struct tagARTIST
|
||||
{
|
||||
QString index;
|
||||
QString name;
|
||||
QString coverArt;
|
||||
qint32 albumCount;
|
||||
} ARTIST;
|
||||
|
||||
class cSubsonic
|
||||
{
|
||||
public:
|
||||
cSubsonic();
|
||||
cSubsonic(const QString& server, const QString& user, const QString& password);
|
||||
|
||||
void setServer(const QString& server);
|
||||
QString server();
|
||||
|
||||
void setUser(const QString& user);
|
||||
QString user();
|
||||
|
||||
void setPassword(const QString& password);
|
||||
|
||||
bool verify();
|
||||
bool getLicense(bool &valid, QString &email, QDateTime &licenseExpires);
|
||||
bool getMusicFolders(QMap<qint32, QString>& folders);
|
||||
bool getIndexes(QMap<qint32, QString>& shortcuts, QStringList& indexes, QMap<qint32, INDEX>& artists, const qint32 id = -1, const QDate& modifiedSince = QDate());
|
||||
bool getMusicDirectory(const qint32 id, QString& name, qint32& playCount, QMap<qint32, ALBUM>& albums);
|
||||
bool getMusicDirectory(const qint32 id, qint32& parent, QString& name, qint32& playCount, QMap<qint32, TRACK>& tracks);
|
||||
bool getGenres(QMap<QString, GENRE>& genres);
|
||||
bool getArtists(QStringList& indexes, QMap<qint32, ARTIST>& artists, const qint32 id = -1);
|
||||
private:
|
||||
QString m_server;
|
||||
QString m_user;
|
||||
QString m_password;
|
||||
QString m_version;
|
||||
|
||||
QString randomString();
|
||||
bool sendRequest(const QString& request, QDomElement& element, const QString& verify = "", const QMap<QString, QString>& parameter = QMap<QString, QString>());
|
||||
};
|
||||
|
||||
#endif // CSUBSONIC_H
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "cmainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QLocale>
|
||||
#include <QTranslator>
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QTranslator translator;
|
||||
const QStringList uiLanguages = QLocale::system().uiLanguages();
|
||||
for (const QString &locale : uiLanguages) {
|
||||
const QString baseName = "subJuke_" + QLocale(locale).name();
|
||||
if (translator.load(":/i18n/" + baseName)) {
|
||||
a.installTranslator(&translator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cMainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
QT += core gui network xml
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
csubsonic.cpp \
|
||||
main.cpp \
|
||||
cmainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
cmainwindow.h \
|
||||
csubsonic.h
|
||||
|
||||
FORMS += \
|
||||
cmainwindow.ui
|
||||
|
||||
TRANSLATIONS += \
|
||||
subJuke_de_AT.ts
|
||||
CONFIG += lrelease
|
||||
CONFIG += embed_translations
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_AT"></TS>
|
||||
Reference in New Issue
Block a user