mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 10:16:11 +00:00
Rework xml unicode handling
This commit is contained in:
parent
183c05919e
commit
bb0a539074
4 changed files with 57 additions and 68 deletions
|
@ -13,8 +13,6 @@ from .utils import event
|
||||||
from .utils import validate
|
from .utils import validate
|
||||||
from .utils import values
|
from .utils import values
|
||||||
from .utils import JSONRPC
|
from .utils import JSONRPC
|
||||||
from .utils import indent
|
|
||||||
from .utils import write_xml
|
|
||||||
from .utils import compare_version
|
from .utils import compare_version
|
||||||
from .utils import unzip
|
from .utils import unzip
|
||||||
from .utils import create_id
|
from .utils import create_id
|
||||||
|
|
|
@ -266,44 +266,6 @@ def values(item, keys):
|
||||||
return (item[key.replace('{', "").replace('}', "")] if isinstance(key, text_type) and key.startswith('{') else key for key in keys)
|
return (item[key.replace('{', "").replace('}', "")] if isinstance(key, text_type) and key.startswith('{') else key for key in keys)
|
||||||
|
|
||||||
|
|
||||||
def indent(elem, level=0):
|
|
||||||
|
|
||||||
''' Prettify xml docs.
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
i = "\n" + level * " "
|
|
||||||
if len(elem):
|
|
||||||
if not elem.text or not elem.text.strip():
|
|
||||||
elem.text = i + " "
|
|
||||||
if not elem.tail or not elem.tail.strip():
|
|
||||||
elem.tail = i
|
|
||||||
for elem in elem:
|
|
||||||
indent(elem, level + 1)
|
|
||||||
if not elem.tail or not elem.tail.strip():
|
|
||||||
elem.tail = i
|
|
||||||
else:
|
|
||||||
if level and (not elem.tail or not elem.tail.strip()):
|
|
||||||
elem.tail = i
|
|
||||||
except Exception as error:
|
|
||||||
LOG.exception(error)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def write_xml(content, file):
|
|
||||||
if isinstance(content, text_type):
|
|
||||||
content = content.encode('utf-8')
|
|
||||||
|
|
||||||
with open(file, 'wb') as infile:
|
|
||||||
|
|
||||||
# replace apostrophes with double quotes only in xml keys, not texts
|
|
||||||
def replace_apostrophes(match):
|
|
||||||
return match.group(0).replace(b"'", b'"')
|
|
||||||
content = re.sub(b"<(.*?)>", replace_apostrophes, content)
|
|
||||||
|
|
||||||
content = content.replace(b'?>', b' standalone="yes" ?>', 1)
|
|
||||||
infile.write(content)
|
|
||||||
|
|
||||||
|
|
||||||
def delete_folder(path):
|
def delete_folder(path):
|
||||||
|
|
||||||
''' Delete objects from kodi cache
|
''' Delete objects from kodi cache
|
||||||
|
|
|
@ -5,11 +5,11 @@ from __future__ import division, absolute_import, print_function, unicode_litera
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import xml.etree.ElementTree as etree
|
from lxml import etree
|
||||||
|
|
||||||
from kodi_six import xbmc
|
from kodi_six import xbmc
|
||||||
|
|
||||||
from . import translate, indent, write_xml, dialog, settings
|
from . import translate, dialog, settings
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@ def sources():
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.exception(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
|
|
||||||
def tvtunes_nfo(path, urls):
|
def tvtunes_nfo(path, urls):
|
||||||
|
@ -95,8 +95,8 @@ def tvtunes_nfo(path, urls):
|
||||||
for url in urls:
|
for url in urls:
|
||||||
etree.SubElement(xml, 'file').text = url
|
etree.SubElement(xml, 'file').text = url
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), path)
|
tree.write(path, pretty_print=True)
|
||||||
|
|
||||||
|
|
||||||
def advanced_settings():
|
def advanced_settings():
|
||||||
|
@ -125,8 +125,8 @@ def advanced_settings():
|
||||||
LOG.warning("cleanonupdate disabled")
|
LOG.warning("cleanonupdate disabled")
|
||||||
video.remove(cleanonupdate)
|
video.remove(cleanonupdate)
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), path)
|
tree.write(path, pretty_print=True)
|
||||||
|
|
||||||
dialog("ok", heading="{jellyfin}", line1=translate(33097))
|
dialog("ok", heading="{jellyfin}", line1=translate(33097))
|
||||||
xbmc.executebuiltin('RestartApp')
|
xbmc.executebuiltin('RestartApp')
|
||||||
|
|
|
@ -6,13 +6,13 @@ from __future__ import division, absolute_import, print_function, unicode_litera
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import xml.etree.ElementTree as etree
|
from lxml import etree
|
||||||
|
|
||||||
from six.moves.urllib.parse import urlencode
|
from six.moves.urllib.parse import urlencode
|
||||||
from kodi_six import xbmc, xbmcvfs
|
from kodi_six import xbmc, xbmcvfs
|
||||||
|
|
||||||
from database import Database, jellyfin_db, get_sync, save_sync
|
from database import Database, jellyfin_db, get_sync, save_sync
|
||||||
from helper import translate, api, indent, write_xml, window, event
|
from helper import translate, api, window, event
|
||||||
from jellyfin import Jellyfin
|
from jellyfin import Jellyfin
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
@ -126,8 +126,8 @@ def verify_kodi_defaults():
|
||||||
|
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
xml.set('order', str(17 + index))
|
xml.set('order', str(17 + index))
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
playlist_path = xbmc.translatePath("special://profile/playlists/video")
|
playlist_path = xbmc.translatePath("special://profile/playlists/video")
|
||||||
|
|
||||||
|
@ -272,7 +272,12 @@ class Views(object):
|
||||||
file = os.path.join(path, "jellyfin%s%s.xsp" % (view['Media'], view['Id']))
|
file = os.path.join(path, "jellyfin%s%s.xsp" % (view['Media'], view['Id']))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
if os.path.isfile(file):
|
||||||
|
xml = etree.parse(file).getroot()
|
||||||
|
else:
|
||||||
|
xml = etree.Element('smartplaylist', {'type': view['Media']})
|
||||||
|
etree.SubElement(xml, 'name')
|
||||||
|
etree.SubElement(xml, 'match')
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning("Unable to parse file '%s'", file)
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = etree.Element('smartplaylist', {'type': view['Media']})
|
xml = etree.Element('smartplaylist', {'type': view['Media']})
|
||||||
|
@ -292,8 +297,8 @@ class Views(object):
|
||||||
rule = etree.SubElement(xml, 'rule', {'field': "tag", 'operator': "is"})
|
rule = etree.SubElement(xml, 'rule', {'field': "tag", 'operator': "is"})
|
||||||
etree.SubElement(rule, 'value').text = view['Tag']
|
etree.SubElement(rule, 'value').text = view['Tag']
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
def add_nodes(self, path, view, mixed=False):
|
def add_nodes(self, path, view, mixed=False):
|
||||||
|
|
||||||
|
@ -316,7 +321,13 @@ class Views(object):
|
||||||
file = os.path.join(path, "jellyfin_%s.xml" % view['Tag'].replace(" ", ""))
|
file = os.path.join(path, "jellyfin_%s.xml" % view['Tag'].replace(" ", ""))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
if os.path.isfile(file):
|
||||||
|
xml = etree.parse(file).getroot()
|
||||||
|
else:
|
||||||
|
xml = self.node_root('folder' if item_type == 'favorites' and view['Media'] == 'episodes' else 'filter', index)
|
||||||
|
etree.SubElement(xml, 'label')
|
||||||
|
etree.SubElement(xml, 'match')
|
||||||
|
etree.SubElement(xml, 'content')
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning("Unable to parse file '%s'", file)
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('folder' if item_type == 'favorites' and view['Media'] == 'episodes' else 'filter', index)
|
xml = self.node_root('folder' if item_type == 'favorites' and view['Media'] == 'episodes' else 'filter', index)
|
||||||
|
@ -348,8 +359,8 @@ class Views(object):
|
||||||
else:
|
else:
|
||||||
self.node_all(xml)
|
self.node_all(xml)
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
def node_root(self, root, index):
|
def node_root(self, root, index):
|
||||||
|
|
||||||
|
@ -372,8 +383,14 @@ class Views(object):
|
||||||
index = self.sync['SortedViews'].index(view['Id'])
|
index = self.sync['SortedViews'].index(view['Id'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
if os.path.isfile(file):
|
||||||
xml.set('order', str(index))
|
xml = etree.parse(file).getroot()
|
||||||
|
xml.set('order', str(index))
|
||||||
|
else:
|
||||||
|
xml = self.node_root('filter', index)
|
||||||
|
etree.SubElement(xml, 'label')
|
||||||
|
etree.SubElement(xml, 'match')
|
||||||
|
etree.SubElement(xml, 'content')
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.exception(error)
|
LOG.exception(error)
|
||||||
xml = self.node_root('main', index)
|
xml = self.node_root('main', index)
|
||||||
|
@ -382,8 +399,8 @@ class Views(object):
|
||||||
label = xml.find('label')
|
label = xml.find('label')
|
||||||
label.text = view['Name'] if not mixed else "%s (%s)" % (view['Name'], translate(view['Media']))
|
label.text = view['Name'] if not mixed else "%s (%s)" % (view['Name'], translate(view['Media']))
|
||||||
|
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
def node(self, folder, view):
|
def node(self, folder, view):
|
||||||
|
|
||||||
|
@ -412,7 +429,14 @@ class Views(object):
|
||||||
def add_node(self, index, file, view, node, name):
|
def add_node(self, index, file, view, node, name):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
if os.path.isfile(file):
|
||||||
|
xml = etree.parse(file).getroot()
|
||||||
|
else:
|
||||||
|
xml = self.node_root('filter', index)
|
||||||
|
etree.SubElement(xml, 'label')
|
||||||
|
etree.SubElement(xml, 'match')
|
||||||
|
etree.SubElement(xml, 'content')
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning("Unable to parse file '%s'", file)
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('filter', index)
|
xml = self.node_root('filter', index)
|
||||||
|
@ -437,13 +461,18 @@ class Views(object):
|
||||||
etree.SubElement(rule, 'value').text = view['Tag']
|
etree.SubElement(rule, 'value').text = view['Tag']
|
||||||
|
|
||||||
getattr(self, 'node_' + node)(xml) # get node function based on node type
|
getattr(self, 'node_' + node)(xml) # get node function based on node type
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
def add_dynamic_node(self, index, file, view, node, name, path):
|
def add_dynamic_node(self, index, file, view, node, name, path):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
if os.path.isfile(file):
|
||||||
|
xml = etree.parse(file).getroot()
|
||||||
|
else:
|
||||||
|
xml = self.node_root('filter', index)
|
||||||
|
etree.SubElement(xml, 'label')
|
||||||
|
etree.SubElement(xml, 'content')
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning("Unable to parse file '%s'", file)
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('folder', index)
|
xml = self.node_root('folder', index)
|
||||||
|
@ -454,8 +483,8 @@ class Views(object):
|
||||||
label.text = name
|
label.text = name
|
||||||
|
|
||||||
getattr(self, 'node_' + node)(xml, path)
|
getattr(self, 'node_' + node)(xml, path)
|
||||||
indent(xml)
|
tree = etree.ElementTree(xml)
|
||||||
write_xml(etree.tostring(xml, 'UTF-8'), file)
|
tree.write(file, pretty_print=True)
|
||||||
|
|
||||||
def node_all(self, root):
|
def node_all(self, root):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue