pyship 0.1.6__py3-none-any.whl → 0.1.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyship/_version_.py CHANGED
@@ -2,7 +2,7 @@ from pyshipupdate import __author__ as pyship_author
2
2
 
3
3
  __application_name__ = "pyship"
4
4
  __author__ = pyship_author
5
- __version__ = "0.1.6"
5
+ __version__ = "0.1.7"
6
6
  __title__ = __application_name__
7
7
  __author_email__ = "j@abel.co"
8
8
  __url__ = "https://github.com/jamesabel/pyship"
pyship/create_launcher.py CHANGED
@@ -4,6 +4,7 @@ import subprocess
4
4
 
5
5
  from typeguard import typechecked
6
6
  from balsa import get_logger
7
+ from semver import VersionInfo
7
8
 
8
9
  from pyshipupdate import mkdirs
9
10
  import pyship
@@ -99,6 +100,7 @@ def create_pyship_launcher(target_app_info: AppInfo, app_path_output: Path):
99
100
  # avoid re-building launcher if its functionality wouldn't change
100
101
  assert isinstance(target_app_info.author, str)
101
102
  assert isinstance(target_app_info.is_gui, bool)
103
+ assert isinstance(target_app_info.version, VersionInfo)
102
104
  metadata = calculate_metadata(target_app_info.name, target_app_info.author, target_app_info.version, Path(launcher_module_dir), icon_path, target_app_info.is_gui)
103
105
  if not launcher_exe_path.exists() or metadata != load_metadata(app_path_output, metadata_filename):
104
106
  pyship_print(f'building launcher ("{launcher_exe_path}")')
pyship/download.py CHANGED
@@ -32,6 +32,22 @@ def file_download(url: str, destination_folder: Path, file_name: Path):
32
32
  return destination_path
33
33
 
34
34
 
35
+ def is_within_directory(directory: Path, target: Path):
36
+ abs_directory = directory.absolute()
37
+ abs_target = target.absolute()
38
+ prefix = os.path.commonprefix([abs_directory, abs_target])
39
+ return prefix == str(abs_directory)
40
+
41
+
42
+ def safe_extract(tar, path: Path = Path(".")):
43
+ # for CVE-2007-4559
44
+ for member in tar.getmembers():
45
+ member_path = Path(path, member.name)
46
+ if not is_within_directory(path, member_path):
47
+ raise Exception("Attempted Path Traversal in Tar File")
48
+ tar.extractall(path, None, numeric_owner=False)
49
+
50
+
35
51
  @typechecked
36
52
  def extract(source_folder: Path, source_file: Path, destination_folder: Path):
37
53
  mkdirs(destination_folder, remove_first=True)
@@ -43,9 +59,9 @@ def extract(source_folder: Path, source_file: Path, destination_folder: Path):
43
59
  zf.extractall(destination_folder)
44
60
  elif source_file.suffix == ".tgz":
45
61
  with tarfile.open(source) as tf:
46
- tf.extractall(destination_folder)
62
+ safe_extract(tf, destination_folder)
47
63
  elif source_file.suffix == ".gz":
48
64
  with tarfile.open(source) as tf:
49
- tf.extractall(destination_folder)
65
+ safe_extract(tf, destination_folder)
50
66
  else:
51
67
  raise Exception(f"Unsupported file type {source_file.suffix} ({source_file})")
@@ -6,6 +6,7 @@ import appdirs
6
6
  import re
7
7
  import logging
8
8
  import subprocess
9
+ from typing import Union
9
10
 
10
11
  from ismain import is_main
11
12
  from balsa import HandlerType, get_logger
@@ -73,7 +74,7 @@ def setup_logging(is_gui: bool, report_exceptions: bool) -> bool:
73
74
  return verbose
74
75
 
75
76
 
76
- def launch(additional_path: Path = None, app_dir: Path = None) -> int:
77
+ def launch(additional_path: Union[Path, None] = None, app_dir: Union[Path, None] = None) -> int:
77
78
  """
78
79
  launch the pyship app
79
80
  :param additional_path - additional search path for app (mainly for testing)
@@ -97,8 +98,8 @@ def launch(additional_path: Path = None, app_dir: Path = None) -> int:
97
98
  target_app_author = __author__
98
99
 
99
100
  for metadata_file_path in app_dir.glob("*_metadata.json"):
100
- with metadata_file_path.open() as f:
101
- metadata = json.load(f)
101
+ with metadata_file_path.open() as metadata_file:
102
+ metadata = json.load(metadata_file)
102
103
  target_app_name = metadata.get("app")
103
104
  target_app_author = metadata.get("author", target_app_author)
104
105
  is_gui = metadata.get("is_gui", is_gui)
@@ -187,7 +188,7 @@ def launch(additional_path: Path = None, app_dir: Path = None) -> int:
187
188
  log_function(out)
188
189
 
189
190
  # log, and possibly print, each line of output from the process
190
- for name, std_x, f in [("stdout", std_out, sys.stdout), ("stderr", std_err, sys.stderr)]:
191
+ for name, std_x, sys_f in [("stdout", std_out, sys.stdout), ("stderr", std_err, sys.stderr)]:
191
192
  if std_x is not None and len(std_x.strip()) > 0:
192
193
  for so_line in std_x.splitlines():
193
194
  so_line_strip = so_line.strip()
@@ -195,7 +196,7 @@ def launch(additional_path: Path = None, app_dir: Path = None) -> int:
195
196
  log.info(f"{name}:{so_line_strip}") # when logging, start with the name of the output string (stdout, stderr)
196
197
 
197
198
  # output stdout, stderr that came (directly) from the process
198
- print(std_x, file=f)
199
+ print(std_x, file=sys_f)
199
200
 
200
201
  log.info(f"{return_code=}")
201
202
 
pyship/pyship.py CHANGED
@@ -7,6 +7,7 @@ from attr import attrs
7
7
  from typeguard import typechecked
8
8
  from awsimple import S3Access
9
9
  from balsa import get_logger
10
+ from semver import VersionInfo
10
11
 
11
12
  from pyship import __application_name__ as pyship_application_name
12
13
  from pyship import __author__ as pyship_author
@@ -32,7 +33,7 @@ class PyShip:
32
33
  cloud_id: Union[str, None] = None # e.g. AWS Access Key ID
33
34
  cloud_secret: Union[str, None] = None # e.g. AWS Secret Access Key
34
35
  cloud_access: Union[PyShipCloud, None] = None # making this accessible outside this class aids in testing, especially when mocking
35
- upload: bool = True # set to False to tell pyship to not attempt to perform file upload to the cloud (e.g. installer, clip files to AWS S3)
36
+ upload: bool = True # set to False in order to tell pyship to not attempt to perform file upload to the cloud (e.g. installer, clip files to AWS S3)
36
37
 
37
38
  @typechecked
38
39
  def ship(self) -> Path:
@@ -63,6 +64,7 @@ class PyShip:
63
64
  clip_dir = create_clip(target_app_info, app_dir, True, Path(self.project_dir, self.dist_dir), self.cache_dir, self.find_links)
64
65
 
65
66
  clip_file_path = create_clip_file(clip_dir) # create clip file
67
+ assert isinstance(target_app_info.version, VersionInfo)
66
68
  installer_exe_path = run_nsis(target_app_info, target_app_info.version, app_dir) # create installer
67
69
 
68
70
  if self.upload:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyship
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: freezer, installer and updater for Python applications
5
5
  Home-page: https://github.com/jamesabel/pyship
6
6
  Download-URL: https://github.com/jamesabel/pyship
@@ -1,21 +1,21 @@
1
1
  pyship/__init__.py,sha256=x7jisL_D4Wuyw5tfmyLz57WlRLX9QQYpkb3Vne_J3W0,1336
2
2
  pyship/__main__.py,sha256=mn9BUEsE52gyI7SLrXh_dBxLwD335iVG_iqRCNqocq4,86
3
- pyship/_version_.py,sha256=s-tyBvcMBAL-DIOAUGlD0JGMe-peqnUrSIg7hxunfSY,389
3
+ pyship/_version_.py,sha256=_lpeahvzNw7RLUbyDSBVoziS-tN4LJxasGcrBlkALBo,389
4
4
  pyship/app_info.py,sha256=mhbwJHkoWek1FRv9dwRlrf_8ssNK-UtDhvnZ-8kWQFo,7347
5
5
  pyship/arguments.py,sha256=p4cA8FwbNSZqg4XI6LsYit1QN7TpAWWZH2xrgLf-f-g,1882
6
6
  pyship/atomic_zip.py,sha256=HEZuHEatyWAGqZcvS_EoByQQRCQph5ajkszfZ3OxnRU,1366
7
7
  pyship/clip.py,sha256=kmdbnzJbgD9ggBEUqs73_p2kac2looaOeGItk9N50xo,8237
8
8
  pyship/cloud.py,sha256=FDJvTlURrtA00z3a8fWkR_K7YzURNKnd0NypJQKxHAo,1264
9
9
  pyship/constants.py,sha256=FVkr1c9XDkaXyQnL1bEP-dWSbk4SUkrRuVQYPIxHMaA,19
10
- pyship/create_launcher.py,sha256=vIZi5ABVmfXKFc9IHjYMkyAVbRKkSIxWgvHSdIyNrD8,6146
11
- pyship/download.py,sha256=inG18XKZ1qhOam27prKT0cTUx1IXRQooUPiIezZ_xf8,1871
10
+ pyship/create_launcher.py,sha256=HQby4dmnBnSbohspex8TaCgu-jEaEjLb1QGE76D_ky4,6247
11
+ pyship/download.py,sha256=QHbdVwxLNBToMEC0tOF2ZquDpoydRu0-cj7LOERr5Q4,2460
12
12
  pyship/get-pip.py,sha256=BC5otuX7znr6F8Llv4oQLwLDp22R0GwHmThf0UIHRHI,1829954
13
13
  pyship/logging.py,sha256=cIB7487tN8TsKeDHwwzjA30rHRW5Ci5GA5uPbaEXaY0,966
14
14
  pyship/main.py,sha256=pALpy8ooWsKkUpWUtGWO567I9u1fbIFWdBU0dnWm2K4,866
15
15
  pyship/nsis.py,sha256=QhG8FMwFZRsoPQbntCSCr5av1NNqgjksinhfxXpc0Vg,12744
16
16
  pyship/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  pyship/pyship.ico,sha256=9oiMtmA7NiBmxM0NmMJQU5jXmnbEWCdqTaO3XvJ7ozY,103500
18
- pyship/pyship.py,sha256=tqTd6kOU7i_LP9VCfSCcGZBpGU8OfPiCxb7arRAIGuc,5444
18
+ pyship/pyship.py,sha256=vMeFK940mIReKTMy0x-hFvTHXfATt97tL5knyK7R_9I,5554
19
19
  pyship/pyship_custom_print.py,sha256=WHgZNZNiKwQjKmxdsBrn7aJfG5VJdfQ1-9AC_tg5MxE,651
20
20
  pyship/pyship_exceptions.py,sha256=teUOh3FuRUU9hyv7L4owACQZPWNdwpYTEz6l-Ao35nw,959
21
21
  pyship/pyship_get_icon.py,sha256=FwglA67RXX0lhW9baIGsQy3_T4hVsVkBmvAhPyuhHLo,2016
@@ -24,13 +24,13 @@ pyship/pyship_subprocess.py,sha256=hH4MW_j2zLJLDmLDkkl2JWupXrvSemAeCPAEtPdSGyk,3
24
24
  pyship/launcher/__init__.py,sha256=25vVghziYIHDBA0mCaGqhj6hWxxjQqlm4LrY0Hem0YY,245
25
25
  pyship/launcher/__main__.py,sha256=KhFSf1RU5Cj15y0c4FlzvIvDpWWi9NKYy0gzJ-w7KQE,115
26
26
  pyship/launcher/hash.py,sha256=THEh8G-StEJeh5tH24RnAQpYB0Zv1nnBwqOoStN6_NY,1153
27
- pyship/launcher/launcher.py,sha256=XI0X4NvYYxz88dYf9_Fk7D1D_Y0qC1ZRfef1RFB4r5g,10275
27
+ pyship/launcher/launcher.py,sha256=AmjAwt8VbQTOVmRC-vUd7Cm-KS3ALYe1RLSxmcutthY,10359
28
28
  pyship/launcher/metadata.py,sha256=vkf70w_eX8EZbMDHFKqBWW1kn0RyZl70z4DGsLCahmA,1666
29
29
  pyship/launcher/restart_monitor.py,sha256=jfzchLxGuC_xUNdPAr849FhAdozJ6BX9M-gqLd-gGIA,952
30
30
  pyship/patch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  pyship/patch/pyship_patch.py,sha256=KgObD80QPeOhu1KCdhdQzn-4AnyzCUxIGWKj22BjTCc,1256
32
- pyship-0.1.6.dist-info/LICENSE,sha256=wJpPh6rC_YhbTZ7ZIy1VjrqeLdJ8Pz0ppx2MUi7s8Dg,1088
33
- pyship-0.1.6.dist-info/METADATA,sha256=ZEZv2MqEiTzDYtbXX3_6u-xhynfaIFW3lP2wEFYLWw8,1361
34
- pyship-0.1.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
35
- pyship-0.1.6.dist-info/top_level.txt,sha256=mlozeft-UInVAceSajzNvtkn2vPa8El9j0RulsTVtlU,7
36
- pyship-0.1.6.dist-info/RECORD,,
32
+ pyship-0.1.7.dist-info/LICENSE,sha256=wJpPh6rC_YhbTZ7ZIy1VjrqeLdJ8Pz0ppx2MUi7s8Dg,1088
33
+ pyship-0.1.7.dist-info/METADATA,sha256=0vrDjPX1xcZbErIhF_WDmKFPVRgviw4a0iJhEPLUm00,1361
34
+ pyship-0.1.7.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
35
+ pyship-0.1.7.dist-info/top_level.txt,sha256=mlozeft-UInVAceSajzNvtkn2vPa8El9j0RulsTVtlU,7
36
+ pyship-0.1.7.dist-info/RECORD,,
File without changes