mirror of
https://github.com/agresdominik/predictify.git
synced 2026-04-21 17:55:49 +00:00
150 lines
5.0 KiB
Python
150 lines
5.0 KiB
Python
import sqlite3
|
|
from enum import Enum
|
|
|
|
from logger import LoggerWrapper
|
|
|
|
# DATABASE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'spotify_scraped.db')
|
|
|
|
log = LoggerWrapper()
|
|
|
|
|
|
class Table(Enum):
|
|
TRACK_INFORMATION = "track_information"
|
|
ARTIST_INFORMATION = "artist_information"
|
|
ALBUM_INFORMATION = "album_information"
|
|
TRACK_ATTRIBUTES = "track_attributes"
|
|
RECENTLY_PLAYED = "recently_played"
|
|
|
|
|
|
class Database:
|
|
"""
|
|
A class to handle the database connection and operations
|
|
"""
|
|
|
|
def __init__(self, db_name: str):
|
|
"""Initialize the connection to the database"""
|
|
self.db_name = db_name
|
|
self.conn = sqlite3.connect(db_name)
|
|
self.cursor = self.conn.cursor()
|
|
self.create_tables()
|
|
|
|
def create_tables(self):
|
|
"""Create the tables in the database"""
|
|
|
|
self.cursor.execute(f'''
|
|
CREATE TABLE IF NOT EXISTS {Table.TRACK_INFORMATION.value} (
|
|
track_id TEXT PRIMARY KEY,
|
|
title TEXT,
|
|
duration_ms INTEGER,
|
|
explicit BOOLEAN,
|
|
popularity INTEGER
|
|
);
|
|
''')
|
|
|
|
self.cursor.execute(f'''
|
|
CREATE TABLE IF NOT EXISTS {Table.ARTIST_INFORMATION.value} (
|
|
artist_id TEXT PRIMARY KEY,
|
|
artist_name TEXT,
|
|
followers INTEGER,
|
|
genres TEXT,
|
|
popularity INTEGER
|
|
);
|
|
''')
|
|
|
|
self.cursor.execute(f'''
|
|
CREATE TABLE IF NOT EXISTS {Table.ALBUM_INFORMATION.value} (
|
|
album_id TEXT PRIMARY KEY,
|
|
album_name TEXT,
|
|
album_type TEXT,
|
|
total_tracks INTEGER,
|
|
release_date TEXT,
|
|
label TEXT
|
|
);
|
|
''')
|
|
|
|
self.cursor.execute(f'''
|
|
CREATE TABLE IF NOT EXISTS {Table.TRACK_ATTRIBUTES.value} (
|
|
track_id TEXT PRIMARY KEY,
|
|
acousticness FLOAT,
|
|
danceability FLOAT,
|
|
duration_ms INTEGER,
|
|
energy FLOAT,
|
|
instrumentalness FLOAT,
|
|
key INTEGER,
|
|
liveness FLOAT,
|
|
loudness FLOAT,
|
|
speechiness FLOAT,
|
|
tempo FLOAT,
|
|
time_signature INTEGER,
|
|
valence FLOAT
|
|
);
|
|
''')
|
|
|
|
self.cursor.execute(f'''
|
|
CREATE TABLE IF NOT EXISTS {Table.RECENTLY_PLAYED.value} (
|
|
played_at TIMESTAMP PRIMARY KEY,
|
|
track_id TEXT,
|
|
artist_id TEXT,
|
|
album_id TEXT,
|
|
FOREIGN KEY (track_id) REFERENCES {Table.TRACK_INFORMATION.value}(track_id),
|
|
FOREIGN KEY (artist_id) REFERENCES {Table.ARTIST_INFORMATION.value}(artist_id),
|
|
FOREIGN KEY (album_id) REFERENCES {Table.ALBUM_INFORMATION.value}(album_id),
|
|
FOREIGN KEY (track_id) REFERENCES {Table.TRACK_ATTRIBUTES.value}(track_id)
|
|
);
|
|
''')
|
|
|
|
# Commit the changes
|
|
self.conn.commit()
|
|
log.debug("Initialised tables")
|
|
|
|
def add_row(self, table: Table, values):
|
|
"""Add a new row into the specified table"""
|
|
try:
|
|
placeholders = ', '.join(['?'] * len(values))
|
|
query = f"INSERT INTO {table.value} VALUES ({placeholders})"
|
|
self.cursor.execute(query, values)
|
|
self.conn.commit()
|
|
except Exception as e:
|
|
log.error(f"Error while inserting row into table {table.value}: {e}")
|
|
|
|
def read_all_rows(self, table: Table, column: str = "*"):
|
|
"""Read all rows from the specified table"""
|
|
try:
|
|
self.cursor.execute(f"SELECT {column} FROM {table.value}")
|
|
rows = self.cursor.fetchall()
|
|
return rows
|
|
except Exception as e:
|
|
log.error(f"Error while reading all rows from table {table.value}: {e}")
|
|
return []
|
|
|
|
def close(self, message: str):
|
|
"""Close the database connection"""
|
|
self.conn.close()
|
|
log.info(f"Database connection closed from file: {message}")
|
|
|
|
def get_total_overview(self) -> list:
|
|
"""Retrieve a total overview of all recently played songs with full details"""
|
|
try:
|
|
# Join recently_played with track_information, artist_information, and album_information
|
|
query = f'''
|
|
SELECT rp.played_at,
|
|
ti.track_id,
|
|
ti.title,
|
|
ai.artist_id,
|
|
ai.artist_name,
|
|
al.album_id,
|
|
al.album_name
|
|
FROM {Table.RECENTLY_PLAYED.value} rp
|
|
JOIN {Table.TRACK_INFORMATION.value} ti ON rp.track_id = ti.track_id
|
|
JOIN {Table.ARTIST_INFORMATION.value} ai ON rp.artist_id = ai.artist_id
|
|
JOIN {Table.ALBUM_INFORMATION.value} al ON rp.album_id = al.album_id
|
|
ORDER BY rp.played_at DESC
|
|
'''
|
|
self.cursor.execute(query)
|
|
rows = self.cursor.fetchall()
|
|
return rows
|
|
except Exception as e:
|
|
log.error(f"Error retrieving total overview: {e}"
|
|
f"\nQuery Executed: {query}")
|
|
return []
|