aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleteoryx <alyx@aleteoryx.me>2024-07-29 19:17:03 +0100
committerAleteoryx <alyx@aleteoryx.me>2024-07-29 19:17:03 +0100
commit4f3556a3030ba97d3eec590cdd5d1e7046f53588 (patch)
tree58d99f1d307d2a3faa801c1e9009126bdb82157a
parente9ca1e6b14fe635fb940f5bae8560c68acca3d12 (diff)
downloadlfm_embed-master.tar.gz
lfm_embed-master.tar.bz2
lfm_embed-master.zip
Mark this page as deadHEADmaster
-rw-r--r--README.md403
1 files changed, 1 insertions, 402 deletions
diff --git a/README.md b/README.md
index 5cb7b17..b8fca66 100644
--- a/README.md
+++ b/README.md
@@ -1,402 +1 @@
-# `lfm_embed`
-A simple webserver for rendering a last.fm embed.
-
-More specifically, this displays a simple webpage with info about your current or most recent last.fm scrobble.
-Its intended use is to be put in an iframe on a personal site or whatever.
-While it is self-hostable, there is an official public instance at [scrobble.observer](https://scrobble.observer).
-
-Release builds available [here](https://aleteoryx.me/downloads2/lfm_embed).
-
-Index:
-
-- [Usage](#usage)
-- [Self-Hosting](#self-hosting)
-- [Configuration](#configuration)
-- [Theming](#theming)
-- [Contributing](#contributing)
-- [Legal](#legal)
-
-# Usage
-
-`lfm_embed` serves one thing:
-Requests to `/user/<last.fm username>` will generate a page displaying your current or last last.fm scrobble.
-The look and feel of this is down to the configured theme for your request.
-
-As the user, you may select a theme supported by the server by passing `?theme=` query string.
-Check with your host for a list of supported themes.
-
-Individual themes may also support parameters, via additional query parameters.
-
-## Builtin Themes
-
-### `plain`
-
-A minimal theme, displaying just the username, album art, and track info.
-It is the default fallback for an unset or unknown theme.
-
-![A screenshot of the plain theme, displaying album art, and the text "@vvinrg is scrobbling Sweet Tooth from Sleepyhead by Cavetown".](screenshots/plain-light.png)
-
-#### Parameters
-
-- `?dark`: toggle the theme's dark mode.
-
-# Self-Hosting
-`lfm_embed` is, as it stands, designed to use a reverse proxy.
-A future release may include HTTPS support, but currently, it will only listen on `localhost`, prohibiting it from public access.
-Once configured, a request of the form `http://localhost:9999/user/<last.fm username>` will render out an embed with the default theme.
-
-As it stands, there are no plans to support displaying users with private listen history.
-
-# Configuration
-Configuration should be done via the environment.
-`lfm_embed` also supports reading from a standard `.env` file.
-The following are the environment variables which `lfm_embed` understands.
-
-## Core Config
-
-### `LMFE_LASTFM_API_KEY` (Required)
-Your last.fm API key. You'll need to create one [here](https://www.last.fm/api/account/create) for self-hosting.
-
-### `LMFE_GOOGLE_API_KEY`
-Your google API key. This is necessary for custom google fonts to work. You can create one [here](https://developers.google.com/fonts/docs/developer_api#APIKey), and you'll need some familiarity with the Google cloud API console
-
-### `LFME_PORT` (Default: `9999`)
-The port to serve on locally.
-
-### `LFME_NO_REFRESH` (Default: `0`)
-If set to `1`, disable outputting of the HTTP `Refresh: <cache refresh>` header, used to provide live status updates.
-
-## Logging
-
-### `LFME_LOG_LEVEL` (Default: `"warn"`)
-The loglevel. This is actually parsed as an [`env_logger`](https://docs.rs/env_logger/latest/env_logger) filter string.
-Read the docs for more info.
-
-### `LFME_LOG_FILE`
-If set, logs will be written to the specified file. Otherwise, logs are written to `stderr`.
-
-## User Perms
-
-### `LFME_ALLOWLIST_MODE` (Default: `"open"`)
-The following(case-insensitive) values are supported:
-
-- `open`: Allow requests for all users.
-
-- `exclusive`: Only allow requests for users in `LFME_ALLOWLIST`, returning HTTP 403 for all others. `LFME_ALLOWLIST` _must_ be set if this mode is enabled.
-
-If the user requested has their listen history private, a 403 will be returned.
-
-### `LFME_ALLOWLIST` (Default: `""`)
-This is expected to be a sequence of comma-separated usernames.
-Leading/trailing whitespace will be stripped, and unicode is fully supported.
-
-### `LFME_ALLOWLIST_REFRESH` (Default: `"1m"`)
-The amount of time to cache allowlisted user info for.
-It is interpreted as a sequence of `<num><suffix>` values, where `num` is a positive integer,
-and `suffix` is one of `y`,`mon`,`w`,`d`,`h`,`m`,`s`, `ms`, `µs`, or `ns`, each of which
-corresponds to a self-explanatory unit of time.
-For most practical applications, one should only use `m` and `s`, as caching your current listen for more than that time has the potential to omit most songs.
-Parsing is delegated to the [`duration_str`](https://docs.rs/duration-str/latest/duration_str/) crate, and further info may be found there.
-
-### `LFME_DEFAULT_REFRESH` (Default: `"5m"`)
-The amount of time to cache non-allowlisted user info for.
-See `LFME_ALLOWLIST_REFRESH` for more info.
-
-## Themes
-
-### `LFME_THEME_DIR`
-If set, must be a valid path to a directory containing a tree of [Handlebars](https://handlebarsjs.com/guide/#language-features) and [Lua](https://www.lua.org/) files, ending in `LFME_THEME_EXT_HBS` and `LFME_THEME_EXT_LUA`, respectively.
-They will be registered as themes on top of the builtin ones, with each theme's name being their filename minus the extension.
-Same-named themes will override builtin ones.
-
-See [Theming](#theming) for details on writing custom themes.
-
-Theme names are the same as their path, minus the extension. A directory like:
-```
-themes/
- mytheme.hbs
- myothertheme.lua
- myunrelatedfile.css
- alices-themes/
- mytheme.lua
- mysuperawesometheme.hbs
-```
-results in the following themes:
-```
-mytheme
-myothertheme
-alices-themes/mytheme
-alices-themes/mysuperawesometheme
-```
-
-By default, these are loaded and compiled once, at startup.
-
-### `LFME_THEME_EXT_HBS` (Default: `.hbs`)
-The file extension for handlebars themes in `LFME_THEME_DIR`.
-
-Note: This behaves more like a suffix than a file extension. You must include the leading dot for a file extension.
-
-### `LFME_THEME_EXT_LUA` (Default: `.lua`)
-The file extension for lua themes in `LFME_THEME_DIR`.
-
-Note: This behaves more like a suffix than a file extension. You must include the leading dot for a file extension.
-
-### `LFME_THEME_DEV` (Default: `0`)
-If set to `1`, themes will be reloaded on edit.
-
-Note: Even with this mode, adding a new handlebars theme requires a full reload.
-Handlebars hemes are only enumerated once, at startup. (This is a limitation of the [`handlebars`](https://docs.rs/handlebars/latest/handlebars) implementation in use, and may change.)
-
-### `LFME_THEME_DEFAULT` (Default: `"plain"`)
-The theme to use when no query string is present.
-
-## Example Configuration
-```ini
-LFME_API_KEY=0123456789abcdef0123456789abcdef
-LFME_LOG_LEVEL=error
-LFME_PORT=3000
-
-LFME_ALLOWLIST_REFRESH=30s
-LFME_ALLOWLIST_MODE=exclusive
-LFME_ALLOWLIST=a_precious_basket_case, realRiversCuomo, Pixiesfan12345
-```
-
-# Theming
-
-Custom themes are, as stated above, [Handlebars](https://handlebarsjs.com/guide/#language-features) and [Lua](https://www.lua.org/) files.
-They are expected to produce a complete HTML doc, which should contain info about a user's scrobbles.
-
-You should have a passing familiarity with either language before reading below.
-
-## Handlebars Themes
-
-Handlebars is a simple templating language, and great for themes that don't do much complicated.
-The builtin `plain` theme is written in handlebars, and any themes that want to just relay the basic scrobble info should be written in it.
-
-If you're looking to do more complicated effects, or need server-side computation, see below on writing [Lua Themes](#lua-themes).
-Handlebars should __not__ be used if you're looking to do advanced effects.
-
-All builtin handlebars themes are located at [`/src/theming/hbs`](https://git.aleteoryx.me/cgit/lfm_embed/tree/src/theming/hbs).
-
-The following [helpers](https://handlebarsjs.com/guide/expressions.html#helpers) are provided, on top of the handlebars [builtins](https://handlebarsjs.com/guide/builtin-helpers.html):
-
-- `(eq Object Object) => Boolean`: Check equality between its args.
-
-- `(ne Object Object) => Boolean`: Check inequality between its args.
-
-- `(gt Number|String Number|String) => Boolean`: Check if the first arg is greater than the second.
-
-- `(gte Number|String Number|String) => Boolean`: Check if the first arg is greater than or equal to the second.
-
-- `(lt Number|String Number|String) => Boolean`: Check if the first arg is less than the second.
-
-- `(lte Number|String Number|String) => Boolean`: Check if the first arg is less than or equal to the second.
-
-- `(and Boolean Boolean) => Boolean`: Boolean AND gate.
-
-- `(or Boolean Boolean) => Boolean`: Boolean OR gate.
-
-- `(not Boolean) => Boolean`: Boolean NOT gate.
-
-- `(uri_encode String) => String`: URI-encode input text, making the output suitable to be included as part of a link or other URL.
-
-### Writing a Handlebars Theme
-
-Handlebars themes should have, roughly, the skeleton below:
-
-```html
-<!DOCTYPE html>
-<html lang="en"> <!-- Or really whatever you want, but I speak English. -->
- <head>
- <meta charset="UTF-8">
- <style>
- {{#if font.css}}
- {{{font.css}}}
- {{/if}}
- /* cursed hack to deal with weird rendering in chrome */
- * { font-size: {{#if font}}17px{{else}}{{#if font.scale}}calc(20px * {{font.scale}}){{else}}20px{{/if}}{{/if}}; }
- {{#if font.name }}
- * { font-family: '{{font.name}}' }
- {{/if}}
- /* actual styles */
- </style>
- </head>
- <body>
- {{#if error}}<p>{{error}}</p>{{else}}
- <!-- theme contents here -->
- {{/if}}
- </body>
-</html>
-```
-
-See below for the [Context Object](#the-context-object)
-
-## Lua Themes
-
-Lua is a powerful scripting language, for themes that need to do a lot of math on the server.
-`lfm_embed` uses the [Luau](https://luau-lang.org/) implementation, specicially.
-
-You are provided with only the `table`, `string`, `utf8`, `bit`, and `math` stdlib modules.
-You are also provided with the `html` global.
-
-- `html(el: String, tbl: Table) => String`: Generates the HTML for `<el>`, with the sequential entries in `tbl` as concatenated text, and the named entries as attributes. Sequential entries wrapped in a table will be escaped.
-
-- `html.<el>(tbl: Table) => String` Functions like `html`, but with the index name as the element type. It is intended to be called like `html.a{"Homepage", href = "/"}`.
-
-- `html.root(tbl: Table) => String` Generates the root of an HTML document, including doctype, processing `tbl` as normal.
-
-Example:
-
-```lua
-print(html.root{html.body{html.p{"Check out my cool site!"}}})
--- <!DOCTYPE html>
--- <html><body><p>Check out my cool site!</p></body></html>
-
-print(html.p{ "This <b>doesn't</b> get escaped, ", {"but this <b>does</b>!"} })
--- <p>This <b>doesn't</b> get escaped, but this &lt;b&gt;does&lt;/b&gt;!</p>
-```
-
-### Writing a Lua Theme
-
-Lua theme scripts are expected to return a function which takes one argument, the [Context Object](#the-context-object), and return a fully formed html document.
-They may contain anything as far as locals go, but are not allowed to manipulate the global context.
-The returned function will be repeatedly called for any incoming request.
-
-Lua themes should have, roughly, the skeleton below:
-
-```lua
-local stylefmt = [[
-/* font css */
-%s
-* { font-size: %spx; }
-%s
-/* actual styles go here*/
-]]
-
-return function(ctx)
- local contents
- local style
- if ctx.error then
- contents = html.p{{ctx.error}}
- style = ""
- else
- contents = ""
- if not ctx.font then ctx.font = {} end
- local font_setter = ""
- if ctx.font.name then
- font_setter = string.format("* { font-family: '%s'; }", ctx.font.name)
- end
- local font_px
- -- hack to deal with chrome being weird
- if ctx.font then font_px = 17
- elseif ctx.font.scale then font_px = 20 * ctx.font.scale
- else font_px = 20 end
- style = string.format(stylefmt, ctx.font.css or "", font_px, font_setter)
- end
- return html.root{lang = "en",
- html.head{
- html.meta{charset = "UTF-8"},
- html.style{style}
- },
- html.body{contents}
- }
-end
-```
-
-## The Context Object
-
-You will be passed one of 2 context objects, depending on if there was an error dealing with the remote backends.
-If there was an error, the object will just be `{ error: String }`, otherwise it will be the following:
-
-```js
-{
- // The user the request was made on the behalf of.
- user: {
- // Their username.
- name: String,
- // Their "Display Name".
- realname: String,
- // Link to user's profile picture.
- image_url: String,
- // Link to user's profile.
- url: String,
-
- // Total scrobbles.
- scrobble_count: Number,
- // Number of artists in library.
- artist_count: Number,
- // Number of tracks in library.
- track_count: Number,
- // Number of albums in library.
- album_count: Number,
-
- // True if user subscribes to last.fm pro.
- pro_subscriber: Boolean
- },
-
- // The user's most current, or most scrobble.
- scrobble: {
- // The name of the track.
- name: String,
- // The name of its album.
- album: String,
- // The artist who made it.
- artist: {
- // Their name.
- name: String,
- // Link to their profile image.
- image_url: String,
- // Link to the artist's last.fm page.
- url: String
- },
- // A link to the track image.
- image_url: String,
- // A link to the track's last.fm page.
- url: String,
-
- // True if the user has loved the track.
- loved: Boolean,
- // True if the user is currently scrobbling it, false if it's just
- // the most recently played track.
- now_playing: Boolean
- },
-
- // Custom font info.
- font: {
- // Set if the theme should replace the custom font with something.
- name: String?,
- // Will contain CSS which includes a custom font as 'included_font'.
- css: String?,
- // Will contain a factor of the base font scale to scale the theme's font by, for custom font reasons.
- scale: Number?
- },
-
- // A set of extraneous query parameters.
- //
- // This should be considered UNTRUSTED, as the requester has full
- // control over it. Use the provided `html_escape`,
- // `html_attr_escape`, and `uri_encode` helpers when inlining
- // any contained text.
- query: Object
-}
-```
-
-# Contributing
-
-[E-Mail me](mailto:alyx@aleteoryx.me) if you'd like to help out, submit a custom theme, or request a feature.
-
-# Legal
-```txt
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-```
+All development has been moved to [amehut](https://amehut.dev/~aleteoryx/scrobble.observer/), this repository is no longer used.