* 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:
2020-08-21 23:38:00 +07:00
parent 33ce4d1148
commit 34f38b5a59
13 changed files with 128 additions and 120 deletions

7
.gitignore vendored
View File

@@ -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

View File

@@ -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)
*** ***

View File

@@ -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')

View File

@@ -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):

View File

@@ -1 +1 @@
pyinstaller build.spec pyinstaller build.spec --noupx

View File

@@ -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

View File

@@ -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)

View File

@@ -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>

View File

@@ -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()

View File

@@ -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
View 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
View File

@@ -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