mirror of
https://github.com/Findus23/RadioStats.git
synced 2024-09-19 16:03:48 +02:00
datePicker
This commit is contained in:
parent
8a643d6954
commit
8ec826446b
10 changed files with 183 additions and 33 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ __pycache__/
|
|||
queries.sql
|
||||
dist/
|
||||
web/node_modules/
|
||||
web/stats.json
|
||||
|
|
2
fetch.py
2
fetch.py
|
@ -66,7 +66,7 @@ for channel in Channel.select():
|
|||
|
||||
if " - " in song["title"]:
|
||||
if channel.shortname == "oe3" or channel.shortname=="fm4":
|
||||
artist, title = song["title"].split(" - ")
|
||||
artist, title = song["title"].split(" - ")[:2]
|
||||
else:
|
||||
title, artist = song["title"].split(" - ")[:2] # non oe3 channels are the other way round
|
||||
else:
|
||||
|
|
34
server.py
34
server.py
|
@ -1,3 +1,6 @@
|
|||
import calendar
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from flask import jsonify, request
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
|
@ -34,15 +37,40 @@ def index():
|
|||
return query_to_response(Channel.select(), limit=False, key="shortname")
|
||||
|
||||
|
||||
def getRange(date, date_type):
|
||||
if date_type == "day":
|
||||
start = date
|
||||
end = date
|
||||
elif date_type == "week":
|
||||
start = date - timedelta(days=date.weekday())
|
||||
end = start + timedelta(days=6)
|
||||
elif date_type == "month":
|
||||
start = date.replace(day=1)
|
||||
end = date.replace(day=calendar.monthrange(date.year, date.month)[1])
|
||||
else:
|
||||
start = datetime.strptime("2000-01-01", '%Y-%m-%d')
|
||||
end = datetime.strptime("2050-01-01", '%Y-%m-%d')
|
||||
end = end + timedelta(days=1)
|
||||
return start, end
|
||||
|
||||
|
||||
@app.route('/api/<channel>')
|
||||
def popular(channel):
|
||||
# range = request.args.get('')
|
||||
try:
|
||||
date = datetime.strptime(request.args.get('date'), '%Y-%m-%d')
|
||||
date_type = request.args.get('dateType')
|
||||
if date_type not in ["day", "week", "month", "alltime"]:
|
||||
raise ValueError
|
||||
except (TypeError, ValueError):
|
||||
date = datetime.today()
|
||||
date_type = "month"
|
||||
start, end = getRange(date, date_type)
|
||||
get = Play.select(Play.song, fn.Count(SQL('*')).alias("count")) \
|
||||
.join(Channel).switch(Play).join(Song) \
|
||||
.where((Song.show == 0) & (Channel.shortname == channel)) \
|
||||
.where((Song.show == 0) & (Channel.shortname == channel) & (
|
||||
Play.time.between(start, end))) \
|
||||
.group_by(Play.song).order_by(SQL('count').desc())
|
||||
if request.args.get('offset'):
|
||||
print(request.args.get('offset'))
|
||||
get = get.offset(int(request.args.get('offset')))
|
||||
return query_to_response(get, extra_attrs=["count"], exclude=[Play.channel, Play.time, Play.id])
|
||||
|
||||
|
|
14
web/.babelrc
Normal file
14
web/.babelrc
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": [
|
||||
">1% in AT"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
15
web/.eslintrc.json
Normal file
15
web/.eslintrc.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"semi": 2
|
||||
},
|
||||
"plugins": [
|
||||
"html"
|
||||
]
|
||||
}
|
138
web/List.vue
138
web/List.vue
|
@ -20,6 +20,27 @@
|
|||
|
||||
</header>
|
||||
<main>
|
||||
<div id="date" class="row">
|
||||
<div class="column">
|
||||
<datepicker language="de" v-model="date" :mondayFirst="true" :inline="true"
|
||||
:highlighted="highlighted"></datepicker>
|
||||
|
||||
</div>
|
||||
<div class="column">
|
||||
|
||||
<input type="radio" id="day" value="day" v-model="dateType">
|
||||
<label class="label-inline" for="day">Tag</label>
|
||||
<br>
|
||||
<input type="radio" id="week" value="week" v-model="dateType">
|
||||
<label class="label-inline" for="week">Woche</label>
|
||||
<br>
|
||||
<input type="radio" id="month" value="month" v-model="dateType">
|
||||
<label class="label-inline" for="month">Monat</label>
|
||||
<br>
|
||||
<input type="radio" id="alltime" value="alltime" v-model="dateType">
|
||||
<label class="label-inline" for="alltime">Gesamter Zeitraum</label>
|
||||
</div>
|
||||
</div>
|
||||
<table>
|
||||
<tr v-for="song in popular">
|
||||
<td>{{song.song.title}}</td>
|
||||
|
@ -42,9 +63,12 @@
|
|||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import Datepicker from 'vuejs-datepicker';
|
||||
|
||||
const baseURL = (process.env.NODE_ENV === "production") ? "/api/" : "http://127.0.0.1:5000/api/";
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
components: {Datepicker},
|
||||
name: 'list',
|
||||
data() {
|
||||
return {
|
||||
|
@ -52,86 +76,138 @@
|
|||
popular: [],
|
||||
offset: 0,
|
||||
showMore: true,
|
||||
httpError: false
|
||||
httpError: false,
|
||||
date: new Date(),
|
||||
dateType: "week",
|
||||
highlighted: {
|
||||
from: new Date(),
|
||||
to: new Date(),
|
||||
}
|
||||
};
|
||||
},
|
||||
props: ["channel"],
|
||||
computed: {
|
||||
channelData: function() {
|
||||
channelData: function () {
|
||||
return this.channels[this.channel];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getChannels: function() {
|
||||
getChannels: function () {
|
||||
let vm = this;
|
||||
axios.get('http://127.0.0.1:5001/', {
|
||||
axios.get(baseURL, {
|
||||
params: {}
|
||||
})
|
||||
.then(function(response) {
|
||||
.then(function (response) {
|
||||
vm.channels = response.data;
|
||||
vm.getPopular();
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
vm.httpError = error;
|
||||
});
|
||||
},
|
||||
getPopular: function() {
|
||||
getPopular: function () {
|
||||
this.offset = 0;
|
||||
this.showMore = true;
|
||||
this.httpError = false;
|
||||
|
||||
if (!this.channelData || !this.channelData.has_data) {
|
||||
this.popular = [];
|
||||
return false;
|
||||
}
|
||||
let vm = this;
|
||||
axios.get('http://127.0.0.1:5001/' + this.channel, {
|
||||
params: {}
|
||||
axios.get(baseURL + this.channel, {
|
||||
params: {
|
||||
date: vm.date.toISOString().split('T')[0],
|
||||
dateType: vm.dateType
|
||||
}
|
||||
})
|
||||
.then(function(response) {
|
||||
.then(function (response) {
|
||||
vm.offset += 5;
|
||||
vm.popular = response.data;
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
vm.httpError = error;
|
||||
});
|
||||
},
|
||||
getAdditional: function() {
|
||||
getAdditional: function () {
|
||||
let vm = this;
|
||||
|
||||
axios.get('http://127.0.0.1:5001/' + this.channel, {
|
||||
axios.get(baseURL + this.channel, {
|
||||
params: {
|
||||
offset: vm.offset
|
||||
offset: vm.offset,
|
||||
date: vm.date.toISOString().split('T')[0],
|
||||
dateType: vm.dateType
|
||||
}
|
||||
})
|
||||
.then(function(response) {
|
||||
.then(function (response) {
|
||||
vm.offset += 5;
|
||||
vm.popular = vm.popular.concat(response.data);
|
||||
if (response.data.length < 5) {
|
||||
vm.showMore = false
|
||||
vm.showMore = false;
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
vm.httpError = error;
|
||||
});
|
||||
|
||||
},
|
||||
icon: function(id) {
|
||||
icon: function (id) {
|
||||
if (id === "fm4" || id === "oe3") {
|
||||
return id + ".svg";
|
||||
} else {
|
||||
return id + ".png";
|
||||
}
|
||||
},
|
||||
updateSelection: function () {
|
||||
let from, to;
|
||||
let y = this.date.getFullYear();
|
||||
let d = this.date.getDay();
|
||||
let m = this.date.getMonth();
|
||||
switch (this.dateType) {
|
||||
case "day":
|
||||
from = new Date(this.date);
|
||||
to = new Date(this.date);
|
||||
break;
|
||||
case "week":
|
||||
let diff = this.date.getDate() - (d - 1) + (d === 0 ? -7 : 0);
|
||||
from = new Date(this.date);
|
||||
from.setDate(diff);
|
||||
to = new Date(this.date);
|
||||
to.setDate(diff + 6);
|
||||
break;
|
||||
case "month":
|
||||
from = new Date(y, m, 1);
|
||||
to = new Date(y, m + 1, 1);
|
||||
break;
|
||||
default:
|
||||
from = new Date(2000, 0, 0);
|
||||
to = new Date(2050, 0, 0);
|
||||
}
|
||||
from.setHours(0, 0, 0, 0);
|
||||
to.setHours(23, 59, 59, 0);
|
||||
this.highlighted = {
|
||||
"from": from,
|
||||
"to": to,
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
channel: function(id) {
|
||||
this.offset = 0;
|
||||
this.showMore = true;
|
||||
this.httpError = false;
|
||||
|
||||
this.getPopular()
|
||||
channel: function () {
|
||||
this.getPopular();
|
||||
},
|
||||
dateType: function () {
|
||||
this.updateSelection();
|
||||
this.getPopular();
|
||||
},
|
||||
date: function () {
|
||||
this.updateSelection();
|
||||
this.getPopular();
|
||||
}
|
||||
|
||||
},
|
||||
mounted: function() {
|
||||
mounted: function () {
|
||||
this.getChannels();
|
||||
this.updateSelection();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -206,4 +282,12 @@
|
|||
background-color: $warning;
|
||||
}
|
||||
|
||||
#date {
|
||||
align-items: center;
|
||||
.vdp-datepicker__calendar {
|
||||
margin-right: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default class MatomoTracker {
|
|||
(function() {
|
||||
let u = (process.env.NODE_ENV === "production") ? "https://matomo.lw1.at/" : "//localhost/piwik/";
|
||||
_paq.push(['setTrackerUrl', u + 'piwik.php']);
|
||||
_paq.push(['setSiteId', (process.env.NODE_ENV === "production") ? 14 : 5]);
|
||||
_paq.push(['setSiteId', (process.env.NODE_ENV === "production") ? 15 : 5]);
|
||||
let d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
g.type = 'text/javascript';
|
||||
g.async = true;
|
||||
|
|
5
web/package-lock.json
generated
5
web/package-lock.json
generated
|
@ -13403,6 +13403,11 @@
|
|||
"integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==",
|
||||
"dev": true
|
||||
},
|
||||
"vuejs-datepicker": {
|
||||
"version": "0.9.25",
|
||||
"resolved": "https://registry.npmjs.org/vuejs-datepicker/-/vuejs-datepicker-0.9.25.tgz",
|
||||
"integrity": "sha512-+Vldt5bl2/7tW8ScQm7eE9wVIOq7eNSGupRNLP8ej9vTR3wWz9i8fwJjWgxZ3HyGrUo4J5ki1hAzyY9cdxccoQ=="
|
||||
},
|
||||
"ware": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz",
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
"normalize.css": "^7.0.0",
|
||||
"vue": "^2.5.13",
|
||||
"vue-head": "^2.0.12",
|
||||
"vue-router": "^3.0.1"
|
||||
"vue-router": "^3.0.1",
|
||||
"vuejs-datepicker": "^0.9.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0-beta.39",
|
||||
|
|
2
web/upload.sh
Executable file
2
web/upload.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
rsync -rvzP ../dist/ lukas@lw1.at:/srv/server/RadioStats/dist/ --fuzzy --delete-after -v
|
Loading…
Reference in a new issue