Total rewrite #15
77
README.md
77
README.md
@ -1,5 +1,3 @@
|
||||
# xdg-sanity
|
||||
|
||||
The `xdg-sanity` script is built to replace your default web browser in your
|
||||
desktop/XDG settings. It intercepts http/s URIs sent to the default browser by
|
||||
`xdg-open` and sends it to the appropriate application. For example, it will
|
||||
@ -7,28 +5,73 @@ send `image/jpeg` MIME type files to your image viewer.
|
||||
|
||||
## Installation
|
||||
|
||||
### Arch
|
||||
### Arch Linux
|
||||
|
||||
I maintain a package [on the
|
||||
AUR](https://aur.archlinux.org/packages/xdg-sanity).
|
||||
|
||||
### From Source
|
||||
|
||||
First, make sure you have `curl(1)` and `handlr(1)` installed. Then, clone this
|
||||
repository and move the `xdg-sanity/` folder into `/etc` and `xdg-sanity.sh` to
|
||||
`xdg-sanity` wherever your operating system stores locally-installed binaries.
|
||||
This is usually `/usr/local/bin`. Make sure the installation location is in your
|
||||
`$PATH`.
|
||||
Dependencies:
|
||||
- `curl(1)`
|
||||
- `handlr(1)`
|
||||
- [`tomcat(1)`](https://git.tebibyte.media/emma/tomcat) (optional; enables
|
||||
[extensions](#extensions))
|
||||
|
||||
Create a `xdg-sanity.desktop` file either manually or with `gendesk(1)`,
|
||||
placing it, also, where your OS stores locally-installed `.desktop` files,
|
||||
usually `/usr/local/applications`. Set your default web browser to that
|
||||
`.desktop` file.
|
||||
Instructions:
|
||||
Clone this repository and move the `xdg-sanity` binary wherever your operating
|
||||
system stores locally-installed binaries. This is usually `/usr/local/bin/` or
|
||||
`"$HOME/.local/bin/"` for your user. Make sure the installation location is in
|
||||
your `$PATH`.
|
||||
|
||||
Add your default web browser to `/etc/xdg-sanity/xdg-sanity.conf` so the
|
||||
script can forward links to it.
|
||||
Create an `xdg-sanity.desktop` file, placing it where your OS stores
|
||||
locally-installed `.desktop` files, which is usually
|
||||
`/usr/local/share/applications` or `$XDG_DATA_HOME/applications` for your user.
|
||||
Set your default web browser to that `.desktop` file using `handlr set`.
|
||||
|
||||
### Usage
|
||||
#### Extensions
|
||||
|
||||
Open links from applications outside your web browser as normal. Alternatively,
|
||||
you can call `xdg-sanity` directly with the only argument accepted being a URI.
|
||||
Extensions are written using TOML and are stored in either
|
||||
`/usr/share/xdg-sanity` when installed from a package manager,
|
||||
`/usr/local/share/xdg-sanity` when installed locally, or
|
||||
`$XDG_DATA_HOME/xdg-sanity` for your user.
|
||||
|
||||
Extension support requires the installation of the `tomcat(1)` tool, which
|
||||
parses TOML for the command line.
|
||||
|
||||
There are three kinds of extensions: MIME, replace, and scheme. MIME extensions
|
||||
are parsed first and replace the MIME type of the content being fetched. Replace
|
||||
extensions change the URI passed to the command to another. Scheme extensions
|
||||
replace the protocol by which the URI hostname is being accessed.
|
||||
|
||||
The type of the extension depends on the file name. MIME extensions should have
|
||||
a name ending in `.mime.toml`, replace extensions should have
|
||||
`.replace.toml`, and scheme extensions should end with `.scheme.toml`.
|
||||
|
||||
Here's what a MIME extension looks like:
|
||||
```
|
||||
$ cat $XDG_DATA_HOME/xdg-sanity/youtube.mime.toml
|
||||
[replace]
|
||||
urls = [ "youtube.com", "youtu.be" ]
|
||||
|
||||
[with]
|
||||
mime = "video/vnd.youtube.yt"
|
||||
```
|
||||
what a replace extension looks like:
|
||||
```
|
||||
$ cat $XDG_DATA_HOME/xdg-sanity/youtube.replace.toml
|
||||
[replace]
|
||||
urls = [ "youtube.com", "youtu.be" ]
|
||||
|
||||
[with]
|
||||
url = "https://piped.mint.lgbt/"
|
||||
```
|
||||
and what a scheme extension looks like:
|
||||
```
|
||||
$ cat $XDG_DATA_HOME/xdg-sanity/spotify.scheme.toml
|
||||
[replace]
|
||||
urls = [ "spotify.com" ]
|
||||
|
||||
[with]
|
||||
scheme = "spotify://"
|
||||
```
|
||||
|
133
xdg-sanity
Executable file
133
xdg-sanity
Executable file
@ -0,0 +1,133 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2022–2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, either version 3 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
set -e
|
||||
|
||||
argv0="$0"
|
||||
|
||||
get_urls() {
|
||||
i="0"
|
||||
until ! tomcat replace.urls["$i"] "$file" >/dev/null 2>&1
|
||||
do
|
||||
URLS="$(printf "%s\n%s" \
|
||||
"$URLS" \
|
||||
"$(tomcat replace.urls["$i"] "$file")"
|
||||
)"
|
||||
|
||||
i="$(printf "%s+1\n" "$i" | bc)"
|
||||
done
|
||||
}
|
||||
|
||||
# check if usage is valid
|
||||
if test -z "$1"; then
|
||||
printf "Usage: %s [resource...]\n" "$argv0" 1>&2
|
||||
exit 64 # sysexits(3) EX_USAGE
|
||||
fi
|
||||
|
||||
for dep in \
|
||||
curl \
|
||||
handlr
|
||||
do
|
||||
if ! command -v "$dep" >/dev/null 2>&1; then
|
||||
printf "%s: Missing dependency: %s(1)\n" "$argv0" "$dep" 1>&2
|
||||
exit 69 # sysexits(3) EX_UNAVAILABLE
|
||||
fi
|
||||
done
|
||||
|
||||
# check if we have a BROWSER
|
||||
if test -z "$BROWSER"; then
|
||||
printf "%s: \$BROWSER not filled.\n" "$argv0" 1>&2
|
||||
exit 71 # sysexits(3) EX_OSERR
|
||||
fi
|
||||
|
||||
while test -n "$1"; do
|
||||
URL="$1"
|
||||
|
||||
# use curl(1) to write out the request header's content_type, strip everything
|
||||
# after the first semicolon, chop off any weird whitespace remnants
|
||||
MIME="$(curl -Ls -o /dev/null -w '%{content_type}' "$1" | sed 's/\;.*//' \
|
||||
| xargs echo)"
|
||||
|
||||
# get the URL with no scheme
|
||||
NO_SCHEME="$(printf "%s\n" "$URL" | sed -n 's/^h.\+\/\///p')"
|
||||
|
||||
# get the pattern for the extensions to MATCH
|
||||
MATCH="$(printf "%s\n" "$NO_SCHEME" | sed 's/\/.*\+//g')"
|
||||
|
||||
# get the non-domain of the URI for tacking onto the end of replaced URIs
|
||||
URI="$(printf "%s\n" "$NO_SCHEME" | sed -n 's/^[^/]*\///p')"
|
||||
|
||||
# only check for extensions if tomcat(1) is installed
|
||||
if command -v tomcat >/dev/null 2>&1; then
|
||||
# run through MIME extensions
|
||||
for file in \
|
||||
"$XDG_DATA_HOME"/xdg-sanity/*.mime.toml \
|
||||
/usr/share/xdg-sanity/*.mime.toml \
|
||||
/usr/local/share/xdg-sanity/*.mime.toml
|
||||
do
|
||||
if test -e "$file"; then
|
||||
get_urls
|
||||
for url in $URLS; do
|
||||
if [ "$MATCH" = "$url" ]; then
|
||||
MIME="$(tomcat with.mime "$file")"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# then replace extensions
|
||||
for file in \
|
||||
"$XDG_DATA_HOME"/xdg-sanity/*.replace.toml \
|
||||
/usr/share/xdg-sanity/*.replace.toml \
|
||||
/usr/local/share/xdg-sanity/*.replace.toml
|
||||
do
|
||||
if test -e "$file"; then
|
||||
get_urls
|
||||
for url in $URLS; do
|
||||
if [ "$MATCH" = "$url" ]; then
|
||||
URL="$(tomcat with.url "$file")$URI"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# and the scheme extensions
|
||||
for file in \
|
||||
"$XDG_DATA_HOME"/xdg-sanity/*.scheme.toml \
|
||||
/usr/share/xdg-sanity/*.scheme.toml \
|
||||
/usr/local/share/xdg-sanity/*.scheme.toml
|
||||
do
|
||||
get_urls
|
||||
for url in $URLS; do
|
||||
if [ "$URL" = "$url" ]; then
|
||||
URL="$(tomcat with.scheme "$file")$MATCH"
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# these commands may fail; this is intentional
|
||||
if [ "$MIME" = "text/html" ]; then
|
||||
"$BROWSER" "$URL"
|
||||
else
|
||||
handlr launch "$MIME" -- "$URL"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
exit 0
|
@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
INPUT=$(echo $1)
|
||||
echo "Loading configuration..."
|
||||
CONFIG=$(cat /etc/xdg-sanity/xdg-sanity.conf)
|
||||
BROWSER=$(echo $CONFIG | sed -ne 's/^browser *= *//p')
|
||||
|
||||
if [ "$BROWSER" = "" ]
|
||||
then
|
||||
echo "Please place the path to your default browser's executable in /etc/xdg-sanity/xdg-sanity.conf"
|
||||
exit
|
||||
else
|
||||
echo "Found default browser $BROWSER"
|
||||
fi
|
||||
|
||||
echo "Loading extensions..."
|
||||
for EXT in /etc/xdg-sanity/extensions/*.sh
|
||||
do
|
||||
|
||||
if [ "$EXT" = "/etc/xdg-sanity/extensions/*.sh" ]
|
||||
then
|
||||
echo "No extensions to load"
|
||||
else
|
||||
|
||||
for EXT in /etc/xdg-sanity/extensions/*.sh
|
||||
do
|
||||
TYPE=$(cat $EXT | sed -ne 's/^# EXT-TYPE=//p' | tr -d '\n')
|
||||
echo "Found $TYPE extension $EXT"
|
||||
|
||||
if [ "$TYPE" = "replace" ]
|
||||
then
|
||||
echo "Modifying $INPUT..."
|
||||
INPUT=$($EXT "$INPUT")
|
||||
echo "Got $INPUT"
|
||||
|
||||
else
|
||||
if [ "$TYPE" = "mime" ]
|
||||
then
|
||||
echo "Modifying MIME type..."
|
||||
MIME=$($EXT "$INPUT")
|
||||
echo "Got $MIME"
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if [ "$MIME" = "" ] || [ "$MIME" = "$1" ] || [ "$MIME" = "$INPUT" ]
|
||||
then
|
||||
echo "Determining MIME type of $INPUT:"
|
||||
# Determines HTTP code, might use for something else?
|
||||
# CODE=$(curl -fLIs "$INPUT" | sed -ne 's/ [[:space:]]*$//p' | sed -ne 's|^HTTP/.\+ ||p')
|
||||
MIME=$(curl -fLIs "$INPUT" | sed -ne 's/^[cC]ontent-[tT]ype: //p' | sed -e 's/;.\+//p' | tail -n1 | tr -d '\r')
|
||||
echo $MIME
|
||||
fi
|
||||
|
||||
if [ "$MIME" = "text/html" ]
|
||||
then
|
||||
$BROWSER $INPUT
|
||||
|
||||
else
|
||||
handlr launch "$MIME" -- "$INPUT"
|
||||
fi
|
@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# EXT-TYPE=mime
|
||||
|
||||
TEST=$(echo $1 | sed -ne 's/^h.\+\/\///p' | sed -e 's/\/.*\+//g')
|
||||
|
||||
if [ "$TEST" = "teddit.net" ]
|
||||
then
|
||||
echo "text/html"
|
||||
else
|
||||
echo $1
|
||||
fi
|
@ -1,3 +0,0 @@
|
||||
# EXT-TYPE=replace
|
||||
|
||||
replace youtube.com or youtu.be with piped.mint.lgbt
|
@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# EXT-TYPE=replace
|
||||
|
||||
TEST=$(echo $1 | sed -ne 's/^h.\+\/\///p' | sed -e 's/\/.*\+//g')
|
||||
|
||||
if [ "$TEST" = "youtube.com" ]
|
||||
then
|
||||
echo $1 | sed -ne 's/youtube.com/piped.mint.lgbt/p'
|
||||
else
|
||||
echo $1
|
||||
fi
|
@ -1 +0,0 @@
|
||||
browser =
|
Loading…
Reference in New Issue
Block a user