diff --git a/app/mydatabase.db b/app/mydatabase.db index 77ebe0e..4a53692 100644 Binary files a/app/mydatabase.db and b/app/mydatabase.db differ diff --git a/app/static/css/style.css b/app/static/css/style.css index f98f69e..a5ea33e 100755 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -1,9 +1,12 @@ *{ -font-family: "Helvetica" +font-family: "Helvetica"; +box-sizing: border-box; } body{ background-color: #f1f1f1; + font-size: clamp(12px, 1.2vw, 25px); + box-sizing: border-box; } p{ @@ -12,12 +15,27 @@ p{ a{ text-decoration: underline; - color: black; + color: inherit; } a:hover{ - text-decoration: underline; - color: #0000FF; + text-decoration: inherit; + color: inherit; +} + +audio{ + width: 100%; +} + +.navigation ul{ + list-style-type: none; + padding: 0; + display: flex; + justify-content: right; +} + +.navigation ul li{ + padding: 0.5em; } #map { @@ -27,5 +45,162 @@ a:hover{ height: 100vh; width: 100vw; z-index: -1; +} + +.locations_list{ + width: 100%; +} + +.locations_list .row{ + display: flex; + justify-content: space-between; + border-bottom: 1px solid black; +} + + +.locations_list .row div:first-of-type { + width: 5%; +} + +.locations_list .row div:last-of-type{ + width: 10%; + min-width: 3rem; +} + +.locations_list .row div{ + width: 20%; + padding: 1em; + white-space: wrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.locations_list .row div audio{ + width: 100%; +} +.locations_list .row .delete_btn{ + text-decoration: none; + background-color: black; + color: white; + padding: 0.5em; + border-radius: 1em; } + + +/* FROM */ + +.form-control{ + width: 100%; + height: 20vh; + box-sizing: border-box; +} + +#audio{ +margin: 4em 0; +} + +.record_controls{ + display: flex; + justify-content: space-between; +} + +.audio_btn{ + font-size: 2em; + padding: 0.5em; + text-decoration: none; + background-color: black; + border-radius: 2em; + color: white; + margin: 2em 0; + display: block; + box-sizing: border-box; + min-width: 25%; +} + +.audio_btn:hover{ + color: white; +} + +.stop_btn{ + display: none; + flex-grow:1; +} + +.record_btn .icon{ + display: inline-block; + background-color: white; + width: 0.5em; + height: 0.5em; + border-radius: 100%; + margin-right: 0.5em; +} + +.stop_btn .icon{ + display: inline-block; + background-color: white; + width: 0.5em; + height: 0.5em; + margin-right: 0.5em; +} + +.record_btn{ + background-color: red; + flex-grow:1; +} + +.play_btn{ + display: none; + flex-grow: 1; + position: relative; + overflow: hidden; +} + +.play_btn .icon_p{ + display: inline-block; + position: relative; + top: 0px; + left: 3px; + border-style: solid; + border-width: 0.3em 0 0.3em 0.6em; + border-color: transparent transparent transparent white; + + margin-right: 0.5em; + z-index: 99; +} + + +.play_btn .icon_b{ + box-sizing: border-box; + position: relative; + display: inline-block; + /* transform: scale(var(--ggs,1)); */ + width: 0.5em; + height: 0.5em; + border-left: 0.15em solid; + border-right: 0.15em solid; + margin-right: 0.5em; + z-index: 99; +} + +.play_btn .text{ + display: inline-block; + position: relative; + z-index: 99; +} + +.play_btn .progress_bar{ + display: block; + background-color: rgb(115, 115, 115); + position: absolute; + top: 0em; + left: 0em; + border-radius: 2em 2em 2em 2em; + height: 100%; + border-right: 1px solid white; + z-index: 0; +} + +.redo_btn{ + display: none; +} \ No newline at end of file diff --git a/app/templates/about.html b/app/templates/about.html index 7eba7fc..f45f967 100755 --- a/app/templates/about.html +++ b/app/templates/about.html @@ -3,26 +3,7 @@ {% block main %}

About

-

-XPPL is a project aimed at people who are studying the field of media culture, or as we like to call them: knowledge comrades. -
-
-This digital library gathers all the books and articles floating around on the shelves of the Piet Zwart Institute, and our hard drives and memory sticks, so that they can be shared, annotated and grouped together into stacks... Its web interface hosts a curated catalogue of books and articles, and its distributed architecture provides instances for uploading and downloading. -
-
- It starts at XPUB, but can go anywhere we want it to. -
-
-Are you interested in how this library works? Have a look at the source code in our git. -

-

What's the deal with the stacks?

-

- A stack is a number of books that are read at a certain point in time, alternating between them. They usually have a topic in common, or follow a certain study path that can bring you to a point of knowledge. Rather than a bookshelf, where books are lined up and often forgotten, the stack on your table/nightstand/toilet consists of books prone to be opened and reopened at any time. -

-

Who's behind this?

-

-We're Angeliki, Alex, Alice, Joca, Natasha and Zalán, helped and supported by Femke, Aymeric, Michael, Steve, Andre, Leslie and many more. XPUB is a study path within the Piet Zwart Institute masters program. -

+

About

{% endblock %} diff --git a/app/templates/addaudio.html b/app/templates/addaudio.html index 3ad2f89..8a031d7 100755 --- a/app/templates/addaudio.html +++ b/app/templates/addaudio.html @@ -3,7 +3,7 @@ {% block main %} {% from "_formhelpers.html" import render_field %} -

Add Message

+

Add Audio

{% with messages = get_flashed_messages() %} {% if messages %}
@@ -20,18 +20,24 @@ {{ form.csrf_token }} -
- message: {{ form.message(cols="45", rows="10", class="form-control") }} -
+
- record - stop - seconds +
+ record + stop + play + redo + +
-
+
+ +
+ message:
{{ form.message(class="form-control") }} +
@@ -48,26 +54,32 @@ var mediaRecorder; var seconds_rec = 0; var seconds_int; +var audio; +var state = "empty"; function record_audio(){ - seconds_int = setInterval( - function () { - document.getElementById("seconds_rec").innerHTML = seconds_rec; - seconds_rec += 1; - }, 1000); - + if(state == "empty"){ navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { mediaRecorder = new MediaRecorder(stream); mediaRecorder.start(); + state = "recording"; + document.getElementById('stop_btn').style.display = 'block' + + seconds_int = setInterval( + function () { + document.getElementById("record_btn").innerHTML = seconds_rec + " s"; + seconds_rec += 1; + }, 1000); + const audioChunks = []; mediaRecorder.addEventListener("dataavailable", event => { audioChunks.push(event.data); }); mediaRecorder.addEventListener("stop", () => { - const audioBlob = new Blob(audioChunks); + const audioBlob = new Blob(audioChunks, {type: 'audio/mpeg'}); const audioUrl = URL.createObjectURL(audioBlob); var sound = document.createElement('audio'); sound.id = 'audio-player'; @@ -75,32 +87,68 @@ navigator.mediaDevices.getUserMedia({ audio: true }) sound.src = audioUrl; console.log(audioUrl) sound.type = 'audio/mpeg'; - document.getElementById("audio-player-container").innerHTML = sound.outerHTML; + // document.getElementById("audio-player-container").innerHTML = sound.outerHTML; + + audio = new Audio(audioUrl); + audio.addEventListener("ended", function(){ + audio.currentTime = 0; + document.getElementById("play_btn").innerHTML = 'play' + }); + audio.addEventListener("timeupdate", function() { + var currentTime = audio.currentTime; + var duration = audio.duration; + $('.progress_bar').stop(true,true).animate({'width':(currentTime +.25)/duration*100+'%'},0,'linear'); + }); + + + document.getElementById('play_btn').style.display = 'block' + document.getElementById('redo_btn').style.display = 'block' + document.getElementById('stop_btn').style.display = 'none' + document.getElementById("record_btn").innerHTML = "recording…"; + document.getElementById('record_btn').style.display = 'none' + - const audio = new Audio(audioUrl); //audio.play(); let file = new File([audioBlob], "audio.mp3",{type:"audio/mpeg"}); let container = new DataTransfer(); container.items.add(file); document.getElementById("uploadedFile").files = container.files; - - //const audio = new Audio(audioUrl); - //audio.play(); + }); setTimeout(() => { stop_audio() }, 1000 * 60); }); - +} } function stop_audio(){ clearInterval(seconds_int); mediaRecorder.stop(); +} - +function redo_audio(){ + state = "empty"; + seconds_rec = 0; + document.getElementById('play_btn').style.display = 'none' + document.getElementById('redo_btn').style.display = 'none' + document.getElementById('stop_btn').style.display = 'block' + document.getElementById('record_btn').style.display = 'block' + record_audio() +} + +function play_audio(){ + if(audio.paused){ + audio.play(); + document.getElementById("play_btn").innerHTML = 'pause' + } + else{ + audio.pause(); + document.getElementById("play_btn").innerHTML = 'play' + + } } diff --git a/app/templates/header.html b/app/templates/header.html index ea8947a..c48ac39 100755 --- a/app/templates/header.html +++ b/app/templates/header.html @@ -1,8 +1,8 @@ diff --git a/app/templates/home.html b/app/templates/home.html index 31e7346..e039daf 100755 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -7,22 +7,11 @@ - - -


- -{% for location in locations %} - -
{{location.id}}: {{location.longitude}}, {{location.latitude}} {{location.message if location.loc_type == "message"}} - {% if location.loc_type == "audio" %} - - {% endif %} - delete
- -{% endfor %} -
+ + + {% endblock main %} {% block js %} @@ -41,21 +30,16 @@ attributionControl:false, scrollWheelZoom: false, zoom: 2000 - }).setView([48.505, 1.09], 10); - - - L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 19, - zoom:2, - attribution: '© OpenStreetMap' - }).addTo(map); - + }).setView([48.505, 1.09], 16); + // L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { + // maxZoom: 19, + // zoom:2, + // attribution: '© OpenStreetMap' + // }).addTo(map); locations.forEach(function (item, index) { - - try { var circle = L.circle([item.latitude, item.longitude], { color: 'red', diff --git a/app/templates/list.html b/app/templates/list.html new file mode 100755 index 0000000..0ec81c9 --- /dev/null +++ b/app/templates/list.html @@ -0,0 +1,33 @@ +{% extends "base.html" %} + +{% block main %} +
+

Index

+ +
+ {% for location in locations %} +
+
{{location.id}}
+
{{location.longitude}}, {{location.latitude}}
+
{{location.message if location.loc_type == "message"}}
+
+ {% if location.loc_type == "audio" %} + + {% endif %} +
+
+ delete +
+
+ {% endfor %} +
+
+ +{% endblock main %} +{% block js %} + + + +{% endblock js %} \ No newline at end of file diff --git a/app/views.py b/app/views.py index 4e62520..326da1d 100755 --- a/app/views.py +++ b/app/views.py @@ -52,20 +52,20 @@ def uploaded_file(filename): @app.route('/', methods= ['POST','GET']) def home(): - - username = 'librarian' server = request.host - if request.environ.get('HTTP_X_FORWARDED_FOR') is None: - client =request.environ['REMOTE_ADDR'] - else: - client = request.environ['HTTP_X_FORWARDED_FOR'] + locations = db.session.query(Location).all() + serialized = [location_schema.dump(location) for location in locations] + return render_template('home.html',domain=DOMAIN, server=server, locations = locations, data_locations = serialized) + +@app.route('/listlocations', methods= ['POST','GET']) +def list_locations(): locations = db.session.query(Location).all() serialized = [location_schema.dump(location) for location in locations] - print(locations) + return render_template('list.html',domain=DOMAIN, locations = locations, data_locations = serialized) + - return render_template('home.html',domain=DOMAIN, server=server, locations = locations, data_locations = serialized) @app.route('/hello/') def hello(name): @@ -138,7 +138,10 @@ def addaudio(): return render_template('addaudio.html', form=upload_form, longitude=longitude, latitude=latitude) - +@app.route('/about/') +def about(): + """Render the website's about page.""" + return render_template('about.html') @app.route('/location//delete', methods=['POST', 'GET']) def delete_location(id): diff --git a/run.py b/run.py index 61f7a27..df06e09 100755 --- a/run.py +++ b/run.py @@ -1,3 +1,3 @@ #! /usr/bin/env python from app import app, socketio -socketio.run(app,host="0.0.0.0", port=8080) +socketio.run(app,host="0.0.0.0", port=8080, ssl_context='adhoc')