Sign inSign up

jacobshuman/readl8r

By jacobshuman

•Updated almost 2 years ago

A no-nonsense read later service

Image
Web servers
1

305

jacobshuman/readl8r repository overview

logo

⁠readl8r

A no-nonsense read later service

svelte badge tailwindcss badge docker badge

ā ā­ļø Features

  • āž• Add an article by making a POST request (with url in a JSON body) to /articles/add.
  • šŸ“‹ Get a JSON array of all articles by making a GET request to /articles.
  • šŸ—‘ļø Remove all articles by making a DELETE request to /articles/clear.
  • šŸ—„ļø All articles are stored in a /data/local.sqlite SQLite database.
  • šŸ“„ Get an RSS⁠, Atom⁠, and JSON⁠ feed of articles at /rss, /atom, and /json respectively.
home page screenshot

ā šŸš€ Getting started

⁠🚢 Docker Compose

Although you can clone/build readl8r locally, it's recommended for users to run the docker image on Docker Hub⁠. Copy the contents of this docker-compose.yml⁠ file to your computer and run:

docker compose up
⁠🌓 Environment variables
NameRequiredDescriptionDefault
AUTH_SECRETIf PASSWORD is setUsed to sign auth JWTsundefined
HOSTNoHostname or IP address where the service is hosted0.0.0.0
PORTNoThe port number used for the service80
SECURENoIndicates whether to use HTTPS (true) or HTTP (false)false
PASSWORDNoPassword required for authenticationundefined
FEED_TITLENoTitle of the feed (displayed on the web app)undefined
FEED_DESCRIPTIONNoBrief description of the feed's content and purpose (displayed on the web app)undefined
FEED_IMAGENoURL to an image that represents the feed (e.g., logo or banner)undefined
FEED_FAVICONNoURL to the favicon to be displayed in browsers for the feedundefined
FEED_COPYRIGHTNoCopyright information regarding the content of the feedundefined
AUTHOR_NAMENoName of the feed's authorundefined
AUTHOR_EMAILNoEmail address of the authorundefined
AUTHOR_LINKNoURL to the author's website or social media profileundefined
ā šŸ”’ Authentication

You can optionally protect your reading list with a password by setting the PASSWORD and AUTH_SECRET environment variables in your docker compose config.

This will protect all routes excluding feed routes (/rss, /atom, etc).

I'm still looking into how rss aggregators generally handle auth for feeds and only want to add auth when it doesn't prevent aggregators from accessing reading lists.

⁠Stucture of an article

{
	id: number;
	url: string;
	publish_date: string; // date article was published (added_date if this can't be found)
	added_date: string; // date the article was added to readl8r
	title: string | null;
	description: string | null;
	content: string | null;
	author: string | null;
	favicon: string | null;
	ttr: number | null; // estimated time to read article in seconds
}

ā āž• Add an article

šŸ”’ Requires Authentication

You can add an article by providing the article's url in the body of a POST request:

POST (http|https)://HOST:PORT/articles/add

ā šŸ‹ļø body
{
	// required
	"url": "https://dev.to/jacobshuman/wtf-is-a-github-profile-readmemd-1p8c"
}
⁠Responses
StatusStatusTextBodyContent-Type
200article added successfullyundefinedapplication/json
400url is requiredundefinedundefined
400unable to extract metadata at {url}undefinedundefined
401not authorizedundefinedundefined

ā šŸ“„ Get a single JSON article

šŸ”’ Requires Authentication

You can get a single JSON object representing an article by making a GET request to the /articles/:id route:

GET (http|https)://HOST:PORT/articles/:id

⁠Responses
StatusStatusTextBodyContent-Type
200undefinedArticleapplication/json
401not authorizedundefinedundefined
404there is no article with an id of ":id"undefinedundefined

ā šŸ“‹ Get a JSON array of all articles

šŸ”’ Requires Authentication

You can get a JSON array of articles by making a GET request to the /articles route:

GET (http|https)://HOST:PORT/articles

⁠Responses
StatusStatusTextBodyContent-Type
200undefinedArticle[]application/json
401not authorizedundefinedundefined

ā šŸ“ Update an article

šŸ”’ Requires Authentication

You can update an article based on it's id by making a PATCH request to the /articles/:id/update route:

PATCH (http|https)://HOST:PORT/articles/:id/update

ā šŸ‹ļø body
{
	"article": {
		"url": "", // optional
		"publish_date": "", // optional
		"added_date": "", // optional
		"title": "", // optional
		"description": "", // optional
		"content": "", // optional
		"author": "", // optional
		"favicon": "", // optional
		"ttr": "" // optional
	}
}
⁠Responses
StatusStatusTextBodyContent-Type
200article :id deleted successfullyundefinedundefined
401not authorizedundefinedundefined
404there is no article with id of :idundefinedundefined

ā šŸ—‘ļø Delete an article

šŸ”’ Requires Authentication

You can delete an article based on it's id by making a DELETE request to the /articles/:id/delete route:

DELETE (http|https)://HOST:PORT/articles/:id/delete

⁠Responses
StatusStatusTextBodyContent-Type
200article :id deleted successfullyundefinedundefined
401not authorizedundefinedundefined
404there is no article with id of :idundefinedundefined

ā šŸ—‘ļø Remove all articles

šŸ”’ Requires Authentication

DELETE (http|https)://HOST:PORT/articles/clear

⁠Responses
StatusStatusTextBodyContent-Type
200x articles cleared successfullyundefinedundefined
401not authorizedundefinedundefined

ā šŸ—‘ļø Purge old articles

šŸ”’ Requires Authentication

You can manually purge articles older than a certain threshhold using the /articles/purge route. Simply pass an older_than query parameter in the url with the following format:

h = hours
d = days
m = months
y = years

<integer>h|d|m|y

Examples

30d = 30 days
4m  = 4 months
2y  = 2 years

Please note the older_than parameter does not accept numbers with decimals.

DELETE (http|https)://HOST:PORT/articles/purge?older_than=<number>(h|d|m|y)

⁠Responses
StatusStatusTextBodyContent-Type
200x articles purged successfullyundefinedundefined
400invalid format, use the formula "<number><h | d | m | y>"undefinedundefined
401not authorizedundefinedundefined

ā šŸ“„ Generate RSS2 feed from articles

GET (http|https)://HOST:PORT/rss

GET (http|https)://HOST:PORT/rss.xml

GET (http|https)://HOST:PORT/feed

GET (http|https)://HOST:PORT/feed.xml

⁠Responses
StatusStatusTextBodyContent-Type
200undefinedRSS Feedapplication/rss+xml

ā šŸ“„ Generate Atom feed from articles

GET (http|https)://HOST:PORT/atom

⁠Responses
StatusStatusTextBodyContent-Type
200undefinedAtom Feedapplication/atom+xml

ā šŸ“„ Generate JSON feed from articles

GET (http|https)://HOST:PORT/json

⁠Responses
StatusStatusTextBodyContent-Type
200undefinedJSON Feedapplication/json

ā ā¤ļø Health

A simple GET route to see if the server is up and ready to handle incoming requests.

GET (http|https)://HOST:PORT/health

⁠Responses
StatusStatusTextBodyContent-Type
200OKundefinedundefined

Tag summary

Content type

Image

Digest

sha256:b093db449…

Size

107.3 MB

Last updated

almost 2 years ago

docker pull jacobshuman/readl8r