setup the project
This commit is contained in:
commit
a3c3dd0413
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
.venv*/
|
||||
venv*/
|
||||
__pycache__/
|
||||
dist/
|
||||
.coverage*
|
||||
htmlcov/
|
||||
.tox/
|
||||
docs/_build/
|
||||
uploads
|
54
app.py
Normal file
54
app.py
Normal file
@ -0,0 +1,54 @@
|
||||
import os
|
||||
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory
|
||||
from werkzeug.utils import secure_filename
|
||||
import secrets
|
||||
|
||||
UPLOAD_FOLDER = 'uploads'
|
||||
ALLOWED_EXTENSIONS = {'flac', 'mp3', 'm4a', 'ogg', 'wav'}
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
app.secret_key = secrets.token_urlsafe(16)
|
||||
|
||||
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
upload = request.args.get('upload')
|
||||
return render_template("index.jinja", status=upload)
|
||||
|
||||
@app.route('/', methods=['POST'])
|
||||
def upload_file():
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'the_voicemail' not in request.files:
|
||||
flash('No file uploaded', 'form')
|
||||
return redirect(request.url)
|
||||
|
||||
file = request.files['the_voicemail']
|
||||
|
||||
if file.filename == '':
|
||||
flash('No selected file', 'form')
|
||||
return redirect(request.url)
|
||||
|
||||
if file and allowed_file(file.filename):
|
||||
filename = secure_filename(file.filename)
|
||||
path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||
file.save(path)
|
||||
return redirect("?upload=completed")
|
||||
else:
|
||||
print(request.method)
|
||||
return "not a valid thing"
|
||||
|
||||
@app.route('/recent')
|
||||
def get_most_recent():
|
||||
files = os.listdir(app.config["UPLOAD_FOLDER"])
|
||||
paths = [os.path.join(app.config["UPLOAD_FOLDER"], basename) for basename in files]
|
||||
if paths:
|
||||
return send_from_directory(".", max(paths, key=os.path.getctime))
|
||||
else:
|
||||
return 'file not found', 404
|
17
requirements.txt
Normal file
17
requirements.txt
Normal file
@ -0,0 +1,17 @@
|
||||
audioop-lts==0.2.1
|
||||
blinker==1.9.0
|
||||
certifi==2024.12.14
|
||||
charset-normalizer==3.4.1
|
||||
click==8.1.8
|
||||
docopt==0.6.2
|
||||
Flask==3.1.0
|
||||
idna==3.10
|
||||
itsdangerous==2.2.0
|
||||
Jinja2==3.1.5
|
||||
MarkupSafe==3.0.2
|
||||
pipreqs==0.4.13
|
||||
pydub==0.25.1
|
||||
requests==2.32.3
|
||||
urllib3==2.3.0
|
||||
Werkzeug==3.1.3
|
||||
yarg==0.1.10
|
87
static/style.css
Normal file
87
static/style.css
Normal file
@ -0,0 +1,87 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body{
|
||||
background: url(#background);
|
||||
background-size: 100% 100%;
|
||||
-o-background-size: 100% 100%;
|
||||
-webkit-background-size: 100% 100%;
|
||||
background-size: cover;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
margin: 0 auto;
|
||||
max-width: 620px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
#main {
|
||||
text-align: center;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.border{
|
||||
border-color: black;
|
||||
background-color: white;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
box-shadow: 5px 5px 5px black;
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 1.8rem;
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
padding: 0.5vh 1vw;
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.home-img{
|
||||
width: 620px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
#menu{
|
||||
position: fixed;
|
||||
display: inline-flex;
|
||||
transform: rotate(-90deg) translate(-100%, 50%);
|
||||
transform-origin: 0 50%;
|
||||
left: 10px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#menu > p{
|
||||
margin: 0px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#background{
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: -1;
|
||||
}
|
73
templates/index.jinja
Normal file
73
templates/index.jinja
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}" />
|
||||
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
|
||||
<title>Klankschool voicemail</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<canvas id="background" style="width:100%; height: 100%;"></canvas>
|
||||
<div id="menu">
|
||||
<p class="border"><a href="voicemail.html">voicemail</a></p>
|
||||
<p class="border"><a href="https://funk.klank.school">funkwhale</a></p>
|
||||
<p class="border"><a href="http://calendar.klank.school">calendar</a></p>
|
||||
|
||||
</div>
|
||||
<div id="app">
|
||||
<h1 id="main" class="border"><marquee behavior="alternate">VoiceMail</marquee></h1>
|
||||
|
||||
<p class="border">Heard or made something funky at Klankschool? Leave a voicemail! <br> Voicemails are archived and can be used by any klankschool member. </p>
|
||||
<div class="border">
|
||||
<p>
|
||||
{% with messages = get_flashed_messages(category_filter=["form"]) %}
|
||||
{% if messages %}
|
||||
<ul class=flashes>
|
||||
{% for message in messages %}
|
||||
<li>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% if status == "completed" %}
|
||||
<h1>Wow thank you!</h1>
|
||||
{% endif %}<form method="POST" action="/" enctype="multipart/form-data">
|
||||
<input type='file' name="the_voicemail" />
|
||||
<input type="submit">
|
||||
</form></p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
// very special. just background. joak 2024-10-13
|
||||
const canvas = document.querySelector("canvas");
|
||||
const height = window.innerHeight;
|
||||
const width = window.innerWidth;
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.canvas.height = window.innerHeight;
|
||||
ctx.canvas.width = window.innerWidth;
|
||||
console.log(height, width);
|
||||
size = 20;
|
||||
function rfiller (){
|
||||
console.log("now");
|
||||
for(var w = 0; w < width; w=w+size){
|
||||
for(var h = 0; h < height; h=h+size){
|
||||
var r = Math.floor(Math.random()*255).toString(16);
|
||||
var g= Math.floor(Math.random()*255).toString(16);
|
||||
var b = Math.floor(Math.random()*255).toString(16);
|
||||
ctx.fillStyle = "#"+r+g+b;
|
||||
ctx.fillRect(w, h, w+size, h+size);
|
||||
}
|
||||
}
|
||||
}
|
||||
rfiller();
|
||||
setInterval(rfiller, 2000);
|
||||
</script>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user