mirror of
https://github.com/JDM170/SaveWizard
synced 2025-04-20 22:30:42 +07:00
Update
* Updated build.spec for PyInstaller build * Some code and typo fixes Signed-off-by: JDM170 <30170278+JDM170@users.noreply.github.com>
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -5,12 +5,15 @@
|
|||||||
/__pycache__
|
/__pycache__
|
||||||
/parsing/__pycache__
|
/parsing/__pycache__
|
||||||
/choice/__pycache__
|
/choice/__pycache__
|
||||||
/main/__pycache__
|
|
||||||
/second/__pycache__
|
|
||||||
/choice/form.py
|
/choice/form.py
|
||||||
|
/main/__pycache__
|
||||||
/main/form.py
|
/main/form.py
|
||||||
|
/second/__pycache__
|
||||||
/second/form.py
|
/second/form.py
|
||||||
|
|
||||||
|
## Ignoring UPX
|
||||||
|
/upx
|
||||||
|
|
||||||
## Ignoring build from cx_Freeze
|
## Ignoring build from cx_Freeze
|
||||||
/prog_build
|
/prog_build
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -17,11 +17,11 @@ Features:
|
|||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
Requirments:
|
Requirments to build project:
|
||||||
* Python 3.7.7
|
* Python >=3.5.4
|
||||||
* PyQt5 5.15.0
|
* PyQt5 >=5.6.0
|
||||||
* requests 2.24.0
|
* requests >=2.24.0
|
||||||
* cx_Freeze 6.2
|
* cx_Freeze >=6.0 (or PyInstaller >=3.6)
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
|||||||
65
build.spec
65
build.spec
@@ -1,38 +1,33 @@
|
|||||||
# -*- mode: python ; coding: utf-8 -*-
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
block_cipher = None
|
app = Analysis(
|
||||||
|
['init_main_program.py'],
|
||||||
|
pathex=['.'],
|
||||||
|
datas=[
|
||||||
|
('configs/ats', 'configs/ats'),
|
||||||
|
('configs/ets2', 'configs/ets2')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
app_pyz = PYZ(app.pure, app.zipped_data)
|
||||||
|
|
||||||
|
app_exe = EXE(
|
||||||
|
app_pyz,
|
||||||
|
app.scripts,
|
||||||
|
[],
|
||||||
|
exclude_binaries=True,
|
||||||
|
name='SaveWizard',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
console=False
|
||||||
|
)
|
||||||
|
app_coll = COLLECT(
|
||||||
|
app_exe,
|
||||||
|
app.binaries,
|
||||||
|
app.zipfiles,
|
||||||
|
app.datas,
|
||||||
|
strip=False,
|
||||||
|
name='app_build'
|
||||||
|
)
|
||||||
|
|
||||||
a = Analysis(['__init__.py'],
|
|
||||||
pathex=['.'],
|
|
||||||
binaries=[],
|
|
||||||
datas=[
|
|
||||||
('ats_configs', 'ats_configs'),
|
|
||||||
('ets2_configs', 'ets2_configs')
|
|
||||||
],
|
|
||||||
hiddenimports=[],
|
|
||||||
hookspath=[],
|
|
||||||
runtime_hooks=[],
|
|
||||||
excludes=[],
|
|
||||||
win_no_prefer_redirects=False,
|
|
||||||
win_private_assemblies=False,
|
|
||||||
cipher=block_cipher,
|
|
||||||
noarchive=False)
|
|
||||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
||||||
exe = EXE(pyz,
|
|
||||||
a.scripts,
|
|
||||||
[],
|
|
||||||
exclude_binaries=True,
|
|
||||||
name='SaveWizard',
|
|
||||||
debug=False,
|
|
||||||
bootloader_ignore_signals=False,
|
|
||||||
strip=False,
|
|
||||||
upx=True,
|
|
||||||
console=False )
|
|
||||||
coll = COLLECT(exe,
|
|
||||||
a.binaries,
|
|
||||||
a.zipfiles,
|
|
||||||
a.datas,
|
|
||||||
strip=False,
|
|
||||||
upx=True,
|
|
||||||
upx_exclude=[],
|
|
||||||
name='build')
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from ast import literal_eval
|
|||||||
from .form import Ui_Choice
|
from .form import Ui_Choice
|
||||||
from main.script import MainWindow
|
from main.script import MainWindow
|
||||||
from parsing.script import check_remote_hashes, update_configs
|
from parsing.script import check_remote_hashes, update_configs
|
||||||
from util import update_config_name
|
from statics import update_config_name
|
||||||
|
|
||||||
|
|
||||||
class ChoiceWindow(QDialog, Ui_Choice):
|
class ChoiceWindow(QDialog, Ui_Choice):
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
pyinstaller build.spec
|
pyinstaller build.spec --noupx
|
||||||
|
|||||||
13
dataIO.py
13
dataIO.py
@@ -2,9 +2,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from json import decoder, load, dump
|
from json import decoder, load, dump
|
||||||
from os import replace
|
|
||||||
from os.path import splitext
|
|
||||||
from random import randint
|
|
||||||
|
|
||||||
|
|
||||||
class DataIO:
|
class DataIO:
|
||||||
@@ -30,18 +27,12 @@ class DataIO:
|
|||||||
|
|
||||||
def save_json(self, filename, data):
|
def save_json(self, filename, data):
|
||||||
"""Atomically saves json file"""
|
"""Atomically saves json file"""
|
||||||
rnd = randint(1000, 9999)
|
|
||||||
path, ext = splitext(filename)
|
|
||||||
tmp_file = "{}-{}.tmp".format(path, rnd)
|
|
||||||
# self._save_json(filename, data)
|
|
||||||
with open(filename, encoding="utf-8", mode="w") as f:
|
with open(filename, encoding="utf-8", mode="w") as f:
|
||||||
dump(data, f, indent=4, sort_keys=True, separators=(",", " : "))
|
dump(data, f, indent=4, separators=(",", " : "))
|
||||||
# return data (?)
|
|
||||||
try:
|
try:
|
||||||
self._read_json(tmp_file)
|
self._read_json(filename)
|
||||||
except decoder.JSONDecodeError:
|
except decoder.JSONDecodeError:
|
||||||
return False
|
return False
|
||||||
replace(tmp_file, filename)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,61 +2,49 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from requests import get
|
from requests import get
|
||||||
from hashlib import md5
|
|
||||||
from ast import literal_eval
|
from ast import literal_eval
|
||||||
import os
|
import os
|
||||||
|
from statics import github_link, update_config_name
|
||||||
from dataIO import dataIO
|
from dataIO import dataIO
|
||||||
from util import github_link, update_config_name
|
from util import generate_md5
|
||||||
|
|
||||||
|
|
||||||
def send_response(txt):
|
def get_response_result(url):
|
||||||
response = get(txt)
|
response = get(url)
|
||||||
return response if response.status_code == 200 else False
|
return response.status_code == 200, response
|
||||||
|
|
||||||
|
|
||||||
def generate_md5(fn):
|
def check_path(path):
|
||||||
hash_md5 = md5()
|
current_path = os.getcwd()
|
||||||
try:
|
|
||||||
with open(fn, "rb") as f:
|
|
||||||
for chunk in iter(lambda: f.read(4096), b""):
|
|
||||||
hash_md5.update(chunk)
|
|
||||||
return hash_md5.hexdigest()
|
|
||||||
except FileNotFoundError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def check_files(path):
|
|
||||||
temp = os.getcwd()
|
|
||||||
for item in path.split("/"):
|
for item in path.split("/"):
|
||||||
temp = os.path.join(temp, item)
|
current_path = os.path.join(current_path, item)
|
||||||
if not os.path.exists(temp):
|
if not os.path.exists(current_path):
|
||||||
if item.find(".json") > 0:
|
if item.find(".json") > 0:
|
||||||
f = open(temp, "w")
|
open(current_path, "w").close()
|
||||||
f.close()
|
|
||||||
else:
|
else:
|
||||||
os.mkdir(temp)
|
os.mkdir(current_path)
|
||||||
|
|
||||||
|
|
||||||
def check_remote_hashes():
|
def check_remote_hashes():
|
||||||
response = send_response(github_link + "configs/version.cfg")
|
response_status, response = get_response_result(github_link + "configs/version.cfg")
|
||||||
if response is not False:
|
if response_status:
|
||||||
remote_cfg = literal_eval(response.text)
|
remote_cfg = literal_eval(response.text)
|
||||||
need_to_be_updated = []
|
need_update = []
|
||||||
for key, value in remote_cfg.items():
|
for key, value in remote_cfg.items():
|
||||||
path = key.split("_")
|
path = key.split("_")
|
||||||
path = "configs/{}/{}.json".format(path[0], path[1])
|
path = "configs/{}/{}.json".format(path[0], path[1])
|
||||||
if generate_md5(path) != value:
|
if generate_md5(path) != value:
|
||||||
need_to_be_updated.append(path)
|
need_update.append(path)
|
||||||
return need_to_be_updated
|
return need_update
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def update_configs(is_save, cfg_list):
|
def update_configs(is_save, cfg_list):
|
||||||
if is_save in (0, 1):
|
if is_save in (0, 1):
|
||||||
for cfg in cfg_list:
|
for cfg in cfg_list:
|
||||||
check_files(cfg)
|
check_path(cfg)
|
||||||
response = send_response(github_link + cfg)
|
response_status, response = get_response_result(github_link + cfg)
|
||||||
if response is not False:
|
if response_status:
|
||||||
remote_cfg = literal_eval(response.text)
|
remote_cfg = literal_eval(response.text)
|
||||||
if dataIO.is_valid_json(cfg) or os.path.exists(cfg):
|
if dataIO.is_valid_json(cfg) or os.path.exists(cfg):
|
||||||
dataIO.save_json(cfg, remote_cfg)
|
dataIO.save_json(cfg, remote_cfg)
|
||||||
|
|||||||
@@ -39,25 +39,6 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="garages_layout">
|
<layout class="QGridLayout" name="garages_layout">
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QTextBrowser" name="garages_text">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Times New Roman</family>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="openLinks">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="garages_label">
|
<widget class="QLabel" name="garages_label">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
@@ -90,6 +71,25 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QTextEdit" name="garages_text">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Times New Roman</family>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="gridLayoutWidget_5">
|
<widget class="QWidget" name="gridLayoutWidget_5">
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QTextBrowser" name="cities_text">
|
<widget class="QTextEdit" name="cities_text">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Times New Roman</family>
|
<family>Times New Roman</family>
|
||||||
@@ -132,8 +132,8 @@
|
|||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="openLinks">
|
<property name="readOnly">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QTextBrowser" name="dealerships_text">
|
<widget class="QTextEdit" name="dealerships_text">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Times New Roman</family>
|
<family>Times New Roman</family>
|
||||||
@@ -179,8 +179,8 @@
|
|||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="openLinks">
|
<property name="readOnly">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -213,7 +213,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QTextBrowser" name="agencies_text">
|
<widget class="QTextEdit" name="agencies_text">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Times New Roman</family>
|
<family>Times New Roman</family>
|
||||||
@@ -226,8 +226,8 @@
|
|||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="openLinks">
|
<property name="readOnly">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
|||||||
|
|
||||||
def check_garages(self):
|
def check_garages(self):
|
||||||
self.ui.garages_text.clear()
|
self.ui.garages_text.clear()
|
||||||
for garage in self.purchased_garages():
|
garages = self.purchased_garages()
|
||||||
|
for garage in garages:
|
||||||
self.ui.garages_text.append(garage)
|
self.ui.garages_text.append(garage)
|
||||||
|
self.ui.garages_text.scrollToAnchor(garages[0])
|
||||||
|
|
||||||
def add_garage(self):
|
def add_garage(self):
|
||||||
garage = self.ui.garage_edit.text().lower()
|
garage = self.ui.garage_edit.text().lower()
|
||||||
@@ -175,6 +177,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
|||||||
return
|
return
|
||||||
for city in visited_cities:
|
for city in visited_cities:
|
||||||
self.ui.cities_text.append(city)
|
self.ui.cities_text.append(city)
|
||||||
|
self.ui.cities_text.scrollToAnchor(visited_cities[0])
|
||||||
|
|
||||||
def add_city(self):
|
def add_city(self):
|
||||||
city = self.ui.city_edit.text().lower()
|
city = self.ui.city_edit.text().lower()
|
||||||
@@ -207,6 +210,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
|||||||
return
|
return
|
||||||
for dealer in visited_dealers:
|
for dealer in visited_dealers:
|
||||||
self.ui.dealerships_text.append(dealer)
|
self.ui.dealerships_text.append(dealer)
|
||||||
|
self.ui.dealerships_text.scrollToAnchor(visited_dealers[0])
|
||||||
|
|
||||||
def add_all_dealers(self):
|
def add_all_dealers(self):
|
||||||
all_cities = self.all_cities()
|
all_cities = self.all_cities()
|
||||||
@@ -225,6 +229,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
|||||||
return
|
return
|
||||||
for agency in visited_agencies:
|
for agency in visited_agencies:
|
||||||
self.ui.agencies_text.append(agency)
|
self.ui.agencies_text.append(agency)
|
||||||
|
self.ui.agencies_text.scrollToAnchor(visited_agencies[0])
|
||||||
|
|
||||||
def add_all_agencies(self):
|
def add_all_agencies(self):
|
||||||
all_cities = self.all_cities()
|
all_cities = self.all_cities()
|
||||||
|
|||||||
15
setup.py
15
setup.py
@@ -8,7 +8,9 @@ base = None
|
|||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
base = 'Win32GUI'
|
base = 'Win32GUI'
|
||||||
|
|
||||||
executables = [Executable('__init__.py', targetName='SaveWizard.exe', base=base)]
|
executables = [
|
||||||
|
Executable('init_main_program.py', targetName='SaveWizard.exe', base=base)
|
||||||
|
]
|
||||||
|
|
||||||
excludes = ['html', 'pydoc_data', 'unittest', 'xml', 'pwd', 'shlex', 'platform', 'webbrowser', 'pydoc', 'tty',
|
excludes = ['html', 'pydoc_data', 'unittest', 'xml', 'pwd', 'shlex', 'platform', 'webbrowser', 'pydoc', 'tty',
|
||||||
'inspect', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading']
|
'inspect', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading']
|
||||||
@@ -27,7 +29,14 @@ zip_include_packages = [
|
|||||||
'parsing', 'choice', 'main', 'second'
|
'parsing', 'choice', 'main', 'second'
|
||||||
]
|
]
|
||||||
|
|
||||||
include_files = ['dlls/imageformats', 'dlls/platforms', 'dlls/styles', 'SII_Decrypt.exe', 'configs']
|
include_files = [
|
||||||
|
'dlls/imageformats',
|
||||||
|
'dlls/platforms',
|
||||||
|
'dlls/styles',
|
||||||
|
'SII_Decrypt.exe',
|
||||||
|
('configs/ats', 'configs/ats'),
|
||||||
|
('configs/ets2', 'configs/ets2')
|
||||||
|
]
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
'build_exe': {
|
'build_exe': {
|
||||||
@@ -42,7 +51,7 @@ options = {
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SaveWizard',
|
name='SaveWizard',
|
||||||
version='1.2',
|
version='1.2.1',
|
||||||
description='For editing ETS2 sii files',
|
description='For editing ETS2 sii files',
|
||||||
executables=executables,
|
executables=executables,
|
||||||
options=options,
|
options=options,
|
||||||
|
|||||||
6
statics.py
Normal file
6
statics.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
update_config_name = "update.cfg"
|
||||||
|
github_link = "https://raw.githubusercontent.com/JDM170/SaveWizard/master/"
|
||||||
|
hash_chunk_size = 4096
|
||||||
15
util.py
15
util.py
@@ -4,9 +4,9 @@
|
|||||||
# from re import search, match, sub
|
# from re import search, match, sub
|
||||||
from re import search, match
|
from re import search, match
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
from hashlib import md5
|
||||||
|
from statics import hash_chunk_size
|
||||||
|
|
||||||
github_link = "https://raw.githubusercontent.com/JDM170/SaveWizard/master/"
|
|
||||||
update_config_name = "update.cfg"
|
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +28,17 @@ def show_message(icon, title, text):
|
|||||||
box.exec()
|
box.exec()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_md5(fn):
|
||||||
|
try:
|
||||||
|
hash_md5 = md5()
|
||||||
|
with open(fn, "rb") as f:
|
||||||
|
for chunk in iter(lambda: f.read(hash_chunk_size), b""):
|
||||||
|
hash_md5.update(chunk)
|
||||||
|
return hash_md5.hexdigest()
|
||||||
|
except FileNotFoundError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Stock functions
|
# Stock functions
|
||||||
def search_line(term, start=0, cancel=r"this_string_must_not_exist"):
|
def search_line(term, start=0, cancel=r"this_string_must_not_exist"):
|
||||||
global lines
|
global lines
|
||||||
|
|||||||
Reference in New Issue
Block a user