keep seeding
parent
14a1862e5f
commit
ff9644321e
1214
.idea/workspace.xml
1214
.idea/workspace.xml
File diff suppressed because it is too large
Load Diff
74
Core.py
74
Core.py
|
@ -18,8 +18,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
'''
|
||||
|
||||
import StringIO
|
||||
import gzip, thread
|
||||
from StringIO import StringIO
|
||||
import gzip
|
||||
import tempfile
|
||||
|
||||
import Downloader
|
||||
|
@ -64,7 +64,7 @@ class Core:
|
|||
('«', '"'),
|
||||
('»', '"'),
|
||||
)
|
||||
scrapperDB_ver = {'en':'1.0', 'ru':'1.2'}
|
||||
scrapperDB_ver = {'en':'1.1', 'ru':'1.2'}
|
||||
|
||||
print 'SYS ARGV: ' + str(sys.argv)
|
||||
|
||||
|
@ -107,10 +107,11 @@ class Core:
|
|||
ListString % ('full_download', '', 'url', json.dumps({'action': 'delete'}))))
|
||||
self.drawItem('< %s >' % self.localize('Content Lists'), 'openContent', image=self.ROOT + '/icons/media.png',
|
||||
contextMenu=CLcontextMenu, replaceMenu=False)
|
||||
DLScontextMenu=[]
|
||||
DLScontextMenu.extend(contextMenu)
|
||||
DLScontextMenu=[(self.localize('Start All'), ListString % ('DownloadStatus', 'startall', 'addtime', '')),
|
||||
(self.localize('Stop All'), ListString % ('DownloadStatus', 'stopall', 'addtime', '')),]
|
||||
DLScontextMenu.append(
|
||||
(self.localize('Clear %s') % self.localize('Download Status'), ListString % ('DownloadStatus', 'clear', 'addtime', '')))
|
||||
DLScontextMenu.extend(contextMenu)
|
||||
self.drawItem('< %s >' % self.localize('Download Status'), 'DownloadStatus', image=self.ROOT + '/icons/download.png',
|
||||
contextMenu=DLScontextMenu, replaceMenu=False)
|
||||
self.drawItem('< %s >' % self.localize('Torrent-client Browser'), 'uTorrentBrowser',
|
||||
|
@ -324,14 +325,32 @@ class Core:
|
|||
|
||||
if action2 == 'start':
|
||||
start=db.get_byaddtime(addtime)
|
||||
link, ind=start[6], start[7]
|
||||
torrent, ind=start[6], start[7]
|
||||
storage=get('storage') if get('storage') else ''
|
||||
start_exec='XBMC.RunPlugin(%s)' % ('%s?action=%s&url=%s&ind=%s&storage=%s') % (
|
||||
sys.argv[0], 'downloadLibtorrent', urllib.quote_plus(link.encode('utf-8')), str(ind), storage)
|
||||
sys.argv[0], 'downloadLibtorrent', urllib.quote_plus(torrent.encode('utf-8')), str(ind), storage)
|
||||
xbmc.executebuiltin(start_exec)
|
||||
xbmc.executebuiltin('Container.Refresh')
|
||||
showMessage(self.localize('Download Status'), self.localize('Started!'))
|
||||
|
||||
if action2 == 'startall':
|
||||
items = db.get_all()
|
||||
if items:
|
||||
for addtime, title, path, type, info, status, torrent, ind, lastupdate, storage in items:
|
||||
start_exec='XBMC.RunPlugin(%s)' % ('%s?action=%s&url=%s&ind=%s&storage=%s') % (
|
||||
sys.argv[0], 'downloadLibtorrent', urllib.quote_plus(torrent.encode('utf-8')), str(ind), urllib.quote_plus(storage.encode('utf-8')))
|
||||
xbmc.executebuiltin(start_exec)
|
||||
xbmc.sleep(1000)
|
||||
showMessage(self.localize('Download Status'), self.localize('Started All!'))
|
||||
|
||||
if action2 == 'stopall':
|
||||
items = db.get_all()
|
||||
if items:
|
||||
for addtime, title, path, type, info, status, torrent, ind, lastupdate, storage in items:
|
||||
db.update_status(addtime, 'stopped')
|
||||
xbmc.sleep(1000)
|
||||
showMessage(self.localize('Download Status'), self.localize('Stopped All!'))
|
||||
|
||||
if action2 == 'unpause':
|
||||
db.update_status(addtime, 'downloading')
|
||||
xbmc.executebuiltin('Container.Refresh')
|
||||
|
@ -369,9 +388,9 @@ class Core:
|
|||
title = '[%d%%]%s %s' % (progress, status_sign, title)
|
||||
if jsoninfo.get('seeds')!=None and jsoninfo.get('peers')!=None and \
|
||||
jsoninfo.get('download')!=None and jsoninfo.get('upload')!=None:
|
||||
d,u=int(jsoninfo['download']/ 1000000), int(jsoninfo['upload'] / 1000000)
|
||||
d,u=float(jsoninfo['download'])/ 1000000, float(jsoninfo['upload']) / 1000000
|
||||
s,p=str(jsoninfo['seeds']),str(jsoninfo['peers'])
|
||||
title='%s [S/L %s/%s][D/U %s/%s (MB/s)]' %(title,s,p,d,u)
|
||||
title='%s [D/U %.2f/%.2f (MB/s)][S/L %s/%s]' %(title,d,u,s,p)
|
||||
|
||||
if status=='pause':
|
||||
contextMenu=[(self.localize('Unpause'), ListString+'unpause)'),
|
||||
|
@ -492,7 +511,6 @@ class Core:
|
|||
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
|
||||
|
||||
def drawContent(self, category_dict, provider=None, category=None, subcategory=None):
|
||||
|
||||
if not category and not provider:
|
||||
self.drawItem('[COLOR FFFFFFFF][B]< %s >[/B][/COLOR]' % self.localize('Personal List'), 'List', image=self.ROOT + '/icons/list.png')
|
||||
for cat in category_dict.keys():
|
||||
|
@ -1075,7 +1093,7 @@ class Core:
|
|||
dllist = sorted(Download().listfiles(hash), key=lambda x: x[0])
|
||||
for name, percent, ind, size in dllist:
|
||||
if '/' not in name:
|
||||
menu.append({"title": '[' + str(percent) + '%]' + '[' + str(size) + '] ' + name,
|
||||
menu.append({"title": '[' + str(percent) + '%]' + '[' + str(size) + '] ' + name, "image":'',
|
||||
"argv": {'hash': hash, 'ind': str(ind), 'action': 'context'}})
|
||||
else:
|
||||
tdir = name.split('/')[0]
|
||||
|
@ -1086,7 +1104,7 @@ class Core:
|
|||
for name, percent, ind, size in dllist:
|
||||
if '/' in name and tdir in name:
|
||||
menu.append(
|
||||
{"title": '[' + str(percent) + '%]' + '[' + str(size) + '] ' + name[len(tdir) + 1:],
|
||||
{"title": '[' + str(percent) + '%]' + '[' + str(size) + '] ' + name[len(tdir) + 1:], "image":'',
|
||||
"argv": {'hash': hash, 'ind': str(ind), 'action': 'context'}})
|
||||
|
||||
for i in dirs:
|
||||
|
@ -1151,14 +1169,8 @@ class Core:
|
|||
|
||||
def torrentPlayer(self, params={}):
|
||||
get = params.get
|
||||
try:
|
||||
url = urllib.unquote_plus(get("url"))
|
||||
except:
|
||||
url = None
|
||||
try:
|
||||
tdir = urllib.unquote_plus(get("url2"))
|
||||
except:
|
||||
tdir = None
|
||||
url = unquote(get("url"),None)
|
||||
tdir = unquote(get("url2"),None)
|
||||
|
||||
#url="D:\\[rutracker.org].t4563731.torrent"
|
||||
|
||||
|
@ -1267,7 +1279,6 @@ class Core:
|
|||
request = urllib2.Request(url)
|
||||
request.add_header('Referer', url)
|
||||
request.add_header('Accept-encoding', 'gzip')
|
||||
localFile = xbmcvfs.File(torrentFile, "w+b")
|
||||
result = urllib2.urlopen(request)
|
||||
if result.info().get('Content-Encoding') == 'gzip':
|
||||
buf = StringIO(result.read())
|
||||
|
@ -1275,6 +1286,7 @@ class Core:
|
|||
content = f.read()
|
||||
else:
|
||||
content = result.read()
|
||||
localFile = xbmcvfs.File(torrentFile, "wb+")
|
||||
localFile.write(content)
|
||||
localFile.close()
|
||||
return torrentFile
|
||||
|
@ -1284,24 +1296,12 @@ class Core:
|
|||
|
||||
def openTorrent(self, params={}):
|
||||
get = params.get
|
||||
try:
|
||||
external = urllib.unquote_plus(get("external"))
|
||||
except:
|
||||
external = None
|
||||
external = unquote(get("external"),None)
|
||||
silent = get("silent")
|
||||
not_download_only = get("not_download_only") == 'False'
|
||||
try:
|
||||
tdir = urllib.unquote_plus(get("url2"))
|
||||
except:
|
||||
tdir = None
|
||||
try:
|
||||
thumbnail = urllib.unquote_plus(get("thumbnail"))
|
||||
except:
|
||||
thumbnail = ''
|
||||
try:
|
||||
save_folder = urllib.unquote_plus(get("save_folder"))
|
||||
except:
|
||||
save_folder = ''
|
||||
tdir = unquote(get("url2"),None)
|
||||
thumbnail = unquote(get("thumbnail"),'')
|
||||
save_folder = unquote(get("save_folder"),'')
|
||||
url = urllib.unquote_plus(get("url"))
|
||||
self.__settings__.setSetting("lastTorrentUrl", url)
|
||||
classMatch = re.search('(\w+)::(.+)', url)
|
||||
|
|
|
@ -47,8 +47,6 @@ class Libtorrent:
|
|||
session = None
|
||||
downloadThread = None
|
||||
threadComplete = False
|
||||
threadSeeding = False
|
||||
seedingHandle = None
|
||||
lt = None
|
||||
|
||||
def __init__(self, storageDirectory='', torrentFile='', torrentFilesDirectory='torrents'):
|
||||
|
@ -281,7 +279,7 @@ class Libtorrent:
|
|||
db=DownloadDB()
|
||||
status='downloading'
|
||||
while db.get(title) and status!='stopped':
|
||||
xbmc.sleep(1000)
|
||||
xbmc.sleep(3000)
|
||||
status=db.get_status(title)
|
||||
if not self.paused:
|
||||
if status=='pause':
|
||||
|
@ -354,7 +352,7 @@ class Libtorrent:
|
|||
#if seeding:# and None == self.magnetLink:
|
||||
# thread.start_new_thread(self.addToSeeding, (contentId,))
|
||||
|
||||
def addToSeeding(self, contentId):
|
||||
'''def addToSeeding(self, contentId):
|
||||
print 'addToSeeding!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1'
|
||||
if self.torrentHandle:
|
||||
print 'addToSeeding torrentHandle OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1'
|
||||
|
@ -386,7 +384,7 @@ class Libtorrent:
|
|||
self.seedingHandle.piece_priority(endPart, 7)
|
||||
while self.seedingHandle:
|
||||
xbmc.sleep(5000)
|
||||
self.debug(seeding=True)
|
||||
self.debug(seeding=True)'''
|
||||
|
||||
def fetchParts(self):
|
||||
priorities = self.torrentHandle.piece_priorities()
|
||||
|
@ -403,18 +401,11 @@ class Libtorrent:
|
|||
if self.threadComplete == True:
|
||||
print 'checkThread KIIIIIIIIIIILLLLLLLLLLLLLLL'
|
||||
self.session.remove_torrent(self.torrentHandle)
|
||||
if self.threadSeeding == True and self.seedingHandle:
|
||||
print 'Seeding KIIIIIIIIIIILLLLLLLLLLLLLLL'
|
||||
self.session.remove_torrent(self.seedingHandle)
|
||||
thread.exit()
|
||||
|
||||
def debug(self, seeding=False):
|
||||
def debug(self):
|
||||
try:
|
||||
#print str(self.getFilePath(0))
|
||||
if seeding:
|
||||
s = self.seedingHandle.status()
|
||||
else:
|
||||
s = self.torrentHandle.status()
|
||||
s = self.torrentHandle.status()
|
||||
#get_settings=self.torrentHandle.status
|
||||
#print s.num_pieces
|
||||
#priorities = self.torrentHandle.piece_priorities()
|
||||
|
@ -423,8 +414,8 @@ class Libtorrent:
|
|||
|
||||
state_str = ['queued', 'checking', 'downloading metadata',
|
||||
'downloading', 'finished', 'seeding', 'allocating']
|
||||
print '[%s;%s] %.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % \
|
||||
(self.lt.version, str(seeding), s.progress * 100, s.download_rate / 1000,
|
||||
print '[%s] %.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % \
|
||||
(self.lt.version, s.progress * 100, s.download_rate / 1000,
|
||||
s.upload_rate / 1000,
|
||||
s.num_peers, state_str[s.state])
|
||||
i = 0
|
||||
|
|
|
@ -213,6 +213,11 @@ dictionary = {
|
|||
'Pause':'Пауза',
|
||||
'Delete':'Удалить',
|
||||
'Open (no return)':'Открыть (без возврата)',
|
||||
'Torrent is seeding. To stop it use Download Status.':'Сидирование. Для остановки используйте Статус Загрузки.',
|
||||
'Start All':'Запустить Все',
|
||||
'Started All!':'Все Запущены!',
|
||||
'Stopped All!':'Все Остановлено!',
|
||||
'Stop All':'Остановить Все',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
52
Player.py
52
Player.py
|
@ -12,7 +12,7 @@ import Downloader
|
|||
import xbmcgui
|
||||
import xbmcvfs
|
||||
import Localization
|
||||
from functions import calculate, showMessage, clearStorage, tempdir
|
||||
from functions import calculate, showMessage, clearStorage, DownloadDB
|
||||
|
||||
|
||||
ROOT = sys.modules["__main__"].__root__
|
||||
|
@ -112,10 +112,13 @@ class TorrentPlayer(xbmc.Player):
|
|||
torrentFilesDirectory = 'torrents'
|
||||
debug = __settings__.getSetting('debug') == 'true'
|
||||
subs_dl = __settings__.getSetting('subs_dl') == 'true'
|
||||
seeding = __settings__.getSetting('keep_seeding') == 'true'
|
||||
seeding = __settings__.getSetting('keep_seeding') == 'true' and __settings__.getSetting('keep_files') == 'true'
|
||||
seeding_status=False
|
||||
seeding_run=False
|
||||
|
||||
def __init__(self, userStorageDirectory, torrentUrl, params={}):
|
||||
self.userStorageDirectory = userStorageDirectory
|
||||
self.torrentUrl=torrentUrl
|
||||
xbmc.Player.__init__(self)
|
||||
print ("[TorrentPlayer] Initalized")
|
||||
self.params = params
|
||||
|
@ -126,19 +129,19 @@ class TorrentPlayer(xbmc.Player):
|
|||
#print str(self.ids_video)
|
||||
except:
|
||||
self.ids_video = None
|
||||
self.torrent = Downloader.Torrent(self.userStorageDirectory, torrentUrl, self.torrentFilesDirectory).player
|
||||
self.torrent = Downloader.Torrent(self.userStorageDirectory, self.torrentUrl, self.torrentFilesDirectory).player
|
||||
self.init()
|
||||
self.setup_torrent()
|
||||
if self.buffer():
|
||||
while True:
|
||||
if self.setup_play():
|
||||
#print '************************************* GOING LOOP'
|
||||
self.torrent.continueSession(self.contentId, seeding=self.seeding)
|
||||
self.torrent.continueSession(self.contentId)
|
||||
self.loop()
|
||||
else:
|
||||
break
|
||||
#print '************************************* GO NEXT?'
|
||||
if self.next_dl and self.next_dling and self.next_contentId and self.iterator == 100:
|
||||
if self.next_dl and self.next_dling and (self.next_contentId or self.next_contentId==0) and self.iterator == 100:
|
||||
self.contentId = self.next_contentId
|
||||
continue
|
||||
#print '************************************* NO! break'
|
||||
|
@ -150,7 +153,12 @@ class TorrentPlayer(xbmc.Player):
|
|||
if 'false' == self.__settings__.getSetting("keep_files"):
|
||||
clearStorage(self.userStorageDirectory)
|
||||
else:
|
||||
showMessage(Localization.localize('Information'),
|
||||
if self.seeding_status:
|
||||
showMessage(Localization.localize('Information'),
|
||||
Localization.localize('Torrent is seeding. To stop it use Download Status.'), forced=True)
|
||||
else:
|
||||
if self.seeding: self.db_delete()
|
||||
showMessage(Localization.localize('Information'),
|
||||
Localization.localize('Torrent downloading is stopped.'), forced=True)
|
||||
|
||||
|
||||
|
@ -176,8 +184,7 @@ class TorrentPlayer(xbmc.Player):
|
|||
self.fullSize = self.torrent.getFileSize(self.contentId)
|
||||
Offset = calculate(self.fullSize)
|
||||
#print 'Offset: '+str(Offset)
|
||||
self.torrent.threadSeeding = self.seeding
|
||||
self.torrent.continueSession(self.contentId, Offset=Offset, seeding=self.seeding)
|
||||
self.torrent.continueSession(self.contentId, Offset=Offset)
|
||||
|
||||
def buffer(self):
|
||||
iterator = 0
|
||||
|
@ -258,6 +265,8 @@ class TorrentPlayer(xbmc.Player):
|
|||
self.iterator=0
|
||||
path = self.torrent.getFilePath(self.contentId)
|
||||
label = os.path.basename(path)
|
||||
self.basename=label
|
||||
self.seeding_run=False
|
||||
listitem = xbmcgui.ListItem(label, path=path)
|
||||
|
||||
if self.subs_dl:
|
||||
|
@ -346,16 +355,19 @@ class TorrentPlayer(xbmc.Player):
|
|||
overlay.text = "\n".join(self._get_status_lines(status))
|
||||
#downloadedSize = torrent.torrentHandle.file_progress()[contentId]
|
||||
self.iterator = int(status.progress * 100)
|
||||
if self.iterator == 100 and not self.next_dling and self.next_contentId:
|
||||
if not self.seeding_run and self.iterator == 100:
|
||||
self.seeding_run=True
|
||||
xbmc.sleep(1000)
|
||||
self.seed(self.contentId)
|
||||
self.seeding_status=True
|
||||
if self.iterator == 100 and not self.next_dling and (self.next_contentId or self.next_contentId==0):
|
||||
showMessage(Localization.localize('Torrent Downloading'),
|
||||
Localization.localize('Starting download next episode!'), forced=True)
|
||||
self.torrent.stopSession()
|
||||
xbmc.sleep(1000)
|
||||
self.torrent.threadSeeding = self.seeding
|
||||
self.torrent.continueSession(self.next_contentId, seeding=self.seeding)
|
||||
|
||||
path = self.torrent.getFilePath(self.next_contentId)
|
||||
self.display_name = os.path.basename(path)
|
||||
self.basename=self.display_name = os.path.basename(path)
|
||||
self.torrent.continueSession(self.next_contentId)
|
||||
self.next_dling = True
|
||||
xbmc.sleep(1000)
|
||||
|
||||
|
@ -367,3 +379,17 @@ class TorrentPlayer(xbmc.Player):
|
|||
s.upload_rate / 1000, Localization.localize('kb/s').decode('utf-8'),
|
||||
s.num_seeds, s.num_peers)
|
||||
]
|
||||
|
||||
def db_delete(self):
|
||||
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)
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.torrenter" name="Torrenter" version="2.1.0" provider-name="vadim.skorba, DiMartino">
|
||||
<addon id="plugin.video.torrenter" name="Torrenter" version="2.1.1" provider-name="vadim.skorba, DiMartino">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
<import addon="script.module.libtorrent"/>
|
||||
|
|
60
functions.py
60
functions.py
|
@ -854,16 +854,6 @@ class ListDB:
|
|||
self.db.commit()
|
||||
self._close()
|
||||
|
||||
def ClearCache(self, silent=False):
|
||||
self._connect()
|
||||
self.cur.execute('delete from cache')
|
||||
self.db.commit()
|
||||
self._close()
|
||||
if not silent:
|
||||
xbmcgui.Dialog().ok(__language__(30208), __language__(30236))
|
||||
ontop('update')
|
||||
xbmc.executebuiltin("Action(back)")
|
||||
|
||||
def get(self, addtime):
|
||||
self._connect()
|
||||
self.cur.execute('select info from list where addtime="' + addtime + '"')
|
||||
|
@ -945,26 +935,23 @@ class HistoryDB:
|
|||
self._connect()
|
||||
providers=self.get_providers(addtime)
|
||||
keys=Searchers().dic().keys()
|
||||
if searcher in providers:
|
||||
providers.remove(searcher)
|
||||
else:
|
||||
providers.append(searcher)
|
||||
for i in providers:
|
||||
if i not in keys:
|
||||
providers.remove(i)
|
||||
self.set_providers(addtime, providers)
|
||||
self.db.commit()
|
||||
self._close()
|
||||
if len(providers)>0:
|
||||
if searcher in providers:
|
||||
providers.remove(searcher)
|
||||
else:
|
||||
providers.append(searcher)
|
||||
for i in providers:
|
||||
if i not in keys:
|
||||
providers.remove(i)
|
||||
self.set_providers(addtime, providers)
|
||||
self.db.commit()
|
||||
self._close()
|
||||
|
||||
def add(self, url):
|
||||
try:
|
||||
url = url.decode('utf-8')
|
||||
except:
|
||||
pass
|
||||
if not self.get(url):
|
||||
self._connect()
|
||||
self.cur.execute('insert into history(addtime,string,fav,providers)'
|
||||
' values(?,?,?,?)', (int(time.time()), url, 0, ""))
|
||||
' values(?,?,?,?)', (int(time.time()), decode(url), 0, ""))
|
||||
self.db.commit()
|
||||
self._close()
|
||||
|
||||
|
@ -1542,11 +1529,20 @@ class DownloadDB:
|
|||
self.db.close()
|
||||
|
||||
def decode(string, ret=None):
|
||||
try:
|
||||
string = string.decode('utf-8')
|
||||
try:
|
||||
string = string.decode('utf-8')
|
||||
return string
|
||||
except:
|
||||
if ret:
|
||||
return ret
|
||||
else:
|
||||
return string
|
||||
except:
|
||||
if ret:
|
||||
return ret
|
||||
else:
|
||||
return string
|
||||
|
||||
def unquote(string, ret=None):
|
||||
try:
|
||||
return urllib.unquote_plus(string)
|
||||
except:
|
||||
if ret:
|
||||
return ret
|
||||
else:
|
||||
return string
|
|
@ -27,7 +27,7 @@
|
|||
<string id="30027">Normal (20s)</string>
|
||||
<string id="30028">Long (30s)</string>
|
||||
<string id="30029">Predownload subtitles from all folders</string>
|
||||
<string id="30030">Keep seeding until Kodi restart</string>
|
||||
<string id="30030">Keep seeding after watching</string>
|
||||
<string id="30031">Ask to change storage before play</string>
|
||||
<string id="30032">Delete Russian stuff</string>
|
||||
<string id="30033">Return Russian stuff</string>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<string id="30027">Среднее (20с)</string>
|
||||
<string id="30028">Долгое (30с)</string>
|
||||
<string id="30029">Предзакачать и подключить субтитры</string>
|
||||
<string id="30030">Сидировать до полного выключения Kodi</string>
|
||||
<string id="30030">Продолжать сидировать после просмотра</string>
|
||||
<string id="30031">Предлагать изменить место хранения</string>
|
||||
<string id="30032">Удалить русские трекеры</string>
|
||||
<string id="30033">Вернуть русские трекеры</string>
|
||||
|
|
|
@ -125,9 +125,8 @@
|
|||
id="keep_seeding"
|
||||
type="bool"
|
||||
label="30030"
|
||||
enable="false"
|
||||
default="false"
|
||||
visible="false"
|
||||
enable="eq(-7,true)"
|
||||
/>
|
||||
</category>
|
||||
<category label="Torrent-client">
|
||||
|
|
|
@ -11,11 +11,11 @@ import base64
|
|||
import mimetools
|
||||
import json
|
||||
import itertools
|
||||
from StringIO import StringIO
|
||||
import gzip
|
||||
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
import xbmcplugin
|
||||
import xbmcvfs
|
||||
|
||||
|
||||
|
@ -153,7 +153,12 @@ class HTTP:
|
|||
if self.request.download:
|
||||
self._download()
|
||||
else:
|
||||
self.response.body = self.con.read()
|
||||
if not self.response.headers.get('content-encoding')=='gzip':
|
||||
self.response.body = self.con.read()
|
||||
else:
|
||||
buf = StringIO(self.con.read())
|
||||
f = gzip.GzipFile(fileobj=buf)
|
||||
self.response.body = f.read()
|
||||
|
||||
if self.request.cookies:
|
||||
self.cookies.save(self.request.cookies)
|
||||
|
@ -826,6 +831,269 @@ class Transmission:
|
|||
return mapping[code]
|
||||
|
||||
|
||||
class Deluge:
|
||||
def config(self, login, password, host, port, url):
|
||||
self.login = login
|
||||
self.password = password
|
||||
|
||||
self.url = ['http://','https://'][int(url)] + host
|
||||
if port:
|
||||
self.url += ':' + str(port)
|
||||
|
||||
self.http = HTTP()
|
||||
|
||||
self.token = '0'
|
||||
|
||||
def list(self):
|
||||
obj = self.action({"method":"web.update_ui",
|
||||
"params":[["queue","name","total_wanted","state","progress",
|
||||
"num_seeds","total_seeds","num_peers","total_peers",
|
||||
"download_payload_rate","upload_payload_rate","eta",
|
||||
"ratio","distributed_copies","is_auto_managed",
|
||||
"time_added","tracker_host","save_path","total_done",
|
||||
"total_uploaded","max_download_speed","max_upload_speed",
|
||||
"seeds_peers_ratio"],{}],"id":1})
|
||||
if obj is None:
|
||||
return False
|
||||
|
||||
res = []
|
||||
if len(obj['result'].get('torrents'))>0:
|
||||
for k in obj['result'].get('torrents').keys():
|
||||
r=obj['result']['torrents'][k]
|
||||
res.append({
|
||||
'id': str(k),
|
||||
'status': self.get_status(r['state']),
|
||||
'name': r['name'],
|
||||
'size': r['total_wanted'],
|
||||
'progress': round(r['progress'], 2),
|
||||
'download': r['total_done'],
|
||||
'upload': r['total_uploaded'],
|
||||
'upspeed': r['upload_payload_rate'],
|
||||
'downspeed': r['download_payload_rate'],
|
||||
'ratio': round(r['ratio'], 2),
|
||||
'eta': r['eta'],
|
||||
'peer': r['total_peers'],
|
||||
'seed': r['num_seeds'],
|
||||
'leech': r['num_peers'],
|
||||
'add': r['time_added'],
|
||||
#'finish': r['doneDate'],
|
||||
'dir': r['save_path']
|
||||
})
|
||||
|
||||
'''if len(r['fileStats']) > 1:
|
||||
res.append({
|
||||
'id': str(r['id']),
|
||||
'status': self.get_status(r['status']),
|
||||
'name': r['name'],
|
||||
'size': r['totalSize'],
|
||||
'progress': 0 if not r['sizeWhenDone'] else int(
|
||||
100.0 * float(r['sizeWhenDone'] - r['leftUntilDone']) / float(r['sizeWhenDone'])),
|
||||
'download': r['downloadedEver'],
|
||||
'upload': r['uploadedEver'],
|
||||
'upspeed': r['rateUpload'],
|
||||
'downspeed': r['rateDownload'],
|
||||
'ratio': float(r['uploadRatio']),
|
||||
'eta': r['eta'],
|
||||
'peer': r['peersConnected'],
|
||||
'seed': r['peersSendingToUs'],
|
||||
'leech': r['peersGettingFromUs'],
|
||||
'add': r['addedDate'],
|
||||
'finish': r['doneDate'],
|
||||
'dir': os.path.join(r['downloadDir'], r['name'])
|
||||
})
|
||||
else:
|
||||
res.append({
|
||||
'id': str(r['id']),
|
||||
'status': self.get_status(r['status']),
|
||||
'name': r['name'],
|
||||
'size': r['totalSize'],
|
||||
'progress': 0 if not r['sizeWhenDone'] else int(
|
||||
100.0 * float(r['sizeWhenDone'] - r['leftUntilDone']) / float(r['sizeWhenDone'])),
|
||||
'download': r['downloadedEver'],
|
||||
'upload': r['uploadedEver'],
|
||||
'upspeed': r['rateUpload'],
|
||||
'downspeed': r['rateDownload'],
|
||||
'ratio': float(r['uploadRatio']),
|
||||
'eta': r['eta'],
|
||||
'peer': r['peersConnected'],
|
||||
'seed': r['peersSendingToUs'],
|
||||
'leech': r['peersGettingFromUs'],
|
||||
'add': r['addedDate'],
|
||||
'finish': r['doneDate'],
|
||||
'dir': r['downloadDir']
|
||||
})'''
|
||||
|
||||
return res
|
||||
|
||||
def listdirs(self):
|
||||
obj = self.action({'method': 'session-get'})
|
||||
if obj is None:
|
||||
return False
|
||||
|
||||
res = [obj['arguments'].get('download-dir')]
|
||||
# Debug('[Transmission][listdirs]: %s' % (str(res)))
|
||||
return res, res
|
||||
|
||||
def listfiles(self, id):
|
||||
obj = self.action({"method":"web.get_torrent_files","params":[id],"id":2})
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
print str(obj)
|
||||
|
||||
res = []
|
||||
i = -1
|
||||
obj=obj['result']
|
||||
|
||||
content=obj['contents']
|
||||
while content.get('contents'):
|
||||
for k in obj['contents'].keys():
|
||||
|
||||
res_new, i=self.contents(obj['contents'])
|
||||
res.extend(res_new)
|
||||
return res
|
||||
|
||||
def contents(self, contents={}, i=-1):
|
||||
res = []
|
||||
i = -1
|
||||
for k in contents.keys():
|
||||
x=contents[k]
|
||||
i += 1
|
||||
if x['size'] >= 1024 * 1024 * 1024:
|
||||
size = str(x['size'] / (1024 * 1024 * 1024)) + 'GB'
|
||||
elif x['size'] >= 1024 * 1024:
|
||||
size = str(x['size'] / (1024 * 1024)) + 'MB'
|
||||
elif x['size'] >= 1024:
|
||||
size = str(x['size'] / 1024) + 'KB'
|
||||
else:
|
||||
size = str(x['size']) + 'B'
|
||||
res.append([x['path'], round(x['progress'], 2), i, size])
|
||||
|
||||
return res, i
|
||||
|
||||
def add(self, torrent, dirname):
|
||||
if self.action({'method': 'torrent-add',
|
||||
'arguments': {'download-dir': dirname, 'metainfo': base64.b64encode(torrent)}}) is None:
|
||||
return None
|
||||
return True
|
||||
|
||||
def add_url(self, torrent, dirname):
|
||||
if self.action({'method': 'torrent-add', 'arguments': {'download-dir': dirname, 'filename': torrent}}) is None:
|
||||
return None
|
||||
return True
|
||||
|
||||
def delete(self, id):
|
||||
pass
|
||||
|
||||
def setprio(self, id, ind):
|
||||
obj = self.action({"method": "torrent-get", "arguments": {"fields": ["id", "fileStats", "files"],
|
||||
"ids": [int(id)]}})['arguments']['torrents'][0]
|
||||
if not obj or ind == None:
|
||||
return None
|
||||
|
||||
inds = []
|
||||
i = -1
|
||||
|
||||
for x in obj['fileStats']:
|
||||
i += 1
|
||||
if x['wanted'] == True and x['priority'] == 0:
|
||||
inds.append(i)
|
||||
|
||||
if len(inds) > 1: self.action(
|
||||
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
|
||||
|
||||
res = self.setprio_simple(id, '3', ind)
|
||||
|
||||
# self.action_simple('start',id)
|
||||
|
||||
return True if res else None
|
||||
|
||||
def setprio_simple(self, id, prio, ind):
|
||||
if ind == None:
|
||||
return None
|
||||
|
||||
res = None
|
||||
inds = [int(ind)]
|
||||
|
||||
if prio == '3':
|
||||
res = self.action(
|
||||
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-wanted": inds}})
|
||||
elif prio == '0':
|
||||
res = self.action({"method": "torrent-set",
|
||||
"arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
|
||||
|
||||
return True if res else None
|
||||
|
||||
def action(self, request):
|
||||
cookie = self.get_auth()
|
||||
if not cookie:
|
||||
return None
|
||||
|
||||
try:
|
||||
jsobj = json.dumps(request)
|
||||
except:
|
||||
return None
|
||||
else:
|
||||
|
||||
while True:
|
||||
# пробуем сделать запрос
|
||||
response = self.http.fetch(self.url + '/json', method='POST', params=jsobj,
|
||||
headers={'X-Requested-With': 'XMLHttpRequest', 'Cookie': cookie,
|
||||
'Content-Type': 'application/json; charset=UTF-8'})
|
||||
|
||||
if response.error:
|
||||
return None
|
||||
|
||||
else:
|
||||
try:
|
||||
obj = json.loads(response.body)
|
||||
except:
|
||||
return None
|
||||
else:
|
||||
return obj
|
||||
|
||||
def action_simple(self, action, id):
|
||||
actions = {'start': {"method": "torrent-start", "arguments": {"ids": [int(id)]}},
|
||||
'stop': {"method": "torrent-stop", "arguments": {"ids": [int(id)]}},
|
||||
'remove': {"method": "torrent-remove", "arguments": {"ids": [int(id)], "delete-local-data": False}},
|
||||
'removedata': {"method": "torrent-remove",
|
||||
"arguments": {"ids": [int(id)], "delete-local-data": True}}}
|
||||
obj = self.action(actions[action])
|
||||
return True if obj else None
|
||||
|
||||
def get_auth(self):
|
||||
params=json.dumps({"method":"auth.login","params":[self.password],"id":0})
|
||||
response = self.http.fetch(self.url + '/json', method='POST', params=params, gzip=True,
|
||||
headers={'X-Requested-With': 'XMLHttpRequest',
|
||||
'Content-Type': 'application/json; charset=UTF-8'})
|
||||
if response.error:
|
||||
return None
|
||||
|
||||
auth=json.loads(response.body)
|
||||
if auth["result"]==False:
|
||||
return False
|
||||
else:
|
||||
# _session_id=7167aae78e7cbdff694571f640ee2cd02351
|
||||
r = re.compile('_session_id=([^;]+);').search(response.headers.get('set-cookie', ''))
|
||||
if r:
|
||||
cookie = r.group(1).strip()
|
||||
return '_session_id=' + cookie
|
||||
|
||||
|
||||
|
||||
def get_status(self, code):
|
||||
mapping = {
|
||||
'Queued': 'stopped',
|
||||
'Error': 'check_pending',
|
||||
'Checking': 'checking',
|
||||
'Paused': 'download_pending',
|
||||
'Downloading': 'downloading',
|
||||
'Active': 'seed_pending',
|
||||
'Seeding': 'seeding'
|
||||
}
|
||||
return mapping[code]
|
||||
|
||||
|
||||
class Vuze:
|
||||
def config(self, login, password, host, port, url):
|
||||
self.login = login
|
||||
|
@ -996,6 +1264,9 @@ class Download():
|
|||
elif self.client == 'vuze':
|
||||
self.client = Vuze()
|
||||
|
||||
elif self.client == 'deluge':
|
||||
self.client = Deluge()
|
||||
|
||||
self.client.config(host=config['host'], port=config['port'], login=config['login'], password=config['password'],
|
||||
url=config['url'])
|
||||
# print(self.client.list())
|
||||
|
@ -1032,6 +1303,15 @@ class Download():
|
|||
'login': self.setting.getSetting("torrent_vuze_login"),
|
||||
'password': self.setting.getSetting("torrent_vuze_password")
|
||||
}
|
||||
elif client == '3':
|
||||
self.client = 'deluge'
|
||||
config = {
|
||||
'host': self.setting.getSetting("torrent_deluge_host"),
|
||||
'port': self.setting.getSetting("torrent_deluge_port"),
|
||||
'url': self.setting.getSetting("torrent_deluge_url"),
|
||||
'login': '',
|
||||
'password': self.setting.getSetting("torrent_deluge_password")
|
||||
}
|
||||
|
||||
return config
|
||||
|
||||
|
|
Loading…
Reference in New Issue