pull/1/head
DiMartinoXBMC 2015-01-15 22:53:23 +03:00
parent ff9644321e
commit fbaaf9e1e1
13 changed files with 218 additions and 325 deletions

74
Core.py
View File

@ -45,7 +45,7 @@ class Core:
debug = __settings__.getSetting('debug') == 'true' debug = __settings__.getSetting('debug') == 'true'
torrent_player=__settings__.getSetting("torrent_player") torrent_player=__settings__.getSetting("torrent_player")
history_bool = __settings__.getSetting('history') == 'true' history_bool = __settings__.getSetting('history') == 'true'
context_open = __settings__.getSetting('context_open') == 'true' open_option = int(__settings__.getSetting('open_option'))
language = {0: 'en', 1: 'ru'}.get(int(__settings__.getSetting("language"))) language = {0: 'en', 1: 'ru'}.get(int(__settings__.getSetting("language")))
htmlCodes = ( htmlCodes = (
('&', '&'), ('&', '&'),
@ -411,8 +411,9 @@ class Core:
self.drawItem(title, 'DownloadStatus', link, image=img, contextMenu=contextMenu, replaceMenu=False) self.drawItem(title, 'DownloadStatus', link, image=img, contextMenu=contextMenu, replaceMenu=False)
view_style('DownloadStatus') view_style('DownloadStatus')
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
xbmc.sleep(30000) #xbmc.sleep(30000)
xbmc.executebuiltin('Container.Refresh') #xbmc.executebuiltin('Container.Refresh')
return
def History(self, params={}): def History(self, params={}):
db = HistoryDB() db = HistoryDB()
@ -449,7 +450,7 @@ class Core:
items = db.get_all() items = db.get_all()
favlist = [(1, '[B]%s[/B]'), (0, '%s')] favlist = [(1, '[B]%s[/B]'), (0, '%s')]
if items: if items:
ListString = 'XBMC.RunPlugin(%s)' % (sys.argv[0] + '?action=History&action2=%s&%s=%s') ListString = 'XBMC.RunPlugin(%s)' % (sys.argv[0] + '?action=%s&action2=%s&%s=%s')
for favbool, bbstring in favlist: for favbool, bbstring in favlist:
for addtime, string, fav in items: for addtime, string, fav in items:
if favbool == int(fav): if favbool == int(fav):
@ -459,19 +460,21 @@ class Core:
contextMenu.append((self.localize('Individual Tracker Options'), contextMenu.append((self.localize('Individual Tracker Options'),
'XBMC.RunScript(%s)' % (os.path.join(ROOT, 'controlcenter.py,') + 'addtime=%s&title=%s' % (str(addtime), title)))) 'XBMC.RunScript(%s)' % (os.path.join(ROOT, 'controlcenter.py,') + 'addtime=%s&title=%s' % (str(addtime), title))))
contextMenu.append((self.localize('Keyboard'),
ListString % ('search', '&showKey=true', 'url', urllib.quote_plus(title))))
if int(fav) == 1: if int(fav) == 1:
contextMenu.append((self.localize('Delete from %s') % self.localize('Favourites SH'), contextMenu.append((self.localize('Delete from %s') % self.localize('Favourites SH'),
ListString % ('unfav', 'addtime', str(addtime)))) ListString % ('History', 'unfav', 'addtime', str(addtime))))
img = self.ROOT + '/icons/fav.png' img = self.ROOT + '/icons/fav.png'
else: else:
contextMenu.append((self.localize('Add to %s') % self.localize('Favourites SH'), contextMenu.append((self.localize('Add to %s') % self.localize('Favourites SH'),
ListString % ('fav', 'addtime', str(addtime)),)) ListString % ('History', 'fav', 'addtime', str(addtime)),))
img = self.ROOT + '/icons/unfav.png' img = self.ROOT + '/icons/unfav.png'
contextMenu.append((self.localize('Delete from %s') % self.localize('Search History'), contextMenu.append((self.localize('Delete from %s') % self.localize('Search History'),
ListString % ('delete', 'addtime', str(addtime)))) ListString % ('History', 'delete', 'addtime', str(addtime))))
link = {'url': title, 'addtime': str(addtime)} link = {'url': title, 'addtime': str(addtime)}
self.drawItem(bbstring % title, 'search', link, image=img, contextMenu=contextMenu) self.drawItem(bbstring % title, 'search', link, image=img, contextMenu=contextMenu, replaceMenu=False)
view_style('History') view_style('History')
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
@ -1068,7 +1071,7 @@ class Core:
menu.append((hash, action, str(ind))) menu.append((hash, action, str(ind)))
else: else:
menu.append((hash, action, str(ind))) menu.append((hash, action, str(ind)))
for hash, action, ind in menu: Download().setprio_simple(hash, action, ind) Download().setprio_simple_multi(menu)
return return
xbmc.executebuiltin('Container.Refresh') xbmc.executebuiltin('Container.Refresh')
return return
@ -1142,8 +1145,9 @@ class Core:
replaceMenu=True) replaceMenu=True)
view_style('uTorrentBrowser') view_style('uTorrentBrowser')
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
xbmc.sleep(30000) #xbmc.sleep(30000)
xbmc.executebuiltin('Container.Refresh') #xbmc.executebuiltin('Container.Refresh')
return
def clearStorage(self, params={}): def clearStorage(self, params={}):
clearStorage(self.userStorageDirectory) clearStorage(self.userStorageDirectory)
@ -1456,19 +1460,10 @@ class Core:
def showFilesList(self, filesList, params={}): #myshows def showFilesList(self, filesList, params={}): #myshows
get = params.get get = params.get
try: external = unquote(get("external"), None)
external = urllib.unquote_plus(get("external"))
except:
external = None
silent = get("silent") silent = get("silent")
try: thumbnail = unquote(get("thumbnail"),'')
thumbnail = urllib.unquote_plus(get("thumbnail")) save_folder = unquote(get("save_folder"),'')
except:
thumbnail = ''
try:
save_folder = urllib.unquote_plus(get("save_folder"))
except:
save_folder = ''
if external: if external:
try: try:
s = json.loads(json.loads(urllib.unquote_plus(get("sdata")))) s = json.loads(json.loads(urllib.unquote_plus(get("sdata"))))
@ -1493,7 +1488,14 @@ class Core:
return return
else: else:
for (order, seeds, leechers, size, title, link, image) in filesList: for (order, seeds, leechers, size, title, link, image) in filesList:
contextMenu = [ link_dict = {'url': link, 'thumbnail': thumbnail, 'save_folder':save_folder}
link_url=''
for key in link_dict.keys():
if link_dict.get(key):
link_url = '%s&%s=%s' % (link_url, key, urllib.quote_plus(link_dict.get(key)))
contextMenu = [(self.localize('Open (no return)'),
'XBMC.ActivateWindow(Videos,%s)' % ('%s?action=%s%s') % (
sys.argv[0], 'openTorrent', link_url)),
(myshows_lang(30409), (myshows_lang(30409),
'XBMC.RunPlugin(%s)' % ( 'XBMC.RunPlugin(%s)' % (
'plugin://plugin.video.myshows/?mode=3010&sort=activate&stringdata=' + urllib.quote_plus( 'plugin://plugin.video.myshows/?mode=3010&sort=activate&stringdata=' + urllib.quote_plus(
@ -1514,6 +1516,7 @@ class Core:
link_dict = {'url': link, 'thumbnail': thumbnail, 'save_folder':save_folder} link_dict = {'url': link, 'thumbnail': thumbnail, 'save_folder':save_folder}
link_url='' link_url=''
for key in link_dict.keys(): for key in link_dict.keys():
if link_dict.get(key):
link_url = '%s&%s=%s' % (link_url, key, urllib.quote_plus(link_dict.get(key))) link_url = '%s&%s=%s' % (link_url, key, urllib.quote_plus(link_dict.get(key)))
contextMenu = [ contextMenu = [
(self.localize('Open (no return)'), (self.localize('Open (no return)'),
@ -1528,16 +1531,21 @@ class Core:
] ]
title = self.titleMake(seeds, leechers, size, title) title = self.titleMake(seeds, leechers, size, title)
if self.context_open: if self.open_option==0:
self.drawItem(title, 'context', link, image, contextMenu=contextMenu, replaceMenu=False)
else:
self.drawItem(title, 'openTorrent', link_dict, image, contextMenu=contextMenu, replaceMenu=False) self.drawItem(title, 'openTorrent', link_dict, image, contextMenu=contextMenu, replaceMenu=False)
elif self.open_option==1:
self.drawItem(title, 'context', link, image, contextMenu=contextMenu, replaceMenu=False)
elif self.open_option==2:
self.drawItem(title, 'downloadFilesList', link_dict, image, contextMenu=contextMenu, replaceMenu=False)
elif self.open_option==3:
self.drawItem(title, 'downloadLibtorrent', link_dict, image, contextMenu=contextMenu, replaceMenu=False)
view_style('showFilesList') view_style('showFilesList')
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
def context(self, params={}): def context(self, params={}):
xbmc.executebuiltin("Action(ContextMenu)") xbmc.executebuiltin("Action(ContextMenu)")
sys.exit() return
def downloadFilesList(self, params={}): def downloadFilesList(self, params={}):
dirname = None dirname = None
@ -1549,7 +1557,7 @@ class Core:
if self.__settings__.getSetting("torrent_save") == '0': if self.__settings__.getSetting("torrent_save") == '0':
if items and clean: if items and clean:
if self.__settings__.getSetting("torrent") == '0': if self.__settings__.getSetting("torrent") in ['0','3']:
if len(items) > 1: if len(items) > 1:
dialog = xbmcgui.Dialog() dialog = xbmcgui.Dialog()
dirid = dialog.select(self.localize('Choose directory:'), items) dirid = dialog.select(self.localize('Choose directory:'), items)
@ -1557,7 +1565,7 @@ class Core:
dirid = 0 dirid = 0
if dirid == -1: return if dirid == -1: return
dirname = clean[dirid] dirname = clean[dirid]
if self.__settings__.getSetting("torrent") == '1': if self.__settings__.getSetting("torrent") in ['1','2']:
default = self.__settings__.getSetting("torrent_dir") default = self.__settings__.getSetting("torrent_dir")
keyboard = xbmc.Keyboard(default, self.localize('Save to path') + ':') keyboard = xbmc.Keyboard(default, self.localize('Save to path') + ':')
keyboard.doModal() keyboard.doModal()
@ -1606,6 +1614,7 @@ class Core:
f = open(url, 'rb') f = open(url, 'rb')
torrent = f.read() torrent = f.read()
f.close()
success = Download().add(torrent, dirname) success = Download().add(torrent, dirname)
if success and ind: if success and ind:
id = self.chooseHASH()[0] id = self.chooseHASH()[0]
@ -1645,6 +1654,7 @@ class Core:
int(self.__settings__.getSetting("download_limit")) * 1000000 / 8) #MBits/second int(self.__settings__.getSetting("download_limit")) * 1000000 / 8) #MBits/second
torrent.downloadProcess(ind) torrent.downloadProcess(ind)
showMessage(self.localize('Download Status'), self.localize('Added!')) showMessage(self.localize('Download Status'), self.localize('Added!'))
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True)
def titleMake(self, seeds, leechers, size, title): def titleMake(self, seeds, leechers, size, title):
@ -1672,9 +1682,13 @@ class Core:
showKey = myshows_setting.getSetting("torrenter_keyboard") showKey = myshows_setting.getSetting("torrenter_keyboard")
except: except:
showKey = None showKey = None
if params.get('showKey'): showKey=params.get('showKey')
if showKey == "true" or defaultKeyword == '' or not defaultKeyword: if showKey == "true" or defaultKeyword == '' or not defaultKeyword:
if not defaultKeyword: if not defaultKeyword:
defaultKeyword = '' defaultKeyword = ''
defaultKeyword=unquote(defaultKeyword)
keyboard = xbmc.Keyboard(defaultKeyword, self.localize('Search Phrase') + ':') keyboard = xbmc.Keyboard(defaultKeyword, self.localize('Search Phrase') + ':')
keyboard.doModal() keyboard.doModal()
query = keyboard.getText() query = keyboard.getText()

View File

@ -218,6 +218,7 @@ dictionary = {
'Started All!':'Все Запущены!', 'Started All!':'Все Запущены!',
'Stopped All!':'Все Остановлено!', 'Stopped All!':'Все Остановлено!',
'Stop All':'Остановить Все', 'Stop All':'Остановить Все',
'Keyboard':'Клавиатура',
} }
} }

View File

@ -355,7 +355,7 @@ class TorrentPlayer(xbmc.Player):
overlay.text = "\n".join(self._get_status_lines(status)) overlay.text = "\n".join(self._get_status_lines(status))
#downloadedSize = torrent.torrentHandle.file_progress()[contentId] #downloadedSize = torrent.torrentHandle.file_progress()[contentId]
self.iterator = int(status.progress * 100) self.iterator = int(status.progress * 100)
if not self.seeding_run and self.iterator == 100: if not self.seeding_run and self.iterator == 100 and self.seeding:
self.seeding_run=True self.seeding_run=True
xbmc.sleep(1000) xbmc.sleep(1000)
self.seed(self.contentId) self.seed(self.contentId)

View File

@ -1,80 +0,0 @@
import socket
import thread
import re
import os
class Proxier:
HOST = '127.0.0.1'
PORT = 51515
PATH = ''
CHUNK_SIZE = 1024
seekBytes = 0
buffering = 0
def server(self, path):
self.PATH = path
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.settimeout(600)
s.bind((self.HOST, self.PORT))
s.listen(1)
while True:
conn, addr = s.accept()
conn.setblocking(1)
data = conn.recv(1024)
range = re.compile('Range: bytes=(\d+)-(\d*)')
size = os.path.getsize(self.PATH)
byte1, byte2 = 0, None
if range.search(data):
g = range.search(data).groups()
if g[0]: byte1 = int(g[0])
if g[1]: byte2 = int(g[1])
length = size - byte1
if byte2 is not None:
length = byte2 - byte1
thread.start_new_thread(self.streamer, (conn, byte1, byte2, length, size, ))
def streamer(self, conn, byte1, byte2, length, size):
send = ''
if byte1 > 0 or byte2 != None:
send = send + "HTTP/1.1 206 Partial Content"
send = send + "\r\n"
send = send + "Content-Range: %s-%s/%s" % (str(byte1), str(byte1 + length - 1), str(size))
send = send + "\r\n"
self.seekBytes = byte1
else:
send = send + "HTTP/1.1 200 OK"
send = send + "\r\n"
send = send + "Content-Type: video/mp4"
send = send + "\r\n"
send = send + "Content-Length: " + str(length)
send = send + "\r\n"
send = send + "Accept-Ranges: bytes"
send = send + "\r\n"
send = send + "Connection: close"
send = send + "\r\n"
send = send + "\r\n"
conn.send(send)
fp = open(self.PATH, "rb")
fp.seek(byte1)
sent = 0
while length > sent:
chunk = fp.read(self.CHUNK_SIZE)
if chunk:
self.buffering = 0
try:
sent = sent + conn.send(chunk)
except socket.error, e:
conn.close()
break
else:
self.buffering = self.buffering + 1
time.sleep(1)
if self.buffering > 60:
break
fp.close()
conn.close()

View File

@ -1,66 +0,0 @@
# -*- coding: utf-8 -*-
'''
Torrenter plugin for XBMC
Copyright (C) 2012 Vadim Skorba
vadim.skorba@gmail.com
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 <http://www.gnu.org/licenses/>.
'''
import sys
import xbmcgui
import Localization
class Rates(xbmcgui.Window):
buttonWidth = 250
buttonHeight = 250
width = 1280
height = 720
rate = 0
def __init__(self, *kargs):
noFocus = sys.modules["__main__"].__root__ + '/icons/bookmarks.png'
focus = sys.modules["__main__"].__root__ + '/icons/add_bookmark.png'
self.addControl(xbmcgui.ControlLabel(0, self.height / 4, self.width, 100,
Localization.localize('Please, rate watched video:'), alignment=6))
self.bad = xbmcgui.ControlButton(self.buttonWidth / 2, self.height / 2, self.buttonWidth, self.buttonHeight,
Localization.localize('Bad'), alignment=6, textColor='0xFFCC3333',
focusedColor='0xFFFF0000', focusTexture=focus, noFocusTexture=noFocus,
shadowColor='0xFF000000')
self.normal = xbmcgui.ControlButton(self.width / 2 - self.buttonWidth / 2, self.height / 2, self.buttonWidth,
self.buttonHeight, Localization.localize('So-So'), alignment=6,
textColor='0xFFCCCC33', focusedColor='0xFFFFFF00', focusTexture=focus,
noFocusTexture=noFocus, shadowColor='0xFF000000')
self.good = xbmcgui.ControlButton(self.width - self.buttonWidth * 3 / 2, self.height / 2, self.buttonWidth,
self.buttonHeight, Localization.localize('Good'), alignment=6,
textColor='0xFF33CC33', focusedColor='0xFF00FF00', focusTexture=focus,
noFocusTexture=noFocus, shadowColor='0xFF000000')
self.addControl(self.bad)
self.addControl(self.normal)
self.addControl(self.good)
self.bad.setNavigation(self.bad, self.bad, self.bad, self.normal)
self.normal.setNavigation(self.normal, self.normal, self.bad, self.good)
self.good.setNavigation(self.good, self.good, self.normal, self.good)
self.setFocus(self.normal)
def onControl(self, control):
if control == self.bad:
self.rate = -1
if control == self.normal:
self.rate = 0
if control == self.good:
self.rate = 1
self.close()

View File

@ -1,5 +1,5 @@
<?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.1.1" provider-name="vadim.skorba, DiMartino"> <addon id="plugin.video.torrenter" name="Torrenter" version="2.1.3" 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"/>

14
cal.py

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,12 @@
[B]Version 2.1.0[/B] [B]Version 2.1.2[/B]
[+] Торрент-клиент: Поддержка Deluge WebUI (No SSL)
[+] История Поиска: Возможность изменять с помощью клавиатуры
[+] Поиска: Настройка выбора действия вместо Открытия торрента
[B]Version 2.1.1[/B]
[+] Проигрыватель: Опция продолжать сидировать после просмотра
[B]Version 2.1.0[/B]
[+] Загрузка: Добавлена возможность управлять закачками, а так же возобновлять [+] Загрузка: Добавлена возможность управлять закачками, а так же возобновлять
[+] Поиск: Возможность замены открытия торрента на вызов контекстного меню [+] Поиск: Возможность замены открытия торрента на вызов контекстного меню
@ -41,7 +49,7 @@
[+] Rutor, OpenSharing, OldPirateBay переведены на .torrent с магнит-ссылок [+] Rutor, OpenSharing, OldPirateBay переведены на .torrent с магнит-ссылок
[B]Version 2.0.2[/B] [B]Version 2.0.2[/B]
[+] Отображение статуса загрузки при паузе [+] Проигрыватель: Отображение статуса загрузки при паузе
[B]Version 2.0.1[/B] [B]Version 2.0.1[/B]
[+] Увеличен буфер для файлов более 1 ГБ [+] Увеличен буфер для файлов более 1 ГБ

View File

@ -1071,7 +1071,7 @@ class Contenters():
pass pass
def first_time(self, scrapperDB_ver, language='ru'): def first_time(self, scrapperDB_ver, language='ru'):
searcher = 'metadata'+language searcher = 'metadata'
redl = False redl = False
scrapperDB_ver=scrapperDB_ver[language] scrapperDB_ver=scrapperDB_ver[language]
if scrapperDB_ver != __settings__.getSetting('scrapperDB_ver'+language) and self.getBoolSetting(searcher): if scrapperDB_ver != __settings__.getSetting('scrapperDB_ver'+language) and self.getBoolSetting(searcher):
@ -1092,8 +1092,8 @@ class Contenters():
Localization.localize( Localization.localize(
'You can always restart this by deleting DBs via Context Menu'), ) 'You can always restart this by deleting DBs via Context Menu'), )
if not self.getBoolSetting('oldc_' + searcher): if not self.getBoolSetting('oldc_' + searcher + language):
self.setBoolSetting('oldc_' + searcher, True) self.setBoolSetting('oldc_' + searcher+ language, True)
__settings__.setSetting('scrapperDB_ver'+language, scrapperDB_ver) __settings__.setSetting('scrapperDB_ver'+language, scrapperDB_ver)
ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Content Lists'), ok = xbmcgui.Dialog().yesno('< %s >' % Localization.localize('Content Lists'),
Localization.localize('Do you want to search and cache full metadata + arts?'), Localization.localize('Do you want to search and cache full metadata + arts?'),

View File

@ -31,7 +31,11 @@
<string id="30031">Ask to change storage before play</string> <string id="30031">Ask to change storage before play</string>
<string id="30032">Delete Russian stuff</string> <string id="30032">Delete Russian stuff</string>
<string id="30033">Return Russian stuff</string> <string id="30033">Return Russian stuff</string>
<string id="30034">Open context menu instead of torrent</string> <string id="30034">Action onClick for torrent</string>
<string id="30035">Open Torrent File</string>
<string id="30036">Open Context Menu</string>
<string id="30037">Download via Torrent-client</string>
<string id="30038">Download via Python-Libtorrent (Download Status)</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>

View File

@ -31,7 +31,11 @@
<string id="30031">Предлагать изменить место хранения</string> <string id="30031">Предлагать изменить место хранения</string>
<string id="30032">Удалить русские трекеры</string> <string id="30032">Удалить русские трекеры</string>
<string id="30033">Вернуть русские трекеры</string> <string id="30033">Вернуть русские трекеры</string>
<string id="30034">Открывать контекстное меню вместо торрента</string> <string id="30034">Действие при нажатии на торрент</string>
<string id="30035">Открыть Торрент Файл</string>
<string id="30036">Открыть Контекстное меню</string>
<string id="30037">Скачать Торрент-клиентом</string>
<string id="30038">Скачать Python-Libtorrent</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

@ -27,10 +27,11 @@
default="1" default="1"
/> />
<setting <setting
id="context_open" id="open_option"
type="bool" type="enum"
label="30034" label="30034"
default="false" lvalues="30035|30036|30037|30038"
default="0"
/> />
</category> </category>
<category label="30103"> <category label="30103">
@ -134,7 +135,7 @@
<setting id="torrent_dir" type="text" label="50304"/> <setting id="torrent_dir" type="text" label="50304"/>
<setting id="torrent_replacement" type="folder" label="30426"/> <setting id="torrent_replacement" type="folder" label="30426"/>
<setting type="sep"/> <setting type="sep"/>
<setting id="torrent" type="enum" label="50311" values="µTorrent|Transmission|Vuze (XML over HTTP plugin)" <setting id="torrent" type="enum" label="50311" values="µTorrent WebUI|Transmission|Vuze (XML over HTTP plugin)|Deluge WebUI"
default="0"/> default="0"/>
<setting id="torrent_utorrent_host" type="ipaddress" label="50312" visible="eq(-1,0)" default="127.0.0.1"/> <setting id="torrent_utorrent_host" type="ipaddress" label="50312" visible="eq(-1,0)" default="127.0.0.1"/>
<setting id="torrent_utorrent_port" type="number" label="50313" visible="eq(-2,0)" default="8080"/> <setting id="torrent_utorrent_port" type="number" label="50313" visible="eq(-2,0)" default="8080"/>
@ -151,5 +152,9 @@
<setting id="torrent_vuze_port" type="number" label="50313" visible="eq(-11,2)" default="6884"/> <setting id="torrent_vuze_port" type="number" label="50313" visible="eq(-11,2)" default="6884"/>
<setting id="torrent_vuze_login" type="text" label="50315" visible="eq(-12,2)" default=""/> <setting id="torrent_vuze_login" type="text" label="50315" visible="eq(-12,2)" default=""/>
<setting id="torrent_vuze_password" type="text" label="50316" visible="eq(-13,2)" default="" option="hidden"/> <setting id="torrent_vuze_password" type="text" label="50316" visible="eq(-13,2)" default="" option="hidden"/>
<setting id="torrent_deluge_host" type="ipaddress" label="50312" visible="eq(-14,3)" default="127.0.0.1"/>
<setting id="torrent_deluge_url" type="enum" label="50314" visible="eq(-15,3)" values="http:// (only No SSL)" default="0"/>
<setting id="torrent_deluge_port" type="number" label="50313" visible="eq(-16,3)" default="8112"/>
<setting id="torrent_deluge_password" type="text" label="50316" visible="eq(-17,3)" default="deluge" option="hidden"/>
</category> </category>
</settings> </settings>

View File

@ -459,6 +459,10 @@ class UTorrent:
return True if obj else None return True if obj else None
def setprio_simple_multi(self, menu):
for hash, action, ind in menu:
self.setprio_simple(hash, action, ind)
def delete(self, id): def delete(self, id):
pass pass
@ -751,6 +755,22 @@ class Transmission:
return True if res else None return True if res else None
def setprio_simple_multi(self, menu):
id=menu[0][0]
prio=menu[0][1]
inds=[]
for hash, action, ind in menu:
inds.append(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): def action(self, request):
try: try:
jsobj = json.dumps(request) jsobj = json.dumps(request)
@ -842,17 +862,13 @@ class Deluge:
self.http = HTTP() self.http = HTTP()
self.token = '0' def get_info(self):
obj = self.action({"method":"web.update_ui",
"params":[[],{}],"id":1})
return obj
def list(self): def list(self):
obj = self.action({"method":"web.update_ui", obj=self.get_info()
"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: if obj is None:
return False return False
@ -860,7 +876,7 @@ class Deluge:
if len(obj['result'].get('torrents'))>0: if len(obj['result'].get('torrents'))>0:
for k in obj['result'].get('torrents').keys(): for k in obj['result'].get('torrents').keys():
r=obj['result']['torrents'][k] r=obj['result']['torrents'][k]
res.append({ add={
'id': str(k), 'id': str(k),
'status': self.get_status(r['state']), 'status': self.get_status(r['state']),
'name': r['name'], 'name': r['name'],
@ -876,89 +892,34 @@ class Deluge:
'seed': r['num_seeds'], 'seed': r['num_seeds'],
'leech': r['num_peers'], 'leech': r['num_peers'],
'add': r['time_added'], 'add': r['time_added'],
#'finish': r['doneDate'],
'dir': r['save_path'] 'dir': r['save_path']
}) }
if len(r['files'])>1: add['dir']=os.path.join(r['save_path'],r['name'])
'''if len(r['fileStats']) > 1: res.append(add)
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 return res
def listdirs(self): def listdirs(self):
obj = self.action({'method': 'session-get'}) obj = self.action({"method":"core.get_config","params":[],"id":5})
if obj is None: if obj is None:
return False return False
res = [obj['arguments'].get('download-dir')] res = [obj['result'].get('download_location')]
# Debug('[Transmission][listdirs]: %s' % (str(res)))
return res, res return res, res
def listfiles(self, id): def listfiles(self, id):
obj = self.action({"method":"web.get_torrent_files","params":[id],"id":2}) obj = self.get_info()
if obj is None: if obj is None:
return None return None
print str(obj)
res = [] res = []
i = -1 obj=obj['result']['torrents'][id]
obj=obj['result'] #print str(obj)
if len(obj['files'])==1:
strip_path=None
else:
strip_path=obj['name']
content=obj['contents'] for x in obj['files']:
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: if x['size'] >= 1024 * 1024 * 1024:
size = str(x['size'] / (1024 * 1024 * 1024)) + 'GB' size = str(x['size'] / (1024 * 1024 * 1024)) + 'GB'
elif x['size'] >= 1024 * 1024: elif x['size'] >= 1024 * 1024:
@ -967,18 +928,41 @@ class Deluge:
size = str(x['size'] / 1024) + 'KB' size = str(x['size'] / 1024) + 'KB'
else: else:
size = str(x['size']) + 'B' size = str(x['size']) + 'B'
res.append([x['path'], round(x['progress'], 2), i, size]) if strip_path:
path=x['path'].lstrip(strip_path).lstrip('/')
else:
path=x['path']
return res, i if x.get('progress'):
percent=int(x['progress']*100)
else:percent=0
res.append([path, percent, x['index'], size])
return res
def get_prio(self, id):
obj = self.get_info()
if obj is None:
return None
res=obj['result']['torrents'][id]['file_priorities']
return res
def add(self, torrent, dirname): def add(self, torrent, dirname):
if self.action({'method': 'torrent-add', torrentFile=os.path.join(self.http._dirname,'deluge.torrent')
'arguments': {'download-dir': dirname, 'metainfo': base64.b64encode(torrent)}}) is None: if self.action({'method': 'core.add_torrent_file',
'params': [torrentFile,
base64.b64encode(torrent), {"download_path": dirname}],"id":3}) is None:
return None return None
return True return True
def add_url(self, torrent, dirname): def add_url(self, torrent, dirname):
if self.action({'method': 'torrent-add', 'arguments': {'download-dir': dirname, 'filename': torrent}}) is None: if re.match("^magnet\:.+$", torrent):
if self.action({'method': 'core.add_torrent_magnet', 'params':[torrent,
{'download_path': dirname}],"id":3}) is None:
return None
else:
if self.action({"method": "core.add_torrent_url", "params":[torrent, {'download_path': dirname}],"id":3}) is None:
return None return None
return True return True
@ -986,43 +970,50 @@ class Deluge:
pass pass
def setprio(self, id, ind): def setprio(self, id, ind):
obj = self.action({"method": "torrent-get", "arguments": {"fields": ["id", "fileStats", "files"], i = -1
"ids": [int(id)]}})['arguments']['torrents'][0] prios=self.get_prio(id)
if not obj or ind == None:
for p in prios:
i=i+1
if p==1:
prios.pop(i)
prios.insert(i,0)
prios.pop(int(ind))
prios.insert(int(ind),7)
if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
return None return None
inds = [] return True
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): def setprio_simple(self, id, prio, ind):
if ind == None: prios=self.get_prio(id)
return None
res = None
inds = [int(ind)]
if ind!=None:
prios.pop(int(ind))
if prio == '3': if prio == '3':
res = self.action( prios.insert(int(ind),7)
{"method": "torrent-set", "arguments": {"ids": [int(id)], "priority-high": inds, "files-wanted": inds}})
elif prio == '0': elif prio == '0':
res = self.action({"method": "torrent-set", prios.insert(int(ind),0)
"arguments": {"ids": [int(id)], "priority-high": inds, "files-unwanted": inds}})
return True if res else None if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
return None
return True
def setprio_simple_multi(self, menu):
id=menu[0][0]
prios=self.get_prio(id)
for hash, action, ind in menu:
prios.pop(int(ind))
if action == '3':
prios.insert(int(ind),7)
elif action == '0':
prios.insert(int(ind),0)
if self.action({"method": "core.set_torrent_file_priorities", "params":[id, prios],"id":6}) is None:
return None
def action(self, request): def action(self, request):
cookie = self.get_auth() cookie = self.get_auth()
@ -1034,9 +1025,6 @@ class Deluge:
except: except:
return None return None
else: else:
while True:
# пробуем сделать запрос
response = self.http.fetch(self.url + '/json', method='POST', params=jsobj, response = self.http.fetch(self.url + '/json', method='POST', params=jsobj,
headers={'X-Requested-With': 'XMLHttpRequest', 'Cookie': cookie, headers={'X-Requested-With': 'XMLHttpRequest', 'Cookie': cookie,
'Content-Type': 'application/json; charset=UTF-8'}) 'Content-Type': 'application/json; charset=UTF-8'})
@ -1053,11 +1041,10 @@ class Deluge:
return obj return obj
def action_simple(self, action, id): def action_simple(self, action, id):
actions = {'start': {"method": "torrent-start", "arguments": {"ids": [int(id)]}}, actions = {'start': {"method":"core.resume_torrent","params":[[id]],"id":4},
'stop': {"method": "torrent-stop", "arguments": {"ids": [int(id)]}}, 'stop': {"method":"core.pause_torrent","params":[[id]],"id":4},
'remove': {"method": "torrent-remove", "arguments": {"ids": [int(id)], "delete-local-data": False}}, 'remove': {"method":"core.remove_torrent","params":[id, False],"id":4},
'removedata': {"method": "torrent-remove", 'removedata': {"method":"core.remove_torrent", "params":[id, True],"id":4}}
"arguments": {"ids": [int(id)], "delete-local-data": True}}}
obj = self.action(actions[action]) obj = self.action(actions[action])
return True if obj else None return True if obj else None
@ -1073,20 +1060,17 @@ class Deluge:
if auth["result"]==False: if auth["result"]==False:
return False return False
else: else:
# _session_id=7167aae78e7cbdff694571f640ee2cd02351
r = re.compile('_session_id=([^;]+);').search(response.headers.get('set-cookie', '')) r = re.compile('_session_id=([^;]+);').search(response.headers.get('set-cookie', ''))
if r: if r:
cookie = r.group(1).strip() cookie = r.group(1).strip()
return '_session_id=' + cookie return '_session_id=' + cookie
def get_status(self, code): def get_status(self, code):
mapping = { mapping = {
'Queued': 'stopped', 'Queued': 'stopped',
'Error': 'check_pending', 'Error': 'stopped',
'Checking': 'checking', 'Checking': 'checking',
'Paused': 'download_pending', 'Paused': 'seed_pending',
'Downloading': 'downloading', 'Downloading': 'downloading',
'Active': 'seed_pending', 'Active': 'seed_pending',
'Seeding': 'seeding' 'Seeding': 'seeding'
@ -1228,6 +1212,10 @@ class Vuze:
time.sleep(0.1) time.sleep(0.1)
return True if obj else None return True if obj else None
def setprio_simple_multi(self, menu):
for hash, action, ind in menu:
self.setprio_simple(hash, action, ind)
def action_simple(self, action, id): def action_simple(self, action, id):
torrent = self.downloads[int(id)] torrent = self.downloads[int(id)]
obj = None obj = None
@ -1340,5 +1328,8 @@ class Download():
# Debug('[setprio_simple] '+str((id, prio, ind))) # Debug('[setprio_simple] '+str((id, prio, ind)))
return self.client.setprio_simple(id, prio, ind) return self.client.setprio_simple(id, prio, ind)
def setprio_simple_multi(self, prio_list):
return self.client.setprio_simple_multi(prio_list)
def action_simple(self, action, id): def action_simple(self, action, id):
return self.client.action_simple(action, id) return self.client.action_simple(action, id)