commit 5b0189cc37f86e269a21515c8e47a8642006ea8e Author: Marty Sluijtman Date: Sat Feb 24 12:30:17 2024 +0100 Rewrite in nushell diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..726d2d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result +.direnv diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6a9aa53 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1708655239, + "narHash": "sha256-ZrP/yACUvDB+zbqYJsln4iwotbH6CTZiTkANJ0AgDv4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "cbc4211f0afffe6dfd2478a62615dd5175a13f9a", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a464a89 --- /dev/null +++ b/flake.nix @@ -0,0 +1,52 @@ +{ description = "Extremely basic flake"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = { self, nixpkgs, flake-utils}: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { inherit system; }; + in { + + packages = { + default = pkgs.stdenvNoCC.mkDerivation { + name = "arbit-nu"; + version = "2.0"; + src = ./src; + + nativeBuildInputs = with pkgs; [ + scdoc + ]; + + propagatedBuikdInputs = with pkgs; [ + pipe-viewer + yt-dlp + mpv + libnotify + xclip + ]; + + buildInputs = with pkgs; [ + nushell + ]; + + preConfigure = '' + patchShebangs ./bin/* + ''; + + buildPhase = '' + scdoc < manpages/arbit.1.scd > arbit.1 + ''; + + installPhase = '' + mkdir -p $out/{bin,share/{man/man1,zsh/site-functions}} + cp bin/arbit $out/bin/ + cp arbit.1 $out/share/man/man1/ + cp completions/_arbit $out/share/zsh/site-functions/ + ''; + + }; + }; + + }); +} diff --git a/src/bin/arbit b/src/bin/arbit new file mode 100755 index 0000000..60709d6 --- /dev/null +++ b/src/bin/arbit @@ -0,0 +1,87 @@ +#!/usr/bin/env nu +# Copyright 2024 Marty Sluijtman +# Distributed under the terms of the GPLv3 license + +let videoDir = $env.XDG_VIDEOS_DIR? | default $"($env.HOME)/Videos" +let downloadDir = $env.ARBITDIR? | default $"($videoDir)/YouTube" +let clipboardContent = xclip -o + +# Ensure the download directory exists +def init_dir [] { + if ($downloadDir | path exists) == false { + $"Creating download directory: '($downloadDir)'..." + mkdir $downloadDir + } +} + +# Generic notification wrapper +def notify [message: string] { + init_dir # annoying way to ensure the download directory exists + notify-send "Arbit" $message +} + +# Notification error function +def die [exit_code: int, error?: string] { + let message = $error. | default "Failed" + notify $"($message), exiting with exit status ($exit_code)..." + $"($message), exiting with exit status ($exit_code)..." +} + +# Documentation for mpv_clip +def play_video [url: string, message: string] { + notify $message + let mpvStatus = do { mpv --force-window $url } | complete + if $mpvStatus.exit_code != 0 { + die $mpvStatus.exit_code $mpvStatus.stdout + } +} + +# Documentation for download_video +def download_video [url: string, message: string] { + notify $message + let ytdlpStatus = do { yt-dlp --embed-chapters --embed-metadata --embed-subs -o $"($downloadDir)/%\(title\)s - %\(uploader\)s.%\(ext\)s" $url } | complete + if $ytdlpStatus.exit_code != 0 { + die $ytdlpStatus.exit_code $ytdlpStatus.stderr + } +} + +# Documentation for pipe-viewer_search +def pipe-viewer_search [query: string] { + pipe-viewer --player=mpv "$query" +} + +# Documentation for main +def main [] { + +} + +# Open the given argument with 'mpv' +def "main url" [url: string] { + play_video $url "Opening URL with mpv..." +} + +# Take the contents of the clipboard and open them using 'mpv' +def "main clipboard-url" [] { + play_video $clipboardContent "Opening clipboard content with mpv..." +} + +# Open the given argument with 'yt-dlp' +def "main download" [url: string] { + download_video $url $"Downloading video to '($downloadDir)'..." +} + +# Take the contents of the clipboard and open them using 'yt-dlp' +def "main download-url" [] { + download_video $clipboardContent $"Downloading video to '($downloadDir)'..." +} + +# Query YouTube using the given string with 'pipe-viewer' +def "main search" [query: string] { + pipe-viewer_search $query +} + +# Query YouTube using the contents of the clipboard with 'pipe-viewer' +def "main clipboard-content" [] { + notify $"Searching YouTube with:\n\n($clipboardContent)" + pipe-viewer_search $clipboardContent +} \ No newline at end of file diff --git a/src/completions/_arbit b/src/completions/_arbit new file mode 100644 index 0000000..83d727b --- /dev/null +++ b/src/completions/_arbit @@ -0,0 +1,6 @@ +#compdef arbit _arbit + +_arguments -C \ + "1: :(clipboard-url clipboard-content download-url search url download)" \ + "*::args:->args" +_arguments : $arguments diff --git a/src/manpages/arbit.1.scd b/src/manpages/arbit.1.scd new file mode 100644 index 0000000..d50f191 --- /dev/null +++ b/src/manpages/arbit.1.scd @@ -0,0 +1,48 @@ +arbit(1) + +# NAME + +arbit - A wrapper around yt-dlp, mpv and pipe-viewer to watch aribtrary videos +without a browser + +# SYNOPSIS + +*arbit* __ + +# DESCRIPTION + +A little video watch and download script made to be used in tandem with +minimalist window managers. + +# CONFIGURATION + +*arbit* saves it's output to '*~/Videos/YouTube*' by default. +This can be changed by setting the *$ARBITDIR* environment variable. + +# COMMANDS + +*clipboard-url* + Open the contents of the clipboard either in *pipe-viewer(1)* or directly in + *mpv(1)*. If a given URL contains either 'youtube' or 'youtu.be', it will be + opened in pipe-viewer. Any other URLs will be opened directly using mpv. + +*clipboard-content* + Open *pipe-viewer(1)* with the contents of the clipboard as search query. + +*download-url* + Open *yt-dlp(1)* with the contents of the clipboard to download the + resulting file. + +*search* __ + Query YouTube using *pipe-viewer(1)* + +*url* + Open a given URL either in *pipe-viewer(1)* or directly in + *mpv(1)*. + +*download* __ + Open *yt-dlp(1)* with the contents of the given URL to download the + resulting file. + +# SEE ALSO + *mpv(1)*, *pipe-viewer(1)*, *yt-dlp(1)*