Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[service.subtitles.rvm.addic7ed@matrix] 3.2.0 #2627

Merged
merged 1 commit into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 79 additions & 71 deletions service.subtitles.rvm.addic7ed/addic7ed/actions.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
# coding: utf-8
# Created on: 07.04.2016
# Author: Roman Miroshnychenko aka Roman V.M. ([email protected])
# Copyright (C) 2016, Roman Miroshnychenko aka Roman V.M.
#
# 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 <https://www.gnu.org/licenses/>.

from __future__ import absolute_import, unicode_literals
import logging
import os
import sys
import re
import shutil
import sys
from collections import namedtuple
from six import PY2
from six.moves import urllib_parse as urlparse
from kodi_six import xbmc, xbmcplugin, xbmcgui
from . import parser
from .addon import addon, profile, get_ui_string, icon
from .exceptions import DailyLimitError, ParseError, SubsSearchError, \
from urllib import parse as urlparse

import xbmc
import xbmcgui
import xbmcplugin

from addic7ed import parser
from addic7ed.addon import ADDON, PROFILE, ICON, get_ui_string
from addic7ed.exceptions import NoSubtitlesReturned, ParseError, SubsSearchError, \
Add7ConnectionError
from .utils import logger, get_languages, get_now_played, parse_filename, \
normalize_showname
from addic7ed.parser import parse_filename, normalize_showname, get_languages
from addic7ed.utils import get_now_played
from addic7ed.webclient import Session

__all__ = ['router']

temp_dir = os.path.join(profile, 'temp')
handle = int(sys.argv[1])
logger = logging.getLogger(__name__)

TEMP_DIR = os.path.join(PROFILE, 'temp')
HANDLE = int(sys.argv[1])


VIDEOFILES = {'.avi', '.mkv', '.mp4', '.ts', '.m2ts', '.mov'}
dialog = xbmcgui.Dialog()
release_re = re.compile(r'-(.*?)(?:\[.*?\])?\.')
VIDEOFILE_EXTENSIONS = {'.avi', '.mkv', '.mp4', '.ts', '.m2ts', '.mov'}
DIALOG = xbmcgui.Dialog()
RELEASE_RE = re.compile(r'-(.*?)(?:\[.*?\])?\.')

EpisodeData = namedtuple('EpisodeData',
['showname', 'season', 'episode', 'filename'])
Expand All @@ -42,13 +59,13 @@ def _detect_synced_subs(subs_list, filename):
"""
listing = []
for item in subs_list:
release_match = release_re.search(filename)
release_match = RELEASE_RE.search(filename)
if release_match is not None:
release = release_match.group(1).lower()
else:
release = ''
lowercase_version = item.version.lower()
resync_pattern = r'sync.+?{}'.format(release)
resync_pattern = rf'sync.+?{release}'
synced = (release and
release in lowercase_version and
re.search(resync_pattern, lowercase_version, re.I) is None)
Expand Down Expand Up @@ -92,7 +109,7 @@ def display_subs(subs_list, episode_url, filename):
list_item.setProperty('hearing_imp', 'true')
if synced:
list_item.setProperty('sync', 'true')
url = '{0}?{1}'.format(
url = '{}?{}'.format( # pylint: disable=consider-using-f-string
sys.argv[0],
urlparse.urlencode(
{'action': 'download',
Expand All @@ -101,7 +118,7 @@ def display_subs(subs_list, episode_url, filename):
'filename': filename}
)
)
xbmcplugin.addDirectoryItem(handle=handle, url=url, listitem=list_item,
xbmcplugin.addDirectoryItem(handle=HANDLE, url=url, listitem=list_item,
isFolder=False)


Expand All @@ -118,22 +135,22 @@ def download_subs(link, referrer, filename):
label - the download location for subs.
"""
# Re-create a download location in a temporary folder
if not os.path.exists(profile):
os.mkdir(profile)
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
os.mkdir(temp_dir)
if not os.path.exists(PROFILE):
os.mkdir(PROFILE)
if os.path.exists(TEMP_DIR):
shutil.rmtree(TEMP_DIR)
os.mkdir(TEMP_DIR)
# Combine a path where to download the subs
filename = os.path.splitext(filename)[0] + '.srt'
subspath = os.path.join(temp_dir, filename)
subspath = os.path.join(TEMP_DIR, filename)
# Download the subs from addic7ed.com
try:
parser.download_subs(link, referrer, subspath)
Session().download_subs(link, referrer, subspath)
except Add7ConnectionError:
logger.error('Unable to connect to addic7ed.com')
dialog.notification(get_ui_string(32002), get_ui_string(32005), 'error')
except DailyLimitError:
dialog.notification(get_ui_string(32002), get_ui_string(32003), 'error',
DIALOG.notification(get_ui_string(32002), get_ui_string(32005), 'error')
except NoSubtitlesReturned:
DIALOG.notification(get_ui_string(32002), get_ui_string(32003), 'error',
3000)
logger.error('Exceeded daily limit for subs downloads.')
else:
Expand All @@ -144,11 +161,11 @@ def download_subs(link, referrer, filename):
# in 'Settings > Video > Subtitles' section.
# A 2-letter language code will be added to subs filename.
list_item = xbmcgui.ListItem(label=subspath)
xbmcplugin.addDirectoryItem(handle=handle,
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=subspath,
listitem=list_item,
isFolder=False)
dialog.notification(get_ui_string(32000), get_ui_string(32001), icon,
DIALOG.notification(get_ui_string(32000), get_ui_string(32001), ICON,
3000, False)
logger.info('Subs downloaded.')

Expand All @@ -161,44 +178,41 @@ def extract_episode_data():
:raises ParseError: if cannot determine episode data
"""
now_played = get_now_played()
logger.debug('Played file info: %s', now_played)
showname = now_played['showtitle'] or xbmc.getInfoLabel('VideoPlayer.TVshowtitle')
parsed = urlparse.urlparse(now_played['file'])
filename = os.path.basename(parsed.path)
if addon.getSetting('use_filename') == 'true' or not now_played['showtitle']:
if ADDON.getSetting('use_filename') == 'true' or not showname:
# Try to get showname/season/episode data from
# the filename if 'use_filename' setting is true
# or if the video-file does not have library metadata.
try:
logger.debug('Using filename: {0}'.format(filename))
logger.debug('Using filename: %s', filename)
showname, season, episode = parse_filename(filename)
except ParseError:
logger.debug(
'Filename {0} failed. Trying ListItem.Label...'.format(filename)
)
logger.debug('Filename %s failed. Trying ListItem.Label...', filename)
try:
filename = now_played['label']
logger.debug('Using filename: {0}'.format(filename))
logger.debug('Using filename: %s', filename)
showname, season, episode = parse_filename(filename)
except ParseError:
logger.error(
'Unable to determine episode data for {0}'.format(filename)
)
dialog.notification(get_ui_string(32002), get_ui_string(32006),
logger.error('Unable to determine episode data for %s', filename)
DIALOG.notification(get_ui_string(32002), get_ui_string(32006),
'error', 3000)
raise
else:
# Get get showname/season/episode data from
# Kodi if the video-file is being played from
# the TV-Shows library.
showname = now_played['showtitle']
season = str(now_played['season']).zfill(2)
episode = str(now_played['episode']).zfill(2)
if not os.path.splitext(filename)[1].lower() in VIDEOFILES:
filename = '{0}.{1}x{2}.foo'.format(
showname, season, episode
)
logger.debug('Using library metadata: {0} - {1}x{2}'.format(
showname, season, episode)
)
season = str(now_played['season'] if now_played['season'] > -1
else xbmc.getInfoLabel('VideoPlayer.Season'))
season = season.zfill(2)
episode = str(now_played['episode'] if now_played['episode'] > -1
else xbmc.getInfoLabel('VideoPlayer.Episode'))
episode = episode.zfill(2)
if not os.path.splitext(filename)[1].lower() in VIDEOFILE_EXTENSIONS:
filename = f'{showname}.{season}x{episode}.foo'
logger.debug('Using library metadata: %s - %sx%s', showname, season, episode)
return EpisodeData(showname, season, episode, filename)


Expand All @@ -214,39 +228,36 @@ def search_subs(params):
except ParseError:
return
# Create a search query string
query = '{0} {1}x{2}'.format(
normalize_showname(episode_data.showname),
episode_data.season,
episode_data.episode
)
showname = normalize_showname(episode_data.showname)
query = f'{showname} {episode_data.season}x{episode_data.episode}'
filename = episode_data.filename
else:
# Get the query string typed on the on-screen keyboard
query = params['searchstring']
filename = query
if query:
logger.debug('Search query: {0}'.format(query))
logger.debug('Search query: %s', query)
try:
results = parser.search_episode(query, languages)
except Add7ConnectionError:
logger.error('Unable to connect to addic7ed.com')
dialog.notification(
DIALOG.notification(
get_ui_string(32002), get_ui_string(32005), 'error'
)
except SubsSearchError:
logger.info('No subs for "{}" found.'.format(query))
logger.info('No subs for "%s" found.', query)
else:
if isinstance(results, list):
logger.info('Multiple episodes found:\n{0}'.format(results))
i = dialog.select(
logger.info('Multiple episodes found:\n%s', results)
i = DIALOG.select(
get_ui_string(32008), [item.title for item in results]
)
if i >= 0:
try:
results = parser.get_episode(results[i].link, languages)
except Add7ConnectionError:
logger.error('Unable to connect to addic7ed.com')
dialog.notification(get_ui_string(32002),
DIALOG.notification(get_ui_string(32002),
get_ui_string(32005), 'error')
return
except SubsSearchError:
Expand All @@ -255,9 +266,8 @@ def search_subs(params):
else:
logger.info('Episode selection cancelled.')
return
logger.info('Found subs for "{0}"'.format(query))
display_subs(results.subtitles, results.episode_url,
filename)
logger.info('Found subs for "%s"', query)
display_subs(results.subtitles, results.episode_url, filename)


def router(paramstring):
Expand All @@ -268,8 +278,6 @@ def router(paramstring):
:type paramstring: str
"""
# Get plugin call params
if PY2:
paramstring = urlparse.unquote(paramstring).decode('utf-8')
params = dict(urlparse.parse_qsl(paramstring))
if params['action'] in ('search', 'manualsearch'):
# Search and display subs.
Expand All @@ -279,4 +287,4 @@ def router(paramstring):
params['link'], params['ref'],
urlparse.unquote(params['filename'])
)
xbmcplugin.endOfDirectory(handle)
xbmcplugin.endOfDirectory(HANDLE)
40 changes: 24 additions & 16 deletions service.subtitles.rvm.addic7ed/addic7ed/addon.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
# coding: utf-8

from __future__ import unicode_literals
# Copyright (C) 2016, Roman Miroshnychenko aka Roman V.M.
#
# 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 <https://www.gnu.org/licenses/>.

import os

from kodi_six import xbmcaddon

try:
from kodi_six.xbmcvfs import translatePath
except (ImportError, AttributeError):
from kodi_six.xbmc import translatePath
import xbmcaddon
from xbmcvfs import translatePath

__all__ = ['ADDON_ID', 'addon', 'path', 'profile', 'icon', 'get_ui_string']
__all__ = ['ADDON_ID', 'ADDON', 'ADDON_VERSION', 'PATH', 'PROFILE', 'ICON', 'get_ui_string']

ADDON_ID = 'service.subtitles.rvm.addic7ed'
addon = xbmcaddon.Addon(ADDON_ID)
path = translatePath(addon.getAddonInfo('path'))
profile = translatePath(addon.getAddonInfo('profile'))
icon = os.path.join(path, 'icon.png')
ADDON = xbmcaddon.Addon()
ADDON_ID = ADDON.getAddonInfo('id')
ADDON_VERSION = ADDON.getAddonInfo('version')
PATH = translatePath(ADDON.getAddonInfo('path'))
PROFILE = translatePath(ADDON.getAddonInfo('profile'))
ICON = os.path.join(PATH, 'icon.png')


def get_ui_string(string_id):
Expand All @@ -27,4 +35,4 @@ def get_ui_string(string_id):
:param string_id: UI string ID
:return: UI string
"""
return addon.getLocalizedString(string_id)
return ADDON.getLocalizedString(string_id)
Loading
Loading