mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 02:06:09 +00:00
Merge pull request #366 from oddstr13/pr-json-filter-1
Filter keys containing None values from dictionaries returned from the server
This commit is contained in:
commit
4e2c8a0af3
20 changed files with 214 additions and 26 deletions
|
@ -1,9 +1,11 @@
|
|||
import xml.etree.ElementTree as ET
|
||||
import yaml
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def indent(elem, level=0):
|
||||
'''
|
||||
Nicely formats output xml with newlines and spaces
|
||||
|
@ -23,6 +25,7 @@ def indent(elem, level=0):
|
|||
if level and (not elem.tail or not elem.tail.strip()):
|
||||
elem.tail = i
|
||||
|
||||
|
||||
try:
|
||||
py_version = sys.argv[1]
|
||||
except IndexError:
|
||||
|
|
66
.gitignore
vendored
66
.gitignore
vendored
|
@ -1,12 +1,72 @@
|
|||
*.pyo
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
|
||||
|
||||
__local__/
|
||||
machine_guid
|
||||
/resources/media/Thumbs.db
|
||||
Thumbs.db
|
||||
|
||||
.idea/
|
||||
.DS_Store
|
||||
.vscode/
|
||||
pyinstrument/
|
||||
pyinstrument_cext.so
|
||||
|
||||
# Now managed by templates
|
||||
addon.xml
|
||||
|
||||
*.log
|
||||
|
|
|
@ -17,8 +17,8 @@ sys.path.insert(0, __base__)
|
|||
|
||||
#################################################################################################
|
||||
|
||||
from entrypoint import Context # noqa: F402
|
||||
from helper import LazyLogger # noqa: F402
|
||||
from entrypoint import Context # noqa: E402
|
||||
from helper import LazyLogger # noqa: E402
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ sys.path.insert(0, __base__)
|
|||
|
||||
#################################################################################################
|
||||
|
||||
from entrypoint import Context # noqa: F402
|
||||
from helper import LazyLogger # noqa: F402
|
||||
from entrypoint import Context # noqa: E402
|
||||
from helper import LazyLogger # noqa: E402
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ sys.path.insert(0, __base__)
|
|||
|
||||
#################################################################################################
|
||||
|
||||
from entrypoint import Events # noqa: F402
|
||||
from helper import LazyLogger # noqa: F402
|
||||
from entrypoint import Events # noqa: E402
|
||||
from helper import LazyLogger # noqa: E402
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ def get_library_items(library_id, item_type):
|
|||
|
||||
return _get(url, params)
|
||||
|
||||
|
||||
def get_albums_by_artist(artist_id, basic=False):
|
||||
|
||||
params = {
|
||||
|
|
|
@ -11,6 +11,7 @@ from six import string_types, ensure_str
|
|||
from helper.utils import JsonDebugPrinter
|
||||
from helper import LazyLogger
|
||||
from helper.exceptions import HTTPException
|
||||
from jellyfin.utils import clean_none_dict_values
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
@ -161,7 +162,7 @@ class HTTP(object):
|
|||
LOG.debug("---<[ http ][%s ms]", elapsed)
|
||||
LOG.debug(JsonDebugPrinter(response))
|
||||
|
||||
return response
|
||||
return clean_none_dict_values(response)
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
|
|
43
jellyfin_kodi/jellyfin/utils.py
Normal file
43
jellyfin_kodi/jellyfin/utils.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from six import string_types
|
||||
from six.moves import collections_abc
|
||||
|
||||
|
||||
def clean_none_dict_values(obj):
|
||||
"""
|
||||
Recursively remove keys with a value of None
|
||||
"""
|
||||
if not isinstance(obj, collections_abc.Iterable) or isinstance(obj, string_types):
|
||||
return obj
|
||||
|
||||
queue = [obj]
|
||||
|
||||
while queue:
|
||||
item = queue.pop()
|
||||
|
||||
if isinstance(item, collections_abc.Mapping):
|
||||
mutable = isinstance(item, collections_abc.MutableMapping)
|
||||
remove = []
|
||||
|
||||
for key, value in item.items():
|
||||
if value is None and mutable:
|
||||
remove.append(key)
|
||||
|
||||
elif isinstance(value, string_types):
|
||||
continue
|
||||
|
||||
elif isinstance(value, collections_abc.Iterable):
|
||||
queue.append(value)
|
||||
|
||||
if mutable:
|
||||
# Remove keys with None value
|
||||
for key in remove:
|
||||
item.pop(key)
|
||||
|
||||
elif isinstance(item, collections_abc.Iterable):
|
||||
for value in item:
|
||||
if value is None or isinstance(value, string_types):
|
||||
continue
|
||||
elif isinstance(value, collections_abc.Iterable):
|
||||
queue.append(value)
|
||||
|
||||
return obj
|
13
requirements-dev.txt
Normal file
13
requirements-dev.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
setuptools >= 44.1.1 # Old setuptools causes script.module.addon.signals to fail installing
|
||||
six >= 1.13
|
||||
python-dateutil >= 2.8.1
|
||||
requests >= 2.22
|
||||
futures >= 2.2; python_version < '3.0'
|
||||
git+https://github.com/oddstr13/Kodistubs@python3 # Kodistubs >= 18
|
||||
git+https://github.com/romanvm/kodi.six
|
||||
git+https://github.com/ruuk/script.module.addon.signals
|
||||
|
||||
pytest >= 4.6.11
|
||||
coverage >= 5.2
|
||||
flake8 >= 3.8
|
||||
flake8-import-order >= 0.18
|
|
@ -18,9 +18,9 @@ sys.path.insert(0, __base__)
|
|||
|
||||
#################################################################################################
|
||||
|
||||
from entrypoint import Service # noqa: F402
|
||||
from helper.utils import settings # noqa: F402
|
||||
from helper import LazyLogger # noqa: F402
|
||||
from entrypoint import Service # noqa: E402
|
||||
from helper.utils import settings # noqa: E402
|
||||
from helper import LazyLogger # noqa: E402
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
51
tests/test_clean_none_dict_values.py
Normal file
51
tests/test_clean_none_dict_values.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, 'jellyfin_kodi')
|
||||
|
||||
from jellyfin.utils import clean_none_dict_values # noqa: E402
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj,expected", [
|
||||
(None, None),
|
||||
([None, 1, 2, 3, None, 4], [None, 1, 2, 3, None, 4]),
|
||||
({'foo': None, 'bar': 123}, {'bar': 123}),
|
||||
({
|
||||
'dict': {
|
||||
'empty': None,
|
||||
'string': "Hello, Woorld!",
|
||||
},
|
||||
'number': 123,
|
||||
'list': [
|
||||
None,
|
||||
123,
|
||||
"foo",
|
||||
{
|
||||
'empty': None,
|
||||
'number': 123,
|
||||
'string': "foo",
|
||||
'list': [],
|
||||
'dict': {},
|
||||
}
|
||||
]
|
||||
}, {
|
||||
'dict': {
|
||||
'string': "Hello, Woorld!",
|
||||
},
|
||||
'number': 123,
|
||||
'list': [
|
||||
None,
|
||||
123,
|
||||
"foo",
|
||||
{
|
||||
'number': 123,
|
||||
'string': "foo",
|
||||
'list': [],
|
||||
'dict': {},
|
||||
}
|
||||
]
|
||||
}),
|
||||
])
|
||||
def test_clean_none_dict_values(obj, expected):
|
||||
assert clean_none_dict_values(obj) == expected
|
16
tox.ini
16
tox.ini
|
@ -6,3 +6,19 @@ extend-ignore =
|
|||
I202
|
||||
per-file-ignores =
|
||||
*/__init__.py: F401
|
||||
|
||||
[pytest]
|
||||
minversion = 4.6
|
||||
testpaths =
|
||||
tests
|
||||
|
||||
[coverage:run]
|
||||
source =
|
||||
jellyfin_kodi
|
||||
context.py
|
||||
context_play.py
|
||||
default.py
|
||||
service.py
|
||||
.config/generate_xml.py
|
||||
omit = tests/*
|
||||
command_line = -m pytest
|
||||
|
|
Loading…
Reference in a new issue