-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Livemetadata PR #1675
Closed
Closed
[WIP] Livemetadata PR #1675
Changes from all commits
Commits
Show all changes
79 commits
Select commit
Hold shift + click to select a range
32cece7
Added .vscode on gitignore
davidhm ba829a2
First few files
davidhm 5169748
So far manual tests are working
davidhm 3d8c501
Pre automatic tests
davidhm 523d09b
Using github as a backup
davidhm 23ef862
Error when compiling moc generated cpp
davidhm 0a4a4d6
WIP: Automatic tests
davidhm d203e85
Moved timers away from Track object
davidhm 1a6bc0d
Pre volume scrobbling
davidhm ff27795
Pre tests, scrobbling manager
davidhm db2db23
Deadlock
davidhm 7f55150
Solved the deadlock, simple tests pass
davidhm 121443e
WIP: Adding file listener
davidhm 2cd5bbc
Fixed file buffer, it's automatically updated now
davidhm b9c4a6c
[Untested] Fixed file info, modified metadatabroadcast
davidhm e10df9e
[WIP] Adding tests for scrobbling manager
davidhm c1de7db
Added first test for scrobbling manager
davidhm 50019b0
File listener template + factory
davidhm d805306
Scrobbling tests done
davidhm 4e714d5
[WIP] Adding file preferences
davidhm b3f8ea8
Preferences mock-up
davidhm 8cd9c16
Changed everything to a weak pointer
davidhm d4b9aa5
Added file listener path in options
davidhm ec98ef6
[WIP] Persistent config now playing file
davidhm 0209b4a
[WIP] Requested changes
davidhm 2d8f4a2
Adding new tab
davidhm 88c4819
Added mock-up in preferences
davidhm ab8b524
Table view mockup
davidhm 97daf77
Pre changing prefmetadata class
davidhm 4bc2de3
Added file settings
davidhm 49b8b93
[Untested] Added options to file listener
davidhm 567e9b5
Modified settings, added concurrency
davidhm 5748fa9
Added dedicated thread
davidhm 3a677b6
Modified author and title string
davidhm 9c43d09
Merge branch 'master' into Livemetadata
davidhm 2c21183
Added connections to lambda expressions in player manager, file liste…
davidhm a6d67d7
Fixed tests failing
davidhm ba8a6fc
Added mock network manager, gotta test with mock server
davidhm 6b7f207
Now listening scrobbles work with ListenBrainz
davidhm f7c6a83
Deleted log file
davidhm 1057b06
Merge branch 'master' into Livemetadata
davidhm 152925c
ListenBrainz full scrobbles work now too
davidhm ad43628
Fixed double delete in developer mode
davidhm 751f567
Forgot to compile
davidhm 64d35c5
Modified metadata file options
davidhm ddfb859
Editable combobox
davidhm e4dc8df
Added mpris stub, not working
davidhm a1ad4c6
MPRIS now reflects the playback state
davidhm ee4c5a5
Disabled failing test until a solution is found
davidhm 4571d43
Fixed broken tests, continuing MPRIS implementation
davidhm 185d2f2
Fixed non compiling build
davidhm 0bc22be
Segfault on weak_ptr
davidhm 0af2279
Fixed eject bug
davidhm 6be0042
Mpris reflects AutoDJ enabled
davidhm 62eae49
Pause, play and go next MPRIS functions work
davidhm c2317c7
Fixed correct fade-in in MPRIS
davidhm 8b5e54a
Added volume, playback status and loop status as well as a LINUX define
davidhm cac8c1f
Moved MPRIS into a feature
davidhm 6807838
Added MPRIS macro in includes too
davidhm d6880a1
MPRIS is seekable now
davidhm 32e565a
MPRIS broadcasts current track and rate works now too
davidhm 1b77c8b
Modified linked lists into hash maps
davidhm 7ba10a7
Added space after commas
davidhm 94ab525
Changed ref ampersand and disabled non working test
davidhm 5e8fb60
Added more button in encoding combo box
davidhm 41bdfb9
Resized combobox
davidhm 0def3e3
Merge remote-tracking branch 'upstream/master' into Livemetadata
davidhm 9fe5277
Added few UI suggestions
davidhm 97271d8
Missing include
davidhm f4b9649
Added cover art to mpris
davidhm dde6c47
Added cover art to MPRIS player
davidhm e1cfd7a
Fixed few things
davidhm 69a3020
Deleting all cover art files
davidhm 7af4dd7
Single file image
davidhm 170e6c9
Cover art file is now QTemporaryFile
davidhm 8c6fa58
Revamped encoding combobox
davidhm 899f207
Fixed some cover URL generation issues
daschuer 4a13665
Small fixes
davidhm 39dc901
Merge pull request #1 from daschuer/Livemetadata
davidhm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
|
||
#include <QTextCodec> | ||
#include <QtConcurrentRun> | ||
|
||
#include "broadcast/filelistener/filelistener.h" | ||
#include "broadcast/filelistener/metadatafileworker.h" | ||
#include "preferences/metadatafilesettings.h" | ||
|
||
|
||
FileListener::FileListener(UserSettingsPointer pConfig) | ||
: m_COsettingsChanged(kFileSettingsChanged), | ||
m_pConfig(pConfig), | ||
m_latestSettings(MetadataFileSettings::getPersistedSettings(pConfig)), | ||
m_filePathChanged(false), | ||
m_tracksPaused(false) { | ||
|
||
MetadataFileWorker *newWorker = new MetadataFileWorker(m_latestSettings.filePath); | ||
newWorker->moveToThread(&m_workerThread); | ||
|
||
connect(&m_workerThread, SIGNAL(finished()), | ||
newWorker, SLOT(deleteLater())); | ||
|
||
connect(this, SIGNAL(deleteFile()), | ||
newWorker, SLOT(slotDeleteFile())); | ||
|
||
connect(this, SIGNAL(moveFile(QString)), | ||
newWorker, SLOT(slotMoveFile(QString))); | ||
|
||
connect(this, SIGNAL(writeMetadataToFile(QByteArray)), | ||
newWorker, SLOT(slotWriteMetadataToFile(QByteArray))); | ||
|
||
connect(this, SIGNAL(clearFile()), | ||
newWorker, SLOT(slotClearFile())); | ||
|
||
connect(&m_COsettingsChanged, SIGNAL(valueChanged(double)), | ||
this, SLOT(slotFileSettingsChanged(double))); | ||
|
||
m_workerThread.start(); | ||
} | ||
|
||
FileListener::~FileListener() { | ||
emit clearFile(); | ||
m_workerThread.quit(); | ||
m_workerThread.wait(); | ||
} | ||
|
||
|
||
void FileListener::slotBroadcastCurrentTrack(TrackPointer pTrack) { | ||
if (!m_latestSettings.enabled) { | ||
return; | ||
} | ||
if (!pTrack) { | ||
emit clearFile(); | ||
} | ||
else { | ||
m_fileContents.title = pTrack->getTitle(); | ||
m_fileContents.artist = pTrack->getArtist(); | ||
QString writtenString(m_latestSettings.fileFormatString); | ||
writtenString.replace("$author", pTrack->getArtist()). | ||
replace("$title", pTrack->getTitle()) += '\n'; | ||
QTextCodec *codec = QTextCodec::codecForName(m_latestSettings.fileEncoding); | ||
DEBUG_ASSERT(codec); | ||
QByteArray fileContents = codec->fromUnicode(writtenString); | ||
m_tracksPaused = false; | ||
emit writeMetadataToFile(fileContents); | ||
} | ||
} | ||
|
||
void FileListener::slotScrobbleTrack(TrackPointer pTrack) { | ||
Q_UNUSED(pTrack); | ||
} | ||
|
||
void FileListener::slotAllTracksPaused() { | ||
if (!m_latestSettings.enabled) { | ||
return; | ||
} | ||
m_tracksPaused = true; | ||
emit clearFile(); | ||
} | ||
|
||
void FileListener::slotFileSettingsChanged(double value) { | ||
if (value) { | ||
FileSettings latestSettings = MetadataFileSettings::getLatestSettings(); | ||
m_filePathChanged = latestSettings.filePath != m_latestSettings.filePath; | ||
m_latestSettings = latestSettings; | ||
updateStateFromSettings(); | ||
} | ||
} | ||
|
||
void FileListener::updateStateFromSettings() { | ||
if (m_latestSettings.enabled) { | ||
updateFile(); | ||
} | ||
else { | ||
emit deleteFile(); | ||
} | ||
} | ||
|
||
void FileListener::updateFile() { | ||
if (m_filePathChanged) { | ||
emit moveFile(m_latestSettings.filePath); | ||
m_filePathChanged = false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think m_filePathChanged = false; is missing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, thanks. |
||
if (!m_tracksPaused && !m_fileContents.isEmpty()) { | ||
QTextCodec *codec = QTextCodec::codecForName(m_latestSettings.fileEncoding); | ||
if (!codec) { | ||
qWarning() << "Text codec selected from metadata broadcast settings doesn't exist"; | ||
codec = QTextCodec::codecForName("UTF-8"); | ||
} | ||
QString newContents(m_latestSettings.fileFormatString); | ||
newContents.replace("$author", m_fileContents.artist) | ||
.replace("$title", m_fileContents.title) += '\n'; | ||
QByteArray contentsBinary = codec->fromUnicode(newContents); | ||
emit writeMetadataToFile(contentsBinary); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#pragma once | ||
|
||
#include <QFile> | ||
#include <QThread> | ||
#include "preferences/dialog/dlgprefmetadata.h" | ||
#include "control/controlpushbutton.h" | ||
#include "broadcast/scrobblingservice.h" | ||
|
||
class FileListener: public ScrobblingService { | ||
Q_OBJECT | ||
public: | ||
explicit FileListener(UserSettingsPointer pSettings); | ||
~FileListener() override; | ||
void slotBroadcastCurrentTrack(TrackPointer pTrack) override; | ||
void slotScrobbleTrack(TrackPointer pTrack) override; | ||
void slotAllTracksPaused() override; | ||
signals: | ||
void deleteFile(); | ||
void moveFile(QString destination); | ||
void writeMetadataToFile(QByteArray contents); | ||
void clearFile(); | ||
private slots: | ||
void slotFileSettingsChanged(double value); | ||
private: | ||
|
||
struct WrittenMetadata { | ||
QString title, artist; | ||
bool isEmpty() { | ||
return title.isEmpty() && artist.isEmpty(); | ||
} | ||
}; | ||
|
||
void updateStateFromSettings(); | ||
void updateFile(); | ||
|
||
ControlPushButton m_COsettingsChanged; | ||
UserSettingsPointer m_pConfig; | ||
FileSettings m_latestSettings; | ||
QThread m_workerThread; | ||
WrittenMetadata m_fileContents; | ||
bool m_filePathChanged; | ||
bool m_tracksPaused; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
#include "broadcast/filelistener/metadatafileworker.h" | ||
|
||
MetadataFileWorker::MetadataFileWorker(const QString& filePath) | ||
: m_file(filePath) { | ||
} | ||
|
||
void MetadataFileWorker::slotDeleteFile() { | ||
m_file.remove(); | ||
} | ||
|
||
void MetadataFileWorker::slotMoveFile(QString destination) { | ||
m_file.remove(); | ||
m_file.setFileName(destination); | ||
} | ||
|
||
void MetadataFileWorker::slotWriteMetadataToFile(QByteArray fileContents) { | ||
m_file.open(QIODevice::WriteOnly | | ||
QIODevice::Text | | ||
QIODevice::Unbuffered); | ||
m_file.write(fileContents); | ||
m_file.close(); | ||
} | ||
|
||
void MetadataFileWorker::slotClearFile() { | ||
m_file.resize(0); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include <QObject> | ||
#include <QFile> | ||
|
||
class MetadataFileWorker : public QObject { | ||
Q_OBJECT | ||
public: | ||
explicit MetadataFileWorker(const QString& filePath); | ||
public slots: | ||
void slotDeleteFile(); | ||
void slotMoveFile(QString destination); | ||
void slotWriteMetadataToFile(QByteArray fileContents); | ||
void slotClearFile(); | ||
private: | ||
QFile m_file; | ||
}; | ||
|
38 changes: 38 additions & 0 deletions
38
src/broadcast/listenbrainzlistener/listenbrainzjsonfactory.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
|
||
#include <QDateTime> | ||
#include <QJsonArray> | ||
#include <QJsonDocument> | ||
#include <QJsonObject> | ||
|
||
#include "broadcast/listenbrainzlistener/listenbrainzjsonfactory.h" | ||
|
||
|
||
QByteArray ListenBrainzJSONFactory::getJSONFromTrack(TrackPointer pTrack, JsonType type) { | ||
QJsonObject jsonObject; | ||
QString stringType; | ||
if (type == NowListening) { | ||
stringType = "playing_now"; | ||
} | ||
else { | ||
stringType = "single"; | ||
} | ||
|
||
QJsonArray payloadArray; | ||
QJsonObject payloadObject; | ||
QJsonObject metadataObject; | ||
QString title = pTrack->getTitle(); | ||
QString artist = pTrack->getArtist(); | ||
metadataObject.insert("artist_name", artist); | ||
metadataObject.insert("track_name", title); | ||
payloadObject.insert("track_metadata", metadataObject); | ||
qint64 timeStamp = QDateTime::currentMSecsSinceEpoch() / 1000; | ||
|
||
if (type == Single) { | ||
payloadObject.insert("listened_at", timeStamp); | ||
} | ||
payloadArray.append(payloadObject); | ||
jsonObject.insert("listen_type", stringType); | ||
jsonObject.insert("payload", payloadArray); | ||
QJsonDocument doc(jsonObject); | ||
return doc.toJson(QJsonDocument::Compact); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this one deleted?
You can make it a patented_ptr to let Qt take care of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the signal finished from the thread is emitted the object is deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is hard to spot. Where exactly is it?
We should follow the rule to pass the pointer with the ownership. Since this is a QObject, the qt object tee may works best as an owner.