summaryrefslogtreecommitdiff
path: root/lib/thandy/bt_compat.py
diff options
context:
space:
mode:
authorSebastian Hahn <sebastian@torproject.org>2009-08-11 13:43:06 +0200
committerSebastian Hahn <sebastian@torproject.org>2009-08-25 20:10:25 +0200
commitaa0d32f4b675e155e6e004604bf8b6ee4e607873 (patch)
tree110c9722f93380497447c54bf07f4227f11b7206 /lib/thandy/bt_compat.py
parent6ebc7d6103098e695c33f55f84e6f64f5d795e84 (diff)
Add ability to create .torrent metadata when making a package
Also update the spec with the information where the .torrent metadata file will be stored.
Diffstat (limited to 'lib/thandy/bt_compat.py')
-rw-r--r--lib/thandy/bt_compat.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/thandy/bt_compat.py b/lib/thandy/bt_compat.py
new file mode 100644
index 0000000..43cecad
--- /dev/null
+++ b/lib/thandy/bt_compat.py
@@ -0,0 +1,76 @@
+# Copyright 2008 The Tor Project, Inc. See LICENSE for licensing information.
+
+import os.path
+import time
+
+import thandy.master_keys
+
+no_bt = None
+try:
+ import BitTorrent.bencode
+ import BitTorrent.btformats
+ import BitTorrent.download
+except ImportError:
+ no_bt = True
+from sha import sha # XXX Use PyCrypto here?
+
+
+class BtCompat:
+ """Interface for different bittorrent implementations"""
+
+ usingBt = False
+
+ def __init__(self):
+ self.tUrl = thandy.master_keys.DEFAULT_TRACKER
+ if not no_bt:
+ assert(self.tUrl is not None and self.tUrl != "")
+ self.pieceLength = 2 ** 18 # Piece length of 262144 bytes
+
+ # XXX Do we need to be thread-safe here and below?
+ @staticmethod
+ def shouldUseBt():
+ return BtCompat.usingBt
+
+ @staticmethod
+ def setUseBt(useBt):
+ if no_bt:
+ return
+ BtCompat.usingBt = useBt
+
+ @staticmethod
+ def getBtMetadataLocation(packagepath, filepath, pathprefix=""):
+ """Given a path for the package, the path for a file of that
+ package, and an optional prefix, return the path for the
+ .torrent metadata file. Always return Unix-like paths, to
+ ensure compatibility with fetching the path from a
+ webserver.
+ """
+ return (os.path.join(pathprefix, os.path.dirname(packagepath),
+ os.path.basename(filepath)) + ".torrent"
+ ).replace("\\", "/")
+
+ def makeMetaFile(self, file):
+ """Given a path to a file, create the contents of a .torrent
+ metadata file and return them.
+ """
+ size = os.path.getsize(file)
+ filename = os.path.basename(file)
+ pieces = []
+ p = 0
+ h = open(file, 'rb')
+ while p < size:
+ x = h.read(min(self.pieceLength, size - p))
+ pieces.append(sha(x).digest())
+ p += self.pieceLength
+ if p > size:
+ p = size
+ h.close()
+ info = {'pieces': ''.join(pieces),
+ 'piece length': self.pieceLength, 'length': size,
+ 'name': filename}
+ # Check we didn't screw up with the info
+ BitTorrent.btformats.check_info(info)
+ data = {'info': info, 'announce': self.tUrl,
+ 'creation date': long(time.time())}
+ return BitTorrent.bencode.bencode(data)
+