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