my-local-wrapped/websitemodule.py
2025-02-08 21:20:48 +03:00

226 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sqlite3
import datetime
# For now
import flask
def read_music_database():
conn = sqlite3.connect("assets/localwrapped/music.db")
c = conn.cursor()
c.execute('SELECT * FROM music')
music_list = c.fetchall()
conn.close()
return music_list
def read_count_database(year: int):
db_path = f'assets/localwrapped/count-{year}.db' if year != datetime.datetime.now().year else 'assets/localwrapped/count.db'
if not os.path.exists(db_path):
return []
conn = sqlite3.connect(db_path)
c = conn.cursor()
c.execute('SELECT * FROM count')
count_list = c.fetchall()
conn.close()
return count_list
def get_available_years():
years = []
for file in os.listdir('assets/localwrapped'):
if file.startswith('count') and file.endswith('.db'):
year = file.split('-')[-1].split('.')[0]
if year.isdigit():
years.append(int(year))
return sorted(years, reverse=True)
def total_play_time(year: int):
total_time = 0
music_data = {row[0]: row for row in read_music_database()}
for count_entry in read_count_database(year):
if count_entry[0] in music_data:
total_time += float(music_data[count_entry[0]][7]) * count_entry[1]
return total_time
def generatehtmlcode(year: int = datetime.datetime.now().year):
available_years = get_available_years()
current_year = datetime.datetime.now().year
selected_year = year if year in available_years else current_year
html = '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Halhadus' Local Wrapped</title>
<link rel="icon" type="image/png" href="assets/favicon.png">
<meta name="description" content="Halhadus' Local Wrapped">
<meta name="author" content="Halhadus">
<meta property="og:title" content="Halhadus' Local Wrapped">
<meta property="og:description" content="Halhadus' Local Wrapped">
<meta property="og:url" content="https://halhadus.rocks/localwrapped.html">
<link rel="icon" type="image/png" href="assets/favicon.png">
<style>
:root {
--bg-color: #1f1f1f;
--card-bg: #2a2a2a;
--border-color: #333;
--text-color: #ffffff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
.year-selector {
display: flex;
gap: 0.5rem;
margin: 1rem 0;
flex-wrap: wrap;
}
.year-button {
background: #333;
border: 1px solid #444;
color: var(--text-color);
padding: 0.5rem 1rem;
border-radius: 5px;
text-decoration: none;
font-family: 'JetBrains Mono', monospace;
}
.year-button.active {
background: #444;
border-color: #555;
}
.music-card {
background: var(--card-bg);
border-radius: 8px;
margin: 1rem 0;
padding: 1rem;
display: grid;
grid-template-columns: 120px 1fr;
gap: 1rem;
align-items: center;
}
.thumbnail {
width: 100%;
border-radius: 6px;
aspect-ratio: 16/9;
object-fit: cover;
border: 2px solid var(--border-color);
}
.play-button {
background: #333;
border: 1px solid #444;
color: var(--text-color);
padding: 0.5rem 1rem;
margin: 0.3rem;
border-radius: 5px;
text-decoration: none;
display: inline-block;
text-align: center;
font-family: 'JetBrains Mono', monospace;
}
.stats {
background: var(--card-bg);
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
@media (max-width: 768px) {
.music-card {
grid-template-columns: 1fr;
}
}
.source-banner {
background: #2a2a2a;
padding: 12px;
border-radius: 8px;
margin: 20px 0;
text-align: center;
border: 1px solid #333333;
}
</style>
</head>
<body style="background-color: var(--bg-color); color: var(--text-color); font-family: 'JetBrains Mono', monospace;">
<div class="container">
<h1>🎵 Halhadus' Local Wrapped</h1>
<a href="/index.html" class="play-button">← Main Page</a>
<div class="source-banner">
<a href="https://git.halhadus.rocks/Halhadus/my-local-wrapped" style="color: #ffffff; text-decoration: none;">📁 Source Codes</a>
</div>
<div class="year-selector">
{% for y in available_years %}
<a href="?year={{ y }}" class="year-button {% if y == selected_year %}active{% endif %}">
{{ y }}
</a>
{% endfor %}
</div>
<div class="stats">
<h2>📊 Statistics for {{ selected_year }}</h2>
<p>⏳ Total Play Time: {{ total_time }} minutes</p>
<p>🕒 Last Updated: {{ last_updated }}</p>
</div>
<h2>🎶 Most Played Tracks</h2>
{% for music in top_tracks %}
<div class="music-card">
<img src="https://img.youtube.com/vi/{{ music.video_id }}/hqdefault.jpg"
class="thumbnail"
alt="{{ music.name }} cover">
<div>
<h3>{{ music.name }}</h3>
<p>▶ Played {{ music.count }} times</p>
<div>
<a href="https://www.youtube.com/watch?v={{ music.video_id }}"
class="play-button"
target="_blank">
YouTube
</a>
<a href="https://music.youtube.com/watch?v={{ music.video_id }}"
class="play-button"
target="_blank">
YT Music
</a>
</div>
</div>
</div>
{% endfor %}
</div>
</body>
</html>'''
# Verileri hazırla
music_data = {row[0]: row for row in read_music_database()}
count_data = read_count_database(selected_year)
top_tracks = []
for count_entry in count_data:
if count_entry[0] in music_data:
video_id = music_data[count_entry[0]][1]
top_tracks.append({
'name': count_entry[0],
'count': count_entry[1],
'video_id': video_id
})
top_tracks.sort(key=lambda x: x['count'], reverse=True)
total_time = int(total_play_time(selected_year) / 60)
db_path = f'assets/localwrapped/count-{selected_year}.db' if selected_year != current_year else 'assets/localwrapped/count.db'
last_updated = datetime.datetime.utcfromtimestamp(os.path.getmtime(db_path)).strftime('%Y-%m-%d %H:%M UTC')
return flask.render_template_string(html, top_tracks=top_tracks, total_time=total_time, last_updated=last_updated, available_years=available_years, selected_year=selected_year)