diff --git a/addon.xml b/addon.xml
index d67e56d..39c9855 100644
--- a/addon.xml
+++ b/addon.xml
@@ -1,18 +1,25 @@
-
-
-
-
-
- Kodi / XBMC BSPlayer Subtitles allows for downloading subtitles from the bsplayer subtitles community.
- Search and download various subtitles from the bsplayer subtitles community.
-
- realgam3@gmail.com
- GNU GENERAL PUBLIC LICENSE. Version 2, June 1991
-
+
+
+
+
+
+
+ BSPlayer Subtitles
+
+
+ Search and download various subtitles from the BSPlayer subtitles community.
+
+
+ realgam3@gmail.com
+ GNU GENERAL PUBLIC LICENSE. Version 2, June 1991
+ all
+
+ logo.png
+
+
\ No newline at end of file
diff --git a/changelog.txt b/changelog.txt
index bfa041b..bab6f09 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,6 @@
+0.3.0 - 15/05/2022
+- Migrating to python 3, support kodi 19
+
0.2.1 - 07/11/2015
- Fixed android non rar support, rearrange code
diff --git a/resources/__init__.py b/resources/__init__.py
index b93054b..e69de29 100644
--- a/resources/__init__.py
+++ b/resources/__init__.py
@@ -1 +0,0 @@
-# Dummy file to make this directory a package.
diff --git a/resources/lib/bsplayer.py b/resources/lib/bsplayer.py
index 6052322..3042c24 100644
--- a/resources/lib/bsplayer.py
+++ b/resources/lib/bsplayer.py
@@ -1,26 +1,24 @@
import gzip
+import socket
import random
from time import sleep
-from StringIO import StringIO
from xml.etree import ElementTree
+from urllib.request import Request
-from utils import movie_size_and_hash, get_session, log
-
-# s1-9, s101-109
-SUB_DOMAINS = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9',
- 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109']
-API_URL_TEMPLATE = "http://{sub_domain}.api.bsplayer-subtitles.com/v1.php"
-
-
-def get_sub_domain():
- sub_domains_end = len(SUB_DOMAINS) - 1
- return API_URL_TEMPLATE.format(sub_domain=SUB_DOMAINS[random.randint(0, sub_domains_end)])
+from .utils import movie_size_and_hash, get_session, log
class BSPlayer(object):
+ VERSION = "2.67"
+ DOMAIN = "api.bsplayer-subtitles.com"
+ SUB_DOMAINS = [
+ 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8',
+ 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109'
+ ]
+
def __init__(self, search_url=None, proxies=None):
self.session = get_session(proxies=proxies)
- self.search_url = search_url or get_sub_domain()
+ self.search_url = search_url or self.get_sub_domain()
self.token = None
def __enter__(self):
@@ -30,33 +28,43 @@ def __enter__(self):
def __exit__(self, exc_type, exc_val, exc_tb):
return self.logout()
+ def get_sub_domain(self, tries=5):
+ for t in range(tries):
+ domain = f"{random.choice(self.SUB_DOMAINS)}.{self.DOMAIN}"
+ try:
+ socket.gethostbyname(domain)
+ return f"http://{domain}/v1.php"
+ except socket.gaierror:
+ continue
+ raise Exception("API Domain not found")
+
def api_request(self, func_name='logIn', params='', tries=5):
headers = {
'User-Agent': 'BSPlayer/2.x (1022.12360)',
'Content-Type': 'text/xml; charset=utf-8',
'Connection': 'close',
- 'SOAPAction': '"http://api.bsplayer-subtitles.com/v1.php#{func_name}"'.format(func_name=func_name)
+ 'SOAPAction': f'"http://{self.DOMAIN}/v1.php#{func_name}"'
}
data = (
'\n'
''
+ f'xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="{self.search_url}">'
''
- '{params}'
- ).format(search_url=self.search_url, func_name=func_name, params=params)
+ f'{params}'
+ )
log('BSPlayer.api_request', 'Sending request: %s.' % func_name)
- for i in xrange(tries):
+ for i in range(tries):
try:
- self.session.addheaders.extend(headers.items())
- res = self.session.open(self.search_url, data)
+ req = Request(self.search_url, data=data.encode(), headers=headers, method="POST")
+ res = self.session.open(req)
return ElementTree.fromstring(res.read())
- except Exception, ex:
+ except Exception as ex:
log("BSPlayer.api_request", "ERROR: %s." % ex)
if func_name == 'logIn':
- self.search_url = get_sub_domain()
+ self.search_url = self.get_sub_domain()
sleep(1)
log('BSPlayer.api_request', 'ERROR: Too many tries (%d)...' % tries)
raise Exception('Too many tries...')
@@ -68,9 +76,11 @@ def login(self):
root = self.api_request(
func_name='logIn',
- params=(''
- ''
- 'BSPlayer v2.67')
+ params=(
+ ''
+ ''
+ f'BSPlayer v{self.VERSION}'
+ )
)
res = root.find('.//return')
if res.find('status').text == 'OK':
@@ -86,7 +96,7 @@ def logout(self):
root = self.api_request(
func_name='logOut',
- params='{token}'.format(token=self.token)
+ params=f'{self.token}'
)
res = root.find('.//return')
self.token = None
@@ -102,18 +112,21 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
if isinstance(language_ids, (tuple, list, set)):
language_ids = ",".join(language_ids)
- movie_size, movie_hash = movie_size_and_hash(movie_path)
- log('BSPlayer.search_subtitles', 'Movie Size: %s, Movie Hash: %s.' % (movie_size, movie_hash))
+ try:
+ movie_size, movie_hash = movie_size_and_hash(movie_path)
+ except Exception as ex:
+ print(ex)
+ exit(1)
+ log('BSPlayer.search_subtitles', f'Movie Size: {movie_size}, Movie Hash: {movie_hash}.')
root = self.api_request(
func_name='searchSubtitles',
params=(
- '{token}'
- '{movie_hash}'
- '{movie_size}'
- '{language_ids}'
+ f'{self.token}'
+ f'{movie_hash}'
+ f'{movie_size}'
+ f'{language_ids}'
'*'
- ).format(token=self.token, movie_hash=movie_hash,
- movie_size=movie_size, language_ids=language_ids)
+ )
)
res = root.find('.//return/result')
if res.find('status').text != 'OK':
@@ -129,7 +142,8 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
subDownloadLink=item.find('subDownloadLink').text,
subLang=item.find('subLang').text,
subName=item.find('subName').text,
- subFormat=item.find('subFormat').text
+ subFormat=item.find('subFormat').text,
+ subRating=item.find('subRating').text or '0'
))
if logout:
@@ -141,10 +155,10 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
def download_subtitles(download_url, dest_path, proxies=None):
session = get_session(proxies=proxies, http_10=True)
session.addheaders = [('User-Agent', 'Mozilla/4.0 (compatible; Synapse)'),
- ('Content-Length', 0)]
+ ('Content-Length', 0)]
res = session.open(download_url)
if res:
- gf = gzip.GzipFile(fileobj=StringIO(res.read()))
+ gf = gzip.GzipFile(fileobj=res)
with open(dest_path, 'wb') as f:
f.write(gf.read())
f.flush()
diff --git a/resources/lib/utils.py b/resources/lib/utils.py
index 8035de1..fb645db 100644
--- a/resources/lib/utils.py
+++ b/resources/lib/utils.py
@@ -1,30 +1,28 @@
import sys
import struct
-import urllib2
-import urlparse
-import cookielib
from os import path
-from httplib import HTTPConnection
+from urllib import parse, request
+from http.cookiejar import CookieJar
+from http.client import HTTPConnection
import xbmc
-import xbmcvfs
def log(module, msg):
- xbmc.log((u"### [%s] - %s" % (module, msg)).encode('utf-8'), level=xbmc.LOGDEBUG)
+ xbmc.log(f"### [{module}] - {msg}", level=xbmc.LOGDEBUG)
def notify(script_name, language, string_id):
- xbmc.executebuiltin((u'Notification(%s,%s)' % (script_name, language(string_id))).encode('utf-8'))
+ xbmc.executebuiltin(f"Notification({script_name}, {language(string_id)})")
def get_params(params_str=""):
params_str = params_str or sys.argv[2]
- return dict(urlparse.parse_qsl(params_str.lstrip('?')))
+ return dict(parse.parse_qsl(params_str.lstrip('?')))
def get_video_path(xbmc_path=''):
- xbmc_path = xbmc_path or urlparse.unquote(xbmc.Player().getPlayingFile().decode('utf-8'))
+ xbmc_path = xbmc_path or parse.unquote(xbmc.Player().getPlayingFile())
if xbmc_path.startswith('rar://'):
return path.dirname(xbmc_path.replace('rar://', ''))
elif xbmc_path.startswith('stack://'):
@@ -50,7 +48,7 @@ class HTTP10Connection(HTTPConnection):
_http_vsn_str = "HTTP/1.0"
-class HTTP10Handler(urllib2.HTTPHandler):
+class HTTP10Handler(request.HTTPHandler):
def http_open(self, req):
return self.do_open(HTTP10Connection, req)
@@ -58,13 +56,13 @@ def http_open(self, req):
def get_session(proxies=None, cookies=True, http_10=False):
handlers = []
if proxies:
- handlers.append(urllib2.ProxyHandler(proxies))
+ handlers.append(request.ProxyHandler(proxies))
if cookies:
- cj = cookielib.CookieJar()
- handlers.append(urllib2.HTTPCookieProcessor(cj))
+ cj = CookieJar()
+ handlers.append(request.HTTPCookieProcessor(cj))
if http_10:
handlers.append(HTTP10Handler)
- return urllib2.build_opener(*handlers)
+ return request.build_opener(*handlers)
def __get_last_split(firs_rar_file, x):
@@ -78,7 +76,7 @@ def __get_last_split(firs_rar_file, x):
def __add_file_hash(name, file_hash, seek):
- f = xbmcvfs.File(name)
+ f = open(name, "rb")
f.seek(max(0, seek), 0)
for i in range(8192):
file_hash += struct.unpack('