Python Read Torrent Size / 讀取BT檔案的大小


因為某些情況下,不想常常使用軟件來打開種子查看大小.
所以就寫了這個小程式,當中使用了別人寫的 decoder 檔案.
所以寫起來比較輕鬆..記錄一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/python
# -*- coding: utf-8 -*-
#=========================================
split_line_length = 80
#=========================================
__version__ = "0.0.1 Beta"
__author__ = "Zeuxis Lo"
__datetime__ = "201005312313"
__appname__ = "Torrent File Total Size(Python)"

import sys, getopt, decoder, time

def get_size_fromat(n):
K, M, G, T = 1 << 10, 1 << 20, 1 << 30, 1 << 40
if n >= T:
return '%.2f T' % (float(n) / T)
elif n >= G:
return '%.2f G' % (float(n) / G)
elif n >= M:
return '%.2f M' % (float(n) / M)
elif n >= K:
return '%.2f K' % (float(n) / K)
else:
return '%.2f B' % n

def main(argv=None):
if argv is None:
argv = sys.argv

if len(argv) == 2:
data = decoder.decode(open(argv[1], "rb").read())

#data.keys()
print "%-25s" % ("-" * split_line_length)
print "%-14s | %s" % ("Size", "File Name")
print "%-25s" % ("-" * split_line_length)

total_size = 0
for file in data["info"]["files"]:
path = "/".join(file["path"])
length = file["length"]
if path[:5] != "_____":
total_size += length
print "%14s | %s" % (get_size_fromat(length), path.decode(data["encoding"]).encode("big5"))

print "%-25s" % ("-" * split_line_length)
print "Total Size: %s" % get_size_fromat(total_size)
print "%-25s" % ("-" * split_line_length)

time.sleep(1)
sys.exit()
else:
print "python torrent_size.py [file name]"
return 2

if __name__ == "__main__":
sys.exit(main())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import re

def tokenize(text, match=re.compile("([idel])|(\d+):|(-?\d+)").match):
i = 0
while i < len(text):
m = match(text, i)
s = m.group(m.lastindex)
i = m.end()
if m.lastindex == 2:
yield "s"
yield text[i:i+int(s)]
i = i + int(s)
else:
yield s

def decode_item(next, token):
if token == "i":
# integer: "i" value "e"
data = int(next())
if next() != "e":
raise ValueError
elif token == "s":
# string: "s" value (virtual tokens)
data = next()
elif token == "l" or token == "d":
# container: "l" (or "d") values "e"
data = []
tok = next()
while tok != "e":
data.append(decode_item(next, tok))
tok = next()
if token == "d":
data = dict(zip(data[0::2], data[1::2]))
else:
raise ValueError
return data

def decode(text):
try:
src = tokenize(text)
data = decode_item(src.next, src.next())
for token in src: # look for more tokens
raise SyntaxError("trailing junk")
except (AttributeError, ValueError, StopIteration):
raise SyntaxError("syntax error")
return data