diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 04efc65..f68d626 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,13 +2,15 @@ + + - + @@ -42,7 +44,7 @@ - + @@ -53,21 +55,37 @@ - - + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -76,36 +94,25 @@ - - + + - - - - - - - - - - - @@ -116,7 +123,7 @@ - + @@ -125,8 +132,8 @@ - - + + @@ -141,10 +148,9 @@ - - + + - @@ -154,18 +160,14 @@ - - - - - - - - - - - - + + + + + + + + @@ -174,8 +176,8 @@ - - + + @@ -190,13 +192,11 @@ - - @@ -229,66 +229,53 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + @@ -354,18 +341,18 @@ @@ -401,8 +388,6 @@ - - @@ -474,9 +459,55 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -658,12 +689,6 @@ - + + - + @@ -976,7 +1008,6 @@ - @@ -993,7 +1024,6 @@ - @@ -1018,7 +1048,8 @@ - @@ -1230,14 +1261,6 @@ - - - - - - - - @@ -1264,13 +1287,6 @@ - - - - - - - @@ -1292,14 +1308,6 @@ - - - - - - - - @@ -1315,75 +1323,77 @@ - + - - - - - - - - - - - - + + - + - - - - - + + - + - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -1398,104 +1408,58 @@ - - - + - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - @@ -1505,39 +1469,93 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Anteoloader.py b/Anteoloader.py index aaf8761..5f73c4f 100644 --- a/Anteoloader.py +++ b/Anteoloader.py @@ -81,6 +81,11 @@ ENCRYPTION_SETTINGS = { "Disabled": 2, } +class Encryption: + FORCED = 0 + ENABLED = 1 + DISABLED = 2 + class AnteoLoader: magnetLink = None engine = None @@ -97,10 +102,12 @@ class AnteoLoader: sys.exit(1) #pre settings - if xbmcvfs.exists(torrentFile): + if os.path.exists(torrentFile): self.torrentFile = "file:///"+torrentFile.replace('\\','//').replace('////','//') elif re.match("^magnet\:.+$", torrentFile): self.magnetLink = torrentFile + else: + self.torrentFile = torrentFile def __exit__(self): log('on __exit__') @@ -134,17 +141,15 @@ class AnteoLoader: return filelist def saveTorrent(self, torrentUrl): - if not xbmcvfs.exists(torrentUrl): + if not xbmcvfs.exists(torrentUrl) or re.match("^http.+$", torrentUrl): if re.match("^magnet\:.+$", torrentUrl): self.magnetLink = torrentUrl self.magnetToTorrent(torrentUrl) self.magnetLink = None return self.torrentFile else: - if not xbmcvfs.exists(self.torrentFilesPath): - xbmcvfs.mkdirs(self.torrentFilesPath) - torrentFile = self.torrentFilesPath + self.md5( - torrentUrl) + '.torrent' + if not xbmcvfs.exists(self.torrentFilesPath): xbmcvfs.mkdirs(self.torrentFilesPath) + torrentFile = self.torrentFilesPath + self.md5(torrentUrl) + '.torrent' try: if not re.match("^http\:.+$", torrentUrl): content = xbmcvfs.File(torrentUrl, "rb").read() @@ -169,6 +174,10 @@ class AnteoLoader: return else: torrentFile = torrentUrl + if xbmcvfs.exists(torrentFile) and not os.path.exists(torrentFile): + if not xbmcvfs.exists(self.torrentFilesPath): xbmcvfs.mkdirs(self.torrentFilesPath) + torrentFile = self.torrentFilesPath + self.md5(torrentUrl) + '.torrent' + xbmcvfs.copy(torrentUrl, torrentFile) if xbmcvfs.exists(torrentFile): self.torrentFile = "file:///"+torrentFile.replace('\\','//').replace('////','//') return self.torrentFile @@ -203,26 +212,44 @@ class AnteoPlayer(xbmc.Player): self.userStorageDirectory = userStorageDirectory self.torrentUrl = torrentUrl xbmc.Player.__init__(self) - log("[TorrentPlayer] Initalized") + log("[AnteoPlayer] Initalized") self.params = params self.get = self.params.get self.contentId = int(self.get("url")) - self.torrent = AnteoLoader(self.userStorageDirectory, self.torrentUrl, self.torrentFilesDirectory) - try: - if self.get("url2"): - self.ids_video = urllib.unquote_plus(self.get("url2")).split(',') - else: - self.ids_video = self.get_ids() - except: - pass + #self.torrent = AnteoLoader(self.userStorageDirectory, self.torrentUrl, self.torrentFilesDirectory) self.init() self.setup_engine() with closing(self.engine): self.engine.start(self.contentId) - ready = self.buffer() - if ready: - self.stream() + self.setup_nextep() + while True: + if self.buffer(): + log('[AnteoPlayer]: ************************************* GOING LOOP') + if self.setup_play(): + self.loop() + else: + log('[AnteoPlayer]: ************************************* break') + break + log('[AnteoPlayer]: ************************************* GO NEXT?') + if self.next_dl and isinstance(self.next_contentId, int) and self.iterator == 100: + self.contentId = self.next_contentId + continue + log('[AnteoPlayer]: ************************************* NO! break') + break + xbmc.Player().stop() + + if '1' != self.__settings__.getSetting("keep_files") and 'Saved Files' not in self.userStorageDirectory: + xbmc.sleep(1000) + clearStorage(self.userStorageDirectory) + else: + if self.seeding_status: + showMessage(self.localize('Information'), + self.localize('Torrent is seeding. To stop it use Download Status.'), forced=True) + else: + if self.seeding: self.db_delete() + showMessage(self.localize('Information'), + self.localize('Torrent downloading is stopped.'), forced=True) def __exit__(self): log('on __exit__') @@ -231,8 +258,6 @@ class AnteoPlayer(xbmc.Player): log('__exit__ worked!') def init(self): - self.next_dl = True if self.__settings__.getSetting('next_dl') == 'true' and self.ids_video else False - log('[AnteoPlayer]: init - ' + str(self.next_dl)) self.next_contentId = False self.display_name = '' self.downloadedSize = 0 @@ -245,16 +270,43 @@ class AnteoPlayer(xbmc.Player): self.torrentUrl = "file:///"+str(self.torrentUrl).replace('\\','//').replace('////','//') def setup_engine(self): - encryption = True if self.__settings__.getSetting('encryption') == 'true' else False + #uri=None, binaries_path=None, platform=None, download_path=".", + #bind_host='127.0.0.1', bind_port=5001, connections_limit=None, download_kbps=None, upload_kbps=None, + #enable_dht=True, enable_lsd=True, enable_natpmp=True, enable_upnp=True, enable_scrape=False, + #log_stats=False, encryption=Encryption.ENABLED, keep_complete=False, keep_incomplete=False, + #keep_files=False, log_files_progress=False, log_overall_progress=False, log_pieces_progress=False, + #listen_port=6881, use_random_port=False, max_idle_timeout=None, no_sparse=False, resume_file=None, + #user_agent=None, startup_timeout=5, state_file=None, enable_utp=True, enable_tcp=True, + #debug_alerts=False, logger=None, torrent_connect_boost=50, connection_speed=50, + #peer_connect_timeout=15, request_timeout=20, min_reconnect_time=60, max_failcount=3, + #dht_routers=None, trackers=None) - upload_limit = self.__settings__.getSetting("upload_limit") if self.__settings__.getSetting( + encryption = Encryption.ENABLED if self.__settings__.getSetting('encryption') == 'true' else Encryption.DISABLED + upload_limit = int(self.__settings__.getSetting("upload_limit"))*1024 if self.__settings__.getSetting( "upload_limit") != "" else 0 - download_limit = self.__settings__.getSetting("download_limit") if self.__settings__.getSetting( + download_limit = int(self.__settings__.getSetting("download_limit"))*1024 if self.__settings__.getSetting( "download_limit") != "" else 0 - self.pre_buffer_bytes = 15*1024*1024 - self.engine = Engine(uri=self.torrentUrl) + + if self.__settings__.getSetting("connections_limit") not in ["",0,"0"]: + connections_limit = int(self.__settings__.getSetting("connections_limit")) + else: + connections_limit = None + + if '1' != self.__settings__.getSetting("keep_files") and 'Saved Files' not in self.userStorageDirectory: + keep_complete = False + keep_incomplete = False + else: + keep_complete = True + keep_incomplete = True + + dht_routers = ["router.bittorrent.com:6881","router.utorrent.com:6881"] + self.engine = Engine(uri=self.torrentUrl, download_path=self.userStorageDirectory, + connections_limit=connections_limit, download_kbps=download_limit, upload_kbps=upload_limit, + encryption=encryption, keep_complete=keep_complete, keep_incomplete=keep_incomplete, + dht_routers=dht_routers) def buffer(self): + self.pre_buffer_bytes = 30*1024*1024 #30 MB ready = False progressBar = xbmcgui.DialogProgress() progressBar.create(self.localize('Please Wait'), @@ -265,22 +317,14 @@ class AnteoPlayer(xbmc.Player): # for ind, title in subs: # self.torrent.continueSession(ind) - #FileStatus = namedtuple('FileStatus', "name, save_path, url, size, offset, download, progress, index, media_type") - - #SessionStatus = namedtuple('SessionStatus', "name, state, state_str, error, progress, download_rate, upload_rate, " - # "total_download, total_upload, num_peers, num_seeds, total_seeds, " - # "total_peers") - while not xbmc.abortRequested and not ready: xbmc.sleep(500) status = self.engine.status() + self.print_debug(status) self.engine.check_torrent_error(status) file_status = self.engine.file_status(self.contentId) if not file_status: continue - log('[buffer] file_status:'+str(file_status)) - log('[buffer] status:'+str(status)) - #self.torrent.debug() fullSize = file_status.size / 1024 / 1024 downloadedSize = status.total_download / 1024 / 1024 getDownloadRate = status.download_rate / 1024 * 8 @@ -320,19 +364,227 @@ class AnteoPlayer(xbmc.Player): progressBar.close() return ready - def stream(self): + def setup_nextep(self): + try: + if self.get("url2"): + debug("url2") + self.ids_video = urllib.unquote_plus(self.get("url2")).split(',') + else: + debug("not url2") + self.ids_video = self.get_ids() + except: + pass + + if self.__settings__.getSetting('next_dl') == 'true' and self.ids_video: + self.next_dl = True + else: + self.next_dl = False + log('[AnteoPlayer]: nextdl - %s, ids_video - %s' % (str(self.next_dl), str(self.ids_video))) + + def setup_play(self): file_status = self.engine.file_status(self.contentId) - listitem = xbmcgui.ListItem('xxxx') - playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) - playlist.clear() - playlist.add(file_status.url, listitem) - xbmc.Player().play(playlist) - while not xbmc.abortRequested and xbmc.Player().isPlaying(): - xbmc.sleep(500) - xbmc.Player().stop() + self.iterator = 0 + url = file_status.url + label = os.path.basename(file_status.name) + self.basename = label + self.seeding_run = False + subtitles = None + listitem = xbmcgui.ListItem(label, path=url) + + if self.next_dl: + next_contentId_index = self.ids_video.index(str(self.contentId)) + 1 + if len(self.ids_video) > next_contentId_index: + self.next_contentId = int(self.ids_video[next_contentId_index]) + else: + self.next_contentId = False + log('[AnteoPlayer][setup_play]: next_contentId: '+str(self.next_contentId)) + + if self.subs_dl: + sub_files = self.engine.list(media_types=[MediaType.SUBTITLES]) + if sub_files: + log("[AnteoPlayer][setup_play]: Detected subtitles: %s" % str(sub_files[0])) + subtitles = sub_files[0] + try: + seasonId = self.get("seasonId") + self.episodeId = self.get("episodeId") if not self.episodeId else int(self.episodeId) + 1 + title = urllib.unquote_plus(self.get("title")) if self.get("title") else None + + if self.get("label") and self.episodeId == self.get("episodeId"): + label = urllib.unquote_plus(self.get("label")) + elif seasonId and self.episodeId and title: + label = '%s S%02dE%02d.%s (%s)' % ( + title, int(seasonId), int(self.episodeId), self.basename.split('.')[-1], self.basename) + + if seasonId and self.episodeId and label and title: + listitem = xbmcgui.ListItem(label, path=url) + + listitem.setInfo(type='video', infoLabels={'title': label, + 'episode': int(self.episodeId), + 'season': int(seasonId), + 'tvshowtitle': title}) + except: + log('[AnteoPlayer]: Operation INFO failed!') + + thumbnail = self.get("thumbnail") + if thumbnail: + listitem.setThumbnailImage(urllib.unquote_plus(thumbnail)) + self.display_name = label + + player = xbmc.Player() + player.play(url, listitem) + xbmc.sleep(1000) + if subtitles: + player.setSubtitles(subtitles.url) + + xbmc.sleep(2000) # very important, do not edit this, podavan + return True + + def loop(self): + debug_counter=0 + xbmc.sleep(1000) + + with closing( + OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay: + with nested(self.attach(overlay.show, self.on_playback_paused), + self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)): + while not xbmc.abortRequested and self.isPlaying(): + #self.print_fulldebug() + status = self.engine.status() + file_status = self.engine.file_status(self.contentId) + if self.iterator == 100 and debug_counter < 100: + debug_counter += 1 + else: + self.print_debug(status) + debug_counter=0 + + overlay.text = "\n".join(self._get_status_lines(status, file_status)) + + self.iterator = int(file_status.progress * 100) + xbmc.sleep(1000) + + #if not self.seeding_run and self.iterator == 100 and self.seeding: + #self.seeding_run = True + #self.seed(self.contentId) + #self.seeding_status = True + # xbmc.sleep(7000) + + def onPlayBackStarted(self): + for f in self.on_playback_started: + f() + log('[onPlayBackStarted]: '+(str(("video", "play", self.display_name)))) + + def onPlayBackResumed(self): + for f in self.on_playback_resumed: + f() + self.onPlayBackStarted() + + def onPlayBackPaused(self): + for f in self.on_playback_paused: + f() + log('[onPlayBackPaused]: '+(str(("video", "pause", self.display_name)))) + + def onPlayBackStopped(self): + for f in self.on_playback_stopped: + f() + log('[onPlayBackStopped]: '+(str(("video", "stop", self.display_name)))) + + @contextmanager + def attach(self, callback, *events): + for event in events: + event.append(callback) + yield + for event in events: + event.remove(callback) + + def _get_status_lines(self, s, f): + return [ + self.display_name, + "%.2f%% %s" % (f.progress * 100, self.localize(STATE_STRS[s.state]).decode('utf-8')), + "D:%.2f%s U:%.2f%s S:%d P:%d" % (s.download_rate * 8, self.localize('kb/s').decode('utf-8'), + s.upload_rate * 8, self.localize('kb/s').decode('utf-8'), + s.num_seeds, s.num_peers) + ] def localize(self, string): try: return Localization.localize(string) except: - return string \ No newline at end of file + return string + + def print_debug(self, status=None): + #FileStatus = namedtuple('FileStatus', "name, save_path, url, size, offset, download, progress, index, media_type") + + #SessionStatus = namedtuple('SessionStatus', "name, state, state_str, error, progress, download_rate, upload_rate, " + # "total_download, total_upload, num_peers, num_seeds, total_seeds, " + # "total_peers") + + #log('[buffer] file_status:'+str(file_status)) + #log('[buffer] status:'+str(status)) + if not status: + status = self.engine.status() + self.engine.check_torrent_error(status) + log('[AnteoPlayer]: %.2f%% complete (down: %.1f kb/s up: %.1f kb/s peers: %d) %s' % \ + (status.progress * 100, status.download_rate * 8, + status.upload_rate * 8, status.num_peers, status.state_str)) + + def print_fulldebug(self): + status = self.engine.status() + file_status = self.engine.file_status(self.contentId) + log('[buffer] file_status:'+str(file_status)) + log('[buffer] status:'+str(status)) + + def get_ids(self): + contentList = [] + for fs in self.engine.list(): + contentList.append((fs.name, str(fs.index))) + contentList = sorted(contentList, key=lambda x: x[0]) + return get_ids_video(contentList) + +class OverlayText(object): + def __init__(self, w, h, *args, **kwargs): + self.window = xbmcgui.Window(WINDOW_FULLSCREEN_VIDEO) + viewport_w, viewport_h = self._get_skin_resolution() + # Adjust size based on viewport, we are using 1080p coordinates + w = int(w * viewport_w / VIEWPORT_WIDTH) + h = int(h * viewport_h / VIEWPORT_HEIGHT) + x = (viewport_w - w) / 2 + y = (viewport_h - h) / 2 + self._shown = False + self._text = "" + self._label = xbmcgui.ControlLabel(x, y, w, h, self._text, *args, **kwargs) + self._background = xbmcgui.ControlImage(x, y, w, h, os.path.join(RESOURCES_PATH, "images", "black.png")) + self._background.setColorDiffuse("0xD0000000") + + def show(self): + if not self._shown: + self.window.addControls([self._background, self._label]) + self._shown = True + self._background.setColorDiffuse("0xD0000000") + + def hide(self): + if self._shown: + self._shown = False + self.window.removeControls([self._background, self._label]) + self._background.setColorDiffuse("0xFF000000") + + def close(self): + self.hide() + + @property + def text(self): + return self._text + + @text.setter + def text(self, text): + self._text = text + if self._shown: + self._label.setLabel(self._text) + + # This is so hackish it hurts. + def _get_skin_resolution(self): + import xml.etree.ElementTree as ET + + skin_path = xbmc.translatePath("special://skin/") + tree = ET.parse(os.path.join(skin_path, "addon.xml")) + res = tree.findall("./extension/res")[0] + return int(res.attrib["width"]), int(res.attrib["height"]) \ No newline at end of file diff --git a/BTClientPlayer.py b/BTClientPlayer.py deleted file mode 100644 index 631bfc4..0000000 --- a/BTClientPlayer.py +++ /dev/null @@ -1,479 +0,0 @@ -# -*- coding: utf-8 -*- -''' - Torrenter v2 plugin for XBMC/Kodi - Copyright (C) 2012-2015 Vadim Skorba v1 - DiMartino v2 - http://forum.kodi.tv/showthread.php?tid=214366 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -''' - -import os -import urllib -import json -import sys -from contextlib import contextmanager, closing, nested - -import xbmc -import xbmcgui -import Downloader -import xbmcgui -import xbmcvfs -import Localization -from platform_pulsar import get_platform -import traceback -from btclient import * -from functions import calculate, showMessage, clearStorage, DownloadDB, get_ids_video, log, debug, is_writable -from argparse import Namespace -from Player import OverlayText -from Libtorrent import Libtorrent - - - -ROOT = sys.modules["__main__"].__root__ -RESOURCES_PATH = os.path.join(ROOT, 'resources') -TORRENT2HTTP_TIMEOUT = 20 -TORRENT2HTTP_POLL = 1000 -PLAYING_EVENT_INTERVAL = 60 -MIN_COMPLETED_PIECES = 0.5 - -WINDOW_FULLSCREEN_VIDEO = 12005 - -XBFONT_LEFT = 0x00000000 -XBFONT_RIGHT = 0x00000001 -XBFONT_CENTER_X = 0x00000002 -XBFONT_CENTER_Y = 0x00000004 -XBFONT_TRUNCATED = 0x00000008 -XBFONT_JUSTIFY = 0x00000010 - -STATE_STRS = [ - 'Queued', - 'Checking', - 'Downloading metadata', - 'Downloading', - 'Finished', - 'Seeding', - 'Allocating', - 'Allocating file & Checking resume' -] - -VIEWPORT_WIDTH = 1920.0 -VIEWPORT_HEIGHT = 1088.0 -OVERLAY_WIDTH = int(VIEWPORT_WIDTH * 0.7) # 70% size -OVERLAY_HEIGHT = 150 - -ENCRYPTION_SETTINGS = { - "Forced": 0, - "Enabled": 1, - "Disabled": 2, -} - -class BTClientPlayer(xbmc.Player): - __plugin__ = sys.modules["__main__"].__plugin__ - __settings__ = sys.modules["__main__"].__settings__ - ROOT = sys.modules["__main__"].__root__ # .decode('utf-8').encode(sys.getfilesystemencoding()) - USERAGENT = "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" - torrentFilesDirectory = 'torrents' - debug = __settings__.getSetting('debug') == 'true' - subs_dl = __settings__.getSetting('subs_dl') == 'true' - seeding = __settings__.getSetting('keep_seeding') == 'true' and __settings__.getSetting('keep_files') == '1' - seeding_status = False - seeding_run = False - ids_video = None - episodeId = None - basename = '' - - def __init__(self, userStorageDirectory, torrentUrl, params={}): - self.userStorageDirectory = userStorageDirectory - self.torrentUrl = torrentUrl - xbmc.Player.__init__(self) - log("[BTClientPlayer] Initalized") - self.params = params - self.get = self.params.get - self.contentId = int(self.get("url")) - self.platform = get_platform() - self.init() - - self.torrent = Downloader.Torrent(self.userStorageDirectory, self.torrentUrl, self.torrentFilesDirectory).player - self.lt=self.torrent.lt - try: - if self.get("url2"): - self.ids_video = urllib.unquote_plus(self.get("url2")).split(',') - else: - self.ids_video = self.get_ids() - except: - pass - - args=Namespace(bt_download_limit=self.download_limit,#KB - bt_upload_limit=self.upload_limit, - choose_subtitles=False, - clear_older=0, - debug_log='',#os.path.join(self.userStorageDirectory, 'log.txt'), - delete_on_finish=False, - directory=self.userStorageDirectory, - listen_port_max=6891,# - listen_port_min=6881, - no_resume=False, - player='kodi', - port=5001, - print_pieces=False, - quiet=False, - stdin=False, - stream=True, - subtitles=None, - trace=False, - content_id=self.contentId, - url=self.torrentUrl) - args=main(args) #config - self.free_port = args.port - log('BTClientPlayer: args '+str(args)) - - self.btclient=self.stream(args, BTClient) - - #self.init() - #self.setup_torrent() - #if self.buffer(): - # while True: - # if self.setup_play(): - # debug('************************************* GOING LOOP') - # #self.torrent.continueSession(self.contentId) - # self.loop() - # else: - # break - # debug('************************************* GO NEXT?') - # if self.next_dl and self.next_dling and isinstance(self.next_contentId, int) and self.iterator == 100: - # self.contentId = self.next_contentId - # continue - # debug('************************************* NO! break') - # break - #self.torrent.stopSession() - #self.torrent.threadComplete = True - #self.torrent.checkThread() - - #if '1' != self.__settings__.getSetting("keep_files") and 'Saved Files' not in self.userStorageDirectory: - # xbmc.sleep(1000) - # clearStorage(self.userStorageDirectory) - #else: - # if self.seeding_status: - # showMessage(self.localize('Information'), - # self.localize('Torrent is seeding. To stop it use Download Status.'), forced=True) - # else: - # if self.seeding: self.db_delete() - # showMessage(self.localize('Information'), - # self.localize('Torrent downloading is stopped.'), forced=True) - - def on_exit(self): - self.c.close() - sys.exit(0) - - def stream(self, args, client_class): - self.c = client_class(args.directory, args=args, lt=self.lt) - try: - while True: - try: - s = socket.socket() - res = s.connect_ex(('127.0.0.1', self.free_port)) - if res: - break - finally: - s.close() - self.free_port += 1 - - self.server = StreamServer(('127.0.0.1', self.free_port), BTFileHandler, allow_range=True, - status_fn=self.c.get_normalized_status) - log('Started http server on port %d' % self.free_port) - self.server.run() - - log('Starting btclient - libtorrent version %s' % self.lt.version) - self.c.start_url(args.url) - - if self.buffer(): - f = self.c._file - self.server.set_file(f) - self.setup_play() - - with closing( - OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay: - with nested(self.attach(overlay.show, self.on_playback_paused), - self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)): - while True: - if xbmc.abortRequested or not self.isPlaying(): - break - - status = self.c.status - overlay.text = "\n".join(self._get_status_lines(status)) - xbmc.sleep(1000) - - log('Play ended') - if self.server: - self.server.stop() - except Exception: - traceback.print_exc() - finally: - self.on_exit() - - def init(self): - self.next_dl = True if self.__settings__.getSetting('next_dl') == 'true' and self.ids_video else False - log('[BTClientPlayer]: init next_dl - ' + str(self.next_dl)) - self.next_contentId = False - self.display_name = '' - self.downloadedSize = 0 - self.dialog = xbmcgui.Dialog() - self.on_playback_started = [] - self.on_playback_resumed = [] - self.on_playback_paused = [] - self.on_playback_stopped = [] - self.fullSize = 0 - if self.__settings__.getSetting("upload_limit") == "": - self.upload_limit = 0.0 - else: - self.upload_limit = float(self.__settings__.getSetting("upload_limit")) / 8 * 1024 - if self.__settings__.getSetting("download_limit") == "": - self.download_limit = 0.0 - else: - self.download_limit = float(self.__settings__.getSetting("download_limit")) / 8 * 1024 - - def setup_torrent(self): - pass - #if self.__settings__.getSetting('encryption') == 'true': - # self.torrent.encryptSession() - #self.torrent.startSession() - - - #if self.subs_dl: - # subs = self.torrent.getSubsIds(os.path.basename(self.torrent.getFilePath(self.contentId))) - # if len(subs) > 0: - # for ind, title in subs: - # self.torrent.continueSession(ind) - - def buffer(self): - #iterator = 0 - progressBar = xbmcgui.DialogProgress() - progressBar.create(self.localize('Please Wait') + str(' [%s]' % str(self.lt.version)), - self.localize('Seeds searching.')) - while not self.c.is_file_ready: #iterator < 100:#or not self.torrent.is_playble() - status = self.c.get_normalized_status() - iterator = int(status['progress'] * 10000) - if iterator > 99: iterator = 99 - if status['state'] in ['queued','checking','checking fastresume'] or (status['progress'] == 0 and status['num_pieces'] > 0): - progressBar.update(iterator, self.localize('Checking preloaded files...'), ' ', ' ') - elif status['state'] == 'downloading': - dialogText = self.localize('Preloaded: ') + str(status['downloaded'] / 1024 / 1024) + ' MB / ' + str( - status['total_size'] / 1024 / 1024) + ' MB' - peersText = ' [%s: %s; %s: %s]' % ( - self.localize('Seeds'), str(status['seeds_connected']), self.localize('Peers'), - str(status['peers_connected']),) - speedsText = '%s: %s Mbit/s; %s: %s Mbit/s' % ( - self.localize('Downloading'), str(status['download_rate'] * 8 / 1000000), - self.localize('Uploading'), str(status['upload_rate'] * 8 / 1000000)) - #if self.debug: - # peersText=peersText + ' ' + self.torrent.get_debug_info('dht_state') - # dialogText=dialogText.replace(self.localize('Preloaded: '),'') + ' ' + self.torrent.get_debug_info('trackers_sum') - progressBar.update(iterator, self.localize('Seeds searching.') + peersText, dialogText, - speedsText) - else: - progressBar.update(iterator, self.localize('UNKNOWN STATUS'), ' ', ' ') - if progressBar.iscanceled(): - self.c.close() - break - xbmc.sleep(1000) - progressBar.update(0) - progressBar.close() - return True - - def setup_subs(self, label, path): - iterator = 0 - subs = self.torrent.getSubsIds(label) - debug('[setup_subs] subs: '+str(subs)) - if len(subs) > 0: - showMessage(self.localize('Information'), - self.localize('Downloading and copy subtitles. Please wait.'), forced=True) - for ind, title in subs: - self.torrent.continueSession(ind) - while iterator < 100: - xbmc.sleep(1000) - self.torrent.debug() - status = self.torrent.torrentHandle.status() - iterator = int(status.progress * 100) - # xbmc.sleep(2000) - for ind, title in subs: - folder = title.split(os.sep)[0] - temp = os.path.basename(title) - addition = os.path.dirname(title).lstrip(folder + os.sep).replace(os.sep, '.').replace(' ', '_').strip() - ext = temp.split('.')[-1] - temp = temp[:len(temp) - len(ext) - 1] + '.' + addition + '.' + ext - newFileName = os.path.join(os.path.dirname(path), temp) - debug('[setup_subs]: '+str((os.path.join(os.path.dirname(os.path.dirname(path)),title),newFileName))) - if not xbmcvfs.exists(newFileName): - xbmcvfs.copy(os.path.join(os.path.dirname(os.path.dirname(path)), title), newFileName) - - def setup_play(self): - #self.next_dling = False - #self.iterator = 0 - path = os.path.join(self.userStorageDirectory, self.c._file.path) - label = os.path.basename(self.c._file.path) - self.basename = label - #self.seeding_run = False - listitem = xbmcgui.ListItem(label) - - #if self.subs_dl: - # self.setup_subs(label, path) - try: - seasonId = self.get("seasonId") - self.episodeId = self.get("episodeId") if not self.episodeId else int(self.episodeId) + 1 - title = urllib.unquote_plus(self.get("title")) if self.get("title") else None - - if self.get("label") and self.episodeId == self.get("episodeId"): - label = urllib.unquote_plus(self.get("label")) - elif seasonId and self.episodeId and title: - label = '%s S%02dE%02d.%s (%s)' % ( - title, int(seasonId), int(self.episodeId), self.basename.split('.')[-1], self.basename) - - if seasonId and self.episodeId and label and title: - listitem = xbmcgui.ListItem(label) - - listitem.setInfo(type='video', infoLabels={'title': label, - 'episode': int(self.episodeId), - 'season': int(seasonId), - 'tvshowtitle': title}) - except: - log('[BTClientPlayer] Operation INFO failed!') - - thumbnail = self.get("thumbnail") - if thumbnail: - listitem.setThumbnailImage(urllib.unquote_plus(thumbnail)) - self.display_name = label - - base = 'http://127.0.0.1:' + str(self.free_port) + '/' - url = urlparse.urljoin(base, urllib.quote(self.c._file.path)) - # мегакостыль! - rpc = ({'jsonrpc': '2.0', 'method': 'Files.GetDirectory', 'params': { - 'media': 'video', 'directory': path}, 'id': 0}) - data = json.dumps(rpc) - request = xbmc.executeJSONRPC(data) - response = json.loads(request) - while not response: - xbmc.sleep(100) - if response: - playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) - playlist.clear() - playlist.add(url, listitem) - xbmc.Player().play(playlist) - print "\nServing file on %s" % url - return True - - def onPlayBackStarted(self): - for f in self.on_playback_started: - f() - log('[onPlayBackStarted]: '+(str(("video", "play", self.display_name)))) - - def onPlayBackResumed(self): - for f in self.on_playback_resumed: - f() - self.onPlayBackStarted() - - def onPlayBackPaused(self): - for f in self.on_playback_paused: - f() - log('[onPlayBackPaused]: '+(str(("video", "pause", self.display_name)))) - - def onPlayBackStopped(self): - for f in self.on_playback_stopped: - f() - log('[onPlayBackStopped]: '+(str(("video", "stop", self.display_name)))) - - @contextmanager - def attach(self, callback, *events): - for event in events: - event.append(callback) - yield - for event in events: - event.remove(callback) - - def loop(self): - debug_counter=0 - with closing( - OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay: - with nested(self.attach(overlay.show, self.on_playback_paused), - self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)): - while not xbmc.abortRequested and self.isPlaying() and not self.torrent.threadComplete: - self.torrent.checkThread() - if self.iterator == 100 and debug_counter < 100: - debug_counter += 1 - else: - self.torrent.debug() - debug_counter=0 - status = self.torrent.torrentHandle.status() - overlay.text = "\n".join(self._get_status_lines(status)) - # downloadedSize = torrent.torrentHandle.file_progress()[contentId] - self.iterator = int(status.progress * 100) - xbmc.sleep(1000) - if self.iterator == 100 and self.next_dl: - next_contentId_index = self.ids_video.index(str(self.contentId)) + 1 - if len(self.ids_video) > next_contentId_index: - self.next_contentId = int(self.ids_video[next_contentId_index]) - else: - self.next_contentId = False - debug('[loop] next_contentId: '+str(self.next_contentId)) - if not self.seeding_run and self.iterator == 100 and self.seeding: - self.seeding_run = True - self.seed(self.contentId) - self.seeding_status = True - # xbmc.sleep(7000) - if self.iterator == 100 and self.next_dl and not self.next_dling and isinstance(self.next_contentId, - int) and self.next_contentId != False: - showMessage(self.localize('Torrent Downloading'), - self.localize('Starting download next episode!'), forced=True) - self.torrent.stopSession() - # xbmc.sleep(1000) - path = self.torrent.getFilePath(self.next_contentId) - self.basename = self.display_name = os.path.basename(path) - self.torrent.continueSession(self.next_contentId) - self.next_dling = True - - def _get_status_lines(self, s): - return [ - self.display_name.decode('utf-8'), - "%.2f%% %s" % (s.progress * 100, self.localize(STATE_STRS[s.state]).decode('utf-8')), - "D:%.2f%s U:%.2f%s S:%d P:%d" % (s.download_rate / 1024, self.localize('kb/s').decode('utf-8'), - s.upload_rate / 1024, self.localize('kb/s').decode('utf-8'), - s.num_seeds, s.num_peers) - ] - - def db_delete(self): - if self.basename: - db = DownloadDB() - get = db.get(self.basename) - if get: - db.delete(get[0]) - - def seed(self, contentId): - self.db_delete() - exec_str = 'XBMC.RunPlugin(%s)' % \ - ('%s?action=%s&url=%s&storage=%s&ind=%s') % \ - (sys.argv[0], 'downloadLibtorrent', urllib.quote_plus(self.torrentUrl), - urllib.quote_plus(self.userStorageDirectory), str(contentId)) - xbmc.executebuiltin(exec_str) - - def get_ids(self): - contentList = [] - for filedict in self.torrent.getContentList(): - contentList.append((filedict.get('title'), str(filedict.get('ind')))) - contentList = sorted(contentList, key=lambda x: x[0]) - return get_ids_video(contentList) - - def localize(self, string): - try: - return Localization.localize(string) - except: - return string diff --git a/Core.py b/Core.py index b916b6e..1848d22 100644 --- a/Core.py +++ b/Core.py @@ -233,8 +233,8 @@ class Core: lockView('wide') def test(self, params={}): - from Anteoloader import AnteoLoader - torrentUrl='D:\\ntest.torrent' + from Anteoloader import AnteoPlayer + torrentUrl='D:\\test.torrent' params['url']='0' if not xbmcvfs.exists(torrentUrl): action = xbmcgui.Dialog() @@ -244,11 +244,12 @@ class Core: self.Downloader = Downloader.Torrent(self.userStorageDirectory, torrentUrl) else: print self.__plugin__ + " Unexpected access to method Anteoloader() without torrent content" - if self.Downloader: - x=self.Downloader.getContentList() - print str(x) - xbmc.sleep(1000) - #self.Downloader.__exit__() + #if self.Downloader: + # x=self.Downloader.getContentList() + # print str(x) + # xbmc.sleep(1000) + # self.Downloader.__exit__() + self.Player = AnteoPlayer(userStorageDirectory=self.userStorageDirectory, torrentUrl=torrentUrl, params=params) def DownloadStatus(self, params={}): db = DownloadDB() diff --git a/Downloader.py b/Downloader.py index 502a2c2..823e5da 100644 --- a/Downloader.py +++ b/Downloader.py @@ -74,7 +74,7 @@ class Torrent(): return self.player.getPeers() def getSeeds(self): - return self.player.getMagnetInfo() + return self.player.getSeeds() def getFileSize(self, contentId=0): return self.player.getFileSize(contentId) diff --git a/Player.py b/Player.py index 377aaa2..b0de4f4 100644 --- a/Player.py +++ b/Player.py @@ -205,12 +205,12 @@ class TorrentPlayer(xbmc.Player): upload_limit = self.__settings__.getSetting("upload_limit") if self.__settings__.getSetting( "upload_limit") != "" else 0 if 0 < int(upload_limit): - self.torrent.setUploadLimit(int(upload_limit) * 1000000 / 8) # MBits/second + self.torrent.setUploadLimit(int(upload_limit) * 1024 * 1024 / 8) # MBits/second download_limit = self.__settings__.getSetting("download_limit") if self.__settings__.getSetting( "download_limit") != "" else 0 if 0 < int(download_limit): self.torrent.setDownloadLimit( - int(download_limit) * 1000000 / 8) # MBits/second + int(download_limit) * 1024 * 1024 / 8) # MBits/second self.torrent.status = False self.fullSize = self.torrent.getFileSize(self.contentId) Offset = calculate(self.fullSize) @@ -253,8 +253,8 @@ class TorrentPlayer(xbmc.Player): self.localize('Seeds'), str(self.torrent.getSeeds()), self.localize('Peers'), str(self.torrent.getPeers()),) speedsText = '%s: %s Mbit/s; %s: %s Mbit/s' % ( - self.localize('Downloading'), str(self.torrent.getDownloadRate() * 8 / 1000000), - self.localize('Uploading'), str(self.torrent.getUploadRate() * 8 / 1000000)) + self.localize('Downloading'), str(self.torrent.getDownloadRate() * 8 / 1024 / 1024), + self.localize('Uploading'), str(self.torrent.getUploadRate() * 8 / 1024 / 1024)) if self.debug: peersText=peersText + ' ' + self.torrent.get_debug_info('dht_state') dialogText=dialogText.replace(self.localize('Preloaded: '),'') + ' ' + self.torrent.get_debug_info('trackers_sum') @@ -431,8 +431,8 @@ class TorrentPlayer(xbmc.Player): return [ self.display_name.decode('utf-8')+'; '+self.torrent.get_debug_info('dht_state'), "%.2f%% %s; %s" % (s.progress * 100, self.localize(STATE_STRS[s.state]).decode('utf-8'), self.torrent.get_debug_info('trackers_sum')), - "D:%.2f%s U:%.2f%s S:%d P:%d" % (s.download_rate / 1000, self.localize('kb/s').decode('utf-8'), - s.upload_rate / 1000, self.localize('kb/s').decode('utf-8'), + "D:%.2f%s U:%.2f%s S:%d P:%d" % (s.download_rate / 1024, self.localize('kb/s').decode('utf-8'), + s.upload_rate / 1024, self.localize('kb/s').decode('utf-8'), s.num_seeds, s.num_peers) ] diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 8546fc5..34fc0a9 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -48,6 +48,7 @@ None Anti-zapret Immunicity + Max. connections (0 - unlimited) Interface P2P Network Advanced diff --git a/resources/language/Russian/strings.xml b/resources/language/Russian/strings.xml index 5c4a919..1cccee7 100644 --- a/resources/language/Russian/strings.xml +++ b/resources/language/Russian/strings.xml @@ -48,6 +48,7 @@ Не использовать Anti-zapret Immunicity + Макс. соединений (0 - безлимит) Интерфейс P2P Сеть Дополнительные diff --git a/resources/settings.xml b/resources/settings.xml index 5b81080..f5e606b 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -26,6 +26,7 @@ +