Skip to content

Instantly share code, notes, and snippets.

@benjacoblee
Created November 1, 2023 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjacoblee/a5c50cde77a0da72dbb2f24fd5a05aa2 to your computer and use it in GitHub Desktop.
Save benjacoblee/a5c50cde77a0da72dbb2f24fd5a05aa2 to your computer and use it in GitHub Desktop.
import strutils
import std/os
import system
import std/httpclient
import strformat
import std/xmltree
from htmlparser import parseHtml
import nimquery
# https://stackoverflow.com/questions/54713213/how-do-i-handle-ctrl-c-interrupt-in-nim#54723375
proc ctrlc() {.noconv.} =
quit("Exiting.", 0)
setControlCHook(ctrlc)
const baseURL = "https://www.musixmatch.com"
const helpStr = """
Error: please provide a valid text file.
Usage: $ lrix songs.txt"""
let
args = commandLineParams()
client = newHttpClient()
var f = ""
try:
let path = args[0]
f = readFile(path).strip()
except IndexDefect:
quit(helpStr, 1)
except IOError:
quit(helpStr, 1)
var songTitles: seq[string] = @[]
for l in f.splitLines():
if l.len > 0:
let l = l.split("-")
var song: seq[string] = @[]
for s in l:
let stripped = s.strip().split(" ").join("%20")
song.add(stripped)
songTitles.add(song.join("%20"))
for song in songTitles:
let searchURL = fmt"{baseURL}/search/{song}"
let html = client.getContent(searchURL)
let xml = parseHtml(html)
let elements = xml.querySelectorAll("a.title")
let songToDisplay = song.split("%20").join(" ")
echo &"Getting results for \"{songToDisplay}\"..."
echo "0. Exit"
for i, el in elements:
echo fmt"{i+1}. {el.innerText}"
let consoleInput = readLine(stdin);
try:
var idx = consoleInput.parseInt
if idx == 0:
quit(0)
idx -= 1
if idx > elements.len - 1:
quit("Error: index out of bounds", 1)
else:
let chosen = elements[idx]
let slug = attr(chosen, "href")
let songURL = fmt"{baseURL}{slug}"
echo &"Getting lyrics for: \"{chosen.innerText}\"..."
let lyricsHtml = client.getContent(songURL)
let lyricsXml = parseHtml(lyricsHtml)
let lyricsElements = lyricsXml.querySelectorAll(".lyrics__content__ok")
if lyricsElements.len > 0:
let filePath = fmt"{chosen.innerText}.txt"
try:
let f = open(filePath, fmWrite)
f.write("")
f.close()
for el in lyricsElements:
for ln in el:
let f = open(fmt"{chosen.innerText}.txt", fmAppend)
defer: f.close()
f.writeLine(ln)
echo &"Wrote lyrics to \"{filePath}\" 💾"
except IOError as e:
echo e.msg
except ParseError as e:
echo e.msg
else:
echo "Error: lyrics not available"
except ValueError:
echo "Error: not a valid value"
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment