From c12cc641fe659e7e584a589bde9444904018b3b5 Mon Sep 17 00:00:00 2001 From: Joseph Nuthalapati Date: Fri, 5 Jun 2020 01:14:15 +0530 Subject: [PATCH] PeerTube: Pick magnet link of the best resolution --- README.md | 3 +++ src/lib.nim | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2968502..ddba7a1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ only the standard library. - [x] Download video - [x] Play playlists (MPV only) - [ ] Download playlists +- [x] Stream video from torrent file URLs +- [x] BitTorrent is preferred for PeerTube video links +- [ ] Search PeerTube (3.0 or later) - [ ] Autoplay next video/audio - [ ] Configuration options diff --git a/src/lib.nim b/src/lib.nim index 6153992..26df762 100644 --- a/src/lib.nim +++ b/src/lib.nim @@ -1,15 +1,17 @@ import htmlparser, httpClient, + json, os, osproc, + re, sequtils, - sugar, - strformat, std/[terminal], strformat, + strformat, strtabs, strutils, + sugar, tables, uri, xmltree @@ -25,9 +27,13 @@ type # poEchoCmd can be added to options for debugging let processOptions = {poStdErrToStdOut, poUsePath} +let PEERTUBE_REGEX = re"videos\/watch\/[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}" + +proc isInstalled(program: string): bool = + execProcess("which " & program).len != 0 proc selectMediaPlayer*(): string = - let availablePlayers = filterIt(supportedPlayers, execProcess("which " & it).len != 0) + let availablePlayers = supportedPlayers.filter(isInstalled) if len(availablePlayers) == 0: stderr.writeLine &"Please install one of the supported media players: {supportedPlayers}" raise newException(OSError, "No supported media player found") @@ -40,6 +46,16 @@ proc getYoutubePage*(searchQuery: string): string = let response = get(client, &"https://www.youtube.com/results?hl=en&search_query={queryParam}") return $response.body +proc getPeerTubeMagnetLink(url: string): string = + # Gets the magnet link of the best possible resolutino from PeerTube + let uuid = url.substr(find(url, PEERTUBE_REGEX) + "videos/watch/".len) + let domainName = url.substr(8, find(url, '/', start=8) - 1) + let apiURL = &"https://{domainName}/api/v1/videos/{uuid}" + let client = newHttpClient() + let response = get(client, apiURL) + let jsonNode = parseJson($response.body) + jsonNode["files"][0]["magnetUri"].getStr() + func extractTitlesAndUrls*(html: string): SearchResults = {.noSideEffect.}: parseHtml(html).findAll("a"). @@ -100,6 +116,10 @@ func sanitizeURL*(url: string): string = urlLongen(stripZshEscaping(url)) proc directPlay*(url: string, player: string, options: Table[string, bool]) = + let url = + if find(url, PEERTUBE_REGEX) != -1 and isInstalled("webtorrent"): + getPeerTubeMagnetLink(url) + else: url if url.startswith("magnet:") or url.endswith(".torrent"): if options["musicOnly"]: # TODO Replace with WebTorrent once it supports media player options -- 2.43.0