diff --git a/assets/icons/gitdark.png b/assets/icons/gitdark.png index e69de29..0dafe28 100644 Binary files a/assets/icons/gitdark.png and b/assets/icons/gitdark.png differ diff --git a/assets/logo_.png b/assets/logo_.png index e69de29..e655c75 100644 Binary files a/assets/logo_.png and b/assets/logo_.png differ diff --git a/hashsystem.py b/hashsystem.py index e69de29..0fef90d 100644 --- a/hashsystem.py +++ b/hashsystem.py @@ -0,0 +1,60 @@ +import hashlib +import os +import requests + +def file_hash_(file_path: str) -> str: + """ + Возвращает md5 hash файла по его пути + ```python + path = "/path/to/file.txt" + hash_md5 = file_hash(path) + print(hash_md5) + ``` + :param file_path: + :return: + """ + hash_md5 = hashlib.md5() + try: + with open(file_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_md5.update(chunk) + return hash_md5.hexdigest() + except: + return "404" + + +def is_directory(path: str) -> bool: + return os.path.isdir(path) +def files_update(path_to_games_dir: str, game_id: str, files_hashs) -> None: + error_files = [] + file_names = [] + for file in files_hashs: + print(f"- {game_id}/{file['name']}...", end="") + if file['type'] == "dir": + if not os.path.isdir(f"{path_to_games_dir}/{game_id}/{file['name']}"): + os.mkdir(f"{path_to_games_dir}/{game_id}/{file['name']}") + files_update("games", f"{game_id}/{file['name']}", file['files']) + continue + file_names.append(file['name']) + file_hash = file_hash_(f"{path_to_games_dir}/{game_id}/{file['name']}") + if not file_hash == "404": + if file_hash == file["hash"]: + print("OK", file_hash) + else: + print("FAIL") + file['local_hash'] = file_hash + error_files.append(file) + else: + print("404") + error_files.append(file) + + print("---------------------------") + for file in error_files: + print(f"- {file['name']}...", end="") + try: + with open(f"{path_to_games_dir}/{game_id}/{file['name']}", "wb") as f: + f.write(requests.get(file['url']).content) + print("DONE!") + except: + print("FAIL!") + print("=============================") \ No newline at end of file diff --git a/internets.py b/internets.py index f5cba6c..e84e5a9 100644 --- a/internets.py +++ b/internets.py @@ -4,8 +4,41 @@ def get_ip(): return requests.get("https://ipinfo.io/ip").text -def get_updates(only_last:bool = False, game_id = ""): + + +# Эта функция возвращает обнавления указанной игры +def get_updates(only_last:bool = False, game_id = "") -> []: news = requests.get(f"http://127.0.0.1:8000/updates/{game_id}").json() if only_last: return news[0] return news + + +#Функция для проверки работы нового api (пока что только существование потом добавлю проверку всех ендпоинтов) +def check_api(url: str) -> bool: + """ + Функция для проверки работы нового api + ```python + check_api("http://127.0.0.1:8000") -> Fasle/TRue + ``` + :param url: + :return: + """ + try: + req = requests.get(f"{url}/online") + if req.status_code == 200: + req_json = req.json() + print(req_json) + if "status" in req_json: + print("API работает") + return True + + else: + print("в json нет online") + return False + else: + print("не 200") + return False + except Exception as e: + print(e) + return False diff --git a/main.py b/main.py index d18e79a..71e8136 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ from settings_page import go_to_settings, get_settings_page from ui import interface_button, interface_switch from game_run_page import GamesPage +from home_page import get_main_page_home sound = True launcher_name = "PixelLauncher" @@ -35,16 +36,20 @@ def main(page: ft.Page): duration=500, reverse_duration=500, ) + def go_to_home(e): + content.content = get_main_page_home(page) + content.update() + + HOME = ft.Container(get_main_page_home(page)) GAMES = ft.Container(get_games_page(page, content)) SETTINGS = ft.Container(get_settings_page(page)) - content.content = GAMES - + content.content = SETTINGS - drag_area, nav_left = get_elements(page, height, lambda e: go_to_main(content, page), lambda _: go_to_settings(content, page)) + drag_area, nav_left = get_elements(page, height, lambda e: go_to_home(page), lambda _: go_to_settings(content, page), lambda e: go_to_main(content, page)) page.add(drag_area) page.add(ft.Row([nav_left, content])) diff --git a/navifation.py b/navifation.py index 30ebb64..66155f6 100644 --- a/navifation.py +++ b/navifation.py @@ -1,31 +1,37 @@ import flet as ft -from sound_effect import BoopSound - +from PIL import Image +import io +import base64 +from ui import navigation_button launcher_name = "PixelLauncher" +def colorize_image(rgb, image_path): + image = Image.open(image_path).convert('RGB') + colored_image = Image.new('RGB', image.size, rgb) + colored_image = Image.blend(colored_image, image, 0.5) + byte_stream = io.BytesIO() + colored_image.save(byte_stream, format='PNG') + byte_stream.seek(0) + base64_image = base64.b64encode(byte_stream.getvalue()).decode('utf-8') + return base64_image -navigation_button = { - "width": 250, - "height": 45, - "bgcolor": ft.colors.TRANSPARENT, - "color": ft.colors.WHITE, - "icon_color": ft.colors.WHITE, - "style": ft.ButtonStyle(shape=ft.RoundedRectangleBorder(radius=0), bgcolor=ft.colors.TRANSPARENT, - surface_tint_color=ft.colors.TRANSPARENT, shadow_color=ft.colors.TRANSPARENT, overlay_color=ft.colors.with_opacity(0.1, ft.colors.WHITE)), -} +logo_path = "assets/logo_.png" +rgb = (100, -5, -2) -def get_elements(page, height, main, settings): +def get_elements(page, height, main, settings, library): def close(e): page.window_minimized = True page.update() + + image_base64 = colorize_image(rgb, logo_path) navigation = ft.Container(ft.Column([ft.Container( - ft.Image("assets/logo.png", width=150), + ft.Image(src_base64=image_base64, width=150, border_radius=30), margin=ft.margin.only(bottom=40, top=20), on_click=lambda _: page.launch_url("https://www.sovagroup.one"), tooltip="site:https://www.sovagroup.one"), ft.ElevatedButton("Главная", **navigation_button, on_click=main), - ft.ElevatedButton("Библиотека", **navigation_button, on_click=lambda _: BoopSound(page).play()), + ft.ElevatedButton("Библиотека", **navigation_button, on_click=library), ft.ElevatedButton("Настройки", **navigation_button, on_click=settings), ft.Divider(), ft.ElevatedButton("Оффициальный лаунчер", **navigation_button, icon=ft.icons.OPEN_IN_NEW, on_click=lambda _: page.launch_url("https://www.sovagroup.one/sovalaucher"), tooltip="sovagroup:official-launcher"), diff --git a/settings_page.py b/settings_page.py index 90eed02..99f0792 100644 --- a/settings_page.py +++ b/settings_page.py @@ -1,30 +1,56 @@ import flet as ft from sound_effect import BoopSound from ui import interface_button, interface_switch, interface_input +from internets import check_api - -def go_to_settings(content, page): +def go_to_settings(content, page: ft.Page): boop = BoopSound(page) boop.play() content.content = get_settings_page(page) content.update() def get_settings_page(page: ft.Page): + cdn = page.client_storage.get("cdn_url") + if cdn == None: + page.client_storage.set("cdn_url", "http://127.0.0.1:8000") + print("CDN - УСТАНОВЛЕННО") def edit_cdn(e): def close(e): dialog.open = False page.update() + + def edit(e): + edited_cdn = dialog.content.content.controls[0].value + e.control.content = ft.ProgressRing(width=20, height=20, color=ft.colors.RED_400, bgcolor=ft.colors.BLACK26) + e.control.update() + if check_api(edited_cdn): + close(e) + page.client_storage.set("cdn_url", "http://127.0.0.1:8000") + else: + e.control.content = ft.Text("Сохранить") + e.control.update() + dialog.content.content.controls[0].error_text = "Некорректная ссылка" + dialog.content.content.controls[0].update() + + def one_change(e): + e.control.error_text = None + dialog.content.content.controls[0].update() + boop.play() + cdn_url = page.client_storage.get("cdn_url") dialog = ft.AlertDialog( modal=True, - shape=ft.ContinuousRectangleBorder(radius=20), + shape=ft.ContinuousRectangleBorder(radius=50), + content_padding=15, + actions_padding=15, content=ft.Container( ft.Column([ - ft.TextField(label="CDN", value="https://cdn.sovagroup.one", on_change=boop.play_e, color="#FFFFFF", cursor_color="#FFFFFF", border_color=ft.colors.WHITE, border_radius=15, focused_border_color=ft.colors.RED_400), + ft.TextField(label="CDN", value=cdn_url, on_change=one_change, **interface_input), ]), - height=50, - width=300 + height=60, + width=300, + ), - actions=[ft.ElevatedButton("Сохранить", on_click=boop.play_e, **interface_button, width=150), ft.ElevatedButton("Отмена", on_click=close, **interface_button, width=150)] + actions=[ft.ElevatedButton("Сохранить", on_click=edit, **interface_button, width=150), ft.ElevatedButton("Отмена", on_click=close, **interface_button, width=150)] ) page.dialog = dialog dialog.open = True diff --git a/ui.py b/ui.py index 1e0b72e..a7a4997 100644 --- a/ui.py +++ b/ui.py @@ -2,19 +2,33 @@ interface_button = { "color": ft.colors.WHITE, - "style": ft.ButtonStyle(shape=ft.RoundedRectangleBorder(radius=10), bgcolor=ft.colors.WHITE24, overlay_color=ft.colors.with_opacity(0.5, ft.colors.RED_500), padding=20), + "style": ft.ButtonStyle(shape=ft.RoundedRectangleBorder(radius=10), bgcolor=ft.colors.WHITE24, overlay_color=ft.colors.with_opacity(0.05, ft.colors.WHITE), padding=20), "icon_color": "white", } interface_switch = { - "active_color" : ft.colors.WHITE, - "active_track_color" : ft.colors.RED_400, - "inactive_track_color" : "#1e1f22", - "thumb_color" : ft.colors.WHITE, + "active_color": ft.colors.WHITE, + "active_track_color": ft.colors.RED_400, + "inactive_track_color": "#1e1f22", + "thumb_color": ft.colors.WHITE, "inactive_thumb_color" : "white", "focus_color" : ft.colors.WHITE } -interface_input = { +navigation_button = { + "width": 250, + "height": 45, + "bgcolor": ft.colors.TRANSPARENT, + "color": ft.colors.WHITE, + "icon_color": ft.colors.WHITE, + "style": ft.ButtonStyle(shape=ft.RoundedRectangleBorder(radius=0), bgcolor=ft.colors.TRANSPARENT, + surface_tint_color=ft.colors.TRANSPARENT, shadow_color=ft.colors.TRANSPARENT, overlay_color=ft.colors.with_opacity(0.1, ft.colors.WHITE)), +} +interface_input = { + "color": "#FFFFFF", + "cursor_color": "#FFFFFF", + "border_color": ft.colors.WHITE, + "border_radius": 15, + "focused_border_color": ft.colors.RED_400 } \ No newline at end of file