migrating to frogejo
This commit is contained in:
commit
350c0764eb
8 changed files with 400 additions and 0 deletions
27
app.py
Normal file
27
app.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import ast
|
||||
from flask import Flask, render_template, request
|
||||
from constants import chords
|
||||
from generate_chord_tones import ChordToneGenerator
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/', methods=('GET', 'POST'))
|
||||
def index():
|
||||
chord_map = None
|
||||
counts = None
|
||||
if request.method == 'POST':
|
||||
selected_chords = []
|
||||
for chord in request.form:
|
||||
current_chord = request.form.get(chord)
|
||||
if current_chord:
|
||||
selected_chords.append(current_chord)
|
||||
|
||||
if selected_chords:
|
||||
generator = ChordToneGenerator(selected_chords)
|
||||
generator.main()
|
||||
chord_map = generator.prepped_chord_map
|
||||
counts = generator.counts
|
||||
|
||||
return render_template('index.html', chords=chords, chord_map=chord_map, counts=counts)
|
||||
16
constants.py
Normal file
16
constants.py
Normal file
File diff suppressed because one or more lines are too long
57
generate_chord_tones.py
Normal file
57
generate_chord_tones.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from pychord import Chord
|
||||
from constants import notes, strings, enharmonic_map, html_string_ids
|
||||
|
||||
|
||||
class ChordToneGenerator:
|
||||
def __init__(self, chords):
|
||||
self.chords = chords
|
||||
self.chord_map = {}
|
||||
self.note_to_fret_map = {}
|
||||
self.prepped_chord_map = {}
|
||||
self.all_frets = []
|
||||
self.counts = None
|
||||
|
||||
def main(self):
|
||||
self.generate_chord_map()
|
||||
self.prepare_chord_map()
|
||||
self.prepare_counts()
|
||||
|
||||
def generate_chord_map(self):
|
||||
for chord in self.chords:
|
||||
if chord not in self.chord_map:
|
||||
self.chord_map[chord] = {}
|
||||
c = Chord(chord)
|
||||
for note in c.components():
|
||||
self.chord_map[chord][note] = self.determine_frets(note)
|
||||
|
||||
def determine_frets(self, note):
|
||||
if note not in self.note_to_fret_map:
|
||||
frets = []
|
||||
for string in strings:
|
||||
current_string = (notes[notes.index(string):] + notes[:notes.index(string)]) * 2
|
||||
if note in enharmonic_map:
|
||||
note = enharmonic_map[note]
|
||||
frets.append([i for i, x in enumerate(current_string) if x == note and i <= 12])
|
||||
|
||||
self.note_to_fret_map[note] = frets
|
||||
return self.note_to_fret_map[note]
|
||||
|
||||
def prepare_chord_map(self):
|
||||
for chord, data in self.chord_map.items():
|
||||
self.prepped_chord_map[chord] = []
|
||||
for note, strings in data.items():
|
||||
for idx, string in enumerate(strings):
|
||||
for fret in string:
|
||||
html_fret = f'{html_string_ids[idx]}{fret}'
|
||||
self.prepped_chord_map[chord].append(html_fret)
|
||||
self.all_frets.append(html_fret)
|
||||
|
||||
def prepare_counts(self):
|
||||
self.counts = {x:self.all_frets.count(x) for x in self.all_frets}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = ChordToneGenerator(["Ab", "Dsus2"])
|
||||
t.main()
|
||||
|
||||
|
||||
26
requirements.txt
Normal file
26
requirements.txt
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
attrdict==2.0.0
|
||||
blinker==1.8.2
|
||||
click==8.1.7
|
||||
cssselect2==0.7.0
|
||||
Flask==3.0.3
|
||||
freetype-py==2.3.0
|
||||
fretboardgtr==0.2.7
|
||||
itsdangerous==2.2.0
|
||||
Jinja2==3.1.4
|
||||
lxml==5.3.0
|
||||
MarkupSafe==2.1.5
|
||||
pillow==10.4.0
|
||||
pycairo==1.27.0
|
||||
pychord==1.2.2
|
||||
pyparsing==3.1.4
|
||||
pypdf==5.0.0
|
||||
PyYAML==6.0.2
|
||||
reportlab==4.0.0
|
||||
rlPyCairo==0.3.0
|
||||
six==1.16.0
|
||||
svglib==1.5.1
|
||||
svgwrite==1.1.9
|
||||
tinycss2==1.3.0
|
||||
webencodings==0.5.1
|
||||
Werkzeug==3.0.4
|
||||
wheel==0.44.0
|
||||
BIN
static/fretboard.png
Normal file
BIN
static/fretboard.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
94
static/main.css
Normal file
94
static/main.css
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
.fretboard-container {
|
||||
position: relative;
|
||||
padding: 30px;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.fretboard-container div {
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.fretboard-container div div {
|
||||
width:100%;
|
||||
height: 100%;
|
||||
float:left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.e {
|
||||
top: 20px
|
||||
}
|
||||
|
||||
.b {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.g {
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
.d {
|
||||
top: 140px;
|
||||
}
|
||||
|
||||
.a {
|
||||
top: 180px;
|
||||
}
|
||||
|
||||
.E {
|
||||
top: 220px;
|
||||
}
|
||||
|
||||
.zero {
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.one {
|
||||
left: 70px;
|
||||
}
|
||||
|
||||
.two {
|
||||
left: 125px
|
||||
}
|
||||
|
||||
.three {
|
||||
left: 177px;
|
||||
}
|
||||
|
||||
.four {
|
||||
left: 230px;
|
||||
}
|
||||
|
||||
.five {
|
||||
left: 282px;
|
||||
}
|
||||
|
||||
.six {
|
||||
left: 335px;
|
||||
}
|
||||
|
||||
.seven {
|
||||
left: 385px;
|
||||
}
|
||||
|
||||
.eight {
|
||||
left: 438px;
|
||||
}
|
||||
|
||||
.nine {
|
||||
left: 491px;
|
||||
}
|
||||
|
||||
.ten {
|
||||
left: 542px;
|
||||
}
|
||||
|
||||
.eleven {
|
||||
left: 597px;
|
||||
}
|
||||
|
||||
.twelve {
|
||||
left: 647px;
|
||||
}
|
||||
29
static/main.js
Normal file
29
static/main.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
var colors = ['red', 'green', 'blue', 'grey']
|
||||
var stats = document.getElementById("stats")
|
||||
|
||||
function generateFretMarkers(chordMap, counts) {
|
||||
var chordCount = 0;
|
||||
for (const [chord, notes] of Object.entries(chordMap)) {
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
var fret = document.getElementById(notes[i]);
|
||||
var fretMarker = document.createElement("div");
|
||||
fretMarker.style.backgroundColor = colors[chordCount]
|
||||
|
||||
if (counts[notes[i]] == 2) {
|
||||
fretMarker.style.width = "50%"
|
||||
}
|
||||
|
||||
if (counts[notes[i]] == 3) {
|
||||
fretMarker.style.width = "33%"
|
||||
}
|
||||
|
||||
if (counts[notes[i]] == 4) {
|
||||
fretMarker.style.width = "25%"
|
||||
}
|
||||
|
||||
fret.appendChild(fretMarker)
|
||||
}
|
||||
stats.innerHTML += '<button style="height:20px; width:20px; background-color:' + colors[chordCount] + ';"></button>' + chord + ' ';
|
||||
chordCount++
|
||||
}
|
||||
}
|
||||
151
templates/index.html
Normal file
151
templates/index.html
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Chord Tone</title>
|
||||
<link rel="stylesheet" href="/static/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Chord Tone Map Generator</h1>
|
||||
<hr>
|
||||
<p>This will map the notes of multiple chords on the fretboard in different colors.
|
||||
Use this to map out chord tones for improvisation, melody construction,
|
||||
and whatever else you can think of. If this has helped you at all,
|
||||
please consider <a href="https://www.domdit.com/donate" target="_blank">donating</a>!</p>
|
||||
|
||||
<form method="post">
|
||||
|
||||
<datalist id="chords">
|
||||
{% for chord in chords %}
|
||||
<option value="{{chord}}">{{chord}}</option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
|
||||
<label for="chord_1">Chord 1:</label>
|
||||
<input list="chords" name="chord_1" id="chord_1">
|
||||
|
||||
<label for="chord_2">Chord 2:</label>
|
||||
<input list="chords" name="chord_2" id="chord_2">
|
||||
<br>
|
||||
<label for="chord_3">Chord 3:</label>
|
||||
<input list="chords" name="chord_3" id="chord_3">
|
||||
|
||||
<label for="chord_4">Chord 4:</label>
|
||||
<input list="chords" name="chord_4" id="chord_4">
|
||||
|
||||
<br><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="fretboard-container">
|
||||
|
||||
<img src="{{ url_for('static', filename='fretboard.png') }}">
|
||||
|
||||
<div id="e0" class="e zero"></div>
|
||||
<div id="e1" class="e one"></div>
|
||||
<div id="e2" class="e two"></div>
|
||||
<div id="e3" class="e three"></div>
|
||||
<div id="e4" class="e four"></div>
|
||||
<div id="e5" class="e five"></div>
|
||||
<div id="e6" class="e six"></div>
|
||||
<div id="e7" class="e seven"></div>
|
||||
<div id="e8" class="e eight"></div>
|
||||
<div id="e9" class="e nine"></div>
|
||||
<div id="e10" class="e ten"></div>
|
||||
<div id="e11" class="e eleven"></div>
|
||||
<div id="e12" class="e twelve"></div>
|
||||
|
||||
<div id="b0" class="b zero"></div>
|
||||
<div id="b1" class="b one"></div>
|
||||
<div id="b2" class="b two"></div>
|
||||
<div id="b3" class="b three"></div>
|
||||
<div id="b4" class="b four"></div>
|
||||
<div id="b5" class="b five"></div>
|
||||
<div id="b6" class="b six"></div>
|
||||
<div id="b7" class="b seven"></div>
|
||||
<div id="b8" class="b eight"></div>
|
||||
<div id="b9" class="b nine"></div>
|
||||
<div id="b10" class="b ten"></div>
|
||||
<div id="b11" class="b eleven"></div>
|
||||
<div id="b12" class="b twelve"></div>
|
||||
|
||||
<div id="g0" class="g zero"></div>
|
||||
<div id="g1" class="g one"></div>
|
||||
<div id="g2" class="g two"></div>
|
||||
<div id="g3" class="g three"></div>
|
||||
<div id="g4" class="g four"></div>
|
||||
<div id="g5" class="g five"></div>
|
||||
<div id="g6" class="g six"></div>
|
||||
<div id="g7" class="g seven"></div>
|
||||
<div id="g8" class="g eight"></div>
|
||||
<div id="g9" class="g nine"></div>
|
||||
<div id="g10" class="g ten"></div>
|
||||
<div id="g11" class="g eleven"></div>
|
||||
<div id="g12" class="g twelve"></div>
|
||||
|
||||
<div id="d0" class="d zero"></div>
|
||||
<div id="d1" class="d one"></div>
|
||||
<div id="d2" class="d two"></div>
|
||||
<div id="d3" class="d three"></div>
|
||||
<div id="d4" class="d four"></div>
|
||||
<div id="d5" class="d five"></div>
|
||||
<div id="d6" class="d six"></div>
|
||||
<div id="d7" class="d seven"></div>
|
||||
<div id="d8" class="d eight"></div>
|
||||
<div id="d9" class="d nine"></div>
|
||||
<div id="d10" class="d ten"></div>
|
||||
<div id="d11" class="d eleven"></div>
|
||||
<div id="d12" class="d twelve"></div>
|
||||
|
||||
<div id="a0" class="a zero"></div>
|
||||
<div id="a1" class="a one"></div>
|
||||
<div id="a2" class="a two"></div>
|
||||
<div id="a3" class="a three"></div>
|
||||
<div id="a4" class="a four"></div>
|
||||
<div id="a5" class="a five"></div>
|
||||
<div id="a6" class="a six"></div>
|
||||
<div id="a7" class="a seven"></div>
|
||||
<div id="a8" class="a eight"></div>
|
||||
<div id="a9" class="a nine"></div>
|
||||
<div id="a10" class="a ten"></div>
|
||||
<div id="a11" class="a eleven"></div>
|
||||
<div id="a12" class="a twelve"></div>
|
||||
|
||||
<div id="ee0" class="E zero"></div>
|
||||
<div id="ee1" class="E one"></div>
|
||||
<div id="ee2" class="E two"></div>
|
||||
<div id="ee3" class="E three"></div>
|
||||
<div id="ee4" class="E four"></div>
|
||||
<div id="ee5" class="E five"></div>
|
||||
<div id="ee6" class="E six"></div>
|
||||
<div id="ee7" class="E seven"></div>
|
||||
<div id="ee8" class="E eight"></div>
|
||||
<div id="ee9" class="E nine"></div>
|
||||
<div id="ee10" class="E ten"></div>
|
||||
<div id="ee11" class="E eleven"></div>
|
||||
<div id="ee12" class="E twelve"></div>
|
||||
</div>
|
||||
|
||||
<div id="stats"></div>
|
||||
|
||||
<hr>
|
||||
<h4>Upcoming Features:</h4>
|
||||
<ul>
|
||||
<li>Select Your Own Colors</li>
|
||||
<li>Fix the fret dots so they are more visible</li>
|
||||
<li>Add up to 24 frets</li>
|
||||
<li>Add option to choose your which frets you want to see</li>
|
||||
<li>Improve the overall look of the app</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<small>Version 1.0 | Created By <a href="https://www.domdit.com" target="_blank">Dominic DiTaranto</a> | Questions/Suggestions: me@domdit.com | Last Update 09/22/2024</small>
|
||||
|
||||
<script src="static/main.js"></script>
|
||||
<script>
|
||||
generateFretMarkers(JSON.parse('{{chord_map | tojson}}'), JSON.parse('{{counts | tojson}}'))
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue