Created
January 10, 2019 13:00
-
-
Save nicholastay/1273da34ff3cdfcbf7d4cce3aeb1e3d1 to your computer and use it in GitHub Desktop.
ALSong lyrics plugin for MusicBrainz Picard (warn: getting lyrics is synchronous, so UI will be locked)
This file contains hidden or 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
PLUGIN_NAME = 'ALSong Lyrics' | |
PLUGIN_AUTHOR = 'Nicholas Tay (nexerq)' | |
PLUGIN_DESCRIPTION = 'Gets lyric data from ALSong API.' | |
PLUGIN_VERSION = '0.1.0' | |
PLUGIN_API_VERSIONS = ['2.0'] | |
PLUGIN_LICENSE = 'Zlib' | |
# Based on musixmatch plugin as a starting point | |
from picard.metadata import register_track_metadata_processor | |
from picard.file import File | |
from picard.ui.itemviews import BaseAction, register_track_action, register_file_action | |
from picard.log import info, warning, error | |
import re | |
import urllib.request | |
from xml.sax.saxutils import escape | |
# https://github.com/sunghwan2789/osu-lyrics/blob/master/osu!Lyrics/Lyrics/Sources/AlsongSource.cs | |
ALSONG_API = 'http://lyrics.alsong.co.kr/alsongwebservice/service1.asmx' | |
TEMPLATE = u'<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope"><Body><GetResembleLyric2 xmlns="ALSongWebServer"><stQuery><strTitle>%s</strTitle><strArtistName>%s</strArtistName></stQuery></GetResembleLyric2></Body></Envelope>' | |
HEADER_DATA = { 'User-Agent': 'gSOAP', 'Content-Type': 'application/soap+xml; charset=UTF-8', 'SOAPAction': '"ALSongWebServer/GetResembleLyric2"' } | |
lyricReg = re.compile('<strLyric>(.*?)</strLyric>') | |
timingsReg = re.compile('^\\[\\d\\d:\\d\\d.\\d\\d\\]', re.MULTILINE) | |
def process_track(album, metadata, release, track): | |
get_lyrics(metadata) | |
def get_lyrics(metadata): | |
try: | |
info('Trying to get ALSong lyrics for "%s"...', metadata['title']) | |
data = TEMPLATE % (escape(metadata['title']), escape(metadata['artist'])) | |
data = data.encode('utf8') # to bytes so we can post (utf8 bytes as def in headers) | |
req = urllib.request.Request(ALSONG_API, data, HEADER_DATA) | |
with urllib.request.urlopen(req) as response: | |
info('Pulled lyric page data.') | |
page = response.read().decode('utf-8') | |
#info(page) | |
match = lyricReg.search(page) | |
if match != None: | |
lyr = match.group(1) # still need to clean up | |
lyr = lyr.replace('<br>', '\n') # html newlines | |
lyr = re.sub(timingsReg, '', lyr) # unfortunately cant do synced lyrics for now, so we remove timings :( | |
metadata['lyrics:description'] = lyr | |
info('Lyrics found and written to tag.') | |
else: | |
info('No lyrics found.') | |
except Exception as e: | |
info('EXCEPTION: %s', e) | |
pass | |
# Uncomment for automatic on lookup | |
#register_track_metadata_processor(process_track) | |
class AlsongLyricsMenu(BaseAction): | |
NAME = 'Try get lyrics from ALSong' | |
def callback(self, objs): | |
for obj in objs: | |
if isinstance(obj, File): | |
get_lyrics(obj.metadata) | |
else: | |
for file in obj.iterfiles(): | |
get_lyrics(file.metadata) | |
alm = AlsongLyricsMenu() | |
register_file_action(alm) | |
register_track_action(alm) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment