]>
Commit | Line | Data |
---|---|---|
44978125 JN |
1 | import htmlparser |
2 | import httpClient | |
3 | import os | |
4 | import osproc | |
2f3c8875 | 5 | import sequtils, sugar |
3d5bf3fd | 6 | import std/[terminal] |
44978125 JN |
7 | import strtabs |
8 | import strutils | |
9 | import uri | |
10 | import xmltree | |
44978125 | 11 | |
44978125 | 12 | # Supported video players in order of preference |
28a19d65 | 13 | let supportedPlayers = @["mpv", "vlc"] |
44978125 | 14 | |
c760b5d9 JN |
15 | # Only show these many results |
16 | let limit = 10 | |
17 | ||
2f3c8875 JN |
18 | type SearchResult = tuple[title: string, url: string] |
19 | ||
933e339b JN |
20 | proc selectMediaPlayer(): string = |
21 | let availablePlayers = filterIt(supportedPlayers, execProcess("which " & it).len != 0) | |
22 | if len(availablePlayers) == 0: | |
833bfdd4 | 23 | stderr.writeLine "Please install one of the supported media players: ", $supportedPlayers |
933e339b JN |
24 | raise newException(OSError, "No supported media player found") |
25 | else: | |
26 | return availablePlayers[0] | |
44978125 | 27 | |
39a495a9 JN |
28 | proc getYoutubePage(searchQuery: string): string = |
29 | let queryParam = encodeUrl(searchQuery) | |
44978125 | 30 | var client = newHttpClient() |
39a495a9 | 31 | let response = get(client, "https://www.youtube.com/results?hl=en&search_query=" & queryParam) |
3d5bf3fd JN |
32 | writeFile("/tmp/clitube-page.html", response.body) |
33 | return "/tmp/clitube-page.html" | |
44978125 | 34 | |
2f3c8875 | 35 | proc extractTitlesAndUrls(htmlFile: string): seq[SearchResult] = |
39a495a9 | 36 | loadHtml(htmlFile).findAll("a"). |
44978125 | 37 | filter(a => "watch" in a.attrs["href"] and a.attrs.hasKey "title"). |
c760b5d9 | 38 | map(a => (a.attrs["title"], "https://www.youtube.com" & a.attrs["href"]))[..(limit-1)] |
44978125 | 39 | |
2f3c8875 | 40 | proc presentVideoOptions(searchResults: seq[SearchResult]) = |
efcc0441 | 41 | echo "" |
2f3c8875 | 42 | for index, (title, url) in searchResults: |
3d5bf3fd | 43 | styledEcho $index, ". ", styleBright, fgMagenta, title, "\n", resetStyle, fgCyan, url, "\n" |
44978125 | 44 | |
84d84780 JN |
45 | let input = paramStr(1) |
46 | let player = selectMediaPlayer() | |
47 | ||
48 | if "https://www.youtube.com" in input: | |
49 | discard execProcess(player & " " & input) | |
50 | quit(0) | |
51 | ||
52 | let searchResults = extractTitlesAndUrls(getYoutubePage(input)) | |
efcc0441 JN |
53 | |
54 | presentVideoOptions(searchResults) | |
55 | ||
3d5bf3fd | 56 | stdout.styledWrite(fgYellow, "Choose video number: ") |
efcc0441 JN |
57 | var number: int = parseInt(readLine(stdin)) |
58 | ||
3d5bf3fd | 59 | styledEcho "\n", fgGreen, "Playing ", styleBright, fgMagenta, searchResults[number].title |
efcc0441 | 60 | |
3d5bf3fd | 61 | # Play the video using the preferred/available media player |
efcc0441 | 62 | discard execProcess(player & " " & searchResults[number].url) |