From 34f38b5a59e2593105ba27338856d4c81b5c9a7c Mon Sep 17 00:00:00 2001
From: JDM170 <30170278+JDM170@users.noreply.github.com>
Date: Fri, 21 Aug 2020 23:38:00 +0700
Subject: [PATCH] Update
* Updated build.spec for PyInstaller build
* Some code and typo fixes
Signed-off-by: JDM170 <30170278+JDM170@users.noreply.github.com>
---
.gitignore | 7 +++-
README.md | 10 ++---
build.spec | 65 +++++++++++++----------------
choice/script.py | 2 +-
compile_pyinstaller.bat | 2 +-
dataIO.py | 13 +-----
__init__.py => init_main_program.py | 0
parsing/script.py | 50 +++++++++-------------
second/form.ui | 56 ++++++++++++-------------
second/script.py | 7 +++-
setup.py | 15 +++++--
statics.py | 6 +++
util.py | 15 ++++++-
13 files changed, 128 insertions(+), 120 deletions(-)
rename __init__.py => init_main_program.py (100%)
create mode 100644 statics.py
diff --git a/.gitignore b/.gitignore
index 40e59bb..da2ee48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/README.md b/README.md
index 73c6639..6657dcd 100644
--- a/README.md
+++ b/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)
***
diff --git a/build.spec b/build.spec
index e37f866..a34cf60 100644
--- a/build.spec
+++ b/build.spec
@@ -1,38 +1,33 @@
# -*- 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')
diff --git a/choice/script.py b/choice/script.py
index 2e2b797..4251a1a 100644
--- a/choice/script.py
+++ b/choice/script.py
@@ -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):
diff --git a/compile_pyinstaller.bat b/compile_pyinstaller.bat
index c3d2dfc..25d6f9e 100644
--- a/compile_pyinstaller.bat
+++ b/compile_pyinstaller.bat
@@ -1 +1 @@
-pyinstaller build.spec
+pyinstaller build.spec --noupx
diff --git a/dataIO.py b/dataIO.py
index d212344..e2d6192 100644
--- a/dataIO.py
+++ b/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
diff --git a/__init__.py b/init_main_program.py
similarity index 100%
rename from __init__.py
rename to init_main_program.py
diff --git a/parsing/script.py b/parsing/script.py
index 0fa6357..2b0d725 100644
--- a/parsing/script.py
+++ b/parsing/script.py
@@ -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)
diff --git a/second/form.ui b/second/form.ui
index 5484325..f4e6f53 100644
--- a/second/form.ui
+++ b/second/form.ui
@@ -39,25 +39,6 @@
- -
-
-
-
- Times New Roman
- 11
-
-
-
- false
-
-
- Qt::ScrollBarAlwaysOff
-
-
- false
-
-
-
-
@@ -90,6 +71,25 @@
+ -
+
+
+
+ Times New Roman
+ 11
+
+
+
+ false
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ true
+
+
+
@@ -119,7 +119,7 @@
-
-
+
Times New Roman
@@ -132,8 +132,8 @@
Qt::ScrollBarAlwaysOff
-
- false
+
+ true
@@ -166,7 +166,7 @@
-
-
+
Times New Roman
@@ -179,8 +179,8 @@
Qt::ScrollBarAlwaysOff
-
- false
+
+ true
@@ -213,7 +213,7 @@
-
-
+
Times New Roman
@@ -226,8 +226,8 @@
Qt::ScrollBarAlwaysOff
-
- false
+
+ true
diff --git a/second/script.py b/second/script.py
index e7f38d2..a053583 100644
--- a/second/script.py
+++ b/second/script.py
@@ -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()
diff --git a/setup.py b/setup.py
index 02020ea..de23fb1 100644
--- a/setup.py
+++ b/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,
diff --git a/statics.py b/statics.py
new file mode 100644
index 0000000..dcc579e
--- /dev/null
+++ b/statics.py
@@ -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
diff --git a/util.py b/util.py
index 5d7c591..3b59091 100644
--- a/util.py
+++ b/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