From 1d31efa48c5b76117b0614370a1015caa6102db2 Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Sat, 21 Nov 2015 20:29:42 +0100 Subject: [PATCH 1/7] fixed small bug with unloading --- streaming/gtkui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/streaming/gtkui.py b/streaming/gtkui.py index e536e4d..d8cce91 100644 --- a/streaming/gtkui.py +++ b/streaming/gtkui.py @@ -132,8 +132,8 @@ class GtkUI(GtkPluginBase): torrentmenu = component.get("MenuBar").torrentmenu - file_menu.remove(self.item_torrentmenu) - file_menu.remove(self.sep_torrentmenu) + torrentmenu.remove(self.item_torrentmenu) + torrentmenu.remove(self.sep_torrentmenu) self.site.stopFactory() yield self.listening.stopListening() From bcc2067e55ab46868ba23f67f364c58f1aa20778 Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Sun, 22 Nov 2015 16:20:37 +0100 Subject: [PATCH 2/7] Proper handling of name / not name in requested file --- streaming/core.py | 34 +++++++++++++++++----------------- streaming/data/streaming.js | 2 +- streaming/gtkui.py | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/streaming/core.py b/streaming/core.py index ab1bdc3..de58bee 100644 --- a/streaming/core.py +++ b/streaming/core.py @@ -295,23 +295,23 @@ class Torrent(object): last_piece = (f['offset'] + f['size']) / piece_length full_path = os.path.join(save_path, f['path']) - path = f['path'] - if '/' in path: - path = '/'.join(path.split('/')[1:]) - self.torrent_files.append(TorrentFile(self, first_piece, last_piece, piece_length, f['offset'], - path, full_path, f['size'], f['index'])) + f['path'], full_path, f['size'], f['index'])) return files - def find_file(self, file_or_index=None): + def find_file(self, file_or_index=None, includes_name=False): best_file = None biggest_file_size = 0 for i, f in enumerate(self.torrent_files): - logger.debug('Testing file %r against %s / %r' % (file_or_index, i, f.path)) + path = f.path + if not includes_name and '/' in path: + path = '/'.join(path.split('/')[1:]) + + logger.debug('Testing file %r against %s / %r' % (file_or_index, i, path)) if file_or_index is not None: - if i == file_or_index or f.path == file_or_index: + if i == file_or_index or path == file_or_index: best_file = f break else: @@ -321,8 +321,8 @@ class Torrent(object): return best_file - def get_file(self, file_or_index=None): - f = self.find_file(file_or_index) + def get_file(self, file_or_index=None, includes_name=False): + f = self.find_file(file_or_index, includes_name) if f is None: raise UnknownFileException('Was unable to find %s' % file_or_index) @@ -365,8 +365,8 @@ class Torrent(object): self.torrent.set_file_priorities(self.file_priorities) self.blackhole_all_pieces(0, self.last_piece) - def get_torrent_file(self, file_or_index): - f = self.get_file(file_or_index) + def get_torrent_file(self, file_or_index, includes_name): + f = self.get_file(file_or_index, includes_name) f.file_requested = True self.torrent.resume() @@ -500,12 +500,12 @@ class TorrentHandler(object): self.alerts = component.get("AlertManager") self.alerts.register_handler("torrent_removed_alert", self.on_alert_torrent_removed) - def get_stream(self, infohash, file_or_index=None): - logger.info('Trying to stream infohash %s and file %s' % (infohash, file_or_index)) + def get_stream(self, infohash, file_or_index=None, includes_name=False): + logger.info('Trying to stream infohash %s and file %s include_name %s' % (infohash, file_or_index, includes_name)) if infohash not in self.torrents: self.torrents[infohash] = Torrent(self, infohash) - return self.torrents[infohash].get_torrent_file(file_or_index) + return self.torrents[infohash].get_torrent_file(file_or_index, includes_name) def on_alert_torrent_removed(self, alert): try: @@ -582,7 +582,7 @@ class Core(CorePluginBase): @export @defer.inlineCallbacks - def stream_torrent(self, infohash=None, url=None, filedump=None, filepath_or_index=None): + def stream_torrent(self, infohash=None, url=None, filedump=None, filepath_or_index=None, includes_name=False): tor = component.get("TorrentManager").torrents.get(infohash, None) if tor is None: @@ -604,7 +604,7 @@ class Core(CorePluginBase): defer.returnValue({'status': 'error', 'message': 'failed to add torrent'}) try: - tf = self.torrent_handler.get_stream(infohash, filepath_or_index) + tf = self.torrent_handler.get_stream(infohash, filepath_or_index, includes_name) except UnknownTorrentException: defer.returnValue({'status': 'error', 'message': 'unable to find torrent, probably failed to add it'}) diff --git a/streaming/data/streaming.js b/streaming/data/streaming.js index faecf38..788f5fe 100644 --- a/streaming/data/streaming.js +++ b/streaming/data/streaming.js @@ -151,7 +151,7 @@ StreamingPlugin = Ext.extend(Deluge.Plugin, { console.log('Streaming plugin loaded'); var doStream = function (tid, fileIndex) { - deluge.client.streaming.stream_torrent(tid, null, null, fileIndex, { + deluge.client.streaming.stream_torrent(tid, null, null, fileIndex, true, { success: function (result) { console.log('Got result', result); if (result.status == 'success') { diff --git a/streaming/gtkui.py b/streaming/gtkui.py index d8cce91..b40bca9 100644 --- a/streaming/gtkui.py +++ b/streaming/gtkui.py @@ -192,7 +192,7 @@ class GtkUI(GtkPluginBase): for select in selected: path = ft.get_file_path(select) - client.streaming.stream_torrent(infohash=torrent_id, filepath_or_index=path).addCallback(self.stream_ready) + client.streaming.stream_torrent(infohash=torrent_id, filepath_or_index=path, includes_name=True).addCallback(self.stream_ready) break def on_torrentmenu_menuitem_stream(self, data=None): From c85c5763d6076d1e878cb9139042ec95cb8be94c Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Sun, 22 Nov 2015 16:20:58 +0100 Subject: [PATCH 3/7] Listening to 0.0.0.0 instead of 127.0.0.1 when attempted address is not local --- streaming/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/streaming/core.py b/streaming/core.py index de58bee..63162d4 100644 --- a/streaming/core.py +++ b/streaming/core.py @@ -553,7 +553,7 @@ class Core(CorePluginBase): try: self.listening = reactor.listenTCP(self.config['port'], self.site, interface=self.config['ip']) except: - self.listening = reactor.listenTCP(self.config['port'], self.site, interface='127.0.0.1') + self.listening = reactor.listenTCP(self.config['port'], self.site, interface='0.0.0.0') @defer.inlineCallbacks def disable(self): From 6bc72dbc44032949e46da1efee8142132fefe5c9 Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Sun, 22 Nov 2015 16:21:10 +0100 Subject: [PATCH 4/7] Problem with filename encoding --- streaming/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/streaming/core.py b/streaming/core.py index 63162d4..3df7f9b 100644 --- a/streaming/core.py +++ b/streaming/core.py @@ -613,5 +613,5 @@ class Core(CorePluginBase): 'use_stream_urls': self.config['use_stream_urls'], 'auto_open_stream_urls': self.config['auto_open_stream_urls'], 'url': 'http://%s:%s/file/%s/%s' % (self.config.config['ip'], self.config.config['port'], - self.fsr.add_file(tf), urllib.quote_plus(os.path.basename(tf.path))) + self.fsr.add_file(tf), urllib.quote_plus(os.path.basename(tf.path).encode('utf-8'))) }) \ No newline at end of file From 636bd0edc233eb55f775f6cdef3524939221f0f0 Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Tue, 8 Dec 2015 19:35:41 +0100 Subject: [PATCH 5/7] fixed small bug with file releasing --- streaming/core.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/streaming/core.py b/streaming/core.py index 3df7f9b..d23ea89 100644 --- a/streaming/core.py +++ b/streaming/core.py @@ -256,7 +256,6 @@ class TorrentFile(object): # can be read from, knows about itself defer.returnValue(data) def shutdown(self): - #self.alerts.deregister_handler(self.on_alert_torrent_finished) self.do_shutdown = True class Torrent(object): @@ -271,7 +270,7 @@ class Torrent(object): self.torrent_files = None self.priority_increased = defaultdict(set) self.do_shutdown = False - self.torrent_released = False # set to True if all the files are set to download + self.torrent_released = True # set to True if all the files are set to download self.populate_files() From 0cc8ed42802c622b6451a95f8929ceb3e2db96ae Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Fri, 24 Jun 2016 20:31:21 +0200 Subject: [PATCH 6/7] improved algorithm a little, changed default to not use streaming url --- streaming/core.py | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/streaming/core.py b/streaming/core.py index d23ea89..79b5dfe 100644 --- a/streaming/core.py +++ b/streaming/core.py @@ -66,7 +66,7 @@ DEFAULT_PREFS = { 'port': 46123, 'allow_remote': False, 'reset_complete': True, - 'use_stream_urls': True, + 'use_stream_urls': False, 'auto_open_stream_urls': False, 'remote_username': 'username', 'remote_password': 'password', @@ -206,6 +206,9 @@ class TorrentFile(object): # can be read from, knows about itself def close(self, tfr): self.current_readers.remove(tfr) self.torrent.unprioritize_pieces(tfr) + + if not self.current_readers: + self.torrent.unprioritize_pieces(self) def is_complete(self): torrent_status = self.torrent.torrent.get_status(['file_progress', 'state']) @@ -239,7 +242,7 @@ class TorrentFile(object): # can be read from, knows about itself self.waiting_pieces[piece] = defer.Deferred() logger.debug('Waiting for %s' % piece) - self.torrent.schedule_piece(self, piece, 0) + self.torrent.schedule_piece(self, self, piece, 0) while not self.torrent.torrent.handle.have_piece(piece): if self.do_shutdown: raise Exception() @@ -281,6 +284,13 @@ class Torrent(object): reactor.callLater(0, self.update_piece_priority) reactor.callLater(0, self.blackhole_all_pieces, 0, self.last_piece) + def is_unstreamed(self): # check if anyone streams this file + for tf in self.torrent_files: + if tf.current_readers: + return True + + return False + def populate_files(self): self.torrent_files = [] @@ -329,6 +339,11 @@ class Torrent(object): def unprioritize_pieces(self, tfr): logger.debug('Unprioritizing pieces for %s' % tfr) + + if self.torrent_handler.config['reset_complete'] and self.is_unstreamed(): + logger.debug('Not unprioritizing pieces because there are no streams and it would stop the file (causes problems)') + return + currently_downloading = self.get_currently_downloading() for piece, increased_by in self.priority_increased.items(): @@ -354,7 +369,7 @@ class Torrent(object): if piece not in currently_downloading and not self.torrent.status.pieces[piece]: if piece in self.priority_increased: continue - logger.debug('Setting piece priority %s to blacklist' % piece) + #logger.debug('Setting piece priority %s to blacklist' % piece) self.torrent.handle.piece_priority(piece, 0) def unrelease(self): @@ -390,19 +405,16 @@ class Torrent(object): for tf in self.torrent_files: tf.shutdown() - def schedule_piece(self, torrent_file, piece, distance): - if torrent_file not in self.priority_increased[piece]: + def schedule_piece(self, torrent_file, schedule_target, piece, distance): + if schedule_target not in self.priority_increased[piece]: if not self.priority_increased[piece]: - self.priority_increased[piece].add(torrent_file) - logger.debug('Scheduled piece %s at distance %s' % (piece, distance)) self.torrent.handle.piece_priority(piece, (7 if distance <= 4 else 6)) self.torrent.handle.set_piece_deadline(piece, 700*(distance+1)) - - self.priority_increased[piece].add(torrent_file) + self.priority_increased[piece].add(schedule_target) - def do_pieces_schedule(self, torrent_file, currently_downloading, from_piece): + def do_pieces_schedule(self, torrent_file, schedule_target, currently_downloading, from_piece): logger.debug('Looking for stuff to do with pieces for file %s from piece %s' % (torrent_file, from_piece)) priority_increased = 0 @@ -433,7 +445,7 @@ class Torrent(object): logger.debug('Done increasing priority for %i pieces' % status_increase) break - self.schedule_piece(torrent_file, piece, piece-from_piece) + self.schedule_piece(torrent_file, schedule_target, piece, piece-from_piece) else: logger.info('We are done with the rest of this chain, we might be able to increase others') return True @@ -459,18 +471,18 @@ class Torrent(object): logger.debug('Rescheduling file %s' % f.path) if f.file_requested: - all_heads_done &= self.do_pieces_schedule(f, currently_downloading, f.first_piece) - self.schedule_piece(f, f.last_piece, 0) + all_heads_done &= self.do_pieces_schedule(f, f, currently_downloading, f.first_piece) + self.schedule_piece(f, f, f.last_piece, 0) if f.first_piece != f.last_piece: - self.schedule_piece(f, f.last_piece-1, 1) + self.schedule_piece(f, f, f.last_piece-1, 1) for tfr in f.current_readers: if tfr.waiting_for_piece is not None: logger.debug('Scheduling based on waiting for piece %s' % tfr.waiting_for_piece) - all_heads_done &= self.do_pieces_schedule(f, currently_downloading, tfr.waiting_for_piece) + all_heads_done &= self.do_pieces_schedule(f, tfr, currently_downloading, tfr.waiting_for_piece) elif tfr.current_piece is not None: logger.debug('Scheduling based on current piece %s' % tfr.current_piece) - all_heads_done &= self.do_pieces_schedule(f, currently_downloading, tfr.current_piece) + all_heads_done &= self.do_pieces_schedule(f, tfr, currently_downloading, tfr.current_piece) if all(self.torrent.status.pieces): logger.debug('All pieces complete, no need to loop') From 6b2817ce5e5a09ab4b95cdc254de004eaefd2395 Mon Sep 17 00:00:00 2001 From: JohnDoee Date: Fri, 24 Jun 2016 20:42:39 +0200 Subject: [PATCH 7/7] bumped version and updated changelog --- README.md | 5 +++++ setup.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 651efbf..dccb872 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,11 @@ The _allow remote_ option is to allow remote add and stream of torrents. # Version Info +## Version 0.6.0 +* Fixed URL encoding error +* Fixed "resume on complete" broken-ness (i hope) +* Changed default to not use stream urls + ## Version 0.5.0 * Restructured the whole plugin * Added support for StreamProtocol diff --git a/setup.py b/setup.py index 7a9c72a..57a9cb9 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ from setuptools import setup __plugin_name__ = "Streaming" __author__ = "John Doee" __author_email__ = "johndoee@tidalstream.org" -__version__ = "0.5.0" +__version__ = "0.6.0" __url__ = "https://github.com/JohnDoee/deluge-streaming" __license__ = "GPLv3" __description__ = "Enables streaming of files while downloading them."