README.md

  1<!--
  2SPDX-FileCopyrightText: 2022 Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# earl
  8[![REUSE status][reuse-shield]][reuse]
  9[![Donate with fosspay][fosspay-shield]][fosspay]
 10![Time spent on project][wakapi-shield]
 11
 12Personal shortlink generator
 13
 14## Features
 15Links are …
 16- Editable
 17- Removable
 18- Four characters long (26 uppercase letters + 26 lowercase letters + 10 numbers
 19  = 14,776,336 possible shortened URLs)
 20
 21Service has …
 22- A simple API
 23- A simple web UI
 24- A simple backup procedure (database is a single directory)
 25- No user management (this is a *personal* service after all)
 26
 27## API documentation
 28
 29### `/create`
 30
 31#### Required parameters
 32- `url`: percent-encoded URL being shortened
 33
 34#### Optional parameters
 35- `name`: percent-encoded short link the `url` will be mapped to. If this is not
 36  provided, a random, 4-character code will be generated instead.
 37
 38#### Output
 39- `401 Unauthorized: You do not have permission to create shortlinks` if access
 40  token provided in `Authorization` header does not match the configured access
 41  token
 42- `400 Bad Request: URL parameter is required`
 43- `406 Not Acceptable: A shortened URL with this name already exists` if
 44  provided name already exists in the database
 45- `URL mapped to $NAME` (200 OK)
 46
 47### `/read`
 48
 49#### Required parameters
 50- None
 51
 52#### Optional parameters
 53- None
 54
 55#### Output
 56- `401 Unauthorized: You do not have permission to view shortlinks` if access
 57  token provided in `Authorization` header does not match the configured access
 58  token
 59- JSON representation of the key/value database (200 OK)  
 60  ``` json
 61  {
 62    "6H1g": "https://git.sr.ht/~amolith/earl/tree/dev",
 63    "N3yg": "https://secluded.site/"
 64  }
 65  ```
 66
 67### `/update`
 68
 69#### Required parameters:
 70- `oldName`: percent-encoded name the URL is *currently* referred to with
 71- `name`: percent-encoded name the URL *will* be referred to with
 72- `url`: percent-encoded URL being shortened
 73
 74`name` and `url` are first set as a key/value pair. If `name` already exists,
 75`url` is updated. If `name` does *not* already exist, it's created and `oldName`
 76is deleted. If the user is only modifying `url`, `oldName` and `name` should
 77both be submitted but their values should be identical.
 78
 79#### Optional parameters:
 80- None
 81
 82#### Output:
 83- `401 Unauthorized: You do not have permission to create shortlinks` if access
 84  token provided in `Authorization` header does not match the configured access
 85  token
 86- `400 Bad Request: oldName parameter is required`
 87- `400 Bad Request: name parameter is required`
 88- `400 Bad Request: URL parameter is required`
 89- `406 Not Acceptable: A shortened URL with this name already exists` if
 90  provided name already exists in the database
 91- `$URL mapped to $NAME` (200 OK)
 92
 93### `/delete`
 94
 95#### Required parameters:
 96- `name`: percent-encoded short link
 97
 98#### Optional parameters:
 99- None
100
101#### Output:
102- `401 Unauthorized: You do not have permission to create shortlinks` if access
103  token provided in `Authorization` header does not match the configured access
104  token
105- `400 Bad Request: name parameter is required`
106- `$URL has been deleted` (200 OK)
107
108## But … why?
109Good question. URL shorteners are (usually) terrible and useless. Except when
110used correctly :thinkingsmart:
111
112I take a lot of hand-written notes on things and, having both a passion for and
113job in IT, my notes would be much more useful if they included links to the
114things I'm writing about. However, there's no way I'm going to hand-write a 50+
115character URL.
116
117That's where URL shorteners come in!
118
119Most shortener services I've found that are both open source and self-hosted use
120something like 6-character-long paths for the links as they're meant for use by
121multiple people; 14.8m possible URLs (your cap with 4 character paths) aren't
122enough for public services.
123
124Now six characters is *fine* but why write six characters when you could write
125four :D
126
127And why deal with user management and a relational database when you're only
128going to have one user and a bunch of keys with values :D
129
130I was also unsatisfied with the tech stack and feature sets of the alternatives;
131they were all either a pain to set up and update or they had click counters and
132link tracking and a bunch of other crap I have no use for.
133
134So I decided to make my own that has exactly what I want and nothing more :D
135
136## Questions & Contributions
137Questions, comments, and patches can always be sent to my public inbox, but I'm
138also in my IRC channel/XMPP room pretty much 24/7. However, I might not see
139messages right away because I'm working on something else (or sleeping) so
140please stick around!
141
142If you're wanting to introduce a new feature and I don't feel like it fits with
143this project's goal, I encourage you to fork the repo and make whatever changes
144you like!
145
146- Email: [~amolith/public-inbox@lists.sr.ht][email]
147- IRC: [irc.nixnet.services/#secluded][irc]
148- XMPP: [secluded@muc.secluded.site][xmpp]
149
150*If you haven't used mailing lists before, please take a look at [SourceHut's
151documentation](https://man.sr.ht/lists.sr.ht/), especially the etiquette
152section.*
153
154[reuse]: https://api.reuse.software/info/git.sr.ht/~amolith/earl
155[reuse-shield]: https://shields.io/reuse/compliance/git.sr.ht/~amolith/earl
156
157[fosspay]: https://secluded.site/donate/
158[fosspay-shield]: https://shields.io/badge/donate-fosspay-yellow
159
160[wakapi-shield]: https://img.shields.io/endpoint?url=https://waka.secluded.site/api/compat/shields/v1/amolith/interval:any/project:umu&color=blue&label=time%20spent
161
162[email]: mailto:~amolith/public-inbox@lists.sr.ht
163[irc]: irc://irc.nixnet.services/#secluded
164[xmpp]: xmpp:secluded@muc.secluded.site?join