From 436b1fda837e6871787086167189c4ad9a87c6a0 Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 18 Dec 2020 17:10:20 +0100 Subject: [PATCH] Automatically convert source code from Python 2 to 3 using futurize --- contextmenu.py | 4 +- default.py | 9 ++- resources/lib/app/account.py | 1 + resources/lib/app/application.py | 9 ++- resources/lib/app/connection.py | 1 + resources/lib/app/libsync.py | 1 + resources/lib/app/playstate.py | 1 + resources/lib/backgroundthread.py | 25 ++++--- resources/lib/clientinfo.py | 1 + resources/lib/companion.py | 2 +- resources/lib/context_entry.py | 1 + resources/lib/downloadutils.py | 3 +- resources/lib/entrypoint.py | 1 + resources/lib/initialsetup.py | 3 + resources/lib/itemtypes/common.py | 3 +- resources/lib/itemtypes/music.py | 1 + resources/lib/itemtypes/tvshows.py | 1 + resources/lib/json_rpc.py | 3 +- resources/lib/kodi_db/common.py | 5 +- resources/lib/kodi_db/video.py | 4 +- resources/lib/library_sync/common.py | 2 + .../lib/library_sync/fill_metadata_queue.py | 4 +- resources/lib/library_sync/full_sync.py | 9 ++- resources/lib/library_sync/nodes.py | 33 +++++---- resources/lib/library_sync/sections.py | 15 ++-- resources/lib/library_sync/websocket.py | 3 +- resources/lib/loghandler.py | 2 +- resources/lib/migration.py | 1 + resources/lib/pathtools/path.py | 3 +- resources/lib/pathtools/patterns.py | 1 + resources/lib/playback.py | 5 +- resources/lib/playlist_func.py | 1 + resources/lib/playlists/common.py | 7 +- resources/lib/playlists/db.py | 1 + resources/lib/playlists/pms.py | 3 +- resources/lib/playqueue.py | 1 + resources/lib/plex_api/artwork.py | 5 +- resources/lib/plex_api/base.py | 8 +- resources/lib/plex_api/fanart_lookup.py | 2 + resources/lib/plex_api/file.py | 1 + resources/lib/plex_api/media.py | 1 + resources/lib/plex_api/playback.py | 1 + resources/lib/plex_api/user.py | 1 + resources/lib/plex_companion.py | 4 +- resources/lib/plex_db/common.py | 1 + resources/lib/plex_db/movies.py | 1 + resources/lib/plex_db/music.py | 1 + resources/lib/plex_db/playlists.py | 1 + resources/lib/plex_db/sections.py | 1 + resources/lib/plex_db/tvshows.py | 1 + resources/lib/plex_functions.py | 7 +- resources/lib/plex_tv.py | 1 + resources/lib/plexbmchelper/httppersist.py | 14 ++-- resources/lib/plexbmchelper/listener.py | 6 +- resources/lib/plexbmchelper/plexgdm.py | 4 +- resources/lib/plexbmchelper/subscribers.py | 20 +++-- resources/lib/service_entry.py | 1 + resources/lib/tools/unicode_paths.py | 2 +- resources/lib/transfer.py | 14 ++-- resources/lib/utils.py | 74 ++++++++++--------- resources/lib/variables.py | 2 +- resources/lib/watchdog/events.py | 1 + resources/lib/watchdog/observers/api.py | 1 + resources/lib/watchdog/observers/fsevents.py | 2 +- resources/lib/watchdog/observers/fsevents2.py | 8 +- resources/lib/watchdog/observers/inotify_c.py | 1 + resources/lib/watchdog/observers/kqueue.py | 1 + resources/lib/watchdog/observers/winapi.py | 3 +- resources/lib/watchdog/utils/__init__.py | 3 +- resources/lib/watchdog/utils/bricks.py | 2 + resources/lib/watchdog/utils/compat.py | 4 +- resources/lib/watchdog/utils/decorators.py | 1 + resources/lib/watchdog/utils/delayed_queue.py | 1 + resources/lib/watchdog/utils/dirsnapshot.py | 2 + resources/lib/watchdog/utils/echo.py | 2 + .../lib/watchdog/utils/event_backport.py | 1 + resources/lib/watchdog/utils/importlib2.py | 2 +- resources/lib/watchdog/utils/unicode_paths.py | 2 +- resources/lib/watchdog/utils/win32stat.py | 4 +- resources/lib/watchdog/watchmedo.py | 6 +- resources/lib/websocket.py | 22 ++++-- resources/lib/widgets.py | 9 ++- resources/lib/windows/direct_path_sources.py | 8 +- resources/lib/windows/kodigui.py | 26 ++++--- resources/lib/windows/userselect.py | 1 + 85 files changed, 297 insertions(+), 160 deletions(-) diff --git a/contextmenu.py b/contextmenu.py index dfc7546e..88b8448d 100644 --- a/contextmenu.py +++ b/contextmenu.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- ############################################################################### from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() from sys import listitem -from urllib import urlencode +from urllib.parse import urlencode from xbmc import getCondVisibility, sleep from xbmcgui import Window diff --git a/default.py b/default.py index 149f145e..770f2a00 100644 --- a/default.py +++ b/default.py @@ -2,9 +2,12 @@ ############################################################################### from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import object import logging from sys import argv -from urlparse import parse_qsl +from urllib.parse import parse_qsl import xbmc import xbmcgui @@ -23,7 +26,7 @@ LOG = logging.getLogger('PLEX.default') HANDLE = int(argv[1]) -class Main(): +class Main(object): # MAIN ENTRY POINT # @utils.profiling() def __init__(self): @@ -33,7 +36,7 @@ class Main(): arguments = unicode_paths.decode(argv[2]) path = unicode_paths.decode(argv[0]) # Ensure unicode - for key, value in params.iteritems(): + for key, value in params.items(): params[key.decode('utf-8')] = params.pop(key) params[key] = value.decode('utf-8') mode = params.get('mode', '') diff --git a/resources/lib/app/account.py b/resources/lib/app/account.py index 3a8ffb7f..67da18da 100644 --- a/resources/lib/app/account.py +++ b/resources/lib/app/account.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from .. import utils diff --git a/resources/lib/app/application.py b/resources/lib/app/application.py index 79608afd..f2c46ba5 100644 --- a/resources/lib/app/application.py +++ b/resources/lib/app/application.py @@ -1,8 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import object from logging import getLogger -import Queue +import queue from threading import Lock, RLock import xbmc @@ -38,9 +41,9 @@ class App(object): self.lock_playlists = Lock() # Plex Companion Queue() - self.companion_queue = Queue.Queue(maxsize=100) + self.companion_queue = queue.Queue(maxsize=100) # Websocket_client queue to communicate with librarysync - self.websocket_queue = Queue.Queue() + self.websocket_queue = queue.Queue() # xbmc.Monitor() instance from kodimonitor.py self.monitor = None # xbmc.Player() instance diff --git a/resources/lib/app/connection.py b/resources/lib/app/connection.py index 303ff165..c3d0531d 100644 --- a/resources/lib/app/connection.py +++ b/resources/lib/app/connection.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from .. import utils, json_rpc as js, variables as v diff --git a/resources/lib/app/libsync.py b/resources/lib/app/libsync.py index c49db72b..66833072 100644 --- a/resources/lib/app/libsync.py +++ b/resources/lib/app/libsync.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from .. import utils diff --git a/resources/lib/app/playstate.py b/resources/lib/app/playstate.py index 13d61ac3..caebfb8f 100644 --- a/resources/lib/app/playstate.py +++ b/resources/lib/app/playstate.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, unicode_literals +from builtins import object class PlayState(object): # "empty" dict for the PLAYER_STATES above. Use copy.deepcopy to duplicate! template = { diff --git a/resources/lib/backgroundthread.py b/resources/lib/backgroundthread.py index 831b3274..a1f5724f 100644 --- a/resources/lib/backgroundthread.py +++ b/resources/lib/backgroundthread.py @@ -1,10 +1,15 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import range +from builtins import object from logging import getLogger from time import time as _time import threading -import Queue +import queue import heapq from collections import deque @@ -113,7 +118,7 @@ class KillableThread(threading.Thread): self._suspension_reached.set() -class ProcessingQueue(Queue.Queue, object): +class ProcessingQueue(queue.Queue, object): """ Queue of queues that processes a queue completely before moving on to the next queue. There's one queue per Section(). You need to initialize each @@ -148,7 +153,7 @@ class ProcessingQueue(Queue.Queue, object): if self.maxsize > 0: if not block: if self._total_qsize() == self.maxsize: - raise Queue.Full + raise queue.Full elif timeout is None: while self._total_qsize() == self.maxsize: self.not_full.wait() @@ -159,7 +164,7 @@ class ProcessingQueue(Queue.Queue, object): while self._total_qsize() == self.maxsize: remaining = endtime - _time() if remaining <= 0.0: - raise Queue.Full + raise queue.Full self.not_full.wait(remaining) self._put(item) self.unfinished_tasks += 1 @@ -212,7 +217,7 @@ class ProcessingQueue(Queue.Queue, object): self._sections.append(section) self._queues.append( OrderedQueue() if section.plex_type == v.PLEX_TYPE_ALBUM - else Queue.Queue()) + else queue.Queue()) if self._current_section is None: self._activate_next_section() @@ -237,7 +242,7 @@ class ProcessingQueue(Queue.Queue, object): return item[1] -class OrderedQueue(Queue.PriorityQueue, object): +class OrderedQueue(queue.PriorityQueue, object): """ Queue that enforces an order on the items it returns. An item you push onto the queue must be a tuple @@ -328,7 +333,7 @@ class FunctionAsTask(Task): self._callback(result) -class MutablePriorityQueue(Queue.PriorityQueue): +class MutablePriorityQueue(queue.PriorityQueue): def _get(self, heappop=heapq.heappop): self.queue.sort() return heappop(self.queue) @@ -388,7 +393,7 @@ class BackgroundWorker(object): self._runTask(self._task) self._queue.task_done() self._task = None - except Queue.Empty: + except queue.Empty: LOG.debug('(%s): Idle', self.name) def shutdown(self, block=True): @@ -428,7 +433,7 @@ class NonstoppingBackgroundWorker(BackgroundWorker): return self._working -class BackgroundThreader: +class BackgroundThreader(object): def __init__(self, name=None, worker=BackgroundWorker, worker_count=6): self.name = name self._queue = MutablePriorityQueue() @@ -508,7 +513,7 @@ class BackgroundThreader: qitem.priority = lowest - 1 -class ThreaderManager: +class ThreaderManager(object): def __init__(self, worker=NonstoppingBackgroundWorker, worker_count=WORKER_COUNT): diff --git a/resources/lib/clientinfo.py b/resources/lib/clientinfo.py index 48df4554..626dfba1 100644 --- a/resources/lib/clientinfo.py +++ b/resources/lib/clientinfo.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger import xbmc diff --git a/resources/lib/companion.py b/resources/lib/companion.py index bb068159..2636f661 100644 --- a/resources/lib/companion.py +++ b/resources/lib/companion.py @@ -28,7 +28,7 @@ def skip_to(params): LOG.debug('Skipping to playQueueItemID %s, plex_id %s', playqueue_item_id, plex_id) found = True - for player in js.get_players().values(): + for player in list(js.get_players().values()): playqueue = PQ.PLAYQUEUES[player['playerid']] for i, item in enumerate(playqueue.items): if item.id == playqueue_item_id: diff --git a/resources/lib/context_entry.py b/resources/lib/context_entry.py index bbdd2c60..6dda7352 100644 --- a/resources/lib/context_entry.py +++ b/resources/lib/context_entry.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger import xbmc import xbmcgui diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 678876c4..3d5de800 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger import requests import requests.exceptions as exceptions @@ -18,7 +19,7 @@ LOG = getLogger('PLEX.download') ############################################################################### -class DownloadUtils(): +class DownloadUtils(object): """ Manages any up/downloads with PKC. Careful to initiate correctly Use startSession() to initiate. diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index 7983f5f0..694f3a64 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -5,6 +5,7 @@ Loads of different functions called in SEPARATE Python instances through e.g. plugin://... calls. Hence be careful to only rely on window variables. """ from __future__ import absolute_import, division, unicode_literals +from builtins import range from logging import getLogger import sys diff --git a/resources/lib/initialsetup.py b/resources/lib/initialsetup.py index b8536dec..4ffd36b8 100644 --- a/resources/lib/initialsetup.py +++ b/resources/lib/initialsetup.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import range +from builtins import object from logging import getLogger from xbmc import executebuiltin diff --git a/resources/lib/itemtypes/common.py b/resources/lib/itemtypes/common.py index e2d9323f..c9fa16c2 100644 --- a/resources/lib/itemtypes/common.py +++ b/resources/lib/itemtypes/common.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from ntpath import dirname @@ -162,7 +163,7 @@ class ItemBase(object): Returns a dict of the Kodi ids: {: } """ kodi_unique_ids = api.guids.copy() - for provider, provider_id in api.guids.iteritems(): + for provider, provider_id in api.guids.items(): kodi_unique_ids[provider] = self.kodidb.add_uniqueid( kodi_id, api.kodi_type, diff --git a/resources/lib/itemtypes/music.py b/resources/lib/itemtypes/music.py index 7e2721cc..353705fb 100644 --- a/resources/lib/itemtypes/music.py +++ b/resources/lib/itemtypes/music.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from .common import ItemBase diff --git a/resources/lib/itemtypes/tvshows.py b/resources/lib/itemtypes/tvshows.py index 632d7f2c..0a2894a4 100644 --- a/resources/lib/itemtypes/tvshows.py +++ b/resources/lib/itemtypes/tvshows.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from .common import ItemBase, process_path diff --git a/resources/lib/json_rpc.py b/resources/lib/json_rpc.py index 165b0a37..4547b20d 100644 --- a/resources/lib/json_rpc.py +++ b/resources/lib/json_rpc.py @@ -5,6 +5,7 @@ Collection of functions using the Kodi JSON RPC interface. See http://kodi.wiki/view/JSON-RPC_API """ from __future__ import absolute_import, division, unicode_literals +from builtins import object from json import loads, dumps from xbmc import executeJSONRPC @@ -85,7 +86,7 @@ def get_player_ids(): Returns a list of all the active Kodi player ids (usually 3) as int """ ret = [] - for player in get_players().values(): + for player in list(get_players().values()): ret.append(player['playerid']) return ret diff --git a/resources/lib/kodi_db/common.py b/resources/lib/kodi_db/common.py index e362ca6c..e249de25 100644 --- a/resources/lib/kodi_db/common.py +++ b/resources/lib/kodi_db/common.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from threading import Lock from .. import db, path_ops @@ -65,7 +66,7 @@ class KodiDBBase(object): """ Pass in an artworks dict (see PlexAPI) to set an items artwork. """ - for kodi_art, url in artworks.iteritems(): + for kodi_art, url in artworks.items(): self.add_art(url, kodi_id, kodi_type, kodi_art) @db.catch_operationalerrors @@ -84,7 +85,7 @@ class KodiDBBase(object): """ Pass in an artworks dict (see PlexAPI) to set an items artwork. """ - for kodi_art, url in artworks.iteritems(): + for kodi_art, url in artworks.items(): self.modify_art(url, kodi_id, kodi_type, kodi_art) @db.catch_operationalerrors diff --git a/resources/lib/kodi_db/video.py b/resources/lib/kodi_db/video.py index 2466e5e3..5bd7f1f4 100644 --- a/resources/lib/kodi_db/video.py +++ b/resources/lib/kodi_db/video.py @@ -318,7 +318,7 @@ class KodiVideoDB(common.KodiDBBase): for the elmement kodi_id, kodi_type. Will also delete a freshly orphaned actor entry. """ - for kind, people_list in people.iteritems(): + for kind, people_list in people.items(): self._add_people_kind(kodi_id, kodi_type, kind, people_list) @db.catch_operationalerrors @@ -363,7 +363,7 @@ class KodiVideoDB(common.KodiDBBase): for kind, people_list in (people if people else {'actor': [], 'director': [], - 'writer': []}).iteritems(): + 'writer': []}).items(): self._modify_people_kind(kodi_id, kodi_type, kind, people_list) @db.catch_operationalerrors diff --git a/resources/lib/library_sync/common.py b/resources/lib/library_sync/common.py index a0f43285..2432dc33 100644 --- a/resources/lib/library_sync/common.py +++ b/resources/lib/library_sync/common.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import next +from builtins import object from logging import getLogger import xbmc diff --git a/resources/lib/library_sync/fill_metadata_queue.py b/resources/lib/library_sync/fill_metadata_queue.py index 492db28c..9f006c10 100644 --- a/resources/lib/library_sync/fill_metadata_queue.py +++ b/resources/lib/library_sync/fill_metadata_queue.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() from logging import getLogger -from Queue import Full +from queue import Full from . import common, sections from ..plex_db import PlexDB diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index cdb85e30..b8970335 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -1,8 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import range from logging import getLogger -import Queue +import queue import xbmcgui @@ -80,7 +83,7 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread): @utils.log_time def process_new_and_changed_items(self, section_queue, processing_queue): LOG.debug('Start working') - get_metadata_queue = Queue.Queue(maxsize=BACKLOG_QUEUE_SIZE) + get_metadata_queue = queue.Queue(maxsize=BACKLOG_QUEUE_SIZE) scanner_thread = FillMetadataQueue(self.repair, section_queue, get_metadata_queue, @@ -182,7 +185,7 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread): LOG.debug('Exiting threaded_get_generators') def full_library_sync(self): - section_queue = Queue.Queue() + section_queue = queue.Queue() processing_queue = bg.ProcessingQueue(maxsize=XML_QUEUE_SIZE) kinds = [ (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_MOVIE), diff --git a/resources/lib/library_sync/nodes.py b/resources/lib/library_sync/nodes.py index 59097a6e..8a8fb123 100644 --- a/resources/lib/library_sync/nodes.py +++ b/resources/lib/library_sync/nodes.py @@ -1,7 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals -import urllib +from future import standard_library +standard_library.install_aliases() +from builtins import str +import urllib.request, urllib.parse, urllib.error import copy from ..utils import etree @@ -56,7 +59,7 @@ NODE_TYPES = { { 'mode': 'browseplex', 'key': ('/library/sections/{self.section_id}&%s' - % urllib.urlencode({'sort': 'rating:desc'})), + % urllib.parse.urlencode({'sort': 'rating:desc'})), 'section_id': '{self.section_id}' }, v.CONTENT_TYPE_MOVIE, @@ -84,7 +87,7 @@ NODE_TYPES = { { 'mode': 'browseplex', 'key': ('/library/sections/{self.section_id}&%s' - % urllib.urlencode({'sort': 'random'})), + % urllib.parse.urlencode({'sort': 'random'})), 'section_id': '{self.section_id}' }, v.CONTENT_TYPE_MOVIE, @@ -154,7 +157,7 @@ NODE_TYPES = { { 'mode': 'browseplex', 'key': ('/library/sections/{self.section_id}&%s' - % urllib.urlencode({'sort': 'rating:desc'})), + % urllib.parse.urlencode({'sort': 'rating:desc'})), 'section_id': '{self.section_id}' }, v.CONTENT_TYPE_SHOW, @@ -182,7 +185,7 @@ NODE_TYPES = { { 'mode': 'browseplex', 'key': ('/library/sections/{self.section_id}&%s' - % urllib.urlencode({'sort': 'random'})), + % urllib.parse.urlencode({'sort': 'random'})), 'section_id': '{self.section_id}' }, v.CONTENT_TYPE_SHOW, @@ -192,7 +195,7 @@ NODE_TYPES = { { 'mode': 'browseplex', 'key': ('/library/sections/{self.section_id}/recentlyViewed&%s' - % urllib.urlencode({'type': v.PLEX_TYPE_NUMBER_FROM_PLEX_TYPE[v.PLEX_TYPE_EPISODE]})), + % urllib.parse.urlencode({'type': v.PLEX_TYPE_NUMBER_FROM_PLEX_TYPE[v.PLEX_TYPE_EPISODE]})), 'section_id': '{self.section_id}' }, v.CONTENT_TYPE_EPISODE, @@ -236,7 +239,7 @@ def node_pms(section, node_name, args): else: folder = False xml = etree.Element('node', - attrib={'order': unicode(section.order), + attrib={'order': str(section.order), 'type': 'folder' if folder else 'filter'}) etree.SubElement(xml, 'label').text = node_name etree.SubElement(xml, 'icon').text = ICON_PATH @@ -249,7 +252,7 @@ def node_ondeck(section, node_name): """ For movies only - returns in-progress movies sorted by last played """ - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -270,7 +273,7 @@ def node_ondeck(section, node_name): def node_recent(section, node_name): xml = etree.Element('node', - attrib={'order': unicode(section.order), + attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -299,7 +302,7 @@ def node_recent(section, node_name): def node_all(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -316,7 +319,7 @@ def node_all(section, node_name): def node_recommended(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -337,7 +340,7 @@ def node_recommended(section, node_name): def node_genres(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -355,7 +358,7 @@ def node_genres(section, node_name): def node_sets(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -374,7 +377,7 @@ def node_sets(section, node_name): def node_random(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', @@ -392,7 +395,7 @@ def node_random(section, node_name): def node_lastplayed(section, node_name): - xml = etree.Element('node', attrib={'order': unicode(section.order), + xml = etree.Element('node', attrib={'order': str(section.order), 'type': 'filter'}) etree.SubElement(xml, 'match').text = 'all' rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', diff --git a/resources/lib/library_sync/sections.py b/resources/lib/library_sync/sections.py index 04acbbad..993358e3 100644 --- a/resources/lib/library_sync/sections.py +++ b/resources/lib/library_sync/sections.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import range +from builtins import object from logging import getLogger import copy @@ -98,7 +101,7 @@ class Section(object): "}}").format(self=self).encode('utf-8') __str__ = __repr__ - def __nonzero__(self): + def __bool__(self): return (self.section_id is not None and self.name is not None and self.section_type is not None) @@ -236,7 +239,7 @@ class Section(object): {key: '{self.
}'} """ args = copy.deepcopy(args) - for key, value in args.iteritems(): + for key, value in args.items(): args[key] = value.format(self=self) return utils.extend_url('plugin://%s' % v.ADDON_ID, args) @@ -265,7 +268,7 @@ class Section(object): args = { 'mode': 'browseplex', 'key': '/library/sections/%s' % self.section_id, - 'section_id': unicode(self.section_id) + 'section_id': str(self.section_id) } if not self.sync_to_kodi: args['synched'] = 'false' @@ -276,7 +279,7 @@ class Section(object): args = { 'mode': 'browseplex', 'key': '/library/sections/%s/all' % self.section_id, - 'section_id': unicode(self.section_id) + 'section_id': str(self.section_id) } if not self.sync_to_kodi: args['synched'] = 'false' @@ -318,7 +321,7 @@ class Section(object): if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')): LOG.debug('Creating index.xml for section %s', self.name) xml = etree.Element('node', - attrib={'order': unicode(self.order)}) + attrib={'order': str(self.order)}) etree.SubElement(xml, 'label').text = self.name etree.SubElement(xml, 'icon').text = self.icon or nodes.ICON_PATH self._write_xml(xml, 'index.xml') @@ -708,7 +711,7 @@ def _clear_window_vars(index): utils.window('%s.path' % node, clear=True) utils.window('%s.id' % node, clear=True) # Just clear everything here, ignore the plex_type - for typus in (x[0] for y in nodes.NODE_TYPES.values() for x in y): + for typus in (x[0] for y in list(nodes.NODE_TYPES.values()) for x in y): for kind in WINDOW_ARGS: node = 'Plex.nodes.%s.%s.%s' % (index, typus, kind) utils.window(node, clear=True) diff --git a/resources/lib/library_sync/websocket.py b/resources/lib/library_sync/websocket.py index a899362d..49bbff9e 100644 --- a/resources/lib/library_sync/websocket.py +++ b/resources/lib/library_sync/websocket.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED @@ -160,7 +161,7 @@ def store_timeline_message(data): continue status = int(message['state']) if typus == 'playlist' and PLAYLIST_SYNC_ENABLED: - playlists.websocket(plex_id=unicode(message['itemID']), + playlists.websocket(plex_id=str(message['itemID']), status=status) elif status == 9: # Immediately and always process deletions (as the PMS will diff --git a/resources/lib/loghandler.py b/resources/lib/loghandler.py index 2106b1dc..b2d288c0 100644 --- a/resources/lib/loghandler.py +++ b/resources/lib/loghandler.py @@ -41,7 +41,7 @@ class LogHandler(logging.StreamHandler): self.setFormatter(logging.Formatter(fmt=b"%(name)s: %(message)s")) def emit(self, record): - if isinstance(record.msg, unicode): + if isinstance(record.msg, str): record.msg = record.msg.encode('utf-8') try: xbmc.log(self.format(record), level=LEVELS[record.levelno]) diff --git a/resources/lib/migration.py b/resources/lib/migration.py index e99e3210..3718f4b3 100644 --- a/resources/lib/migration.py +++ b/resources/lib/migration.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger from . import variables as v diff --git a/resources/lib/pathtools/path.py b/resources/lib/pathtools/path.py index b82ba7fd..95cd78b3 100644 --- a/resources/lib/pathtools/path.py +++ b/resources/lib/pathtools/path.py @@ -39,6 +39,7 @@ Functions .. autofunction:: parent_dir_path """ +from builtins import next import os.path from functools import partial @@ -72,7 +73,7 @@ def get_dir_walker(recursive, topdown=True, followlinks=False): try: yield next(os.walk(path, topdown=topdown, followlinks=followlinks)) except NameError: - yield os.walk(path, topdown=topdown, followlinks=followlinks).next() #IGNORE:E1101 + yield next(os.walk(path, topdown=topdown, followlinks=followlinks)) #IGNORE:E1101 return walk diff --git a/resources/lib/pathtools/patterns.py b/resources/lib/pathtools/patterns.py index 4ecd8537..65748ba6 100644 --- a/resources/lib/pathtools/patterns.py +++ b/resources/lib/pathtools/patterns.py @@ -34,6 +34,7 @@ Functions .. autofunction:: filter_paths """ +from builtins import map from fnmatch import fnmatch, fnmatchcase __all__ = ['match_path', diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 310f8b0f..9a47e5b8 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -4,6 +4,9 @@ Used to kick off Kodi playback """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str from logging import getLogger from threading import Thread import datetime @@ -296,7 +299,7 @@ def resume_dialog(resume): resume = datetime.timedelta(seconds=resume) LOG.debug('Showing PKC resume dialog for resume: %s', resume) answ = utils.dialog('contextmenu', - [utils.lang(12022).replace('{0:s}', '{0}').format(unicode(resume)), + [utils.lang(12022).replace('{0:s}', '{0}').format(str(resume)), utils.lang(12021)]) if answ == -1: return diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index c1500bc2..d14fae9e 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -4,6 +4,7 @@ Collection of functions associated with Kodi and Plex playlists and playqueues """ from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from .plex_api import API diff --git a/resources/lib/playlists/common.py b/resources/lib/playlists/common.py index 96ca151b..6d173af5 100644 --- a/resources/lib/playlists/common.py +++ b/resources/lib/playlists/common.py @@ -1,8 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import object from logging import getLogger -import Queue +import queue import time import os import hashlib @@ -188,7 +191,7 @@ class PlaylistObserver(Observer): while time.time() - start < timeout: try: new_event, new_watch = event_queue.get(block=False) - except Queue.Empty: + except queue.Empty: app.APP.monitor.waitForAbort(0.2) else: event_queue.task_done() diff --git a/resources/lib/playlists/db.py b/resources/lib/playlists/db.py index 673fc02a..d3cb18ea 100644 --- a/resources/lib/playlists/db.py +++ b/resources/lib/playlists/db.py @@ -5,6 +5,7 @@ Synced playlists are stored in our plex.db. Interact with it through this module """ from __future__ import absolute_import, division, unicode_literals +from builtins import next from logging import getLogger from .common import Playlist, PlaylistError diff --git a/resources/lib/playlists/pms.py b/resources/lib/playlists/pms.py index b4de8e4a..9ac90977 100644 --- a/resources/lib/playlists/pms.py +++ b/resources/lib/playlists/pms.py @@ -5,6 +5,7 @@ Functions to communicate with the currently connected PMS in order to manipulate playlists """ from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger from .common import PlaylistError @@ -108,7 +109,7 @@ def add_items(playlist, plex_ids): 'smart': 0, 'uri': ('server://%s/com.plexapp.plugins.library/library/metadata/%s' % (app.CONN.machine_identifier, - ','.join(unicode(x) for x in plex_ids))) + ','.join(str(x) for x in plex_ids))) } xml = DU().downloadUrl(url='{server}/playlists/', action_type='POST', diff --git a/resources/lib/playqueue.py b/resources/lib/playqueue.py index 45fb1d50..20577300 100644 --- a/resources/lib/playqueue.py +++ b/resources/lib/playqueue.py @@ -4,6 +4,7 @@ Monitors the Kodi playqueue and adjusts the Plex playqueue accordingly """ from __future__ import absolute_import, division, unicode_literals +from builtins import range from logging import getLogger import copy diff --git a/resources/lib/plex_api/artwork.py b/resources/lib/plex_api/artwork.py index 632d4355..13a7d4ed 100644 --- a/resources/lib/plex_api/artwork.py +++ b/resources/lib/plex_api/artwork.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from ..kodi_db import KodiVideoDB, KodiMusicDB @@ -71,7 +72,7 @@ class Artwork(object): # either the season or the show return artworks for kodi_artwork, plex_artwork in \ - v.KODI_TO_PLEX_ARTWORK_EPISODE.iteritems(): + v.KODI_TO_PLEX_ARTWORK_EPISODE.items(): art = self.one_artwork(plex_artwork) if art: artworks[kodi_artwork] = art @@ -109,7 +110,7 @@ class Artwork(object): with KodiMusicDB(lock=False) as kodidb: return kodidb.get_art(kodi_id, kodi_type) - for kodi_artwork, plex_artwork in v.KODI_TO_PLEX_ARTWORK.iteritems(): + for kodi_artwork, plex_artwork in v.KODI_TO_PLEX_ARTWORK.items(): art = self.one_artwork(plex_artwork) if art: artworks[kodi_artwork] = art diff --git a/resources/lib/plex_api/base.py b/resources/lib/plex_api/base.py index f20178e7..0f2891c0 100644 --- a/resources/lib/plex_api/base.py +++ b/resources/lib/plex_api/base.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import object from logging import getLogger from re import sub @@ -357,9 +359,9 @@ class Base(object): total = int(self.xml.attrib['leafCount']) watched = int(self.xml.attrib['viewedLeafCount']) return { - 'totalepisodes': unicode(total), - 'watchedepisodes': unicode(watched), - 'unwatchedepisodes': unicode(total - watched) + 'totalepisodes': str(total), + 'watchedepisodes': str(watched), + 'unwatchedepisodes': str(total - watched) } except (KeyError, TypeError): pass diff --git a/resources/lib/plex_api/fanart_lookup.py b/resources/lib/plex_api/fanart_lookup.py index 863a7437..0def080a 100644 --- a/resources/lib/plex_api/fanart_lookup.py +++ b/resources/lib/plex_api/fanart_lookup.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import range from logging import getLogger from re import sub from string import punctuation diff --git a/resources/lib/plex_api/file.py b/resources/lib/plex_api/file.py index 78ec31a9..f00264de 100644 --- a/resources/lib/plex_api/file.py +++ b/resources/lib/plex_api/file.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from .. import utils, variables as v, app diff --git a/resources/lib/plex_api/media.py b/resources/lib/plex_api/media.py index e6eb7a59..c0b06315 100644 --- a/resources/lib/plex_api/media.py +++ b/resources/lib/plex_api/media.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger from ..utils import cast diff --git a/resources/lib/plex_api/playback.py b/resources/lib/plex_api/playback.py index 2b585845..3bbaa7d7 100644 --- a/resources/lib/plex_api/playback.py +++ b/resources/lib/plex_api/playback.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from ..utils import cast diff --git a/resources/lib/plex_api/user.py b/resources/lib/plex_api/user.py index 4245fa9b..53afca87 100644 --- a/resources/lib/plex_api/user.py +++ b/resources/lib/plex_api/user.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from ..utils import cast from .. import timing, variables as v, app diff --git a/resources/lib/plex_companion.py b/resources/lib/plex_companion.py index e0cbb807..6511bca6 100644 --- a/resources/lib/plex_companion.py +++ b/resources/lib/plex_companion.py @@ -4,9 +4,11 @@ The Plex Companion master python file """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() from logging import getLogger from threading import Thread -from Queue import Empty +from queue import Empty from socket import SHUT_RDWR from xbmc import executebuiltin diff --git a/resources/lib/plex_db/common.py b/resources/lib/plex_db/common.py index 6a70cb42..b249eaf8 100644 --- a/resources/lib/plex_db/common.py +++ b/resources/lib/plex_db/common.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from threading import Lock from .. import db, variables as v diff --git a/resources/lib/plex_db/movies.py b/resources/lib/plex_db/movies.py index 74ed360b..1348515a 100644 --- a/resources/lib/plex_db/movies.py +++ b/resources/lib/plex_db/movies.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from .. import variables as v diff --git a/resources/lib/plex_db/music.py b/resources/lib/plex_db/music.py index ca954ae4..0d8c8e78 100644 --- a/resources/lib/plex_db/music.py +++ b/resources/lib/plex_db/music.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from .. import variables as v diff --git a/resources/lib/plex_db/playlists.py b/resources/lib/plex_db/playlists.py index 68575bb8..0c95dd07 100644 --- a/resources/lib/plex_db/playlists.py +++ b/resources/lib/plex_db/playlists.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, unicode_literals +from builtins import object class Playlists(object): def playlist_ids(self): """ diff --git a/resources/lib/plex_db/sections.py b/resources/lib/plex_db/sections.py index a65e3cec..efc07d39 100644 --- a/resources/lib/plex_db/sections.py +++ b/resources/lib/plex_db/sections.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, unicode_literals +from builtins import object class Sections(object): def all_sections(self): """ diff --git a/resources/lib/plex_db/tvshows.py b/resources/lib/plex_db/tvshows.py index ae643b0e..67478200 100644 --- a/resources/lib/plex_db/tvshows.py +++ b/resources/lib/plex_db/tvshows.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from .. import variables as v diff --git a/resources/lib/plex_functions.py b/resources/lib/plex_functions.py index dac7e2b0..6785f84f 100644 --- a/resources/lib/plex_functions.py +++ b/resources/lib/plex_functions.py @@ -1,6 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import range +from builtins import object from logging import getLogger from ast import literal_eval from copy import deepcopy @@ -333,7 +338,7 @@ def _pms_list_from_plex_tv(token): LOG.error('Could not get list of PMS from plex.tv') return [] - from Queue import Queue + from queue import Queue queue = Queue() thread_queue = [] diff --git a/resources/lib/plex_tv.py b/resources/lib/plex_tv.py index c6712b4f..43ea9d51 100644 --- a/resources/lib/plex_tv.py +++ b/resources/lib/plex_tv.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object from logging import getLogger import time import threading diff --git a/resources/lib/plexbmchelper/httppersist.py b/resources/lib/plexbmchelper/httppersist.py index 89a77ed8..55b61ff8 100644 --- a/resources/lib/plexbmchelper/httppersist.py +++ b/resources/lib/plexbmchelper/httppersist.py @@ -1,8 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import object from logging import getLogger -import httplib +import http.client import traceback import string import errno @@ -15,7 +19,7 @@ LOG = getLogger('PLEX.httppersist') ############################################################################### -class RequestMgr: +class RequestMgr(object): def __init__(self): self.conns = {} @@ -23,9 +27,9 @@ class RequestMgr: conn = self.conns.get(protocol + host + str(port), False) if not conn: if protocol == "https": - conn = httplib.HTTPSConnection(host, port) + conn = http.client.HTTPSConnection(host, port) else: - conn = httplib.HTTPConnection(host, port) + conn = http.client.HTTPConnection(host, port) self.conns[protocol + host + str(port)] = conn return conn @@ -36,7 +40,7 @@ class RequestMgr: self.conns.pop(protocol + host + str(port), None) def dumpConnections(self): - for conn in self.conns.values(): + for conn in list(self.conns.values()): conn.close() self.conns = {} diff --git a/resources/lib/plexbmchelper/listener.py b/resources/lib/plexbmchelper/listener.py index a5c6ecd1..391cc622 100644 --- a/resources/lib/plexbmchelper/listener.py +++ b/resources/lib/plexbmchelper/listener.py @@ -4,10 +4,12 @@ Plex Companion listener """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() from logging import getLogger from re import sub -from SocketServer import ThreadingMixIn -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +from socketserver import ThreadingMixIn +from http.server import HTTPServer, BaseHTTPRequestHandler from .. import utils, companion, json_rpc as js, clientinfo, variables as v from .. import app diff --git a/resources/lib/plexbmchelper/plexgdm.py b/resources/lib/plexbmchelper/plexgdm.py index e94feaba..895eee23 100644 --- a/resources/lib/plexbmchelper/plexgdm.py +++ b/resources/lib/plexbmchelper/plexgdm.py @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import object import logging import socket import threading @@ -39,7 +41,7 @@ log = logging.getLogger('PLEX.plexgdm') ############################################################################### -class plexgdm: +class plexgdm(object): def __init__(self): self.discover_message = 'M-SEARCH * HTTP/1.0' diff --git a/resources/lib/plexbmchelper/subscribers.py b/resources/lib/plexbmchelper/subscribers.py index 24873714..64b235ec 100644 --- a/resources/lib/plexbmchelper/subscribers.py +++ b/resources/lib/plexbmchelper/subscribers.py @@ -5,6 +5,10 @@ Manages getting playstate from Kodi and sending it to the PMS as well as subscribed Plex Companion clients. """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import object from logging import getLogger from threading import Thread @@ -174,7 +178,7 @@ class SubscriptionMgr(object): Returns the string 'key1="value1" key2="value2" ...' for dictionary """ answ = '' - for key, value in dictionary.iteritems(): + for key, value in dictionary.items(): answ += '%s="%s" ' % (key, value) return answ @@ -317,7 +321,7 @@ class SubscriptionMgr(object): Hence we'd have a missmatch between the state.PLAYER_STATES and our playqueues. """ - for player in players.values(): + for player in list(players.values()): info = app.PLAYSTATE.player_states[player['playerid']] playqueue = PQ.PLAYQUEUES[player['playerid']] position = self._get_correct_position(info, playqueue) @@ -342,7 +346,7 @@ class SubscriptionMgr(object): # Get all the active/playing Kodi players (video, audio, pictures) players = js.get_players() # Update the PKC info with what's playing on the Kodi side - for player in players.values(): + for player in list(players.values()): update_player_info(player['playerid']) # Check whether we can use the CURRENT info or whether PKC is still # initializing @@ -352,12 +356,12 @@ class SubscriptionMgr(object): self._notify_server(players) if self.subscribers: msg = self.msg(players) - for subscriber in self.subscribers.values(): + for subscriber in list(self.subscribers.values()): subscriber.send_update(msg) self.lastplayers = players def _notify_server(self, players): - for typus, player in players.iteritems(): + for typus, player in players.items(): self._send_pms_notification( player['playerid'], self._get_pms_params(player['playerid'])) try: @@ -365,7 +369,7 @@ class SubscriptionMgr(object): except KeyError: pass # Process the players we have left (to signal a stop) - for player in self.lastplayers.values(): + for player in list(self.lastplayers.values()): self.last_params['state'] = 'stopped' self._send_pms_notification(player['playerid'], self.last_params) @@ -442,13 +446,13 @@ class SubscriptionMgr(object): (Calls the cleanup() method of the subscriber) """ with app.APP.lock_subscriber: - for subscriber in self.subscribers.values(): + for subscriber in list(self.subscribers.values()): if subscriber.uuid == uuid or subscriber.host == uuid: subscriber.cleanup() del self.subscribers[subscriber.uuid] def _cleanup(self): - for subscriber in self.subscribers.values(): + for subscriber in list(self.subscribers.values()): if subscriber.age > 30: subscriber.cleanup() del self.subscribers[subscriber.uuid] diff --git a/resources/lib/service_entry.py b/resources/lib/service_entry.py index dc732ff1..75c3620f 100644 --- a/resources/lib/service_entry.py +++ b/resources/lib/service_entry.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import object import logging import sys import xbmc diff --git a/resources/lib/tools/unicode_paths.py b/resources/lib/tools/unicode_paths.py index c1e3ceed..3f8df963 100644 --- a/resources/lib/tools/unicode_paths.py +++ b/resources/lib/tools/unicode_paths.py @@ -28,7 +28,7 @@ from . import platform try: # Python 2 - str_cls = unicode + str_cls = str bytes_cls = str except NameError: # Python 3 diff --git a/resources/lib/transfer.py b/resources/lib/transfer.py index 6e072d24..aa965b3c 100644 --- a/resources/lib/transfer.py +++ b/resources/lib/transfer.py @@ -5,6 +5,8 @@ Used to shovel data from separate Kodi Python instances to the main thread and vice versa. """ from __future__ import absolute_import, division, unicode_literals +from builtins import str +from builtins import object from logging import getLogger import json @@ -33,15 +35,15 @@ def cast(func, value): return value elif func == bool: return bool(int(value)) - elif func == unicode: - if isinstance(value, (int, long, float)): - return unicode(value) - elif isinstance(value, unicode): + elif func == str: + if isinstance(value, (int, float)): + return str(value) + elif isinstance(value, str): return value else: return value.decode('utf-8') elif func == str: - if isinstance(value, (int, long, float)): + if isinstance(value, (int, float)): return str(value) elif isinstance(value, str): return value @@ -163,7 +165,7 @@ def convert_pkc_to_listitem(pkc_listitem): listitem.addStreamInfo(**stream) if data['art']: listitem.setArt(data['art']) - for key, value in data['property'].iteritems(): + for key, value in data['property'].items(): listitem.setProperty(key, cast(str, value)) if data['subtitles']: listitem.setSubtitles(data['subtitles']) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 5f14e5ea..b6513d43 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -4,13 +4,17 @@ Various functions and decorators for PKC """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import object from logging import getLogger from sqlite3 import OperationalError from datetime import datetime from unicodedata import normalize from threading import Lock -import urllib -import urlparse as _urlparse +import urllib.request, urllib.parse, urllib.error +import urllib.parse as _urlparse # Originally tried faster cElementTree, but does NOT work reliably with Kodi import xml.etree.ElementTree as etree # etree parse unsafe; make sure we're always receiving unicode @@ -191,7 +195,7 @@ def dialog(typus, *args, **kwargs): '{warning}': xbmcgui.NOTIFICATION_WARNING, '{error}': xbmcgui.NOTIFICATION_ERROR } - for key, value in types.iteritems(): + for key, value in types.items(): kwargs['icon'] = kwargs['icon'].replace(key, value) if 'type' in kwargs: types = { @@ -291,15 +295,15 @@ def cast(func, value): return value elif func == bool: return bool(int(value)) - elif func == unicode: - if isinstance(value, (int, long, float)): - return unicode(value) - elif isinstance(value, unicode): + elif func == str: + if isinstance(value, (int, float)): + return str(value) + elif isinstance(value, str): return value else: return value.decode('utf-8') elif func == str: - if isinstance(value, (int, long, float)): + if isinstance(value, (int, float)): return str(value) elif isinstance(value, str): return value @@ -329,7 +333,7 @@ def extend_url(url, params): in unicode """ params = encode_dict(params) if params else {} - params = urllib.urlencode(params).decode('utf-8') + params = urllib.parse.urlencode(params).decode('utf-8') if '?' in url: return '%s&%s' % (url, params) else: @@ -343,10 +347,10 @@ def encode_dict(dictionary): Useful for urllib.urlencode or urllib.(un)quote """ - for key, value in dictionary.iteritems(): - if isinstance(key, unicode): + for key, value in dictionary.items(): + if isinstance(key, str): dictionary[key.encode('utf-8')] = dictionary.pop(key) - if isinstance(value, unicode): + if isinstance(value, str): dictionary[key] = value.encode('utf-8') return dictionary @@ -357,11 +361,11 @@ def parse_qs(qs, keep_blank_values=0, strict_parsing=0): either as str or unicode Returns a dict with lists as values; all entires unicode """ - if isinstance(qs, unicode): + if isinstance(qs, str): qs = qs.encode('utf-8') qs = _urlparse.parse_qs(qs, keep_blank_values, strict_parsing) return {k.decode('utf-8'): [e.decode('utf-8') for e in v] - for k, v in qs.iteritems()} + for k, v in qs.items()} def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): @@ -369,7 +373,7 @@ def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): unicode-safe way to use urlparse.parse_qsl(). Pass in either str or unicode Returns a list of unicode tuples """ - if isinstance(qs, unicode): + if isinstance(qs, str): qs = qs.encode('utf-8') qs = _urlparse.parse_qsl(qs, keep_blank_values, strict_parsing) return [(x.decode('utf-8'), y.decode('utf-8')) for (x, y) in qs] @@ -380,7 +384,7 @@ def urlparse(url, scheme='', allow_fragments=True): unicode-safe way to use urlparse.urlparse(). Pass in either str or unicode CAREFUL: returns an encoded urlparse.ParseResult()! """ - if isinstance(url, unicode): + if isinstance(url, str): url = url.encode('utf-8') return _urlparse.urlparse(url, scheme, allow_fragments) @@ -404,13 +408,13 @@ def escape_path(path, safe_url_char=SAFE_URL_CHARACTERS): user = is_http_dav_ftp.group(6) psswd = is_http_dav_ftp.group(7) if user and psswd: - user = urllib.quote(user.encode('utf-8'), safe=safe_url_char).decode('utf-8') - psswd = urllib.quote(psswd.encode('utf-8'), safe=safe_url_char).decode('utf-8') + user = urllib.parse.quote(user.encode('utf-8'), safe=safe_url_char).decode('utf-8') + psswd = urllib.parse.quote(psswd.encode('utf-8'), safe=safe_url_char).decode('utf-8') host = is_http_dav_ftp.group(8) port = is_http_dav_ftp.group(10) url_path = path.replace(is_http_dav_ftp.group(), '', 1) if url_path: - url_path = urllib.quote(path.replace(is_http_dav_ftp.group(), '', 1).encode('utf-8'), + url_path = urllib.parse.quote(path.replace(is_http_dav_ftp.group(), '', 1).encode('utf-8'), safe=safe_url_char).decode('utf-8') return protocol + \ u'://' + \ @@ -422,7 +426,7 @@ def escape_path(path, safe_url_char=SAFE_URL_CHARACTERS): else: # If paths does not seem to be a http(s), dav(s) or (s)ftp url (e.g. plugin://) # escape path as before - return urllib.quote(path.encode('utf-8'), + return urllib.parse.quote(path.encode('utf-8'), safe=SAFE_URL_CHARACTERS).decode('utf-8') @@ -431,9 +435,9 @@ def quote(s, safe='/'): unicode-safe way to use urllib.quote(). Pass in either str or unicode Returns unicode """ - if isinstance(s, unicode): + if isinstance(s, str): s = s.encode('utf-8') - s = urllib.quote(s, safe.encode('utf-8')) + s = urllib.parse.quote(s, safe.encode('utf-8')) return s.decode('utf-8') @@ -442,9 +446,9 @@ def quote_plus(s, safe=''): unicode-safe way to use urllib.quote(). Pass in either str or unicode Returns unicode """ - if isinstance(s, unicode): + if isinstance(s, str): s = s.encode('utf-8') - s = urllib.quote_plus(s, safe.encode('utf-8')) + s = urllib.parse.quote_plus(s, safe.encode('utf-8')) return s.decode('utf-8') @@ -453,9 +457,9 @@ def unquote(s): unicode-safe way to use urllib.unquote(). Pass in either str or unicode Returns unicode """ - if isinstance(s, unicode): + if isinstance(s, str): s = s.encode('utf-8') - s = urllib.unquote(s) + s = urllib.parse.unquote(s) return s.decode('utf-8') @@ -481,7 +485,7 @@ def try_decode(string, encoding='utf-8'): fails with e.g. Android TV's Python, which does not accept arguments for string.encode() """ - if isinstance(string, unicode): + if isinstance(string, str): # already decoded return string try: @@ -496,9 +500,9 @@ def slugify(text): Normalizes text (in unicode or string) to e.g. enable safe filenames. Returns unicode """ - if not isinstance(text, unicode): - text = unicode(text) - return unicode(normalize('NFKD', text).encode('ascii', 'ignore')) + if not isinstance(text, str): + text = str(text) + return str(normalize('NFKD', text).encode('ascii', 'ignore')) def valid_filename(text): @@ -542,7 +546,7 @@ def escape_html(string): '>': '>', '&': '&' } - for key, value in escapes.iteritems(): + for key, value in escapes.items(): string = string.replace(key, value) return string @@ -690,7 +694,7 @@ def normalize_string(text): # Remove dots from the last character as windows can not have directories # with dots at the end text = text.rstrip('.') - text = try_encode(normalize('NFKD', unicode(text, 'utf-8'))) + text = try_encode(normalize('NFKD', str(text, 'utf-8'))) return text @@ -713,7 +717,7 @@ def normalize_nodes(text): # Remove dots from the last character as windows can not have directories # with dots at the end text = text.rstrip('.') - text = normalize('NFKD', unicode(text, 'utf-8')) + text = normalize('NFKD', str(text, 'utf-8')) return text @@ -936,7 +940,7 @@ class XmlKodiSetting(object): # Write new values element.text = value if attrib: - for key, attribute in attrib.iteritems(): + for key, attribute in attrib.items(): element.set(key, attribute) return element @@ -958,7 +962,7 @@ def process_method_on_list(method_to_run, items): pool.join() else: all_items = [method_to_run(item) for item in items] - all_items = filter(None, all_items) + all_items = [_f for _f in all_items if _f] return all_items diff --git a/resources/lib/variables.py b/resources/lib/variables.py index b6fd59e8..c6ebd133 100644 --- a/resources/lib/variables.py +++ b/resources/lib/variables.py @@ -20,7 +20,7 @@ def try_decode(string, encoding='utf-8'): fails with e.g. Android TV's Python, which does not accept arguments for string.encode() """ - if isinstance(string, unicode): + if isinstance(string, str): # already decoded return string try: diff --git a/resources/lib/watchdog/events.py b/resources/lib/watchdog/events.py index 24cfec62..9218fa4c 100644 --- a/resources/lib/watchdog/events.py +++ b/resources/lib/watchdog/events.py @@ -85,6 +85,7 @@ Event Handler Classes """ +from builtins import object import os.path import logging import re diff --git a/resources/lib/watchdog/observers/api.py b/resources/lib/watchdog/observers/api.py index 35a7748d..fc464484 100644 --- a/resources/lib/watchdog/observers/api.py +++ b/resources/lib/watchdog/observers/api.py @@ -16,6 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from builtins import object from __future__ import with_statement import threading from ..utils import BaseThread diff --git a/resources/lib/watchdog/observers/fsevents.py b/resources/lib/watchdog/observers/fsevents.py index d2519e28..3b65f5bc 100644 --- a/resources/lib/watchdog/observers/fsevents.py +++ b/resources/lib/watchdog/observers/fsevents.py @@ -150,7 +150,7 @@ class FSEventsObserver(BaseObserver): def schedule(self, event_handler, path, recursive=False): # Python 2/3 compat try: - str_class = unicode + str_class = str except NameError: str_class = str diff --git a/resources/lib/watchdog/observers/fsevents2.py b/resources/lib/watchdog/observers/fsevents2.py index e2d7c667..8b97ab30 100644 --- a/resources/lib/watchdog/observers/fsevents2.py +++ b/resources/lib/watchdog/observers/fsevents2.py @@ -19,7 +19,11 @@ :synopsis: FSEvents based emitter implementation. :platforms: Mac OS X """ +from __future__ import absolute_import +from builtins import hex +from builtins import zip +from builtins import object import os import logging import unicodedata @@ -45,7 +49,7 @@ from ..observers.api import ( # pyobjc import AppKit -from FSEvents import ( +from .FSEvents import ( FSEventStreamCreate, CFRunLoopGetCurrent, FSEventStreamScheduleWithRunLoop, @@ -57,7 +61,7 @@ from FSEvents import ( FSEventStreamRelease, ) -from FSEvents import ( +from .FSEvents import ( kCFAllocatorDefault, kCFRunLoopDefaultMode, kFSEventStreamEventIdSinceNow, diff --git a/resources/lib/watchdog/observers/inotify_c.py b/resources/lib/watchdog/observers/inotify_c.py index 6c7f1ffc..3b2f7b2b 100644 --- a/resources/lib/watchdog/observers/inotify_c.py +++ b/resources/lib/watchdog/observers/inotify_c.py @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from builtins import object from __future__ import with_statement import os import errno diff --git a/resources/lib/watchdog/observers/kqueue.py b/resources/lib/watchdog/observers/kqueue.py index a5838d18..353bb32f 100644 --- a/resources/lib/watchdog/observers/kqueue.py +++ b/resources/lib/watchdog/observers/kqueue.py @@ -77,6 +77,7 @@ Collections and Utility Classes """ +from builtins import object from __future__ import with_statement from ..utils import platform diff --git a/resources/lib/watchdog/observers/winapi.py b/resources/lib/watchdog/observers/winapi.py index a828f8a5..ccc6f788 100644 --- a/resources/lib/watchdog/observers/winapi.py +++ b/resources/lib/watchdog/observers/winapi.py @@ -36,6 +36,7 @@ # Portions of this code were taken from pyfilesystem, which uses the above # new BSD license. +from builtins import object from __future__ import with_statement import ctypes.wintypes @@ -308,7 +309,7 @@ def read_directory_changes(handle, recursive): # Python 2/3 compat try: - int_class = long + int_class = int except NameError: int_class = int return event_buffer.raw, int_class(nbytes.value) diff --git a/resources/lib/watchdog/utils/__init__.py b/resources/lib/watchdog/utils/__init__.py index e912033c..a932e690 100644 --- a/resources/lib/watchdog/utils/__init__.py +++ b/resources/lib/watchdog/utils/__init__.py @@ -30,6 +30,7 @@ Classes :inherited-members: """ +from __future__ import absolute_import import os import sys import threading @@ -39,7 +40,7 @@ from .compat import Event if sys.version_info[0] == 2 and platform.is_windows(): # st_ino is not implemented in os.stat on this platform - import win32stat + from . import win32stat stat = win32stat.stat else: stat = os.stat diff --git a/resources/lib/watchdog/utils/bricks.py b/resources/lib/watchdog/utils/bricks.py index b6d6516e..ac351f2b 100644 --- a/resources/lib/watchdog/utils/bricks.py +++ b/resources/lib/watchdog/utils/bricks.py @@ -36,6 +36,8 @@ Classes """ +from builtins import next +from builtins import range import sys import collections from .compat import queue diff --git a/resources/lib/watchdog/utils/compat.py b/resources/lib/watchdog/utils/compat.py index b1ae6674..117291e0 100644 --- a/resources/lib/watchdog/utils/compat.py +++ b/resources/lib/watchdog/utils/compat.py @@ -13,6 +13,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from future import standard_library +standard_library.install_aliases() import sys __all__ = ['queue', 'Event'] @@ -20,7 +22,7 @@ __all__ = ['queue', 'Event'] try: import queue except ImportError: - import Queue as queue + import queue as queue if sys.version_info < (2, 7): diff --git a/resources/lib/watchdog/utils/decorators.py b/resources/lib/watchdog/utils/decorators.py index abb325c1..dce4ec75 100644 --- a/resources/lib/watchdog/utils/decorators.py +++ b/resources/lib/watchdog/utils/decorators.py @@ -14,6 +14,7 @@ decorators: - deprecated """ +from builtins import zip import functools import warnings import threading diff --git a/resources/lib/watchdog/utils/delayed_queue.py b/resources/lib/watchdog/utils/delayed_queue.py index 6d98a504..e89e1c97 100644 --- a/resources/lib/watchdog/utils/delayed_queue.py +++ b/resources/lib/watchdog/utils/delayed_queue.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from builtins import object import time import threading from collections import deque diff --git a/resources/lib/watchdog/utils/dirsnapshot.py b/resources/lib/watchdog/utils/dirsnapshot.py index 7d56fe0a..f16fd6e7 100644 --- a/resources/lib/watchdog/utils/dirsnapshot.py +++ b/resources/lib/watchdog/utils/dirsnapshot.py @@ -44,6 +44,8 @@ Classes """ +from builtins import str +from builtins import object import errno import os from stat import S_ISDIR diff --git a/resources/lib/watchdog/utils/echo.py b/resources/lib/watchdog/utils/echo.py index 12803e03..28955dc8 100644 --- a/resources/lib/watchdog/utils/echo.py +++ b/resources/lib/watchdog/utils/echo.py @@ -32,6 +32,8 @@ Example: def my_function(args): pass """ +from builtins import map +from builtins import zip import inspect import sys diff --git a/resources/lib/watchdog/utils/event_backport.py b/resources/lib/watchdog/utils/event_backport.py index 5c136e46..5cd8c936 100644 --- a/resources/lib/watchdog/utils/event_backport.py +++ b/resources/lib/watchdog/utils/event_backport.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- # Backport of Event from py2.7 (method wait in py2.6 returns None) +from builtins import object from threading import Condition, Lock diff --git a/resources/lib/watchdog/utils/importlib2.py b/resources/lib/watchdog/utils/importlib2.py index 5ad3ec57..303a16c8 100644 --- a/resources/lib/watchdog/utils/importlib2.py +++ b/resources/lib/watchdog/utils/importlib2.py @@ -31,7 +31,7 @@ def import_module(target, relative_to=None): relative_parts = relative_to.split('.') relative_to = '.'.join(relative_parts[:-(target_depth - 1) or None]) if len(target_path) > 1: - relative_to = '.'.join(filter(None, [relative_to]) + target_path[:-1]) + relative_to = '.'.join([_f for _f in [relative_to] if _f] + target_path[:-1]) fromlist = target_path[-1:] target = fromlist[0] elif not relative_to: diff --git a/resources/lib/watchdog/utils/unicode_paths.py b/resources/lib/watchdog/utils/unicode_paths.py index c1e3ceed..3f8df963 100644 --- a/resources/lib/watchdog/utils/unicode_paths.py +++ b/resources/lib/watchdog/utils/unicode_paths.py @@ -28,7 +28,7 @@ from . import platform try: # Python 2 - str_cls = unicode + str_cls = str bytes_cls = str except NameError: # Python 3 diff --git a/resources/lib/watchdog/utils/win32stat.py b/resources/lib/watchdog/utils/win32stat.py index c18d66f3..6bddad3b 100644 --- a/resources/lib/watchdog/utils/win32stat.py +++ b/resources/lib/watchdog/utils/win32stat.py @@ -24,7 +24,9 @@ Functions .. autofunction:: stat """ +from __future__ import division +from past.utils import old_div import ctypes import ctypes.wintypes import stat as stdstat @@ -99,7 +101,7 @@ def _to_mode(attr): def _to_unix_time(ft): t = (ft.dwHighDateTime) << 32 | ft.dwLowDateTime - return (t / 10000000) - 11644473600 + return (old_div(t, 10000000)) - 11644473600 def stat(path): hfile = CreateFile(path, diff --git a/resources/lib/watchdog/watchmedo.py b/resources/lib/watchdog/watchmedo.py index 29c63e46..2e08095c 100644 --- a/resources/lib/watchdog/watchmedo.py +++ b/resources/lib/watchdog/watchmedo.py @@ -22,6 +22,8 @@ :synopsis: ``watchmedo`` shell script utility. """ +from future import standard_library +standard_library.install_aliases() import os.path import sys import yaml @@ -29,10 +31,10 @@ import time import logging try: - from cStringIO import StringIO + from io import StringIO except ImportError: try: - from StringIO import StringIO + from io import StringIO except ImportError: from io import StringIO diff --git a/resources/lib/websocket.py b/resources/lib/websocket.py index 8f9e372b..1c172699 100644 --- a/resources/lib/websocket.py +++ b/resources/lib/websocket.py @@ -20,6 +20,12 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import chr +from builtins import range +from builtins import object import socket try: @@ -35,7 +41,7 @@ except ImportError: HAVE_SSL = False -from urlparse import urlparse +from urllib.parse import urlparse import os import array import struct @@ -228,7 +234,7 @@ def create_connection(url, timeout=None, **options): _MAX_INTEGER = (1 << 32) - 1 -_AVAILABLE_KEY_CHARS = range(0x21, 0x2f + 1) + range(0x3a, 0x7e + 1) +_AVAILABLE_KEY_CHARS = list(range(0x21, 0x2f + 1)) + list(range(0x3a, 0x7e + 1)) _MAX_CHAR_BYTE = (1 << 8) - 1 # ref. Websocket gets an update, and it breaks stuff. @@ -308,7 +314,7 @@ class ABNF(object): opcode: operation code. please see OPCODE_XXX. """ - if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode): + if opcode == ABNF.OPCODE_TEXT and isinstance(data, str): data = utils.try_encode(data) # mask must be set if send data from client return ABNF(1, 0, 0, 0, opcode, 1, data) @@ -358,7 +364,7 @@ class ABNF(object): """ _m = array.array("B", mask_key) _d = array.array("B", data) - for i in xrange(len(_d)): + for i in range(len(_d)): _d[i] ^= _m[i % 4] return _d.tostring() @@ -529,7 +535,7 @@ class WebSocket(object): @staticmethod def _validate_header(headers, key): - for k, v in _HEADERS_TO_CHECK.iteritems(): + for k, v in _HEADERS_TO_CHECK.items(): r = headers.get(k, None) if not r: return False @@ -882,11 +888,11 @@ class WebSocketApp(object): if data is None or self.keep_running is False: break self._callback(self.on_message, data) - except Exception, e: + except Exception as e: if "timed out" not in e.args[0]: raise e - except Exception, e: + except Exception as e: self._callback(self.on_error, e) finally: if thread: @@ -899,7 +905,7 @@ class WebSocketApp(object): if callback: try: callback(self, *args) - except Exception, e: + except Exception as e: LOG.error(e) _, _, tb = sys.exc_info() traceback.print_tb(tb) diff --git a/resources/lib/widgets.py b/resources/lib/widgets.py index 80805f00..9d18b11f 100644 --- a/resources/lib/widgets.py +++ b/resources/lib/widgets.py @@ -7,6 +7,7 @@ Loads of different functions called in SEPARATE Python instances through e.g. plugin://... calls. Hence be careful to only rely on window variables. """ from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger import xbmc @@ -296,7 +297,7 @@ def prepare_listitem(item): if "imdbnumber" not in properties and "imdbnumber" in item: properties["imdbnumber"] = item["imdbnumber"] if "imdbnumber" not in properties and "uniqueid" in item: - for value in item["uniqueid"].values(): + for value in list(item["uniqueid"].values()): if value.startswith("tt"): properties["imdbnumber"] = value @@ -421,8 +422,8 @@ def prepare_listitem(item): item["thumbnail"] = art["thumb"] # clean art - for key, value in art.iteritems(): - if not isinstance(value, (str, unicode)): + for key, value in art.items(): + if not isinstance(value, str): art[key] = "" elif value: art[key] = get_clean_image(value) @@ -473,7 +474,7 @@ def create_listitem(item, as_tuple=True, offscreen=True, nodetype = "Music" # extra properties - for key, value in item["extraproperties"].iteritems(): + for key, value in item["extraproperties"].items(): liz.setProperty(key, value) # video infolabels diff --git a/resources/lib/windows/direct_path_sources.py b/resources/lib/windows/direct_path_sources.py index 888e9667..c03e14ff 100644 --- a/resources/lib/windows/direct_path_sources.py +++ b/resources/lib/windows/direct_path_sources.py @@ -6,10 +6,12 @@ e.g. smb paths """ from __future__ import absolute_import, division, unicode_literals +from future import standard_library +standard_library.install_aliases() from logging import getLogger import re import socket -import urllib +import urllib.request, urllib.parse, urllib.error import xbmc @@ -156,7 +158,7 @@ def start(): xml.write_xml = False return user = user.strip() - user = urllib.quote(user) + user = urllib.parse.quote(user) user = user.decode('utf-8') # "Password" # May also be blank!! (=user aborts dialog) @@ -165,7 +167,7 @@ def start(): '', type='{alphanum}', option='{hide}') - password = urllib.quote(password) + password = urllib.parse.quote(password) password = password.decode('utf-8') utils.etree.SubElement(entry, 'from', diff --git a/resources/lib/windows/kodigui.py b/resources/lib/windows/kodigui.py index ee55335d..a71741ef 100644 --- a/resources/lib/windows/kodigui.py +++ b/resources/lib/windows/kodigui.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, unicode_literals +from builtins import zip +from builtins import str +from builtins import range +from builtins import object import xbmc import xbmcgui import time @@ -12,7 +16,7 @@ from .. import app MONITOR = None -class BaseFunctions: +class BaseFunctions(object): xmlFile = '' path = '' theme = '' @@ -187,7 +191,7 @@ class BaseDialog(xbmcgui.WindowXMLDialog, BaseFunctions): pass -class ControlledBase: +class ControlledBase(object): def doModal(self): self.show() self.wait() @@ -242,10 +246,10 @@ class ManagedListItem(object): self._manager = None self._valid = True if properties: - for k, v in properties.items(): + for k, v in list(properties.items()): self.setProperty(k, v) - def __nonzero__(self): + def __bool__(self): return self._valid @property @@ -281,7 +285,7 @@ class ManagedListItem(object): self.listItem.setIconImage(self.iconImage) self.listItem.setThumbnailImage(self.thumbnailImage) self.listItem.setPath(self.path) - for k in self._manager._properties.keys(): + for k in list(self._manager._properties.keys()): self.listItem.setProperty(k, self.properties.get(k) or '') def clear(self): @@ -615,9 +619,9 @@ class ManagedControlList(object): def getViewRange(self): viewPosition = self.getViewPosition() selected = self.getSelectedPosition() - return range(max(selected - viewPosition, 0), + return list(range(max(selected - viewPosition, 0), min(selected + (self._maxViewIndex - viewPosition) + 1, - self.size() - 1)) + self.size() - 1))) def positionIsValid(self, pos): return 0 <= pos < self.size() @@ -751,7 +755,7 @@ class MultiWindow(object): self._current.setProperty(key, value) def _onFirstInit(self): - for k, v in self._properties.items(): + for k, v in list(self._properties.items()): self._current.setProperty(k, v) self.onFirstInit() @@ -897,7 +901,7 @@ class SafeControlEdit(object): self._setText(self.getText()[:-1]) -class PropertyTimer(): +class PropertyTimer(object): def __init__(self, window_id, timeout, property_, value='', init_value='1', addon_id=None, callback=None): self._winID = window_id self._timeout = timeout @@ -976,7 +980,7 @@ class PropertyTimer(): self._start() -class WindowProperty(): +class WindowProperty(object): def __init__(self, win, prop, val='1', end=None): self.win = win self.prop = prop @@ -995,7 +999,7 @@ class WindowProperty(): self.win.setProperty(self.prop, self.end or self.old) -class GlobalProperty(): +class GlobalProperty(object): def __init__(self, prop, val='1', end=None): import xbmcaddon self._addonID = xbmcaddon.Addon().getAddonInfo('id') diff --git a/resources/lib/windows/userselect.py b/resources/lib/windows/userselect.py index f6e5ba7b..6439baba 100644 --- a/resources/lib/windows/userselect.py +++ b/resources/lib/windows/userselect.py @@ -6,6 +6,7 @@ (home) users """ from __future__ import absolute_import, division, unicode_literals +from builtins import str from logging import getLogger import xbmc import xbmcgui