From 389f9b71cbfe5e692f9662295e80199fd1fba284 Mon Sep 17 00:00:00 2001 From: Alexander Roidl Date: Fri, 4 Nov 2022 07:48:05 +0100 Subject: [PATCH] added upload and messages --- .DS_Store | Bin 8196 -> 8196 bytes Dockerfile | 7 ++ app/.DS_Store | Bin 0 -> 6148 bytes app/forms.py | 35 +++---- app/models.py | 11 +- app/olddata.db | 0 app/templates/_formhelpers.html | 12 +++ app/templates/add_book.html | 129 ----------------------- app/templates/addaudio.html | 108 ++++++++++++++++++++ app/templates/addtext.html | 33 ++++++ app/templates/base.html | 136 +----------------------- app/templates/home.html | 176 +++++++++++++++++++++++++++++++- app/views.py | 66 +++++++++++- main.py | 1 + requirements.txt | 13 +++ run.py | 2 +- start.sh | 6 ++ uwsgi.ini | 5 + 18 files changed, 450 insertions(+), 290 deletions(-) create mode 100644 Dockerfile create mode 100644 app/.DS_Store create mode 100644 app/olddata.db create mode 100644 app/templates/_formhelpers.html delete mode 100755 app/templates/add_book.html create mode 100755 app/templates/addaudio.html create mode 100755 app/templates/addtext.html create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 start.sh create mode 100644 uwsgi.ini diff --git a/.DS_Store b/.DS_Store index 90c6f1b9642e5bb7fed810db19abaceb7e64afe8..3b02fa6525b4518cf38c928242834d34512cb9cd 100644 GIT binary patch delta 159 zcmZp1XmOa3$h;$|U}NDl_K6L=o7p*}IFx|=oXp}91A}XfOw25-Z0sED9NZkS!5R7G z!6k_$rNvH@0|mT&I5{}u1thAg&5TTR6ikgwYjqT=EzFH|6if^)Yil_n?H`IdkT`(}2DZ!DYNh_EvQ0O5Bk A8UO$Q diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4c71317 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM tiangolo/uwsgi-nginx-flask:python3.8-alpine +RUN apk --update add bash nano +ENV STATIC_URL /static +ENV STATIC_PATH /var/www/app/static +COPY ./requirements.txt /var/www/requirements.txt +RUN pip install -r /var/www/requirements.txt + diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9806897eddffa978635136b2f221b2e51a230aef GIT binary patch literal 6148 zcmeHK%}T>S5T0$TO({YT3Oz1(E!fu9AH0NGU%-eSRBA$s24l7~tv!@N&iX<=iO=KA z?gp&(;7P>J!0tCYKf9R^vOfSIdeg84Py+x58=)X&g^+ort6+l(g`UHQ5Yk|lj)Hi_ zM1Rpl-(H3(j35RDpT1uO=y?l9ag&zQ%~h0yYSvTJBusU#XBa7Dix;~S?L`Z@RVE8{$N<^1s?^y+ArIvj*+kb7o;8CYhZXofX9 z|IhH3S^3CcPT>(VzzqB|21Kdv^?O*9JzKw(M`x|Xc886G;xbZDP+z(P;DGj#x^^1B bBpu^ii1h3q;VkuL(85bl_PUtr(^z!yxb literal 0 HcmV?d00001 diff --git a/app/forms.py b/app/forms.py index 9a3d0aa..7170ad2 100755 --- a/app/forms.py +++ b/app/forms.py @@ -6,33 +6,26 @@ from wtforms import Form as NoCsrfForm from wtforms.fields import StringField, FormField, SubmitField, SelectField, RadioField from app.models import Location, LocationSchema from wtforms.fields import DecimalRangeField +from wtforms.widgets import TextArea # - - - Forms - - - # class AuthorForm(NoCsrfForm): -# # this forms is never exposed so we can user the non CSRF version +# # this forms is never exposed so we can use the non CSRF version # author_name = StringField('Author Name', validators=[DataRequired()]) -# class UploadForm(FlaskForm): -# title = StringField('title', validators=[InputRequired()]) -# author = FieldList(FormField(AuthorForm, default=lambda: Author()), min_entries=1) -# category = StringField('category', validators=[InputRequired()]) -# year_published = StringField('year published', [validators.Length(max=4)],default=None) -# file = FileField() -# upload = SubmitField(label='Upload') -# wish = SubmitField(label='''I don't have the file, but wish I did.''') -# message = StringField('message', default=None) -# sameness = DecimalRangeField('sameness', default=0) -# diversity = DecimalRangeField('diversity', default=0) -# gender = DecimalRangeField('gender', default=50) -# choices = [('Student', 'Student'), -# ('Librarian', 'Librarian'), -# ('Pirate', 'Pirate'), -# ('Teacher', 'Teacher'), -# ('Institution', 'Institution'), -# ('All of the above', 'All of the above'), -# ('None of the above', 'None of the above')] -# who = SelectField('', choices=choices, default='Student') +class UploadText(FlaskForm): + message = StringField('message', widget=TextArea(), default=None) + longitude = DecimalRangeField('longitude', default=0) + latitude = DecimalRangeField('latitude', default=0) + + +class UploadAudio(FlaskForm): + message = StringField('message', widget=TextArea(), default=None) + audio = FileField() + longitude = DecimalRangeField('longitude', default=0) + latitude = DecimalRangeField('latitude', default=0) + # class EditForm(FlaskForm): diff --git a/app/models.py b/app/models.py index 297d88c..1d55dcc 100755 --- a/app/models.py +++ b/app/models.py @@ -25,6 +25,9 @@ class Location(db.Model): id = db.Column(db.Integer, primary_key = True) longitude = db.Column(db.Numeric(10,8)) latitude = db.Column(db.Numeric(10,8)) + loc_type = db.Column(db.String(200)) + message = db.Column(db.String(4000)) + audio = db.Column(db.String(255)) # title = db.Column(db.String(255)) # file = db.Column(db.String(255)) @@ -50,9 +53,12 @@ class Location(db.Model): # who = db.Column(db.String(255)) - def __init__(self, longitude, latitude): + def __init__(self, longitude, latitude, loc_type, message, audio): self.longitude = longitude self.latitude = latitude + self.loc_type = loc_type + self.message = message + self.audio = audio # def __repr__(self): # return '' % self.title @@ -66,6 +72,9 @@ class LocationSchema(Schema): id = fields.Int(dump_only=True) longitude = fields.Float() latitude = fields.Float() + loc_type = fields.String() + message = fields.String() + audio = fields.String() def must_not_be_blank(data): diff --git a/app/olddata.db b/app/olddata.db new file mode 100644 index 0000000..e69de29 diff --git a/app/templates/_formhelpers.html b/app/templates/_formhelpers.html new file mode 100644 index 0000000..01adf81 --- /dev/null +++ b/app/templates/_formhelpers.html @@ -0,0 +1,12 @@ +{% macro render_field(field) %} + <dt>{{ field.label }} + <dd>{{ field(**kwargs)|safe }} + {% if field.errors %} + <ul class=errors> + {% for error in field.errors %} + <li>{{ error }}</li> + {% endfor %} + </ul> + {% endif %} + </dd> +{% endmacro %} diff --git a/app/templates/add_book.html b/app/templates/add_book.html deleted file mode 100755 index c49bd2c..0000000 --- a/app/templates/add_book.html +++ /dev/null @@ -1,129 +0,0 @@ -{% extends 'base.html' %} - -{% block main %} -{% from "_formhelpers.html" import render_field %} - -<head> -<script> -function outputUpdate(sameness) { - document.querySelector('#selected-sameness').value = sameness; -} -function outputUpdate2(diversity) { - document.querySelector('#selected-diversity').value = diversity; -} -function outputUpdate3(gender) { - document.querySelector('#selected-gender').value = gender; -} -</script> -</head> -<div class="container" style="float: left; width:50%;"> -<div style="width: 98%; border-right: dashed; border-width: 1px;"> - - <h1 class="page-header">Add Book</h1> - {% with messages = get_flashed_messages() %} - {% if messages %} - <div class="alert alert-danger"> - <ul> - {% for message in messages %} - <li>{{ message }}</li> - {% endfor %} - </ul> - </div> - {% endif %} - {% endwith %} - <form method="POST" action="{{ url_for('add_book') }}" enctype=multipart/form-data> - {{ form.csrf_token }} - <div class="form-group">Title:* <br> {{ form.title (size=50, class="form-control") }}</div> - <br> - <div data-toggle="fieldset" id="phone-fieldset"> - Author(s):* <button type="button" data-toggle="fieldset-add-row" data-target="#phone-fieldset">+</button> - <table> - <tr> - <th></th> - <th></th> - </tr> - {% for author in form.author %} - <tr data-toggle="fieldset-entry"> - <td>{{ author.author_name (size=50)}}</td> - <td><button type="button" data-toggle="fieldset-remove-row" id="phone-{{loop.index0}}-remove">-</button></td> - </tr> - {% endfor %} - </table> - </div> -<br> - Category:* <br> {{ form.category(size=50, class="form-control") }} <br><br> - Year published: <br> {{ form.year_published(size=8, class="form-control") }} <br><br> - -How different is this item to the rest of the collection? -Or is it more of the same? <br> -{{ form.sameness(min=0, max=100, oninput="outputUpdate(value)") }}   -<span style="color: #d3d3d3;"><output for="sameness" id="selected-sameness">{{ form.sameness.data }} </output> % different</span> - -<br><hr align="left" style="width:96%;"><br> - -Check the bibliography. How diverse are the references in this book? <br> -{{ form.diversity(min=0, max=100, oninput="outputUpdate2(value)") }}   -<span style="color: #d3d3d3;"><output for="diversity" id="selected-diversity">{{ form.diversity.data }} </output> % diverse</span> - -<br><hr align="left" style="width:96%;"><br> - -Check the writing. Who is speaking? Is the voice more often male or female? <br> -{{ form.gender(min=1, max=100, oninput="outputUpdate3(value)") }}   -<span style="color: #d3d3d3;"><output for="diversity" id="selected-gender">{{ form.gender.data }} </output> % female</span> - -<br><hr align="left" style="width:96%;"><br> -Who are you? {{ render_field(form.who) }} - -<br><hr align="left" style="width:96%;"><br> - -<div style="width: 40%;"> - Add a message for future readers: {{ form.message(size=90, class="form-control") }} -<br></div> -<br> - {{ form.file }} - {{ form.upload }} - {{ form.wish }} - - </div> -</form> -</div> -<div> -<table class="library_table" id="table" style="width:30% padding:10px; padding-bottom: 400px;" > - <thead> - <tr id="header" style="height:15px;"> - <th style="width: 10%;"> <h5> Currently in the library </h5></th> - <th style="width: 20%;"></th> - </tr> - </thead> - <tbody> - <tr> - <td> Titles: </td> - <td> {{ books_all }}</td> - </tr> - <tr> - <td> Authors: </td> - <td> {{ authors_all }} </td> - </tr> - <tr> - <td> Categories: </td> - <td> {{ categories|replace('[', '')|replace(']', '') }}</td> - </tr> - <tr> - <td> Stacks: </td> - <td> {{ stacks_all|replace('[', '')|replace(']', '') }}</td> - </tr> - <tr> - <td> From the years: </td> - <td> {{earliest}} –– {{latest}}</td> - </tr> - <tr> - <td> Gaps in the collection: </td> - <td> At least {{ books_potential }} potential books missing</td> - </tr> - -</tbody> - </table> -</div> -</div> -<clear> -{% endblock %} diff --git a/app/templates/addaudio.html b/app/templates/addaudio.html new file mode 100755 index 0000000..600c203 --- /dev/null +++ b/app/templates/addaudio.html @@ -0,0 +1,108 @@ +{% extends 'base.html' %} + +{% block main %} +{% from "_formhelpers.html" import render_field %} + + <h1 class="page-header">Add Message</h1> + {% with messages = get_flashed_messages() %} + {% if messages %} + <div class="alert alert-danger"> + <ul> + {% for message in messages %} + <li>{{ message }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + {% endwith %} + + <form method="POST" action="{{ url_for('addaudio') }}" enctype=multipart/form-data> + {{ form.csrf_token }} + <input type="hidden" name="longitude" value="{{ longitude }}" /> + <input type="hidden" name="latitude" value="{{ latitude }}" /> + <div style="width: 40%;"> + message: {{ form.message(cols="45", rows="10", class="form-control") }} + </div> + + <div id="audio"> + <a onclick="record_audio()" href="#">record</a> + <a onclick="stop_audio()" href="#">stop</a> + <span id="seconds_rec"></span><span> seconds</span> + <div id="audio-player-container"></div> + </div> + + <input type="file" name="file" id="uploadedFile" accept="audio/*"><br> + + <button type="submit">Submit</button> + + + +</form> + +<clear> +{% endblock main %} +{% block js%} + +<script> + +var mediaRecorder; +var seconds_rec = 0; +var seconds_int; + +function record_audio(){ + seconds_int = setInterval( + function () { + document.getElementById("seconds_rec").innerHTML = seconds_rec; + seconds_rec += 1; + }, 1000); + +navigator.mediaDevices.getUserMedia({ audio: true }) + .then(stream => { + mediaRecorder = new MediaRecorder(stream); + mediaRecorder.start(); + + const audioChunks = []; + mediaRecorder.addEventListener("dataavailable", event => { + audioChunks.push(event.data); + }); + + mediaRecorder.addEventListener("stop", () => { + const audioBlob = new Blob(audioChunks); + const audioUrl = URL.createObjectURL(audioBlob); + var sound = document.createElement('audio'); + sound.id = 'audio-player'; + sound.controls = 'controls'; + sound.src = audioUrl; + console.log(audioUrl) + sound.type = 'audio/ogg'; + document.getElementById("audio-player-container").innerHTML = sound.outerHTML; + + + const audio = new Audio(audioUrl); + //audio.play(); + let file = new File([audioBlob], "audio.ogg",{type:"audio/ogg"}); + 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(); + + +} + +</script> + +{% endblock js%} diff --git a/app/templates/addtext.html b/app/templates/addtext.html new file mode 100755 index 0000000..90af30a --- /dev/null +++ b/app/templates/addtext.html @@ -0,0 +1,33 @@ +{% extends 'base.html' %} + +{% block main %} +{% from "_formhelpers.html" import render_field %} + + <h1 class="page-header">Add Message</h1> + {% with messages = get_flashed_messages() %} + {% if messages %} + <div class="alert alert-danger"> + <ul> + {% for message in messages %} + <li>{{ message }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + {% endwith %} + <form method="POST" action="{{ url_for('addtext') }}" enctype=multipart/form-data> + {{ form.csrf_token }} + <input type="hidden" name="longitude" value="{{ longitude }}" /> + <input type="hidden" name="latitude" value="{{ latitude }}" /> + <div style="width: 40%;"> + message: {{ form.message(cols="45", rows="10", class="form-control") }} + </div> + + <button type="submit">Submit</button> + + +</form> + +<clear> +{% endblock main %} + diff --git a/app/templates/base.html b/app/templates/base.html index c2384bd..df52574 100755 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -43,144 +43,12 @@ </div> </footer> - {% block js %} {% endblock%} + <script src="{{ url_for("static", filename="js/jquery-3.3.1.min.js") }}"></script> <script src="{{ url_for("static", filename="js/app.js") }}"></script> +{% block js %} {% endblock%} -<script> - - -var locations; -function assign_data(data) { - console.log(data); - locations = data; -} -assign_data({{ data_locations|tojson }}); - - -var map = L.map('map', {zoomControl:false, - 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: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' -}).addTo(map); - - - - -locations.forEach(function (item, index) { - var circle = L.circle([item.latitude, item.longitude], { - color: 'red', - fillColor: 'red', - fillOpacity: 1, - radius: 30 -}).addTo(map); -}); - -var myPositionCircle = L.circle([48.172934, 9.01236], { - color: 'black', - fillColor: 'black', - fillOpacity: 1, - radius: 30 -}).addTo(map); - - - -var x = document.getElementById("position"); - -let id; -let target; -let options; - - -//first: latitude, second: longitude -target = { - latitude : 48.172934, - longitude: 9.01236 -}; - -var my_location = { - latitude : 0, - longitude: 0 -}; - -function success(pos) { - const crd = pos.coords; - my_location.longitude = crd.longitude; - my_location.latitude = crd.latitude; - - map.setView([my_location.latitude, my_location.longitude], 16); - myPositionCircle.setLatLng([my_location.latitude, my_location.longitude]) - - console.log("updated") - - x.innerHTML = "Latitude: " + crd.latitude + - "<br>Longitude: " + crd.longitude + - "<br>Distance: " + distance(target.longitude, target.latitude, crd.longitude, crd.latitude); - - // if we want to clear the watch - // if (target.latitude === crd.latitude && target.longitude === crd.longitude) { - // console.log('Congratulations, you reached the target'); - // navigator.geolocation.clearWatch(id); - // } - -} - -function error(err) { - console.error(`ERROR(${err.code}): ${err.message}`); - console.log("trying again") - id = navigator.geolocation.watchPosition(success, error, options); -} - - -options = { - enableHighAccuracy: false, - timeout: 5000, - maximumAge: 0 -}; - -id = navigator.geolocation.watchPosition(success, error, options); - -function distance(lon1, lat1, lon2, lat2) { - var R = 6371; // Radius of the earth in km - var dLat = (lat2-lat1).toRad(); // Javascript functions in radians - var dLon = (lon2-lon1).toRad(); - var a = Math.sin(dLat/2) * Math.sin(dLat/2) + - Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * - Math.sin(dLon/2) * Math.sin(dLon/2); - var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); - var d = R * c; // Distance in km - return d; -} - -/** Converts numeric degrees to radians */ -if (typeof(Number.prototype.toRad) === "undefined") { - Number.prototype.toRad = function() { - return this * Math.PI / 180; - } -} - -function store_location(){ - console.log("storing location"); - console.log(my_location) - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/addlocation", true); - xhr.setRequestHeader('Content-Type', 'application/json'); - xhr.send(JSON.stringify({ - longitude: my_location.longitude, - latitude: my_location.latitude - })); -location.reload(); -} - -</script> </body> </html> diff --git a/app/templates/home.html b/app/templates/home.html index a9f1ad0..31e7346 100755 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -5,14 +5,186 @@ <h1 class="header" id="title">GEO</h1> <p id="position"></p> <button id="store_location" onclick="store_location()">store my position</button> +<button id="add_text" onclick="add_text()">add message</button> +<button id="add_audio" onclick="add_audio()">add audio</button> + + <br><br><br> {% for location in locations %} -<div >{{location.id}}: {{location.longitude}}, {{location.latitude}} <a href="location/{{location.id}}/delete">delete</a></div> +<div >{{location.id}}: {{location.longitude}}, {{location.latitude}} {{location.message if location.loc_type == "message"}} + {% if location.loc_type == "audio" %} + <audio id="audio-player" controls="" src="uploads/{{location.audio}}"></audio> + {% endif %} + <a href="location/{{location.id}}/delete">delete</a></div> {% endfor %} </div> -{% endblock %} +{% endblock main %} +{% block js %} + +<script> + + + var locations; + function assign_data(data) { + console.log(data); + locations = data; + } + assign_data({{ data_locations|tojson }}); + + + var map = L.map('map', {zoomControl:false, + 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: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' + }).addTo(map); + + + + + locations.forEach(function (item, index) { + + + try { + var circle = L.circle([item.latitude, item.longitude], { + color: 'red', + fillColor: 'red', + fillOpacity: 1, + radius: 30 + }).addTo(map); + } catch (error) { + console.error(error); + } + + + }); + + var myPositionCircle = L.circle([48.172934, 9.01236], { + color: 'black', + fillColor: 'black', + fillOpacity: 1, + radius: 30 + }).addTo(map); + + + + var x = document.getElementById("position"); + + let id; + let target; + let options; + + + //first: latitude, second: longitude + target = { + latitude : 48.172934, + longitude: 9.01236 + }; + + var my_location = { + latitude : 0, + longitude: 0 + }; + + function success(pos) { + const crd = pos.coords; + my_location.longitude = crd.longitude; + my_location.latitude = crd.latitude; + + map.setView([my_location.latitude, my_location.longitude], 16); + myPositionCircle.setLatLng([my_location.latitude, my_location.longitude]) + + console.log("updated") + + x.innerHTML = "Latitude: " + crd.latitude + + "<br>Longitude: " + crd.longitude + + "<br>Distance: " + distance(target.longitude, target.latitude, crd.longitude, crd.latitude); + + // if we want to clear the watch + // if (target.latitude === crd.latitude && target.longitude === crd.longitude) { + // console.log('Congratulations, you reached the target'); + // navigator.geolocation.clearWatch(id); + // } + + } + + function error(err) { + console.error(`ERROR(${err.code}): ${err.message}`); + console.log("trying again") + // id = navigator.geolocation.watchPosition(success, error, options); + } + + + options = { + enableHighAccuracy: true, + timeout: 1000, + maximumAge: 1000 + }; + + id = navigator.geolocation.watchPosition(success, error, options); + + function distance(lon1, lat1, lon2, lat2) { + var R = 6371; // Radius of the earth in km + var dLat = (lat2-lat1).toRad(); // Javascript functions in radians + var dLon = (lon2-lon1).toRad(); + var a = Math.sin(dLat/2) * Math.sin(dLat/2) + + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * + Math.sin(dLon/2) * Math.sin(dLon/2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + var d = R * c; // Distance in km + return d; + } + + /** Converts numeric degrees to radians */ + if (typeof(Number.prototype.toRad) === "undefined") { + Number.prototype.toRad = function() { + return this * Math.PI / 180; + } + } + + function store_location(){ + console.log("storing location"); + console.log(my_location) + var xhr = new XMLHttpRequest(); + xhr.open("POST", "./addlocation", true); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.send(JSON.stringify({ + longitude: my_location.longitude, + latitude: my_location.latitude + })); + + xhr.onreadystatechange=function(){ + if (xhr.readyState==4 && xhr.status==200){ + + location.reload(); + + } + } + + + } + + + function add_text(){ + window.location.href = "addtext?longitude="+ my_location.longitude +"&latitude="+my_location.latitude; + } + + function add_audio(){ + window.location.href = "addaudio?longitude="+ my_location.longitude +"&latitude="+my_location.latitude; + } + + + </script> + +{% endblock js %} \ No newline at end of file diff --git a/app/views.py b/app/views.py index 6a60e2d..4e62520 100755 --- a/app/views.py +++ b/app/views.py @@ -14,6 +14,7 @@ from sqlalchemy.sql.expression import func, select from sqlalchemy.sql import except_ from sqlalchemy.ext.serializer import loads, dumps # from app.forms import UploadForm, EditForm, SearchForm, ChatForm, StackForm, AddtoStackForm, EditStackForm +from app.forms import UploadText, UploadAudio from app.models import Location, LocationSchema from app.cover import get_cover from app.getannot import get_annotations, get_annot_results, get_annot_book @@ -21,7 +22,7 @@ from urllib.parse import quote as urlquote from app.extractText import extract_text from os import environ from flask_socketio import SocketIO, emit -import datetime +from datetime import datetime import time from csv import DictWriter, DictReader import io @@ -44,6 +45,11 @@ def allowed_file(filename): # Routing for your application. ### +@app.route('/uploads/<filename>') +def uploaded_file(filename): + return send_from_directory(app.config['UPLOAD_FOLDER'], + filename) + @app.route('/', methods= ['POST','GET']) def home(): @@ -71,13 +77,69 @@ def hello(name): def add_location(): if request.method == 'POST': data = request.get_json() + print("UPDATING DATA") print(data['longitude']) - location = Location(data['longitude'],data['latitude']) + location = Location(data['longitude'],data['latitude'], "mosquito", "", "") db.session.add(location) db.session.commit() return redirect(url_for('home')) + +@app.route('/addtext', methods=['POST', 'GET']) +def addtext(): + upload_form = UploadText() + longitude = request.args.get('longitude') + latitude = request.args.get('latitude') + print(longitude) + print(latitude) + + if request.method == 'POST': + if upload_form.validate_on_submit(): + #get data from form + message = upload_form.message.data + longitude = upload_form.longitude.data + latitude = upload_form.latitude.data + location = Location(longitude,latitude, "message", message, ""); + db.session.add(location) + db.session.commit() + return redirect(url_for('home')) + return render_template('addtext.html', form=upload_form, longitude=longitude, latitude=latitude) + +@app.route('/addaudio', methods=['POST', 'GET']) +def addaudio(): + upload_form = UploadAudio() + if request.method == 'GET': + longitude = request.args.get('longitude') + latitude = request.args.get('latitude') + + if request.method == 'POST': + if upload_form.validate_on_submit(): + #get data from form + message = upload_form.message.data + longitude = upload_form.longitude.data + latitude = upload_form.latitude.data + file = request.files['file'] + print(file.filename) + locations = db.session.query(Location).all() + id = len(locations)+1 + # Getting the current date and time + dt = datetime.now() + # getting the timestamp + ts = datetime.timestamp(dt) + filename = str(id) + "_" + str(ts) +"_"+ secure_filename(file.filename) + fullpath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + file.save(fullpath) + #add to database + location = Location(longitude,latitude, "audio", message, filename); + db.session.add(location) + db.session.commit() + return redirect(url_for('home')) + return render_template('addaudio.html', form=upload_form, longitude=longitude, latitude=latitude) + + + + @app.route('/location/<int:id>/delete', methods=['POST', 'GET']) def delete_location(id): if request.method == 'GET': diff --git a/main.py b/main.py new file mode 100644 index 0000000..d099b92 --- /dev/null +++ b/main.py @@ -0,0 +1 @@ +from app import app diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a9b8045 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,13 @@ +click==8.1.3 +Flask==2.2.2 +Flask_SocketIO==5.3.1 +flask_sqlalchemy==3.0.2 +Flask_WTF==1.0.1 +marshmallow==3.18.0 +PyPDF2==2.11.1 +python-dotenv==0.21.0 +requests==2.28.1 +SQLAlchemy==1.4.42 +Wand==0.6.10 +Werkzeug==2.2.2 +WTForms==3.0.1 diff --git a/run.py b/run.py index df06e09..61f7a27 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, ssl_context='adhoc') +socketio.run(app,host="0.0.0.0", port=8080) diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..9cd5e1e --- /dev/null +++ b/start.sh @@ -0,0 +1,6 @@ +#!/bin/bash +app="geo.app" +docker build -t ${app} . +docker run --platform linux/amd64 -p 56733:80 \ + --name=${app} \ + -v $PWD:/app ${app} diff --git a/uwsgi.ini b/uwsgi.ini new file mode 100644 index 0000000..2496d5a --- /dev/null +++ b/uwsgi.ini @@ -0,0 +1,5 @@ +[uwsgi] +module = main +callable = app +master = true +