From b5fcddd6a68b7e18d1e5521e7363046ca0e68667 Mon Sep 17 00:00:00 2001
From: jvoisin <julien.voisin@dustri.org>
Date: Sun, 8 Jul 2018 13:47:00 +0200
Subject: [PATCH] Simplify how torrent files are handled

- Rework the testsuite wrt. torrent
- fail at parser's instantiation on corrupted torrent,
  instead of during `get_meta` or `remove_all` call
---
 libmat2/torrent.py            | 20 ++++++++++----------
 tests/test_corrupted_files.py | 11 +++++------
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/libmat2/torrent.py b/libmat2/torrent.py
index ad49f47..d614136 100644
--- a/libmat2/torrent.py
+++ b/libmat2/torrent.py
@@ -8,13 +8,16 @@ class TorrentParser(abstract.AbstractParser):
     mimetypes = {'application/x-bittorrent', }
     whitelist = {b'announce', b'announce-list', b'info'}
 
+    def __init__(self, filename):
+        super().__init__(filename)
+        with open(self.filename, 'rb') as f:
+            self.dict_repr = _BencodeHandler().bdecode(f.read())
+        if self.dict_repr is None:
+            raise ValueError
+
     def get_meta(self) -> Dict[str, str]:
         metadata = {}
-        with open(self.filename, 'rb') as f:
-            d = _BencodeHandler().bdecode(f.read())
-        if d is None:
-            return {'Unknown meta': 'Unable to parse torrent file "%s".' % self.filename}
-        for k, v in d.items():
+        for k, v in self.dict_repr.items():
             if k not in self.whitelist:
                 metadata[k.decode('utf-8')] = v
         return metadata
@@ -22,15 +25,12 @@ class TorrentParser(abstract.AbstractParser):
 
     def remove_all(self) -> bool:
         cleaned = dict()
-        with open(self.filename, 'rb') as f:
-            d = _BencodeHandler().bdecode(f.read())
-        if d is None:
-            return False
-        for k, v in d.items():
+        for k, v in self.dict_repr.items():
             if k in self.whitelist:
                 cleaned[k] = v
         with open(self.output_filename, 'wb') as f:
             f.write(_BencodeHandler().bencode(cleaned))
+        self.dict_repr = cleaned  # since we're stateful
         return True
 
 
diff --git a/tests/test_corrupted_files.py b/tests/test_corrupted_files.py
index bc5b9d0..776b0e9 100644
--- a/tests/test_corrupted_files.py
+++ b/tests/test_corrupted_files.py
@@ -46,15 +46,14 @@ class TestCorruptedFiles(unittest.TestCase):
 
     def test_torrent(self):
         shutil.copy('./tests/data/dirty.png', './tests/data/clean.torrent')
-        p = torrent.TorrentParser('./tests/data/clean.torrent')
-        self.assertFalse(p.remove_all())
-        expected = {'Unknown meta': 'Unable to parse torrent file "./tests/data/clean.torrent".'}
-        self.assertEqual(p.get_meta(), expected)
+        with self.assertRaises(ValueError):
+            torrent.TorrentParser('./tests/data/clean.torrent')
 
         with open("./tests/data/clean.torrent", "a") as f:
             f.write("trailing garbage")
-        p = torrent.TorrentParser('./tests/data/clean.torrent')
-        self.assertEqual(p.get_meta(), expected)
+        with self.assertRaises(ValueError):
+            torrent.TorrentParser('./tests/data/clean.torrent')
+
         os.remove('./tests/data/clean.torrent')
 
     def test_odg(self):
-- 
GitLab