earl
Personal shortlink generator
Features
Links are …
- Editable
- Removable
- Four characters long (26 uppercase letters + 26 lowercase letters + 10 numbers = 14,776,336 possible shortened URLs)
Service has …
- A simple API
- A simple web UI
- A simple backup procedure (database is a single directory)
- No user management (this is a personal service after all)
Installation
- Download the binary appropriate for your system or build from source with
go build .List of latest binaries
- [earl-darwin-amd64](https://earl.run/earl-darwin-amd64) - [earl-darwin-arm64](https://earl.run/earl-darwin-arm64) - [earl-dragonfly-amd64](https://earl.run/earl-dragonfly-amd64) - [earl-freebsd-amd64](https://earl.run/earl-freebsd-amd64) - [earl-freebsd-arm](https://earl.run/earl-freebsd-arm) - [earl-freebsd-i386](https://earl.run/earl-freebsd-i386) - [earl-illumos-amd64](https://earl.run/earl-illumos-amd64) - [earl-linux-amd64](https://earl.run/earl-linux-amd64) - [earl-linux-arm](https://earl.run/earl-linux-arm) - [earl-linux-arm64](https://earl.run/earl-linux-arm64) - [earl-linux-i386](https://earl.run/earl-linux-i386) - [earl-linux-mips](https://earl.run/earl-linux-mips) - [earl-linux-mips64](https://earl.run/earl-linux-mips64) - [earl-linux-mips64le](https://earl.run/earl-linux-mips64le) - [earl-linux-mipsle](https://earl.run/earl-linux-mipsle) - [earl-linux-ppc64](https://earl.run/earl-linux-ppc64) - [earl-linux-ppc64le](https://earl.run/earl-linux-ppc64le) - [earl-linux-riscv64](https://earl.run/earl-linux-riscv64) - [earl-linux-s390x](https://earl.run/earl-linux-s390x) - [earl-netbsd-amd64](https://earl.run/earl-netbsd-amd64) - [earl-netbsd-arm](https://earl.run/earl-netbsd-arm) - [earl-netbsd-i386](https://earl.run/earl-netbsd-i386) - [earl-openbsd-amd64](https://earl.run/earl-openbsd-amd64) - [earl-openbsd-arm](https://earl.run/earl-openbsd-arm) - [earl-openbsd-arm64](https://earl.run/earl-openbsd-arm64) - [earl-openbsd-i386](https://earl.run/earl-openbsd-i386) - [earl-plan9-amd64](https://earl.run/earl-plan9-amd64) - [earl-plan9-arm](https://earl.run/earl-plan9-arm) - [earl-plan9-i386](https://earl.run/earl-plan9-i386) - [earl-solaris-amd64](https://earl.run/earl-solaris-amd64) - [earl-windows-amd64.exe](https://earl.run/earl-windows-amd64.exe) - [earl-windows-arm64.exe](https://earl.run/earl-windows-arm64.exe) - [earl-windows-arm.exe](https://earl.run/earl-windows-arm.exe) - [earl-windows-i386.exe](https://earl.run/earl-windows-i386.exe) - On Unix-based OSes (which includes macOS), mark the binary as executable with
chmod u+x path/to/binary- I don't think this is necessary with Windows.
- On Unix-based OSes, execute the binary with
./path/to/binary- No clue how to execute the Windows binaries. Feel free to send a patch with this information!
- Edit
./config.yamland modifyaccessTokento something secure; earl won't start until the access token is changed. - Re-execute the binary and earl should be accessible on localhost:1313!
- To make it accessible over the internet on a short domain, you'll need said
short domain, a server, a reverse proxy, and a TLS certificate. How to
obtain/configure those components is out-of-scope though.
- Contributions adding a Caddyfile, an NGINX vhost, systemd/OpenRC/runit/etc. units are welcome.
API documentation
/create
Required parameters
url: percent-encoded URL being shortened
Optional parameters
name: percent-encoded short link theurlwill be mapped to. If this is not provided, a random, 4-character code will be generated instead.
Output
401 Unauthorized: You do not have permission to create shortlinksif access token provided inAuthorizationheader does not match the configured access token400 Bad Request: URL parameter is required406 Not Acceptable: A shortened URL with this name already existsif provided name already exists in the databaseURL mapped to $NAME(200 OK)
/read
Required parameters
- None
Optional parameters
- None
Output
401 Unauthorized: You do not have permission to view shortlinksif access token provided inAuthorizationheader does not match the configured access token- JSON representation of the key/value database (200 OK)
{ "6H1g": "https://git.sr.ht/~amolith/earl/tree/dev", "N3yg": "https://secluded.site/" }
/update
Required parameters:
oldName: percent-encoded name the URL is currently referred to withname: percent-encoded name the URL will be referred to withurl: percent-encoded URL being shortened
name and url are first set as a key/value pair. If name already exists,
url is updated. If name does not already exist, it's created and oldName
is deleted. If the user is only modifying url, oldName and name should
both be submitted but their values should be identical.
Optional parameters:
- None
Output:
401 Unauthorized: You do not have permission to create shortlinksif access token provided inAuthorizationheader does not match the configured access token400 Bad Request: oldName parameter is required400 Bad Request: name parameter is required400 Bad Request: URL parameter is required406 Not Acceptable: A shortened URL with this name already existsif provided name already exists in the database$URL mapped to $NAME(200 OK)
/delete
Required parameters:
name: percent-encoded short link
Optional parameters:
- None
Output:
401 Unauthorized: You do not have permission to create shortlinksif access token provided inAuthorizationheader does not match the configured access token400 Bad Request: name parameter is required$URL has been deleted(200 OK)
But … why?
Good question. URL shorteners are (usually) terrible and useless. Except when used correctly :thinkingsmart:
I take a lot of hand-written notes on things and, having both a passion for and job in IT, my notes would be much more useful if they included links to the things I'm writing about. However, there's no way I'm going to hand-write a 50+ character URL.
That's where URL shorteners come in!
Most shortener services I've found that are both open source and self-hosted use something like 6-character-long paths for the links as they're meant for use by multiple people; 14.8m possible URLs (your cap with 4 character paths) aren't enough for public services.
Now six characters is fine but why write six characters when you could write four :D
And why deal with user management and a relational database when you're only going to have one user and a bunch of keys with values :D
I was also unsatisfied with the tech stack and feature sets of the alternatives; they were all either a pain to set up and update or they had click counters and link tracking and a bunch of other crap I have no use for.
So I decided to make my own that has exactly what I want and nothing more :D
Questions & Contributions
Questions, comments, and patches can always be sent to my public inbox, but I'm also in my IRC channel/XMPP room pretty much 24/7. However, I might not see messages right away because I'm working on something else (or sleeping) so please stick around!
If you're wanting to introduce a new feature and I don't feel like it fits with this project's goal, I encourage you to fork the repo and make whatever changes you like!
- Email: ~amolith/public-inbox@lists.sr.ht
- IRC: irc.nixnet.services/#secluded
- XMPP: secluded@muc.secluded.site
If you haven't used mailing lists before, please take a look at SourceHut's documentation, especially the etiquette section.