Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
manzari committed Dec 22, 2018
0 parents commit 195c06a
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### PyCharm ###
.idea/

### Python ###
venv/
__pycache__/
*.pyc
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Raspotify Status
A simple monitoring app for the awesome [raspotify client](https://github.com/dtcooper/raspotify) on raspbian

![](/screenshot.png?raw=true)

## Installation
### Fast
Open a new ssh session to the raspotify host and navigate to your home directory then run the following command
```bash
wget -qO- https://github.com/manzari/raspotify-monitor/raw/master/install/install.sh | bash
```
### Manual
#### Requirements
```bash
sudo apt-get install -y python3-pip nginx
sudo -H pip3 install -r requirements.txt
```
#### Copy config files
```bash
sudo cp nginx.conf /etc/nginx/nginx.conf
sudo cp gunicorn.service /etc/systemd/system/gunicorn.service
```
#### Start the services
```bash
sudo systemctl daemon-reload
sudo service gunicorn start
sudo service nginx start
```
17 changes: 17 additions & 0 deletions install/gunicorn.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Unit]
Description=gunicorn daemon for raspotify-monitor
After=network.target

[Service]
PIDFile=/run/gunicorn/pid
User=pi
Group=pi
RuntimeDirectory=/home/pi/raspotify-monitor
WorkingDirectory=/home/pi/raspotify-monitor
ExecStart=/usr/bin/sudo gunicorn --bind 127.0.0.1:8000 raspotify-monitor:app
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
26 changes: 26 additions & 0 deletions install/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/bash
sudo apt-get update
sudo apt-get install -y python3-pip nginx
if test "$PWD" = "/home/pi"; then
if test -d /home/pi/raspotify-monitor; then
sudo service gunicorn stop
sudo service nginx stop
sudo rm -r /home/pi/raspotify-monitor
fi
echo downloading repo... >&2
wget https://github.com/manzari/raspotify-monitor/archive/master.zip
unzip master.zip
rm master.zip
mv raspotify-monitor-master raspotify-monitor
else
echo ERROR: must be executed in /home/pi >&2
exit 1
fi
sudo -H pip3 install -r raspotify-monitor/install/requirements.txt
sudo cp raspotify-monitor/install/nginx.conf /etc/nginx/nginx.conf
sudo cp raspotify-monitor/install/gunicorn.service /etc/systemd/system/gunicorn.service
sudo systemctl daemon-reload
sudo service gunicorn start
sudo service nginx start
echo done! >&2
exit 0
24 changes: 24 additions & 0 deletions install/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
worker_processes 1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name raspotify.fritz.box;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
4 changes: 4 additions & 0 deletions install/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Flask
jinja2
gunicorn

75 changes: 75 additions & 0 deletions raspotify-monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from flask import Flask, redirect
from jinja2 import Template
from subprocess import getoutput
import re

app = Flask(__name__)
status_template = Template(open('templates/status.html', 'r').read())


def refresh_status():
stdout = getoutput("sudo netstat -anpt | awk '((/LISTEN/||/ESTABLISHED/)&&/librespot/)||/Program/{;print $0}'")
stati = {'run': False, 'listen': False, 'established': False, 'statuslines': []}
if re.search(r"(LISTEN\s+\d+\/librespot)", stdout, re.MULTILINE):
stati['listen'] = True
if re.search(r"(ESTABLISHED\s+\d+\/librespot)", stdout, re.MULTILINE):
stati['established'] = True
stdout2 = getoutput("sudo service raspotify status")
stati['statuslines'] = stdout2.split('\n')
if re.search(r"(Active:\sactive\s\(running\))", stdout2, re.MULTILINE):
stati['run'] = True
return stati


def control_service(task):
stdout = getoutput("sudo service raspotify " + task)
return stdout


@app.route('/')
def home():
return redirect("/status", code=301)


@app.route('/status')
def status():
print("STATUS CALLED")
stati = refresh_status()
return status_template.render(
listenstatus=stati['listen'],
establishedstatus=stati['established'],
runstatus=stati['run'],
statuslines=stati['statuslines'][:5],
refreshtime=7
)


@app.route('/restart')
def restart():
output = control_service('restart')
if output == '':
return 'OK'
else:
return 'ERROR'


@app.route('/start')
def start():
output = control_service('start')
if output == '':
return 'OK'
else:
return 'ERROR'


@app.route('/stop')
def stop():
output = control_service('stop')
if output == '':
return 'OK'
else:
return 'ERROR'


if __name__ == '__main__':
app.run()
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 74 additions & 0 deletions templates/status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Refresh" content="{{ refreshtime }}">
<title>RaspotifyStatus</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<style>
.codebox {
width: 90%;
margin: 20px auto 0 auto;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);

-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.code {
margin: 0;
padding: 5px;
list-style: none;
background: #151515;
color: #45D42A;
font: 0.8em 'Andale Mono', Consolas, 'Courier New';
line-height: 1.6em;

-webkit-border-bottom-right-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
-moz-border-radius-bottomright: 3px;
-moz-border-radius-bottomleft: 3px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
}
.code li {
word-wrap: break-word;
position: relative;
padding: 0 0 0 15px;
}
</style>
</head>
<body>
<div class="text-center">
<br>
<p>{% if runstatus %}✔{% else %}❌{% endif %}Service Running</p>
<p>{% if listenstatus %}✔{% else %}❌{% endif %} Listening</p>
<p>{% if establishedstatus %}✔{% else %}❌{% endif %} Connection Established</p>
<br>
<div class="container">
<button id="start" class="btn btn-success">Start</button>
<button id="stop" class="btn btn-danger">Stop</button>
<button id="restart" class="btn btn-warning">Restart</button>
</div>
</div>
<div class="codebox">
<ul class="code">
{% for line in statuslines %}
<li>{{ line }}</li>
{% endfor %}
</ul>
</div>
<script>
$("#start").click(function () {
$.get("/start")
});
$("#stop").click(function () {
$.get("/stop")
});
$("#restart").click(function () {
$.get("/restart")
});
</script>
</body>
</html>

0 comments on commit 195c06a

Please sign in to comment.