Fix bugs, add update system + tests + fix deployment/build system
This commit is contained in:
parent
981a11ce83
commit
b46ecacbd9
@ -7,8 +7,8 @@ VSVersionInfo(
|
|||||||
ffi=FixedFileInfo(
|
ffi=FixedFileInfo(
|
||||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||||
# Set not needed items to zero 0. Must always contain 4 elements.
|
# Set not needed items to zero 0. Must always contain 4 elements.
|
||||||
filevers=(1,0,0,1),
|
filevers=(1,0,0,0),
|
||||||
prodvers=(1,0,0,1),
|
prodvers=(1,0,0,0),
|
||||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||||
mask=0x3f,
|
mask=0x3f,
|
||||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||||
@ -32,12 +32,12 @@ VSVersionInfo(
|
|||||||
u'040904B0',
|
u'040904B0',
|
||||||
[StringStruct(u'CompanyName', u'EndMove Corp.'),
|
[StringStruct(u'CompanyName', u'EndMove Corp.'),
|
||||||
StringStruct(u'FileDescription', u'Scraping tool to recover all the images of a website.'),
|
StringStruct(u'FileDescription', u'Scraping tool to recover all the images of a website.'),
|
||||||
StringStruct(u'FileVersion', u'1.0.0.1'),
|
StringStruct(u'FileVersion', u'1.0.0.0'),
|
||||||
StringStruct(u'InternalName', u'webpic'),
|
StringStruct(u'InternalName', u'webpic'),
|
||||||
StringStruct(u'LegalCopyright', u'© Copyright 2022 EndMove. All rights reserved.'),
|
StringStruct(u'LegalCopyright', u'© Copyright 2022 EndMove. All rights reserved.'),
|
||||||
StringStruct(u'OriginalFilename', u'WebPicDownloader.exe'),
|
StringStruct(u'OriginalFilename', u'WebPicDownloader.exe'),
|
||||||
StringStruct(u'ProductName', u'WebPicDownloader'),
|
StringStruct(u'ProductName', u'WebPicDownloader'),
|
||||||
StringStruct(u'ProductVersion', u'1.0.0.1')])
|
StringStruct(u'ProductVersion', u'1.0.0.0')])
|
||||||
]),
|
]),
|
||||||
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
|
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
|
||||||
]
|
]
|
||||||
|
@ -19,11 +19,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "icon_file",
|
"optionDest": "icon_file",
|
||||||
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/assets/logo.ico"
|
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/webpicdownloader/assets/logo.ico"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "name",
|
"optionDest": "name",
|
||||||
"value": "WebPicDownloader_v1.0.0"
|
"value": "WebPicDownloader"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "ascii",
|
"optionDest": "ascii",
|
||||||
@ -47,7 +47,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "version_file",
|
"optionDest": "version_file",
|
||||||
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/versionfile.txt"
|
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/app_version_file.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "embed_manifest",
|
"optionDest": "embed_manifest",
|
||||||
@ -79,7 +79,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"optionDest": "datas",
|
"optionDest": "datas",
|
||||||
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/assets;assets/"
|
"value": "C:/Users/super/Documents/Developpement/Python/WebPicDownloader/webpicdownloader/assets;webpicdownloader/assets/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "excludes",
|
||||||
|
"value": "auto_py_to_exe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "excludes",
|
||||||
|
"value": "pyinstaller"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "excludes",
|
||||||
|
"value": "unittest"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nonPyinstallerOptions": {
|
"nonPyinstallerOptions": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from auto_py_to_exe import __main__ as apte
|
|
||||||
import pyinstaller_versionfile
|
import pyinstaller_versionfile
|
||||||
|
from auto_py_to_exe import __main__ as apte
|
||||||
|
from main import get_config
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file allows you to start auto-py in order to quickly and easily build the solution
|
This file allows you to start auto-py in order to quickly and easily build the solution
|
||||||
@ -9,7 +9,8 @@ into a viable .exe. Moreover this script will compile the meta data for windows.
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pyinstaller_versionfile.create_versionfile_from_input_file(
|
pyinstaller_versionfile.create_versionfile_from_input_file(
|
||||||
output_file="app_version_file.txt",
|
output_file="app_version_file.txt",
|
||||||
input_file="app_metadata.yml"
|
input_file="app_metadata.yml",
|
||||||
|
version=get_config().get('app_version')
|
||||||
)
|
)
|
||||||
apte.__name__ = '__main__'
|
apte.__name__ = '__main__'
|
||||||
apte.run()
|
apte.run()
|
5
main.py
5
main.py
@ -29,8 +29,9 @@ def get_config() -> dict:
|
|||||||
'app_name': 'WebPicDownloader',
|
'app_name': 'WebPicDownloader',
|
||||||
'app_folder': os.getcwd(),
|
'app_folder': os.getcwd(),
|
||||||
'app_version': '1.0.0', # This version must match with the version.txt at root
|
'app_version': '1.0.0', # This version must match with the version.txt at root
|
||||||
'app_version_date': '2022-09-05',
|
'app_version_date': '2022-09-11',
|
||||||
'app_version_source': 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/branch/dev/VERSION',
|
'app_depo_version': 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/branch/master/VERSION',
|
||||||
|
'app_depo_releases': 'https://git.endmove.eu/EndMove/WebPicDownloader/releases',
|
||||||
|
|
||||||
'sys_version_matcher': re.compile(r'^(\d{1,2}\.)(\d{1,2}\.)(\d{1,2})$'),
|
'sys_version_matcher': re.compile(r'^(\d{1,2}\.)(\d{1,2}\.)(\d{1,2})$'),
|
||||||
'sys_directory': get_sys_directory(),
|
'sys_directory': get_sys_directory(),
|
||||||
|
@ -12,27 +12,32 @@ class TestUpdateRegex(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
regex: Pattern = compile(r'^(\d{1,2}\.)(\d{1,2}\.)(\d{1,2})$')
|
regex: Pattern = compile(r'^(\d{1,2}\.)(\d{1,2}\.)(\d{1,2})$')
|
||||||
|
|
||||||
|
|
||||||
def test_first_version(self):
|
def test_first_version(self):
|
||||||
self.assertTrue(fullmatch(self.regex, '1.0.0'))
|
self.assertTrue(fullmatch(self.regex, '1.0.0'))
|
||||||
|
|
||||||
|
|
||||||
def test_patch_version(self):
|
def test_patch_version(self):
|
||||||
self.assertTrue(fullmatch(self.regex, '1.0.00'))
|
self.assertTrue(fullmatch(self.regex, '1.0.00'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.0.1'))
|
self.assertTrue(fullmatch(self.regex, '1.0.1'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.0.12'))
|
self.assertTrue(fullmatch(self.regex, '1.0.12'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.0.54'))
|
self.assertTrue(fullmatch(self.regex, '1.0.54'))
|
||||||
|
|
||||||
|
|
||||||
def test_minor_version(self):
|
def test_minor_version(self):
|
||||||
self.assertTrue(fullmatch(self.regex, '1.00.0'))
|
self.assertTrue(fullmatch(self.regex, '1.00.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.1.0'))
|
self.assertTrue(fullmatch(self.regex, '1.1.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.98.0'))
|
self.assertTrue(fullmatch(self.regex, '1.98.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '1.24.0'))
|
self.assertTrue(fullmatch(self.regex, '1.24.0'))
|
||||||
|
|
||||||
|
|
||||||
def test_major_version(self):
|
def test_major_version(self):
|
||||||
self.assertTrue(fullmatch(self.regex, '00.0.0'))
|
self.assertTrue(fullmatch(self.regex, '00.0.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '10.0.0'))
|
self.assertTrue(fullmatch(self.regex, '10.0.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '99.0.0'))
|
self.assertTrue(fullmatch(self.regex, '99.0.0'))
|
||||||
self.assertTrue(fullmatch(self.regex, '42.0.0'))
|
self.assertTrue(fullmatch(self.regex, '42.0.0'))
|
||||||
|
|
||||||
|
|
||||||
def test_bad_version(self):
|
def test_bad_version(self):
|
||||||
self.assertFalse(fullmatch(self.regex, '1.0.0000'))
|
self.assertFalse(fullmatch(self.regex, '1.0.0000'))
|
||||||
self.assertFalse(fullmatch(self.regex, '1.00000.0'))
|
self.assertFalse(fullmatch(self.regex, '1.00000.0'))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from urllib.error import HTTPError, URLError
|
from urllib.error import HTTPError, URLError
|
||||||
from test_update_regex import TestUpdateRegex
|
from test_update_regex import TestUpdateRegex
|
||||||
from webpicdownloader.util.UpdateUtils import fetch_version, is_new_version_available
|
from webpicdownloader.util.UpdateUtils import fetch_version, check_for_update
|
||||||
|
|
||||||
class TestUpdateUtils(unittest.TestCase):
|
class TestUpdateUtils(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
@ -11,32 +11,64 @@ class TestUpdateUtils(unittest.TestCase):
|
|||||||
* regex -> use UpdateRegex unittest regex.
|
* regex -> use UpdateRegex unittest regex.
|
||||||
* good_url -> use a permalink VERSION file.
|
* good_url -> use a permalink VERSION file.
|
||||||
* bad_url -> bad link that point a 404 error.
|
* bad_url -> bad link that point a 404 error.
|
||||||
* bad_version -> use a permalink VERSION file for wich version format is bad.
|
|
||||||
"""
|
"""
|
||||||
regex = TestUpdateRegex.regex
|
regex = TestUpdateRegex.regex
|
||||||
good_url = 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/commit/6b26b89c6901841faaa09154c185d202223492c2/VERSION'
|
good_url = 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/commit/6b26b89c6901841faaa09154c185d202223492c2/VERSION'
|
||||||
bad_url = 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/commit/bad-commit/VERSION'
|
bad_url = 'https://git.endmove.eu/EndMove/WebPicDownloader/raw/commit/bad-commit/VERSION'
|
||||||
bad_version = 'https://git.endmove.eu/EndMove/WebPicDownloader/src/commit/6b26b89c6901841faaa09154c185d202223492c2/app_version_file.txt'
|
|
||||||
|
|
||||||
def test_fetch_version__good_url(self):
|
def test_fetch_version__good_url(self):
|
||||||
|
"""
|
||||||
|
We test the recovery of the available version with a URL
|
||||||
|
indicating a correct version file.
|
||||||
|
"""
|
||||||
self.assertTrue(fetch_version(self.good_url) == '1.0.0')
|
self.assertTrue(fetch_version(self.good_url) == '1.0.0')
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_version__bad_url(self):
|
def test_fetch_version__bad_url(self):
|
||||||
|
"""
|
||||||
|
We test the recovery of the version with erroneous URLs,
|
||||||
|
or not leading to any specific file
|
||||||
|
"""
|
||||||
self.assertRaises(HTTPError, lambda: fetch_version(self.bad_url))
|
self.assertRaises(HTTPError, lambda: fetch_version(self.bad_url))
|
||||||
self.assertRaises(URLError, lambda: fetch_version('https://bad'))
|
self.assertRaises(URLError, lambda: fetch_version('https://bad'))
|
||||||
self.assertRaises(ValueError, lambda: fetch_version('bad'))
|
self.assertRaises(ValueError, lambda: fetch_version('bad'))
|
||||||
|
|
||||||
def test_is_new_version_available__new_version_available(self):
|
|
||||||
self.assertTrue(is_new_version_available('0.0.0', self.good_url, self.regex))
|
|
||||||
self.assertTrue(is_new_version_available('0.48.0', self.good_url, self.regex))
|
|
||||||
self.assertTrue(is_new_version_available('0.48.14', self.good_url, self.regex))
|
|
||||||
self.assertTrue(is_new_version_available('5.48.14', self.good_url, self.regex))
|
|
||||||
|
|
||||||
def test_is_new_version_available__no_new_version_available(self):
|
def test_check_for_update__new_version(self):
|
||||||
self.assertFalse(is_new_version_available('1.0.0', self.good_url, self.regex))
|
"""
|
||||||
|
We check the availability of an update with softwares whose
|
||||||
|
versions are different from the one indicated by the repository
|
||||||
|
(thus available update).
|
||||||
|
"""
|
||||||
|
self.assertTrue(check_for_update('0.0.0', self.good_url, self.regex))
|
||||||
|
self.assertTrue(check_for_update('0.48.0', self.good_url, self.regex))
|
||||||
|
self.assertTrue(check_for_update('0.48.14', self.good_url, self.regex))
|
||||||
|
self.assertTrue(check_for_update('5.48.14', self.good_url, self.regex))
|
||||||
|
|
||||||
def test_is_new_version_available__bad_version(self):
|
|
||||||
self.assertRaises(ValueError, lambda: is_new_version_available('1.0.0', self.bad_version, self.regex))
|
|
||||||
|
|
||||||
def test_is_new_version_available__bad_url(self):
|
def test_check_for_update__no_new_version(self):
|
||||||
self.assertRaises(HTTPError, lambda: is_new_version_available('1.0.0', self.bad_url, self.regex))
|
"""
|
||||||
|
We check the availability of an update with software that has the
|
||||||
|
same version as the one on the repository (so no update available).
|
||||||
|
"""
|
||||||
|
self.assertFalse(check_for_update('1.0.0', self.good_url, self.regex))
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_for_update__bad_version(self):
|
||||||
|
"""
|
||||||
|
We check for the availability of an update with an incorrect version
|
||||||
|
in the repository.
|
||||||
|
"""
|
||||||
|
self.assertRaises(ValueError, lambda: check_for_update(
|
||||||
|
'1.0.0',
|
||||||
|
'https://git.endmove.eu/EndMove/WebPicDownloader/src/commit/6b26b89c6901841faaa09154c185d202223492c2/app_version_file.txt',
|
||||||
|
self.regex
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_for_update__bad_url(self):
|
||||||
|
"""
|
||||||
|
We check the availability of an update with a bad repository url
|
||||||
|
"""
|
||||||
|
self.assertRaises(HTTPError, lambda: check_for_update('1.0.0', self.bad_url, self.regex))
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
|
import webbrowser
|
||||||
from webpicdownloader.controller.Frames import Frames
|
from webpicdownloader.controller.Frames import Frames
|
||||||
|
from webpicdownloader.util.UpdateUtils import check_for_update
|
||||||
|
|
||||||
|
|
||||||
class MainController:
|
class MainController:
|
||||||
@ -11,8 +13,8 @@ class MainController:
|
|||||||
|
|
||||||
@author Jérémi Nihart / EndMove
|
@author Jérémi Nihart / EndMove
|
||||||
@link https://git.endmove.eu/EndMove/WebPicDownloader
|
@link https://git.endmove.eu/EndMove/WebPicDownloader
|
||||||
@version 1.0.0
|
@version 1.0.1
|
||||||
@since 2022-08-30
|
@since 2022-09-11
|
||||||
"""
|
"""
|
||||||
# Variables
|
# Variables
|
||||||
__config: dict = None
|
__config: dict = None
|
||||||
@ -64,8 +66,13 @@ class MainController:
|
|||||||
[event function for view]
|
[event function for view]
|
||||||
=> Event launched when a check for available updates is requested.
|
=> Event launched when a check for available updates is requested.
|
||||||
"""
|
"""
|
||||||
# TODO write the function
|
try:
|
||||||
self.show_information_dialog(self.get_config('app_name'), "Oupss, this functionality isn't available yet!\nTry it again later.")
|
if check_for_update(self.get_config('app_version'), self.get_config('app_depo_version'), self.get_config('sys_version_matcher')):
|
||||||
|
if self.show_question_dialog(self.get_config('app_name'), "An update is available! Would you like to visit the release page to download the latest version?"):
|
||||||
|
webbrowser.open(self.get_config('app_depo_releases'))
|
||||||
|
else: self.show_information_dialog(self.get_config('app_name'), "No update available.")
|
||||||
|
except Exception as e:
|
||||||
|
self.show_information_dialog(self.get_config('app_name'), f"An error occured: {e}.", 'error')
|
||||||
|
|
||||||
def on_about(self) -> None:
|
def on_about(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -85,12 +92,13 @@ class MainController:
|
|||||||
"""
|
"""
|
||||||
self.__view.show_frame(frame)
|
self.__view.show_frame(frame)
|
||||||
|
|
||||||
def get_config(self, name: str) -> str|int:
|
def get_config(self, name: str):
|
||||||
"""
|
"""
|
||||||
[function for controller]
|
[function for controller]
|
||||||
=> Allows controllers to access the application's configuration.
|
=> Allows controllers to access the application's configuration.
|
||||||
|
|
||||||
* :name: -> The name of the configuration parameter for which we want to access the configured value.
|
* :name: -> The name of the configuration parameter for which we want to access the configured value.
|
||||||
|
* THROWABLE -> If the key is wrong, throw a ValueError.
|
||||||
"""
|
"""
|
||||||
if self.__config.get(name):
|
if self.__config.get(name):
|
||||||
return self.__config.get(name)
|
return self.__config.get(name)
|
||||||
|
@ -6,19 +6,23 @@ from urllib.error import HTTPError
|
|||||||
def fetch_version(url: str) -> str:
|
def fetch_version(url: str) -> str:
|
||||||
"""
|
"""
|
||||||
Retrieve the latest webpicdownloader version available.
|
Retrieve the latest webpicdownloader version available.
|
||||||
|
This method, only accept 200 http response.
|
||||||
|
|
||||||
* :url: -> Url of the "VERSION" file on the repository.
|
* :url: -> Url of the "VERSION" file on the repository.
|
||||||
* RETURN -> the latests 'VERSION' file content.
|
* RETURN -> the latests 'VERSION' file content.
|
||||||
* THROWABLE -> can raise HTTP or URL error see urllib doc.
|
* THROWABLE -> can raise HTTP or URL error see urllib doc.
|
||||||
"""
|
"""
|
||||||
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/604.1"}
|
request = http.Request(
|
||||||
request = http.Request(url=url, headers=headers, method='GET')
|
url=url,
|
||||||
|
headers={'User-Agent': "Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/604.1"},
|
||||||
|
method='GET'
|
||||||
|
)
|
||||||
response = http.urlopen(request)
|
response = http.urlopen(request)
|
||||||
if response.getcode() != 200:
|
if response.getcode() != 200:
|
||||||
raise HTTPError("Bad response returned by server")
|
raise HTTPError("Bad response returned by server")
|
||||||
return response.read().decode('utf-8')
|
return response.read().decode('utf-8')
|
||||||
|
|
||||||
def is_new_version_available(version_current: str, version_url: str, version_pattern: Pattern) -> bool:
|
def check_for_update(version_current: str, version_url: str, version_pattern: Pattern) -> bool:
|
||||||
"""
|
"""
|
||||||
Verify if a new version is available.
|
Verify if a new version is available.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user