Various check fixes (#11)
* Various check fixes This PR includes: - Fix invalid-name pylint check - Enable overriding PYTHON in Makefile - Supporting multiple languages * Add invalid-name to routing tests Co-authored-by: Michaël Arnauts <michael.arnauts@gmail.com>
This commit is contained in:
parent
3281c41e21
commit
b282b3ef34
@ -1,10 +1,10 @@
|
|||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
disable=
|
disable=
|
||||||
bad-option-value,
|
bad-option-value,
|
||||||
|
cyclic-import, # This shoud be fixed
|
||||||
duplicate-code,
|
duplicate-code,
|
||||||
fixme,
|
fixme,
|
||||||
import-outside-toplevel,
|
import-outside-toplevel,
|
||||||
invalid-name,
|
|
||||||
line-too-long,
|
line-too-long,
|
||||||
old-style-class,
|
old-style-class,
|
||||||
too-few-public-methods,
|
too-few-public-methods,
|
||||||
@ -13,4 +13,3 @@ disable=
|
|||||||
too-many-instance-attributes,
|
too-many-instance-attributes,
|
||||||
too-many-locals,
|
too-many-locals,
|
||||||
too-many-public-methods,
|
too-many-public-methods,
|
||||||
cyclic-import, # This shoud be fixed
|
|
28
Makefile
28
Makefile
@ -1,16 +1,20 @@
|
|||||||
ENVS = py27,py36,py37
|
|
||||||
export PYTHONPATH := $(CURDIR):$(CURDIR)/test
|
export PYTHONPATH := $(CURDIR):$(CURDIR)/test
|
||||||
|
PYTHON := python
|
||||||
|
|
||||||
# Collect information to build as sensible package name
|
# Collect information to build as sensible package name
|
||||||
name = plugin.video.viervijfzes
|
name = $(shell xmllint --xpath 'string(/addon/@id)' addon.xml)
|
||||||
version = $(shell xmllint --xpath 'string(/addon/@version)' addon.xml)
|
version = $(shell xmllint --xpath 'string(/addon/@version)' addon.xml)
|
||||||
git_branch = $(shell git rev-parse --abbrev-ref HEAD)
|
git_branch = $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
git_hash = $(shell git rev-parse --short HEAD)
|
git_hash = $(shell git rev-parse --short HEAD)
|
||||||
zip_name = $(name)-$(version)-$(git_branch)-$(git_hash).zip
|
zip_name = $(name)-$(version)-$(git_branch)-$(git_hash).zip
|
||||||
include_files = addon_entry.py addon.xml CHANGELOG.md LICENSE README.md service_entry.py resources/
|
include_files = addon_entry.py addon.xml CHANGELOG.md LICENSE README.md resources/ service_entry.py
|
||||||
include_paths = $(patsubst %,$(name)/%,$(include_files))
|
include_paths = $(patsubst %,$(name)/%,$(include_files))
|
||||||
exclude_files = \*.new \*.orig \*.pyc \*.pyo
|
exclude_files = \*.new \*.orig \*.pyc \*.pyo
|
||||||
|
|
||||||
|
languages = $(filter-out en_gb, $(patsubst resources/language/resource.language.%, %, $(wildcard resources/language/*)))
|
||||||
|
|
||||||
|
.PHONY: check test
|
||||||
|
|
||||||
all: check test build
|
all: check test build
|
||||||
zip: build
|
zip: build
|
||||||
|
|
||||||
@ -18,15 +22,17 @@ check: check-pylint check-tox check-translations
|
|||||||
|
|
||||||
check-pylint:
|
check-pylint:
|
||||||
@echo ">>> Running pylint checks"
|
@echo ">>> Running pylint checks"
|
||||||
@pylint *.py resources/ test/
|
@$(PYTHON) -m pylint *.py resources/lib/ test/
|
||||||
|
|
||||||
check-tox:
|
check-tox:
|
||||||
@echo ">>> Running tox checks"
|
@echo ">>> Running tox checks"
|
||||||
@tox -q
|
@$(PYTHON) -m tox -q
|
||||||
|
|
||||||
check-translations:
|
check-translations:
|
||||||
@echo ">>> Running translation checks"
|
@echo ">>> Running translation checks"
|
||||||
@msgcmp resources/language/resource.language.nl_nl/strings.po resources/language/resource.language.en_gb/strings.po
|
@$(foreach lang,$(languages), \
|
||||||
|
msgcmp resources/language/resource.language.$(lang)/strings.po resources/language/resource.language.en_gb/strings.po; \
|
||||||
|
)
|
||||||
|
|
||||||
check-addon: clean build
|
check-addon: clean build
|
||||||
@echo ">>> Running addon checks"
|
@echo ">>> Running addon checks"
|
||||||
@ -43,7 +49,7 @@ ifdef GITHUB_ACTIONS
|
|||||||
@coverage run -m unittest discover
|
@coverage run -m unittest discover
|
||||||
@coverage xml
|
@coverage xml
|
||||||
else
|
else
|
||||||
@python -m unittest discover -v -b -f
|
@$(PYTHON) -m unittest discover -v -b -f
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@ -60,11 +66,5 @@ build: clean
|
|||||||
@echo "Successfully wrote package as: ../$(zip_name)"
|
@echo "Successfully wrote package as: ../$(zip_name)"
|
||||||
|
|
||||||
release: build
|
release: build
|
||||||
rm -rf ../repo-plugins/plugin.video.viervijfzes/*
|
rm -rf ../repo-plugins/$(name)/*
|
||||||
unzip ../$(zip_name) -d ../repo-plugins/
|
unzip ../$(zip_name) -d ../repo-plugins/
|
||||||
|
|
||||||
run:
|
|
||||||
@echo ">>> Run CLI"
|
|
||||||
python test/run.py /
|
|
||||||
|
|
||||||
.PHONY: check test
|
|
||||||
|
@ -10,7 +10,7 @@ from routing import Plugin
|
|||||||
from resources.lib import kodilogging
|
from resources.lib import kodilogging
|
||||||
|
|
||||||
kodilogging.config()
|
kodilogging.config()
|
||||||
routing = Plugin()
|
routing = Plugin() # pylint: disable=invalid-name
|
||||||
_LOGGER = logging.getLogger('addon')
|
_LOGGER = logging.getLogger('addon')
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,18 +104,18 @@ class Catalog:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Add the seasons
|
# Add the seasons
|
||||||
for s in list(program.seasons.values()):
|
for season in list(program.seasons.values()):
|
||||||
listing.append(
|
listing.append(
|
||||||
TitleItem(
|
TitleItem(
|
||||||
title=s.title, # kodiutils.localize(30205, season=s.number), # Season {season}
|
title=season.title, # kodiutils.localize(30205, season=season.number), # Season {season}
|
||||||
path=kodiutils.url_for('show_catalog_program_season', channel=channel, program=program_id, season=s.uuid),
|
path=kodiutils.url_for('show_catalog_program_season', channel=channel, program=program_id, season=season.uuid),
|
||||||
art_dict={
|
art_dict={
|
||||||
'fanart': program.background,
|
'fanart': program.background,
|
||||||
},
|
},
|
||||||
info_dict={
|
info_dict={
|
||||||
'tvshowtitle': program.title,
|
'tvshowtitle': program.title,
|
||||||
'title': kodiutils.localize(30205, season=s.number), # Season {season}
|
'title': kodiutils.localize(30205, season=season.number), # Season {season}
|
||||||
'plot': s.description,
|
'plot': season.description,
|
||||||
'set': program.title,
|
'set': program.title,
|
||||||
'studio': studio,
|
'studio': studio,
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class BackgroundService(Monitor):
|
|||||||
|
|
||||||
_LOGGER.info('Service stopped')
|
_LOGGER.info('Service stopped')
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
def onSettingsChanged(self): # pylint: disable=invalid-name
|
||||||
""" Callback when a setting has changed """
|
""" Callback when a setting has changed """
|
||||||
if self._has_credentials_changed():
|
if self._has_credentials_changed():
|
||||||
_LOGGER.info('Clearing auth tokens due to changed credentials')
|
_LOGGER.info('Clearing auth tokens due to changed credentials')
|
||||||
|
@ -32,8 +32,8 @@ class AuthApi:
|
|||||||
|
|
||||||
# Load tokens from cache
|
# Load tokens from cache
|
||||||
try:
|
try:
|
||||||
with kodiutils.open_file(self._cache_dir + self.TOKEN_FILE, 'rb') as f:
|
with kodiutils.open_file(self._cache_dir + self.TOKEN_FILE, 'rb') as fdesc:
|
||||||
data_json = json.loads(f.read())
|
data_json = json.loads(fdesc.read())
|
||||||
self._id_token = data_json.get('id_token')
|
self._id_token = data_json.get('id_token')
|
||||||
self._refresh_token = data_json.get('refresh_token')
|
self._refresh_token = data_json.get('refresh_token')
|
||||||
self._expiry = int(data_json.get('expiry', 0))
|
self._expiry = int(data_json.get('expiry', 0))
|
||||||
@ -57,8 +57,8 @@ class AuthApi:
|
|||||||
self._id_token = self._refresh(self._refresh_token)
|
self._id_token = self._refresh(self._refresh_token)
|
||||||
self._expiry = now + 3600
|
self._expiry = now + 3600
|
||||||
_LOGGER.debug('Got an id token by refreshing: %s', self._id_token)
|
_LOGGER.debug('Got an id token by refreshing: %s', self._id_token)
|
||||||
except (InvalidLoginException, AuthenticationException) as e:
|
except (InvalidLoginException, AuthenticationException) as exc:
|
||||||
_LOGGER.error('Error logging in: %s', str(e))
|
_LOGGER.error('Error logging in: %s', str(exc))
|
||||||
self._id_token = None
|
self._id_token = None
|
||||||
self._refresh_token = None
|
self._refresh_token = None
|
||||||
self._expiry = 0
|
self._expiry = 0
|
||||||
@ -76,13 +76,13 @@ class AuthApi:
|
|||||||
# Store new tokens in cache
|
# Store new tokens in cache
|
||||||
if not kodiutils.exists(self._cache_dir):
|
if not kodiutils.exists(self._cache_dir):
|
||||||
kodiutils.mkdirs(self._cache_dir)
|
kodiutils.mkdirs(self._cache_dir)
|
||||||
with kodiutils.open_file(self._cache_dir + self.TOKEN_FILE, 'wb') as f:
|
with kodiutils.open_file(self._cache_dir + self.TOKEN_FILE, 'wb') as fdesc:
|
||||||
data = json.dumps(dict(
|
data = json.dumps(dict(
|
||||||
id_token=self._id_token,
|
id_token=self._id_token,
|
||||||
refresh_token=self._refresh_token,
|
refresh_token=self._refresh_token,
|
||||||
expiry=self._expiry,
|
expiry=self._expiry,
|
||||||
))
|
))
|
||||||
f.write(data.encode('utf8'))
|
fdesc.write(data.encode('utf8'))
|
||||||
|
|
||||||
return self._id_token
|
return self._id_token
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ class AwsIdp:
|
|||||||
self.info_bits = bytearray('Caldera Derived Key', 'utf-8')
|
self.info_bits = bytearray('Caldera Derived Key', 'utf-8')
|
||||||
|
|
||||||
self.big_n = self.__hex_to_long(self.n_hex)
|
self.big_n = self.__hex_to_long(self.n_hex)
|
||||||
self.g = self.__hex_to_long(self.g_hex)
|
self.g = self.__hex_to_long(self.g_hex) # pylint: disable=invalid-name
|
||||||
self.k = self.__hex_to_long(self.__hex_hash('00' + self.n_hex + '0' + self.g_hex))
|
self.k = self.__hex_to_long(self.__hex_hash('00' + self.n_hex + '0' + self.g_hex)) # pylint: disable=invalid-name
|
||||||
self.small_a_value = self.__generate_random_small_a()
|
self.small_a_value = self.__generate_random_small_a()
|
||||||
self.large_a_value = self.__calculate_a()
|
self.large_a_value = self.__calculate_a()
|
||||||
_LOGGER.debug("Created %s", self)
|
_LOGGER.debug("Created %s", self)
|
||||||
@ -299,8 +299,8 @@ class AwsIdp:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def __hash_sha256(buf):
|
def __hash_sha256(buf):
|
||||||
"""AuthenticationHelper.hash"""
|
"""AuthenticationHelper.hash"""
|
||||||
a = hashlib.sha256(buf).hexdigest()
|
digest = hashlib.sha256(buf).hexdigest()
|
||||||
return (64 - len(a)) * '0' + a
|
return (64 - len(digest)) * '0' + digest
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __pad_hex(long_int):
|
def __pad_hex(long_int):
|
||||||
|
@ -187,9 +187,9 @@ class ContentApi:
|
|||||||
content_tree = self.get_content_tree(channel)
|
content_tree = self.get_content_tree(channel)
|
||||||
|
|
||||||
programs = []
|
programs = []
|
||||||
for p in content_tree['programs']:
|
for uuid in content_tree['programs']:
|
||||||
try:
|
try:
|
||||||
program = self.get_program_by_uuid(p)
|
program = self.get_program_by_uuid(uuid)
|
||||||
program.channel = channel
|
program.channel = channel
|
||||||
programs.append(program)
|
programs.append(program)
|
||||||
except UnavailableException:
|
except UnavailableException:
|
||||||
@ -211,7 +211,7 @@ class ContentApi:
|
|||||||
data = self._get_url(CHANNELS[channel]['url'])
|
data = self._get_url(CHANNELS[channel]['url'])
|
||||||
|
|
||||||
# Parse programs
|
# Parse programs
|
||||||
h = HTMLParser()
|
parser = HTMLParser()
|
||||||
regex_programs = re.compile(r'<a class="program-overview__link" href="(?P<path>[^"]+)">\s+'
|
regex_programs = re.compile(r'<a class="program-overview__link" href="(?P<path>[^"]+)">\s+'
|
||||||
r'<span class="program-overview__title">\s+(?P<title>[^<]+)</span>.*?'
|
r'<span class="program-overview__title">\s+(?P<title>[^<]+)</span>.*?'
|
||||||
r'</a>', re.DOTALL)
|
r'</a>', re.DOTALL)
|
||||||
@ -228,8 +228,7 @@ class ContentApi:
|
|||||||
# Use program with the values that we've parsed from the page
|
# Use program with the values that we've parsed from the page
|
||||||
programs.append(Program(channel=channel,
|
programs.append(Program(channel=channel,
|
||||||
path=path,
|
path=path,
|
||||||
title=h.unescape(item.group('title').strip())))
|
title=parser.unescape(item.group('title').strip())))
|
||||||
|
|
||||||
return programs
|
return programs
|
||||||
|
|
||||||
def get_program(self, channel, path, cache=CACHE_AUTO):
|
def get_program(self, channel, path, cache=CACHE_AUTO):
|
||||||
@ -314,15 +313,15 @@ class ContentApi:
|
|||||||
page = self._get_url(CHANNELS[channel]['url'] + '/' + path)
|
page = self._get_url(CHANNELS[channel]['url'] + '/' + path)
|
||||||
|
|
||||||
# Extract program JSON
|
# Extract program JSON
|
||||||
h = HTMLParser()
|
parser = HTMLParser()
|
||||||
regex_program = re.compile(r'data-hero="([^"]+)', re.DOTALL)
|
regex_program = re.compile(r'data-hero="([^"]+)', re.DOTALL)
|
||||||
json_data = h.unescape(regex_program.search(page).group(1))
|
json_data = parser.unescape(regex_program.search(page).group(1))
|
||||||
data = json.loads(json_data)['data']
|
data = json.loads(json_data)['data']
|
||||||
program = self._parse_program_data(data)
|
program = self._parse_program_data(data)
|
||||||
|
|
||||||
# Extract episode JSON
|
# Extract episode JSON
|
||||||
regex_episode = re.compile(r'<script type="application/json" data-drupal-selector="drupal-settings-json">(.*?)</script>', re.DOTALL)
|
regex_episode = re.compile(r'<script type="application/json" data-drupal-selector="drupal-settings-json">(.*?)</script>', re.DOTALL)
|
||||||
json_data = h.unescape(regex_episode.search(page).group(1))
|
json_data = parser.unescape(regex_episode.search(page).group(1))
|
||||||
data = json.loads(json_data)
|
data = json.loads(json_data)
|
||||||
|
|
||||||
# Lookup the episode in the program JSON based on the nodeId
|
# Lookup the episode in the program JSON based on the nodeId
|
||||||
|
@ -16,6 +16,7 @@ _LOGGER = logging.getLogger('epg-api')
|
|||||||
class EpgProgram:
|
class EpgProgram:
|
||||||
""" Defines a Program in the EPG. """
|
""" Defines a Program in the EPG. """
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def __init__(self, channel, program_title, episode_title, episode_title_original, number, season, genre, start, won_id, won_program_id, program_description,
|
def __init__(self, channel, program_title, episode_title, episode_title_original, number, season, genre, start, won_id, won_program_id, program_description,
|
||||||
description, duration, program_url, video_url, cover, airing):
|
description, duration, program_url, video_url, cover, airing):
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
|
@ -9,13 +9,13 @@ import unittest
|
|||||||
|
|
||||||
from resources.lib import addon
|
from resources.lib import addon
|
||||||
|
|
||||||
xbmc = __import__('xbmc')
|
xbmc = __import__('xbmc') # pylint: disable=invalid-name
|
||||||
xbmcaddon = __import__('xbmcaddon')
|
xbmcaddon = __import__('xbmcaddon') # pylint: disable=invalid-name
|
||||||
xbmcgui = __import__('xbmcgui')
|
xbmcgui = __import__('xbmcgui') # pylint: disable=invalid-name
|
||||||
xbmcplugin = __import__('xbmcplugin')
|
xbmcplugin = __import__('xbmcplugin') # pylint: disable=invalid-name
|
||||||
xbmcvfs = __import__('xbmcvfs')
|
xbmcvfs = __import__('xbmcvfs') # pylint: disable=invalid-name
|
||||||
|
|
||||||
routing = addon.routing
|
routing = addon.routing # pylint: disable=invalid-name
|
||||||
|
|
||||||
|
|
||||||
class TestRouting(unittest.TestCase):
|
class TestRouting(unittest.TestCase):
|
||||||
|
3
tox.ini
3
tox.ini
@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27,py36,py37,flake8
|
envlist = py27,py36,py37,py38,flake8
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
skip_missing_interpreters = True
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
@ -17,6 +17,7 @@ max-line-length = 160
|
|||||||
ignore = FI13,FI50,FI51,FI53,FI54,W503
|
ignore = FI13,FI50,FI51,FI53,FI54,W503
|
||||||
require-code = True
|
require-code = True
|
||||||
min-version = 2.7
|
min-version = 2.7
|
||||||
|
exclude = .git,.tox
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
filterwarnings = default
|
filterwarnings = default
|
||||||
|
Loading…
Reference in New Issue
Block a user