commit 81fbc9847a47040490c60c5796c4b4bc1f4be159 Author: M1rs3m Date: Mon Mar 9 16:59:21 2026 +0300 Загрузить файлы в «/» Веб diff --git a/prikolv3_1web.py b/prikolv3_1web.py new file mode 100644 index 0000000..27afc21 --- /dev/null +++ b/prikolv3_1web.py @@ -0,0 +1,254 @@ +import os +import sqlite3 +import csv +from flask import Flask, render_template_string, request, redirect, url_for +import pandas as pd # Still needed for initial conversion if not done +from collections import defaultdict + +app = Flask(__name__) + +# Database file +DB_FILE = 'all_tops.db' + +# Function to convert CSV to SQLite if not exists, with indexes for speed +def csv_to_sqlite(csv_file, db_file): + if os.path.exists(db_file): + print(f"Database {db_file} already exists. Skipping conversion.") + return + print(f"Converting {csv_file} to {db_file}...") + conn = sqlite3.connect(db_file) + cur = conn.cursor() + cur.execute(''' + CREATE TABLE tops ( + stat TEXT, + rank INTEGER, + username TEXT, + uuid TEXT, + raw_value INTEGER, + formatted_value REAL, + unit TEXT + ) + ''') + with open(csv_file, 'r', encoding='utf-8') as f: + reader = csv.reader(f) + next(reader) # Skip header + cur.executemany('INSERT INTO tops VALUES (?, ?, ?, ?, ?, ?, ?)', reader) + # Add indexes for faster queries + cur.execute('CREATE INDEX idx_username ON tops (username)') + cur.execute('CREATE INDEX idx_uuid ON tops (uuid)') + cur.execute('CREATE INDEX idx_stat ON tops (stat)') + cur.execute('CREATE INDEX idx_rank ON tops (rank)') + cur.execute('CREATE INDEX idx_raw_value ON tops (raw_value)') + conn.commit() + conn.close() + print("Conversion complete with indexes.") + +# Run conversion +csv_to_sqlite('all_tops.csv', DB_FILE) + +# Connect to DB +def get_db_connection(): + conn = sqlite3.connect(DB_FILE) + conn.row_factory = sqlite3.Row + return conn + +# Get unique players with pagination +def get_unique_players(page=1, per_page=20): + conn = get_db_connection() + cur = conn.cursor() + offset = (page - 1) * per_page + cur.execute('SELECT COUNT(DISTINCT username) FROM tops') + total = cur.fetchone()[0] + cur.execute('SELECT DISTINCT username FROM tops ORDER BY username LIMIT ? OFFSET ?', (per_page, offset)) + players = [row['username'] for row in cur.fetchall()] + conn.close() + return players, total + +# Get unique stats +def get_unique_stats(): + conn = get_db_connection() + cur = conn.cursor() + cur.execute('SELECT DISTINCT stat FROM tops ORDER BY stat') + stats = [row['stat'] for row in cur.fetchall()] + conn.close() + return stats + +# HTML template for main page (no full table to save memory) +main_template = """ + + + + Данные о Топах + + + +

Данные о Топах из all_tops.db

+

Всего уникальных игроков: {{ num_players }}

+

Всего уникальных статистик: {{ num_stats }}

+
+ + +
+

Игроки (Страница {{ page }} из {{ num_pages }})

+ + + + +""" + +# HTML template for player page +player_template = """ + + + + Игрок: {{ player }} + + + +

Игрок: {{ player }}

+ Голова Игрока + Назад к Главной +

Обзор Лучших Результатов

+
+ {% for cat, top_entries in best_groups %} +
+

Лучшее в {{ cat }}

+
    + {% for entry in top_entries %} +
  • {{ entry['stat'] }}: Ранг {{ entry['rank'] }} ({{ entry['formatted_value'] }} {{ entry['unit'] }})
  • + {% endfor %} +
+
+ {% endfor %} +
+

Все Ранги в Топах

+ {% for cat, group_entries in sorted_groups %} +

{{ cat }}

+ + + + + + + + + {% for entry in group_entries %} + + + + + + + + {% endfor %} +
СтатистикаРангСырое ЗначениеФорматированное ЗначениеЕдиница
{{ entry['stat'] }}{{ entry['rank'] }}{{ entry['raw_value'] }}{{ entry['formatted_value'] }}{{ entry['unit'] }}
+ {% endfor %} + + +""" + +@app.route('/') +def index(): + page = request.args.get('page', 1, type=int) + per_page = 20 + players, total = get_unique_players(page, per_page) + num_pages = (total + per_page - 1) // per_page + return render_template_string(main_template, num_players=total, num_stats=len(get_unique_stats()), players=players, page=page, num_pages=num_pages) + +@app.route('/search') +def search(): + query = request.args.get('query', '').strip() + if not query: + return redirect(url_for('index')) + + conn = get_db_connection() + cur = conn.cursor() + + # Check if query is username + cur.execute('SELECT DISTINCT username FROM tops WHERE username = ?', (query,)) + result = cur.fetchone() + if result: + conn.close() + return redirect(url_for('player_page', player=query)) + + # Check if query is uuid + cur.execute('SELECT DISTINCT username FROM tops WHERE uuid = ?', (query,)) + result = cur.fetchone() + if result: + conn.close() + return redirect(url_for('player_page', player=result['username'])) + + conn.close() + return f"Игрок с ником или UUID '{query}' не найден." + +@app.route('/player/') +def player_page(player): + conn = get_db_connection() + cur = conn.cursor() + cur.execute('SELECT * FROM tops WHERE username = ? AND raw_value > 0 ORDER BY rank ASC', (player,)) + entries = cur.fetchall() + conn.close() + + if not entries: + return f"Нет данных для игрока {player}" + + uuid = entries[0]['uuid'] + + grouped = defaultdict(list) + for entry in entries: + stat = entry['stat'] + cat = stat.split(':')[0] if ':' in stat else stat + grouped[cat].append(entry) + + # Sort groups by the min rank in the group (best performance first) + sorted_groups = sorted(grouped.items(), key=lambda x: min(e['rank'] for e in x[1])) + + # For each group, sort entries by rank ASC (best on top) + for cat, group_entries in sorted_groups: + group_entries.sort(key=lambda e: e['rank']) + + # For best overview: for each cat, take top 5 best (lowest rank) + best_groups = [] + for cat, group_entries in sorted_groups: + top5 = sorted(group_entries, key=lambda e: e['rank'])[:5] + best_groups.append((cat, top5)) + + return render_template_string(player_template, player=player, sorted_groups=sorted_groups, best_groups=best_groups, uuid=uuid) + +if __name__ == '__main__': + print("Starting Flask server...") + app.run(debug=True) \ No newline at end of file