|
5 | 5 | import contextlib |
6 | 6 | import enum |
7 | 7 | import os |
| 8 | +import pathlib |
8 | 9 | import subprocess |
9 | 10 | import traceback |
10 | 11 | import logging |
@@ -1214,6 +1215,32 @@ def tmc_channel(self): |
1214 | 1215 | for k, v in sorted(data.items()): |
1215 | 1216 | print(f"{k:<16s} {str(v):<10s}") |
1216 | 1217 |
|
| 1218 | + def write_files(self): |
| 1219 | + place = self.get_acquired_place() |
| 1220 | + target = self._get_target(place) |
| 1221 | + name = self.args.name |
| 1222 | + drv = self._get_driver_or_new(target, "USBStorageDriver", activate=False, name=name) |
| 1223 | + drv.storage.timeout = self.args.wait |
| 1224 | + target.activate(drv) |
| 1225 | + |
| 1226 | + try: |
| 1227 | + if self.args.partition == 0: |
| 1228 | + self.args.partition = None |
| 1229 | + |
| 1230 | + if self.args.rename: |
| 1231 | + if len(self.args.SOURCE) != 2: |
| 1232 | + self.args.parser.error("the following arguments are required: SOURCE DEST") |
| 1233 | + |
| 1234 | + drv.write_files([self.args.SOURCE[0]], self.args.SOURCE[1], |
| 1235 | + self.args.partition, target_is_directory=False) |
| 1236 | + else: |
| 1237 | + drv.write_files(self.args.SOURCE, self.args.target_directory, |
| 1238 | + self.args.partition, target_is_directory=True) |
| 1239 | + except subprocess.CalledProcessError as e: |
| 1240 | + raise UserError(f"could not copy files to network usb storage: {e}") |
| 1241 | + except FileNotFoundError as e: |
| 1242 | + raise UserError(e) |
| 1243 | + |
1217 | 1244 | def write_image(self): |
1218 | 1245 | place = self.get_acquired_place() |
1219 | 1246 | target = self._get_target(place) |
@@ -1761,6 +1788,27 @@ def main(): |
1761 | 1788 | tmc_subparser.add_argument('action', choices=['info', 'values']) |
1762 | 1789 | tmc_subparser.set_defaults(func=ClientSession.tmc_channel) |
1763 | 1790 |
|
| 1791 | + subparser = subparsers.add_parser('write-files', help="copy files onto mass storage device", |
| 1792 | + usage="%(prog)s [OPTION]... -T SOURCE DEST\n" + |
| 1793 | + " %(prog)s [OPTION]... [-t DIRECTORY] SOURCE...") |
| 1794 | + subparser.add_argument('-w', '--wait', type=float, default=10.0, |
| 1795 | + help='storage poll timeout in seconds') |
| 1796 | + subparser.add_argument('-p', '--partition', type=int, choices=range(0, 256), |
| 1797 | + metavar='0-255', default=1, |
| 1798 | + help='partition number to mount or 0 to mount whole disk (default: %(default)s)') |
| 1799 | + group = subparser.add_mutually_exclusive_group() |
| 1800 | + group.add_argument('-t', '--target-directory', type=pathlib.PurePath, metavar='DIRECTORY', |
| 1801 | + default=pathlib.PurePath("/"), |
| 1802 | + help='copy all SOURCE files into DIRECTORY (default: partition root)') |
| 1803 | + group.add_argument('-T', action='store_true', dest='rename', |
| 1804 | + help='copy SOURCE file and rename to DEST') |
| 1805 | + subparser.add_argument('--name', '-n', help="optional resource name") |
| 1806 | + subparser.add_argument('SOURCE', type=pathlib.PurePath, nargs='+', |
| 1807 | + help='source file(s) to copy') |
| 1808 | + subparser.add_argument('DEST', type=pathlib.PurePath, nargs='?', |
| 1809 | + help='destination file name for SOURCE') |
| 1810 | + subparser.set_defaults(func=ClientSession.write_files, parser=subparser) |
| 1811 | + |
1764 | 1812 | subparser = subparsers.add_parser('write-image', help="write an image onto mass storage") |
1765 | 1813 | subparser.add_argument('-w', '--wait', type=float, default=10.0) |
1766 | 1814 | subparser.add_argument('-p', '--partition', type=int, help="partition number to write to") |
|
0 commit comments