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:
Dag Wieers 2020-03-25 08:08:15 +01:00 committed by GitHub
parent 3281c41e21
commit b282b3ef34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 48 deletions

View File

@ -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

View File

@ -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

View File

@ -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')

View File

@ -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,
} }

View File

@ -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')

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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