Skip to content

Commit

Permalink
release: v3.16.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xZetsubou authored and newt-sc committed Sep 15, 2024
1 parent eb18fa2 commit 09cc5a9
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 4 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/cron-tests-subsource.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: SubSource
on:
push:
branches:
- master
paths:
- '.github/workflows/cron-tests-subsource.yml'
schedule:
- cron: '0 7 * * *'
workflow_dispatch: ~

jobs:
tests:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: setup-python
uses: actions/setup-python@v5
with:
python-version: 3.8

- name: install
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: test
run: |
pytest -v -k 'test_subsource' ./tests/test_suite.py
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* [v3.16.0](https://github.com/newt-sc/a4kSubtitles/releases/tag/service.subtitles.a4ksubtitles%2Fservice.subtitles.a4ksubtitles-3.16.0):
* Fix subtitle international characters encoding
* Add SubSource

* [v3.15.0](https://github.com/newt-sc/a4kSubtitles/releases/tag/service.subtitles.a4ksubtitles%2Fservice.subtitles.a4ksubtitles-3.15.0):
* Remove Subscene
* Add SubDL
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Subtitle addon for KODI with support for multiple subtitle services:
* OpenSubtitles
* Podnadpisi.NET
* SubDL
* SubSource

## Configuration
![configuration](https://media.giphy.com/media/kewuE4BgfOnFin0vEC/source.gif)
Expand Down
2 changes: 1 addition & 1 deletion a4kSubtitles/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __insert_lang_code_in_filename(core, filename, lang_code):

def __postprocess(core, filepath, lang_code):
try:
with open(filepath, 'rb') as f:
with open(filepath, 'rb', encoding=core.utils.default_encoding) as f:
text_bytes = f.read()

if core.kodi.get_bool_setting('general.use_chardet'):
Expand Down
1 change: 1 addition & 0 deletions a4kSubtitles/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
'opensubtitles': 'OpenSubtitles',
'podnadpisi': 'Podnadpisi',
'subdl': 'SubDL',
'subsource': 'SubSource'
}

def __set_fn_if_missing(service, fn_name, fn):
Expand Down
135 changes: 135 additions & 0 deletions a4kSubtitles/services/subsource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# -*- coding: utf-8 -*-

__api = "https://api.subsource.net/api/"

__getMovie = __api + "getMovie"
__getSub = __api + "getSub"
__search = __api + "searchMovie"
__download = __api + "downloadSub/"

def __extract_season_episode(core, text):
pattern = core.re.compile(r'(?:S(\d+)|Season\s*(\d+))[^E]*?(?:E(\d+)|Episode\s*(\d+))', core.re.IGNORECASE)
match = pattern.search(text)

if match:
# Extract season and episode numbers from groups
season = match.group(1) or match.group(2)
episode = match.group(3) or match.group(4)
return (season, episode)

# If no matches found, attempt to capture episode-like sequences
fallback_pattern = core.re.compile(r'\bE?P?(\d{2,5})\b', core.re.IGNORECASE)
fallback_matches = fallback_pattern.findall(text)

if fallback_matches:
# Assuming the last number in the fallback matches is the episode number
episode_number = fallback_matches[-1]
return (None, episode_number)

return (None, None)

def build_search_requests(core, service_name, meta):
def get_movie(response):
results = response.json()
found = results.get("found", [])
movie_name = ""

for res in found:
if res.get("type", "Movie") == "Movie" and meta.is_tvshow:
continue
movie_name = res["linkName"]
break

params = {"movieName": movie_name, "langs": meta.languages}
if meta.is_tvshow:
params["season"] = "season-" + meta.season
return {"method": "POST", "url": __getMovie, "data": params}

name = (meta.title if meta.is_movie else meta.tvshow)
year = meta.tvshow_year if meta.is_tvshow else meta.year

params = {"query": name + " " + year}
request = {
"method": "POST",
"url": __search,
"data": params,
"next": lambda gm: get_movie(gm)
}
return [request]


def parse_search_response(core, service_name, meta, response):
try:
results = response.json()
except Exception as exc:
core.logger.error("%s - %s" % (service_name, exc))
return []

service = core.services[service_name]

if "subs" not in results:
return []

movie_details = results.get("movie", {})

# altname = movie_details.get("altName")
full_name = movie_details.get("fullName", "")

def map_result(result):
name = result.get("releaseName", "")
lang = result.get("lang")

if lang not in meta.languages:
return None

rating = result.get("rating", 0)
lang_code = core.utils.get_lang_id(lang, core.kodi.xbmc.ISO_639_1)

if meta.is_tvshow:
subtitle_season = core.re.search(r'Season\s(\d+)', full_name)
season, episode = __extract_season_episode(core, name)
season = subtitle_season.group(1).zfill(2) if subtitle_season else season

if season == meta.season.zfill(2) and episode == meta.episode.zfill(2):
name = meta.filename
elif not season and meta.season == "1" and episode == meta.episode.zfill(2):
name = meta.filename

return {
"service_name": service_name,
"service": service.display_name,
"lang": lang,
"name": name,
"rating": rating,
"lang_code": lang_code,
"sync": "true" if meta.filename_without_ext in result["releaseName"] else "false",
"impaired": "true" if result.get("hi", 0) != 0 else "false",
"color": "teal",
"action_args": {
"url": result["subId"],
"lang": lang,
"filename": name,
"full_link": result["fullLink"],
},
}

return list(map(map_result, results["subs"]))


def build_download_request(core, service_name, args):
*_, movie, lang, sub_id = args["full_link"].split("/")
params = {"movie": movie, "lang": lang, "id": sub_id}

def downloadsub(response):
result = response.json()
download_token = result["sub"]["downloadToken"]
return {"method": "GET", "url": __download + download_token, "stream": True}

request = {
"method": "POST",
"url": __getSub,
"data": params,
"next": lambda dw: downloadsub(dw)
}

return request
6 changes: 5 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="3.15.0"
version="3.16.0"
provider-name="Unknown">
<requires>
<import addon="script.module.requests"/>
Expand All @@ -27,6 +27,10 @@ Supports: OpenSubtitles, BSPlayer, Podnadpisi.NET, SubDL, Addic7ed
<screenshot>screenshot-03.png</screenshot>
</assets>
<news>
[v3.16.0]:
* Fix subtitle international characters encoding
* Add SubSource

[v3.15.0]:
* Remove Subscene
* Add SubDL
Expand Down
6 changes: 5 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="3.15.0"
version="3.16.0"
provider-name="Unknown">
<requires>
<import addon="script.module.requests"/>
Expand All @@ -30,6 +30,10 @@ Supports: OpenSubtitles, BSPlayer, Podnadpisi.NET, SubDL, Addic7ed
<screenshot>screenshot-03.png</screenshot>
</assets>
<news>
[v3.16.0]:
* Fix subtitle international characters encoding
* Add SubSource

[v3.15.0]:
* Remove Subscene
* Add SubDL
Expand Down
2 changes: 1 addition & 1 deletion packages/addons.xml.crc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d8ee5059ea7680d1c5001bc49d4287ad966f4bc3
8359e9e740c02c4d115755752d544406f6892c8b
4 changes: 4 additions & 0 deletions resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ msgctxt "#33206"
msgid "Addic7ed"
msgstr ""

msgctxt "#33207"
msgid "SubSource"
msgstr ""

# Labels
msgctxt "#33301"
msgid "Username"
Expand Down
1 change: 1 addition & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<setting id="opensubtitles.enabled" label="33201" type="bool" default="true"/>
<setting id="podnadpisi.enabled" label="33203" type="bool" default="true"/>
<setting id="subdl.enabled" label="33205" type="bool" default="true"/>
<setting id="subsource.enabled" label="33207" type="bool" default="true"/>
</category>
<!-- Accounts -->
<category label="33003">
Expand Down
86 changes: 86 additions & 0 deletions tests/test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,89 @@ def test_addic7ed_tvshow():
filepath = a4ksubtitles_api.download(params, search.settings)

assert filepath != ''

def test_subsource():
a4ksubtitles_api = api.A4kSubtitlesApi({'kodi': True})
__remove_all_cache(a4ksubtitles_api)

# search
settings = {
'subsource.enabled': 'true',
}
search = __search_movie(a4ksubtitles_api, settings)

# download
item = search.results[0]

params = {
'action': 'download',
'service_name': 'subsource',
'action_args': item['action_args']
}

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

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

assert filepath != ''

def test_subsource_tvshow():
a4ksubtitles_api = api.A4kSubtitlesApi({'kodi': True})
__remove_all_cache(a4ksubtitles_api)

# search
settings = {
'subsource.enabled': 'true',
}

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

search = __search_tvshow(a4ksubtitles_api, settings)

# download
item = search.results[0]

params = {
'action': 'download',
'service_name': 'subsource',
'action_args': item['action_args']
}

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

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

assert filepath != ''

def test_subsource_arabic():
a4ksubtitles_api = api.A4kSubtitlesApi({'kodi': True})
__remove_all_cache(a4ksubtitles_api)

# search
settings = {
'subsource.enabled': 'true',
}

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

search = __search_movie(a4ksubtitles_api, settings, {}, 'Arabic')

# download
item = search.results[0]

params = {
'action': 'download',
'service_name': 'subsource',
'action_args': item['action_args']
}

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

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

assert filepath != ''

0 comments on commit 09cc5a9

Please sign in to comment.