dotfiles/config/nix/scripts/o
Geoffrey Frogeye 1f61ceb395
nix: Migrate scripts
They're a bit slower to start :(.
Hopefully this is something that flakes will help with,
otherwise I'll find another way.
2023-11-26 21:04:58 +01:00

85 lines
1.9 KiB
Plaintext
Executable file

#!/usr/bin/env nix-shell
#! nix-shell -i python3
#! nix-shell -p python3 python3Packages.magic xdg-utils feh zathura
# pylint: disable=C0103
"""
Find the subjectively best software
to open the file given in arguments with.
Doesn't use that XDG mess (only in last resort).
"""
import os
import subprocess
import sys
import tempfile
import urllib.request
import magic
# Getting what's needed
path = sys.argv[1]
# Getting the MIME type
ishttp = path.startswith("http")
buf = None
if ishttp:
buf = urllib.request.urlopen(path)
chunk = buf.read(1024)
fmagic = magic.detect_from_content(chunk)
else:
assert os.path.isfile(path), f"Not a file: {path}"
path = os.path.realpath(path)
fmagic = magic.detect_from_filename(path)
mime = tuple(fmagic.mime_type.split("/"))
assert len(mime) == 2
graphical = os.environ.get("DISPLAY")
# Some energumens
if mime[0] == "application" and mime[1] in ("json", "javascript"):
mime = ("text", mime[1])
# Determine stuff
ex = None # Executable needed to open the file
forcelocal = False # If we need to copy the file locally before opening it
isterm = False # Executable should run in a terminal
if mime[0] == "text":
if not ishttp:
ex = os.environ.get("VISUAL" if graphical else "EDITOR", None)
isterm = True
elif mime[0] == "image":
ex = "feh"
elif mime[0] in ("audio", "video"):
ex = "mpv"
isterm = True
elif mime == ("application", "pdf"):
ex = "zathura"
forcelocal = True
# Open stuff
tmp = None
if ex:
if forcelocal and ishttp:
assert buf
tmp = tempfile.NamedTemporaryFile(prefix="o")
tmp.write(chunk)
tmp.write(buf.read())
path = tmp.name
else:
ex = "xdg-open"
if ishttp:
ex = os.environ.get("BROWSER", ex)
if buf:
buf.close()
# TODO Launch a new terminal window for some
assert ex
p = subprocess.run([ex, path])
if tmp:
tmp.close()
sys.exit(p.returncode)