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
 | 
					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
 | 
					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
 | 
					`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
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Arch
 | 
					### Arch Linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
I maintain a package [on the
 | 
					I maintain a package [on the
 | 
				
			||||||
AUR](https://aur.archlinux.org/packages/xdg-sanity).
 | 
					AUR](https://aur.archlinux.org/packages/xdg-sanity).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### From Source
 | 
					### From Source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First, make sure you have `curl(1)` and `handlr(1)` installed. Then, clone this
 | 
					Dependencies:
 | 
				
			||||||
repository and move the `xdg-sanity/` folder into `/etc` and `xdg-sanity.sh` to
 | 
					- `curl(1)`
 | 
				
			||||||
`xdg-sanity` wherever your operating system stores locally-installed binaries.
 | 
					- `handlr(1)`
 | 
				
			||||||
This is usually `/usr/local/bin`. Make sure the installation location is in your
 | 
					- [`tomcat(1)`](https://git.tebibyte.media/emma/tomcat) (optional; enables
 | 
				
			||||||
`$PATH`.
 | 
					[extensions](#extensions))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create a `xdg-sanity.desktop` file either manually or with `gendesk(1)`,
 | 
					Instructions:
 | 
				
			||||||
placing it, also, where your OS stores locally-installed `.desktop` files,
 | 
					Clone this repository and move the `xdg-sanity` binary wherever your operating
 | 
				
			||||||
usually `/usr/local/applications`. Set your default web browser to that
 | 
					system stores locally-installed binaries. This is usually `/usr/local/bin/` or
 | 
				
			||||||
`.desktop` file.
 | 
					`"$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
 | 
					Create an `xdg-sanity.desktop` file, placing it where your OS stores
 | 
				
			||||||
script can forward links to it.
 | 
					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,
 | 
					Extensions are written using TOML and are stored in either
 | 
				
			||||||
you can call `xdg-sanity` directly with the only argument accepted being a URI.
 | 
					`/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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user