Starts on suggest page
This commit is contained in:
parent
1d9ad9d3db
commit
3e3d318134
64
app.py
64
app.py
@ -1,5 +1,7 @@
|
||||
import flask
|
||||
import sqlite3
|
||||
import csv
|
||||
import datetime
|
||||
|
||||
app = flask.Flask('songbook')
|
||||
|
||||
@ -8,7 +10,7 @@ app = flask.Flask('songbook')
|
||||
# @app.route('/')
|
||||
# def page():
|
||||
|
||||
# db = sqlite3.connect("file:songbook.sqlite?mode=ro", uri=True)
|
||||
# db = openbook()
|
||||
|
||||
# return flask.render_template('.html',
|
||||
# )
|
||||
@ -77,6 +79,46 @@ def searchpage():
|
||||
searchresult=searchresult
|
||||
)
|
||||
|
||||
@app.route('/suggestsearch')
|
||||
def suggestsearchpage():
|
||||
|
||||
db = openbook()
|
||||
|
||||
searchargs = flask.request.args['q']
|
||||
|
||||
if searchargs:
|
||||
searchresult = db.execute('''
|
||||
select
|
||||
'song', id, name, instr(lower(name),lower(?))
|
||||
from
|
||||
song
|
||||
where
|
||||
name
|
||||
like
|
||||
'%' || ? || '%'
|
||||
union all
|
||||
select
|
||||
'motif', id, name, instr(lower(name),lower(?))
|
||||
from
|
||||
motif
|
||||
where
|
||||
name
|
||||
like
|
||||
'%' || ? || '%'
|
||||
order by
|
||||
4
|
||||
limit
|
||||
10
|
||||
''',
|
||||
(searchargs,)*4
|
||||
).fetchall()
|
||||
|
||||
else:
|
||||
searchresult = []
|
||||
|
||||
return flask.render_template('suggestsearchresults.html',
|
||||
searchresult=searchresult
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -365,3 +407,23 @@ def songpage(id):
|
||||
clip_info=clip_info,
|
||||
artist_info=artist_info
|
||||
)
|
||||
|
||||
@app.route('/suggest')
|
||||
def suggestpage():
|
||||
|
||||
|
||||
|
||||
return flask.render_template('suggest.html',
|
||||
)
|
||||
|
||||
@app.route('/sent', methods=['POST'])
|
||||
def sentpage():
|
||||
|
||||
with open ('suggestions.csv', 'a', newline='') as suggestlog:
|
||||
logwriter = csv.writer(suggestlog)
|
||||
logwriter.writerow([
|
||||
datetime.datetime.now().isoformat(),
|
||||
flask.request.form['suggest-description'],
|
||||
])
|
||||
return flask.render_template('sent.html',
|
||||
)
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
// Check for hash on load.
|
||||
|
||||
window.addEventListener('load', (event) => {
|
||||
const preclicked = window.location.hash.slice(1);
|
||||
if (! preclicked) return;
|
||||
const albumheader = document.getElementById(preclicked);
|
||||
if (albumheader){
|
||||
albumheader.classList.add('open');
|
||||
albumheader.scrollIntoView();
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll to search result album
|
||||
|
||||
function albumselect(code){
|
||||
const albumheader = document.getElementById(code);
|
||||
for (const other of document.querySelectorAll('.sort-header.album.open')){
|
||||
@ -18,9 +21,10 @@ function albumselect(code){
|
||||
document.getElementById('search-results').replaceChildren();
|
||||
}
|
||||
|
||||
// Toggle header when clicked
|
||||
|
||||
function albumHeaderClick(clickevent){
|
||||
const albumheader = clickevent.target;
|
||||
// console.log(albumheader);
|
||||
if (albumheader.classList.contains('open')){
|
||||
albumheader.classList.remove('open');
|
||||
history.replaceState(null, document.title, `${window.location.origin}${window.location.pathname}${window.location.search}`);
|
||||
@ -33,3 +37,28 @@ function albumHeaderClick(clickevent){
|
||||
window.location.hash = albumheader.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill out form with suggest search result
|
||||
function suggestform1(id, desc){
|
||||
document.getElementById('connection-1').valueAsNumber = id;
|
||||
document.getElementById('connection-1-desc').valueAsNumber = desc;
|
||||
document.getElementById('search-input-suggest-1').value = '';
|
||||
document.getElementById('search-results-1').replaceChildren();
|
||||
}
|
||||
|
||||
// Mutually exclusive audio playback
|
||||
function onlyPlayOneIn(container) {
|
||||
container.addEventListener("play", function(event) {
|
||||
audio_elements = container.getElementsByTagName("audio")
|
||||
for(i=0; i < audio_elements.length; i++) {
|
||||
audio_element = audio_elements[i];
|
||||
if (audio_element !== event.target) {
|
||||
audio_element.pause();
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
onlyPlayOneIn(document.body);
|
||||
});
|
||||
@ -226,16 +226,17 @@ header{
|
||||
|
||||
/* SEARCH RESULTS */
|
||||
|
||||
#search-results{
|
||||
.search-results{
|
||||
display: flex; flex-direction: column;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#search-results h2{
|
||||
visibility: collapse;
|
||||
.search-results h2{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search-results ul{
|
||||
.search-results ul{
|
||||
background-color: var(--search-back);
|
||||
padding-left: 0;
|
||||
margin-top: 0;
|
||||
@ -244,13 +245,13 @@ header{
|
||||
border-style: solid; border-color: var(--thin-border); border-width: 1px; border-top: 0; border-bottom: 0;
|
||||
}
|
||||
|
||||
#search-results li{
|
||||
.search-results li{
|
||||
display: flex; align-items: center;
|
||||
min-height: 2.4rem;
|
||||
border-style: solid; border-width: 1px; border-color: var(--thin-border); border-left: 0; border-top: 0; border-right: 0;
|
||||
}
|
||||
|
||||
#search-results a{
|
||||
.search-results a{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@ -277,6 +278,10 @@ header{
|
||||
min-width: 2.6rem;
|
||||
}
|
||||
|
||||
.search-bar::-webkit-search-cancel-button{
|
||||
color: var(--text)
|
||||
}
|
||||
|
||||
/* MAIN PAGE */
|
||||
|
||||
main{
|
||||
@ -624,3 +629,39 @@ footer{
|
||||
.clip-pointer a{
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
/* SUGGEST PAGE */
|
||||
|
||||
.suggestbox{
|
||||
display: flex; flex-wrap: wrap; justify-content: center; gap: 4.8rem;
|
||||
margin-top: 2.4rem;
|
||||
}
|
||||
|
||||
.suggestbox h2{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.search-items.suggest{
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.suggest-desc{
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.suggest-desc textarea{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.suggest-button{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#connection-1{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#connection-1-desc{
|
||||
display: none;
|
||||
}
|
||||
4
suggestions.csv
Normal file
4
suggestions.csv
Normal file
@ -0,0 +1,4 @@
|
||||
2023-06-27T15:35:08.245616,Testing the form
|
||||
2023-06-27T15:35:34.195039,testing again
|
||||
2023-06-27T21:54:35.835288,"Hello from Moss and Nat's
|
||||
"
|
||||
|
@ -4,6 +4,7 @@
|
||||
src = "{{ url_for('static', filename='clip/') }}{{ '%04d' % song_id }}-{{ '%03d' % motif_id }}.flac" type="audio/flac">
|
||||
</audio>
|
||||
<span class="clip-pointer">
|
||||
|
||||
<img src="{{ url_for('static', filename='motificon.png') }}" alt="Motif Icon" class="connection-icon"/>
|
||||
<a href = "{{ url_for('motifpage', id=motif_id) }}"> {{ motif }} </a>
|
||||
</span>
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
<div class="footer-content">
|
||||
<span>
|
||||
Suggest a new connection
|
||||
<a href="{{ url_for('suggestpage') }}"> Suggest a new connection </a>
|
||||
</span>
|
||||
<span>
|
||||
<a href="#" class="top-of-page">↑Top of page↑</a>
|
||||
|
||||
11
templates/jinja quarantine.html
Normal file
11
templates/jinja quarantine.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!-- {% macro icon(type) -%}
|
||||
<img src="{{ url_for('static', filename='{0}icon.png'.format(type)) }}" alt='{{ type}} icon' class='connection-icon'>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro link(type) -%}
|
||||
{{ url_for('{0}page'.format(type), id=) }}"> {{ motif }}
|
||||
{%- endmacro %}
|
||||
-->
|
||||
|
||||
<!-- {{ icon(type) }}
|
||||
{{ link(type) }} -->
|
||||
@ -32,8 +32,8 @@
|
||||
placeholder="Search..."
|
||||
hx-get="/search"
|
||||
hx-trigger="keyup changed delay:500ms, search"
|
||||
hx-target="#search-results"
|
||||
hx-target="#search-results-header"
|
||||
/>
|
||||
<div id="search-results"></div>
|
||||
<div id="search-results-header" class="search-results header"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
10
templates/sent.html
Normal file
10
templates/sent.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Suggestion sent{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
<!-- Artist info -->
|
||||
|
||||
<div class="track-info">
|
||||
<div class="track-info" >
|
||||
<div class="songpage-detail">
|
||||
<h2 >Artist: </h2>
|
||||
<ul>
|
||||
@ -75,7 +75,8 @@
|
||||
<h2>Motifs Featured: </h2>
|
||||
<ul>
|
||||
{% for song_id, motif_id, motif in clip_info %}
|
||||
{% include "songpageclipget.html" %}
|
||||
{% set type = 'motif' %}
|
||||
{% include "clipget.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
41
templates/suggest.html
Normal file
41
templates/suggest.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Suggest a connection{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>If you know about a shared motif that you can't find on the website, you can tell me about it here. Just pick the two songs that share a motif - or the motif itself, if it already has a page - and tell me what to listen out for.</p>
|
||||
|
||||
<form action="/sent" method="post" >
|
||||
<div class="suggestbox">
|
||||
<div class="search-items suggest">
|
||||
<h2>Song / Motif 1</h2>
|
||||
<input
|
||||
id="search-input-suggest-1"
|
||||
type="search"
|
||||
name="q"
|
||||
autocomplete="off"
|
||||
placeholder="Search..."
|
||||
hx-get="/suggestsearch"
|
||||
hx-trigger="keyup changed delay:500ms, search"
|
||||
hx-target="#search-results-1"
|
||||
/>
|
||||
<div id="search-results-1" class="search-results"></div>
|
||||
</div>
|
||||
<input type="number" name="connection-1-desc" id="connection-1-desc"/>
|
||||
<input type="number" name="connection-1" id="connection-1" min="1" max="733"/>
|
||||
|
||||
<div class="suggest-desc">
|
||||
<textarea name="suggest-description">
|
||||
Suggest a different connection!
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="suggest-button">
|
||||
<input type="submit" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
22
templates/suggestsearchresults.html
Normal file
22
templates/suggestsearchresults.html
Normal file
@ -0,0 +1,22 @@
|
||||
<h2>Search Results:</h2>
|
||||
<ul>
|
||||
{% for desc, id, name, _ in searchresult %}
|
||||
{% if desc == 'song' %}
|
||||
<li onclick="suggestform('{{ id }}', 1)">
|
||||
<span class="search-icon">
|
||||
<img src="{{ url_for('static', filename='songicon.png') }}" alt="Song Icon"/>
|
||||
</span>
|
||||
<span class="search-type">Song:</span>
|
||||
{{ name }}
|
||||
</li>
|
||||
{% elif desc == 'motif' %}
|
||||
<li onclick="suggestform('{{ id }}', 2)">
|
||||
<span class="search-icon">
|
||||
<img src="{{ url_for('static', filename='motificon.png') }}" alt="Motif Icon"/>
|
||||
</span>
|
||||
<span class="search-type">Motif:</span>
|
||||
{{ name }}
|
||||
</li></a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
Loading…
Reference in New Issue
Block a user