146 lines
6.8 KiB
Markdown
146 lines
6.8 KiB
Markdown
[![License: MIT](https://img.shields.io/badge/License-LGPL-blue.svg)](https://opensource.org/license/lgpl-3-0/)
|
|
[![Release](https://shields.io/badge/dynamic/json.svg?label=release&url=https://phlaym.net/git/api/v1/repos/phlaym/moshing-mammut/releases&query=$[0].tag_name)](https://phlaym.net/phlaym/moshing-mammut/releases)
|
|
|
|
# Moshing Mammut
|
|
|
|
The fine folks on the [metalhead.club Mastodon Server](https://metalhead.club) occasionally share like to share
|
|
what they're currently listening to.
|
|
Having a quick overview over what is being posted can be a great way to discover new music!
|
|
|
|
# Technical Notes
|
|
|
|
This is fairly simple from a technical point of view! metalhead.club's local timeline is being watched using the
|
|
Mastodon Streaming API over a Websocket. Every time a new post arrives, it is checked if it contains any music by
|
|
checking included hashtags and URLs. A list of tags can be found in [the configuration](.env.EXAMPLE).
|
|
Additionally, links are vetted if they are music by checking if https://song.link finds info on them.
|
|
|
|
If a post passes this check it is saved to a SQLite database.
|
|
|
|
The UI is built using [SvelteKit](https://kit.svelte.dev). The initial page is rendered on the server, and works even
|
|
without Javascript. If Javascript is enabled, new posts are fetched every 10 seconds, but there are plans to switch
|
|
to Websockets instead. See #10.
|
|
|
|
# The ~~Mastodon~~ Elephant in the Room
|
|
|
|
> So, are you just going to save other peoples posts into your own database?
|
|
|
|
I'm afraid so, and I'm not particularly happy about this. I've thought about how to do it without and it doesn't look
|
|
good.
|
|
|
|
My initial plan was to search for posts and work with the search results, however
|
|
Mastodon doesn't offer full text search, so this would be limited to work with hashtags.
|
|
I can see that there are plenty of posts using only descriptions and links without a corresponding hashtag that would
|
|
be missed. This isn't a great solution.
|
|
|
|
Another idea was to store only URLs of posts and resolve the content and account information live.
|
|
This would be better, but I'm _still_ storing post information while also slowing the app down and introduce more code
|
|
complexity. I'm willing to make this change if people prefer this though.
|
|
|
|
Additionally, I ended up adding a few things which turned out to be not needed:
|
|
The `tags` table (tags are included in the post's content and I don't do anything separately with tags) and
|
|
~~`accounts.username`~~ (s being used for #18) ~~and `accounts.avatar_static`~~ (has been removed). I will keep these in until the initial wave of feedback arrives, and
|
|
remove it if no new features required them.
|
|
|
|
I'll gladly accept any help in coming up with a good solution which doesn't need to store anything at all!
|
|
|
|
# Set Up
|
|
|
|
This might not be the ideal setup to run this, but here's how I am doing it. Instructions are for running on a Debian
|
|
or Debian derivative, using Apache as HTTP Proxy. Other setups are possible, but not covered here.
|
|
By default, NVM is used to install NodeJS, but you can install it any way you want.
|
|
|
|
This is based on [SvelteKit's instructions](https://kit.svelte.dev/docs/adapter-node#deploying) and [How To Deploy Node.js Applications Using Systemd and Nginx](https://www.digitalocean.com/community/tutorials/how-to-deploy-node-js-applications-using-systemd-and-nginx)
|
|
|
|
#### On your server
|
|
|
|
Install Apache2 if not already installed.
|
|
|
|
Copy `apache2.conf.EXAMPLE` and `moshing-mammut.service.EXAMPLE` to your server.
|
|
|
|
Set up a user for the app: `useradd -mrU moshing-mammut`
|
|
|
|
Switch to your newly created user: `su moshing-mammut`
|
|
|
|
Set up NVM:
|
|
|
|
```
|
|
$ cd
|
|
$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh
|
|
$ source ~/.nvm/nvm.sh
|
|
$ nvm install --lts
|
|
```
|
|
|
|
Create a directory for the app. This will be called `$APP_DIR` from now on. I use `/home/moshing-mammut/app`.
|
|
|
|
Enter `$APP_DIR`.
|
|
|
|
Place `package-lock.json` and `start.sh.EXAMPLE` in this directory.
|
|
Run `npm ci --omit dev` to install the dependencies.
|
|
|
|
Rename `start.sh.EXAMPLE` to `start.sh` and set the path to your NVM.
|
|
|
|
If you do not have NVM installed, simply remove the line and make sure your node executable can be found either by
|
|
specifying the full path or by adding it to your $PATH.
|
|
|
|
Exit out of your `moshing-mammut` user shell.
|
|
|
|
Copy `apache2.conf.EXAMPLE` to `/etc/apache2/sites-available/moshingmammut.conf` and replace `ServerName` with your
|
|
Domain. If you do not need or want SSL support, remove the whole `<IfModule mod_ssl.c>` block.
|
|
If you do, add the path to your SSLCertificateFile and SSLCertificateKeyFile.
|
|
|
|
Modify DocumentRoot and the two Alias and Directory statements, so that thumbnails and avatars are served directly by apache.
|
|
|
|
Copy `moshing-mammut.service.EXAMPLE` to `/etc/systemd/system/moshing-mammut.service`
|
|
and set your `User`, `Group`, `ExecStart` and `WorkingDirectory` accordingly.
|
|
|
|
#### On your development machine
|
|
|
|
Copy `.env.EXAMPLE` to `.env` and add your `YOUTUBE_API_KEY` and `ODESLI_API_KEY`.
|
|
To obtain one follow [YouTube's guide](https://developers.google.com/youtube/registering_an_application) to create an
|
|
_API key_.
|
|
If `YOUTUBE_API_KEY` is unset, no playlist will be updated. Also, _all_ YouTube links will be treated as music videos,
|
|
because the API is the only way to check if a YouTube link leads to music or something else.
|
|
|
|
If `ODESLI_API_KEY` is unset, your rate limit to the song.link API will be lower.
|
|
|
|
Add `MASTODON_ACCESS_TOKEN` as well, see [Creating our application
|
|
|
|
](https://docs.joinmastodon.org/client/token/#app) in the Mastodon documentation.
|
|
`read:statuses` is the only required scope. An access token will be displayed in your settings. Use that!
|
|
|
|
There are currently no plans to implement an actual authentication flow.
|
|
|
|
Run `npm run build` and copy the output folder, usually `build` to `$APP_DIR` on your server.
|
|
|
|
#### On your server again
|
|
|
|
Now, you are ready to start everything up.
|
|
|
|
Enable the site in Apache2 by running `a2ensite moshingmammut.conf`.
|
|
|
|
Create and start the system service by running `sudo systemctl enable moshing-mammut.service`
|
|
and then `service moshing-mammut start`.
|
|
|
|
Verify that everything is okay with `service moshing-mammut status`.
|
|
|
|
The app should now be reachable on http://localhost:3000 or whatever you configured your domain to be!
|
|
|
|
# Icons
|
|
|
|
Favicon is a combination of [speaker-line by remix icon](https://remixicon.com/icon/speaker-line)
|
|
and [the official Mastodon icon](https://joinmastodon.org/en/branding).
|
|
|
|
It has been mushed together by me, saved as SVG file in [icon.svg](./icon.svg)
|
|
and turned into a slew of icons by [https://realfavicongenerator.net/](https://realfavicongenerator.net/):
|
|
|
|
```sh
|
|
npm install -g cli-real-favicon
|
|
real-favicon generate faviconDescription.json faviconData.json static
|
|
```
|
|
|
|
Other icons:
|
|
|
|
- [error-warning-fill by remix icon](https://remixicon.com/icon/error-warning-fill)
|
|
- [git-branch-fill by remix icon](https://remixicon.com/icon/git-branch-fill)
|
|
- [rss-fill by remix icon](https://remixicon.com/icon/rss-line)
|