|
23 | 23 | '''Provides functions for build artifacts''' |
24 | 24 |
|
25 | 25 | import copy |
| 26 | +import datetime |
26 | 27 | import hashlib |
27 | | -import glob |
28 | 28 | import json |
29 | 29 | import logging |
30 | 30 | import os |
|
33 | 33 | import shutil |
34 | 34 | import stat |
35 | 35 | import zipfile |
| 36 | +from pathlib import Path |
36 | 37 |
|
37 | 38 | import requests |
38 | 39 |
|
39 | 40 | import nimp.system |
40 | 41 | import nimp.utils.git |
41 | 42 |
|
42 | | - |
43 | 43 | if platform.system() != 'Windows': |
44 | 44 | try: |
45 | 45 | import magic |
46 | 46 | except ImportError: |
47 | 47 | magic = None |
48 | 48 |
|
49 | 49 | try: |
50 | | - import BitTornado.Meta.Info |
51 | | - import BitTornado.Meta.BTTree |
52 | | - import BitTornado.Meta.bencode |
| 50 | + import torf |
53 | 51 | except ImportError: |
54 | | - BitTornado = None |
| 52 | + torf = None |
55 | 53 |
|
56 | 54 |
|
57 | 55 | def _is_http_url(string): |
@@ -297,48 +295,38 @@ def create_artifact(artifact_path, file_collection, archive, compress, dry_run): |
297 | 295 | def create_torrent(artifact_path, announce, dry_run): |
298 | 296 | '''Create a torrent for an existing artifact''' |
299 | 297 |
|
300 | | - if BitTornado is None: |
301 | | - raise ImportError('Required module "BitTornado" is not available') |
302 | | - |
303 | | - torrent_path = artifact_path + '.torrent' |
304 | | - if not dry_run: |
305 | | - if os.path.isfile(torrent_path + '.tmp'): |
306 | | - os.remove(torrent_path + '.tmp') |
307 | | - if os.path.isfile(torrent_path): |
308 | | - os.remove(torrent_path) |
| 298 | + if torf is None: |
| 299 | + raise ImportError("nimp require the 'torrent' extra dependency to handle torrent creation") |
309 | 300 |
|
310 | | - if os.path.isfile(artifact_path + '.zip'): |
311 | | - torrent_name = os.path.basename(artifact_path + '.zip') |
312 | | - all_torrent_trees = [ |
313 | | - BitTornado.Meta.BTTree.BTTree(artifact_path + '.zip', [os.path.basename(artifact_path + '.zip')]) |
314 | | - ] |
315 | | - elif os.path.isdir(artifact_path): |
316 | | - torrent_name = os.path.basename(artifact_path) |
317 | | - all_torrent_trees = [] |
318 | | - for source in glob.glob(os.path.join(artifact_path, '**'), recursive=True): |
319 | | - if os.path.isfile(source): |
320 | | - destination = os.path.relpath(source, artifact_path) |
321 | | - all_torrent_trees.append( |
322 | | - BitTornado.Meta.BTTree.BTTree(source, os.path.normpath(destination).split(os.path.sep)) |
323 | | - ) |
324 | | - else: |
325 | | - raise FileNotFoundError('Artifact not found: %s' % artifact_path) |
| 301 | + artifact_path = Path(artifact_path) |
326 | 302 |
|
327 | | - torrent_info = BitTornado.Meta.Info.Info(torrent_name, sum(tree.size for tree in all_torrent_trees)) |
328 | | - for torrent_tree in all_torrent_trees: |
329 | | - torrent_tree.addFileToInfos([torrent_info]) |
330 | | - BitTornado.Meta.Info.check_info(torrent_info) |
331 | | - |
332 | | - torrent_metainfo_parameters = {'announce': announce} |
333 | | - torrent_metainfo_parameters = { |
334 | | - key: value for key, value in torrent_metainfo_parameters.items() if value is not None |
335 | | - } |
336 | | - torrent_metainfo = BitTornado.Meta.Info.MetaInfo(info=torrent_info, **torrent_metainfo_parameters) |
| 303 | + torrent_path = artifact_path.with_suffix('.torrent') |
| 304 | + tmp_torrent_path = torrent_path.with_suffix('.tmp') |
| 305 | + if not dry_run: |
| 306 | + tmp_torrent_path.unlink(missing_ok=True) |
| 307 | + torrent_path.unlink(missing_ok=True) |
| 308 | + |
| 309 | + torrent = torf.Torrent( |
| 310 | + path=artifact_path, |
| 311 | + name=artifact_path.name, |
| 312 | + trackers=announce, |
| 313 | + creation_date=datetime.datetime.now(), |
| 314 | + created_by=None, |
| 315 | + private=False, |
| 316 | + piece_size=32768, |
| 317 | + ) |
| 318 | + if (artifact_archive_path := artifact_path.with_suffix('.zip')) and artifact_archive_path.is_file(): |
| 319 | + torrent.name = artifact_archive_path.name |
| 320 | + torrent.path = artifact_archive_path |
| 321 | + elif not artifact_path.is_dir(): |
| 322 | + raise FileNotFoundError(f'Artifact not found: {artifact_path}') |
337 | 323 |
|
338 | 324 | if not dry_run: |
339 | | - with open(torrent_path + '.tmp', 'wb') as torrent_file: |
340 | | - torrent_file.write(BitTornado.Meta.bencode.bencode(torrent_metainfo)) |
341 | | - shutil.move(torrent_path + '.tmp', torrent_path) |
| 325 | + if not torrent.generate(): |
| 326 | + raise RuntimeError("Failed to generate torrent. Unrecoverable.") |
| 327 | + |
| 328 | + torrent.write(tmp_torrent_path, validate=True) |
| 329 | + tmp_torrent_path.rename(torrent_path) |
342 | 330 |
|
343 | 331 |
|
344 | 332 | def create_hash(artifact_path, hash_method, dry_run): |
|
0 commit comments