From 6f161e0bd890c7289b54ad8ccfd5b73a416ea478 Mon Sep 17 00:00:00 2001 From: Joseph Nuthalapati Date: Fri, 27 Mar 2020 09:29:00 +0530 Subject: [PATCH] Make options a dictionary and add validation Signed-off-by: Joseph Nuthalapati --- src/lib.nim | 4 +++- src/nimcoon.nim | 46 ++++++++++++++++++++++++++++++---------------- tests/tests.nim | 11 ++++++++++- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/lib.nim b/src/lib.nim index c737f02..8315473 100644 --- a/src/lib.nim +++ b/src/lib.nim @@ -8,6 +8,7 @@ import std/[terminal], strtabs, strutils, + tables, uri, xmltree @@ -15,7 +16,8 @@ import config type SearchResult* = tuple[title: string, url: string] - CommandLineOptions* = tuple[searchQuery: string, musicOnly: bool, feelingLucky: bool, fullScreen: bool] + Options* = Table[string, bool] + CommandLineOptions* = tuple[searchQuery: string, options: Options] let processOptions = {poStdErrToStdOut, poUsePath} diff --git a/src/nimcoon.nim b/src/nimcoon.nim index 8b1ba59..2143c12 100644 --- a/src/nimcoon.nim +++ b/src/nimcoon.nim @@ -1,17 +1,18 @@ import parseopt, std/[terminal], - strutils + strformat, + strutils, + tables import config import lib -proc parseOptions(): CommandLineOptions = + +proc parseArguments(): CommandLineOptions = var searchQuery = "" - musicOnly = false - feelingLucky = false - fullScreen = false + options = to_table({"musicOnly": false, "feelingLucky": false, "fullScreen": false, "download": false}) for kind, key, value in getopt(): case kind @@ -19,19 +20,32 @@ proc parseOptions(): CommandLineOptions = searchQuery = key of cmdShortOption, cmdLongOption: case key - of "m", "music": musicOnly = true - of "l", "lucky": feelingLucky = true - of "f", "full-screen": fullScreen = true - of cmdEnd: - discard + of "m", "music": options["musicOnly"] = true + of "l", "lucky": options["feelingLucky"] = true + of "f", "full-screen": options["fullScreen"] = true + of "d", "download": options["download"] = true + of cmdEnd: discard + + return (searchQuery, options) - return (searchQuery, musicOnly, feelingLucky, fullScreen) + +proc isValidOptions*(options: Options): bool = + # Check for invalid combinations of options + var invalidCombinations = [("musicOnly", "fullScreen")] + for combination in invalidCombinations: + if options[combination[0]] and options[combination[1]]: + stderr.writeLine fmt"Incompatible options provided: {combination[0]} and {combination[1]}" + return false + return true proc main() = let player = selectMediaPlayer() - (searchQuery, musicOnly, feelingLucky, fullScreen) = parseOptions() + (searchQuery, options) = parseArguments() + + if(not isValidOptions(options)): + quit(1) if searchQuery.startswith("https:") or searchQuery.startswith("magnet:"): directPlay(searchQuery, player) @@ -40,7 +54,7 @@ proc main() = let searchResults = extractTitlesAndUrls(getYoutubePage(searchQuery)) proc getUserInput(): string = - if feelingLucky: "0" + if options["feelingLucky"]: "0" else: presentVideoOptions(searchResults[..(limit-1)]) stdout.styledWrite(fgYellow, "Choose video number: ") @@ -49,8 +63,8 @@ proc main() = # This is a pure function with no side effects func buildArgs(number: int): seq[string] = var args = @[searchResults[number].url] - if musicOnly: args.add("--no-video") - if fullScreen: args.add("--fullscreen") + if options["musicOnly"]: args.add("--no-video") + if options["fullScreen"]: args.add("--fullscreen") return args while(true): @@ -66,7 +80,7 @@ proc main() = # Play the video using the preferred/available media player let videoNumber = parseInt(userInput) play(player, buildArgs(videoNumber), searchResults[videoNumber].title) - if feelingLucky: + if options["feelingLucky"]: break diff --git a/tests/tests.nim b/tests/tests.nim index a218596..dad726c 100644 --- a/tests/tests.nim +++ b/tests/tests.nim @@ -1,6 +1,9 @@ -import unittest +import + tables, + unittest import lib +import nimcoon suite "Playing direct links": @@ -8,3 +11,9 @@ suite "Playing direct links": let expected = "https://www.youtube.com/watch?v=QOEMv0S8AcA" check(sanitizeURL("https://youtu.be/QOEMv0S8AcA") == expected) check(sanitizeURL("https://www.youtube.com/watch\\?v\\=QOEMv0S8AcA") == expected) + + test "validate options": + let invalidOptions = to_table({"musicOnly": true, "feelingLucky": false, "fullScreen": true, "download": false}) + check(not isValidOptions(invalidOptions)) + let validOptions = to_table({"musicOnly": false, "feelingLucky": true, "fullScreen": true, "download": true}) + check(isValidOptions(validOptions)) -- 2.43.0