import
htmlparser,
httpClient,
osproc,
sequtils,
sugar,
strformat,
std/[terminal],
strtabs,
strutils,
uri,
xmltree
import config
type
SearchResult* = tuple[title: string, url: string]
CommandLineOptions* = tuple[searchQuery: string, musicOnly: bool, feelingLucky: bool, fullScreen: bool]
proc selectMediaPlayer*(): string =
let availablePlayers = filterIt(supportedPlayers, execProcess("which " & it).len != 0)
if len(availablePlayers) == 0:
stderr.writeLine &"Please install one of the supported media players: {supportedPlayers}"
raise newException(OSError, "No supported media player found")
else:
return availablePlayers[0]
proc getYoutubePage*(searchQuery: string): string =
let queryParam = encodeUrl(searchQuery)
let client = newHttpClient()
let response = get(client, &"https://www.youtube.com/results?hl=en&search_query={queryParam}")
return $response.body
func extractTitlesAndUrls*(html: string): seq[SearchResult] =
{.noSideEffect.}:
parseHtml(html).findAll("a").
filter(a => "watch" in a.attrs["href"] and a.attrs.hasKey "title").
map(a => (a.attrs["title"], "https://www.youtube.com" & a.attrs["href"]))[..(limit-1)]
proc presentVideoOptions*(searchResults: seq[SearchResult]) =
echo ""
for index, (title, url) in searchResults:
styledEcho $index, ". ", styleBright, fgMagenta, title, "\n", resetStyle, fgCyan, url, "\n"
proc play*(player: string, args: openArray[string]) =
# poEchoCmd can be added to options for debugging
discard execProcess(player, args=args, options={poStdErrToStdOut, poUsePath})
func urlLongen(url: string): string =
url.replace("youtu.be/", "www.youtube.com/watch?v=")
func stripZshEscaping(url: string): string =
url.replace("\\", "")
func sanitizeURL*(url: string): string =
urlLongen(stripZshEscaping(url))
proc directPlay*(searchQuery: string, player: string) =
let url = sanitizeURL(searchQuery)
if searchQuery.startswith("magnet:"):
play("peerflix", args=[url, &"--{player}"])
else:
play(player, args=[url])