Add level
This commit is contained in:
parent
a760e2fabc
commit
3e80e68da7
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
venv
|
||||
config.py
|
||||
__pycache__
|
||||
data/
|
||||
src_audio/
|
31
app.py
31
app.py
@ -62,17 +62,29 @@ def home():
|
||||
@app.route("/signup", methods=["GET", "POST"])
|
||||
def signup():
|
||||
if request.method == "POST":
|
||||
message = ""
|
||||
username = request.form['username']
|
||||
if username == "":
|
||||
message += gettext("Username empty. Try to find one.")
|
||||
email = request.form['email']
|
||||
if email == "":
|
||||
message += gettext("Email empty. Please give me one.")
|
||||
password = request.form['password']
|
||||
registered_user = User.query.filter_by(user_name=username).first()
|
||||
if registered_user is None:
|
||||
if password == "":
|
||||
message += gettext("You should not use an empty password")
|
||||
registered_user_by_username = User.query.filter_by(user_name=username).first()
|
||||
registered_user_by_email = User.query.filter_by(user_email=email).first()
|
||||
if registered_user_by_username is None and registered_user_by_email is None:
|
||||
password_hash = generate_password_hash(password)
|
||||
registered_user = User(user_name=username, user_email=email, user_password=password_hash)
|
||||
db.session.add(registered_user)
|
||||
db.session.commit()
|
||||
else:
|
||||
return render_template("auth/signup.html", message="Username already used. Try with an other.")
|
||||
if not registered_user_by_email is None:
|
||||
message += gettext("Email already used by a user.")
|
||||
else:
|
||||
message += gettext("Username already used by a user.")
|
||||
return render_template("auth/signup.html", message=message)
|
||||
return redirect(url_for("login"))
|
||||
elif request.method == "GET":
|
||||
return render_template("auth/signup.html")
|
||||
@ -109,9 +121,16 @@ def game():
|
||||
|
||||
@app.route("/game/new")
|
||||
def new_game():
|
||||
question = Game.new_question()
|
||||
session["question"] = question
|
||||
return render_template("game/question.html", question=question)
|
||||
if not "username" in session:
|
||||
return redirect(url_for('login'))
|
||||
user = User.query.filter_by(user_name = session['username']).first()
|
||||
if user is None:
|
||||
return redirect(url_for('login'))
|
||||
else:
|
||||
level = str(user.user_level)
|
||||
question = Game.new_question(level)
|
||||
session["question"] = question
|
||||
return render_template("game/question.html", question=question)
|
||||
|
||||
@app.route("/game/answer", methods=["POST", "GET"])
|
||||
def game_answer():
|
||||
|
120
data/level_species_cleaned.json
Normal file
120
data/level_species_cleaned.json
Normal file
@ -0,0 +1,120 @@
|
||||
{
|
||||
"1": [
|
||||
"Buse variable",
|
||||
"Merle noir",
|
||||
"Pic vert",
|
||||
"Rougegorge familier",
|
||||
"Mouette rieuse",
|
||||
"Canard colvert",
|
||||
"Pinson des arbres",
|
||||
"Moineau domestique",
|
||||
"Pie bavarde",
|
||||
"Corneille noire",
|
||||
"Faisan de Colchide"
|
||||
],
|
||||
"2": [
|
||||
"Grive draine",
|
||||
"Grande Aigrette",
|
||||
"Grand Cormoran",
|
||||
"Foulque macroule",
|
||||
"Hirondelle rustique",
|
||||
"Fauvette grisette",
|
||||
"Troglodyte mignon",
|
||||
"Bergeronnette grise",
|
||||
"Choucas des tours",
|
||||
"Pigeon ramier",
|
||||
"Rougequeue noir",
|
||||
"Tourterelle turque"
|
||||
],
|
||||
"3": [
|
||||
"Aigrette garzette",
|
||||
"Grive litorne",
|
||||
"Accenteur mouchet",
|
||||
"Bernache du Canada",
|
||||
"Pipit farlouse",
|
||||
"Tourterelle des bois",
|
||||
"Sittelle torchepot",
|
||||
"Alouette des champs",
|
||||
"Coucou gris",
|
||||
"Corbeau freux",
|
||||
"Martinet noir",
|
||||
"Bruant zizi"
|
||||
],
|
||||
"4": [
|
||||
"Grimpereau des jardins",
|
||||
"Grive musicienne",
|
||||
"Bruant jaune",
|
||||
"Bergeronnette des ruisseaux",
|
||||
"Sterne pierregarin",
|
||||
"Bruant des roseaux",
|
||||
"Milan noir",
|
||||
"Grand Corbeau",
|
||||
"Fuligule morillon"
|
||||
],
|
||||
"5": [
|
||||
"Gobemouche gris",
|
||||
"Cigogne blanche",
|
||||
"Alouette lulu",
|
||||
"Grive mauvis",
|
||||
"Tarin des aulnes",
|
||||
"Chouette hulotte",
|
||||
"Traquet motteux",
|
||||
"Milan royal",
|
||||
"Monticole bleu",
|
||||
"Canard chipeau"
|
||||
],
|
||||
"6": [
|
||||
"Fuligule milouin",
|
||||
"Chevalier guignette",
|
||||
"Bouscarle de Cetti",
|
||||
"Tadorne de Belon",
|
||||
"Cisticole des joncs",
|
||||
"Pic noir",
|
||||
"Nette rousse",
|
||||
"Petit Gravelot",
|
||||
"Fauvette des jardins",
|
||||
"Serin cini"
|
||||
],
|
||||
"7": [
|
||||
"Pic mar",
|
||||
"Perdrix grise",
|
||||
"Pinson du Nord",
|
||||
"Bruant proyer",
|
||||
"Phragmite des joncs",
|
||||
"Rousserolle effarvatte",
|
||||
"Pouillot fitis",
|
||||
"Faucon hobereau"
|
||||
],
|
||||
"8": [
|
||||
"Fauvette pitchou",
|
||||
"Busard des roseaux",
|
||||
"Canard mandarin",
|
||||
"Spatule blanche",
|
||||
"Bernache nonnette",
|
||||
"Torcol fourmilier",
|
||||
"Effraie des clochers",
|
||||
"Sittelle corse",
|
||||
"Perdrix rouge",
|
||||
"Hirondelle de rochers",
|
||||
"Hirondelle de rivage"
|
||||
],
|
||||
"9": [
|
||||
"Moineau friquet",
|
||||
"Bernache cravant",
|
||||
"Plongeon imbrin",
|
||||
"Fuligule nyroca",
|
||||
"Pigeon colombin",
|
||||
"Grimpereau des bois"
|
||||
],
|
||||
"10": [
|
||||
"Petit-duc scops",
|
||||
"Chevalier sylvain",
|
||||
"Chevalier gambette",
|
||||
"Pipit spioncelle",
|
||||
"Canard souchet",
|
||||
"Accenteur alpin",
|
||||
"Sterne naine",
|
||||
"Chevalier aboyeur",
|
||||
"Gobemouche noir"
|
||||
]
|
||||
}
|
22
game.py
22
game.py
@ -1,31 +1,33 @@
|
||||
import random
|
||||
import os
|
||||
from glob import glob
|
||||
import json
|
||||
|
||||
bird_species_folders = list(map(os.path.basename, glob("static/data/src_audio/*")))
|
||||
with open("./data/level_species_cleaned.json", "r") as f:
|
||||
LEVEL_SPECIES_LIST = json.load(f)
|
||||
|
||||
format_name = lambda folder_name : folder_name.replace('_', ' ')
|
||||
to_folder_name = lambda species_name : species_name.replace(' ', '_').replace('\'', '').lower()
|
||||
|
||||
def get_proposals(question_species_name, n):
|
||||
def get_proposals(question_species_name, available_species, n):
|
||||
proposals = [question_species_name]
|
||||
for i in range(n):
|
||||
proposition = format_name(random.choice(bird_species_folders))
|
||||
proposition = random.choice(available_species)
|
||||
while proposition == question_species_name:
|
||||
proposition = format_name(random.choice(bird_species_folders))
|
||||
proposition = random.choice(available_species)
|
||||
proposals.append(proposition)
|
||||
random.shuffle(proposals)
|
||||
return proposals
|
||||
|
||||
def new_question():
|
||||
question_species_folder = random.choice(bird_species_folders)
|
||||
question_species_name = format_name(question_species_folder)
|
||||
print(question_species_folder)
|
||||
def new_question(level):
|
||||
available_species = LEVEL_SPECIES_LIST[level]
|
||||
question_species_name = random.choice(available_species)
|
||||
question_species_folder = to_folder_name(question_species_name)
|
||||
question = {}
|
||||
audio_paths = list(map(os.path.basename, glob(f"static/data/src_audio/{question_species_folder}/*.mp3")))
|
||||
print(audio_paths)
|
||||
audio_path = random.choice(audio_paths)
|
||||
question["species"] = question_species_name
|
||||
question["species_folder"] = question_species_folder
|
||||
question["audio_path"] = audio_path
|
||||
question["proposals"] = get_proposals(question_species_name, 5)
|
||||
question["proposals"] = get_proposals(question_species_name, available_species, 5)
|
||||
return question
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<audio src="/static/data/src_audio/{{ question['species_folder'] }}/{{ question['audio_path'] }}" controls></audio>
|
||||
<audio src="/static/data/src_audio/{{ question['species_folder'] }}/{{ question['audio_path'] }}" controls autoplay></audio>
|
||||
<form action="/game/answer" method="POST">
|
||||
<select name="answer" id="answer">
|
||||
{% for item in question['proposals'] %}
|
||||
|
33
utils/convert_levels.py
Normal file
33
utils/convert_levels.py
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Update levels species folowing the folder names"""
|
||||
|
||||
import json
|
||||
import glob
|
||||
import os
|
||||
|
||||
SPECIES_FOLDER_NAMES = list(map(os.path.basename, glob.glob("./static/data/src_audio/*")))
|
||||
|
||||
def filter(species, condition):
|
||||
keeped = []
|
||||
for name in species:
|
||||
if condition(name):
|
||||
keeped.append(name)
|
||||
return keeped
|
||||
|
||||
def only_matched_folder(species_name):
|
||||
folder_like_name = species_name.replace(' ', '_').replace('\'', '')
|
||||
folder_like_name = folder_like_name.lower()
|
||||
return folder_like_name in SPECIES_FOLDER_NAMES
|
||||
|
||||
def main():
|
||||
with open("./data/level_species.json", "r") as f:
|
||||
data = json.load(f)
|
||||
for level in data:
|
||||
species_list = data[level]
|
||||
species_list = filter(species_list, only_matched_folder)
|
||||
data[level] = species_list
|
||||
with open("./data/level_species_cleaned.json", "w") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
46
utils/generate_levels.py
Normal file
46
utils/generate_levels.py
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate species list for each levels"""
|
||||
|
||||
import os
|
||||
import glob
|
||||
import json
|
||||
import math
|
||||
|
||||
LEVELS = 10
|
||||
|
||||
def load_species_sightings(file):
|
||||
species_sightings = {}
|
||||
with open(file, "r") as f:
|
||||
data = json.load(f)
|
||||
sightings = data['data']['sightings']
|
||||
counter = 0
|
||||
for sighting in sightings:
|
||||
species = sighting["species"]["name"]
|
||||
if species in species_sightings:
|
||||
species_sightings[species] += 1
|
||||
else:
|
||||
species_sightings[species] = 1
|
||||
counter += 1
|
||||
for species in species_sightings:
|
||||
species_sightings[species] /= counter * 0.01
|
||||
return species_sightings
|
||||
|
||||
def split_species_list(species_sightings):
|
||||
level_lists = { level: [] for level in range(1, LEVELS + 1)}
|
||||
species_sorted = sorted(species_sightings, key = lambda species: -species_sightings[species])
|
||||
species_number = len(species_sorted)
|
||||
species_per_level = species_number // LEVELS
|
||||
species_splitted = [species_sorted[i:i+species_per_level] for i in range(0, species_number, species_per_level)]
|
||||
for level in range(1, LEVELS + 1):
|
||||
level_lists[level] = species_splitted[level - 1]
|
||||
return level_lists
|
||||
|
||||
def main():
|
||||
file = "./data/export_26052022_150619.json"
|
||||
species_frequency = load_species_sightings(file)
|
||||
level_species = split_species_list(species_frequency)
|
||||
with open("./data/level_species.json", "w") as f:
|
||||
json.dump(level_species, f, ensure_ascii=False, indent=4)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
x
Reference in New Issue
Block a user