RussakHH stable roll-back

pull/1/head
DiMartinoXBMC 2015-12-15 17:09:25 +03:00
parent 43b53abba7
commit ff762538f1
21 changed files with 490 additions and 870 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,8 +19,10 @@
''' '''
import os import os
import urllib
import json
import sys
from contextlib import contextmanager, closing, nested from contextlib import contextmanager, closing, nested
from resources.btclient.argparse import Namespace
import xbmc import xbmc
import xbmcgui import xbmcgui
@ -29,9 +31,14 @@ import xbmcgui
import xbmcvfs import xbmcvfs
import Localization import Localization
from platform_pulsar import get_platform from platform_pulsar import get_platform
from resources.btclient.btclient import * import traceback
from functions import showMessage, DownloadDB, get_ids_video, log, debug, clearStorage 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 Player import OverlayText
from Libtorrent import Libtorrent
ROOT = sys.modules["__main__"].__root__ ROOT = sys.modules["__main__"].__root__
RESOURCES_PATH = os.path.join(ROOT, 'resources') RESOURCES_PATH = os.path.join(ROOT, 'resources')
@ -65,6 +72,12 @@ VIEWPORT_HEIGHT = 1088.0
OVERLAY_WIDTH = int(VIEWPORT_WIDTH * 0.7) # 70% size OVERLAY_WIDTH = int(VIEWPORT_WIDTH * 0.7) # 70% size
OVERLAY_HEIGHT = 150 OVERLAY_HEIGHT = 150
ENCRYPTION_SETTINGS = {
"Forced": 0,
"Enabled": 1,
"Disabled": 2,
}
class BTClientPlayer(xbmc.Player): class BTClientPlayer(xbmc.Player):
__plugin__ = sys.modules["__main__"].__plugin__ __plugin__ = sys.modules["__main__"].__plugin__
__settings__ = sys.modules["__main__"].__settings__ __settings__ = sys.modules["__main__"].__settings__
@ -80,11 +93,7 @@ class BTClientPlayer(xbmc.Player):
episodeId = None episodeId = None
basename = '' basename = ''
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, userStorageDirectory, torrentUrl, params={}): def __init__(self, userStorageDirectory, torrentUrl, params={}):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.userStorageDirectory = userStorageDirectory self.userStorageDirectory = userStorageDirectory
self.torrentUrl = torrentUrl self.torrentUrl = torrentUrl
xbmc.Player.__init__(self) xbmc.Player.__init__(self)
@ -109,7 +118,7 @@ class BTClientPlayer(xbmc.Player):
bt_upload_limit=self.upload_limit, bt_upload_limit=self.upload_limit,
choose_subtitles=False, choose_subtitles=False,
clear_older=0, clear_older=0,
debug_log=os.path.join(self.userStorageDirectory, 'log.txt'), debug_log='',#os.path.join(self.userStorageDirectory, 'log.txt'),
delete_on_finish=False, delete_on_finish=False,
directory=self.userStorageDirectory, directory=self.userStorageDirectory,
listen_port_max=6891,# listen_port_max=6891,#
@ -122,7 +131,7 @@ class BTClientPlayer(xbmc.Player):
stdin=False, stdin=False,
stream=True, stream=True,
subtitles=None, subtitles=None,
trace=True, trace=False,
content_id=self.contentId, content_id=self.contentId,
url=self.torrentUrl) url=self.torrentUrl)
args=main(args) #config args=main(args) #config
@ -131,6 +140,42 @@ class BTClientPlayer(xbmc.Player):
self.btclient=self.stream(args, BTClient) 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): def stream(self, args, client_class):
self.c = client_class(args.directory, args=args, lt=self.lt) self.c = client_class(args.directory, args=args, lt=self.lt)
try: try:
@ -151,38 +196,23 @@ class BTClientPlayer(xbmc.Player):
log('Starting btclient - libtorrent version %s' % self.lt.version) log('Starting btclient - libtorrent version %s' % self.lt.version)
self.c.start_url(args.url) self.c.start_url(args.url)
self.setup_torrent()
if self.buffer(): if self.buffer():
f = self.c._file f = self.c._file
self.server.set_file(f) self.server.set_file(f)
self.setup_play() self.setup_play()
while True: with closing(
if self.setup_play(): OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay:
log('************************************* GOING LOOP') with nested(self.attach(overlay.show, self.on_playback_paused),
#self.torrent.continueSession(self.contentId) self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)):
self.loop() while True:
else: if xbmc.abortRequested or not self.isPlaying():
break break
log('************************************* 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
log('************************************* NO! break')
break
if '1' != self.__settings__.getSetting("keep_files") and 'Saved Files' not in self.userStorageDirectory: status = self.c.status
xbmc.sleep(1000) overlay.text = "\n".join(self._get_status_lines(status))
clearStorage(self.userStorageDirectory) xbmc.sleep(1000)
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)
log('Play ended') log('Play ended')
if self.server: if self.server:
@ -216,7 +246,10 @@ class BTClientPlayer(xbmc.Player):
def setup_torrent(self): def setup_torrent(self):
pass pass
#if self.__settings__.getSetting('encryption') == 'true': #if self.__settings__.getSetting('encryption') == 'true':
# self.c.encrypt() # self.torrent.encryptSession()
#self.torrent.startSession()
#if self.subs_dl: #if self.subs_dl:
# subs = self.torrent.getSubsIds(os.path.basename(self.torrent.getFilePath(self.contentId))) # subs = self.torrent.getSubsIds(os.path.basename(self.torrent.getFilePath(self.contentId)))
# if len(subs) > 0: # if len(subs) > 0:
@ -224,43 +257,34 @@ class BTClientPlayer(xbmc.Player):
# self.torrent.continueSession(ind) # self.torrent.continueSession(ind)
def buffer(self): def buffer(self):
iterator = 0 #iterator = 0
progressBar = xbmcgui.DialogProgress() progressBar = xbmcgui.DialogProgress()
progressBar.create('%s [%s]' % (self.__class__.__name__,str(self.lt.version)), progressBar.create(self.localize('Please Wait') + str(' [%s]' % str(self.lt.version)),
self.localize('Seeds searching.')) self.localize('Seeds searching.'))
while not self.c.is_file_ready:#iterator < 100: while not self.c.is_file_ready: #iterator < 100:#or not self.torrent.is_playble()
iterator = 0
ready_list=[]
status = self.c.get_normalized_status() status = self.c.get_normalized_status()
conditions=[status['state'] in ['downloading', 'finished', 'seeding'], status['desired_rate'] > 0 or status['progress'] > 0.01, iterator = int(status['progress'] * 10000)
status['progress'] > 0.005, self.c.is_file_ready,# or status['progress'] > 0.02 if iterator > 99: iterator = 99
(status['download_rate'] > status['desired_rate'] or
status['download_rate'] * int(status['progress'] * 100) > status['desired_rate'])]
for cond in conditions:
if cond:
ready_list.append(True)
iterator+=100/len(conditions)
else:
ready_list.append(False)
speedsText = '%s: %s Mbit/s %s %s: %s Mbit/s' % (self.localize('Download speed'),str(status['download_rate'] * 8 / 1000000),
'[COLOR=green]>[/COLOR]' if ready_list[4] else '[COLOR=red]<[/COLOR]',
self.localize('Bitrate'), str(int(status['desired_rate'] * 8 / (1024 * 1024))) if status['desired_rate'] else 0,)
if status['state'] in ['queued','checking','checking fastresume'] or (status['progress'] == 0 and status['num_pieces'] > 0): 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...'), speedsText, ' ') progressBar.update(iterator, self.localize('Checking preloaded files...'), ' ', ' ')
elif status['state'] == 'downloading':
elif status['state'] in ['downloading', 'finished', 'seeding']: dialogText = self.localize('Preloaded: ') + str(status['downloaded'] / 1024 / 1024) + ' MB / ' + str(
dialogText = self.localize('Preloaded: ') + '%s MB %s %s MB (%s MB)' % \ status['total_size'] / 1024 / 1024) + ' MB'
(str(status['downloaded'] / 1024 / 1024), '[COLOR=green]>[/COLOR]' if ready_list[2] else '[COLOR=red]<[/COLOR]', str(status['total_size'] / 1024 / 1024 /200), str(status['total_size'] / 1024 / 1024)) peersText = ' [%s: %s; %s: %s]' % (
peersText = '%s: %s [%s: %s; %s: %s]' % (self.localize('File ready: '), '[COLOR=green]YES[/COLOR]' if ready_list[3] else '[COLOR=red]NO[/COLOR]', self.localize('Seeds'), str(status['seeds_connected']), self.localize('Peers'),
self.localize('Seeds'), str(status['seeds_connected']), self.localize('Peers'), str(status['peers_connected']),) str(status['peers_connected']),)
progressBar.update(iterator, peersText, speedsText, dialogText, 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: else:
progressBar.update(iterator, self.localize('UNKNOWN STATUS'), ' ', ' ') progressBar.update(iterator, self.localize('UNKNOWN STATUS'), ' ', ' ')
if progressBar.iscanceled(): if progressBar.iscanceled():
self.on_exit() self.c.close()
break break
xbmc.sleep(1000) xbmc.sleep(1000)
progressBar.update(0) progressBar.update(0)
@ -270,7 +294,7 @@ class BTClientPlayer(xbmc.Player):
def setup_subs(self, label, path): def setup_subs(self, label, path):
iterator = 0 iterator = 0
subs = self.torrent.getSubsIds(label) subs = self.torrent.getSubsIds(label)
log('[setup_subs] subs: '+str(subs)) debug('[setup_subs] subs: '+str(subs))
if len(subs) > 0: if len(subs) > 0:
showMessage(self.localize('Information'), showMessage(self.localize('Information'),
self.localize('Downloading and copy subtitles. Please wait.'), forced=True) self.localize('Downloading and copy subtitles. Please wait.'), forced=True)
@ -278,7 +302,7 @@ class BTClientPlayer(xbmc.Player):
self.torrent.continueSession(ind) self.torrent.continueSession(ind)
while iterator < 100: while iterator < 100:
xbmc.sleep(1000) xbmc.sleep(1000)
#self.torrent.debug() self.torrent.debug()
status = self.torrent.torrentHandle.status() status = self.torrent.torrentHandle.status()
iterator = int(status.progress * 100) iterator = int(status.progress * 100)
# xbmc.sleep(2000) # xbmc.sleep(2000)
@ -289,7 +313,7 @@ class BTClientPlayer(xbmc.Player):
ext = temp.split('.')[-1] ext = temp.split('.')[-1]
temp = temp[:len(temp) - len(ext) - 1] + '.' + addition + '.' + ext temp = temp[:len(temp) - len(ext) - 1] + '.' + addition + '.' + ext
newFileName = os.path.join(os.path.dirname(path), temp) newFileName = os.path.join(os.path.dirname(path), temp)
log('[setup_subs]: '+str((os.path.join(os.path.dirname(os.path.dirname(path)),title),newFileName))) debug('[setup_subs]: '+str((os.path.join(os.path.dirname(os.path.dirname(path)),title),newFileName)))
if not xbmcvfs.exists(newFileName): if not xbmcvfs.exists(newFileName):
xbmcvfs.copy(os.path.join(os.path.dirname(os.path.dirname(path)), title), newFileName) xbmcvfs.copy(os.path.join(os.path.dirname(os.path.dirname(path)), title), newFileName)
@ -301,7 +325,6 @@ class BTClientPlayer(xbmc.Player):
self.basename = label self.basename = label
#self.seeding_run = False #self.seeding_run = False
listitem = xbmcgui.ListItem(label) listitem = xbmcgui.ListItem(label)
info={}
#if self.subs_dl: #if self.subs_dl:
# self.setup_subs(label, path) # self.setup_subs(label, path)
@ -317,15 +340,16 @@ class BTClientPlayer(xbmc.Player):
title, int(seasonId), int(self.episodeId), self.basename.split('.')[-1], self.basename) title, int(seasonId), int(self.episodeId), self.basename.split('.')[-1], self.basename)
if seasonId and self.episodeId and label and title: if seasonId and self.episodeId and label and title:
info={'title': label, listitem = xbmcgui.ListItem(label)
'episode': int(self.episodeId),
'season': int(seasonId), listitem.setInfo(type='video', infoLabels={'title': label,
'tvshowtitle': title} 'episode': int(self.episodeId),
'season': int(seasonId),
'tvshowtitle': title})
except: except:
log('[BTClientPlayer] Operation INFO failed!') log('[BTClientPlayer] Operation INFO failed!')
thumbnail = self.get("thumbnail") thumbnail = self.get("thumbnail")
listitem.setInfo(type='Video', infoLabels=info)
if thumbnail: if thumbnail:
listitem.setThumbnailImage(urllib.unquote_plus(thumbnail)) listitem.setThumbnailImage(urllib.unquote_plus(thumbnail))
self.display_name = label self.display_name = label
@ -341,13 +365,11 @@ class BTClientPlayer(xbmc.Player):
while not response: while not response:
xbmc.sleep(100) xbmc.sleep(100)
if response: if response:
xbmc.sleep(3000)
#if 1==1:
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear() playlist.clear()
playlist.add(url, listitem) playlist.add(url, listitem)
xbmc.Player().play(playlist) xbmc.Player().play(playlist)
log("Serving file on %s" % url) print "\nServing file on %s" % url
return True return True
def onPlayBackStarted(self): def onPlayBackStarted(self):
@ -370,18 +392,6 @@ class BTClientPlayer(xbmc.Player):
f() f()
log('[onPlayBackStopped]: '+(str(("video", "stop", self.display_name)))) log('[onPlayBackStopped]: '+(str(("video", "stop", self.display_name))))
def onPlayBackSeek(self, x ,y):
log('[onPlayBackSeek]: '+(str(("video", "seek", self.display_name))))
#xbmc.Player().pause()
#if self.buffer():
# xbmc.Player().play()
def onPlayBackSeekChapter(self, x):
log('[onPlayBackSeek]: '+(str(("video", "seek", self.display_name))))
#xbmc.Player().pause()
#if self.buffer():
# xbmc.Player().play()
@contextmanager @contextmanager
def attach(self, callback, *events): def attach(self, callback, *events):
for event in events: for event in events:
@ -391,22 +401,21 @@ class BTClientPlayer(xbmc.Player):
event.remove(callback) event.remove(callback)
def loop(self): def loop(self):
#debug_counter=0 debug_counter=0
with closing( with closing(
OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay: 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), with nested(self.attach(overlay.show, self.on_playback_paused),
self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)): self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped)):
while True: while not xbmc.abortRequested and self.isPlaying() and not self.torrent.threadComplete:
if xbmc.abortRequested or not self.isPlaying(): self.torrent.checkThread()
break if self.iterator == 100 and debug_counter < 100:
debug_counter += 1
#if self.iterator == 100 and debug_counter < 100: else:
# debug_counter += 1 self.torrent.debug()
#else: debug_counter=0
# self.torrent.debug() status = self.torrent.torrentHandle.status()
# debug_counter=0
status = self.c.status
overlay.text = "\n".join(self._get_status_lines(status)) overlay.text = "\n".join(self._get_status_lines(status))
# downloadedSize = torrent.torrentHandle.file_progress()[contentId]
self.iterator = int(status.progress * 100) self.iterator = int(status.progress * 100)
xbmc.sleep(1000) xbmc.sleep(1000)
if self.iterator == 100 and self.next_dl: if self.iterator == 100 and self.next_dl:
@ -415,7 +424,7 @@ class BTClientPlayer(xbmc.Player):
self.next_contentId = int(self.ids_video[next_contentId_index]) self.next_contentId = int(self.ids_video[next_contentId_index])
else: else:
self.next_contentId = False self.next_contentId = False
log('[loop] next_contentId: '+str(self.next_contentId)) debug('[loop] next_contentId: '+str(self.next_contentId))
if not self.seeding_run and self.iterator == 100 and self.seeding: if not self.seeding_run and self.iterator == 100 and self.seeding:
self.seeding_run = True self.seeding_run = True
self.seed(self.contentId) self.seed(self.contentId)
@ -468,7 +477,3 @@ class BTClientPlayer(xbmc.Player):
return Localization.localize(string) return Localization.localize(string)
except: except:
return string return string
def on_exit(self):
self.c.close()
sys.exit(0)

53
Core.py
View File

@ -43,9 +43,6 @@ class Core:
print 'SYS ARGV: ' + str(sys.argv) print 'SYS ARGV: ' + str(sys.argv)
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self): def __init__(self):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__ print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
if len(self.userStorageDirectory) == 0: if len(self.userStorageDirectory) == 0:
@ -236,17 +233,17 @@ class Core:
lockView('wide') lockView('wide')
def test(self, params={}): def test(self, params={}):
#from BTClientPlayer import BTClientPlayer from BTClientPlayer import BTClientPlayer
#torrentUrl='D:\\ntest.torrent' torrentUrl='D:\\ntest.torrent'
#params['url']='0' params['url']='0'
#if not xbmcvfs.exists(torrentUrl): if not xbmcvfs.exists(torrentUrl):
# action = xbmcgui.Dialog() action = xbmcgui.Dialog()
# torrentUrl = action.browse(1, self.localize('Choose .torrent in video library'), 'video', '.torrent') torrentUrl = action.browse(1, self.localize('Choose .torrent in video library'), 'video', '.torrent')
#if torrentUrl and xbmcvfs.exists(torrentUrl): if torrentUrl and xbmcvfs.exists(torrentUrl):
# if 0 != len(torrentUrl): if 0 != len(torrentUrl):
# self.Player = BTClientPlayer(userStorageDirectory=self.userStorageDirectory, torrentUrl=torrentUrl, params=params) self.Player = BTClientPlayer(userStorageDirectory=self.userStorageDirectory, torrentUrl=torrentUrl, params=params)
# else: else:
# print self.__plugin__ + " Unexpected access to method playTorrent() without torrent content" print self.__plugin__ + " Unexpected access to method playTorrent() without torrent content"
#path='http://127.0.0.1:5001/Inception.2010.1080p.BluRay.x264.5xRus.Eng-Otaibi.mkv' #path='http://127.0.0.1:5001/Inception.2010.1080p.BluRay.x264.5xRus.Eng-Otaibi.mkv'
#listitem = xbmcgui.ListItem('Inception.2010.1080p.BluRay.x264.5xRus.Eng-Otaibi.mkv', path=path) #listitem = xbmcgui.ListItem('Inception.2010.1080p.BluRay.x264.5xRus.Eng-Otaibi.mkv', path=path)
#playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) #playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
@ -254,34 +251,6 @@ class Core:
#playlist.add(path, listitem) #playlist.add(path, listitem)
#xbmc.Player().play(playlist) #xbmc.Player().play(playlist)
from resources.proxy import antizapret
config = antizapret.config()
log('[antizapret]: '+str(config["domains"]))
log('[antizapret]: '+str(config["server"]))
#try:
# import cherrytorrent
# http_config = {
# 'port': 8089,
# }
# torrent_config = {
# 'port': 6900,
# 'max_download_rate': 0,
# 'max_upload_rate': 0,
# 'keep_files': False
# }
# server = cherrytorrent.Server(http_config, torrent_config)
# server.run()
# url="http://localhost:8089/add?uri=magnet%3A%3Fxt%3Durn%3Abtih%3Ac39fe3eefbdb62da9c27eb6398ff4a7d2e26e7ab%26dn%3Dbig%2Bbuck%2Bbunny%2Bbdrip%2Bxvid%2Bmedic%26tr%3Dudp%253A%252F%252Ftracker.publicbt.com%253A80%252Fannounce%26tr%3Dudp%253A%252F%252Fopen.demonii.com%253A1337"
# print str(get_url('',url))
# xbmc.sleep(3000)
# path="http://localhost:8089/video"#?info_hash=c39fe3eefbdb62da9c27eb6398ff4a7d2e26e7ab
# xbmc.Player().play(path)
# xbmc.sleep(30000)
#finally:
# get_url('',"http://localhost:8089/shutdown")
def DownloadStatus(self, params={}): def DownloadStatus(self, params={}):
db = DownloadDB() db = DownloadDB()
get = params.get get = params.get

View File

@ -28,11 +28,7 @@ import AceStream
class Torrent(): class Torrent():
__settings__ = sys.modules["__main__"].__settings__ __settings__ = sys.modules["__main__"].__settings__
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, storageDirectory='', torrentFile='', torrentFilesDirectory='torrents'): def __init__(self, storageDirectory='', torrentFile='', torrentFilesDirectory='torrents'):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.get_torrent_client() self.get_torrent_client()
if self.player == 'libtorrent': if self.player == 'libtorrent':
self.player = Libtorrent.Libtorrent(storageDirectory, torrentFile, torrentFilesDirectory) self.player = Libtorrent.Libtorrent(storageDirectory, torrentFile, torrentFilesDirectory)

View File

@ -34,7 +34,6 @@ import Localization
from functions import file_encode, isSubtitle, DownloadDB, log, debug, is_writable from functions import file_encode, isSubtitle, DownloadDB, log, debug, is_writable
from platform_pulsar import get_platform from platform_pulsar import get_platform
class Libtorrent: class Libtorrent:
magnetLink = None magnetLink = None
startPart = 0 startPart = 0
@ -45,12 +44,9 @@ class Libtorrent:
downloadThread = None downloadThread = None
threadComplete = False threadComplete = False
lt = None lt = None
save_resume_data = None
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, storageDirectory='', torrentFile='', torrentFilesDirectory='torrents'): def __init__(self, storageDirectory='', torrentFile='', torrentFilesDirectory='torrents'):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.platform = get_platform() self.platform = get_platform()
self.storageDirectory = storageDirectory self.storageDirectory = storageDirectory
self.torrentFilesPath = os.path.join(self.storageDirectory, torrentFilesDirectory) + os.sep self.torrentFilesPath = os.path.join(self.storageDirectory, torrentFilesDirectory) + os.sep
@ -169,9 +165,7 @@ class Libtorrent:
iterator = 0 iterator = 0
while iterator < 100: while iterator < 100:
xbmc.sleep(500) xbmc.sleep(500)
self.torrentHandle.force_dht_announce() self.torrentHandle.force_dht_announce()
progressBar.update(iterator, Localization.localize('Please Wait'), Localization.localize('Magnet-link is converting')+'.' * (iterator % 4), ' ') progressBar.update(iterator, Localization.localize('Please Wait'), Localization.localize('Magnet-link is converting')+'.' * (iterator % 4), ' ')
iterator += 1 iterator += 1
if progressBar.iscanceled(): if progressBar.iscanceled():
@ -419,9 +413,10 @@ class Libtorrent:
self.torrentFileInfo = self.getMagnetInfo() self.torrentFileInfo = self.getMagnetInfo()
torrent_info={'ti': self.torrentFileInfo, torrent_info={'ti': self.torrentFileInfo,
'save_path': self.storageDirectory, 'save_path': self.storageDirectory,
'flags': 0x300,
#'storage_mode': self.lt.storage_mode_t(1), #'storage_mode': self.lt.storage_mode_t(1),
'paused': False, 'paused': False,
'auto_managed': False, #'auto_managed': False,
#'duplicate_is_error': True #'duplicate_is_error': True
} }
self.torrentHandle = self.session.add_torrent(torrent_info) self.torrentHandle = self.session.add_torrent(torrent_info)
@ -478,9 +473,8 @@ class Libtorrent:
#log('get_cache_status - %s/%s' % (str(get_cache_status.blocks_written), str(get_cache_status.blocks_read))) #log('get_cache_status - %s/%s' % (str(get_cache_status.blocks_written), str(get_cache_status.blocks_read)))
# get_settings=self.torrentHandle.status # get_settings=self.torrentHandle.status
# print s.num_pieces # print s.num_pieces
priorities = self.torrentHandle.piece_priorities() #priorities = self.torrentHandle.piece_priorities()
str(priorities) #print str(priorities)
# print str('anonymous_mode '+str(get_settings['anonymous_mode']))
state_str = ['queued', 'checking', 'downloading metadata', state_str = ['queued', 'checking', 'downloading metadata',
'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume'] 'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']
@ -529,13 +523,11 @@ class Libtorrent:
result=result+'Trackers: verified %d/%d, fails=%d' %(verified_sum, len(trackers)-1, fails_sum) result=result+'Trackers: verified %d/%d, fails=%d' %(verified_sum, len(trackers)-1, fails_sum)
if info=='dht_state': if info=='dht_state':
is_dht_running='ON' if self.session.is_dht_running() else 'OFF' is_dht_running='ON' if self.session.is_dht_running() else 'OFF'
try:
dht_state = self.session.dht_state() nodes=self.session.dht_state().get('nodes')
if 'nodes' in dht_state: except:
nodes = len(dht_state['nodes']) nodes=None
else: nodes=len(nodes) if nodes else 0
nodes=0
result='DHT: %s (%d)' % (is_dht_running, nodes) result='DHT: %s (%d)' % (is_dht_running, nodes)
return result return result

View File

@ -72,11 +72,7 @@ ENCRYPTION_SETTINGS = {
class OverlayText(object): class OverlayText(object):
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, w, h, *args, **kwargs): def __init__(self, w, h, *args, **kwargs):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.window = xbmcgui.Window(WINDOW_FULLSCREEN_VIDEO) self.window = xbmcgui.Window(WINDOW_FULLSCREEN_VIDEO)
viewport_w, viewport_h = self._get_skin_resolution() viewport_w, viewport_h = self._get_skin_resolution()
# Adjust size based on viewport, we are using 1080p coordinates # Adjust size based on viewport, we are using 1080p coordinates
@ -140,11 +136,7 @@ class TorrentPlayer(xbmc.Player):
episodeId = None episodeId = None
basename = '' basename = ''
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, userStorageDirectory, torrentUrl, params={}): def __init__(self, userStorageDirectory, torrentUrl, params={}):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.userStorageDirectory = userStorageDirectory self.userStorageDirectory = userStorageDirectory
self.torrentUrl = torrentUrl self.torrentUrl = torrentUrl
xbmc.Player.__init__(self) xbmc.Player.__init__(self)
@ -277,37 +269,12 @@ class TorrentPlayer(xbmc.Player):
self.torrent.checkThread() self.torrent.checkThread()
return return
xbmc.sleep(1000) xbmc.sleep(1000)
self.torrent.session.remove_torrent(self.torrent.torrentHandle) #self.torrent.torrentHandle.flush_cache()
#self.torrent.session.remove_torrent(self.torrent.torrentHandle)
progressBar.update(0) progressBar.update(0)
progressBar.close() progressBar.close()
return True 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): def setup_play(self):
self.next_dling = False self.next_dling = False
self.iterator = 0 self.iterator = 0
@ -351,11 +318,10 @@ class TorrentPlayer(xbmc.Player):
data = json.dumps(rpc) data = json.dumps(rpc)
request = xbmc.executeJSONRPC(data) request = xbmc.executeJSONRPC(data)
response = json.loads(request) response = json.loads(request)
xbmc.sleep(300) xbmc.sleep(1000)
if response: if response:
# xbmc.Player().play(path, listitem) # xbmc.Player().play(path, listitem)
log('Megakostil worked! Start playing '+str(path))
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear() playlist.clear()
playlist.add(path, listitem) playlist.add(path, listitem)
@ -364,6 +330,32 @@ class TorrentPlayer(xbmc.Player):
xbmc.sleep(2000) # very important, do not edit this, podavan xbmc.sleep(2000) # very important, do not edit this, podavan
return True 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 onPlayBackStarted(self): def onPlayBackStarted(self):
for f in self.on_playback_started: for f in self.on_playback_started:
f() f()

View File

@ -1,4 +1,4 @@
Plugin helps you to watch videos from p2p torrent-networks, without full predownload (uses inner python-libtorrent) or Ace Stream. It also can add, control torrents and play downloaded files with external uTorrent, Transmission, Vuze or Deluge. Plugin helps you to watch videos from p2p torrent-networks, without full predownload (uses inner python-libtorrent) or Ace Stream. It also can add, control torrents and play downloaded files with external uTorrent, Transmission, Vuze or Deluge.
Official forum thread and FAQ: http://forum.kodi.tv/showthread.php?tid=214366 Official forum thread and FAQ: http://forums.tvaddons.ag/addon-releases/29224-torrenter-v2.html
Инструкции и обсуждение: http://xbmc.ru/forum/showthread.php?t=6837 Инструкции и обсуждение: http://xbmc.ru/forum/showthread.php?t=6837

View File

@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.torrenter" name="Torrenter" version="2.3.8g" provider-name="vadim.skorba, DiMartino"> <addon id="plugin.video.torrenter" name="Torrenter" version="2.3.9" provider-name="vadim.skorba, DiMartino">
<requires> <requires>
<import addon="xbmc.python" version="2.1.0"/> <import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.libtorrent"/> <import addon="script.module.libtorrent"/>
<import addon="script.module.beautifulsoup4"/> <import addon="script.module.btclient"/>
<import addon="script.module.hachoir"/>
<import addon="script.module.torrent.ts"/> <import addon="script.module.torrent.ts"/>
<import addon="script.module.requests"/>
</requires> </requires>
<extension point="xbmc.python.pluginsource" provides="video" library="default.py"> <extension point="xbmc.python.pluginsource" provides="video" library="default.py">
<provides>video</provides> <provides>video</provides>
@ -18,10 +16,6 @@
<description lang='en'>Plugin helps you to watch videos from p2p torrent-networks, without full predownload (uses python-libtorrent or Ace Stream). It also can add, control torrents and play downloaded files with external torrent-client (uTorrent, Transmisson, Vuse, Deluge) or python-libtorrent. <description lang='en'>Plugin helps you to watch videos from p2p torrent-networks, without full predownload (uses python-libtorrent or Ace Stream). It also can add, control torrents and play downloaded files with external torrent-client (uTorrent, Transmisson, Vuse, Deluge) or python-libtorrent.
</description> </description>
<disclaimer lang='en'>GNU GPLv3 http://www.gnu.org/licenses/</disclaimer> <disclaimer lang='en'>GNU GPLv3 http://www.gnu.org/licenses/</disclaimer>
<summary lang='he'>תוסף המאפשר לך לצפות בקטעי וידאו מרשתות טורנט P2P, ללא הורדה מלאה.
</summary>
<description lang='he'>תוסף המאפשר לך לצפות בקטעי וידאו מרשתות טורנט P2P, ללא הורדה מלאה (משתמש ב-Python-libtorrent או Ace Stream). ניתן גם להוסיף,לשלוט ולנגן בקבצי טורנטים שהורדו עם תוכנת טורנט חיצונית (uTorrent, Transmisson, Vuse, Deluge) או Python-libtorrent.
</description>
<summary lang='ru'>Плагин позволяет просматривать видео из пиринговых торрент-сетей, не дожидаясь полного скачивания. <summary lang='ru'>Плагин позволяет просматривать видео из пиринговых торрент-сетей, не дожидаясь полного скачивания.
</summary> </summary>
<description lang='ru'>Плагин позволяет просматривать видео из пиринговых торрент-сетей, не дожидаясь полного скачивания. Использует библиотеку python-libtorrent или Ace Stream. Так же плагин может добавлять, проигрывать и управлять скачками в торрент клиентах (uTorrent, Transmisson, Deluge и Vuse) или средставми python-libtorrent. <description lang='ru'>Плагин позволяет просматривать видео из пиринговых торрент-сетей, не дожидаясь полного скачивания. Использует библиотеку python-libtorrent или Ace Stream. Так же плагин может добавлять, проигрывать и управлять скачками в торрент клиентах (uTorrent, Transmisson, Deluge и Vuse) или средставми python-libtorrent.

View File

@ -1,12 +1,8 @@
English changelog at http://bit.ly/1MfSVUP English changelog at http://bit.ly/1MfSVUP
[B]Version 2.3.8[/B]
[+] Добавлен АнтиЗапрет
[+] Списки Медиа: Исправлен KickAssSo
[B]Version 2.3.6[/B] [B]Version 2.3.6[/B]
[+] Оптимизация импорта, ускорена работа меню [+] Оптимизация импорта
[+] Новый Проигрыватель [url=https://github.com/izderadicka/btclient]BTclient[/url] в тестовом режиме, требует python-libtorrent >=1.0.4. [+] Новый Проигрыватель BTclient (https://github.com/izderadicka/btclient) в тестовом режиме.
[B]Version 2.3.5[/B] [B]Version 2.3.5[/B]
[+] Проигрыватель: Уменьшена просадка после загрузки буфера [+] Проигрыватель: Уменьшена просадка после загрузки буфера

View File

@ -19,7 +19,7 @@
''' '''
import sys import sys
import gc
import xbmcaddon import xbmcaddon
@ -38,7 +38,3 @@ if (__name__ == "__main__" ):
else: else:
params = core.getParameters(sys.argv[2]) params = core.getParameters(sys.argv[2])
core.executeAction(params) core.executeAction(params)
del core
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)

View File

@ -99,6 +99,8 @@ def clearStorage(userStorageDirectory):
except Exception, e: except Exception, e:
log('[clearStorage]: DownloadDB().clear() failed. '+str(e)) log('[clearStorage]: DownloadDB().clear() failed. '+str(e))
showMessage(Localization.localize('Storage'), Localization.localize('Storage was cleared'), forced=True)
def sortcomma(dict, json): def sortcomma(dict, json):
for x in dict: for x in dict:
@ -801,11 +803,7 @@ class TimeOut():
class ListDB: class ListDB:
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, version=1.0): def __init__(self, version=1.0):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.dbname = 'list' + '.db3' self.dbname = 'list' + '.db3'
dirname = xbmc.translatePath('special://temp') dirname = xbmc.translatePath('special://temp')
self.dbfilename = os.path.join(dirname, 'xbmcup', self.dbfilename = os.path.join(dirname, 'xbmcup',
@ -864,11 +862,7 @@ class ListDB:
class HistoryDB: class HistoryDB:
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, version=1.1): def __init__(self, version=1.1):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.name = 'history.db3' self.name = 'history.db3'
self.version = version self.version = version
@ -1008,11 +1002,7 @@ class HistoryDB:
class Searchers(): class Searchers():
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self): def __init__(self):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
pass pass
def getBoolSetting(self, setting): def getBoolSetting(self, setting):
@ -1131,6 +1121,7 @@ def search(url, searchersList, isApi=None):
result = {} result = {}
iterator, filesList, left_searchers = 0, [], [] iterator, filesList, left_searchers = 0, [], []
timeout_multi=int(sys.modules["__main__"].__settings__.getSetting("timeout")) timeout_multi=int(sys.modules["__main__"].__settings__.getSetting("timeout"))
wait_time=10+(10*timeout_multi)
left_searchers.extend(searchersList) left_searchers.extend(searchersList)
if not isApi: if not isApi:
progressBar = xbmcgui.DialogProgress() progressBar = xbmcgui.DialogProgress()
@ -1198,11 +1189,7 @@ def join_list(l, char=', ', replace=''):
class Contenters(): class Contenters():
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self): def __init__(self):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
pass pass
def first_time(self, scrapperDB_ver, language='ru'): def first_time(self, scrapperDB_ver, language='ru'):
@ -1410,11 +1397,7 @@ def delete_russian(ok=False, action='delete'):
class DownloadDB: class DownloadDB:
def __del__(self):
print '!!!!!!!!!!!!!!!!!! DIED !!! '+self.__class__.__name__
def __init__(self, version=1.41): def __init__(self, version=1.41):
print '!!!!!!!!!!!!!!!!!! BORN '+self.__class__.__name__
self.name = 'download.db3' self.name = 'download.db3'
self.version = version self.version = version

View File

@ -1,5 +0,0 @@
#-*- coding: utf-8 -*-
'''
Torrenter v2 plugin for XBMC/Kodi
Copyright (C) 2015 DiMartino
'''

View File

@ -44,10 +44,6 @@
<string id="30044">Save files</string> <string id="30044">Save files</string>
<string id="30045">Ask to save</string> <string id="30045">Ask to save</string>
<string id="30046">BTclient (python-libtorrent via http)</string> <string id="30046">BTclient (python-libtorrent via http)</string>
<string id="30047">Auto-unblocking proxy</string>
<string id="30048">None</string>
<string id="30049">Anti-zapret</string>
<string id="30050">Immunicity</string>
<string id="30101">Interface</string> <string id="30101">Interface</string>
<string id="30102">P2P Network</string> <string id="30102">P2P Network</string>
<string id="30103">Advanced</string> <string id="30103">Advanced</string>
@ -73,5 +69,4 @@
<string id="30418">Choose searcher</string> <string id="30418">Choose searcher</string>
<string id="30419">You don't have external searcher. Please install it first.</string> <string id="30419">You don't have external searcher. Please install it first.</string>
</strings> </strings>

View File

@ -44,10 +44,6 @@
<string id="30044">Сохранять файлы</string> <string id="30044">Сохранять файлы</string>
<string id="30045">Спросить о сохранении</string> <string id="30045">Спросить о сохранении</string>
<string id="30046">BTclient (python-libtorrent по http)</string> <string id="30046">BTclient (python-libtorrent по http)</string>
<string id="30047">Антизапрет (прокси)</string>
<string id="30048">Не использовать</string>
<string id="30049">Anti-zapret</string>
<string id="30050">Immunicity</string>
<string id="30101">Интерфейс</string> <string id="30101">Интерфейс</string>
<string id="30102">P2P Сеть</string> <string id="30102">P2P Сеть</string>
<string id="30103">Дополнительные</string> <string id="30103">Дополнительные</string>

View File

@ -7,10 +7,8 @@ ported from python-Levenshtein
[https://github.com/miohtama/python-Levenshtein] [https://github.com/miohtama/python-Levenshtein]
""" """
from warnings import warn
from Levenshtein import * from Levenshtein import *
from warnings import warn
class StringMatcher: class StringMatcher:
"""A SequenceMatcher-like class built on the top of Levenshtein""" """A SequenceMatcher-like class built on the top of Levenshtein"""

View File

@ -25,10 +25,12 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
import warnings
try: try:
from .StringMatcher import StringMatcher as SequenceMatcher from .StringMatcher import StringMatcher as SequenceMatcher
except ImportError: except ImportError:
#warnings.warn('Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning')
from difflib import SequenceMatcher from difflib import SequenceMatcher
from . import utils from . import utils

View File

@ -34,7 +34,6 @@ import translit
# MATCHER_MOVIE_DURATION = re.compile('\s*(\d+).*?', re.UNICODE | re.DOTALL) # MATCHER_MOVIE_DURATION = re.compile('\s*(\d+).*?', re.UNICODE | re.DOTALL)
# MATCHER_IMDB_RATING = re.compile('IMDb:\s*(\d+\.?\d*)\s*\(\s*([\s\d]+)\s*\)', re.UNICODE | re.DOTALL) # MATCHER_IMDB_RATING = re.compile('IMDb:\s*(\d+\.?\d*)\s*\(\s*([\s\d]+)\s*\)', re.UNICODE | re.DOTALL)
# MATCHER_IMDB_RATING = re.compile('IMDb:\s*(\d+\.?\d*)\s?\((.*)\)', re.UNICODE) # MATCHER_IMDB_RATING = re.compile('IMDb:\s*(\d+\.?\d*)\s?\((.*)\)', re.UNICODE)

View File

@ -11,7 +11,6 @@
<setting id="timeout" type="enum" lvalues="30026|30027|30028" label="30025" default="1"/> <setting id="timeout" type="enum" lvalues="30026|30027|30028" label="30025" default="1"/>
<setting id="search_phrase" type="text" label="30040"/> <setting id="search_phrase" type="text" label="30040"/>
<setting id="num_threads" type="slider" label="30042" default="3" range="1,1,9" option="int"/> <setting id="num_threads" type="slider" label="30042" default="3" range="1,1,9" option="int"/>
<setting id="proxy" type="enum" lvalues="30048|30049|" label="30047" default="0"/>
<setting id="debug" type="bool" label="30015" default="false"/> <setting id="debug" type="bool" label="30015" default="false"/>
</category> </category>
<category label="30102"> <category label="30102">

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re import sys, urllib, urllib2, re, os, cookielib, traceback, datetime, htmlentitydefs
import htmlentitydefs import xbmc, xbmcgui, xbmcaddon
import xbmcgui
pattern = re.compile("&(\w+?);") pattern = re.compile("&(\w+?);")

View File

@ -1,5 +0,0 @@
#-*- coding: utf-8 -*-
'''
Torrenter v2 plugin for XBMC/Kodi
Copyright (C) 2015 DiMartino
'''

View File

@ -58,6 +58,7 @@ source file.
# class_defs_make.py. # class_defs_make.py.
# #
import dopal.classes
from dopal.aztypes import AzMethod as _method from dopal.aztypes import AzMethod as _method
from dopal.aztypes import AzureusMethods from dopal.aztypes import AzureusMethods