mpflash 1.25.1__py3-none-any.whl → 1.25.2__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.
@@ -3,6 +3,7 @@ Module to run mpremote commands, and retry on failure or timeout
3
3
  """
4
4
 
5
5
  import contextlib
6
+ import re
6
7
  import sys
7
8
  import time
8
9
  from pathlib import Path
@@ -22,6 +23,8 @@ if sys.version_info >= (3, 11):
22
23
  else:
23
24
  import tomli as tomllib # type: ignore
24
25
 
26
+ import tomli_w
27
+
25
28
  ###############################################################################################
26
29
  HERE = Path(__file__).parent
27
30
 
@@ -61,6 +64,13 @@ class MPRemoteBoard:
61
64
  self.build = ""
62
65
  self.location = location # USB location
63
66
  self.toml = {}
67
+ portinfo = list(serial.tools.list_ports.grep(serialport)) # type: ignore
68
+ if not portinfo or len(portinfo) != 1:
69
+ self.vid = 0x00
70
+ self.pid = 0x00
71
+ else:
72
+ self.vid = portinfo[0].vid
73
+ self.pid = portinfo[0].pid
64
74
  if update:
65
75
  self.get_mcu_info()
66
76
 
@@ -76,7 +86,14 @@ class MPRemoteBoard:
76
86
 
77
87
  @property
78
88
  def board(self) -> str:
79
- return self._board_id.split("-")[0]
89
+ _board = self._board_id.split("-")[0]
90
+ # Workaround for Pimoroni boards
91
+ if not "-" in self._board_id:
92
+ # match with the regex : (.*)(_\d+MB)$
93
+ match = re.match(r"(.*)_(\d+MB)$", self._board_id)
94
+ if match:
95
+ _board = match.group(1)
96
+ return _board
80
97
 
81
98
  @board.setter
82
99
  def board(self, value: str) -> None:
@@ -84,7 +101,14 @@ class MPRemoteBoard:
84
101
 
85
102
  @property
86
103
  def variant(self) -> str:
87
- return self._board_id.split("-")[1] if "-" in self._board_id else ""
104
+ _variant = self._board_id.split("-")[1] if "-" in self._board_id else ""
105
+ if not _variant:
106
+ # Workaround for Pimoroni boards
107
+ # match with the regex : (.*)(_\d+MB)$
108
+ match = re.match(r"(.*)_(\d+MB)$", self._board_id)
109
+ if match:
110
+ _variant = match.group(2)
111
+ return _variant
88
112
 
89
113
  @variant.setter
90
114
  def variant(self, value: str) -> None:
@@ -225,6 +249,39 @@ class MPRemoteBoard:
225
249
  else:
226
250
  log.trace(f"Did not find a board_info.toml: {result}")
227
251
 
252
+ def set_board_info_toml(self, timeout: int = 1):
253
+ """
254
+ Writes the current board information to the board_info.toml file on the connected board.
255
+
256
+ Parameters:
257
+ - timeout (int): The timeout value in seconds.
258
+ """
259
+ if not self.connected:
260
+ raise MPFlashError("Board is not connected")
261
+ if not self.toml:
262
+ log.warning("No board_info.toml to write")
263
+ return
264
+ # write the toml file to a temp file, then copy to the board
265
+
266
+ toml_path = HERE / "tmp_board_info.toml"
267
+ try:
268
+ with open(toml_path, "wb") as f:
269
+ tomli_w.dump(self.toml, f)
270
+
271
+ log.debug(f"Writing board_info.toml to {self.serialport}")
272
+ rc, result = self.run_command(
273
+ ["cp", str(toml_path), ":board_info.toml"],
274
+ no_info=True,
275
+ timeout=timeout,
276
+ log_errors=False,
277
+ )
278
+ except Exception as e:
279
+ raise MPFlashError(f"Failed to write board_info.toml for {self.serialport}: {e}") from e
280
+ finally:
281
+ # remove the temp file
282
+ if toml_path.exists():
283
+ toml_path.unlink()
284
+
228
285
  def disconnect(self) -> bool:
229
286
  """
230
287
  Disconnect from a board.
@@ -92,6 +92,7 @@ def run(
92
92
  except FileNotFoundError as e:
93
93
  raise FileNotFoundError(f"Failed to start {cmd[0]}") from e
94
94
  _timed_out = False
95
+
95
96
  def timed_out():
96
97
  _timed_out = True
97
98
  if log_warnings:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mpflash
3
- Version: 1.25.1
3
+ Version: 1.25.2
4
4
  Summary: Flash and download tool for MicroPython firmwares
5
5
  License: MIT
6
6
  Keywords: MicroPython,firmware,flash,download,UF2,esptool
@@ -37,6 +37,7 @@ Requires-Dist: requests (>=2.31.0,<3.0.0)
37
37
  Requires-Dist: rich-click (>=1.8.1,<2.0.0)
38
38
  Requires-Dist: sqlalchemy (>=2.0.41,<3.0.0)
39
39
  Requires-Dist: tenacity (==9.0.0)
40
+ Requires-Dist: tomli-w (>=1.2.0,<2.0.0)
40
41
  Project-URL: Homepage, https://github.com/Josverl/mpflash/blob/main/README.md
41
42
  Project-URL: Repository, https://github.com/Josverl/mpflash
42
43
  Description-Content-Type: text/markdown
@@ -1,36 +1,38 @@
1
1
  mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mpflash/add_firmware.py,sha256=P1yaNUdExfzC_qnhE-P5ALZg1Uh7XT6Xf7NYccJP7Rc,4317
3
2
  mpflash/ask_input.py,sha256=YUx65Xwj6dNPwWcbQiWG7U4wDW69zEdno2HcT1KwPBg,8886
4
- mpflash/basicgit.py,sha256=Aiz6rF6PVhQir-FU-T1NhbjsW803y39Js6xnWs8-yu4,9676
3
+ mpflash/basicgit.py,sha256=J1jWsM3QuYZLjj-e9yTsj7dLkxPvT4MFz3_YaEttyXg,10190
5
4
  mpflash/bootloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
5
  mpflash/bootloader/activate.py,sha256=orQOw4XTkXVZI-rMInRb0T5Wp3qA_BlzbJUA2gyBToU,2361
7
6
  mpflash/bootloader/detect.py,sha256=OagP2QVWeLLWkZt2paqEF6r4_x3QDcBGNCPOWfMy9NQ,2686
8
7
  mpflash/bootloader/manual.py,sha256=WYC4x-dxrSwVUfgnKTlu34pCzckrWJKZnWsARDocycI,3169
9
8
  mpflash/bootloader/micropython.py,sha256=v_kZkvg0uWZDbMrT78gmiYHbD83QLdnrctvEClI8iRg,529
10
9
  mpflash/bootloader/touch1200.py,sha256=VND7_YniS9Vx6WEaAxjI72RZZ6WBOwmBTsKJkbuaAHk,1105
11
- mpflash/cli_download.py,sha256=cfM3_4It2SE1inx7XsxVhl-j_2efhmuej0d58biOdLo,3507
12
- mpflash/cli_flash.py,sha256=g-ii51MTzxm-CVpLMhC0TszBYREqlZVctoocNG95z9c,8463
13
- mpflash/cli_group.py,sha256=Uf_1ZmeeSIsaGLuuKn3KPPPVi8fJVbIacJYFZx_oPHc,2684
10
+ mpflash/cli_add.py,sha256=hI-o-9hAGD3U8cbpXvy9Nuv1KHNTZ6mS57LC4BTBtj8,3495
11
+ mpflash/cli_download.py,sha256=EeAK5NcuJq0UeePSyHtPvBj_jEt92gh0jBmeNUcA7i0,3555
12
+ mpflash/cli_flash.py,sha256=SekC3goAu9_8UvMRMTEzIiiOK8js1GJRC6ymyA3BQWg,8820
13
+ mpflash/cli_group.py,sha256=RITn2u1_77jKptapX0Vz3oUriPtGMzLVmjZOtM5SP88,2686
14
14
  mpflash/cli_list.py,sha256=dznrQrWQXvev20ai5AFvz2DFe3MNDR5RIrJmtvQou6A,2693
15
- mpflash/cli_main.py,sha256=NMhEtMtSe7ApE-210Q4p-g7ZgewgO-4z1Q-vNKLQ47Y,1277
16
- mpflash/common.py,sha256=LVN3actI__gHorWIG5-55v6dZ1cD1GSIlevk3a8Je-Y,6278
17
- mpflash/config.py,sha256=55cPkGvCajlEd1_lEGsPNCX9YdJqUr9muqBejVOyVVA,4066
18
- mpflash/connected.py,sha256=Bx2R-nAeWC6iNG77mXDMu0n66bvTMyM4sH7ckuKnCFw,3591
15
+ mpflash/cli_main.py,sha256=w5o3swYWDZUnYwIH46hGMCiFdPKVL1-R1YJRM-RSMiY,1496
16
+ mpflash/common.py,sha256=wO3BjG1wtbfi37wNWPnmLk3jNi7kRUl1vTzgJUOwm9I,6355
17
+ mpflash/config.py,sha256=3JIOuKcVIWzV3Y24n6ag_XJpSczMcCbd1fa6FpWGiz8,4143
18
+ mpflash/connected.py,sha256=SZvqbnLztJH-DBByjGrWT24S5DGTSevWSwYncH6dFqk,3707
19
+ mpflash/custom/__init__.py,sha256=l9RU9hRm9j7IuRgacw-gHYjA2Op-5prvRO5yyODhFMQ,5269
20
+ mpflash/custom/naming.py,sha256=uHQzFIDzuWQUNajeGSUcf_A-o7cxX37kfgXhzpFHNtk,3304
19
21
  mpflash/db/__init__.py,sha256=wnIlO4nOXsPGXMbn2OCqHRsR-hUmtJsko8VdqjH3ZUE,45
20
- mpflash/db/core.py,sha256=hyzurZp8QMl8Q9B00Q-tOkOUp68T8XhM7tj3dm5cDHw,2283
21
- mpflash/db/gather_boards.py,sha256=8QS7NIt3n9ROqtgVAnoqU8YMeObLGaN2pvJL7d_kULA,3905
22
- mpflash/db/loader.py,sha256=0L4I3ySaGLFlzy9FlV7_nzbqzA6MHwi0FhgDG5FJ_9U,4848
23
- mpflash/db/meta.py,sha256=I7JycEx37MVVYowA0VFfUYFX9IURiTTsWQ1RhFgGqes,2251
24
- mpflash/db/micropython_boards.zip,sha256=cc4m7VSskj__rhabw3j5OZCiz1yEi6yCx7JGFn1QB0k,16647
25
- mpflash/db/models.py,sha256=Q4yjZPcNRIGWevoACeGDS1i31QX6jq1q5TsyPjmdmz4,3448
22
+ mpflash/db/core.py,sha256=6Ftp-Br3fmVO5prsvR7oc-XfF3qLJrTOy2YKosQeQQk,5271
23
+ mpflash/db/gather_boards.py,sha256=r867g1U4xRRSGLie8cYtdotLyqy9Y7plxfqGQb-1ayw,3970
24
+ mpflash/db/loader.py,sha256=CDlTj2T6w9Ch9s3RHi00E1TbUhjFsgXAsYSQr5kliB0,4889
25
+ mpflash/db/meta.py,sha256=2pFTpFH-1zejGIDp2vs0hbX5rqUONt7B1WIvf8qBx5s,2248
26
+ mpflash/db/micropython_boards.zip,sha256=K9Y0P6JBYlgoY_mR6m_pEVtNxzO9JHaQlb_TCZACcPI,17059
27
+ mpflash/db/models.py,sha256=hZrum-nS-TNFaZAksApjxYMBgGKI_kJ-4oFxc8a4WRk,3572
26
28
  mpflash/db/tools.py,sha256=6SEGfshNob4yRQ4h-Cj_xcWMRY28sbA8CWauNXV_uMI,814
27
- mpflash/download/__init__.py,sha256=zidXvsSFCfR-BZCZ6TiB7uEucEuUqXnZhKSfTs60lzU,7930
29
+ mpflash/download/__init__.py,sha256=EQez0Gj70rgrcJDbWEMYlezQyGgD747ipwmB0nt9eUI,9575
28
30
  mpflash/download/from_web.py,sha256=PVJDaFfYLJGXlPva5fExh4Yg2H7j3idyJEcfOiVVJBs,7608
29
- mpflash/download/fwinfo.py,sha256=gpa92PkysT1B7mxPAFJ-b_6y03QCNgHKm-J6T_RFNMI,1852
31
+ mpflash/download/fwinfo.py,sha256=XGWOWoJ9cqRVtBAgzVYWCIWaBZpLK595SniXn7bzrRk,1844
30
32
  mpflash/download/jid.py,sha256=V57M4K0uXXxBYOB4zOKkmXvUvEQdM_-w22LZ-iMIJSE,2344
31
- mpflash/downloaded.py,sha256=508sqROPf0Ymz7UxMzReXtK6mG1EcoXA-ysGdzV-VM0,4040
33
+ mpflash/downloaded.py,sha256=xaeMYrTIGj_v4scUBojeJPL-U1kWJG-bdvkvJMbPh4Q,4218
32
34
  mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
33
- mpflash/flash/__init__.py,sha256=jif7-ifsXMabidjNdqUQyl1CwD5_USjCAZFhU5W-Aw8,2992
35
+ mpflash/flash/__init__.py,sha256=fkA_3pax9ZLckb14zFxATGk1YWMenpHBlvi66qJCIJA,3433
34
36
  mpflash/flash/esp.py,sha256=4977E1hDqJ4-EIkLzwrUtgZuc0ZTD7NvP1PQZgZ2DoU,3227
35
37
  mpflash/flash/stm32.py,sha256=jNgMpJaxUwtJ-v6VU1luD1t41AQprCUeNVCVEovxQe0,595
36
38
  mpflash/flash/stm32_dfu.py,sha256=W-3JsRQyf3DduoIRXDmGZ35RogqtjQgcJnk-GOtQoLE,3090
@@ -40,19 +42,19 @@ mpflash/flash/uf2/linux.py,sha256=uTgqyS7C7xfQ25RrTcSUkt-m2u2Ks_o7bPLzIecPoC8,43
40
42
  mpflash/flash/uf2/macos.py,sha256=JTaIpqnR_0k4oSEvzs9amhmK-PMxUJyZLnZ_wZwxa-0,1228
41
43
  mpflash/flash/uf2/uf2disk.py,sha256=4_P2l-kedM7VSliA2u706LQLxvu3xWSod1-lj-xjZis,298
42
44
  mpflash/flash/uf2/windows.py,sha256=OEeskObPtpIE4a5NzYIcBqg3FkM5MGPGEa4lGGOfntY,1338
43
- mpflash/flash/worklist.py,sha256=WIiBlbluAiU7UexOu1dlXguUmkvhW0uxvvUaiUCEZ1U,6165
44
- mpflash/list.py,sha256=NNhKpRh3ARZMdq56GLJgJ67GeuUf9SxjTzFhQjDsi9A,4008
45
- mpflash/logger.py,sha256=b2pNiAEXgpUDZKnMjtgBAGgMpPwTB3u030EhJiXyLZQ,2009
45
+ mpflash/flash/worklist.py,sha256=wf-R9yPsmcE54dnoPA29pEEzNPZI3JwY85V_DB0hXNI,6584
46
+ mpflash/list.py,sha256=IrJa3UBjhHHfStbb9fPVYA8JJzoFTyXtbcKGNRSH8sE,4132
47
+ mpflash/logger.py,sha256=XLu4VzMhMPlCdOo2HeS4GfyatE1swwwonV8c6a-GoD4,2651
46
48
  mpflash/mpboard_id/__init__.py,sha256=Z6gDDWTCSKPp2fsuaUz80zgrklBR9XDlSLF9y_evR9A,391
47
49
  mpflash/mpboard_id/alternate.py,sha256=ZhqfdA9sLJmyOfJ6WwK9wrzzUn6JQdkAreiL0q5XEQg,1913
48
- mpflash/mpboard_id/board_id.py,sha256=dGbYnqaGHm6Z68P6aCq5bv95pyhi9KKhQleQXmlyO8Y,2046
50
+ mpflash/mpboard_id/board_id.py,sha256=xdOna_ZpTHVnsV8XQ5rrTIRCuzU69HD_ZJoY19d7dCE,1894
49
51
  mpflash/mpboard_id/board_info.json,sha256=A3ZIt38KvAy2NMB5srHorSBd3Q3wOZIXufWiIs3XLrs,1019745
50
52
  mpflash/mpboard_id/board_info.zip,sha256=-2bnQGRsIQuJUfz-7_-GQ8pMWJ1evhCez6yfjhXocNw,23213
51
- mpflash/mpboard_id/known.py,sha256=GrNe4FtzVIdi9L9xuJ1gzorzXTvdfrugX1iVc_Nblb8,3325
53
+ mpflash/mpboard_id/known.py,sha256=t-oREfW5P5Zue5zbte7WB9e7-mpZBF-NfHGTEUsOVLM,3521
52
54
  mpflash/mpboard_id/resolve.py,sha256=5KCZ0Tcg3FYZ3HK_zux5EguwoSC2E03kCpW2fh4rN2A,779
53
- mpflash/mpremoteboard/__init__.py,sha256=WWzAuUo3irKs_ZfHc7PREKrsywi45aPyZXuz5MaD6go,12093
55
+ mpflash/mpremoteboard/__init__.py,sha256=4OIKAry-GeYUSgnEcs5TRb0xea0bstVQCOb28MjLDyk,14210
54
56
  mpflash/mpremoteboard/mpy_fw_info.py,sha256=ZDEPJN9XJnoG_oeWcLNiLJAD5bkVX2yI_j4K7msUxWM,5196
55
- mpflash/mpremoteboard/runner.py,sha256=auJuK7uBq_qdZOX9DgzRARyAsTyhT8c9ycP02VqhMf4,4943
57
+ mpflash/mpremoteboard/runner.py,sha256=H5f5JBcRnpF06Ui3xDY7IoDdO2Hex9lsI_eGMq5c2A4,4945
56
58
  mpflash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
59
  mpflash/vendor/board_database.py,sha256=Cb8fEhJaZ2siMkLPW5rPwV9yzBsTtKGOqWUd9TxNgFM,8763
58
60
  mpflash/vendor/click_aliases.py,sha256=adLhqLxNpJEPjSCIRSTkR-QzSgavGFKT0cwRbjxpzRU,5395
@@ -62,8 +64,8 @@ mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2,sha256=QuPMppq
62
64
  mpflash/vendor/pydfu.py,sha256=KD1RHHuhvhWi-l1UB6GyggkxouDKtZgkG4ivRbIfwC4,21264
63
65
  mpflash/vendor/readme.md,sha256=BQ7Uxf8joeYMjTUuSLLBG49ob6a9MgFPIEwuc72-Mfw,415
64
66
  mpflash/versions.py,sha256=HuujLNdMKY_mQXyEqwXVHcU8nbuXeBiWP2TMA5JQhr4,4884
65
- mpflash-1.25.1.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
66
- mpflash-1.25.1.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
67
- mpflash-1.25.1.dist-info/METADATA,sha256=IO9Axs0u59gBjzoIlCR7mNbb8jb0RkMi4bQ68JWXASA,27109
68
- mpflash-1.25.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
69
- mpflash-1.25.1.dist-info/RECORD,,
67
+ mpflash-1.25.2.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
68
+ mpflash-1.25.2.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
69
+ mpflash-1.25.2.dist-info/METADATA,sha256=FkHpU3o9_3njLQFFOODMRmgFcoejObaRF9w2JoJ3mrM,27149
70
+ mpflash-1.25.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
71
+ mpflash-1.25.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.1
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
mpflash/add_firmware.py DELETED
@@ -1,125 +0,0 @@
1
- import shutil
2
- from pathlib import Path
3
- from typing import Union
4
-
5
- import jsonlines
6
- import requests
7
- from loguru import logger as log
8
- # re-use logic from mpremote
9
- from mpremote.mip import _rewrite_url as rewrite_url # type: ignore
10
- from pytest import Session
11
-
12
- from mpflash.config import config
13
- from mpflash.db.core import Session
14
- from mpflash.db.models import Firmware
15
- from mpflash.versions import get_preview_mp_version, get_stable_mp_version
16
-
17
- # github.com/<owner>/<repo>@<branch>#<commit>
18
- # $remote_url = git remote get-url origin
19
- # $branch = git rev-parse --abbrev-ref HEAD
20
- # $commit = git rev-parse --short HEAD
21
- # if ($remote_url -match "github.com[:/](.+)/(.+?)(\.git)?$") {
22
- # $owner = $matches[1]
23
- # $repo = $matches[2]
24
- # "github.com/$owner/$repo@$branch#$commit"
25
- # }
26
-
27
-
28
- def add_firmware(
29
- source: Union[Path, str],
30
- new_fw: Firmware,
31
- *,
32
- force: bool = False,
33
- custom: bool = False,
34
- description: str = "",
35
- ) -> bool:
36
- """Add a firmware to the firmware folder.
37
-
38
- stored in the port folder, with the same filename as the source.
39
- """
40
- # Check minimal info needed
41
-
42
- if not new_fw.board_id or not new_fw.board or not new_fw.port:
43
- log.error("board_id, board and port are required")
44
- return False
45
- if not isinstance(source, Path) and not source.startswith("http"):
46
- log.error(f"Invalid source {source}")
47
- return False
48
-
49
- # use sensible defaults
50
- source_2 = Path(source)
51
- # new_fw.variant = new_fw.variant or new_fw.board
52
- new_fw.custom = new_fw.custom or custom
53
- if not new_fw.version:
54
- # TODO: Get version from filename
55
- # or use the last preview version
56
- new_fw.version = get_preview_mp_version()
57
-
58
- config.firmware_folder.mkdir(exist_ok=True)
59
-
60
- fw_filename = config.firmware_folder / new_fw.port / source_2.name
61
-
62
- new_fw.firmware_file = str(fw_filename.relative_to(config.firmware_folder))
63
- new_fw.source = source.as_uri() if isinstance(source, Path) else source
64
-
65
- if not copy_firmware(source, fw_filename, force):
66
- log.error(f"Failed to copy {source} to {fw_filename}")
67
- return False
68
- # add to inventory
69
- with Session() as session:
70
- # check if the firmware already exists
71
- existing_fw = (
72
- session.query(Firmware)
73
- .filter(
74
- Firmware.board_id == new_fw.board_id,
75
- Firmware.version == new_fw.version,
76
- Firmware.port == new_fw.port,
77
- )
78
- .first()
79
- )
80
- if existing_fw:
81
- log.warning(f"Firmware {existing_fw} already exists")
82
- if not force:
83
- return False
84
- # update the existing firmware
85
- existing_fw.firmware_file = new_fw.firmware_file
86
- existing_fw.source = new_fw.source
87
- existing_fw.custom = custom
88
- existing_fw.description = description
89
- else:
90
- session.add(new_fw)
91
-
92
- return True
93
-
94
-
95
- def copy_firmware(source: Union[Path, str], fw_filename: Path, force: bool = False):
96
- """Add a firmware to the firmware folder.
97
- stored in the port folder, with the same filename as the source.
98
- """
99
- if fw_filename.exists() and not force:
100
- log.error(f" {fw_filename} already exists. Use --force to overwrite")
101
- return False
102
- fw_filename.parent.mkdir(exist_ok=True)
103
- if isinstance(source, Path):
104
- if not source.exists():
105
- log.error(f"File {source} does not exist")
106
- return False
107
- # file copy
108
- log.debug(f"Copy {source} to {fw_filename}")
109
- shutil.copy(source, fw_filename)
110
- return True
111
- # handle github urls
112
- url = rewrite_url(source)
113
- if str(source).startswith("http://") or str(source).startswith("https://"):
114
- log.debug(f"Download {url} to {fw_filename}")
115
- response = requests.get(url)
116
-
117
- if response.status_code == 200:
118
- with open(fw_filename, "wb") as file:
119
- file.write(response.content)
120
- log.info("File downloaded and saved successfully.")
121
- return True
122
- else:
123
- print("Failed to download the file.")
124
- return False
125
- return False