From badbc67fc5756361f8b28d1ff4d238f37ae13387 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 26 Mar 2023 02:06:27 -0700 Subject: [PATCH 1/3] v0.8.11 --- CHANGELOG.md | 7 + Makefile | 3 +- docs/Source/cli/index.html | 92 +- docs/Source/commands/index.html | 230 +++- docs/Source/mixins/index.html | 54 +- docs/Source/utils/index.html | 70 +- docs/changelog/index.html | 13 + docs/coverage/covindex.html | 28 +- .../d_1bc82e0ab2fcb2ec___init___py.html | 4 +- .../d_1bc82e0ab2fcb2ec___main___py.html | 4 +- docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html | 1138 +++++++++-------- .../d_1bc82e0ab2fcb2ec_commands_py.html | 168 +-- docs/coverage/d_1bc82e0ab2fcb2ec_edit_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_hasher_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_interactive_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_mixins_py.html | 287 ++--- .../d_1bc82e0ab2fcb2ec_rebuild_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_recheck_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_torrent_py.html | 4 +- .../coverage/d_1bc82e0ab2fcb2ec_utils_py.html | 149 ++- .../d_1bc82e0ab2fcb2ec_version_py.html | 6 +- .../d_a44f0ac069e85531___init___py.html | 4 +- .../d_a44f0ac069e85531_test_cli_py.html | 4 +- .../d_a44f0ac069e85531_test_commands_py.html | 551 ++++---- .../d_a44f0ac069e85531_test_edit_py.html | 4 +- ..._a44f0ac069e85531_test_interactive_py.html | 4 +- .../d_a44f0ac069e85531_test_rebuild_py.html | 4 +- .../d_a44f0ac069e85531_test_recheck_py.html | 4 +- .../d_a44f0ac069e85531_test_torrent_py.html | 4 +- .../d_a44f0ac069e85531_test_utils_py.html | 4 +- docs/coverage/status.json | 2 +- .../d_1bc82e0ab2fcb2ec___init___py.html | 4 +- .../d_1bc82e0ab2fcb2ec___main___py.html | 4 +- docs/htmlcov/d_1bc82e0ab2fcb2ec_cli_py.html | 1138 +++++++++-------- .../d_1bc82e0ab2fcb2ec_commands_py.html | 168 +-- docs/htmlcov/d_1bc82e0ab2fcb2ec_edit_py.html | 4 +- .../htmlcov/d_1bc82e0ab2fcb2ec_hasher_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_interactive_py.html | 4 +- .../htmlcov/d_1bc82e0ab2fcb2ec_mixins_py.html | 287 ++--- .../d_1bc82e0ab2fcb2ec_rebuild_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_recheck_py.html | 4 +- .../d_1bc82e0ab2fcb2ec_torrent_py.html | 4 +- docs/htmlcov/d_1bc82e0ab2fcb2ec_utils_py.html | 149 ++- .../d_1bc82e0ab2fcb2ec_version_py.html | 6 +- .../d_a44f0ac069e85531___init___py.html | 4 +- .../d_a44f0ac069e85531_test_cli_py.html | 4 +- .../d_a44f0ac069e85531_test_commands_py.html | 551 ++++---- .../d_a44f0ac069e85531_test_edit_py.html | 4 +- ..._a44f0ac069e85531_test_interactive_py.html | 4 +- .../d_a44f0ac069e85531_test_rebuild_py.html | 4 +- .../d_a44f0ac069e85531_test_recheck_py.html | 4 +- .../d_a44f0ac069e85531_test_torrent_py.html | 4 +- .../d_a44f0ac069e85531_test_utils_py.html | 4 +- docs/htmlcov/index.html | 28 +- docs/htmlcov/status.json | 2 +- docs/objects.inv | Bin 1192 -> 1197 bytes docs/search/search_index.json | 2 +- docs/sitemap.xml | 38 +- docs/sitemap.xml.gz | Bin 336 -> 336 bytes site/changelog.md | 7 + tests/test_commands.py | 5 +- torrentfile/cli.py | 56 +- torrentfile/commands.py | 40 +- torrentfile/mixins.py | 21 +- torrentfile/utils.py | 35 +- torrentfile/version.py | 2 +- tox.ini | 4 +- 67 files changed, 2877 insertions(+), 2588 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 733e1b85..3da32b53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # TorrentFile +## Version 0.8.11 + +- added new command line option for magnet subcommand +- fixed some coverage gaps caused by 0.8.10 + +--- + ## Version 0.8.10 - added support for bittorrent v2 magnet links diff --git a/Makefile b/Makefile index 49039ad0..f9113a7a 100644 --- a/Makefile +++ b/Makefile @@ -98,8 +98,9 @@ setup: clean test ## setup and build repo pip install -e . twine upload dist/* -release: clean test ## create executables for release +compile: clean pip install pyinstaller pip install -e . + pyinstaller pyinstaller ./runner/execf.spec @python -c "$$RENAME_FILE" diff --git a/docs/Source/cli/index.html b/docs/Source/cli/index.html index ead2d1da..22f00b87 100644 --- a/docs/Source/cli/index.html +++ b/docs/Source/cli/index.html @@ -861,7 +861,7 @@

-TorrentFileHelpFormatter(prog, width = 45, max_help_positions = 45) +TorrentFileHelpFormatter(prog: str, width: int = 45, max_help_positions: int = 45) #

@@ -949,7 +949,11 @@

111 112 113 -114
def __init__(self, prog, width=45, max_help_positions=45):
+114
+115
+116
def __init__(
+    self, prog: str, width: int = 45, max_help_positions: int = 45
+):
     """
     Construct HelpFormat class for usage output.
 
@@ -1056,9 +1060,7 @@ 

Source code in torrentfile\cli.py -
195
-196
-197
+        
197
 198
 199
 200
@@ -1506,7 +1508,27 @@ 

642 643 644 -645

def execute(args: list = None) -> list:
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
def execute(args: list = None) -> list:
     """
     Execute program with provided list of arguments.
 
@@ -1536,7 +1558,7 @@ 

usage="torrentfile <options>", description=( "Command line tools for creating, editing, checking, building " - "and interacting with Bittorrent metainfo files" + "and interacting with Bittorrent meta files" ), prefix_chars="-", formatter_class=TorrentFileHelpFormatter, @@ -1669,6 +1691,7 @@

default="1", action="store", dest="progress", + metavar="<int>", help=""" Set the progress bar level. Options = 0, 1 @@ -1838,7 +1861,22 @@

metavar="<*.torrent>", ) - magnet_parser.set_defaults(func=magnet) + magnet_parser.add_argument( + "--meta-version", + action="store", + choices=["1", "2"], + default="1", + help=""" + This option will only effect hybrid torrent files. + Options: 1 or 2 + (1) sha1 + (2) sha256 + """, + dest="meta_version", + metavar="<int>", + ) + + magnet_parser.set_defaults(func=get_magnet) check_parser = subparsers.add_parser( "recheck", @@ -1866,9 +1904,11 @@

rebuild_parser = subparsers.add_parser( "rebuild", - help="""Re-assemble files obtained from a bittorrent file into the - appropriate file structure for re-seeding. Read documentation - for more information, or use cases.""", + help=""" + Re-assemble files obtained from a bittorrent file into the + appropriate file structure for re-seeding. Read documentation + for more information, or use cases. + """, formatter_class=TorrentFileHelpFormatter, ) @@ -1922,23 +1962,23 @@

rename_parser.set_defaults(func=rename) all_commands = [ - "create", - "new", "c", - "edit", "e", - "info", "i", - "magnet", "m", - "recheck", - "check", "r", - "rename", - "rebuild", "-i", "-h", "-V", + "new", + "edit", + "info", + "check", + "create", + "magnet", + "rename", + "rebuild", + "recheck", ] if not any(i for i in all_commands if i in args): start = 0 @@ -1968,7 +2008,7 @@

-main() +main() -> None #

@@ -1979,11 +2019,11 @@

Source code in torrentfile\cli.py -
651
-652
-653
-654
-655
def main():
+        
+ + + + @@ -1379,7 +1501,7 @@

@@ -1387,26 +1509,7 @@

Source code in torrentfile\commands.py -

671
+672
+673
+674
+675
def main() -> None:
     """
     Initiate main function for CLI script.
     """
diff --git a/docs/Source/commands/index.html b/docs/Source/commands/index.html
index 91fe59cc..05b986bf 100644
--- a/docs/Source/commands/index.html
+++ b/docs/Source/commands/index.html
@@ -465,6 +465,13 @@
     find_config_file()
   
   
+
+        
+          
  • + + get_magnet() + +
  • @@ -1164,6 +1171,105 @@

    +

    +get_magnet(namespace: Namespace) -> str + +#

    + + +
    + +

    Prepare option parameters for retreiving magnet URI.

    + + + + + + + + + + + + + + +
    PARAMETERDESCRIPTION
    namespace +

    command line argument options

    +

    + + TYPE: + Namespace + +

    +
    + + + + + + + + + + + + + + +
    RETURNSDESCRIPTION
    + + str + + +

    Magnet URI

    +
    + +
    + Source code in torrentfile\commands.py +
    346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    def get_magnet(namespace: Namespace) -> str:
    +    """
    +    Prepare option parameters for retreiving magnet URI.
    +
    +    Parameters
    +    ----------
    +    namespace: Namespace
    +        command line argument options
    +
    +    Returns
    +    -------
    +    str
    +        Magnet URI
    +    """
    +    metafile = namespace.metafile
    +    version = int(namespace.meta_version)
    +    return magnet(metafile, version=version)
    +
    +
    +
    + +
  • + +
    + + +

    info(args: Namespace) -> str @@ -1332,7 +1438,7 @@

    -magnet(metafile: Namespace) -> str +magnet(metafile: str, version: int = 1) -> str #

    @@ -1352,11 +1458,27 @@

    metafile -

    Namespace class for CLI arguments.

    +

    path to bittorrent file

    TYPE: - Namespace + str + +

    +
    version +

    version of bittorrent protocol [default=1]

    +

    + + TYPE: + int + + + DEFAULT: + 1

    -

    created magnet URI.

    +

    Magnet URI

    346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    +        
    365
     366
     367
     368
    @@ -1433,31 +1536,48 @@ 

    389 390 391 -392

    def magnet(metafile: Namespace) -> str:
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    def magnet(metafile: str, version: int = 1) -> str:
         """
         Create a magnet URI from a Bittorrent meta file.
     
         Parameters
         ----------
    -    metafile : Namespace
    -        Namespace class for CLI arguments.
    +    metafile : str
    +        path to bittorrent file
    +    version: int
    +        version of bittorrent protocol [default=1]
     
         Returns
         -------
         str
    -        created magnet URI.
    +        Magnet URI
         """
    -    if hasattr(metafile, "metafile"):
    -        metafile = metafile.metafile
         if not os.path.exists(metafile):
    -        raise FileNotFoundError
    -
    +        raise FileNotFoundError(f"No Such File {metafile}")
         meta = pyben.load(metafile)
         data = meta["info"]
    +    hashing_func = sha1  # nosec
         if "meta version" in data:
    -        hashing_func = sha256
    -    else:
    -        hashing_func = sha1  # nosec
    +        if version == 2 or "pieces" not in data:
    +            hashing_func = sha256
     
         bencoded = pyben.dumps(data)
         infohash = hashing_func(bencoded).hexdigest().upper()  # nosec
    @@ -1693,25 +1813,7 @@ 

    Source code in torrentfile\commands.py -
    395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    +        
    413
     414
     415
     416
    @@ -1721,7 +1823,25 @@ 

    420 421 422 -423

    def rebuild(args: Namespace) -> int:
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    def rebuild(args: Namespace) -> int:
         """
         Attempt to rebuild a torrent based on the a torrent file.
     
    diff --git a/docs/Source/mixins/index.html b/docs/Source/mixins/index.html
    index 67b9f006..e8edb1f1 100644
    --- a/docs/Source/mixins/index.html
    +++ b/docs/Source/mixins/index.html
    @@ -939,8 +939,7 @@ 

    Source code in torrentfile\mixins.py -
    203
    -204
    +        
    204
     205
     206
     207
    @@ -950,7 +949,8 @@ 

    211 212 213 -214

    def is_active(self) -> bool:
    +214
    +215
    def is_active(self) -> bool:
         """
         Test to see if there is an active progress bar for object.
     
    @@ -986,8 +986,7 @@ 

    Source code in torrentfile\mixins.py -
    191
    -192
    +        
    192
     193
     194
     195
    @@ -996,7 +995,8 @@ 

    198 199 200 -201

    def prog_close(self):
    +201
    +202
    def prog_close(self):
         """
         Finalize the last bits of progress bar.
     
    @@ -1096,8 +1096,7 @@ 

    Source code in torrentfile\mixins.py -
    142
    -143
    +        
    143
     144
     145
     146
    @@ -1125,7 +1124,8 @@ 

    168 169 170 -171

    def prog_start(
    +171
    +172
    def prog_start(
         self, total: int, path: str, length: int = 50, unit: str = "bytes"
     ):
         """
    @@ -1201,8 +1201,7 @@ 

    Source code in torrentfile\mixins.py -
    173
    -174
    +        
    174
     175
     176
     177
    @@ -1217,7 +1216,8 @@ 

    186 187 188 -189

    def prog_update(self, val: int):
    +189
    +190
    def prog_update(self, val: int):
         """
         Update progress bar.
     
    @@ -1388,15 +1388,15 @@ 

    self.unit = "" # pragma: nocover elif unit == "bytes": if self.total > 1_000_000_000: - self.show_total = math.floor(self.total / (2**30)) + self.show_total = self.total / (2**30) self.unit = "GiB" elif self.total > 1_000_000: - self.show_total = math.floor(self.total / 1048576) + self.show_total = self.total / 1048576 self.unit = "MiB" elif self.total > 10000: - self.show_total = math.floor(self.total / 1024) + self.show_total = self.total / 1024 self.unit = "KiB" - self.suffix = f"/{self.show_total} {self.unit}" + self.suffix = f"/{self.show_total:.02f} {self.unit}" title = str(title) if len(title) > start: title = title[: start - 1] # pragma: nocover @@ -1481,7 +1481,8 @@

    128 129 130 -131

    def get_progress(self) -> str:
    +131
    +132
    def get_progress(self) -> str:
         """
         Return the size of the filled portion of the progress bar.
     
    @@ -1494,17 +1495,18 @@ 

    fill = self.length else: fill = math.ceil((self.state / self.total) * self.length) - empt = self.length - fill + empty = self.length - fill + pbar = ["|", self.fill * fill, self.empty * empty, "| "] if self.unit == "GiB": - state = math.floor(self.state / (2**30)) + state = self.state / (2**30) elif self.unit == "MiB": - state = math.floor(self.state / 1048576) + state = self.state / 1048576 elif self.unit == "KiB": - state = math.floor(self.state / 1024) + state = self.state / 1024 else: state = self.state - progbar = ["|", self.fill * fill, self.empty * empt, "| ", str(state)] - return "".join(progbar) + pbar.append(f"{state:.02f}") + return "".join(pbar)

    @@ -1587,8 +1589,7 @@

    Source code in torrentfile\mixins.py -
    217
    -218
    +        
    218
     219
     220
     221
    @@ -1627,7 +1628,8 @@ 

    254 255 256 -257

    def waiting(msg: str, flag: list, timeout: int = 20):
    +257
    +258
    def waiting(msg: str, flag: list, timeout: int = 20):
         """
         Show loading message while thread completes processing.
     
    diff --git a/docs/Source/utils/index.html b/docs/Source/utils/index.html
    index 24d01cdf..2108f403 100644
    --- a/docs/Source/utils/index.html
    +++ b/docs/Source/utils/index.html
    @@ -1217,7 +1217,10 @@ 

    Source code in torrentfile\utils.py -
    438
    +        
    435
    +436
    +437
    +438
     439
     440
     441
    @@ -1238,10 +1241,7 @@ 

    456 457 458 -459 -460 -461 -462

    def check_path_writable(path: str) -> bool:
    +459
    def check_path_writable(path: str) -> bool:
         """
         Test if output path is writable.
     
    @@ -1357,10 +1357,7 @@ 

    405 406 407 -408 -409 -410 -411

    def copypath(source: str, dest: str) -> None:
    +408
    def copypath(source: str, dest: str) -> None:
         """
         Copy the file located at source to dest.
     
    @@ -1375,26 +1372,23 @@ 

    dest : str path to target destination """ - if not os.path.exists(source): + if not os.path.exists(source) or ( + os.path.exists(dest) + and os.path.getsize(source) <= os.path.getsize(dest) + ): return - if os.path.exists(dest): - if os.path.getsize(source) <= os.path.getsize(dest): - return - shutil.copy(source, dest) # pragma: nocover - return # pragma: nocover - path_parts = iter(Path(dest).parts[:-1]) - try: - root = next(path_parts) - except StopIteration: # pragma: nocover - return - if not os.path.exists(root): - os.mkdir(root) # pragma: nocover - for part in path_parts: - path = os.path.join(root, part) - if not os.path.exists(path): - os.mkdir(path) - root = path - shutil.copy(source, dest) + path_parts = Path(dest).parts + if len(path_parts) > 1: + root = path_parts[0] + path_parts = path_parts[1:-1] + if not os.path.exists(root): + os.mkdir(root) # pragma: nocover + for part in path_parts: + path = os.path.join(root, part) + if not os.path.exists(path): + os.mkdir(path) + root = path + shutil.copy(source, dest)

    @@ -1438,16 +1432,16 @@

    Source code in torrentfile\utils.py -
    426
    +        
    423
    +424
    +425
    +426
     427
     428
     429
     430
     431
    -432
    -433
    -434
    -435
    def debug_is_on() -> bool:
    +432
    def debug_is_on() -> bool:
         """
         Return True if debug mode is on in environment variables.
     
    @@ -2547,16 +2541,16 @@ 

    Source code in torrentfile\utils.py -
    - + - + - + - + @@ -175,10 +175,10 @@

    Coverage report:

    - + - + @@ -203,10 +203,10 @@

    Coverage report:

    - + - - + + @@ -219,10 +219,10 @@

    Coverage report:

    - + - - + +
    414
    +        
    - + - + - + - + @@ -175,10 +175,10 @@

    Coverage report:

    - + - + @@ -203,10 +203,10 @@

    Coverage report:

    - + - - + + @@ -219,10 +219,10 @@

    Coverage report:

    - + - - + +
    411
    +412
    +413
    +414
     415
     416
     417
     418
     419
    -420
    -421
    -422
    -423
    def toggle_debug_mode(switch_on: bool):
    +420
    def toggle_debug_mode(switch_on: bool):
         """
         Switch the environment variable debug indicator on or off.
     
    diff --git a/docs/changelog/index.html b/docs/changelog/index.html
    index 392de638..96e4a6d0 100644
    --- a/docs/changelog/index.html
    +++ b/docs/changelog/index.html
    @@ -326,6 +326,13 @@
         
         
      +
    • + + Version 0.8.11 + + +
    • +
    • Version 0.8.10 @@ -950,6 +957,12 @@

      TorrentFile#

      +

      Version 0.8.11#

      +
        +
      • added new command line option for magnet subcommand
      • +
      • fixed some coverage gaps caused by 0.8.10
      • +
      +

      Version 0.8.10#

      • added support for bittorrent v2 magnet links
      • diff --git a/docs/coverage/covindex.html b/docs/coverage/covindex.html index a9d1eb78..d0c176b8 100644 --- a/docs/coverage/covindex.html +++ b/docs/coverage/covindex.html @@ -45,7 +45,7 @@

        Coverage report:

        coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    @@ -140,17 +140,17 @@

    Coverage report:

    torrentfile\cli.py120121 0 1100%100%
    torrentfile\commands.py168171 0 6100%100%
    torrentfile\edit.py
    torrentfile\mixins.py101102 0 4100%100%
    torrentfile\rebuild.py
    torrentfile\utils.py128126 010100%6100%
    torrentfile\version.py
    Total29252928 071100%67100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html index 2dd8a8d4..5c9eef1d 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html index 3ac9c845..5d36b297 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html @@ -54,8 +54,8 @@

    - 120 statements   - + 121 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 168 statements   - + 171 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 101 statements   - + 102 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 128 statements   - + 126 statements   + - +

    « prev     @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 120 statements   - + 121 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 168 statements   - + 171 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 101 statements   - + 102 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    - 128 statements   - + 126 statements   + - +

    « prev     @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    torrentfile\cli.py120121 0 1100%100%
    torrentfile\commands.py168171 0 6100%100%
    torrentfile\edit.py
    torrentfile\mixins.py101102 0 4100%100%
    torrentfile\rebuild.py
    torrentfile\utils.py128126 010100%6100%
    torrentfile\version.py
    Total29252928 071100%67100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-25 01:31 -0700 + created at 2023-03-26 02:06 -0700

    def execute(args: list = None) -> list:
    +665
    +666
    +667
    def execute(args: list = None) -> list:
         """
         Execute program with provided list of arguments.
     
    @@ -1864,13 +1866,15 @@ 

    magnet_parser.add_argument( "--meta-version", action="store", - choices=["1", "2"], - default="1", + choices=["0", "1", "2", "3"], + default="0", help=""" - This option will only effect hybrid torrent files. - Options: 1 or 2 - (1) sha1 - (2) sha256 + This option is only relevant for hybrid torrent files. + Options = 0, 1, 2, 3 + (0) = [default] version is determined automatically + (1) = create V1 magnet link only + (2) = create V2 magnet link only + (3) = create a hybrid magnet link """, dest="meta_version", metavar="<int>", @@ -2019,11 +2023,11 @@

    Source code in torrentfile\cli.py -
    671
    -672
    -673
    +        
    673
     674
    -675
    def main() -> None:
    +675
    +676
    +677
    def main() -> None:
         """
         Initiate main function for CLI script.
         """
    diff --git a/docs/Source/commands/index.html b/docs/Source/commands/index.html
    index 05b986bf..4ae51ead 100644
    --- a/docs/Source/commands/index.html
    +++ b/docs/Source/commands/index.html
    @@ -778,8 +778,7 @@ 

    Source code in torrentfile\commands.py -
    141
    -142
    +        
    142
     143
     144
     145
    @@ -822,7 +821,8 @@ 

    182 183 184 -185

    def create(args: Namespace) -> Namespace:
    +185
    +186
    def create(args: Namespace) -> Namespace:
         """
         Execute the create CLI sub-command to create a new torrent metafile.
     
    @@ -857,7 +857,7 @@ 

    outfile, meta = torrent.write() if args.magnet: - magnet(outfile) + magnet(outfile, version=0) args.torrent = torrent args.kwargs = kwargs @@ -936,8 +936,7 @@

    Source code in torrentfile\commands.py -
    240
    -241
    +        
    241
     242
     243
     244
    @@ -965,7 +964,8 @@ 

    266 267 268 -269

    def edit(args: Namespace) -> str:
    +269
    +270
    def edit(args: Namespace) -> str:
         """
         Execute the edit CLI sub-command with provided arguments.
     
    @@ -1082,8 +1082,7 @@ 

    Source code in torrentfile\commands.py -
    55
    -56
    +        
    56
     57
     58
     59
    @@ -1121,7 +1120,8 @@ 

    91 92 93 -94

    def find_config_file(args: Namespace) -> str:
    +94
    +95
    def find_config_file(args: Namespace) -> str:
         """
         Locate the path to the torrentfile configuration file.
     
    @@ -1227,8 +1227,7 @@ 

    Source code in torrentfile\commands.py -
    346
    -347
    +        
    347
     348
     349
     350
    @@ -1243,7 +1242,8 @@ 

    359 360 361 -362

    def get_magnet(namespace: Namespace) -> str:
    +362
    +363
    def get_magnet(namespace: Namespace) -> str:
         """
         Prepare option parameters for retreiving magnet URI.
     
    @@ -1328,8 +1328,7 @@ 

    Source code in torrentfile\commands.py -
    188
    -189
    +        
    @@ -1509,8 +1509,7 @@

    Source code in torrentfile\commands.py -

    189
     190
     191
     192
    @@ -1377,7 +1376,8 @@ 

    234 235 236 -237

    def info(args: Namespace) -> str:
    +237
    +238
    def info(args: Namespace) -> str:
         """
         Show torrent metafile details to user via stdout.
     
    @@ -1438,7 +1438,7 @@ 

    -magnet(metafile: str, version: int = 1) -> str +magnet(metafile: str, version: int = 0) -> str #

    @@ -1478,7 +1478,7 @@

    DEFAULT: - 1 + 0

    365
    -366
    +        
    366
     367
     368
     369
    @@ -1554,7 +1553,17 @@ 

    407 408 409 -410

    def magnet(metafile: str, version: int = 1) -> str:
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    def magnet(metafile: str, version: int = 0) -> str:
         """
         Create a magnet URI from a Bittorrent meta file.
     
    @@ -1573,19 +1582,26 @@ 

    if not os.path.exists(metafile): raise FileNotFoundError(f"No Such File {metafile}") meta = pyben.load(metafile) - data = meta["info"] - hashing_func = sha1 # nosec - if "meta version" in data: - if version == 2 or "pieces" not in data: - hashing_func = sha256 + info_dict = meta["info"] + + magnet = "magnet:?" + bencoded_info = pyben.dumps(info_dict) + + v1 = False + if "meta version" not in info_dict or ( + version in [1, 3, 0] and "pieces" in info_dict + ): + infohash = sha1(bencoded_info).hexdigest() # nosec + magnet += "xt=urn:btih:" + infohash + v1 = True - bencoded = pyben.dumps(data) - infohash = hashing_func(bencoded).hexdigest().upper() # nosec + if "meta version" in info_dict and version != 1: + infohash = sha256(bencoded_info).hexdigest() + if v1: + magnet += "&" + magnet += "xt=urn:btmh:" + infohash - logger.info("Magnet Info Hash: %s", infohash) - scheme = "magnet:" - hasharg = "?xt=urn:btih:" + infohash - namearg = "&dn=" + quote_plus(data["name"]) + magnet += "&dn=" + quote_plus(info_dict["name"]) if "announce-list" in meta: announce_args = [ @@ -1593,13 +1609,15 @@

    for urllist in meta["announce-list"] for url in urllist ] - else: + elif "announce" in meta: announce_args = ["&tr=" + quote_plus(meta["announce"])] + else: + announce_args = [""] - full_uri = "".join([scheme, hasharg, namearg] + announce_args) - logger.info("Created Magnet URI %s", full_uri) - sys.stdout.write("\n" + full_uri + "\n") - return full_uri + magnet += "".join(announce_args) + logger.info("Created Magnet URI %s", magnet) + sys.stdout.write("\n" + magnet + "\n") + return magnet

    @@ -1657,8 +1675,7 @@

    Source code in torrentfile\commands.py -
     97
    - 98
    +        
     98
      99
     100
     101
    @@ -1698,7 +1715,8 @@ 

    135 136 137 -138

    def parse_config_file(path: str, kwargs: dict):
    +138
    +139
    def parse_config_file(path: str, kwargs: dict):
         """
         Parse configuration file for torrent setup details.
     
    @@ -1813,17 +1831,7 @@ 

    Source code in torrentfile\commands.py -
    413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    +        
    423
     424
     425
     426
    @@ -1841,7 +1849,17 @@ 

    438 439 440 -441

    def rebuild(args: Namespace) -> int:
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    def rebuild(args: Namespace) -> int:
         """
         Attempt to rebuild a torrent based on the a torrent file.
     
    @@ -1939,8 +1957,7 @@ 

    Source code in torrentfile\commands.py -
    272
    -273
    +        
    273
     274
     275
     276
    @@ -1983,7 +2000,8 @@ 

    313 314 315 -316

    def recheck(args: Namespace) -> str:
    +316
    +317
    def recheck(args: Namespace) -> str:
         """
         Execute recheck CLI sub-command.
     
    @@ -2094,8 +2112,7 @@ 

    Source code in torrentfile\commands.py -
    - + - + @@ -147,10 +147,10 @@

    Coverage report:

    - + - + @@ -219,10 +219,10 @@

    Coverage report:

    - + - +
    319
    -320
    +        
    - + - + @@ -147,10 +147,10 @@

    Coverage report:

    - + - + @@ -219,10 +219,10 @@

    Coverage report:

    - + - +
    320
     321
     322
     323
    @@ -2118,7 +2135,8 @@ 

    340 341 342 -343

    def rename(args: Namespace) -> str:
    +343
    +344
    def rename(args: Namespace) -> str:
         """
         Rename a torrent file to it's original name found in metadata.
     
    diff --git a/docs/changelog/index.html b/docs/changelog/index.html
    index 96e4a6d0..a9aa3378 100644
    --- a/docs/changelog/index.html
    +++ b/docs/changelog/index.html
    @@ -961,6 +961,9 @@ 

    Version 0.8.11
  • added new command line option for magnet subcommand
  • fixed some coverage gaps caused by 0.8.10
  • +
  • fixed bugs introduced by 0.8.10 with magnet URI creation
  • +
  • added support for hybrid magnet links
  • +
  • added tests for when a magnet link is generated with no trackers at all

  • Version 0.8.10#

    diff --git a/docs/coverage/covindex.html b/docs/coverage/covindex.html index d0c176b8..ed846611 100644 --- a/docs/coverage/covindex.html +++ b/docs/coverage/covindex.html @@ -45,7 +45,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    @@ -77,10 +77,10 @@

    Coverage report:

    tests\test_commands.py167177 0 1100%100%
    tests\test_edit.py
    torrentfile\commands.py171176 0 6100%100%
    torrentfile\edit.py
    Total29282943 0 67100%100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html index 5c9eef1d..efa50494 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html index 5d36b297..2e189c0f 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    - 171 statements   - + 176 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    - 167 statements   - + 177 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    - 171 statements   - + 176 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    - 167 statements   - + 177 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    tests\test_commands.py167177 0 1100%100%
    tests\test_edit.py
    torrentfile\commands.py171176 0 6100%100%
    torrentfile\edit.py
    Total29282943 0 67100%100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 02:06 -0700 + created at 2023-03-26 03:49 -0700

    def magnet(metafile: str, version: int = 0) -> str:
    +420
    +421
    +422
    +423
    def magnet(metafile: str, version: int = 0) -> str:
         """
         Create a magnet URI from a Bittorrent meta file.
     
    @@ -1599,7 +1602,7 @@ 

    infohash = sha256(bencoded_info).hexdigest() if v1: magnet += "&" - magnet += "xt=urn:btmh:" + infohash + magnet += "xt=urn:btmh:1220" + infohash magnet += "&dn=" + quote_plus(info_dict["name"]) @@ -1614,7 +1617,10 @@

    else: announce_args = [""] - magnet += "".join(announce_args) + trackers = "".join(announce_args) + + magnet += trackers if trackers != "&tr=" else "" + logger.info("Created Magnet URI %s", magnet) sys.stdout.write("\n" + magnet + "\n") return magnet @@ -1831,10 +1837,7 @@

    Source code in torrentfile\commands.py -
    - + - + @@ -219,10 +219,10 @@

    Coverage report:

    - + - +
    423
    -424
    -425
    -426
    +        
    - + - + @@ -219,10 +219,10 @@

    Coverage report:

    - + - +
    426
     427
     428
     429
    @@ -1859,7 +1862,10 @@ 

    448 449 450 -451

    def rebuild(args: Namespace) -> int:
    +451
    +452
    +453
    +454
    def rebuild(args: Namespace) -> int:
         """
         Attempt to rebuild a torrent based on the a torrent file.
     
    diff --git a/docs/coverage/covindex.html b/docs/coverage/covindex.html
    index ed846611..91ca313e 100644
    --- a/docs/coverage/covindex.html
    +++ b/docs/coverage/covindex.html
    @@ -45,7 +45,7 @@ 

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    @@ -147,10 +147,10 @@

    Coverage report:

    torrentfile\commands.py176177 0 6100%100%
    torrentfile\edit.py
    Total29432944 0 67100%100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html index efa50494..48c2326e 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec___main___py.html @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    diff --git a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html index 2e189c0f..7df77714 100644 --- a/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html +++ b/docs/coverage/d_1bc82e0ab2fcb2ec_cli_py.html @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    - 176 statements   - + 177 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    - 176 statements   - + 177 statements   +

    @@ -65,7 +65,7 @@

    » next       coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700

    torrentfile\commands.py176177 0 6100%100%
    torrentfile\edit.py
    Total29432944 0 67100%100%
    @@ -234,7 +234,7 @@

    Coverage report:

    coverage.py v7.2.2, - created at 2023-03-26 03:49 -0700 + created at 2023-03-26 04:49 -0700