Skip to content

Commit

Permalink
release: v0.0.27
Browse files Browse the repository at this point in the history
  • Loading branch information
newt-sc committed May 10, 2020
1 parent 2f58267 commit 949cafb
Show file tree
Hide file tree
Showing 21 changed files with 91 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ omit =
[report]
exclude_lines =
pragma: no cover
if PY2
if core\.utils\.PY2
if py2
if core\.utils\.py2
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
* [v0.0.27](https://github.com/newt-sc/a4kSubtitles/releases/tag/service.subtitles.a4ksubtitles%2Fservice.subtitles.a4ksubtitles-0.0.27):
* Attempt to auto-fix a garbled cyrillic encoded subtitles
* Fix more encoding issues
* Ensure progress dialog close even if the addon crashes
* Apply color to service name in results and bold tags
* Show notification if imdb id is missing

* [v0.0.26](https://github.com/newt-sc/a4kSubtitles/releases/tag/service.subtitles.a4ksubtitles%2Fservice.subtitles.a4ksubtitles-0.0.26):
* Support for Addic7ed
* Improve cache of the last results
Expand Down
9 changes: 5 additions & 4 deletions a4kSubtitles/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def main(handle, paramstring): # pragma: no cover
core.progress_text = ''
core.progress_dialog = kodi.get_progress_dialog()

search(core, params)

core.progress_dialog.close()
core.progress_dialog = None
try:
search(core, params)
finally:
core.progress_dialog.close()
core.progress_dialog = None

elif params['action'] == 'download':
params['action_args'] = json.loads(params['action_args'])
Expand Down
44 changes: 29 additions & 15 deletions a4kSubtitles/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __download(core, filepath, request):
def __extract_gzip(core, archivepath, filename):
filepath = core.os.path.join(core.utils.temp_dir, filename)

if core.utils.PY2:
if core.utils.py2:
with open(archivepath, 'rb') as f:
gzip_file = f.read()

Expand All @@ -32,7 +32,7 @@ def __extract_zip(core, archivepath, filename, episodeid):
first_subfile = None
subfile = None
for file in files:
if core.utils.PY2:
if core.utils.py2:
file = file.decode('utf8')

file_lower = file.lower()
Expand Down Expand Up @@ -60,19 +60,33 @@ def __insert_lang_code_in_filename(core, filename, lang):
filename_chunks.insert(-1, lang_code)
return '.'.join(filename_chunks)

def __cleanup(core, filepath):
with open(filepath, 'r') as f:
sub_contents = f.read()

def __postprocess(core, filepath):
try:
cleaned_contents = core.utils.cleanup_subtitles(sub_contents)
if len(cleaned_contents) < len(sub_contents) / 2:
return
with open(filepath, 'rb') as f:
text_bytes = f.read()

text = text_bytes.decode(core.utils.default_encoding)

try:
if all(ch in text for ch in core.utils.cp1251_garbled):
text = text.encode(core.utils.base_encoding).decode('cp1251')
elif all(ch in text for ch in core.utils.koi8r_garbled):
try:
text = text.encode(core.utils.base_encoding).decode('koi8-r')
except:
text = text.encode(core.utils.base_encoding).decode('koi8-u')
except: pass

try:
if core.kodi.get_bool_setting('general.remove_ads'):
text = core.utils.cleanup_subtitles(text)
if len(text) < len(text) / 2:
return
except: pass

with open(filepath, 'w') as f:
f.write(cleaned_contents)
except:
pass
with open(filepath, 'wb') as f:
f.write(text.encode(core.utils.default_encoding))
except: pass

def download(core, params):
core.logger.debug(lambda: core.json.dumps(params, indent=2))
Expand All @@ -99,10 +113,10 @@ def download(core, params):
episodeid = actions_args.get('episodeid', '')
filepath = __extract_zip(core, archivepath, filename, episodeid)

if core.kodi.get_bool_setting('general.remove_ads'):
__cleanup(core, filepath)
__postprocess(core, filepath)

if core.api_mode_enabled:
return filepath

listitem = core.kodi.xbmcgui.ListItem(label=filepath)
core.kodi.xbmcplugin.addDirectoryItem(handle=core.handle, url=filepath, listitem=listitem, isFolder=False)
4 changes: 3 additions & 1 deletion a4kSubtitles/lib/kodi.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,12 @@ def create_listitem(item): # pragma: no cover
(item_name, item_ext) = os.path.splitext(item['name'])
item_name = item_name.replace('.', ' ')
item_ext = item_ext.upper()[1:]
item_service = item['service']
item_color = item.get('color', 'white')

args = {
'label': item['lang'],
'label2': '%s (%s) (%s)' % (item_name, item_ext, item['service']),
'label2': '%s ([B]%s[/B]) ([B][COLOR %s]%s[/COLOR][/B])' % (item_name, item_ext, item_color, item_service),
'iconImage': str(item['rating']),
'thumbnailImage': item['lang_code'],
}
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/lib/kodi_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
xbmc.translatePath = lambda p: p
xbmc.getInfoLabel = lambda t: ''
xbmc.executeJSONRPC = lambda _: '{ "result": { "value": true } }'
xbmc.executebuiltin = lambda _: None
xbmc.getCleanMovieTitle = lambda t: t

xbmc.convertLanguage = lambda l, f: l[:f].lower()
Expand Down
3 changes: 3 additions & 0 deletions a4kSubtitles/lib/request.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-

import requests
import urllib3
import re
import time
from .kodi import get_int_setting
from . import logger

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def execute(core, request):
request.setdefault('timeout', get_int_setting('general.timeout'))

Expand Down
23 changes: 12 additions & 11 deletions a4kSubtitles/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@
from urllib.parse import quote_plus, unquote, parse_qsl
from io import StringIO
import queue
unicode = None
unicode = lambda v, e: v

__url_regex = r'(([a-z0-9][a-z0-9-]{1,5}[a-z0-9]\.[a-z0-9]{2,20})|(opensubtitles))\.[a-z]{2,5}'
__credit_part_regex = r'(sync|synced|fix|fixed|corrected|corrections)'
__credit_regex = __credit_part_regex + r' ?&? ?' + __credit_part_regex + r'? by'

PY2 = sys.version_info[0] == 2
PY3 = not PY2
default_encoding = 'utf-8'
base_encoding = 'raw_unicode_escape'
cp1251_garbled = u'аеио'.encode('cp1251').decode('raw_unicode_escape')
koi8r_garbled = u'аеио'.encode('koi8-r').decode('raw_unicode_escape')

py2 = sys.version_info[0] == 2
py3 = not py2

temp_dir = os.path.join(kodi.addon_profile, 'temp')
results_filepath = os.path.join(kodi.addon_profile, 'last_results.json')
Expand All @@ -45,8 +50,7 @@ def __save_cache(filepath, cache):
json_data = json.dumps(cache, indent=2)
with open(filepath, 'w') as f:
f.write(json_data)
except:
pass
except: pass

def get_meta_cache():
meta_cache = __get_cache(__meta_cache_filepath)
Expand All @@ -70,7 +74,7 @@ def get_meta_hash(meta):
'imdb_id': meta.imdb_id,
'filename': meta.filename,
}
json_data = json.dumps(hash_data).encode('utf-8')
json_data = json.dumps(hash_data).encode(default_encoding)
return hashlib.sha256(json_data).hexdigest()

class DictAsObject(dict):
Expand All @@ -85,10 +89,7 @@ def get_all_relative_entries(relative_file, ext='.py', ignore_private=True):
return [os.path.splitext(name)[0] for name in entries if not ignore_private or not name.startswith('__') and name.endswith(ext)]

def strip_non_ascii_and_unprintable(text):
if not isinstance(text, str):
return str(text)

if PY2 and not isinstance(text, unicode):
if not isinstance(text, str) and (not py2 or not isinstance(text, unicode)):
return str(text)

result = ''.join(char for char in text if char in string.printable)
Expand Down Expand Up @@ -140,7 +141,7 @@ def cleanup_subtitles(sub_contents):
continue

if re.search(__url_regex, line, re.IGNORECASE) or re.search(__credit_regex, line, re.IGNORECASE):
logger.notice('(detected ad) %s' % line)
logger.notice('(detected ad) %s' % line.encode('ascii', errors='ignore'))
if not re.match(r'^\{\d+\}\{\d+\}', line):
garbage = True
buffer = []
Expand Down
3 changes: 1 addition & 2 deletions a4kSubtitles/lib/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ def __get_filename(title):
filepath = xbmc.Player().getPlayingFile()
filename = filepath.split('/')[-1]
filename = utils.unquote(filename)
except:
pass
except: pass

return filename

Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def search(core, params):

if meta.imdb_id == '':
core.logger.error('missing imdb id!')
core.kodi.notification('IMDB ID is not provided')
return

last_query_results = __get_last_results(core, meta)
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/addic7ed.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def map_result(result):
'lang_code': lang_code,
'sync': 'true' if release_id in meta.title else 'false',
'impaired': 'true' if hearing_impaired != '' else 'false',
'color': 'deepskyblue',
'action_args': {
'url': url,
'lang': lang,
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/bsplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ def map_result(result):
'lang_code': core.kodi.xbmc.convertLanguage(lang, core.kodi.xbmc.ISO_639_1),
'sync': 'true' if meta.filehash else 'false',
'impaired': 'false',
'color': 'gold',
'action_args': {
'url': result.find('subDownloadLink').text,
'lang': lang,
Expand Down
3 changes: 2 additions & 1 deletion a4kSubtitles/services/opensubtitles.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __set_auth_header(core, service_name, request):
return

token = '%s:%s' % (username, password)
if core.utils.PY3:
if core.utils.py3:
token = token.encode('ascii')

request['headers']['Authorization'] = 'Basic %s' % core.b64encode(token).decode('ascii')
Expand Down Expand Up @@ -92,6 +92,7 @@ def map_result(result):
'lang_code': result['ISO639'],
'sync': 'true' if result['MovieHash'] == meta.filehash else 'false',
'impaired': 'false' if result['SubHearingImpaired'] == '0' else 'true',
'color': 'springgreen',
'action_args': {
'url': result['ZipDownloadLink'].replace('/subad/', '/sub/'),
'lang': result['LanguageName'],
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/podnadpisi.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def map_result(result):
'lang_code': lang_code,
'sync': 'true' if meta.filename_without_ext in result['custom_releases'] else 'false',
'impaired': 'true' if 'hearing_impaired' in result['flags'] else 'false',
'color': 'orange',
'action_args': {
'url': '%s%s' % (__url, result['download']),
'lang': lang,
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/subdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def parse_search_response(core, service_name, meta, response):
'lang_code': lang_code,
'sync': 'true',
'impaired': 'false',
'color': 'cyan',
'action_args': {
'url': '',
'hash': meta.subdb_hash,
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/subscene.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def map_result(result):
'lang_code': lang_code,
'sync': 'true' if meta.filename_without_ext == name else 'false',
'impaired': 'true' if impaired else 'false',
'color': 'dodgerblue',
'action_args': {
'url': download_href,
'lang': lang,
Expand Down
9 changes: 8 additions & 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.a4ksubtitles"
name="a4kSubtitles"
version="0.0.26"
version="0.0.27"
provider-name="Unknown">
<requires>
<import addon="xbmc.python" version="2.25.0"/>
Expand All @@ -24,6 +24,13 @@ Supports: OpenSubtitles, BSPlayer, Podnadpisi.NET, SubDB, Subscene, Addic7ed
<icon>icon.png</icon>
</assets>
<news>
[v0.0.27]:
* Attempt to auto-fix a garbled cyrillic encoded subtitles
* Fix more encoding issues
* Ensure progress dialog close even if the addon crashes
* Apply color to service name in results and bold tags
* Show notification if imdb id is missing

[v0.0.26]:
* Support for Addic7ed
* Improve cache of the last results
Expand Down
9 changes: 8 additions & 1 deletion packages/addons.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<addons>
<addon id="service.subtitles.a4ksubtitles"
name="a4kSubtitles"
version="0.0.26"
version="0.0.27"
provider-name="Unknown">
<requires>
<import addon="xbmc.python" version="2.25.0"/>
Expand All @@ -27,6 +27,13 @@ Supports: OpenSubtitles, BSPlayer, Podnadpisi.NET, SubDB, Subscene, Addic7ed
<icon>icon.png</icon>
</assets>
<news>
[v0.0.27]:
* Attempt to auto-fix a garbled cyrillic encoded subtitles
* Fix more encoding issues
* Ensure progress dialog close even if the addon crashes
* Apply color to service name in results and bold tags
* Show notification if imdb id is missing

[v0.0.26]:
* Support for Addic7ed
* Improve cache of the last results
Expand Down
2 changes: 1 addition & 1 deletion packages/addons.xml.crc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b7b576a871562c3715a9fd0155974309fde0a679
e97fe8337779468558018c00a3b4d465398048e5
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ pytest
flake8
coverage
coveralls
PyYML
6 changes: 3 additions & 3 deletions tests/test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def test_subscene():
}

if os.getenv('CI', None) is not None:
time.sleep(2)
time.sleep(4)

filepath = a4ksubtitles_api.download(params, search.settings)

Expand All @@ -397,7 +397,7 @@ def test_subscene_tvshow():
}

if os.getenv('CI', None) is not None:
time.sleep(2)
time.sleep(4)

search = __search_tvshow(a4ksubtitles_api, settings)

Expand All @@ -411,7 +411,7 @@ def test_subscene_tvshow():
}

if os.getenv('CI', None) is not None:
time.sleep(2)
time.sleep(4)

filepath = a4ksubtitles_api.download(params, search.settings)

Expand Down

0 comments on commit 949cafb

Please sign in to comment.