Skip to content

Commit dc05c74

Browse files
committed
Starting commit
first interface check_for_updates function open_github function update_app to finish
1 parent 0a6f63c commit dc05c74

10 files changed

Lines changed: 410 additions & 0 deletions

File tree

out/auto-py-yo-exe.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cd C:\dev\valorant_change_audio_language\src
2+
auto-py-to-exe

out/build_config.json

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"version": "auto-py-to-exe-configuration_v1",
3+
"pyinstallerOptions": [
4+
{
5+
"optionDest": "noconfirm",
6+
"value": true
7+
},
8+
{
9+
"optionDest": "filenames",
10+
"value": "C:/dev/valorant_change_audio_language/src/main.py"
11+
},
12+
{
13+
"optionDest": "onefile",
14+
"value": true
15+
},
16+
{
17+
"optionDest": "console",
18+
"value": true
19+
},
20+
{
21+
"optionDest": "icon_file",
22+
"value": "C:/ProgramData/Riot Games/Metadata/valorant.live/valorant.live.ico"
23+
},
24+
{
25+
"optionDest": "name",
26+
"value": "Valorant_translator"
27+
},
28+
{
29+
"optionDest": "ascii",
30+
"value": false
31+
},
32+
{
33+
"optionDest": "clean_build",
34+
"value": false
35+
},
36+
{
37+
"optionDest": "strip",
38+
"value": false
39+
},
40+
{
41+
"optionDest": "noupx",
42+
"value": false
43+
},
44+
{
45+
"optionDest": "disable_windowed_traceback",
46+
"value": false
47+
},
48+
{
49+
"optionDest": "embed_manifest",
50+
"value": true
51+
},
52+
{
53+
"optionDest": "uac_admin",
54+
"value": false
55+
},
56+
{
57+
"optionDest": "uac_uiaccess",
58+
"value": false
59+
},
60+
{
61+
"optionDest": "win_private_assemblies",
62+
"value": false
63+
},
64+
{
65+
"optionDest": "win_no_prefer_redirects",
66+
"value": false
67+
},
68+
{
69+
"optionDest": "bootloader_ignore_signals",
70+
"value": false
71+
},
72+
{
73+
"optionDest": "argv_emulation",
74+
"value": false
75+
},
76+
{
77+
"optionDest": "datas",
78+
"value": "C:\\Python310\\Lib\\site-packages\\tk;tk/"
79+
},
80+
{
81+
"optionDest": "datas",
82+
"value": "C:\\Python310\\Lib\\site-packages\\customtkinter;customtkinter/"
83+
},
84+
{
85+
"optionDest": "datas",
86+
"value": "C:/dev/valorant_change_audio_language/src;src/"
87+
},
88+
{
89+
"optionDest": "datas",
90+
"value": "C:/Python310/Lib/tkinter;tkinter/"
91+
}
92+
],
93+
"nonPyinstallerOptions": {
94+
"increaseRecursionLimit": true,
95+
"manualArguments": ""
96+
}
97+
}

src/__init__.py

Whitespace-only changes.

src/gui/__init__.py

Whitespace-only changes.

src/gui/main_app.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from customtkinter import *
2+
3+
from .pages import update_page
4+
from ..libs import lib
5+
# Modes: "System" (standard), "Dark", "Light"
6+
set_appearance_mode("Dark")
7+
# Themes: "blue" (standard), "green", "dark-blue"
8+
set_default_color_theme("blue")
9+
10+
11+
class App(CTk):
12+
WIDTH = 700
13+
HEIGHT = 400
14+
15+
def __init__(self):
16+
super().__init__()
17+
18+
self.title(lib.APP_NAME)
19+
self.geometry(f"{App.WIDTH}x{App.HEIGHT}")
20+
# self.minsize(App.WIDTH, App.HEIGHT)
21+
22+
self.protocol("WM_DELETE_WINDOW", self.on_closing)
23+
if sys.platform == "darwin":
24+
self.bind("<Command-q>", self.on_closing)
25+
self.bind("<Command-w>", self.on_closing)
26+
self.createcommand('tk::mac::Quit', self.on_closing)
27+
28+
# configure grid layout (1x1)
29+
self.grid_columnconfigure(0, weight=1)
30+
self.grid_rowconfigure(1, weight=1)
31+
32+
self.title_label = CTkLabel(master=self,
33+
text=lib.APP_NAME,
34+
font=("Roboto Medium", -16),
35+
)
36+
self.title_label.grid(row=0, column=0, pady=5, padx=10)
37+
38+
self.frame = update_page.UpdatePage(self, self)
39+
self.frame.grid(row=1, sticky="nswe", padx=20, pady=20)
40+
41+
# def change_mode(self):
42+
# if self.switch_dark_mode.get() == 1:
43+
# set_appearance_mode("dark")
44+
# else:
45+
# set_appearance_mode("light")
46+
47+
def on_closing(self):
48+
self.destroy()
49+
50+
def start(self):
51+
self.mainloop()

src/gui/pages/__init__.py

Whitespace-only changes.

src/gui/pages/update_page.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from tkinter import messagebox
2+
import webbrowser
3+
from customtkinter import *
4+
import requests
5+
6+
from ...libs import lib
7+
from ...libs.lib import CONFIG_FILE
8+
9+
10+
class UpdatePage(CTkFrame):
11+
def __init__(self, master, app):
12+
self.app = app
13+
super().__init__(master)
14+
15+
self.grid_rowconfigure((0, 1, 2, 3), weight=1)
16+
self.columnconfigure(0, weight=1)
17+
18+
self.check_updates_button = CTkButton(
19+
self,
20+
text="Controlla aggiornamenti",
21+
command=self.check_for_updates
22+
)
23+
self.check_updates_button.grid(row=0, column=0, padx=20, pady=10)
24+
25+
self.version = CTkLabel(
26+
self,
27+
text="",
28+
width=150,
29+
height=45)
30+
self.version.grid(
31+
row=1, column=0, columnspan=2, padx=5,)
32+
33+
def open_github(self):
34+
url = f'https://api.github.com/repos/{lib.get_key_value_json(CONFIG_FILE, "repo_owner")}/{lib.get_key_value_json(CONFIG_FILE, "repo_name")}/releases/latest'
35+
webbrowser.open_new_tab(url)
36+
37+
def check_for_updates(self):
38+
39+
current_version = lib.get_key_value_json(CONFIG_FILE, "version")
40+
41+
# Recupera la versione più recente dalla repository su GitHub
42+
response = requests.get(
43+
f'https://api.github.com/repos/{lib.get_key_value_json(CONFIG_FILE, "repo_owner")}/{lib.get_key_value_json(CONFIG_FILE, "repo_name")}/releases/latest')
44+
if response.status_code == 200:
45+
latest_release = response.json()
46+
latest_version = latest_release['tag_name']
47+
print(latest_version)
48+
if latest_version != current_version:
49+
self.update_button = CTkButton(
50+
self,
51+
text="Aggiorna ora",
52+
command=lambda: self.update_app(latest_release)
53+
)
54+
self.check_updates_button.grid(
55+
row=2, column=0, padx=20, pady=10)
56+
57+
else:
58+
# Gestione dell'errore
59+
latest_version = current_version
60+
messagebox.showerror(
61+
"Error", "Nessun aggiornamento trovato.")
62+
63+
def update_app(self, latest_release):
64+
# Scarica l'aggiornamento dal repository su GitHub
65+
assets = latest_release['assets']
66+
for asset in assets:
67+
if asset['name'].endswith('.exe'):
68+
url = asset['browser_download_url']
69+
response = requests.get(url)
70+
with open('new_version.exe', 'wb') as f:
71+
f.write(response.content)
72+
73+
# Aggiorna il file di configurazione locale con la nuova versione
74+
lib.update_key_json(CONFIG_FILE, "version",
75+
latest_release['tag_name'])
76+
77+
# Avvia l'applicazione aggiornata
78+
os.startfile('new_version.exe')
79+
self.update_button.destroy()

src/libs/__init__.py

Whitespace-only changes.

src/libs/lib.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# -*- coding: utf-8 -*-
2+
__author__ = "Francesco"
3+
__version__ = "0101 2023/02/05"
4+
5+
import json
6+
import logging
7+
import os
8+
import pathlib
9+
import shutil
10+
import sys
11+
12+
from appdirs import user_data_dir
13+
14+
# CONSTANTS
15+
path_separation = "\\"
16+
file_path = 'src\\resources\\'
17+
image_path = 'src\\resources\\icons\\'
18+
language_path = 'src\\resources\\languages\\'
19+
20+
APP_NAME = "Test_Application_Update"
21+
22+
CONFIG_FILE = "config.json"
23+
24+
# ================== Temp Files functions ==================
25+
26+
27+
def resource_temp_path(relative_path: str) -> str:
28+
""" Get absolute path to resource, works for dev and for PyInstaller """
29+
temp_path = getattr(sys, '_MEIPASS', os.path.dirname(os.getcwd()))
30+
print("Temp - ", os.path.join(temp_path, relative_path))
31+
return os.path.join(temp_path, relative_path)
32+
33+
34+
# ================== File functions ==================
35+
36+
def resource_path(relative_path: str):
37+
base_path = user_data_dir(appname=APP_NAME, appauthor=False)
38+
print("Local - ", os.path.join(base_path, relative_path))
39+
return os.path.join(base_path, relative_path)
40+
41+
42+
def create_app_files():
43+
print("create app files")
44+
copy_dir(resource_temp_path(file_path), resource_path(file_path))
45+
46+
47+
def copy_dir(src: str, dst: str, ignore: str = ""):
48+
source_path = pathlib.Path(src)
49+
destination_path = pathlib.Path(dst)
50+
destination_path.mkdir(parents=True, exist_ok=True)
51+
for item in os.listdir(source_path):
52+
s: pathlib.Path = source_path / item
53+
d: pathlib.Path = destination_path / item
54+
if s.is_dir():
55+
if pathlib.Path(ignore) != s:
56+
copy_dir(str(s), str(d), ignore)
57+
else:
58+
shutil.copy2(str(s), str(d))
59+
60+
61+
# ================== JSON functions ==================
62+
63+
def open_json(file_name: str):
64+
try:
65+
f = open(resource_path(file_path + file_name), 'r+')
66+
return f
67+
except FileNotFoundError:
68+
with open(resource_path(file_path + file_name), 'w') as f:
69+
json.dump({}, f, indent=4)
70+
return open_json(file_name)
71+
except Exception as e:
72+
# TODO collect error
73+
logging.debug(e)
74+
75+
76+
def update_key_json(file_name: str, key: str, value):
77+
f = open_json(file_name)
78+
data = json.load(f)
79+
data[key] = value
80+
f.seek(0)
81+
json.dump(data, f, indent=4)
82+
f.truncate()
83+
f.close()
84+
85+
86+
def update_json(file_name: str, dix: dict):
87+
for key, value in dix.items():
88+
update_key_json(file_name, key, value)
89+
90+
91+
def get_key_value_json(file_name: str, key: str):
92+
f = open_json(file_name)
93+
data = json.load(f)
94+
f.close()
95+
try:
96+
return data[key]
97+
except KeyError:
98+
return ""
99+
100+
101+
def get_dix_json(file_name: str):
102+
f = open_json(file_name)
103+
data = json.load(f)
104+
f.close()
105+
return data
106+
107+
108+
# ========= config.json =========
109+
110+
def default_config_values():
111+
print("default config values")
112+
dix = {
113+
"version": "0.0.0-alpha",
114+
"repo_owner": 'FrenkyDema',
115+
"repo_name": 'Test_Application_Update'
116+
}
117+
118+
update_json(CONFIG_FILE, dix)
119+
120+
121+
# ========= image functions =========
122+
123+
def get_image_path(image_name: str) -> str:
124+
return resource_temp_path(image_path + image_name)
125+
126+
boold = True
127+
if __name__ == "__main__":
128+
if boold:
129+
print("Start")
130+
131+
create_app_files()
132+
133+
default_config_values()
134+
135+
if boold:
136+
print("End")

0 commit comments

Comments
 (0)