~hristoast/mousikofidi

82149c66d0f71dce5265658e9b7d7fde8793a5e9 — Hristos N. Triantafillou 3 months ago 0367355 wiki
Point to the new documentation website
7 files changed, 6 insertions(+), 1139 deletions(-)

D .build.yml
M api.md
M config.md
M devel.md
M index.md
M setup.md
M user_guide.md
D .build.yml => .build.yml +0 -33
@@ 1,33 0,0 @@
image: debian/stable
environment:
  soupault_sha: 4f833c5b45948c5013d75e08add73f8568a50d182ac9f05206e9adec113075cd
  soupault_version: 2.0.0-beta1
packages:
  - cmark
  - rsync
  - wget
secrets:
  - 070153b0-ef25-44ac-8a80-9864079c1eb0
  - 80fe50f8-0cc9-47ab-88e6-43796572caaf
  - b01ad0c2-e714-45b0-a7ee-da26dc17d127
sources:
  - https://git.sr.ht/~hristoast/mousikofidi
tasks:
  - change-branches: |
      cd mousikofidi
      git fetch
      git checkout mousikofidi.info
      git clean -df
  - get-soupault: |
      wget https://files.baturin.org/software/soupault/$soupault_version/soupault-$soupault_version-linux-x86_64.tar.gz
      echo "$soupault_sha  soupault-$soupault_version-linux-x86_64.tar.gz" | sha256sum -c -
  - install-soupault: |
      tar xvf soupault-$soupault_version-linux-x86_64.tar.gz
      sudo mv -v ./soupault-$soupault_version-linux-x86_64/soupault /usr/bin/
  - build: |
      ./mousikofidi/build.sh
  - deploy: |
      cat > ~/.ssh/known_hosts <<EOF
      $(cat ~/.fidi_known_hosts)
      EOF
      rsync --delete -aq -e "ssh -F $HOME/.fidi_demo_ssh_config" ./mousikofidi/build/ demo:~/html/

M api.md => api.md +1 -99
@@ 1,99 1,1 @@
The MousikóFídi API is a work-in-progress. Eventually, all functionality will be exposed via the API.

Examples shown using [HTTPie](https://httpie.org/).

## `/api/v1/metadata/:filepath`

Return metadata for the given track.

```
https --body "demo.mousikofidi.info/api/v1/metadata/srv/music/JaB/JaB - Web City Vol 2- Tha 7th Healer/02 - 7th%20Healer.mp3"
{
    "album": "Web City Vol. 2- Tha 7th Healer",
    "artist": "Ja.B.",
    "comment": "DatPiff.com",
    "date": null,
    "encoded_by": null,
    "genre": "Hip-Hop",
    "length": "3:35",
    "lyrics": "DatPiff",
    "title": "7th Healer",
    "title_mobile": "7th Healer",
    "track": "02",
    "tracktotal": "05"
}
```

## `/api/v1/playlist/:name`

Return the contents of the given playlist.

```
https --body "demo.mousikofidi.info/api/v1/playlist/From freemusicarchive.org"
{
    "audio": [
        "srv/music/from_freemusicarchive.org/Black_Ant_-_01_-_Fater_Lee.mp3",
        "srv/music/from_freemusicarchive.org/BoxCat_Games_-_10_-_Epic_Song.mp3",
        "srv/music/from_freemusicarchive.org/Checkie_Brown_-_09_-_Mary_Roose_CB_36.mp3",
        "srv/music/from_freemusicarchive.org/Derek_Clegg_-_12_-_Annalise.mp3",
        "srv/music/from_freemusicarchive.org/Jahzzar_-_01_-_The_last_ones.mp3",
        "srv/music/from_freemusicarchive.org/Jason_Shaw_-_RUNNING_WATERS.mp3",
        "srv/music/from_freemusicarchive.org/Kai_Engel_-_04_-_Moonlight_Reprise.mp3",
        "srv/music/from_freemusicarchive.org/Latch_Swing_-_01_-_Hungaria.mp3",
        "srv/music/from_freemusicarchive.org/Lobo_Loco_-_01_-_Brain_ID_1270.mp3",
        "srv/music/from_freemusicarchive.org/Podington_Bear_-_Starling.mp3",
        "srv/music/from_freemusicarchive.org/Punk_Rock_Opera_-_14_-_1945.mp3",
        "srv/music/from_freemusicarchive.org/Quantum_Jazz_-_02_-_If_I_Cant_Dance_Its_Not_My_Revolution.mp3",
        "srv/music/from_freemusicarchive.org/Revolution_Void_-_07_-_How_Exciting.mp3",
        "srv/music/from_freemusicarchive.org/Stephan_Siebert_-_07_-_when.mp3",
        "srv/music/from_freemusicarchive.org/The_Ghost_in_Your_Piano_-_02_-_Flux.mp3",
        "srv/music/from_freemusicarchive.org/The_Kyoto_Connection_-_09_-_Hachiko_The_Faithtful_Dog.mp3",
        "srv/music/from_freemusicarchive.org/Urbano_A_Zafra_-_01_-_Danza_Filipina.mp3"
    ],
    "error": null,
    "video": []
}
```

## `/api/v1/playlists`

Return all playlists.

```
https --body demo.mousikofidi.info/api/v1/playlists
[
    {
        "count": 17,
        "filename": "From freemusicarchive.org.m3u",
        "name": "From freemusicarchive.org"
    },
    {
        "count": 12,
        "filename": "JaB Mixtapes.m3u",
        "name": "JaB Mixtapes"
    },
    {
        "count": 74,
        "filename": "OC Remix: FF6 Balance And Ruin.m3u",
        "name": "OC Remix: FF6 Balance And Ruin"
    },
    {
        "count": 45,
        "filename": "OC Remix: FF7 Voices Of The Lifestream.m3u",
        "name": "OC Remix: FF7 Voices Of The Lifestream"
    },
    {
        "count": 4,
        "filename": "Public Domain Videos from utoob.m3u",
        "name": "Public Domain Videos from utoob"
    }
]
```

## `/api/v1/queue/:cmd`

For saving the current queue as a file. The only command available is `save`.

```
https name="My Cool Playlist" demo.mousikofidi.info/api/v1/playlists/save
```
This page has moved: https://mousikofidi.info/api/

M config.md => config.md +1 -125
@@ 1,125 1,1 @@
Each configuration file option for MousikóFídi is explained below:

## `cover_art`

* `cover_art`: Boolean.  Enable or disable support for showing cover art. Default: `true`

        # Enable cover art
        cover_art: true

		# Any value other than 'true' will disable cover art:
        cover_art: ohHello

## `favicon_path`

* `favicon_path`: String.  Path or URL for a favicon.

        # Just use the default
        favicon_path: /fidi.png

        # Some other URL
        favicon_path: https://myfavicondomain.tld/some-image.png

## `holidays`

* `holidays`: Boolean.  Enable or disable the usage of specially-themed logos in the user interface. Default: `true`

        # Enable holidays
        holidays: true

		# Any value other than 'true' will disable holidays:
        holidays: blazin

## `icons`

* `icons`: Boolean.  Enable or disable the usage of icons in the user interface.

        # Enable icons
        icons: true

		# Any value other than 'true' will disable icons:
        icons: enchilada

## `logo_path`

* `logo_path`: String.  Path or URL for a logo image.

        # Just use the default
        logo_path: /fidi.png

        # Some other URL
        logo_path: https://mylogodomain.tld/logo.png

## `music_dirs`

* `music_dirs`: Array of strings.  Each string should be a full path to a music directory.  Ensure the `fidi` user can read these paths.

        music_dirs:
          - /home/hristos/music/flac
          - /home/hristos/music/mp3
          - /home/hristos/music/ogg
          - /home/hristos/video/mp4
          - /home/hristos/video/webm

## `playlist.allow_delete`

* `playlist.allow_delete`: Boolean.  Enable or disable deletion of playlist files.  Default: `false`

        # Enable deletion of playlist files
        playlist:
          allow_delete: true

## `playlist.dir`

* `playlist.dir`: String.  A full path to a playlist directory.

        playlist:
          dir: /home/hristos/music/playlists

## `playlist.save`

* `playlist.save`: Boolean.  Can playlists be saved or not.  Omitting this value from your config file disables it.  Default: `true`

		# Allow saving:
        playlist:
          save: true

		# Any value other than 'true' will disable saving:
        playlist:
          save: taco

## `secret_key`

* `secret_key`: String.  This should be a long, secure string to be used for generating secure cookies (used by the "Queue" feature).
    * One can be generated with this command: `python3 -c 'import os;print(os.urandom(24))'`

            secret_key: b'\xb7(\xa0\x9f>\x7f6\xc8\x9b\x1d\xfe\xcd\x0c\x0c\x06b\xaer\xa6\x11J\xa3\xa8g'

## `site_name`

* `site_name`: String.  The "site name" as shown in the header and elsewhere.

        # Just use the default
        site_name: MousikóFídi - Your Music Cloud

        # Use a custom name
        site_name: My Cool Fidi Instance!

## `theme`

* `theme`: String.  Choose from [`dark`](https://watercss.netlify.com/), [`light`](https://watercss.netlify.com/), [`nes`](https://nostalgic-css.github.io/NES.css/), `terminal`, `terminal-green`, `terminal-solarized` , or supply your own stylesheet URL to provide a custom theme.  This sets the default theme.  Terminal themes by ogenfald.

        # Default to the dark theme...
        theme: dark

        # The light theme...
        theme: light

        # The the "NES" theme...
        theme: nes

        # The the "Terminal" theme...
        theme: terminal

        # Or, supply your own stylesheet:
        theme: https://mycssdomain.tld/my-style.css
This page has moved: https://mousikofidi.info/config/

M devel.md => devel.md +1 -121
@@ 1,121 1,1 @@
The MousikóFídi developer's guide!

## Contributing

All development should be done on the `dev` branch.  To contribute a patch to MousikóFídi:

1. Fork the main repository, check out the `dev` branch.
1. Create a branch named loosely after the work being done (e.g. `my-cool-feature`, but don't get too crazy)
1. Make changes, run tests (see below for more information about creating and running tests)
    * Wiki content lives on [the `wiki` branch](https://git.sr.ht/~hristoast/mousikofidi/tree/wiki).
1. Write tests as needed, run tests
1. Commit your changes
1. [Send in your patch!](https://git.sr.ht/~hristoast/mousikofidi/send-email)

Subscribe and post to the MousikóFídi mailing list [here](https://lists.sr.ht/~hristoast/mousikofidi), and you can hop onto the IRC channel from any instance's [`/about` page](https://demo.mousikofidi.info/about) or by directly joining `#mousikofidi` on `irc.freenode.net`.

## Setup

To get set up for development, first install the required dependencies:

    cd /path/to/mousikofidi
    # Optionally use the --user flag if desired
    pip3 install -r requirements.txt
    pip3 install -r dev-requirements.txt

The main test targets all require a [`yuicompressor`](https://yui.github.io/yuicompressor/) executable to be available on your system.

Run the tests once just to be sure you're in a good spot:

    cd /path/to/mousikofidi
    make tests  # tests-quiet or tests-verbose are also available

Then hack away!  You can run the dev server like this:

    make dev-server

This is of course useful when working on the codebase.

## pre-commit hook

The [`pre-commit.sh`](https://git.sr.ht/~hristoast/mousikofidi/tree/3d9e1a3f0c32c7f731b00330e0a8b8c4ce696250/pre-commit.sh) script within this repo is meant to function as a pre-commit hook.

It can be installed via `make githooks`, but this also happens automatically when `make dev-requirements` and `make test` (and variants) are ran.

Installation can also be done by manually invoking the script:

    /path/to/pre-commit.sh --install

Having this hook installed ensures that commits will not break tests and is essential for working with the MousikóFídi codebase.

## Creating A New CSS Theme

Adding a new CSS theme to MousikóFídi is a relatively simple process:

1. Create the `.css` file that will represent your theme's styling in the [`mousikofidi/static/css`](https://git.sr.ht/~hristoast/mousikofidi/tree/fbad2dc56d3cb3a10209865fda2a8135ff9f0d19/mousikofidi/static/css) directory of the MousikóFídi code repository.  Give it a distinct name that represents the theme well.
1. Add your new theme to the minify Makefile targets; simply copy and paste the existing lines there and edit the name of your theme file in (each line has two mentions, the regular file and the `.min` version).  Do this for both the `minify` and `minify-quiet` targets.
1. Add the path to your theme to [the minification test script](https://git.sr.ht/~hristoast/mousikofidi/tree/fbad2dc56d3cb3a10209865fda2a8135ff9f0d19/test_stuff_is_minified.sh#L19).  Simply append your theme's file to the existing list of files.
1. Finally, add your theme to the `THEMES` dict [in the main MousikóFídi python file](https://git.sr.ht/~hristoast/mousikofidi/tree/fbad2dc56d3cb3a10209865fda2a8135ff9f0d19/mousikofidi/mousikofidi.py#L43).  Follow the format of the existing themes; give your theme's name and the path to the file minus the extension.

## Creating A New Holiday Logo

To add a new date-based "holiday" logo to MousikóFídi:

1. Create the logo file and place it into the [`mousikofidi/static`](https://git.sr.ht/~hristoast/mousikofidi/tree/d4ec0804c26a164123c17278d961796acc9abdad/mousikofidi/static) directory of the MousikóFídi code repository.  Give it a distinct name that represents the holiday or idea behind it well.  Whatever you want, really.
1. Add the logo to the `LOGOS` dict [in the main MousikóFídi python file](https://git.sr.ht/~hristoast/mousikofidi/tree/d4ec0804c26a164123c17278d961796acc9abdad/mousikofidi/mousikofidi.py#L44).
    * The format is: `"date conditional": "file-name.png"`
    * The `date_conditional` can me a specific `month-day` string, such as `05-01`
    * Or, it can be a specific day or month: `day:01`, `month:05`
    * A full example: `"05-01": "file-name.png"`

## Tests

Tests should accompany any new features or fixes as needed.

Please always run tests before making a commit.

### Style

Python code should be formatted with [Python Black](https://black.readthedocs.io/en/stable/).  This is checked as part of the test process when any one of `make test`, `make test-quiet`, or `make test-verbose` are ran.

Also available are the `make test-black`, `make test-black-quiet`, and `make test-black-verbose` targets.

### Minified Statics

Minified versions of MousikóFídi CSS and Javascript are shipped with the codebase.  These can be generated via the `make minify` target, which should be done before making any commits with changes to CSS or Javascript.

This is checked as part of the main test targets, but a working installation of [`yuicompressor`](https://yui.github.io/yuicompressor/) is required.

### Flake 8

Also ran with tests are [`flake8`](http://flake8.pycqa.org/en/latest/) checks.  The `flake8` package is installed as part of the dev setup process above.

Before tests can pass, a `~/.config/flake8` file must exist on your system and it must include [the below lines at minimum](https://git.sr.ht/~hristoast/mousikofidi/tree/7b1d2b8eb0e3cf359e9f35c4659f1d210dac6376/.builds/debian.yml#L23):

    [flake8]
    ignore = E501, E402, W503
    max-line-length = 160

### Pytest

All tests for the Python code in MousikóFídi are driven by [`pytest`](https://pytest.org/en/latest/).  The `pytest` package is installed as part of the dev setup process above.

All tests against Python and HTML code are done here.

### Javascript

The MousikóFídi project aims to only use vanilla Javascript.

Additionally, any Javascript code should have tests.  All Javascript tests are executed on the [`test_js.html`](https://git.sr.ht/~hristoast/mousikofidi/tree/dev/templates/test_js.html) template, which is viewable at [the `/test-js` route](https://demo.mousikofidi.info/test-js) on any instance (note, the tests only work if the [`example` dir](https://git.sr.ht/~hristoast/mousikofidi/tree/7b1d2b8eb0e3cf359e9f35c4659f1d210dac6376/example) is found.)

As of right now, there's no automated process for running these tests, so be sure to check whem when working with the Javascript portion of the codebase.

## Publishing A Release

A release artifact is published to PyPI via a sourcehut build when a git tag is pushed.  This is handled by the [`pypi-upload.sh`](https://git.sr.ht/~hristoast/mousikofidi/tree/dev/pypi-upload.sh) script included in the base of the MousikóFídi code repo.

## Home Page

The "Home Page", or [https://mousikofidi.info/](https://mousikofidi.info/), exists on the [`mousikofidi.info` branch](https://git.sr.ht/~hristoast/mousikofidi/tree/mousikofidi.info) and is automatically updated any time that or [the `wiki` branch](https://git.sr.ht/~hristoast/mousikofidi/tree/wiki) are updated.

It's built with [soupault](https://soupault.neocities.org/) and generates several pages [from the wiki](https://git.sr.ht/~hristoast/mousikofidi/tree/bbb8fcc783f83efa6c3bf4c35f7353a085f4fb5c/build.sh#L12).
This page has moved: https://mousikofidi.info/devel/

M index.md => index.md +1 -9
@@ 1,9 1,1 @@
Welcome to the MousikóFídi wiki!  Please select an article below.

* [Setup And Running](setup.md)

* [User's Guide](user_guide.md)

* [Configuration](config.md)

* [Development](devel.md)
This page has moved: https://mousikofidi.info/

M setup.md => setup.md +1 -433
@@ 1,433 1,1 @@
The complete MousikóFídi setup guide!

## Prerequisites

Before running your own MousikóFídi instance, certain requirements must be satisfied:

* MousikóFídi has only been tested on GNU/Linux; other OSes should work but are not yet officially supported.
* A modern version of Python 3 should be installed - though anything above or equal to the latest release of Python 3.5 should work fine.  Pip is also needed to install MousikóFídi itself, as well as its dependencies.
  * A `python3-devel` package, or the equivalent for your OS, needs to be present to install [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/).
* A webserver that supports reverse proxying is needed - this guide recommends and describes how to use [Nginx](https://nginx.org/) for this purpose.
* Last but not least, you will need some audio and or video files for MousikóFídi to serve up!

## Quickstart

If you just want to run MousikóFídi locally to check it out:

    # Add .local/bin to PATH and source if needed
    echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
    source ~/.profile

    # User install
    pip3 install --user MousikoFidi

	mousikofidi --dev

Now, open `http://127.0.0.1:5000/` in a browser to use MousikóFídi.  You may also want to [configure some media sources](#configuring-mousik--f--di).

## Server Quickstart

This section is a high-level look at what you need to do to run MousikóFídi on a server.

Open a terminal and follow the commands shown below:

	# First, ensure that the "python3-dev" and "python3-pip"
    # packages for your OS are installed and usable.
    # ... whatever the method is.
    sudo apt install python3-dev python3-pip
    sudo dnf install python3-devel python3-pip
    sudo pacman -S python3
    sudo xbps-install -Su python3-devel python3-pip

	# Create a new user to run MousikóFídi as
    sudo useradd --create-home --home-dir /opt/fidi fidi

	# Become that user
    sudo su - fidi

    # Add .local/bin to PATH
    echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
    source ~/.profile

    # Install MousikóFídi
    pip3 install --user MousikoFidi

    # Fix permissions
    chmod 0755 ~/.local
    chmod 0755 ~/.local/lib
    chmod 0755 ~/.local/lib/python3.*
    chmod 0755 ~/.local/lib/python3.*/site-packages

    # Run MousikóFídi via the dev server, make sure ~/.local/bin is in $PATH
    mousikofidi --dev

    # Adjust the config file as needed
    vi ~/.config/fidi/config.yml

At this point, you are ready to go on to setting up [uWSGI](#configuring-uwsgi) and [Nginx](#configuring-nginx).

Continue to the next section for a more detailed breakdown of what is shown above.

## Installation

Although it is not strictly required, this guide covers running MousikóFídi as its own unprivileged user.

### Creating the fidi user

MousikóFídi should be run as its own unprivileged user, though keep in mind that it will need read access to wherever your collections are.

    sudo useradd --create-home --home-dir /opt/fidi fidi

The home directory is specified as `/opt/fidi` to avoid any potential permissions and security problems.

From here, become the new user and verify it is usable:

    sudo su - fidi
    ls -lah

### Ensure `$PATH`

Before installing MousikóFídi we have to make sure that the install location is in the `fidi` user's `$PATH`. If you run this:

    sudo su - fidi
    echo $PATH

And don't see `/opt/fidi/.local/bin` in there, then do this:

    sudo su - fidi
    echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
    source ~/.profile

Now you should be able to successfully run `mousikofidi --dev` after installing (see below).

### Installing MousikóFídi

    sudo su - fidi
    pip3 install --user MousikoFidi

Note that the `--user` flag is used, which installs all packages under `fidi`'s home directory, eliminating the need for any superuser access.

Doing this puts all executables under `/opt/fidi/.local/bin`, so that path must be used or added to the `$PATH` variable as noted above.

Additionally, it will put static files under a local python library path.  Determine where this is like so:

    sudo su - fidi
    ls -d ~/.local/lib/python3.*/site-packages/mousikofidi/static

MousikóFídi should now be installed but not yet usable; a configuration file needs to be installed next.

### Fixing Permissions

There's a good chance that installing MousikóFídi with `pip` will create directories with very restrictive permissions.  Run these commands to allow the web server user to read them:

    sudo su - fidi
    chmod 0755 ~/.local
    chmod 0755 ~/.local/lib
    chmod 0755 ~/.local/lib/python3.*
    chmod 0755 ~/.local/lib/python3.*/site-packages

### Configuring MousikóFídi

Run MousikóFídi like this:

    sudo su - fidi
    mousikofidi --dev

The first time you run MousikóFídi, a config file will be generated at `$HOME/.config/fidi/config.yml`.  You can view the contents of this file [in the MousikóFídi source code](https://git.sr.ht/~hristoast/mousikofidi/tree/29ab6340d79bcf618032f6d35d7b85a8a7e3e11d/mousikofidi/mousikofidi.py#L45-58).

Open this file with a text editor to alter any values as desired:

    sudo su - fidi
    vi ~/.config/fidi/config.yml

See [the Config Guide](https://mousikofidi.info/config/#music-dirs) as well as [the User's Guide](https://mousikofidi.info/user_guide/#adding-your-collection) for more information.

If running on your local machine, at this point you may open `http://127.0.0.1:5000/` in a browser to use MousikóFídi.

Read on for information about how to run MousikóFídi in production mode.

## Configuring uWSGI

Using [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/) takes a bit more work, but it is much more performant and the recommended way to run MousikóFídi.

MousikóFídi comes with [an example `uwsgi.ini` file](https://git.sr.ht/~hristoast/mousikofidi/tree/ece94e3b8bb1aa6df0f4a3e6006f5c3b963cb0c3/example/uwsgi.ini) that can be used as a base:

	sudo su - fidi
    curl -o ~/.config/fidi/uwsgi.ini https://git.sr.ht/~hristoast/mousikofidi/blob/master/example/uwsgi.ini

Now the `pidfile` and `socket` values should be changed to use `/opt/fidi/tmp` instead of `/tmp/`, see the example below as a reference:

    [uwsgi]
    buffer-size=8192
    chmod=660
    manage-script-name=true
    master=true
    max-requests=1000
    mount=/=mousikofidi:app
    pidfile=/opt/fidi/tmp/mousikofidi.pid
    procname=MousikoFidi
    socket=/opt/fidi/tmp/mousikofidi.sock
    vacuum=true

This can be done quickly with `sed`:

    sudo su - fidi
    sed -i "s|/tmp/mousikofidi.pid|/opt/fidi/tmp/mousikofidi.pid|;s|/tmp/mousikofidi.sock|/opt/fidi/tmp/mousikofidi.sock|" ~/.config/fidi/uwsgi.ini

Create that directory:

    sudo su - fidi
	mkdir ~/tmp

MousikóFídi can now be ran via `uwsgi` and the `mousikofidi` executable:

    sudo su - fidi
	mousikofidi --processes $(nproc)

Read on for how to access this via the Nginx HTTP server.

### uWSGI Daemon

One can optionally run `uwsgi` in a deamon-like mode, which forks to the background and writes to a log file.

To do this, first create a log directory:

    sudo su - fidi
    mkdir ~/logs

Then, add the following to `/opt/fidi/.config/fidi/uwsgi.ini`:

    daemonize=/opt/fidi/logs/uwsgi.log

Now, when `uwsgi` is ran as specified above it will fork into the background.  The specified log can be watched to see requests, errors, and etc.

## Configuring Nginx

This section requires superuser access to install the MousikóFídi Nginx configuration and enable it, as well as to install Nginx itself.

### The nginx user

The user that `nginx` is running as on your system will need read and write access to the socket created by running `uwsgi`:

    sudo usermod -a -G fidi www-data

Where `www-data` above is the user that the `nginx` server is running as.

Now, make sure that the `fidi` group can access `/opt/fidi/tmp`:

    sudo chmod 0750 /opt/fidi

    sudo chmod 0750 /opt/fidi/tmp

Read on for a description of how to configure Nginx to read the `uwsgi` socket.

### The nginx configuration

Included with MousikóFídi is [an example Nginx configuration file](https://git.sr.ht/~hristoast/mousikofidi/tree/897ab601f793064307f7ce142cf5eb15598f6998/example/fidi-nginx.conf) that you may use as a base for your own setup.

Copy this file to where nginx configs are kept:

	curl -o fidi-nginx.conf https://git.sr.ht/~hristoast/mousikofidi/blob/master/example/fidi-nginx.conf
    sudo cp -iv fidi-nginx.conf /etc/nginx/sites-available/

The example above is for Debian or Ubuntu; this could go into `/etc/nginx/conf.d` on other OSes.

Some edits need to be made before this config will actually work:

* The `server_name` value should be changed to use an actual domain you control and own ([here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L4) and [here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L14)).
* The `ssl_certificate` and `ssl_certificate_key` values ([here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L5) and [here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L15)) need to be changed with paths to actual self-signed certificates.
    * Generate a self-signed cert like this (you can just use the command as-is since the cert is only temporary. Sources: [one](https://stackoverflow.com/a/10176685), [two](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-in-ubuntu-16-04#step-1-create-the-ssl-certificate)):

            mkdir /etc/ssl/http
            openssl req -new -newkey rsa:4096 -nodes -x509 -utf8 -sha256 -subj "/C=EARTH/ST=SomePlace/L=SomeWhere/O=Internet/CN=mousikofidi.yourdomain.tld" -days 3650 -keyout /etc/ssl/http/yourdomain.tld.key -out /etc/ssl/http/yourdomain.tld.crt

* Ensure the configured log directory ([here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L7) and [here](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L18)) exists, or change it to suit your need:

        sudo su - fidi
        mkdir ~/logs

* Same for [the directory that will be used for the Let's Encrypt challenge](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L23):

        sudo su - fidi
        mkdir ~/ssl

* Create a password file that will be used for basic auth (This requires the `apache2-utils` package on Debian/Ubuntu):

        sudo su - fidi
        htpasswd -c /opt/fidi/.fidiauth YourFidiUserName
        chmod 0640 /opt/fidi/.fidiauth

* The basic auth configuration uses [fake IP addresses](https://git.sr.ht/~hristoast/mousikofidi/tree/462de5f217672af49d4fb1aafda04ef97813ba8f/example/fidi-nginx.conf#L31).  Update or remove those.

* [This line](https://git.sr.ht/~hristoast/mousikofidi/tree/271d7bd9a1b4c5669d967c4a69efe97414331a1e/example/fidi-nginx.conf#L37) needs to point to where `pip` put the static files.  As noted above, this location can be determined with `ls`:

        sudo su - fidi
        ls -d ~/.local/lib/python3.*/site-packages/mousikofidi/static

Test the nginx configuration before reloading:

    sudo nginx -t

If that passes, reload the nginx configuration and MousikóFídi will now be available behind the domain you used for `server_name` -- but your browser will complain about the certificate being bad.

Read on for a description of how to get a free certificate from [Let's Encrypt](https://letsencrypt.org/).

### Getting a Let's Encrypt cert

This section also requires superuser access, possibly to install [`certbot`](https://certbot.eff.org/) and the related Nginx plugin packages but also to install the certs themselves.

Some OSes offer packages for both `certbot` and the Nginx plugin, such as Debian and Ubuntu.  If no package is available, check out [the Certbot pip-nginx help page](https://certbot.eff.org/lets-encrypt/pip-nginx) and [the Certbot general instructions page](https://certbot.eff.org/instructions) page for help getting set up.

At this point, all that's needed to get a certificate is to run certbot:

    certbot --dry-run certonly --nginx -w /opt/fidi/ssl --agree-tos -d mousikofidi.mycooldomain.tld

Replace `mousikofidi.mycooldomain.tld` with your actual configured `server_name`.

Once the command finishes, a path to the new signed certificate and key files will be displayed.  Copy those paths and paste them into the fidi Nginx configuration over the old values for the self-signed ones.

Test and reload Nginx, and then your MousikóFídi instance should be viewable behind HTTPS on your domain.

Great Job!

## Running MousikóFídi As A System Service

Running MousikóFídi as a system service is one way to get better control over the process, as well as potential bonus features like auto-restarting and starting at boot.

### runit

The MousikóFídi demo is behind runit, and the project [includes sample files](https://git.sr.ht/~hristoast/mousikofidi/tree/f0b50a1e5fbb29ffe81d1e0be534c264c61b5fe9/example/runit) that can be used as a reference.

All commands in this section require superuser access.

1. Created the needed directories:

```
mkdir /etc/sv/fidi/{control,log,supervise}
```

1. Create the log `run` script:

```
cat > /etc/sv/fidi/log/run <<EOF
#!/bin/sh
exec logger -t mousikofidi
EOF
```

1. Create the `run` script for MousikóFídi itself:

```
cat > /etc/sv/fidi/run <<EOF
#!/bin/sh
export LANG=en_US.UTF-8
export USER=fidi
export HOME=/opt/\$USER
export PATH=\$HOME/.local/bin:\$PATH

exec chpst -u \$USER:\$USER uwsgi --ini \$HOME/.config/fidi/uwsgi.ini 2>&1
EOF
```

1. Create the `d` script for stopping MousikóFídi:

```
cat > /etc/sv/fidi/control/d <<EOF
#!/bin/sh
export LANG=en_US.UTF-8
export USER=fidi
export HOME=/opt/\$USER
export PATH=\$HOME/.local/bin:\$PATH

exec chpst -u \$USER:\$USER uwsgi --stop \$HOME/run/mousikofidi.pid 2>&1
EOF
```

1. Create the `r` script for reloading/restarting MousikóFídi:

```
cat > /etc/sv/fidi/control/d <<EOF
#!/bin/sh
export LANG=en_US.UTF-8
export USER=fidi
export HOME=/opt/\$USER
export PATH=\$HOME/.local/bin:\$PATH

exec chpst -u \$USER:\$USER uwsgi --reload \$HOME/run/mousikofidi.pid 2>&1
EOF
```

1. Enable the MousikóFídi service:

```
ln -sv /etc/sv/fidi /var/service/
```

Within a few moments, the MousikóFídi should be started.  If you are using some `syslog` provider, you can check the system logs for details about what's going on:

```
tail -f /var/log/messages | grep --color mousikofidi
```

1. Adjust the MousikóFídi service `supervise` permissions so the `fidi` user can manage the service without superuser access:

```
chmod 755 /etc/sv/fidi/supervise
chown fidi /etc/sv/fidi/supervise/*
```

#### Commands

The following commands should be used:

##### Reload/Restart

To reload, or restart the MousikóFídi process:

```
sv reload fidi
```

**NOTE**: The `reload` command is not currently known to work with fidi and will likely time out.  If you do this and end up in a bad state, stopping and starting the service should make things right.

##### Start

If the MousikóFídi process is not running, it can be started with any of these:

```
sv start fidi

sv u fidi

sv up fidi
```

##### Stop

If the MousikóFídi process is running, it can be stopped with any of these:

```
sv stop fidi

sv d fidi

sv down fidi
```

### SysV Init

While it may be possible to create a traditional init script for MousikóFídi, this is not advised and will not be supported by the project.

### systemd

#### User Service

The MousikóFídi repo [includes a sample unit files](https://git.sr.ht/~hristoast/mousikofidi/tree/703bfaa81128fe058916f3d430e6e184771e4160/example/mousikofidi.service) that can be used with systemd to run the application as a service.

Download the example file and run it as a user service:

```
test -d ~/.config/systemd/user || mkdir -p ~/.config/systemd/user
curl -o ~/.config/systemd/user/mousikofidi.service https://git.sr.ht/~hristoast/mousikofidi/blob/master/example/mousikofidi.service
systemctl --user enable --now mousikofidi.service
```
This page has moved: https://mousikofidi.info/setup/

M user_guide.md => user_guide.md +1 -319
@@ 1,319 1,1 @@
This is a guide to the basic functionality of MousikóFídi.

Throughout the guide, [the official MousikóFídi demo](https://demo.mousikofidi.info/) will be linked to as a reference.

## Executables

MousikóFídi ships with two executables: `mousikofidi` and `mousikofidi-client`.

### `mousikofidi`

The `mousikofidi` executable is used to manage and interact with the server process.  It will look for a file at `~/.config/fidi/uwsgi.ini` and if it is present it will automatically use it.

    mousikofidi --processes $(nproc) --daemonize ~/logs/uwsgi.log

It can also be used to start MousikóFídi via the Flask dev server:

    mousikfdi --dev

Run `mousikofidi --help` to see all the options.

### `mousikofidi-client`

The `mousikofidi-client` executable is a convenience utility for opening the MousikóFídi instance of your choosing in the browser of your choosing.

An instance can be specified with the `--instance-url` argument:

    mousikofidi-client --instance-url my-cool-fidi.instance.tld

It will also read the `FIDI_URL` environment variable if it's present:

    FIDI_URL=my-fidi.instance.tld mousikofidi-client

By default, it opens the demo instance with Chromium:

    mousikofidi-client

You can use another browser like this:

    mousikofidi-client --other "palemoon --private-window"

Run `mousikofidi-client --help` to see all the options.

## Server Admin

Working with the MousikóFídi process after it's been installed.  The below items assume that [the setup guide](https://mousikofidi.info/setup/) has been followed.

### Stopping MousikóFídi

The MousikóFídi `uwsgi` process can be stopped like this:

    sudo su - fidi
    mousikofidi --stop ~/run/mousikfdi.pid

### Restarting MousikóFídi

If MousikóFídi is running with the `daemonize` option, it can be reloaded like this:

    sudo su - fidi
    mousikofidi --reload ~/run/mousikfdi.pid

### Updating MousikóFídi

#### Via Pip

If you've installed MousikóFídi via `pip` as [per the setup guide](https://mousikofidi.info/setup/#installing-mousik--f--di), it can be upgraded like this:

    pip3 install --upgrade --user MousikoFidi

	# Or this if your python is newer:
    python3 -m pip install --upgrade --user MousikoFidi

    # If using runit
    sv reload fidi

    # If using systemd
    systemctl --user reload mousikofidi.service

    # If you are managing the process manually
    mousikofidi --reload ~/run/mousikfdi.pid

The reload command must be issued for any changes to take effect.

#### Via Git

Update the code, then restart the `uwsgi` process:

    sudo su - fidi

    cd ~/mousikofidi

    git pull

    make install

    # If using runit
    sv reload fidi

    # If using systemd
    systemctl --user reload mousikofidi.service

    # If you are managing the process manually
    mousikofidi --reload ~/run/mousikfdi.pid

#### Dev Build

If you want to try out a prerelease version of MousikóFídi, you can do so with `pip`:

    pip3 install --upgrade --user git+https://git.sr.ht/~hristoast/mousikofidi@dev

	# Or this if your python is newer:
    python3 -m pip install --user --upgrade git+https://git.sr.ht/~hristoast/mousikofidi@dev

This installs directly from the `dev` branch on the main git repo.

## Adding Your Collection

As described in [the configuration guide](https://mousikofidi.info/config/), paths to your music and video collections should be added to the config file in order to be made available with MousikóFídi.

On Linux and similar systems, often times a user's home directory is set up with permissions that are too tight for [the recommended setup](https://mousikofidi.info/setup/#creating-the-fidi-user) of MousikóFídi.

As an alternative, a path such as `/srv` can be used that's a bit more neutral on the permissions side:

    sudo mkdir -p /srv/{music,playlists,video}

Then, assuming your collections are found in those directories, set the config file:

    music_dirs:
      - /srv/music
      - /srv/video

If multi-user access to the files isn't a concern, these can of course be put under the `fidi` user's home directory in `/opt/fidi`.

### Valid Media Types

Any media type supported by modern web browsers is playable via MousikóFídi.  Please see [this MDN reference](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Audio_codecs#Common_codecs) on common supported audio codecs, and [this one for video codecs](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#Common_codecs).

Note that some `.mkv` video files are supported **via Chrome or Chromium only**.

## Shortcuts

It's often useful to have a shortcut for quickly accessing your MousikóFídi instance.  Depending on your OS, this can be done a few ways:

### Desktop

Desktop users can make a direct link with a launcher; simply run your web browser of choice with the address of your instance as the argument.

The `mousikofidi-client` program is a nice way to orchestrate this, simply put that in a `.desktop` file or call it directly with something like [`dmenu`](https://tools.suckless.org/dmenu/).

### Mobile

Mobile users can make a direct link to their MousikóFídi instance as well; most browsers should have some option to "Add Page Shortcut" (Fennec/Firefox) or similar.

Doing this places a direct link to the specified web page, in this case your MousikóFídi instance, on your device's home screen.

It will likely even sport the MousikóFídi logo, or whatever you have chosen for the site favicon.  This has been tested on Android with: Fennec, Firefox, Chrome, and Chromium.

## Browsing

The [main page of MousikóFídi](https://demo.mousikofidi.info/) features only the logo, and a nav bar with links.

Clicking the "Browse" button takes you to [an index of your configured `music_dirs`](https://demo.mousikofidi.info/browse).  From here, you can navigate freely while directly browsing directories and files in your collection.

You may note a grey triangle in the lower and upper left corners of the screen; clicking then will skip you to the top and bottom of any given page without doing a reload, respectively.

Additionally, on any page with a player the MousikóFídi logo in the nav bar will become a link to that player.  If there's both an audio and a video player, the video player gets the link.

The "top" triangle combined with the logo shortcut can be a great combo for quick navigating.

### Breadcrumb Links

At the top of any given "browse" page you will find a link or series of links that represent the path to the particular [file](https://demo.mousikofidi.info/browse/srv/music/JaB/JaB%20-%20Web%20City%20Vol%201-%20Way%20Of%20The%20Samurai/04%20-%20No%20Weapon.mp3) or [directory](https://demo.mousikofidi.info/browse/srv/music/JaB/JaB%20-%20Web%20City%20Vol%201-%20Way%20Of%20The%20Samurai) you are looking at.

This is a convenient way to navigate while browsing, and when you use these links MousikóFídi will position you on the next page with the thing you were just looking at in view; this saves you the trouble of needing to navigate back to your place.  It's an effect that is most noticeable in large collections, with many and/or deeply nested directories.

### File Detail Page

A [file detail page](https://demo.mousikofidi.info/browse/srv/music/from_freemusicarchive.org/Black_Ant_-_01_-_Fater_Lee.mp3) is what you see when you click the title of a file on a [directory detail page](https://demo.mousikofidi.info/browse/srv/music/from_freemusicarchive.org).

At the top is a series of links to any directory between the file and the base music dir, and an "Add to queue" button for adding this file to your queue.

For audio files, any metadata found will be shown as well as an audio player for just this file.

### Track Metadata

MousikóFídi will try to read an audio or video file and find any metadata that available.  These values will be displayed on the various views where you can see tracks.  If no metadata is present, the the track is referred to by its filename.

Other software, such as [beets](http://beets.io/) or [Kid3](https://kid3.sourceforge.io/) can be used to update or edit the metadata of your files.

### Directory Detail Page

A directory detail page might have [other directories in it](https://demo.mousikofidi.info/browse/srv/music/FF6_Balance_and_Ruin), it may have [files in it](https://demo.mousikofidi.info/browse/srv/music/from_freemusicarchive.org), or it may have a combination of both.

In the event that files are present, a button is offered to "Add All Tracks To Queue".  As expected, it will add any files in the current directory to [your queue](https://demo.mousikofidi.info/queue), found by clicking the "Queue" button in the nav.

Also present in any directory with files: the audio and/or video players will be present for their respective files.

### Playlist Detail Page

When playlist files are present, each playlist will have its own detail page found at [`/playlist/NAME`](https://demo.mousikofidi.info/playlist/JaB%20Mixtapes) where `NAME` here is the name of the playlist.

This page looks like a directory detail page with files in it.  The playlist detail page also sports the audio/video player as found on other pages.  Read on for more information about the player and related controls. 

#### Deleting A Playlist

At the bottom of each Playlist Detail page is a button labeled "Delete Playlist ..." that can be used to delete a playlist file, provided that [`playlist.allow_delete`](https://mousikofidi.info/config/#playlist-allow-delete) is enabled in your MousikóFídi config.

**Note that this action cannot be undone!**

## The Player

The MousikóFídi player is the only component in the application that requires the usage of javascript.  If you are blocking javascript, it will need to be allowed for any MousikóFídi instance that you want to use the player on.

### Audio And Video

The MousikóFídi player supports anything that can be played via your browser and the [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) and/or [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) elements.  The player controls look and act the same for both audio and video playlists, with the exception that they only affect their respective player.

If there is both audio and video tracks in a playlist, enabling Shuffle for the audio player won't also do the same for the video; the shuffle button beneath the video player needs to be clicked for video playback to shuffle too.

### Track Skipping

Clicking the "Previous" or "Next" buttons will advance the playlist in either direction;  if on the first track and "Previous" is clicked, the last track is changed to.  If on the last track and "Next" is clicked, the first track is changed to.

Additionally, the green play arrow next to each track name can be clicked to change to that track.

### Repeat

By default, the player will play through all tracks and then pause playback.  To repeat the current track, when the repeat button says "No Repeat" click it once.  It should now say "Repeat One", and as described before the current track will be repeated.

Clicking the button once more will change it to say "Repeat All" - this will play the entire playlist and repeat it when finished.

When "Repeat All" is active, you can click the button once more to disable repeating altogether (the button will return to saying "No Repeat").

### Shuffle

The playlist may be played in a shuffled order by clicking the "Shuffle Off" button; once clicked, it will say "Shuffle On".

When shuffling is enabled the tracks will play in a shuffled order until the last track is reached, at which time playback will end unless "Repeat All" is enabled.

If "Repeat All" is enabled, once the last track in the shuffled list finishes a new shuffled order will be generated and begin to play.

Additionally, clicking the green play arrow for any track will generate a new shuffled order beginning with this track.

No shuffling will occur if "Repeat One" is enabled.

### Follow

Enabled by default, the "Follow" option will jump to the currently playing track when one ends and another begins.  This behavior can be disabled by unchecking the box in the player.

### Copy Link

The audio and video players each have a button that, when clicked, will insert a link to the current track at the current time into your clipboard.

Listen to or view a track you enjoy, click the link button at the desired time, then share the link with family and friends.

### Volume Control

The MousikóFídi player volume controls will save volume levels for each player. Use the slider or the -/+ buttons to adjust the volume level, and it will perist as you browse your collection.

## The Queue

MousikóFídi supports adding audio and video tracks into a queue for your session.  Audio tracks loaded in this queue can be played in order or shuffled, as well as saved to a playlist file for later loading.

Saving and loading a queue into a playlist requires that `playlist.save` is set to `true` in your config file and that the configured `playlist.dir` exists and is writeable.

### Adding Tracks To The Queue

As described above, tracks can be added to the queue in various ways; either by clicking the "+" next to the track name on a directory detail page, by clicking the "Add All Tracks To Queue" button, or by clicking the "+" on a file detail page.

After adding tracks to the queue, you can click the "Queue" button in the nav to play them or save it to a file.

### Saving A Playlist

When tracks are added to the queue, and provided `playlist.save` is set to `true` (this is the default), when visiting the queue page form will be available which will save it as a file.

Enter the desired name for the playlist into the text box labeled 'Name', and hit enter of click the "Save Queue" button right next to it.

**Playlist names may only contain alphanumeric characters, spaces, underscores, and plus signs.**

If `playlist.save` is disabled, no queue saving will be allowed.  Any playlists that exist in the playlist directory will be loadable, however.  Any `.m3u` that has tracks with full paths and that are in your MousikóFídi music directories can be loaded, regardless of whether or not it was saved via MousikóFídi.

Here's an exmaple of me creating a playlist for the demo site from the command-line:

    ls -1 ~/music/FF6_Balance_and_Ruin/**/** > ~/playlists/OC\ Remix:\ FF6\ Balance\ And\ Ruin.m3u

I'm listing out all directories under that album and outputting it to a playlist file.

### Loading A Playlist

Any playlist that's been saved may be loaded into the queue.

Navigate to the queue page by clicking the "Queue" button in the nav.  If saved playlists are present, two buttons and a drop-down menu will be present.

Use the drop-down menu to select the playlist you wish to load, then click the "Load Playlist" button.

Note that any playlist created outside of MousikóFídi that has relative paths will not load in MousikóFídi.

#### Playlist Load Errors

If a playlist contains a trat is not identifiable as [a valid media track](#valid-media-types), you will receive an error message upon loading the playlist.

The MousikóFídi server log will have error entries for each track that is considered invalid, the server administrator should check there for specific information about what was considered invalid.

### Deleting A Playlist

Any playlist within the MousikóFídi playlist directory can be deleted by selecting it from the drop-down menu and clicking the "Delete Playlist" button.

After doing this, another button will appear asking you to confirm if you really want to delete the selected playlist.  Clicking this button will permanently delete the specified playlist (not the one in the drop-down menu, the one mentioned on the button).  **This cannot be undone**!

### Removing A Track From The Queue

On the Queue page, each track has a red X that can be clicked to remove the track from your queue. Upon clicking the X for any given track, the queue will re-render with the selected track gone.  If the X'd track was playing, it will be stopped and the first track of the queue will be loaded for playback.

### Moving A Track Within The Queue

Next to the red removal "X" are two orange-colored arrows. Clicking the down-pointing orange arrow will move that track down if possible, and clicking the up-pointing orange arrow will move the track up if possible.

### Clearing The Queue

A "Clear Queue" button is also available on the queue page.  Clicking it empties your queue of any tracks. **This cannot be undone**!
This page has moved: https://mousikofidi.info/user_guide/