deluge/deluge/metafile.py
Calum Lind b1cdc32f73 [Lint] Use Black to auto-format code
The move to using auto-formatter makes it easier to read, submit and
speeds up development time. https://github.com/ambv/black/

Although I would prefer 79 chars, the default line length of 88 chars
used by black suffices. The flake8 line length remains at 120 chars
since black does not touch comments or docstrings and this will require
another round of fixes.

The only black setting that is not standard is the use of double-quotes
for strings so disabled any formatting of these. Note however that
flake8 will still flag usage of double-quotes. I may change my mind on
double vs single quotes but for now leave them.

A new pyproject.toml file has been created for black configuration.
2018-10-03 15:21:53 +01:00

247 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
#
# Original file from BitTorrent-5.3-GPL.tar.gz
# Copyright (C) Bram Cohen
#
# Modifications for use in Deluge:
# Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import division, unicode_literals
import logging
import os.path
import time
from hashlib import sha1 as sha
import deluge.component as component
from deluge.bencode import bencode
from deluge.common import utf8_encode_structure
from deluge.event import CreateTorrentProgressEvent
log = logging.getLogger(__name__)
ignore = ['core', 'CVS', 'Thumbs.db', 'desktop.ini']
noncharacter_translate = {}
for i in range(0xD800, 0xE000):
noncharacter_translate[i] = ord('-')
for i in range(0xFDD0, 0xFDF0):
noncharacter_translate[i] = ord('-')
for i in (0xFFFE, 0xFFFF):
noncharacter_translate[i] = ord('-')
def gmtime():
return time.mktime(time.gmtime())
def dummy(*v):
pass
class RemoteFileProgress(object):
def __init__(self, session_id):
self.session_id = session_id
def __call__(self, piece_count, num_pieces):
component.get('RPCServer').emit_event_for_session_id(
self.session_id, CreateTorrentProgressEvent(piece_count, num_pieces)
)
def make_meta_file(
path,
url,
piece_length,
progress=None,
title=None,
comment=None,
safe=None,
content_type=None,
target=None,
webseeds=None,
name=None,
private=False,
created_by=None,
trackers=None,
):
data = {'creation date': int(gmtime())}
if url:
data['announce'] = url.strip()
a, b = os.path.split(path)
if not target:
if b == '':
f = a + '.torrent'
else:
f = os.path.join(a, b + '.torrent')
else:
f = target
if progress is None:
progress = dummy
try:
session_id = component.get('RPCServer').get_session_id()
except KeyError:
pass
else:
if session_id:
progress = RemoteFileProgress(session_id)
info = makeinfo(path, piece_length, progress, name, content_type, private)
# check_info(info)
data['info'] = info
if title:
data['title'] = title.encode('utf8')
if comment:
data['comment'] = comment.encode('utf8')
if safe:
data['safe'] = safe.encode('utf8')
httpseeds = []
url_list = []
if webseeds:
for webseed in webseeds:
if webseed.endswith('.php'):
httpseeds.append(webseed)
else:
url_list.append(webseed)
if url_list:
data['url-list'] = url_list
if httpseeds:
data['httpseeds'] = httpseeds
if created_by:
data['created by'] = created_by.encode('utf8')
if trackers and (len(trackers[0]) > 1 or len(trackers) > 1):
data['announce-list'] = trackers
data['encoding'] = 'UTF-8'
with open(f, 'wb') as file_:
file_.write(bencode(utf8_encode_structure(data)))
def calcsize(path):
total = 0
for s in subfiles(os.path.abspath(path)):
total += os.path.getsize(s[1])
return total
def makeinfo(path, piece_length, progress, name=None, content_type=None, private=False):
# HEREDAVE. If path is directory, how do we assign content type?
path = os.path.abspath(path)
piece_count = 0
if os.path.isdir(path):
subs = sorted(subfiles(path))
pieces = []
sh = sha()
done = 0
fs = []
totalsize = 0.0
totalhashed = 0
for p, f in subs:
totalsize += os.path.getsize(f)
if totalsize >= piece_length:
import math
num_pieces = math.ceil(totalsize / piece_length)
else:
num_pieces = 1
for p, f in subs:
pos = 0
size = os.path.getsize(f)
p2 = [n.encode('utf8') for n in p]
if content_type:
fs.append(
{'length': size, 'path': p2, 'content_type': content_type}
) # HEREDAVE. bad for batch!
else:
fs.append({'length': size, 'path': p2})
with open(f, 'rb') as file_:
while pos < size:
a = min(size - pos, piece_length - done)
sh.update(file_.read(a))
done += a
pos += a
totalhashed += a
if done == piece_length:
pieces.append(sh.digest())
piece_count += 1
done = 0
sh = sha()
progress(piece_count, num_pieces)
if done > 0:
pieces.append(sh.digest())
piece_count += 1
progress(piece_count, num_pieces)
if not name:
name = os.path.split(path)[1]
return {
'pieces': b''.join(pieces),
'piece length': piece_length,
'files': fs,
'name': name.encode('utf8'),
'private': private,
}
else:
size = os.path.getsize(path)
if size >= piece_length:
num_pieces = size // piece_length
else:
num_pieces = 1
pieces = []
p = 0
with open(path, 'rb') as _file:
while p < size:
x = _file.read(min(piece_length, size - p))
pieces.append(sha(x).digest())
piece_count += 1
p += piece_length
if p > size:
p = size
progress(piece_count, num_pieces)
name = os.path.split(path)[1].encode('utf8')
if content_type is not None:
return {
'pieces': b''.join(pieces),
'piece length': piece_length,
'length': size,
'name': name,
'content_type': content_type,
'private': private,
}
return {
'pieces': b''.join(pieces),
'piece length': piece_length,
'length': size,
'name': name,
'private': private,
}
def subfiles(d):
r = []
stack = [([], d)]
while stack:
p, n = stack.pop()
if os.path.isdir(n):
for s in os.listdir(n):
if s not in ignore and not s.startswith('.'):
stack.append((p + [s], os.path.join(n, s)))
else:
r.append((p, n))
return r