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__
|
||||
/parsing/__pycache__
|
||||
/choice/__pycache__
|
||||
/main/__pycache__
|
||||
/second/__pycache__
|
||||
/choice/form.py
|
||||
/main/__pycache__
|
||||
/main/form.py
|
||||
/second/__pycache__
|
||||
/second/form.py
|
||||
|
||||
## Ignoring UPX
|
||||
/upx
|
||||
|
||||
## Ignoring build from cx_Freeze
|
||||
/prog_build
|
||||
|
||||
|
||||
10
README.md
10
README.md
@@ -17,11 +17,11 @@ Features:
|
||||
|
||||
***
|
||||
|
||||
Requirments:
|
||||
* Python 3.7.7
|
||||
* PyQt5 5.15.0
|
||||
* requests 2.24.0
|
||||
* cx_Freeze 6.2
|
||||
Requirments to build project:
|
||||
* Python >=3.5.4
|
||||
* PyQt5 >=5.6.0
|
||||
* requests >=2.24.0
|
||||
* cx_Freeze >=6.0 (or PyInstaller >=3.6)
|
||||
|
||||
***
|
||||
|
||||
|
||||
49
build.spec
49
build.spec
@@ -1,38 +1,33 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(['__init__.py'],
|
||||
app = Analysis(
|
||||
['init_main_program.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,
|
||||
('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,
|
||||
upx=True,
|
||||
console=False )
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
console=False
|
||||
)
|
||||
app_coll = COLLECT(
|
||||
app_exe,
|
||||
app.binaries,
|
||||
app.zipfiles,
|
||||
app.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='build')
|
||||
name='app_build'
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from ast import literal_eval
|
||||
from .form import Ui_Choice
|
||||
from main.script import MainWindow
|
||||
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):
|
||||
|
||||
@@ -1 +1 @@
|
||||
pyinstaller build.spec
|
||||
pyinstaller build.spec --noupx
|
||||
|
||||
13
dataIO.py
13
dataIO.py
@@ -2,9 +2,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from json import decoder, load, dump
|
||||
from os import replace
|
||||
from os.path import splitext
|
||||
from random import randint
|
||||
|
||||
|
||||
class DataIO:
|
||||
@@ -30,18 +27,12 @@ class DataIO:
|
||||
|
||||
def save_json(self, filename, data):
|
||||
"""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:
|
||||
dump(data, f, indent=4, sort_keys=True, separators=(",", " : "))
|
||||
# return data (?)
|
||||
dump(data, f, indent=4, separators=(",", " : "))
|
||||
try:
|
||||
self._read_json(tmp_file)
|
||||
self._read_json(filename)
|
||||
except decoder.JSONDecodeError:
|
||||
return False
|
||||
replace(tmp_file, filename)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -2,61 +2,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from requests import get
|
||||
from hashlib import md5
|
||||
from ast import literal_eval
|
||||
import os
|
||||
from statics import github_link, update_config_name
|
||||
from dataIO import dataIO
|
||||
from util import github_link, update_config_name
|
||||
from util import generate_md5
|
||||
|
||||
|
||||
def send_response(txt):
|
||||
response = get(txt)
|
||||
return response if response.status_code == 200 else False
|
||||
def get_response_result(url):
|
||||
response = get(url)
|
||||
return response.status_code == 200, response
|
||||
|
||||
|
||||
def generate_md5(fn):
|
||||
hash_md5 = md5()
|
||||
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()
|
||||
def check_path(path):
|
||||
current_path = os.getcwd()
|
||||
for item in path.split("/"):
|
||||
temp = os.path.join(temp, item)
|
||||
if not os.path.exists(temp):
|
||||
current_path = os.path.join(current_path, item)
|
||||
if not os.path.exists(current_path):
|
||||
if item.find(".json") > 0:
|
||||
f = open(temp, "w")
|
||||
f.close()
|
||||
open(current_path, "w").close()
|
||||
else:
|
||||
os.mkdir(temp)
|
||||
os.mkdir(current_path)
|
||||
|
||||
|
||||
def check_remote_hashes():
|
||||
response = send_response(github_link + "configs/version.cfg")
|
||||
if response is not False:
|
||||
response_status, response = get_response_result(github_link + "configs/version.cfg")
|
||||
if response_status:
|
||||
remote_cfg = literal_eval(response.text)
|
||||
need_to_be_updated = []
|
||||
need_update = []
|
||||
for key, value in remote_cfg.items():
|
||||
path = key.split("_")
|
||||
path = "configs/{}/{}.json".format(path[0], path[1])
|
||||
if generate_md5(path) != value:
|
||||
need_to_be_updated.append(path)
|
||||
return need_to_be_updated
|
||||
need_update.append(path)
|
||||
return need_update
|
||||
return False
|
||||
|
||||
|
||||
def update_configs(is_save, cfg_list):
|
||||
if is_save in (0, 1):
|
||||
for cfg in cfg_list:
|
||||
check_files(cfg)
|
||||
response = send_response(github_link + cfg)
|
||||
if response is not False:
|
||||
check_path(cfg)
|
||||
response_status, response = get_response_result(github_link + cfg)
|
||||
if response_status:
|
||||
remote_cfg = literal_eval(response.text)
|
||||
if dataIO.is_valid_json(cfg) or os.path.exists(cfg):
|
||||
dataIO.save_json(cfg, remote_cfg)
|
||||
|
||||
@@ -39,25 +39,6 @@
|
||||
</rect>
|
||||
</property>
|
||||
<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">
|
||||
<widget class="QLabel" name="garages_label">
|
||||
<property name="font">
|
||||
@@ -90,6 +71,25 @@
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
<widget class="QWidget" name="gridLayoutWidget_5">
|
||||
@@ -119,7 +119,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTextBrowser" name="cities_text">
|
||||
<widget class="QTextEdit" name="cities_text">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Times New Roman</family>
|
||||
@@ -132,8 +132,8 @@
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -166,7 +166,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTextBrowser" name="dealerships_text">
|
||||
<widget class="QTextEdit" name="dealerships_text">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Times New Roman</family>
|
||||
@@ -179,8 +179,8 @@
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -213,7 +213,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTextBrowser" name="agencies_text">
|
||||
<widget class="QTextEdit" name="agencies_text">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Times New Roman</family>
|
||||
@@ -226,8 +226,8 @@
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -115,8 +115,10 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
||||
|
||||
def check_garages(self):
|
||||
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.scrollToAnchor(garages[0])
|
||||
|
||||
def add_garage(self):
|
||||
garage = self.ui.garage_edit.text().lower()
|
||||
@@ -175,6 +177,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
||||
return
|
||||
for city in visited_cities:
|
||||
self.ui.cities_text.append(city)
|
||||
self.ui.cities_text.scrollToAnchor(visited_cities[0])
|
||||
|
||||
def add_city(self):
|
||||
city = self.ui.city_edit.text().lower()
|
||||
@@ -207,6 +210,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
||||
return
|
||||
for dealer in visited_dealers:
|
||||
self.ui.dealerships_text.append(dealer)
|
||||
self.ui.dealerships_text.scrollToAnchor(visited_dealers[0])
|
||||
|
||||
def add_all_dealers(self):
|
||||
all_cities = self.all_cities()
|
||||
@@ -225,6 +229,7 @@ class SecondWindow(QDialog, Ui_SecondWindow):
|
||||
return
|
||||
for agency in visited_agencies:
|
||||
self.ui.agencies_text.append(agency)
|
||||
self.ui.agencies_text.scrollToAnchor(visited_agencies[0])
|
||||
|
||||
def add_all_agencies(self):
|
||||
all_cities = self.all_cities()
|
||||
|
||||
15
setup.py
15
setup.py
@@ -8,7 +8,9 @@ base = None
|
||||
if platform == 'win32':
|
||||
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',
|
||||
'inspect', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading']
|
||||
@@ -27,7 +29,14 @@ zip_include_packages = [
|
||||
'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 = {
|
||||
'build_exe': {
|
||||
@@ -42,7 +51,7 @@ options = {
|
||||
|
||||
setup(
|
||||
name='SaveWizard',
|
||||
version='1.2',
|
||||
version='1.2.1',
|
||||
description='For editing ETS2 sii files',
|
||||
executables=executables,
|
||||
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
|
||||
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 = []
|
||||
|
||||
|
||||
@@ -28,6 +28,17 @@ def show_message(icon, title, text):
|
||||
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
|
||||
def search_line(term, start=0, cancel=r"this_string_must_not_exist"):
|
||||
global lines
|
||||
|
||||
Reference in New Issue
Block a user