Skip to content

Commit

Permalink
Fixed android non rar support, rearrange code
Browse files Browse the repository at this point in the history
  • Loading branch information
realgam3 committed Nov 7, 2015
1 parent 7265a2f commit 15a1fa3
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 188 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ htmlcov/
nosetests.xml
coverage.xml
*,cover
bsplayer_test.py

# Translations
*.mo
Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="service.subtitles.bsplayer"
name="BSPlayer"
version="0.2.0"
version="0.2.1"
provider-name="realgam3">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
Expand Down
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
0.2.1 - 07/11/2015
- Fixed android non rar support, rearrange code

0.2.0 - 07/11/2015
- Fixed android rar support, works with smb shares

Expand Down
1 change: 1 addition & 0 deletions resources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Dummy file to make this directory a package.
160 changes: 16 additions & 144 deletions resources/lib/bsplayer.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import cookielib
import gzip
import logging
import gzip
import random
import struct
import urllib2
from StringIO import StringIO
from httplib import HTTPConnection
from os import path
from time import sleep
from StringIO import StringIO
from xml.etree import ElementTree

import xbmcvfs
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',
Expand All @@ -23,121 +17,11 @@ def get_sub_domain():
return API_URL_TEMPLATE.format(sub_domain=SUB_DOMAINS[random.randint(0, sub_domains_end)])


def get_session(proxies=None):
cj = cookielib.CookieJar()
proxy_handler = urllib2.ProxyHandler(proxies)
return urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), proxy_handler)


def python_logger(module, msg):
logger = logging.getLogger('BSPlayer')
logger.log(logging.DEBUG, (u"### [%s] - %s" % (module, msg)))


def OpensubtitlesHashRar(firsrarfile):
# log(__name__, "Hash Rar file")
f = xbmcvfs.File(firsrarfile)
a = f.read(4)
if a != 'Rar!':
raise Exception('ERROR: This is not rar file.')
seek = 0
for i in range(4):
f.seek(max(0, seek), 0)
a = f.read(100)
type, flag, size = struct.unpack('<BHH', a[2:2 + 5])
if 0x74 == type:
if 0x30 != struct.unpack('<B', a[25:25 + 1])[0]:
raise Exception('Bad compression method! Work only for "store".')
s_partiizebodystart = seek + size
s_partiizebody, s_unpacksize = struct.unpack('<II', a[7:7 + 2 * 4])
if (flag & 0x0100):
s_unpacksize = (struct.unpack('<I', a[36:36 + 4])[0] << 32) + s_unpacksize
# log(__name__, 'Hash untested for files biger that 2gb. May work or may generate bad hash.')
lastrarfile = getlastsplit(firsrarfile, (s_unpacksize - 1) / s_partiizebody)
hash = addfilehash(firsrarfile, s_unpacksize, s_partiizebodystart)
hash = addfilehash(lastrarfile, hash, (s_unpacksize % s_partiizebody) + s_partiizebodystart - 65536)
f.close()
return (s_unpacksize, "%016x" % hash)
seek += size
raise Exception('ERROR: Not Body part in rar file.')


def getlastsplit(firsrarfile, x):
if firsrarfile[-3:] == '001':
return firsrarfile[:-3] + ('%03d' % (x + 1))
if firsrarfile[-11:-6] == '.part':
return firsrarfile[0:-6] + ('%02d' % (x + 1)) + firsrarfile[-4:]
if firsrarfile[-10:-5] == '.part':
return firsrarfile[0:-5] + ('%1d' % (x + 1)) + firsrarfile[-4:]
return firsrarfile[0:-2] + ('%02d' % (x - 1))


def addfilehash(name, hash, seek):
f = xbmcvfs.File(name)
f.seek(max(0, seek), 0)
for i in range(8192):
hash += struct.unpack('<q', f.read(8))[0]
hash &= 0xffffffffffffffff
f.close()
return hash


def movie_size_and_hash(file_path):
file_ext = path.splitext(file_path)[1]
if file_ext == '.rar' or file_ext =='.001':
return OpensubtitlesHashRar(file_path)

longlong_format = '<q' # little-endian long long
byte_size = struct.calcsize(longlong_format)

f = xbmcvfs.File(file_path)
file_size = f.size()
movie_hash = file_size

if file_size < 65536 * 2:
f.close()
raise Exception("SizeError")

for x in range(65536 / byte_size):
buff = f.read(byte_size)
(l_value,) = struct.unpack(longlong_format, buff)
movie_hash += l_value
movie_hash &= 0xFFFFFFFFFFFFFFFF # to remain as 64bit number

f.seek(max(0, file_size - 65536), 0)
for x in range(65536 / byte_size):
buff = f.read(byte_size)
(l_value,) = struct.unpack(longlong_format, buff)
movie_hash += l_value
movie_hash &= 0xFFFFFFFFFFFFFFFF
returned_movie_hash = "%016x" % movie_hash
f.close()

return file_size, returned_movie_hash


class HTTP10Connection(HTTPConnection):
_http_vsn = 10
_http_vsn_str = "HTTP/1.0"


class HTTP10Handler(urllib2.HTTPHandler):
def http_open(self, req):
return self.do_open(HTTP10Connection, req)


class BSPlayer(object):
def __init__(self, search_url=None, log=python_logger, proxies=None):
self.session = get_session(proxies)
def __init__(self, search_url=None, proxies=None):
self.session = get_session(proxies=proxies)
self.search_url = search_url or get_sub_domain()
self.token = None
self.log = log
if self.log.__name__ == 'python_logger':
logging.basicConfig(
format='%(asctime)s T:%(thread)d %(levelname)s: %(message)s',
datefmt='%H:%M:%S',
level=logging.DEBUG
)

def __enter__(self):
self.login()
Expand All @@ -163,18 +47,18 @@ def api_request(self, func_name='logIn', params='', tries=5):
'<ns1:{func_name}>{params}</ns1:{func_name}></SOAP-ENV:Body></SOAP-ENV:Envelope>'
).format(search_url=self.search_url, func_name=func_name, params=params)

self.log("BSPlayer.api_request", 'Sending request: %s' % func_name)
log('BSPlayer.api_request', 'Sending request: %s.' % func_name)
for i in xrange(tries):
try:
self.session.addheaders.extend(headers.items())
res = self.session.open(self.search_url, data)
return ElementTree.fromstring(res.read())
except Exception, ex:
self.log("BSPlayer.api_request", ex)
log("BSPlayer.api_request", "ERROR: %s." % ex)
if func_name == 'logIn':
self.search_url = get_sub_domain()
sleep(1)

log('BSPlayer.api_request', 'ERROR: Too many tries (%d)...' % tries)
raise Exception('Too many tries...')

def login(self):
Expand All @@ -191,7 +75,7 @@ def login(self):
res = root.find('.//return')
if res.find('status').text == 'OK':
self.token = res.find('data').text
self.log("BSPlayer.login", "Logged In Successfully.")
log("BSPlayer.login", "Logged In Successfully.")
return True
return False

Expand All @@ -207,7 +91,7 @@ def logout(self):
res = root.find('.//return')
self.token = None
if res.find('status').text == 'OK':
self.log("BSPlayer.logout", "Logged Out Successfully.")
log("BSPlayer.logout", "Logged Out Successfully.")
return True
return False

Expand All @@ -219,7 +103,7 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
language_ids = ",".join(language_ids)

movie_size, movie_hash = movie_size_and_hash(movie_path)
self.log('BSPlayer.search_subtitles', 'Movie Size: %s, Movie Hash: %s' % (movie_size, movie_hash))
log('BSPlayer.search_subtitles', 'Movie Size: %s, Movie Hash: %s.' % (movie_size, movie_hash))
root = self.api_request(
func_name='searchSubtitles',
params=(
Expand All @@ -238,7 +122,7 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
items = root.findall('.//return/data/item')
subtitles = []
if items:
self.log("BSPlayer.search_subtitles", "Subtitles Found.")
log("BSPlayer.search_subtitles", "Subtitles Found.")
for item in items:
subtitles.append(dict(
subID=item.find('subID').text,
Expand All @@ -254,12 +138,11 @@ def search_subtitles(self, movie_path, language_ids='heb,eng', logout=False):
return subtitles

@staticmethod
def download_subtitles(download_url, dest_path="Subtitle.srt", proxies=None):
proxy_handler = urllib2.ProxyHandler(proxies)
opener = urllib2.build_opener(HTTP10Handler, proxy_handler)
opener.addheaders = [('User-Agent', 'Mozilla/4.0 (compatible; Synapse)'),
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)]
res = opener.open(download_url)
res = session.open(download_url)
if res:
gf = gzip.GzipFile(fileobj=StringIO(res.read()))
with open(dest_path, 'wb') as f:
Expand All @@ -268,14 +151,3 @@ def download_subtitles(download_url, dest_path="Subtitle.srt", proxies=None):
gf.close()
return True
return False


if __name__ == '__main__':
bsp = BSPlayer(proxies={'http': '207.91.10.234:8080'})
subs = bsp.search_subtitles(
r'V:\Movies\Jackass.Presents.Bad.Grandpa.0.5.2014.720p.Bluray.x264.DTS-EVO\Jackass.Presents.Bad.Grandpa.0.5.2014.720p.Bluray.x264.DTS-EVO.mkv',
logout=True
)
for sub in subs:
print bsp.download_subtitles(sub['subDownloadLink'], proxies={'http': '207.91.10.234:8080'})
break
Loading

0 comments on commit 15a1fa3

Please sign in to comment.