Skip to content
Snippets Groups Projects
Verified Commit be02135e authored by kjk's avatar kjk
Browse files

added flask web service

parent 3b5e2f44
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="postgres@localhost" uuid="0a95704f-2794-4f5f-ac62-0b85ca8d0eff">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://localhost:5432/postgres</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.9 (usdb-downloader)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (usdb-downloader)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/usdb-wishlist/update_db.py" dialect="GenericSQL" />
</component>
</project>
\ No newline at end of file
......@@ -72,12 +72,12 @@ class UltraStarSongFileParser:
self._parse_header(line.strip(), song, linenum)
elif line[0] in (":", "-", "*", "F", "P", "B"):
self._parse_content(line, content, linenum)
elif line == "E":
elif line == "E" or line == "E\n":
logging.debug("=> Parsed content end marker")
break
else:
raise ValueError(f"Line {linenum} unparsable, prefix "
f"unknown: {line}")
f"unknown: {repr(line)}")
song["path"] = file
song["songdata"] = content
file_obj = UltraStarSongFile()
......
beautifulsoup4==4.11.1
Brotli==1.0.9
certifi==2022.6.15
charset-normalizer==2.1.0
beautifulsoup4==4.12.2
blinker==1.7.0
Brotli==1.1.0
certifi==2023.7.22
charset-normalizer==3.3.2
click==8.1.7
decorator==5.1.1
et-xmlfile==1.1.0
idna==3.3
mutagen==1.45.1
numpy==1.23.1
openpyxl==3.0.10
pandas==1.4.3
pycryptodomex==3.15.0
Flask==3.0.0
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
mutagen==1.47.0
numpy==1.26.2
openpyxl==3.1.2
pandas==2.1.3
psycopg2==2.9.9
pycryptodomex==3.19.0
python-dateutil==2.8.2
pytz==2022.1
requests==2.28.1
pytz==2023.3.post1
requests==2.31.0
six==1.16.0
soupsieve==2.3.2.post1
urllib3==1.26.10
websockets==10.3
#yt-dlp==2022.8.19
yt-dlp==2023.7.6
click==8.1.3
validators==0.20.0
\ No newline at end of file
soupsieve==2.5
tzdata==2023.3
urllib3==2.1.0
validators==0.22.0
websockets==12.0
Werkzeug==3.0.1
yt-dlp==2023.10.13
from flask import Flask, render_template, request, redirect, url_for
import psycopg2
app = Flask(__name__)
# Configure your PostgreSQL connection
db_config = {
'host': 'localhost',
'database': 'postgres',
'user': 'postgres',
'password': 'mysecretpassword',
}
# Function to get a list of songs from the database
def get_songs(search_term=None):
connection = psycopg2.connect(**db_config)
cursor = connection.cursor()
query = """
SELECT DISTINCT s.id, s.title, s.artist, s.play_count, q.status
FROM ultra_star_song s
LEFT JOIN queue q ON s.id = q.song_id
"""
if search_term:
query += " WHERE s.title ILIKE %s OR s.artist ILIKE %s"
cursor.execute(query + " ORDER BY s.title", (f"%{search_term}%", f"%{search_term}%"))
else:
cursor.execute(query + " ORDER BY s.title")
songs = cursor.fetchall()
connection.close()
return songs
# Function to get the queue of songs from the database
def get_queue():
connection = psycopg2.connect(**db_config)
cursor = connection.cursor()
cursor.execute(
"SELECT q.id, s.title, s.artist, s.play_count, q.status FROM queue q JOIN ultra_star_song s ON q.song_id = s.id ORDER BY q.position")
queue = cursor.fetchall()
connection.close()
return queue
# Route to display the list of songs and the queue
@app.route('/')
def index():
search_term = request.args.get('search', '')
songs = get_songs(search_term)
queue = get_queue()
return render_template('index.html', songs=songs, search_term=search_term, queue=queue)
# Route to handle song addition to the queue
@app.route('/add_to_queue/<int:song_id>', methods=['POST'])
def add_to_queue(song_id):
add_song_to_queue(song_id)
return redirect(url_for('index'))
# Route to handle song removal from the queue
@app.route('/remove_from_queue/<int:queue_id>', methods=['POST'])
def remove_from_queue(queue_id):
remove_song_from_queue(queue_id)
return redirect(url_for('queue'))
# Route to display the queue
@app.route('/queue')
def queue():
queue = get_queue()
return render_template('queue.html', queue=queue)
# Function to add a song to the queue
def add_song_to_queue(song_id):
connection = psycopg2.connect(**db_config)
cursor = connection.cursor()
# Increment the play count in the songs table
cursor.execute("UPDATE ultra_star_song SET play_count = play_count + 1 WHERE id = %s", (song_id,))
# Add the song to the queue
cursor.execute(
"INSERT INTO queue (song_id, position) VALUES (%s, (SELECT COALESCE(MAX(position), 0) + 1 FROM queue))",
(song_id,))
connection.commit()
connection.close()
# Function to remove a song from the queue
def remove_song_from_queue(queue_id):
connection = psycopg2.connect(**db_config)
cursor = connection.cursor()
cursor.execute("DELETE FROM queue WHERE id = %s", (queue_id,))
connection.commit()
connection.close()
# Function to update the order of songs in the queue
def update_queue_order(new_order):
connection = psycopg2.connect(**db_config)
cursor = connection.cursor()
for position, queue_id in enumerate(new_order, 1):
cursor.execute("UPDATE queue SET position = %s WHERE id = %s", (position, queue_id))
connection.commit()
connection.close()
if __name__ == '__main__':
app.run(debug=True)
<!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.0">
<title>Karaoke Song Selection</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="font-sans bg-gray-100">
<div class="container mx-auto my-8">
<h1 class="text-3xl font-bold mb-4">Song List</h1>
<!-- Search Form -->
<form action="{{ url_for('index') }}" method="get" class="mb-4">
<label for="search" class="sr-only">Search</label>
<input type="text" id="search" name="search" placeholder="Search by title or artist"
class="p-2 border border-gray-300 rounded">
<button type="submit" class="bg-blue-500 text-white p-2 rounded">Search</button>
</form>
<!-- Song List -->
<ul class="list-disc pl-4">
{% for song in songs %}
<li class="mb-2">
<strong>{{ song[1] }}</strong> by {{ song[2 ]}} - Play Count: {{ song[3] }}
{% if song[4] %}
{% if song[4] == 'Queued' %}
<span class="text-green-500"> - Already Queued</span>
{% elif song[4] == 'Played' %}
<span class="text-blue-500"> - Already Played</span>
{% elif song[4] == 'Rejected' %}
<span class="text-red-500"> - Rejected</span>
{% endif %}
{% endif %}
<form action="{{ url_for('add_to_queue', song_id=song[0]) }}" method="post" style="display:inline;">
<button type="submit" class="bg-green-500 text-white p-1 rounded ml-2">Add</button>
</form>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
<!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.0">
<title>Karaoke Song Queue</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="font-sans bg-gray-100">
<div class="container mx-auto my-8">
<h1 class="text-3xl font-bold mb-4">Karaoke Song Queue</h1>
<ul class="list-disc pl-4">
{% for song in queue %}
<li class="mb-2">
<strong>{{ song[1] }}</strong> by {{ song[2] }} - Play Count: {{ song[3] }} - Status: {{ song[4] }}
<form action="{{ url_for('remove_from_queue', queue_id=song[0]) }}" method="post" style="display:inline;">
<button type="submit" class="bg-red-500 text-white p-1 rounded ml-2">Remove</button>
</form>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
import os
import click
import psycopg2
import UltraStarSongFileParser
from UltraStarSongFile import UltraStarSongFile
@click.command()
@click.argument('path', type=click.Path(exists=True, file_okay=False, dir_okay=True))
@click.argument('connection_string', type=str)
def main(path, connection_string):
"""
Parse text files in each subdirectory of the given PATH and add the parsed data to the PostgreSQL database using CONNECTION_STRING.
"""
parser = UltraStarSongFileParser.UltraStarSongFileParser(strict_mode=False)
# Iterate through each subdirectory in the specified path
for subdir in os.listdir(path):
subdir_path = os.path.join(path, subdir)
if os.path.isdir(subdir_path):
# Find the text file within each subdirectory
text_files = [f for f in os.listdir(subdir_path) if f.endswith(".txt")]
if len(text_files) == 1:
file_path = os.path.join(subdir_path, text_files[0])
print(f"parsing: {file_path}")
# Parse the text file
parsed_data = parser.parse_file(file_path)
# Add the parsed data to the PostgreSQL database
print(f"Type of parsed_data: {type(parsed_data)}")
print(f"Attributes of parsed_data: {dir(parsed_data)}")
# Add the parsed data to the PostgreSQL database
add_to_database(connection_string, parsed_data)
def add_to_database(connection_string, song_instance: UltraStarSongFile):
"""
Add content to the PostgreSQL database using the given CONNECTION_STRING.
"""
# Connect to the PostgreSQL database
conn = psycopg2.connect(connection_string)
# Create a cursor object to execute SQL queries
cursor = conn.cursor()
try:
# Replace 'your_table_name' with your actual table name
query = """
INSERT INTO ultra_star_song (path, title, artist, creator, version, edition, genre, language, album, year,
cover, bpm, length, resolution, ultra_star_id, p1, p2, songid, artistid, albumid, duet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s)
"""
cursor.execute(
query,
(
song_instance.path, song_instance.title, song_instance.artist, song_instance.creator, song_instance.version, song_instance.edition, song_instance.genre, song_instance.language, song_instance.album, song_instance.year,
song_instance.cover, song_instance.bpm, song_instance.length, song_instance.resolution, song_instance.id, song_instance.p1, song_instance.p2, song_instance.songid, song_instance.artistid, song_instance.albumid, song_instance.duet
)
)
# Commit the changes to the database
conn.commit()
print("Data added to the database successfully.")
except Exception as e:
print(f"Error: {e}")
finally:
# Close the cursor and connection
cursor.close()
conn.close()
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment