mirror of
https://github.com/Findus23/RadioStats.git
synced 2024-09-19 16:03:48 +02:00
add "all" radio and improve JS
This commit is contained in:
parent
d6c3430931
commit
a5d448799d
5 changed files with 85 additions and 49 deletions
|
@ -239,5 +239,12 @@ channels = {
|
||||||
"cHasData": True,
|
"cHasData": True,
|
||||||
"cPrimaryColor": "#000000",
|
"cPrimaryColor": "#000000",
|
||||||
"cSecondaryColor": "#E2001A"
|
"cSecondaryColor": "#E2001A"
|
||||||
|
},
|
||||||
|
"all": {
|
||||||
|
"shortname": "all",
|
||||||
|
"stationname": "Alle",
|
||||||
|
"cHasData": True,
|
||||||
|
"cPrimaryColor": "black",
|
||||||
|
"cSecondaryColor": "white"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
server.py
29
server.py
|
@ -8,6 +8,12 @@ from app import app
|
||||||
from models import *
|
from models import *
|
||||||
|
|
||||||
|
|
||||||
|
def add_cors(response):
|
||||||
|
header = response.headers
|
||||||
|
header['Access-Control-Allow-Origin'] = '*'
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def query_to_response(query, limit=10, key=False, sort=False, offset=None, list=None, **kwargs):
|
def query_to_response(query, limit=10, key=False, sort=False, offset=None, list=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -83,9 +89,10 @@ def popular(channel):
|
||||||
start, end = get_range(date, date_type)
|
start, end = get_range(date, date_type)
|
||||||
get = Play.select(Play.song, fn.Count(SQL('*')).alias("count")) \
|
get = Play.select(Play.song, fn.Count(SQL('*')).alias("count")) \
|
||||||
.join(Channel).switch(Play).join(Song) \
|
.join(Channel).switch(Play).join(Song) \
|
||||||
.where((Song.show == 0) & (Channel.shortname == channel) & (
|
.where((Song.show == 0) & (Play.time.between(start, end)))
|
||||||
Play.time.between(start, end))) \
|
if channel != "all":
|
||||||
.group_by(Play.song).order_by(SQL('count').desc())
|
get = get.where(Channel.shortname == channel)
|
||||||
|
get = get.group_by(Play.song).order_by(SQL('count').desc())
|
||||||
if request.args.get('offset'):
|
if request.args.get('offset'):
|
||||||
get = get.offset(int(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], key="song.id",
|
return query_to_response(get, extra_attrs=["count"], exclude=[Play.channel, Play.time, Play.id], key="song.id",
|
||||||
|
@ -98,8 +105,10 @@ def plays(channel, song_id):
|
||||||
start, end = get_range(date, date_type)
|
start, end = get_range(date, date_type)
|
||||||
get = Play.select(Play.time) \
|
get = Play.select(Play.time) \
|
||||||
.join(Channel) \
|
.join(Channel) \
|
||||||
.where((Play.song == song_id) & (Channel.shortname == channel) & (Play.time.between(start, end))) \
|
.where((Play.song == song_id) & (Play.time.between(start, end)))
|
||||||
.order_by(Play.time.desc())
|
if channel != "all":
|
||||||
|
get = get.where(Channel.shortname == channel)
|
||||||
|
get = get.order_by(Play.time.desc())
|
||||||
return query_to_response(get, exclude=[Play.channel, Play.song, Play.id], list="time", limit=False)
|
return query_to_response(get, exclude=[Play.channel, Play.song, Play.id], list="time", limit=False)
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,9 +118,12 @@ def details(channel, song_id):
|
||||||
.where(Song.id == song_id)
|
.where(Song.id == song_id)
|
||||||
date, date_type = get_dates_from_request()
|
date, date_type = get_dates_from_request()
|
||||||
start, end = get_range(date, date_type)
|
start, end = get_range(date, date_type)
|
||||||
count = Play.select().join(Channel).where(
|
get = Play.select().join(Channel).where(
|
||||||
(Play.song == song_id) & (Channel.shortname == channel) & (Play.time.between(start, end))
|
(Play.song == song_id) & (Play.time.between(start, end))
|
||||||
).count()
|
)
|
||||||
|
if channel != "all":
|
||||||
|
get = get.where(Channel.shortname == channel)
|
||||||
|
count = get.count()
|
||||||
response = jsonify({"order": -1, "count": count, "song": model_to_dict(get.get())})
|
response = jsonify({"order": -1, "count": count, "song": model_to_dict(get.get())})
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||||
|
@ -120,4 +132,5 @@ def details(channel, song_id):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.debug = True
|
app.debug = True
|
||||||
|
app.after_request(add_cors)
|
||||||
app.run()
|
app.run()
|
||||||
|
|
86
web/List.vue
86
web/List.vue
|
@ -128,13 +128,13 @@
|
||||||
},
|
},
|
||||||
props: ["channel"],
|
props: ["channel"],
|
||||||
computed: {
|
computed: {
|
||||||
channelData: function () {
|
channelData: function() {
|
||||||
return this.channels[this.channel];
|
return this.channels[this.channel];
|
||||||
},
|
},
|
||||||
momentDate: function () {
|
momentDate: function() {
|
||||||
return moment(this.date);
|
return moment(this.date);
|
||||||
},
|
},
|
||||||
popular: function () {
|
popular: function() {
|
||||||
function compare(a, b) {
|
function compare(a, b) {
|
||||||
if (a.order < b.order)
|
if (a.order < b.order)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -149,22 +149,24 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getChannels: function () {
|
getChannels: function() {
|
||||||
let vm = this;
|
|
||||||
axios.get(baseURL, {
|
axios.get(baseURL, {
|
||||||
params: {}
|
params: {}
|
||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(response => {
|
||||||
vm.channels = response.data;
|
const all = response.data["all"];
|
||||||
document.title = "Radiostats - " + vm.channels[vm.channel].stationname;
|
this.channels = response.data;
|
||||||
vm.getPopular();
|
delete response.data["all"];
|
||||||
|
response.data["all"]=all;
|
||||||
|
document.title = "Radiostats - " + this.channels[this.channel].stationname;
|
||||||
|
this.getPopular();
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(error => {
|
||||||
vm.httpError = error;
|
this.httpError = error;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getPopular: function () {
|
getPopular: function() {
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
this.showMore = true;
|
this.showMore = true;
|
||||||
this.httpError = false;
|
this.httpError = false;
|
||||||
|
@ -201,40 +203,38 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(error => {
|
||||||
vm.httpError = error;
|
this.httpError = error;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getAdditional: function () {
|
getAdditional: function() {
|
||||||
let vm = this;
|
|
||||||
|
|
||||||
axios.get(baseURL + this.channel, {
|
axios.get(baseURL + this.channel, {
|
||||||
params: {
|
params: {
|
||||||
offset: vm.offset,
|
offset: this.offset,
|
||||||
date: vm.momentDate.format("YYYY-MM-DD"),
|
date: this.momentDate.format("YYYY-MM-DD"),
|
||||||
dateType: vm.dateType
|
dateType: this.dateType
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(response => {
|
||||||
vm.offset += 10;
|
this.offset += 10;
|
||||||
vm.songs = Object.assign({}, vm.songs, response.data);
|
this.songs = Object.assign({}, this.songs, response.data);
|
||||||
if (Object.keys(response.data).length < 10) {
|
if (Object.keys(response.data).length < 10) {
|
||||||
vm.showMore = false;
|
this.showMore = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(error => {
|
||||||
vm.httpError = error;
|
this.httpError = error;
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
icon: function (id) {
|
icon: function(id) {
|
||||||
if (id === "fm4" || id === "oe3" || id === "kht") {
|
if (id === "fm4" || id === "oe3" || id === "kht") {
|
||||||
return id + ".svg";
|
return id + ".svg";
|
||||||
} else {
|
} else {
|
||||||
return id + ".png";
|
return id + ".png";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateSelection: function () {
|
updateSelection: function() {
|
||||||
let from, to;
|
let from, to;
|
||||||
let date = moment(this.date);
|
let date = moment(this.date);
|
||||||
if (this.dateType !== "alltime") {
|
if (this.dateType !== "alltime") {
|
||||||
|
@ -251,7 +251,7 @@
|
||||||
"to": to.toDate(),
|
"to": to.toDate(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
formatDate: function () {
|
formatDate: function() {
|
||||||
switch (this.dateType) {
|
switch (this.dateType) {
|
||||||
case "day":
|
case "day":
|
||||||
return "am " + this.momentDate.format("D. MMMM");
|
return "am " + this.momentDate.format("D. MMMM");
|
||||||
|
@ -263,10 +263,10 @@
|
||||||
return "im gesamten Zeitraum";
|
return "im gesamten Zeitraum";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toogleVisibility: function () {
|
toogleVisibility: function() {
|
||||||
this.showDate = !this.showDate;
|
this.showDate = !this.showDate;
|
||||||
},
|
},
|
||||||
toogleDetails: function ($event, songId) {
|
toogleDetails: function($event, songId) {
|
||||||
if (this.$route.name !== "DetailView" || this.$route.params.songId !== songId) {
|
if (this.$route.name !== "DetailView" || this.$route.params.songId !== songId) {
|
||||||
this.$router.replace({name: 'DetailView', params: {channel: this.channel, songId: songId}});
|
this.$router.replace({name: 'DetailView', params: {channel: this.channel, songId: songId}});
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,24 +275,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
channel: function () {
|
channel: function() {
|
||||||
document.title = "Radiostats - " + this.channelData.stationname;
|
document.title = "Radiostats - " + this.channelData.stationname;
|
||||||
this.getPopular();
|
this.getPopular();
|
||||||
},
|
},
|
||||||
'$route.name': function (id) {
|
'$route.name': function(id) {
|
||||||
document.title = "Radiostats - " + this.channelData.stationname;
|
document.title = "Radiostats - " + this.channelData.stationname;
|
||||||
},
|
},
|
||||||
dateType: function () {
|
dateType: function() {
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
this.getPopular();
|
this.getPopular();
|
||||||
},
|
},
|
||||||
date: function () {
|
date: function() {
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
this.getPopular();
|
this.getPopular();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function() {
|
||||||
this.getChannels();
|
this.getChannels();
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
}
|
}
|
||||||
|
@ -314,20 +314,24 @@
|
||||||
header {
|
header {
|
||||||
padding: 2.5rem;
|
padding: 2.5rem;
|
||||||
transition: color .2s, background-color .2s;
|
transition: color .2s, background-color .2s;
|
||||||
|
|
||||||
h2, div {
|
h2, div {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 3.0rem;
|
font-size: 3.0rem;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 18.66px;
|
height: 18.66px;
|
||||||
transition: transform .3s;
|
transition: transform .3s;
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
|
|
||||||
|
@ -351,19 +355,23 @@
|
||||||
margin: 10px 10px;
|
margin: 10px 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
/*border-bottom: solid 5px;*/
|
/*border-bottom: solid 5px;*/
|
||||||
|
|
||||||
&.router-link-active {
|
&.router-link-active {
|
||||||
border-bottom: solid 5px;
|
border-bottom: solid 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
display: block;
|
display: block;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
transition: filter .2s;
|
transition: filter .2s;
|
||||||
|
|
||||||
&.noData:not(:hover) {
|
&.noData:not(:hover) {
|
||||||
filter: grayscale(0.7);
|
filter: grayscale(0.7);
|
||||||
}
|
}
|
||||||
|
@ -373,12 +381,14 @@
|
||||||
|
|
||||||
table {
|
table {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
img, .imgPlaceholder {
|
img, .imgPlaceholder {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.clickable {
|
tr.clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -390,6 +400,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color .2s;
|
transition: background-color .2s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
|
@ -410,6 +421,7 @@
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
> div {
|
> div {
|
||||||
.vdp-datepicker {
|
.vdp-datepicker {
|
||||||
|
@ -425,10 +437,12 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
padding: 0 15px !important;
|
padding: 0 15px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
> div {
|
> div {
|
||||||
|
|
BIN
web/icons/all.png
Normal file
BIN
web/icons/all.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
12
web/main.js
12
web/main.js
|
@ -5,11 +5,13 @@ import router from './routes';
|
||||||
import MatomoTracker from './MatomoTracker';
|
import MatomoTracker from './MatomoTracker';
|
||||||
import {init, Integrations} from '@sentry/browser';
|
import {init, Integrations} from '@sentry/browser';
|
||||||
|
|
||||||
init({
|
if (process.env.NODE_ENV === "production") {
|
||||||
dsn: 'https://91af780499634f98a17afe160c6ace89@sentry.lw1.at/12',
|
init({
|
||||||
integrations: [new Integrations.Vue({Vue})],
|
dsn: 'https://91af780499634f98a17afe160c6ace89@sentry.lw1.at/12',
|
||||||
release: COMMIT_HASH
|
integrations: [new Integrations.Vue({Vue})],
|
||||||
});
|
release: COMMIT_HASH
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Vue.use(VueHead);
|
Vue.use(VueHead);
|
||||||
let matomo = new MatomoTracker;
|
let matomo = new MatomoTracker;
|
||||||
|
|
Loading…
Reference in a new issue