This commit is contained in:
Jaidyn Lev 2019-01-20 23:41:10 -06:00
commit 8a258f44e0
3 changed files with 442 additions and 0 deletions

59
README.txt Normal file
View File

@ -0,0 +1,59 @@
===============================================================================
WYRICS Git some lyrics
===============================================================================
Fetch lyrics for a song from lyrics.wikia.com with this script.
You can fetch them by search queries, or by their URL.
----------------------------------------
PRE-REQUISITES
----------------------------------------
You'll need:
* "gendl" in your $PATH
* a POSIX-compatible shell (tested with `pdksh` and `bash`)
* "curl", "wget", or "ftp" installed
* "lynx" installed
----------------------------------------
USAGE
----------------------------------------
Just run "wyrics" like so:
wyrics -s "query"
wyrics -u page_url
If you use the "-u" option, the lyrics will just be printed to stdout.
If you decide to use "-s", though, search results'll be displayed to your
screen (via stderr)-- each numbered from 1-10.
Just type a number, hit enter, and the lyrics'll pop up.
$ wyrics -s "boston"
1 Boston
2 Sonny:We're Better Than Boston
3 Boston Manor:FY1
4 Boston Manor:Halo
5 Boston Manor:Wolf
6 Boston Manor:Stick Up
7 Boston Manor:If I Can't Have It No One Can
8 Boston Manor:Square One
9 Boston Manor:Driftwood
10 Boston Manor:Forget Me Not
>>
If you want to save lyrics to a file, you'll need to redirect the
output-- "wyrics -s 'bob' > BOB.txt"
----------------------------------------
BORING STUFF
----------------------------------------
License is CC-0 (though, "gendl" is GPLv3)
Author is Jenga Phoenix <jadedctrl@teknik.io>
Sauce is at https://git.eunichx.us/wyrics

155
gendl Executable file
View File

@ -0,0 +1,155 @@
#!/bin/sh
##############################
# name: gendl
# lisc: gnu gplv3
# desc: download to stdout or
# file, independent of
# a specific downloader.
# ftp/wget/curl support.
# main: jadedctrl
##############################
# usage: gendl [-o output] url
#---------------------------------------
# backend bits
# NIL --> STRING
# return the download program you're using
function download_program
{
programs="ftp curl wget"
current=""
for program in $programs
do
if whereis $program > /dev/null
then
current=$program
fi
done
if uname -s | grep -e "LibertyBSD" -e "OpenBSD" > /dev/null
then
current="ftp"
fi
echo "$current"
}
# STRING PATH --> NIL
# download URL $1 to stdout
function download_stdout
{
program=$(download_program)
url=$1
case "$program" in
"ftp")
output="$(ftp -VMo- $url)"
;;
"curl")
output="$(curl $url)"
;;
"wget")
output="$(wget --quiet -O $url)"
;;
esac
return_code=$?
echo "$output"
return $return_code
}
# STRING PATH --> NIL
# download URL $1 to path $2
function download_file
{
program=$(download_program)
url=$1
path=$2
case "$program" in
"ftp")
ftp -VMU "." -o $path $url
;;
"curl")
curl -o $path $url
;;
"wget")
wget --quiet -O $path $url
;;
esac
return_code=$?
if test $return_code -ne 0 2>/dev/null
then
rm $path 2> /dev/null
# for consistency in behavior; wget saves 404s anyway, whereas
# ftp doesn't save anything from 404s, etc.
fi
return $return_code
}
# --------------------------------------
# front-end string-manip
# STRING --> STRING
# return the last word in a string
function last_word
{
string="$1"
echo "$string" \
| rev \
| sed 's% .*%%' \
| rev
}
function usage
{
echo "usage: gendl [-o output] URL"
}
# --------------------------------------
# invocation
args="$(getopt o: $*)"
if test -z "$@" 2>/dev/null
then
usage
exit 2
fi
set -- $args
while test $# -ne 0
do
case "$1"
in
-o)
download_path="$2"; shift; shift;;
--)
shift; break;;
esac
done
url="$(last_word "$@")"
if test -n "$download_path" 2> /dev/null
then
download_file $url $download_path
else
download_stdout "$url"
fi

228
wyrics Executable file
View File

@ -0,0 +1,228 @@
#!/bin/sh
########################################
# name: wyrics
# desc: fetch lyrics by URL or query
# from lyrics.wikia.com
# main: Jenga Phoenix
# <jadedctrl@teknik.io>
# lisc: CC 0
########################################
# --------------------------------------
# generic
# NIL --> STRING
# read from stdin until eof hit; return all input
# good for writing functions that take piped info
function reade {
local stack=""
while read input; do
stack="$(printf '%s\n%s' "$stack" "$input")"
done
echo "$stack"
}
# NUMBER STRING --> [BOOLEAN]
# have the user choose a number, up to a given max, with prompt.
function number_choose {
local max=$1
local prompt="$2"
printf "$prompt" >&2
read response
if test $response -lt $max; then
return $response
else
number_choose $max "$prompt"
fi
}
# NUMBER NUMBER --> NUMBER
# add two numbers together. pretty obvious.
function add {
local operator=$1
local operatee=$2
echo "$1 + $2" \
| bc
}
# NUMBER NUMBER --> NUMBER
# subtract two numbers. pretty obvious.
function subtract {
local operator=$1
local operatee=$2
echo "$1 - $2" \
| bc
}
# --------------------------------------
# searching
# STRING --> STRING
# return a result-list from a search query
function search {
local query="$1"
local query="$(echo "$query" | sed 's/ /+/g')"
gendl "https://lyrics.wikia.com/wiki/Special:Search?query=${query}" \
| sed '1,/Results/d' \
| grep "result-link" \
| search_parse
}
# |STRING --> STRING
# take slightly-trimmed search HTML and turn it into result-list
function search_parse {
local html="$(reade)"
local stack=""
local i=0
IFS='
'
for line in $html; do
i=$(add $i 1)
local url="$(echo "$line" \
| sed 's/.*href=\"//' \
| sed 's/\" class.*//')"
local title="$(echo "$line" \
| sed 's%.*\" >%%' \
| sed 's%</a>.*%%')"
if echo "$title" | grep "http" > /dev/null; then
i=$(subtract $i 1)
else
stack="$(printf '%s\n%s@%s@%s' \
"$stack" "$i" "$url" "$title")"
fi
done
echo "$stack" \
| head -11
}
# --------------------------------------
# result manipulation
# |STRING --> STRING
# return the title of a result
function result_title {
local result="$(reade)"
echo "$result" \
| awk -F "@" '{ print $3 }' \
| tr -d '\n'
}
# |STRING --> STRING
# return the ID of a result
function result_index {
local result="$(reade)"
echo "$result" \
| awk -F "@" '{ print $1 }' \
| tr -d '\n'
}
# |STRING --> STRING
# return the URL of a result
function result_url {
local result="$(reade)"
echo "$result" \
| awk -F "@" '{ print $2 }' \
| tr -d '\n'
}
# |STRING [STRING] --> STRING
# display all results in a result-list to stderr.
# if second argument is 'long', then URLs are printed, too.
function results_display {
local results="$(reade)"
local long="$1"
IFS='
'
for result in $results; do
local index="$(echo "$result" | result_index)"
local title="$(echo "$result" | result_title)"
local url="$(echo "$result" | result_url)"
echo "$index $title" >&2
if test "$long" = "long"; then
echo "$url" >&2
fi
done
}
# STRING --> STRING
# have the user choose a single result from the result-list
function result_choose {
local results="$1"
local max="$(echo "$results" | wc -l)"
number_choose $max ">> "
local response=$?
echo "$results" \
| grep "^$response@"
}
# --------------------------------------
# STRING --> STRING
# return the lyrics of a given URL
function lyrics {
local url="$1"
gendl "$url" \
| grep "class=\'lyricbox" \
| sed 's/.*lyricbox.>//' \
| sed 's/;<div.*//' \
| lynx -stdin -dump \
| sed 's/^ //g'
}
# --------------------------------------
# invocation
# NIL --> STRING
# print usage and abort
function usage {
echo "usage: wyrics -s query"
echo " wyrics -u url"
exit 2
}
# --------------------------------------
case "$1" in
"-u")
lyrics "$2"
;;
"-s")
results="$(search "$2")"
echo "$results" | results_display
url="$(result_choose "$results" | result_url)"
lyrics "$url"
;;
*)
usage
;;
esac