barrucadu / lainonlife Goto Github PK
View Code? Open in Web Editor NEWRIP lainchan radio, taken out by HDD failure.
Home Page: https://lainon.life
License: MIT License
RIP lainchan radio, taken out by HDD failure.
Home Page: https://lainon.life
License: MIT License
HSTS can dramatically reduce the efficacy of MITM attacks by telling the browser to only talk to the site over HTTPS.
For background reading see https://scotthelme.co.uk/hsts-the-missing-link-in-tls/
It's unlikely, but MPD can go wrong. Adding a fallback stream to the /mpd-*.{mp3,ogg}
mountpoints would at least prevent the radio from going totally dead until I fix things.
Ideally, the source of this stream should not be another MPD instance. Just something simple that can loop a single audio track.
The 404 music would work fine.
This is a server configuration change and so implementing it would kick everyone off the stream.
https://scotthelme.co.uk/a-new-security-header-referrer-policy/
This is especially useful when #32 is implemented, which may well leak CSRF tokens into GET parameters (and so the default referrer for any external links.)
strict-origin-when-cross-origin
seems like a good default. This sends the full URL when going to the same origin, the origin when going to another origin, and nothing when downgrading from https to http:
This is a server configuration change and so implementing it would kick everyone off the stream.
Currently got a few Vapourwave albums on everything
, worth having a dedicated channel?
backend.py
opens a new MPD client every time a playlist is requested, which is every 15 seconds per listener. This is very inefficient: it should open the clients when it starts, and re-open them if they drop for any reason, returning the current error if reconnection fails.
Not so great:
Jun 07 02:03:23 lainonlife mpd[27198]: client: [118420] closed
Jun 07 02:03:23 lainonlife mpd[22299]: client: [111921] closed
Jun 07 02:03:23 lainonlife mpd[27198]: client: [118419] closed
Jun 07 02:03:23 lainonlife mpd[25580]: client: [536400] closed
Jun 07 02:03:23 lainonlife mpd[25580]: client: [536399] closed
Jun 07 02:03:23 lainonlife mpd[25580]: client: [536398] closed
Jun 07 02:03:23 lainonlife mpd[22299]: client: [111920] closed
Jun 07 02:03:23 lainonlife mpd[27198]: client: [118418] closed
Jun 07 02:03:23 lainonlife mpd[25580]: client: [536397] closed
Jun 07 02:03:23 lainonlife mpd[25580]: client: [536396] closed
...
Jun 07 02:02:44 lainonlife mpd[22299]: client: [111919] closed
Jun 07 02:02:44 lainonlife mpd[25580]: client: [536395] closed
Jun 07 02:02:44 lainonlife mpd[27198]: client: [118417] closed
Jun 07 02:02:44 lainonlife mpd[25580]: client: [536394] closed
Jun 07 02:02:44 lainonlife mpd[22299]: client: [111918] closed
Jun 07 02:02:44 lainonlife mpd[27198]: client: [118416] closed
Jun 07 02:02:44 lainonlife mpd[25580]: client: [536393] closed
Jun 07 02:02:44 lainonlife mpd[25580]: client: [536392] closed
Jun 07 02:02:44 lainonlife mpd[22299]: client: [111917] closed
Jun 07 02:02:44 lainonlife mpd[25580]: client: [536391] closed
The playlist links on the site player (https://lainon.life/file-list/everything.html, https://lainon.life/file-list/cyberia.html, etc) are currently returning 404 errors instead of file lists.
I think it would make more sense to have the donate page display inside a modal window instead of having it as a separate .html
page. So basically like https://lainon.life/#schedule. Also the stream wouldn't be interrupted that way. The donate.html
page could be kept for external linking purposes.
There's a feedback thread on /music/, but something directly on the site would be nice as well. Maybe this would work best as a generic comment form, with suggested topics (eg "music you want").
Steps:
upload_voice
function should be helpful.Currently there's a buttload of AJAX requests. Every client is frequently talking to (1) Icecast, for the number of listeners and channel description; and (2) backend.py, for the current playlist.
All of this data is something which changes relatively infrequently, so it would be nice to use something push-based rather than pull-based.
Steps:
Currently index.html
works for both javascript and non-javascript users, although the non-javascript behaviour is greatly degraded.
This leads to significant complication in the code, however. It also means that it's hard to implement features like (eg) the requests form being a modal window with a javascript submission, rather than a separate page with a regular POST submission. It would be nice to keep everything on one page, to avoid navigating away from the audio stream.
A <noscript>
tag could be used to point people to the raw streams at /radio/
.
From the systemd journal:
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:10:35Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:10:05Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:09:34Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:09:04Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:08:33Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:08:03Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:07:32Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:07:01Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:06:31Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:06:00Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:05:30Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:04:59Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:04:29Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:03:58Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:03:27Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:02:57Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:02:26Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:01:56Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:01:25Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:00:55Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-07T00:00:24Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:59:53Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:59:23Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:58:52Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:58:22Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:57:51Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:57:21Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:56:50Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:56:19Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:55:49Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:55:18Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:54:48Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:54:17Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:53:47Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:53:16Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:52:45Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:52:15Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:51:44Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:51:14Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:50:43Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:50:12Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:49:42Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:49:11Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:48:41Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:48:10Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:47:40Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:47:09Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:46:38Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:46:08Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:45:37Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:45:07Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:44:36Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:44:06Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:43:35Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:43:04Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:42:34Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:42:03Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:41:33Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:41:02Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:40:31Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:40:01Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:39:30Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:39:00Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:38:29Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:37:59Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:37:28Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:36:58Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:36:27Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:35:56Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:35:26Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:34:55Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:34:25Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:33:54Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:33:24Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:32:53Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:32:22Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:31:52Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:31:21Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:30:51Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:30:20Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:29:50Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:29:19Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:28:48Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:28:18Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:27:47Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:27:17Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:26:46Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:26:16Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:25:45Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:25:14Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:24:44Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:24:13Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:23:43Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:23:12Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:22:42Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:22:11Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:21:40Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:21:10Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:20:39Z
Jun 07 02:04:36 lainonlife python3[22806]: Sending report for 2017-06-06T23:20:09Z
Jun 07 02:04:36 lainonlife systemd-journald[460]: Suppressed 105 messages from /system.slice/metrics.service
That shouldn't happen.
The playlist only updates every 15 seconds, so the user will be up to 15s into the next song when the current one ends. Not terribly great UX.
I was having difficulty loading the site and noticed that there had been no journalctl
entries for two hours. Attempting to load the playlist from another machine hung:
--2017-10-14 14:03:51-- https://lainon.life/playlist/cyberia.json
Resolving lainon.life (lainon.life)... 2001:41d0:1:5394::1, 91.121.0.148
Connecting to lainon.life (lainon.life)|2001:41d0:1:5394::1|:443... connected.
HTTP request sent, awaiting response... ^C
I did not try to load the playlist locally, so I don't know if this was an nginx or a http-backend issue.
Restarting the service fixed it. Here's the journal showing the latest requests received before the restart and the restart itself:
Oct 14 14:04:11 lainonlife bash[20651]: * Running on http://127.0.0.1:8002/ (Press CTRL+C to quit)
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: MarkupSafe>=0.23 in ./__venv__/lib/python3.5/site-packages (from Jinja2>=2.4->Flask>=0.12.0->-r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: python-dateutil>=2.6.0 in ./__venv__/lib/python3.5/site-packages (from influxdb->-r requirements.txt (line 8))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: idna<2.6,>=2.5 in ./__venv__/lib/python3.5/site-packages (from requests->-r requirements.txt (line 7))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: urllib3<1.22,>=1.21.1 in ./__venv__/lib/python3.5/site-packages (from requests->-r requirements.txt (line 7))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: chardet<3.1.0,>=3.0.2 in ./__venv__/lib/python3.5/site-packages (from requests->-r requirements.txt (line 7))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: certifi>=2017.4.17 in ./__venv__/lib/python3.5/site-packages (from requests->-r requirements.txt (line 7))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: pytz in ./__venv__/lib/python3.5/site-packages (from apscheduler->-r requirements.txt (line 6))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: setuptools>=0.7 in ./__venv__/lib/python3.5/site-packages (from apscheduler->-r requirements.txt (line 6))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: tzlocal>=1.2 in ./__venv__/lib/python3.5/site-packages (from apscheduler->-r requirements.txt (line 6))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: six>=1.4.0 in ./__venv__/lib/python3.5/site-packages (from apscheduler->-r requirements.txt (line 6))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: Jinja2>=2.4 in ./__venv__/lib/python3.5/site-packages (from Flask>=0.12.0->-r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: itsdangerous>=0.21 in ./__venv__/lib/python3.5/site-packages (from Flask>=0.12.0->-r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: Werkzeug>=0.7 in ./__venv__/lib/python3.5/site-packages (from Flask>=0.12.0->-r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: click>=2.0 in ./__venv__/lib/python3.5/site-packages (from Flask>=0.12.0->-r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: influxdb in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 8))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: requests in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 7))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: apscheduler in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 6))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: tinydb in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 5))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: flask-login in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 4))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: python-mpd2>=0.5.5 in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 3))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: Flask>=0.12.0 in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 2))
Oct 14 14:04:10 lainonlife bash[20651]: Requirement already satisfied: docopt>=0.6.2 in ./__venv__/lib/python3.5/site-packages (from -r requirements.txt (line 1))
Oct 14 14:04:10 lainonlife bash[20651]: The directory '/var/empty/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -
Oct 14 14:04:10 lainonlife bash[20651]: The directory '/var/empty/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want s
Oct 14 14:04:07 lainonlife systemd[1]: Started HTTP backend service.
Oct 14 14:04:07 lainonlife systemd[1]: Stopped HTTP backend service.
Oct 14 14:04:07 lainonlife systemd[1]: Stopping HTTP backend service...
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
Oct 14 12:01:22 lainonlife bash[20093]: 127.0.0.1 - - [14/Oct/2017 12:01:22] "GET /playlist/cyberia.json HTTP/1.0" 200 -
...
As there should be a request to the playlist every 15 seconds, at least, it's very suspicious that there were apparently no requests for two hours. This means that something was going wrong processing all requests: either nginx failing to deliver them (and just hanging internally for some reason) or http-backend failing to process them.
Hi ๐
Like #42, now its returning 404 on https://lainon.life/file-list/everything.html, https://lainon.life/file-list/cyberia.html, https://lainon.life/file-list/cafe.html and https://lainon.life/file-list/swing.html
I think it would be nice if the site would be responsive.
This is not that important, I guess, most people won't use it on a smartphone.
Nevertheless I think it would be a "nice to have"-feature.
I tend to use the site on the go, on mine, so I would be happy about it. ^^
Got this request:
album: Dancefloor Degrader
url: http://lolicore.ml/DanceCorps/[DCRPS010]%20Goreshit%20-%20Dancefloor%20Degrader/
notes: I think there already is a bit of breakcore/lolicore, but I am not really sure tbh.
I am also not really sure if it is fitting, but I thought I suggest it anyway.
It's a classic lolicore album.
Maybe a breakcore/lolicore channel would be something but I think there aren't enough listeners.
artist: Goreshit
Maybe worth having a lolicore channel?
It's currently hard-coded that streaming is to cyberia, which is reasonable as that's the default channel on lainchan.org.
It would be nice to be able to stream to different channels, however. There could even be multiple DJs streaming simultaneously to different channels!
Currently the pause button, when resumed, causes the player to continue where it left off. It's now behind the stream. Better behaviour would be to just resume from wherever the stream is up to.
Hi ๐
Currently the progress bar is only updated by api requests because the progressFun() function is not defined, maybe the problem is this code;
lainonlife/frontend/js/player.js
Lines 125 to 127 in b3fee61
It was removed in commit 33b11a7#diff-cdb222c1cd0bfd939054445c45f332a61fb3c7b246428b4eec259561b2efbbbf
The browser widget really doesn't fit in. Just a simple play button, progress bar, and time, of the appropriate colours (eg http://r-a-d.io/).
Notes:
check_playlist
function gets the duration and progress of the current track. These can be used to correct the progress bar, with constant-rate advancement happening otherwise.Currently the same password is used for the /$channel.$ext
and /mpd-$channel.$ext
streams (although it is a per-channel password). This means a DJ could stream to the MPD mountpoint. It would be better to have different passwords, to prevent this.
This is a server configuration change and so implementing it would kick everyone off the stream.
The current playlist is planned hours in advance. I do think that occasionally playing a complete album is nicer than purely global shuffle, but it does mean we can't really have a request form like r/a/dio. The next best thing is a link to vote to skip an upcoming track.
Steps:
Is there a reason why the backend scripts file-list.sh
and backend.py
are reading files from an absolute path (/srv/http
)?
I'm not much of a Python programmer, but I could imagine this causing issues when deploying the application on different kinds of operating systems. Debian for example uses /var/www/html
as webserver root.
So basically I'm suggesting using relative paths. That way the web application should be able to run from any directory.
The admin actions are particularly bad for this, as they all work with GET requests.
Here's a snippet about CSRF and Flask: http://flask.pocoo.org/snippets/3/
Probably better would be a decorator that checks the params, as that would then work with GET and POST requests.
To match the lainchan radio page.
Fortunately, Icecast makes livestreaming very simple. There's just a little work that needs to be done for it to be seamless.
Some sort of schedule on the website. r/a/dio (click "Schedule") just has a box appear with javascript. We can use something like that too, with an appropriate non-javascript fallback.
The playlist_for
function in backend.py needs to be aware that the playlist may not come from MPD:
radio.js
and player.js
displaying that nicely somehow.A script to start a stream:
playlist_for
in backend.py to know there is a streamA script to stop a stream:
The MPD and Icecast configs are not very exciting, but in case they are of use:
icecast.xml:
<!-- There is nothing exciting here. I have set the hostname and passwords, that's it. Everything else is default. -->
<icecast>
<hostname>lainon.life</hostname>
<authentication>
<admin-user>admin</admin-user>
<admin-password>password</admin-password>
</authentication>
<paths>
<logdir>/var/log/icecast</logdir>
<!-- These paths will depend on your distro -->
<adminroot>/nix/store/d7gk1q4crva10l8785aa8fwm79r3j62l-icecast-2.4.1/share/icecast/admin</adminroot>
<webroot>/nix/store/d7gk1q4crva10l8785aa8fwm79r3j62l-icecast-2.4.1/share/icecast/web</webroot>
<alias source="/" dest="/status.xsl"/>
</paths>
<listen-socket>
<port>8000</port>
<bind-address>::</bind-address>
</listen-socket>
<security>
<chroot>0</chroot>
<changeowner>
<user>nobody</user>
<group>nogroup</group>
</changeowner>
</security>
<authentication>
<source-password>password</source-password>
<relay-password>password</relay-password>
</authentication>
</icecast>
mpd-cyberia.conf:
# These paths will depend on your system
music_directory "/srv/radio/music/cyberia"
playlist_directory "/srv/radio/data/cyberia/playlists"
db_file "/srv/radio/data/cyberia/db"
state_file "/srv/radio/data/cyberia/state"
sticker_file "/srv/radio/data/cyberia/sticker.sql"
log_file "syslog"
bind_to_address "127.0.0.1"
port "6601"
audio_output {
name "cyberia (ogg)"
description "classic lainchan radio: electronic, chiptune, weeb"
type "shout"
encoder "vorbis"
host "localhost"
port "8000"
mount "/cyberia.ogg"
user "source"
password "password"
quality "3"
format "44100:16:2"
always_on "yes"
}
audio_output {
name "cyberia (mp3)"
description "classic lainchan radio: electronic, chiptune, weeb"
type "shout"
encoder "lame"
host "localhost"
port "8000"
mount "/cyberia.mp3"
user "source"
password "password"
quality "3"
format "44100:16:2"
always_on "yes"
}
audio_output {
type "null"
name "null"
}
For dealing with the MPD outputs, see the python-mpd2 docs.
To avoid an ugly http://lainon.life:8000
URL, the stream is currently proxied through nginx, which has two downsides:
It would be best to get a second IP, point stream.lainon.life
to that IP, and have Icecast listen on stream.lainon.life:80
.
This is a server configuration change and so implementing it would kick everyone off the stream.
As evidenced by this morning, just checking configuration is syntactically valid and looks reasonable before deploying is a good way to cause downtime.
Fortunately, NixOS containers should make it trivial to run a staging site.
There are a lot of albums now, so diversity should be encouraged.
it would lower the barrier of entry for people considering djing, this can be done with a vetting procedure or as an auto-dj type thing
Similar to #10 but different.
It would be nice to pick a new album, if there are any, when deciding which one to schedule.
There could simply be a list of which albums have been played, or maybe MPD's sticker mechanism could be used to store that info in its database.
I got an email from someone wanting to donate for server costs.
This is quite possibly the first ever non-scam email I've got out of the blue offering me money.
11 tracks or so: last 5, current, next 5.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.