Skip to content

Commit

Permalink
lyrics: Restore GTK support
Browse files Browse the repository at this point in the history
- Make it possible to reuse most code with the Qt plugin
- Rename to lyrics since lyricwiki is no longer used as source
  • Loading branch information
radioactiveman committed Feb 3, 2024
1 parent 5236ded commit 8cb90d4
Show file tree
Hide file tree
Showing 21 changed files with 1,449 additions and 858 deletions.
16 changes: 8 additions & 8 deletions .github/actions/install-dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ runs:
install: >-
mingw-w64-i686-autotools mingw-w64-i686-faad2 mingw-w64-i686-ffmpeg
mingw-w64-i686-flac mingw-w64-i686-fluidsynth mingw-w64-i686-gcc
mingw-w64-i686-gtk2 mingw-w64-i686-lame mingw-w64-i686-libbs2b
mingw-w64-i686-libcdio-paranoia mingw-w64-i686-libcue
mingw-w64-i686-libmodplug mingw-w64-i686-libopenmpt
mingw-w64-i686-libsamplerate mingw-w64-i686-libsidplayfp
mingw-w64-i686-libsoxr mingw-w64-i686-libvorbis mingw-w64-i686-meson
mingw-w64-i686-mpg123 mingw-w64-i686-neon mingw-w64-i686-opusfile
mingw-w64-i686-pkg-config mingw-w64-i686-qt5-base mingw-w64-i686-SDL2
mingw-w64-i686-wavpack
mingw-w64-i686-gtk2 mingw-w64-i686-json-glib mingw-w64-i686-lame
mingw-w64-i686-libbs2b mingw-w64-i686-libcdio-paranoia
mingw-w64-i686-libcue mingw-w64-i686-libmodplug
mingw-w64-i686-libopenmpt mingw-w64-i686-libsamplerate
mingw-w64-i686-libsidplayfp mingw-w64-i686-libsoxr
mingw-w64-i686-libvorbis mingw-w64-i686-meson mingw-w64-i686-mpg123
mingw-w64-i686-neon mingw-w64-i686-opusfile mingw-w64-i686-pkg-config
mingw-w64-i686-qt5-base mingw-w64-i686-SDL2 mingw-w64-i686-wavpack
7 changes: 4 additions & 3 deletions .github/actions/install-dependencies/install-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ ubuntu_packages='gettext libadplug-dev libasound2-dev libavformat-dev
libbinio-dev libbs2b-dev libcddb2-dev libcdio-cdda-dev
libcue-dev libcurl4-gnutls-dev libdbus-glib-1-dev
libfaad-dev libflac-dev libfluidsynth-dev libgl1-mesa-dev
libjack-jackd2-dev liblircclient-dev libmms-dev libmodplug-dev
libmp3lame-dev libmpg123-dev libneon27-gnutls-dev libnotify-dev
libopenmpt-dev libopusfile-dev libpulse-dev libqt5opengl5-dev
libjack-jackd2-dev libjson-glib-dev liblircclient-dev
libmms-dev libmodplug-dev libmp3lame-dev libmpg123-dev
libneon27-gnutls-dev libnotify-dev libopenmpt-dev
libopusfile-dev libpulse-dev libqt5opengl5-dev
libqt5x11extras5-dev libsamplerate0-dev libsdl2-dev
libsidplayfp-dev libsndfile1-dev libsndio-dev libsoxr-dev
libvorbis-dev libwavpack-dev libxml2-dev qtbase5-dev
Expand Down
4 changes: 4 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ fi
AC_SUBST(USE_GTK)
if test $USE_GTK = yes ; then
PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= 1.0)
fi
if test $HAVE_MSWINDOWS = yes ; then
PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.32)
else
Expand Down
6 changes: 3 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ TRANSPORT_PLUGINS="gio"

if test "x$USE_GTK" = "xyes" ; then
EFFECT_PLUGINS="$EFFECT_PLUGINS ladspa"
GENERAL_PLUGINS="$GENERAL_PLUGINS albumart playlist-manager search-tool statusicon"
GENERAL_PLUGINS="$GENERAL_PLUGINS albumart lyrics playlist-manager search-tool statusicon"
GENERAL_PLUGINS="$GENERAL_PLUGINS gtkui skins"
VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS blur_scope cairo-spectrum"
fi

if test "x$USE_QT" = "xyes" ; then
GENERAL_PLUGINS="$GENERAL_PLUGINS albumart-qt lyricwiki-qt playlist-manager-qt search-tool-qt song-info-qt statusicon-qt"
GENERAL_PLUGINS="$GENERAL_PLUGINS albumart-qt lyrics-qt playlist-manager-qt search-tool-qt song-info-qt statusicon-qt"
GENERAL_PLUGINS="$GENERAL_PLUGINS qtui skins-qt"
VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS blur_scope-qt qt-spectrum vumeter-qt"
fi
Expand Down Expand Up @@ -829,6 +829,7 @@ echo " Ampache browser (requires Qt): $have_ampache"
echo " Delete Files: $USE_GTK_OR_QT"
echo " libnotify OSD: $have_notify"
echo " Linux Infrared Remote Control (LIRC): $have_lirc"
echo " Lyrics Viewer: yes"
echo " MPRIS 2 Server: $have_mpris2"
echo " Scrobbler 2.0: $have_scrobbler2"
echo " Song Change: $have_songchange"
Expand Down Expand Up @@ -859,7 +860,6 @@ if test "x$USE_QT" = "xyes" ; then
echo " Winamp Classic Interface: yes"
echo " Album Art: yes"
echo " Blur Scope: yes"
echo " Lyrics Viewer: yes"
echo " OpenGL Spectrum Analyzer: $have_qtglspectrum"
echo " Playlist Manager: yes"
echo " Search Tool: yes"
Expand Down
2 changes: 2 additions & 0 deletions extra.mk.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ GTK_CFLAGS ?= @GTK_CFLAGS@
GTK_LIBS ?= @GTK_LIBS@
JACK_CFLAGS ?= @JACK_CFLAGS@
JACK_LIBS ?= @JACK_LIBS@
JSON_GLIB_CFLAGS ?= @JSON_GLIB_CFLAGS@
JSON_GLIB_LIBS ?= @JSON_GLIB_LIBS@
LIBFLAC_LIBS ?= @LIBFLAC_LIBS@
LIBFLAC_CFLAGS ?= @LIBFLAC_CFLAGS@
MMS_CFLAGS ?= @MMS_CFLAGS@
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ if meson.version().version_compare('>= 0.53')
'Delete Files': conf.has('USE_GTK_OR_QT'),
'Libnotify OSD': get_variable('have_notify', false),
'Linux Infrared Remote Control (LIRC)': get_variable('have_lirc', false),
'Lyrics Viewer': get_variable('have_lyrics', false),
'MPRIS 2 Server': get_variable('have_mpris2', false),
'Scrobbler 2.0': get_variable('have_scrobbler2', false),
'Song Change': get_option('songchange'),
Expand All @@ -307,7 +308,6 @@ if meson.version().version_compare('>= 0.53')
'Winamp Classic Interface': true,
'Album Art': true,
'Blur Scope': true,
'Lyrics Viewer': get_variable('have_lyrics', false),
'OpenGL Spectrum Analyzer': get_variable('have_qtglspectrum', false),
'Playlist Manager': true,
'Search Tool': true,
Expand Down
18 changes: 18 additions & 0 deletions src/lyrics-qt/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
PLUGIN = lyrics-qt${PLUGIN_SUFFIX}

SRCS = ../lyrics/chart_lyrics_provider.cc \
../lyrics/file_provider.cc \
../lyrics/lyrics-qt.cc \
../lyrics/lyrics_ovh_provider.cc \
../lyrics/utils.cc

include ../../buildsys.mk
include ../../extra.mk

plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}

LD = ${CXX}

CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${QT_CFLAGS} ${GLIB_CFLAGS} ${XML_CFLAGS} -I../..
LIBS += ${QT_LIBS} ${GLIB_LIBS} ${XML_LIBS}
18 changes: 18 additions & 0 deletions src/lyrics/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
PLUGIN = lyrics${PLUGIN_SUFFIX}

SRCS = chart_lyrics_provider.cc \
file_provider.cc \
lyrics.cc \
lyrics_ovh_provider.cc \
utils.cc

include ../../buildsys.mk
include ../../extra.mk

plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}

LD = ${CXX}

CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${JSON_GLIB_CFLAGS} ${XML_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${JSON_GLIB_LIBS} ${XML_LIBS} -laudgui
195 changes: 195 additions & 0 deletions src/lyrics/chart_lyrics_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2024 Thomas Lange <[email protected]>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "lyrics.h"

void ChartLyricsProvider::reset_lyric_metadata ()
{
m_lyric_id = -1;
m_lyric_checksum = String ();
m_lyric_url = String ();
m_lyrics = String ();
}

String ChartLyricsProvider::match_uri (LyricsState state)
{
auto artist = str_copy (state.artist);
artist = str_encode_percent (artist, -1);

auto title = str_copy (state.title);
title = str_encode_percent (title, -1);

return String (str_concat ({m_base_url, "/SearchLyric?artist=", artist, "&song=", title}));
}

bool ChartLyricsProvider::has_match (LyricsState state, xmlNodePtr node)
{
String lyric_id, checksum, url, artist, title;

for (xmlNodePtr cur_node = node->xmlChildrenNode; cur_node; cur_node = cur_node->next)
{
if (cur_node->type != XML_ELEMENT_NODE)
continue;

xmlChar * content = xmlNodeGetContent (cur_node);

if (xmlStrEqual (cur_node->name, (xmlChar *) "LyricId"))
lyric_id = String ((const char *) content);
else if (xmlStrEqual (cur_node->name, (xmlChar *) "LyricChecksum"))
checksum = String ((const char *) content);
else if (xmlStrEqual (cur_node->name, (xmlChar *) "SongUrl"))
url = String ((const char *) content);
else if (xmlStrEqual (cur_node->name, (xmlChar *) "Artist"))
artist = String ((const char *) content);
else if (xmlStrEqual (cur_node->name, (xmlChar *) "Song"))
title = String ((const char *) content);

xmlFree (content);
}

if (lyric_id && checksum && artist && title) // url is optional
{
int id = str_to_int (lyric_id);

if (id > 0 &&
! strcmp_nocase (artist, state.artist) &&
! strcmp_nocase (title, state.title))
{
m_lyric_id = id;
m_lyric_checksum = checksum;
m_lyric_url = url;

return true;
}
}

return false;
}

bool ChartLyricsProvider::match (LyricsState state)
{
reset_lyric_metadata ();

auto handle_result_cb = [=] (const char * uri, const Index<char> & buf) {
if (! buf.len ())
{
update_lyrics_window_error (str_printf (_("Unable to fetch %s"), uri));
return;
}

xmlDocPtr doc = xmlReadMemory (buf.begin (), buf.len (), nullptr, nullptr, 0);
if (! doc)
{
update_lyrics_window_error (str_printf (_("Unable to parse %s"), uri));
return;
}

xmlNodePtr root = xmlDocGetRootElement (doc);

for (xmlNodePtr cur_node = root->xmlChildrenNode; cur_node; cur_node = cur_node->next)
{
if (cur_node->type != XML_ELEMENT_NODE)
continue;

if (has_match (state, cur_node))
break;
}

xmlFreeDoc (doc);

fetch (state);
};

vfs_async_file_get_contents (match_uri (state), handle_result_cb);
update_lyrics_window_message (state, _("Looking for lyrics ..."));

return true;
}

String ChartLyricsProvider::fetch_uri (LyricsState state)
{
if (m_lyric_id <= 0 || ! m_lyric_checksum)
return String ();

auto id = int_to_str (m_lyric_id);
auto checksum = str_copy (m_lyric_checksum);
checksum = str_encode_percent (checksum, -1);

return String (str_concat ({m_base_url, "/GetLyric?lyricId=", id, "&lyricCheckSum=", checksum}));
}

void ChartLyricsProvider::fetch (LyricsState state)
{
String _fetch_uri = fetch_uri (state);
if (! _fetch_uri)
{
update_lyrics_window_notfound (state);
return;
}

auto handle_result_cb = [=] (const char * uri, const Index<char> & buf) {
if (! buf.len ())
{
update_lyrics_window_error (str_printf (_("Unable to fetch %s"), uri));
return;
}

xmlDocPtr doc = xmlReadMemory (buf.begin (), buf.len (), nullptr, nullptr, 0);
if (! doc)
{
update_lyrics_window_error (str_printf (_("Unable to parse %s"), uri));
return;
}

xmlNodePtr root = xmlDocGetRootElement (doc);

for (xmlNodePtr cur_node = root->xmlChildrenNode; cur_node; cur_node = cur_node->next)
{
if (cur_node->type == XML_ELEMENT_NODE &&
xmlStrEqual (cur_node->name, (xmlChar *) "Lyric"))
{
xmlChar * content = xmlNodeGetContent (cur_node);
m_lyrics = String ((const char *) content);
xmlFree (content);
break;
}
}

xmlFreeDoc (doc);

LyricsState new_state = g_state;
new_state.lyrics = String ();

if (! m_lyrics || ! m_lyrics[0])
{
update_lyrics_window_notfound (new_state);
return;
}

new_state.lyrics = m_lyrics;
new_state.source = LyricsState::Source::ChartLyrics;

update_lyrics_window (new_state.title, new_state.artist, new_state.lyrics);
persist_state (new_state);
};

vfs_async_file_get_contents (_fetch_uri, handle_result_cb);
update_lyrics_window_message (state, _("Looking for lyrics ..."));
}
Loading

0 comments on commit 8cb90d4

Please sign in to comment.