Implement video search
authorJoseph Nuthalapati <njoseph@riseup.net>
Sat, 5 Oct 2019 00:19:52 +0000 (05:49 +0530)
committerJoseph Nuthalapati <njoseph@riseup.net>
Sat, 5 Oct 2019 00:40:23 +0000 (06:10 +0530)
Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
README.md
cli_tube.nim [new file with mode: 0644]

index de431e355c077d732c3959250a14731b077a684a..1d1ed04a2da155a3dde8283332d46fce65d169c3 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,4 +1,36 @@
 # CLI Tube
-Play videos from YouTube from the command line.
 
-This application is currently implemented in Nim language.
+Play videos from YouTube (and maybe other sources in the future) from the
+command line using your preferred desktop media player.
+
+This application is implemented in [Nim language](https://nim-lang.org).
+
+## Features
+
+- [x] Search for videos using keywords
+- [ ] Download or watch videos
+- [ ] Configuration options
+
+## Usage
+
+### As a script
+
+You must have nim installed locally for this to work.
+
+```sh
+nim c -d:ssl -r cli_tube.nim emacs
+
+# If your search query has multiple words, use quotes
+nim c -d:ssl -r cli_tube.nim 'nim lang'
+```
+
+### Using the binary
+
+Please use the binary in the repository for now.
+Will setup GitLab CI to publish proper binaries later.
+
+```sh
+./cli_tube emacs
+
+./cli_tube 'nim lang'
+```
diff --git a/cli_tube.nim b/cli_tube.nim
new file mode 100644 (file)
index 0000000..d7a3d91
--- /dev/null
@@ -0,0 +1,44 @@
+import htmlparser
+import httpClient
+import os
+import osproc
+import strtabs
+import strutils
+import uri
+import xmltree
+import sequtils, sugar
+
+# TODO Pretty colors in terminal
+# import terminal
+
+# Supported video players in order of preference
+# TODO Should go into a config file
+let supported_players = @["mpv", "mplayer", "vlc"]
+
+proc find_supported_player(): string =
+  for player in supported_players:
+    let player_bin = execProcess("which " & player)
+    if player_bin.len != 0:
+      return strip(player_bin)
+
+proc get_youtube_page(search_query: string): string =
+  let query_param = encodeUrl(search_query)
+  var client = newHttpClient()
+  let response = get(client, "https://www.youtube.com/results?hl=en&search_query=" & query_param)
+  # TODO Get rid of temp file or make one temp file per user
+  writeFile("/tmp/cli-tube-page.html", response.body)
+  return "/tmp/cli-tube-page.html"
+
+proc extract_titles_and_urls(html_file: string): seq[tuple[title: string, url: string]] =
+  loadHtml(html_file).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"]))
+
+proc present_video_options(titles_and_urls: seq[tuple[title: string, url: string]]) =
+  for number, (title, url) in titles_and_urls:
+    echo number, ". ", title, "\n", url, "\n"
+
+present_video_options(
+  extract_titles_and_urls(
+    get_youtube_page(
+      paramStr(1))))