11 Commits

Author SHA1 Message Date
Anders Jensen
86c6b0db00 Merge branch 'release/0.10.2' 2018-08-25 18:05:25 +02:00
Anders Jensen
73ddeb021c bumped version 2018-08-25 18:05:12 +02:00
Anders Jensen
21f1d77568 ensuring torrent is added fully before streaming 2018-08-25 18:03:30 +02:00
Anders Jensen
015a7cbc7a added buffer buster and some wrong math 2018-08-25 17:53:55 +02:00
Anders Jensen
3417b109ec Added example 2018-08-25 10:20:20 +02:00
Anders Jensen
3a3c90ed8b Merge tag '0.10.1' into develop
-
2018-08-25 09:55:32 +02:00
Anders Jensen
bfe0f9f49c Merge branch 'release/0.10.1' 2018-08-25 09:55:31 +02:00
Anders Jensen
9e38de34f2 updated readme and version 2018-08-25 09:55:11 +02:00
Anders Jensen
ec02a2e61d ensure priorities arent overwritten 2018-08-25 09:53:04 +02:00
Anders Jensen
0e63ed4ebc fixed small bug with file priority overwriting manual priority management 2018-08-25 09:16:07 +02:00
Anders Jensen
ba6c689d98 Merge tag '0.10.0' into develop
-
2018-08-24 21:23:40 +02:00
6 changed files with 96 additions and 26 deletions

View File

@@ -51,6 +51,13 @@ The _allow remote_ option is to allow remote add and stream of torrents.
# Version Info
## Version 0.10.2
* Busting cache when waiting for piece
* Math error in calculating size of readable bytes
## Version 0.10.1
* Small bugfixes related to priorities, should actually make sequential download work.
## Version 0.10.0
* Rewrote large parts of the code
* Now using [thomas](https://github.com/JohnDoee/thomas) as file-reading core - this adds support for multi-rar streaming.

View File

@@ -0,0 +1,23 @@
# Commandline Tool to stream
Stream from the commandline.
## Requirements
* Python
* deluge_client python package
## Installation example
```bash
virtualenv cli-example
cli-example/bin/pip install deluge_client
```
## Usage
Open a torrent directly in VLC on Linux or OSX.
```bash
vlc `cli-example/bin/python stream-cli.py username password my_video.torrent`
```

View File

@@ -0,0 +1,28 @@
import argparse
import urllib
from deluge_client import DelugeRPCClient
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Stream something.')
parser.add_argument('username', type=str, help='Deluge username')
parser.add_argument('password', type=str, help='Deluge password')
parser.add_argument('path_or_url', type=str, help='Path or URL to torrent')
parser.add_argument('--hostname', '-o', type=str, default='localhost', help='Deluge daemon hostname or ip')
parser.add_argument('--port', '-p', type=int, default=58846, help='Deluge daemon port')
args = parser.parse_args()
if args.path_or_url.startswith('http'):
filedata = urllib.urlopen(args.path_or_url).read()
else:
with open(args.path_or_url, 'rb') as f:
filedata = f.read()
client = DelugeRPCClient(args.hostname, args.port, args.username, args.password)
client.connect()
result = client.streaming.stream_torrent(None, None, filedata, None, None, True)
print(result['url'])

View File

@@ -42,7 +42,7 @@ from setuptools import setup, find_packages
__plugin_name__ = "Streaming"
__author__ = "Anders Jensen"
__author_email__ = "johndoee@tidalstream.org"
__version__ = "0.10.0"
__version__ = "0.10.2"
__url__ = "https://github.com/JohnDoee/deluge-streaming"
__license__ = "GPLv3"
__description__ = "Enables streaming of files while downloading them."

View File

@@ -70,6 +70,7 @@ VIDEO_STREAMABLE_EXTENSIONS = ['mkv', 'mp4', 'iso', 'ogg', 'ogm', 'm4v']
AUDIO_STREAMABLE_EXTENSIONS = ['flac', 'mp3', 'oga']
STREAMABLE_EXTENSIONS = set(VIDEO_STREAMABLE_EXTENSIONS + AUDIO_STREAMABLE_EXTENSIONS)
TORRENT_CLEANUP_INTERVAL = timedelta(minutes=30)
MAX_FILE_PRIORITY = 2
DEFAULT_PREFS = {
'ip': '127.0.0.1',
@@ -164,10 +165,12 @@ class Torrent(object):
self.torrent.handle.piece_priority(needed_piece, 7)
f = self.get_file_from_offset(from_byte)
logger.debug('Also setting file to max %r' % (f, ))
file_priorities = self.torrent.get_file_priorities()
file_priorities[f['index']] = 7
self.torrent.set_file_priorities(file_priorities)
if file_priorities[f['index']] != MAX_FILE_PRIORITY:
logger.debug('Also setting file to max %r' % (f, ))
file_priorities[f['index']] = MAX_FILE_PRIORITY
self.torrent.set_file_priorities(file_priorities)
for _ in range(300):
if self.torrent.status.pieces[needed_piece]:
@@ -179,7 +182,7 @@ class Torrent(object):
logger.debug('Calling read again to get the real number')
return self.can_read(from_byte)
else:
return ((last_available_piece - needed_piece) * self.piece_length) + rest + self.piece_length
return ((last_available_piece - needed_piece) * self.piece_length) + self.piece_length - rest
def is_idle(self):
return not self.readers and self.last_activity + TORRENT_CLEANUP_INTERVAL < datetime.now()
@@ -239,7 +242,7 @@ class Torrent(object):
if f['path'] in must_whitelist:
if f['path'] in first_files:
file_priorities[i] = 7
file_priorities[i] = MAX_FILE_PRIORITY
else:
file_priorities[i] = 1
elif f['path'] not in cannot_blacklist:
@@ -265,6 +268,23 @@ class Torrent(object):
else:
fileset_ranges[fileset_hash] = fileset['files'].index(path)
file_priorities = self.torrent.get_file_priorities()
logger.debug('Fileset heads: %r' % (fileset_ranges, ))
for fileset_hash, first_file in fileset_ranges.items():
fileset = self.filesets[fileset_hash]
logger.debug('From index %s' % (first_file, ))
file_mapping = {f['path']: f['index'] for f in status['files']}
for i, f in enumerate(fileset['files']):
index = file_mapping[f]
if i < first_file:
file_priorities[index] = 0
elif i == first_file:
file_priorities[index] = MAX_FILE_PRIORITY
else:
file_priorities[index] = 1
self.torrent.set_file_priorities(file_priorities)
currently_downloading = self.get_currently_downloading()
logger.debug('File heads: %r' % (file_ranges, ))
for f, progress in zip(status['files'], status['file_progress']):
@@ -296,23 +316,6 @@ class Torrent(object):
else:
self.torrent.handle.piece_priority(piece, 1)
file_priorities = self.torrent.get_file_priorities()
logger.debug('Fileset heads: %r' % (fileset_ranges, ))
for fileset_hash, first_file in fileset_ranges.items():
fileset = self.filesets[fileset_hash]
logger.debug('From index %s' % (first_file, ))
file_mapping = {f['path']: f['index'] for f in status['files']}
for i, f in enumerate(fileset['files']):
index = file_mapping[f]
if i < first_file:
file_priorities[index] = 0
elif i == first_file:
file_priorities[index] = 7
else:
file_priorities[index] = 1
self.torrent.set_file_priorities(file_priorities)
def get_currently_downloading(self):
currently_downloading = set()
for peer in self.torrent.handle.get_peer_info():
@@ -388,8 +391,7 @@ class TorrentHandler(object):
def get_filesystem(self, infohash):
torrent = get_torrent(infohash)
status = torrent.get_status(['piece_length', 'files', 'file_progress', 'save_path'])
self.piece_length = status['piece_length']
status = torrent.get_status(['files', 'file_progress', 'save_path'])
save_path = status['save_path']
found_rar = False
@@ -453,9 +455,16 @@ class TorrentHandler(object):
@defer.inlineCallbacks
def stream(self, infohash, path, wait_for_end_pieces=False):
logger.debug('Trying to get path:%s from infohash:%s' % (path, infohash))
local_torrent = self.get_torrent(infohash)
torrent = get_torrent(infohash)
for _ in range(10):
status = torrent.get_status(['piece_length'])
if status['piece_length'] > 0:
break
yield sleep(0.2)
local_torrent = self.get_torrent(infohash)
filesystem = self.get_filesystem(infohash)
if path:
stream_item = filesystem.get_item_from_path(path)

View File

@@ -50,6 +50,9 @@ class DelugeTorrentInput(InputBase.find_plugin('file')):
if self.can_read_to <= tell or self.can_read_to is None:
self.can_read_to = self.torrent.can_read(self.offset + tell) + tell
if self._open_file:
self._open_file.seek(tell)
real_num = min(num, self.can_read_to - tell)
if num != real_num:
logger.info('The real number we can read to is %s and not %s at position %s' % (real_num, num, tell))