zwischenstand
This commit is contained in:
parent
3222c2d77f
commit
ac3674555c
6 changed files with 271 additions and 87 deletions
|
@ -23,6 +23,10 @@ class Directory:
|
|||
else:
|
||||
self.displayname = name
|
||||
|
||||
def to_dict(self):
|
||||
return {'name': self.name , 'displayname': self.displayname, 'count': self.item_count }
|
||||
|
||||
|
||||
|
||||
def mk_writeable_dir(path):
|
||||
try:
|
||||
|
|
|
@ -149,7 +149,7 @@ def landing_api(path):
|
|||
if category.endswith('language'):
|
||||
language = request.args.get('language','german')
|
||||
stations = radiobrowser.get_stations_by_language(language)
|
||||
if category.endswith('countrycode'):
|
||||
if category.endswith('country'):
|
||||
country = request.args.get('country','Germany')
|
||||
stations = radiobrowser.get_stations_by_country(country)
|
||||
|
||||
|
@ -163,7 +163,26 @@ def landing_api(path):
|
|||
if path.endswith('bookmarks'):
|
||||
category = request.args.get('category')
|
||||
stations = my_stations.get_stations_by_category(category)
|
||||
return flask.jsonify({'stations': stations})
|
||||
if stations is not None:
|
||||
stations_dict = []
|
||||
for station in stations:
|
||||
stations_dict.append(station.to_dict())
|
||||
return flask.jsonify(stations_dict)
|
||||
|
||||
if path.endswith('paramlist'):
|
||||
category = request.args.get('category')
|
||||
directories = None
|
||||
if category.endswith('language'):
|
||||
directories = radiobrowser.get_language_directories();
|
||||
if category.endswith('country'):
|
||||
directories = radiobrowser.get_country_directories();
|
||||
if directories is not None:
|
||||
directories_dict = []
|
||||
for directory in directories:
|
||||
directories_dict.append(directory.to_dict())
|
||||
return flask.jsonify(directories_dict)
|
||||
|
||||
|
||||
return abort(400,'Not implemented: ' + path)
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,28 @@
|
|||
function createItem(name, icon, description) {
|
||||
window.onload = function () {
|
||||
category = document.getElementById('id_category').value;
|
||||
param = document.getElementById('id_param').value;
|
||||
requestStationList(category, param)
|
||||
|
||||
}
|
||||
|
||||
function initSearch() {
|
||||
var stationsearch = document.getElementById('stationsearch');
|
||||
stationsearch.value = '';
|
||||
stationsearch.onkeyup = function () {
|
||||
var filter = stationsearch.value.toUpperCase();
|
||||
var lis = document.getElementsByTagName('li');
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
var searchval = lis[i].dataset.search;
|
||||
if (searchval.indexOf(filter) > -1)
|
||||
lis[i].style.display = 'flex';
|
||||
else
|
||||
lis[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createItem(name, icon, description) {
|
||||
|
||||
var itemElem = document.createElement("div");
|
||||
itemElem.className = "item";
|
||||
|
||||
|
@ -7,16 +30,17 @@ function createItem(name, icon, description) {
|
|||
itemicon.className = "itemicon";
|
||||
var itemiconimg = document.createElement("img");
|
||||
itemiconimg.src = icon;
|
||||
itemiconimg.className = "itemicon";
|
||||
|
||||
var itemtext = document.createElement("div");
|
||||
itemtext.className = "itemtext";
|
||||
var h4text = document.createElement("h4");
|
||||
var h4text = document.createElement("h4");
|
||||
h4text.textContent = name;
|
||||
var desc = document.createElement("p");
|
||||
desc.textContent = description;
|
||||
|
||||
|
||||
itemicon.appendChild(itemiconimg);
|
||||
|
||||
|
||||
itemtext.appendChild(h4text);
|
||||
itemtext.appendChild(desc);
|
||||
|
||||
|
@ -26,11 +50,102 @@ function createItem(name, icon, description) {
|
|||
return itemElem;
|
||||
}
|
||||
|
||||
function stationsAddItem() {
|
||||
var listElemet = document.createElement("li");
|
||||
listElemet.className = "item";
|
||||
listElemet.appendChild(createItem(" Halle self created","http://www.klassikradio.de/_nuxt/icons/icon_64.a00w80w0000.png","classic, poppi"));
|
||||
function requestStationList(category, param) {
|
||||
var url = 'api/stations?category=' + category;
|
||||
|
||||
document.getElementById("stationList").appendChild(listElemet);
|
||||
if (category.indexOf('language') > -1) {
|
||||
url = url + '&language=' + param.toLowerCase();
|
||||
}
|
||||
if (category.indexOf('country') > -1) {
|
||||
url = url + '&country=' + param;
|
||||
}
|
||||
var myRequest = new Request(url);
|
||||
var myOldList = document.getElementById("stationList");
|
||||
|
||||
var myList = myOldList.cloneNode(false);
|
||||
myOldList.parentNode.replaceChild(myList, myOldList);
|
||||
|
||||
fetch(myRequest)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
for (const station of data) {
|
||||
let listItem = document.createElement('li');
|
||||
listItem.appendChild(
|
||||
createItem(station.name, station.icon, station.description)
|
||||
);
|
||||
listItem.dataset.json = JSON.stringify(station);
|
||||
listItem.dataset.search = (station.name + '#' + station.description).toUpperCase();
|
||||
myList.appendChild(listItem);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
initSearch();
|
||||
}
|
||||
|
||||
function onInputSelect(e, objElem) {
|
||||
|
||||
if (objElem.id == 'id_category') {
|
||||
paramElem = document.getElementById('id_param')
|
||||
param = paramElem.value
|
||||
category = objElem.value
|
||||
switch (category) {
|
||||
case 'language':
|
||||
setParamlist();
|
||||
try {paramElem.fokus();} catch(e) {};
|
||||
return;
|
||||
case 'country':
|
||||
setParamlist();
|
||||
try {paramElem.fokus();} catch(e) {};
|
||||
return;
|
||||
default:
|
||||
paramElem.disabled = true;
|
||||
break;
|
||||
}
|
||||
requestStationList(category, param);
|
||||
}
|
||||
}
|
||||
|
||||
function setParamlist() {
|
||||
var category = document.getElementById('id_category').value
|
||||
var url = 'api/paramlist?category=' + category;
|
||||
document.getElementById('id_param').value = '';
|
||||
var myRequest = new Request(url);
|
||||
var myOldList = document.getElementById('paramlist');
|
||||
|
||||
var myList = myOldList.cloneNode(false);
|
||||
myOldList.parentNode.replaceChild(myList, myOldList);
|
||||
|
||||
|
||||
fetch(myRequest)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
for (const param of data) {
|
||||
var option = document.createElement('option');
|
||||
option.value = param.name;
|
||||
myList.appendChild(option);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
document.getElementById('id_param').disabled = false;
|
||||
}
|
||||
|
||||
function keyUpEvent(e, objElem) {
|
||||
switch (objElem.id) {
|
||||
case 'id_param':
|
||||
param = objElem.value;
|
||||
category = document.getElementById('id_category').value;
|
||||
if (e instanceof KeyboardEvent) {
|
||||
// it is a keyboard event!
|
||||
if (e.code == 'Enter') {
|
||||
requestStationList(category, param);
|
||||
} else if (e.code == 'Backspace')
|
||||
this.value = '';
|
||||
} else if (e instanceof Event) {
|
||||
// one Element from selection is selected
|
||||
requestStationList(category, param);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,61 +1,78 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page {
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
height = 30rem;
|
||||
width: 90%;
|
||||
height=30rem;
|
||||
width: 38.9rem;
|
||||
margin: 0rem;
|
||||
background-color: blue;
|
||||
color: white;
|
||||
text-align: center;
|
||||
border: 4px #eee solid;
|
||||
min-width: 20rem;
|
||||
max-width: 40rem;
|
||||
padding: 0.5rem
|
||||
}
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: auto;
|
||||
bottom: 0rem;
|
||||
background-color: aquamarine;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
border: 2px #eee solid;
|
||||
width: 45%;
|
||||
display: block;
|
||||
width: 20rem;
|
||||
min-width: 20rem;
|
||||
float: left;
|
||||
margin: 0rem;
|
||||
height: 20rem;
|
||||
height: calc(100% - 13rem);
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
.contentheader {
|
||||
display: block;
|
||||
background-color: blue;
|
||||
color: white;
|
||||
align-items: center;
|
||||
margin: 0rem;
|
||||
padding: 0.2rem;
|
||||
border: 2px #eee solid;
|
||||
height: 5rem;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.contentitems {
|
||||
position: absolute;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
top: 6rem;
|
||||
width: 100%;
|
||||
height: calc(100% - 20rem);
|
||||
max-height: 30rem;
|
||||
border: 2px #eee solid ;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
border: 2px #eee solid;
|
||||
margin: 0rem;
|
||||
display: flex;
|
||||
height: 2.4rem;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background-color: beige;
|
||||
}
|
||||
background-color: beige;
|
||||
}
|
||||
|
||||
.itemicon {
|
||||
height: 2.4rem;
|
||||
|
@ -63,7 +80,9 @@ body {
|
|||
}
|
||||
|
||||
.itemtext {
|
||||
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
@ -73,16 +92,23 @@ ul {
|
|||
width: 100%;
|
||||
display: contents;
|
||||
}
|
||||
|
||||
li {
|
||||
width: 95%;
|
||||
padding: 0rem;
|
||||
margin: 0rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding: 0rem;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border: 2px #eee solid;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
margin: 0rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
|
@ -90,13 +116,16 @@ h4 {
|
|||
padding-left: 1rem;
|
||||
margin: auto
|
||||
}
|
||||
|
||||
p {
|
||||
padding-left: 1.1rem;
|
||||
margin: auto;
|
||||
font-size: 0.8rem;
|
||||
|
||||
|
||||
}
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
padding-left: 1.1rem;
|
||||
}
|
||||
|
||||
input
|
||||
|
|
|
@ -1,56 +1,72 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="../static/style.css">
|
||||
<script type="text/javascript"
|
||||
src="../static/script.js"></script> <title>YCast</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script type="text/javascript" src="/static/script.js"></script>
|
||||
<title>YCast</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>Hallo YCast</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentheader" onclick="stationsAddItem()">
|
||||
<h3>Stations</h3>
|
||||
<div class="page">
|
||||
<div class="header">
|
||||
<h2>YCast advanced</h2>
|
||||
<div>
|
||||
<label for="id_category">station-source:</label>
|
||||
<select tabindex="1" id="id_category" name="category" oninput="onInputSelect(event, this)">
|
||||
<option value="recently">recently</option>
|
||||
<option value="voted">voted</option>
|
||||
<option value="language">language</option>
|
||||
<option value="country">country</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_param">language or country:</label>
|
||||
<input tabindex="2" list="paramlist" id="id_param" autocomplete=off disabled=true onclick="this.value=''" onfocus="this.value=''" onkeyup="keyUpEvent(event,this)">
|
||||
<datalist id="paramlist">
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentheader">
|
||||
<h3 onclick="stations_request()">Stations</h3>
|
||||
<label for="stationsearch">search:</label>
|
||||
<input tabindex="3" type="search" id="stationsearch">
|
||||
</div>
|
||||
<div class="contentitems">
|
||||
<ul id="stationList">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentheader">
|
||||
<h3>Bookmarks</h3>
|
||||
<label for="idCategory">category:</label>
|
||||
<input tabindex="10000" list="category" id="idCategory">
|
||||
<datalist id="category">
|
||||
<option value="Actual">
|
||||
<option value="Pop">
|
||||
<option value="Classics">
|
||||
</datalist>
|
||||
|
||||
</div>
|
||||
<div class="contentitems">
|
||||
<ul id="bookmarkList">
|
||||
<li class="item">
|
||||
<div class="itemicon">
|
||||
<img class="itemicon" src="http://www.klassikradio.de/_nuxt/icons/icon_64.a00w80w0000.png">
|
||||
</div>
|
||||
<div class="itemtext">
|
||||
<h4>Radio</h4>
|
||||
<p>ard,actuell</p>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contentitems">
|
||||
<ul id="stationList">
|
||||
<li class="item">
|
||||
<div class="itemicon">
|
||||
<img src="http://www.klassikradio.de/_nuxt/icons/icon_64.a00w80w0000.png">
|
||||
</div>
|
||||
<div class="itemtext">
|
||||
<h4>Radio</h4>
|
||||
<p>ard,actuell</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item">
|
||||
<div class="itemicon">
|
||||
<img src="http://wgbh.org//apple-touch-icon.png">
|
||||
</div>
|
||||
<div class="itemtext">
|
||||
<h4>Radio</h4>
|
||||
<p>ard,actuell</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentheader"><h3>Bookmarks</h3></div>
|
||||
<ul>
|
||||
<li class="item">
|
||||
<div class="itemicon">
|
||||
<img src="http://www.klassikradio.de/_nuxt/icons/icon_64.a00w80w0000.png">
|
||||
</div>
|
||||
<div class="itemtext">
|
||||
<h4>Radio</h4>
|
||||
<p>ard,actuell</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -67,6 +67,9 @@ class MyTestCase(unittest.TestCase):
|
|||
assert len(result) == 3
|
||||
|
||||
def test_get_countries(self):
|
||||
generic.init_base_dir('.ycast')
|
||||
my_filter.init_filter_file()
|
||||
|
||||
result = radiobrowser.get_country_directories()
|
||||
assert len(result) == 4
|
||||
|
||||
|
@ -79,8 +82,6 @@ class MyTestCase(unittest.TestCase):
|
|||
assert result == 20
|
||||
|
||||
def test_jsonable_classes(self):
|
||||
generic.init_base_dir('.ycast')
|
||||
my_filter.init_filter_file()
|
||||
stations = radiobrowser.get_stations_by_country('Germany')
|
||||
station = stations[0]
|
||||
text = station.to_vtuner()
|
||||
|
|
Loading…
Add table
Reference in a new issue