Fixed torrent transport
solar_torrent.py is copied to resource scripts, this is temporary solution. I added TODO note for that. Fixed torrent ports to 6881-6981 Change-Id: I4d8728f5958929e924c2644874975c0bf9bfe75a
This commit is contained in:
parent
b4ae0f2127
commit
bb0c552abb
@ -1 +0,0 @@
|
||||
../../../solar/core/transports/helpers/solar_torrent.py
|
194
resources/transport_torrent/1.0.0/scripts/solar_torrent.py
Normal file
194
resources/transport_torrent/1.0.0/scripts/solar_torrent.py
Normal file
@ -0,0 +1,194 @@
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO: change to something less naive
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import libtorrent as lt
|
||||
from operator import attrgetter
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
state_str = ['queued', 'checking', 'downloading metadata', 'downloading',
|
||||
'finished', 'seeding', 'allocating', 'checking fastresume']
|
||||
|
||||
|
||||
# we use port range from 6881 to 6981
|
||||
|
||||
|
||||
class MultiTorrent(object):
|
||||
def __init__(self, torrents, ses):
|
||||
self.torrents = torrents
|
||||
self.ses = ses
|
||||
|
||||
def force_reannounce(self):
|
||||
for torrent in self.torrents:
|
||||
torrent.force_reannounce()
|
||||
|
||||
@property
|
||||
def is_seeding(self):
|
||||
for torrent in self.torrents:
|
||||
status = torrent.status()
|
||||
if state_str[status.state] != 'seeding':
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def progress(self):
|
||||
total_progress = map(
|
||||
attrgetter('progress'), map(lambda x: x.status(), self.torrents))
|
||||
return sum(total_progress) / len(total_progress)
|
||||
|
||||
def numbers(self):
|
||||
seeding = 0
|
||||
downloading = 0
|
||||
for torrent in self.torrents:
|
||||
if torrent.status().is_seeding:
|
||||
seeding += 1
|
||||
else:
|
||||
downloading += 1
|
||||
return seeding, downloading
|
||||
|
||||
|
||||
def init_session(args, seed=False):
|
||||
ses = lt.session()
|
||||
all_torrents = []
|
||||
for save_path, magnet_or_path in args:
|
||||
if os.path.exists(magnet_or_path):
|
||||
e = lt.bdecode(open(magnet_or_path, 'rb').read())
|
||||
info = lt.torrent_info(e)
|
||||
params = {'save_path': save_path,
|
||||
'storage_mode': lt.storage_mode_t.storage_mode_sparse,
|
||||
'ti': info,
|
||||
'seed_mode': seed}
|
||||
h = ses.add_torrent(params)
|
||||
else:
|
||||
h = ses.add_torrent({
|
||||
'save_path': save_path,
|
||||
'storage_mode': lt.storage_mode_t.storage_mode_sparse,
|
||||
'url': magnet_or_path,
|
||||
'seed_mode': seed
|
||||
})
|
||||
all_torrents.append(h)
|
||||
return ses, all_torrents
|
||||
|
||||
|
||||
def _daemonize():
|
||||
# should be true daemonize
|
||||
new_pid = os.fork()
|
||||
if new_pid > 0:
|
||||
# first
|
||||
sys.exit(0)
|
||||
os.setsid()
|
||||
new_pid2 = os.fork()
|
||||
if new_pid2 > 0:
|
||||
sys.exit(0)
|
||||
stdin = file(os.devnull, 'r')
|
||||
stdout = file(os.devnull, 'a+')
|
||||
stderr = file(os.devnull, 'a+', 0)
|
||||
os.dup2(stdin.fileno(), sys.stdin.fileno())
|
||||
os.dup2(stdout.fileno(), sys.stdout.fileno())
|
||||
os.dup2(stderr.fileno(), sys.stderr.fileno())
|
||||
|
||||
|
||||
def _seeder(torrents, save_path='.', max_seed_ratio=5):
|
||||
_daemonize()
|
||||
no_peers = 120
|
||||
max_alive = 5 * 60
|
||||
ses, all_torrents = init_session(torrents, seed=True)
|
||||
ses.listen_on(6881, 6981)
|
||||
|
||||
mt = MultiTorrent(all_torrents, ses)
|
||||
end = time.time() + max_alive
|
||||
peers_0 = time.time()
|
||||
i = 0
|
||||
while not time.time() > end:
|
||||
now = time.time()
|
||||
i += 1
|
||||
# if i % 10 == 0 and i != 0:
|
||||
# mt.force_reannounce()
|
||||
s = ses.status()
|
||||
# if not mt.is_seeding:
|
||||
# sys.exit("Was seeder mode but not seeding")
|
||||
if peers_0 < now - no_peers:
|
||||
sys.exit("No peers for %d seconds exiting" % no_peers)
|
||||
if i % 5 == 0:
|
||||
print("%.2f%% up=%.1f kB/s peers=%s total_upload_B=%.1f" %
|
||||
(mt.progress * 100, s.upload_rate / 1000, s.num_peers,
|
||||
s.total_upload))
|
||||
if s.num_peers != 0:
|
||||
peers_0 = now
|
||||
sys.stdout.flush()
|
||||
time.sleep(1)
|
||||
else:
|
||||
print('Seed timeout exiting')
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def _getter(torrents, max_seed_ratio=3):
|
||||
max_no_changes = 1 * 60
|
||||
ses, all_torrents = init_session(torrents)
|
||||
ses.listen_on(6881, 6981)
|
||||
|
||||
mt = MultiTorrent(all_torrents, ses)
|
||||
|
||||
i = 0
|
||||
last_state = (time.time(), None)
|
||||
while (not mt.is_seeding):
|
||||
i += 1
|
||||
# if i % 10 == 0 and i != 0:
|
||||
# mt.force_reannounce()
|
||||
s = ses.status()
|
||||
if i % 5 == 0:
|
||||
print('%.2f%% complete (down: %.1f kb/s up: %.1f kB/s p: %d) %s' %
|
||||
(mt.progress * 100,
|
||||
s.download_rate / 1000,
|
||||
s.upload_rate / 1000,
|
||||
s.num_peers,
|
||||
mt.numbers()))
|
||||
now = time.time()
|
||||
current_state = (now, mt.progress)
|
||||
if current_state[-1] != last_state[-1]:
|
||||
last_state = current_state
|
||||
if last_state[0] < now - max_no_changes:
|
||||
sys.exit("Failed to fetch torrents in %ds" % max_no_changes)
|
||||
time.sleep(0.5)
|
||||
if mt.progress == 1:
|
||||
# ok
|
||||
# torrent lib dislikes forks there
|
||||
from subprocess import check_output
|
||||
args = sys.argv[:]
|
||||
args[-2] = 's'
|
||||
args.insert(0, sys.executable)
|
||||
print("Entering seeder mode")
|
||||
check_output(args, shell=False)
|
||||
else:
|
||||
# err
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mode = sys.argv[1]
|
||||
torrents = sys.argv[2]
|
||||
torrents = [x.split('|') for x in torrents.split(';')]
|
||||
print(repr(torrents))
|
||||
if mode == 'g':
|
||||
_getter(torrents, *sys.argv[3:])
|
||||
elif mode == 's':
|
||||
_seeder(torrents, *sys.argv[3:])
|
||||
else:
|
||||
sys.exit("`s` or `g` needed")
|
Loading…
Reference in New Issue
Block a user