Automatically convert source code from Python 2 to 3 using futurize

This commit is contained in:
croneter 2020-12-18 17:10:20 +01:00
parent e0a27bdb4e
commit 436b1fda83
85 changed files with 297 additions and 160 deletions

View file

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################### ###############################################################################
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from sys import listitem from sys import listitem
from urllib import urlencode from urllib.parse import urlencode
from xbmc import getCondVisibility, sleep from xbmc import getCondVisibility, sleep
from xbmcgui import Window from xbmcgui import Window

View file

@ -2,9 +2,12 @@
############################################################################### ###############################################################################
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import object
import logging import logging
from sys import argv from sys import argv
from urlparse import parse_qsl from urllib.parse import parse_qsl
import xbmc import xbmc
import xbmcgui import xbmcgui
@ -23,7 +26,7 @@ LOG = logging.getLogger('PLEX.default')
HANDLE = int(argv[1]) HANDLE = int(argv[1])
class Main(): class Main(object):
# MAIN ENTRY POINT # MAIN ENTRY POINT
# @utils.profiling() # @utils.profiling()
def __init__(self): def __init__(self):
@ -33,7 +36,7 @@ class Main():
arguments = unicode_paths.decode(argv[2]) arguments = unicode_paths.decode(argv[2])
path = unicode_paths.decode(argv[0]) path = unicode_paths.decode(argv[0])
# Ensure unicode # Ensure unicode
for key, value in params.iteritems(): for key, value in params.items():
params[key.decode('utf-8')] = params.pop(key) params[key.decode('utf-8')] = params.pop(key)
params[key] = value.decode('utf-8') params[key] = value.decode('utf-8')
mode = params.get('mode', '') mode = params.get('mode', '')

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from .. import utils from .. import utils

View file

@ -1,8 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 from logging import getLogger
import Queue import queue
from threading import Lock, RLock from threading import Lock, RLock
import xbmc import xbmc
@ -38,9 +41,9 @@ class App(object):
self.lock_playlists = Lock() self.lock_playlists = Lock()
# Plex Companion Queue() # Plex Companion Queue()
self.companion_queue = Queue.Queue(maxsize=100) self.companion_queue = queue.Queue(maxsize=100)
# Websocket_client queue to communicate with librarysync # Websocket_client queue to communicate with librarysync
self.websocket_queue = Queue.Queue() self.websocket_queue = queue.Queue()
# xbmc.Monitor() instance from kodimonitor.py # xbmc.Monitor() instance from kodimonitor.py
self.monitor = None self.monitor = None
# xbmc.Player() instance # xbmc.Player() instance

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from .. import utils, json_rpc as js, variables as v from .. import utils, json_rpc as js, variables as v

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from .. import utils from .. import utils

View file

@ -3,6 +3,7 @@
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
class PlayState(object): class PlayState(object):
# "empty" dict for the PLAYER_STATES above. Use copy.deepcopy to duplicate! # "empty" dict for the PLAYER_STATES above. Use copy.deepcopy to duplicate!
template = { template = {

View file

@ -1,10 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from time import time as _time from time import time as _time
import threading import threading
import Queue import queue
import heapq import heapq
from collections import deque from collections import deque
@ -113,7 +118,7 @@ class KillableThread(threading.Thread):
self._suspension_reached.set() 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 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 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 self.maxsize > 0:
if not block: if not block:
if self._total_qsize() == self.maxsize: if self._total_qsize() == self.maxsize:
raise Queue.Full raise queue.Full
elif timeout is None: elif timeout is None:
while self._total_qsize() == self.maxsize: while self._total_qsize() == self.maxsize:
self.not_full.wait() self.not_full.wait()
@ -159,7 +164,7 @@ class ProcessingQueue(Queue.Queue, object):
while self._total_qsize() == self.maxsize: while self._total_qsize() == self.maxsize:
remaining = endtime - _time() remaining = endtime - _time()
if remaining <= 0.0: if remaining <= 0.0:
raise Queue.Full raise queue.Full
self.not_full.wait(remaining) self.not_full.wait(remaining)
self._put(item) self._put(item)
self.unfinished_tasks += 1 self.unfinished_tasks += 1
@ -212,7 +217,7 @@ class ProcessingQueue(Queue.Queue, object):
self._sections.append(section) self._sections.append(section)
self._queues.append( self._queues.append(
OrderedQueue() if section.plex_type == v.PLEX_TYPE_ALBUM OrderedQueue() if section.plex_type == v.PLEX_TYPE_ALBUM
else Queue.Queue()) else queue.Queue())
if self._current_section is None: if self._current_section is None:
self._activate_next_section() self._activate_next_section()
@ -237,7 +242,7 @@ class ProcessingQueue(Queue.Queue, object):
return item[1] 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 Queue that enforces an order on the items it returns. An item you push
onto the queue must be a tuple onto the queue must be a tuple
@ -328,7 +333,7 @@ class FunctionAsTask(Task):
self._callback(result) self._callback(result)
class MutablePriorityQueue(Queue.PriorityQueue): class MutablePriorityQueue(queue.PriorityQueue):
def _get(self, heappop=heapq.heappop): def _get(self, heappop=heapq.heappop):
self.queue.sort() self.queue.sort()
return heappop(self.queue) return heappop(self.queue)
@ -388,7 +393,7 @@ class BackgroundWorker(object):
self._runTask(self._task) self._runTask(self._task)
self._queue.task_done() self._queue.task_done()
self._task = None self._task = None
except Queue.Empty: except queue.Empty:
LOG.debug('(%s): Idle', self.name) LOG.debug('(%s): Idle', self.name)
def shutdown(self, block=True): def shutdown(self, block=True):
@ -428,7 +433,7 @@ class NonstoppingBackgroundWorker(BackgroundWorker):
return self._working return self._working
class BackgroundThreader: class BackgroundThreader(object):
def __init__(self, name=None, worker=BackgroundWorker, worker_count=6): def __init__(self, name=None, worker=BackgroundWorker, worker_count=6):
self.name = name self.name = name
self._queue = MutablePriorityQueue() self._queue = MutablePriorityQueue()
@ -508,7 +513,7 @@ class BackgroundThreader:
qitem.priority = lowest - 1 qitem.priority = lowest - 1
class ThreaderManager: class ThreaderManager(object):
def __init__(self, def __init__(self,
worker=NonstoppingBackgroundWorker, worker=NonstoppingBackgroundWorker,
worker_count=WORKER_COUNT): worker_count=WORKER_COUNT):

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
import xbmc import xbmc

View file

@ -28,7 +28,7 @@ def skip_to(params):
LOG.debug('Skipping to playQueueItemID %s, plex_id %s', LOG.debug('Skipping to playQueueItemID %s, plex_id %s',
playqueue_item_id, plex_id) playqueue_item_id, plex_id)
found = True found = True
for player in js.get_players().values(): for player in list(js.get_players().values()):
playqueue = PQ.PLAYQUEUES[player['playerid']] playqueue = PQ.PLAYQUEUES[player['playerid']]
for i, item in enumerate(playqueue.items): for i, item in enumerate(playqueue.items):
if item.id == playqueue_item_id: if item.id == playqueue_item_id:

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
import xbmc import xbmc
import xbmcgui import xbmcgui

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
import requests import requests
import requests.exceptions as exceptions 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 Manages any up/downloads with PKC. Careful to initiate correctly
Use startSession() to initiate. Use startSession() to initiate.

View file

@ -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. e.g. plugin://... calls. Hence be careful to only rely on window variables.
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import range
from logging import getLogger from logging import getLogger
import sys import sys

View file

@ -1,6 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from xbmc import executebuiltin from xbmc import executebuiltin

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from ntpath import dirname from ntpath import dirname
@ -162,7 +163,7 @@ class ItemBase(object):
Returns a dict of the Kodi ids: {<provider>: <kodi_unique_id>} Returns a dict of the Kodi ids: {<provider>: <kodi_unique_id>}
""" """
kodi_unique_ids = api.guids.copy() 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_unique_ids[provider] = self.kodidb.add_uniqueid(
kodi_id, kodi_id,
api.kodi_type, api.kodi_type,

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from .common import ItemBase from .common import ItemBase

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from .common import ItemBase, process_path from .common import ItemBase, process_path

View file

@ -5,6 +5,7 @@ Collection of functions using the Kodi JSON RPC interface.
See http://kodi.wiki/view/JSON-RPC_API See http://kodi.wiki/view/JSON-RPC_API
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from json import loads, dumps from json import loads, dumps
from xbmc import executeJSONRPC 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 Returns a list of all the active Kodi player ids (usually 3) as int
""" """
ret = [] ret = []
for player in get_players().values(): for player in list(get_players().values()):
ret.append(player['playerid']) ret.append(player['playerid'])
return ret return ret

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from threading import Lock from threading import Lock
from .. import db, path_ops from .. import db, path_ops
@ -65,7 +66,7 @@ class KodiDBBase(object):
""" """
Pass in an artworks dict (see PlexAPI) to set an items artwork. 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) self.add_art(url, kodi_id, kodi_type, kodi_art)
@db.catch_operationalerrors @db.catch_operationalerrors
@ -84,7 +85,7 @@ class KodiDBBase(object):
""" """
Pass in an artworks dict (see PlexAPI) to set an items artwork. 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) self.modify_art(url, kodi_id, kodi_type, kodi_art)
@db.catch_operationalerrors @db.catch_operationalerrors

View file

@ -318,7 +318,7 @@ class KodiVideoDB(common.KodiDBBase):
for the elmement kodi_id, kodi_type. for the elmement kodi_id, kodi_type.
Will also delete a freshly orphaned actor entry. 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) self._add_people_kind(kodi_id, kodi_type, kind, people_list)
@db.catch_operationalerrors @db.catch_operationalerrors
@ -363,7 +363,7 @@ class KodiVideoDB(common.KodiDBBase):
for kind, people_list in (people if people else for kind, people_list in (people if people else
{'actor': [], {'actor': [],
'director': [], 'director': [],
'writer': []}).iteritems(): 'writer': []}).items():
self._modify_people_kind(kodi_id, kodi_type, kind, people_list) self._modify_people_kind(kodi_id, kodi_type, kind, people_list)
@db.catch_operationalerrors @db.catch_operationalerrors

View file

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import next
from builtins import object
from logging import getLogger from logging import getLogger
import xbmc import xbmc

View file

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from logging import getLogger from logging import getLogger
from Queue import Full from queue import Full
from . import common, sections from . import common, sections
from ..plex_db import PlexDB from ..plex_db import PlexDB

View file

@ -1,8 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 from logging import getLogger
import Queue import queue
import xbmcgui import xbmcgui
@ -80,7 +83,7 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
@utils.log_time @utils.log_time
def process_new_and_changed_items(self, section_queue, processing_queue): def process_new_and_changed_items(self, section_queue, processing_queue):
LOG.debug('Start working') 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, scanner_thread = FillMetadataQueue(self.repair,
section_queue, section_queue,
get_metadata_queue, get_metadata_queue,
@ -182,7 +185,7 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
LOG.debug('Exiting threaded_get_generators') LOG.debug('Exiting threaded_get_generators')
def full_library_sync(self): def full_library_sync(self):
section_queue = Queue.Queue() section_queue = queue.Queue()
processing_queue = bg.ProcessingQueue(maxsize=XML_QUEUE_SIZE) processing_queue = bg.ProcessingQueue(maxsize=XML_QUEUE_SIZE)
kinds = [ kinds = [
(v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_MOVIE), (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_MOVIE),

View file

@ -1,7 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 import copy
from ..utils import etree from ..utils import etree
@ -56,7 +59,7 @@ NODE_TYPES = {
{ {
'mode': 'browseplex', 'mode': 'browseplex',
'key': ('/library/sections/{self.section_id}&%s' 'key': ('/library/sections/{self.section_id}&%s'
% urllib.urlencode({'sort': 'rating:desc'})), % urllib.parse.urlencode({'sort': 'rating:desc'})),
'section_id': '{self.section_id}' 'section_id': '{self.section_id}'
}, },
v.CONTENT_TYPE_MOVIE, v.CONTENT_TYPE_MOVIE,
@ -84,7 +87,7 @@ NODE_TYPES = {
{ {
'mode': 'browseplex', 'mode': 'browseplex',
'key': ('/library/sections/{self.section_id}&%s' 'key': ('/library/sections/{self.section_id}&%s'
% urllib.urlencode({'sort': 'random'})), % urllib.parse.urlencode({'sort': 'random'})),
'section_id': '{self.section_id}' 'section_id': '{self.section_id}'
}, },
v.CONTENT_TYPE_MOVIE, v.CONTENT_TYPE_MOVIE,
@ -154,7 +157,7 @@ NODE_TYPES = {
{ {
'mode': 'browseplex', 'mode': 'browseplex',
'key': ('/library/sections/{self.section_id}&%s' 'key': ('/library/sections/{self.section_id}&%s'
% urllib.urlencode({'sort': 'rating:desc'})), % urllib.parse.urlencode({'sort': 'rating:desc'})),
'section_id': '{self.section_id}' 'section_id': '{self.section_id}'
}, },
v.CONTENT_TYPE_SHOW, v.CONTENT_TYPE_SHOW,
@ -182,7 +185,7 @@ NODE_TYPES = {
{ {
'mode': 'browseplex', 'mode': 'browseplex',
'key': ('/library/sections/{self.section_id}&%s' 'key': ('/library/sections/{self.section_id}&%s'
% urllib.urlencode({'sort': 'random'})), % urllib.parse.urlencode({'sort': 'random'})),
'section_id': '{self.section_id}' 'section_id': '{self.section_id}'
}, },
v.CONTENT_TYPE_SHOW, v.CONTENT_TYPE_SHOW,
@ -192,7 +195,7 @@ NODE_TYPES = {
{ {
'mode': 'browseplex', 'mode': 'browseplex',
'key': ('/library/sections/{self.section_id}/recentlyViewed&%s' '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}' 'section_id': '{self.section_id}'
}, },
v.CONTENT_TYPE_EPISODE, v.CONTENT_TYPE_EPISODE,
@ -236,7 +239,7 @@ def node_pms(section, node_name, args):
else: else:
folder = False folder = False
xml = etree.Element('node', xml = etree.Element('node',
attrib={'order': unicode(section.order), attrib={'order': str(section.order),
'type': 'folder' if folder else 'filter'}) 'type': 'folder' if folder else 'filter'})
etree.SubElement(xml, 'label').text = node_name etree.SubElement(xml, 'label').text = node_name
etree.SubElement(xml, 'icon').text = ICON_PATH 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 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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -270,7 +273,7 @@ def node_ondeck(section, node_name):
def node_recent(section, node_name): def node_recent(section, node_name):
xml = etree.Element('node', xml = etree.Element('node',
attrib={'order': unicode(section.order), attrib={'order': str(section.order),
'type': 'filter'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -299,7 +302,7 @@ def node_recent(section, node_name):
def node_all(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -316,7 +319,7 @@ def node_all(section, node_name):
def node_recommended(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -337,7 +340,7 @@ def node_recommended(section, node_name):
def node_genres(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -355,7 +358,7 @@ def node_genres(section, node_name):
def node_sets(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -374,7 +377,7 @@ def node_sets(section, node_name):
def node_random(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',
@ -392,7 +395,7 @@ def node_random(section, node_name):
def node_lastplayed(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'}) 'type': 'filter'})
etree.SubElement(xml, 'match').text = 'all' etree.SubElement(xml, 'match').text = 'all'
rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag', rule = etree.SubElement(xml, 'rule', attrib={'field': 'tag',

View file

@ -1,6 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
import copy import copy
@ -98,7 +101,7 @@ class Section(object):
"}}").format(self=self).encode('utf-8') "}}").format(self=self).encode('utf-8')
__str__ = __repr__ __str__ = __repr__
def __nonzero__(self): def __bool__(self):
return (self.section_id is not None and return (self.section_id is not None and
self.name is not None and self.name is not None and
self.section_type is not None) self.section_type is not None)
@ -236,7 +239,7 @@ class Section(object):
{key: '{self.<Section attribute>}'} {key: '{self.<Section attribute>}'}
""" """
args = copy.deepcopy(args) args = copy.deepcopy(args)
for key, value in args.iteritems(): for key, value in args.items():
args[key] = value.format(self=self) args[key] = value.format(self=self)
return utils.extend_url('plugin://%s' % v.ADDON_ID, args) return utils.extend_url('plugin://%s' % v.ADDON_ID, args)
@ -265,7 +268,7 @@ class Section(object):
args = { args = {
'mode': 'browseplex', 'mode': 'browseplex',
'key': '/library/sections/%s' % self.section_id, '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: if not self.sync_to_kodi:
args['synched'] = 'false' args['synched'] = 'false'
@ -276,7 +279,7 @@ class Section(object):
args = { args = {
'mode': 'browseplex', 'mode': 'browseplex',
'key': '/library/sections/%s/all' % self.section_id, '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: if not self.sync_to_kodi:
args['synched'] = 'false' args['synched'] = 'false'
@ -318,7 +321,7 @@ class Section(object):
if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')): if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')):
LOG.debug('Creating index.xml for section %s', self.name) LOG.debug('Creating index.xml for section %s', self.name)
xml = etree.Element('node', xml = etree.Element('node',
attrib={'order': unicode(self.order)}) attrib={'order': str(self.order)})
etree.SubElement(xml, 'label').text = self.name etree.SubElement(xml, 'label').text = self.name
etree.SubElement(xml, 'icon').text = self.icon or nodes.ICON_PATH etree.SubElement(xml, 'icon').text = self.icon or nodes.ICON_PATH
self._write_xml(xml, 'index.xml') 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.path' % node, clear=True)
utils.window('%s.id' % node, clear=True) utils.window('%s.id' % node, clear=True)
# Just clear everything here, ignore the plex_type # 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: for kind in WINDOW_ARGS:
node = 'Plex.nodes.%s.%s.%s' % (index, typus, kind) node = 'Plex.nodes.%s.%s.%s' % (index, typus, kind)
utils.window(node, clear=True) utils.window(node, clear=True)

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED
@ -160,7 +161,7 @@ def store_timeline_message(data):
continue continue
status = int(message['state']) status = int(message['state'])
if typus == 'playlist' and PLAYLIST_SYNC_ENABLED: if typus == 'playlist' and PLAYLIST_SYNC_ENABLED:
playlists.websocket(plex_id=unicode(message['itemID']), playlists.websocket(plex_id=str(message['itemID']),
status=status) status=status)
elif status == 9: elif status == 9:
# Immediately and always process deletions (as the PMS will # Immediately and always process deletions (as the PMS will

View file

@ -41,7 +41,7 @@ class LogHandler(logging.StreamHandler):
self.setFormatter(logging.Formatter(fmt=b"%(name)s: %(message)s")) self.setFormatter(logging.Formatter(fmt=b"%(name)s: %(message)s"))
def emit(self, record): def emit(self, record):
if isinstance(record.msg, unicode): if isinstance(record.msg, str):
record.msg = record.msg.encode('utf-8') record.msg = record.msg.encode('utf-8')
try: try:
xbmc.log(self.format(record), level=LEVELS[record.levelno]) xbmc.log(self.format(record), level=LEVELS[record.levelno])

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
from . import variables as v from . import variables as v

View file

@ -39,6 +39,7 @@ Functions
.. autofunction:: parent_dir_path .. autofunction:: parent_dir_path
""" """
from builtins import next
import os.path import os.path
from functools import partial from functools import partial
@ -72,7 +73,7 @@ def get_dir_walker(recursive, topdown=True, followlinks=False):
try: try:
yield next(os.walk(path, topdown=topdown, followlinks=followlinks)) yield next(os.walk(path, topdown=topdown, followlinks=followlinks))
except NameError: 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 return walk

View file

@ -34,6 +34,7 @@ Functions
.. autofunction:: filter_paths .. autofunction:: filter_paths
""" """
from builtins import map
from fnmatch import fnmatch, fnmatchcase from fnmatch import fnmatch, fnmatchcase
__all__ = ['match_path', __all__ = ['match_path',

View file

@ -4,6 +4,9 @@
Used to kick off Kodi playback Used to kick off Kodi playback
""" """
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from threading import Thread from threading import Thread
import datetime import datetime
@ -296,7 +299,7 @@ def resume_dialog(resume):
resume = datetime.timedelta(seconds=resume) resume = datetime.timedelta(seconds=resume)
LOG.debug('Showing PKC resume dialog for resume: %s', resume) LOG.debug('Showing PKC resume dialog for resume: %s', resume)
answ = utils.dialog('contextmenu', 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)]) utils.lang(12021)])
if answ == -1: if answ == -1:
return return

View file

@ -4,6 +4,7 @@
Collection of functions associated with Kodi and Plex playlists and playqueues Collection of functions associated with Kodi and Plex playlists and playqueues
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from .plex_api import API from .plex_api import API

View file

@ -1,8 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 from logging import getLogger
import Queue import queue
import time import time
import os import os
import hashlib import hashlib
@ -188,7 +191,7 @@ class PlaylistObserver(Observer):
while time.time() - start < timeout: while time.time() - start < timeout:
try: try:
new_event, new_watch = event_queue.get(block=False) new_event, new_watch = event_queue.get(block=False)
except Queue.Empty: except queue.Empty:
app.APP.monitor.waitForAbort(0.2) app.APP.monitor.waitForAbort(0.2)
else: else:
event_queue.task_done() event_queue.task_done()

View file

@ -5,6 +5,7 @@ Synced playlists are stored in our plex.db. Interact with it through this
module module
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import next
from logging import getLogger from logging import getLogger
from .common import Playlist, PlaylistError from .common import Playlist, PlaylistError

View file

@ -5,6 +5,7 @@ Functions to communicate with the currently connected PMS in order to
manipulate playlists manipulate playlists
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
from .common import PlaylistError from .common import PlaylistError
@ -108,7 +109,7 @@ def add_items(playlist, plex_ids):
'smart': 0, 'smart': 0,
'uri': ('server://%s/com.plexapp.plugins.library/library/metadata/%s' 'uri': ('server://%s/com.plexapp.plugins.library/library/metadata/%s'
% (app.CONN.machine_identifier, % (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/', xml = DU().downloadUrl(url='{server}/playlists/',
action_type='POST', action_type='POST',

View file

@ -4,6 +4,7 @@
Monitors the Kodi playqueue and adjusts the Plex playqueue accordingly Monitors the Kodi playqueue and adjusts the Plex playqueue accordingly
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import range
from logging import getLogger from logging import getLogger
import copy import copy

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from ..kodi_db import KodiVideoDB, KodiMusicDB from ..kodi_db import KodiVideoDB, KodiMusicDB
@ -71,7 +72,7 @@ class Artwork(object):
# either the season or the show # either the season or the show
return artworks return artworks
for kodi_artwork, plex_artwork in \ 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) art = self.one_artwork(plex_artwork)
if art: if art:
artworks[kodi_artwork] = art artworks[kodi_artwork] = art
@ -109,7 +110,7 @@ class Artwork(object):
with KodiMusicDB(lock=False) as kodidb: with KodiMusicDB(lock=False) as kodidb:
return kodidb.get_art(kodi_id, kodi_type) 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) art = self.one_artwork(plex_artwork)
if art: if art:
artworks[kodi_artwork] = art artworks[kodi_artwork] = art

View file

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from builtins import object
from logging import getLogger from logging import getLogger
from re import sub from re import sub
@ -357,9 +359,9 @@ class Base(object):
total = int(self.xml.attrib['leafCount']) total = int(self.xml.attrib['leafCount'])
watched = int(self.xml.attrib['viewedLeafCount']) watched = int(self.xml.attrib['viewedLeafCount'])
return { return {
'totalepisodes': unicode(total), 'totalepisodes': str(total),
'watchedepisodes': unicode(watched), 'watchedepisodes': str(watched),
'unwatchedepisodes': unicode(total - watched) 'unwatchedepisodes': str(total - watched)
} }
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass

View file

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from builtins import range
from logging import getLogger from logging import getLogger
from re import sub from re import sub
from string import punctuation from string import punctuation

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from .. import utils, variables as v, app from .. import utils, variables as v, app

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
from ..utils import cast from ..utils import cast

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from ..utils import cast from ..utils import cast

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from ..utils import cast from ..utils import cast
from .. import timing, variables as v, app from .. import timing, variables as v, app

View file

@ -4,9 +4,11 @@
The Plex Companion master python file The Plex Companion master python file
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from logging import getLogger from logging import getLogger
from threading import Thread from threading import Thread
from Queue import Empty from queue import Empty
from socket import SHUT_RDWR from socket import SHUT_RDWR
from xbmc import executebuiltin from xbmc import executebuiltin

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from threading import Lock from threading import Lock
from .. import db, variables as v from .. import db, variables as v

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from .. import variables as v from .. import variables as v

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from .. import variables as v from .. import variables as v

View file

@ -3,6 +3,7 @@
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
class Playlists(object): class Playlists(object):
def playlist_ids(self): def playlist_ids(self):
""" """

View file

@ -3,6 +3,7 @@
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
class Sections(object): class Sections(object):
def all_sections(self): def all_sections(self):
""" """

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from .. import variables as v from .. import variables as v

View file

@ -1,6 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from ast import literal_eval from ast import literal_eval
from copy import deepcopy 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') LOG.error('Could not get list of PMS from plex.tv')
return [] return []
from Queue import Queue from queue import Queue
queue = Queue() queue = Queue()
thread_queue = [] thread_queue = []

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
from logging import getLogger from logging import getLogger
import time import time
import threading import threading

View file

@ -1,8 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
import httplib import http.client
import traceback import traceback
import string import string
import errno import errno
@ -15,7 +19,7 @@ LOG = getLogger('PLEX.httppersist')
############################################################################### ###############################################################################
class RequestMgr: class RequestMgr(object):
def __init__(self): def __init__(self):
self.conns = {} self.conns = {}
@ -23,9 +27,9 @@ class RequestMgr:
conn = self.conns.get(protocol + host + str(port), False) conn = self.conns.get(protocol + host + str(port), False)
if not conn: if not conn:
if protocol == "https": if protocol == "https":
conn = httplib.HTTPSConnection(host, port) conn = http.client.HTTPSConnection(host, port)
else: else:
conn = httplib.HTTPConnection(host, port) conn = http.client.HTTPConnection(host, port)
self.conns[protocol + host + str(port)] = conn self.conns[protocol + host + str(port)] = conn
return conn return conn
@ -36,7 +40,7 @@ class RequestMgr:
self.conns.pop(protocol + host + str(port), None) self.conns.pop(protocol + host + str(port), None)
def dumpConnections(self): def dumpConnections(self):
for conn in self.conns.values(): for conn in list(self.conns.values()):
conn.close() conn.close()
self.conns = {} self.conns = {}

View file

@ -4,10 +4,12 @@
Plex Companion listener Plex Companion listener
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from logging import getLogger from logging import getLogger
from re import sub from re import sub
from SocketServer import ThreadingMixIn from socketserver import ThreadingMixIn
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from http.server import HTTPServer, BaseHTTPRequestHandler
from .. import utils, companion, json_rpc as js, clientinfo, variables as v from .. import utils, companion, json_rpc as js, clientinfo, variables as v
from .. import app from .. import app

View file

@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. MA 02110-1301, USA.
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from builtins import object
import logging import logging
import socket import socket
import threading import threading
@ -39,7 +41,7 @@ log = logging.getLogger('PLEX.plexgdm')
############################################################################### ###############################################################################
class plexgdm: class plexgdm(object):
def __init__(self): def __init__(self):
self.discover_message = 'M-SEARCH * HTTP/1.0' self.discover_message = 'M-SEARCH * HTTP/1.0'

View file

@ -5,6 +5,10 @@ Manages getting playstate from Kodi and sending it to the PMS as well as
subscribed Plex Companion clients. subscribed Plex Companion clients.
""" """
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from threading import Thread from threading import Thread
@ -174,7 +178,7 @@ class SubscriptionMgr(object):
Returns the string 'key1="value1" key2="value2" ...' for dictionary Returns the string 'key1="value1" key2="value2" ...' for dictionary
""" """
answ = '' answ = ''
for key, value in dictionary.iteritems(): for key, value in dictionary.items():
answ += '%s="%s" ' % (key, value) answ += '%s="%s" ' % (key, value)
return answ return answ
@ -317,7 +321,7 @@ class SubscriptionMgr(object):
Hence we'd have a missmatch between the state.PLAYER_STATES and our Hence we'd have a missmatch between the state.PLAYER_STATES and our
playqueues. playqueues.
""" """
for player in players.values(): for player in list(players.values()):
info = app.PLAYSTATE.player_states[player['playerid']] info = app.PLAYSTATE.player_states[player['playerid']]
playqueue = PQ.PLAYQUEUES[player['playerid']] playqueue = PQ.PLAYQUEUES[player['playerid']]
position = self._get_correct_position(info, playqueue) position = self._get_correct_position(info, playqueue)
@ -342,7 +346,7 @@ class SubscriptionMgr(object):
# Get all the active/playing Kodi players (video, audio, pictures) # Get all the active/playing Kodi players (video, audio, pictures)
players = js.get_players() players = js.get_players()
# Update the PKC info with what's playing on the Kodi side # 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']) update_player_info(player['playerid'])
# Check whether we can use the CURRENT info or whether PKC is still # Check whether we can use the CURRENT info or whether PKC is still
# initializing # initializing
@ -352,12 +356,12 @@ class SubscriptionMgr(object):
self._notify_server(players) self._notify_server(players)
if self.subscribers: if self.subscribers:
msg = self.msg(players) msg = self.msg(players)
for subscriber in self.subscribers.values(): for subscriber in list(self.subscribers.values()):
subscriber.send_update(msg) subscriber.send_update(msg)
self.lastplayers = players self.lastplayers = players
def _notify_server(self, players): def _notify_server(self, players):
for typus, player in players.iteritems(): for typus, player in players.items():
self._send_pms_notification( self._send_pms_notification(
player['playerid'], self._get_pms_params(player['playerid'])) player['playerid'], self._get_pms_params(player['playerid']))
try: try:
@ -365,7 +369,7 @@ class SubscriptionMgr(object):
except KeyError: except KeyError:
pass pass
# Process the players we have left (to signal a stop) # 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.last_params['state'] = 'stopped'
self._send_pms_notification(player['playerid'], self.last_params) self._send_pms_notification(player['playerid'], self.last_params)
@ -442,13 +446,13 @@ class SubscriptionMgr(object):
(Calls the cleanup() method of the subscriber) (Calls the cleanup() method of the subscriber)
""" """
with app.APP.lock_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: if subscriber.uuid == uuid or subscriber.host == uuid:
subscriber.cleanup() subscriber.cleanup()
del self.subscribers[subscriber.uuid] del self.subscribers[subscriber.uuid]
def _cleanup(self): def _cleanup(self):
for subscriber in self.subscribers.values(): for subscriber in list(self.subscribers.values()):
if subscriber.age > 30: if subscriber.age > 30:
subscriber.cleanup() subscriber.cleanup()
del self.subscribers[subscriber.uuid] del self.subscribers[subscriber.uuid]

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import object
import logging import logging
import sys import sys
import xbmc import xbmc

View file

@ -28,7 +28,7 @@ from . import platform
try: try:
# Python 2 # Python 2
str_cls = unicode str_cls = str
bytes_cls = str bytes_cls = str
except NameError: except NameError:
# Python 3 # Python 3

View file

@ -5,6 +5,8 @@ Used to shovel data from separate Kodi Python instances to the main thread
and vice versa. and vice versa.
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from builtins import object
from logging import getLogger from logging import getLogger
import json import json
@ -33,15 +35,15 @@ def cast(func, value):
return value return value
elif func == bool: elif func == bool:
return bool(int(value)) return bool(int(value))
elif func == unicode: elif func == str:
if isinstance(value, (int, long, float)): if isinstance(value, (int, float)):
return unicode(value) return str(value)
elif isinstance(value, unicode): elif isinstance(value, str):
return value return value
else: else:
return value.decode('utf-8') return value.decode('utf-8')
elif func == str: elif func == str:
if isinstance(value, (int, long, float)): if isinstance(value, (int, float)):
return str(value) return str(value)
elif isinstance(value, str): elif isinstance(value, str):
return value return value
@ -163,7 +165,7 @@ def convert_pkc_to_listitem(pkc_listitem):
listitem.addStreamInfo(**stream) listitem.addStreamInfo(**stream)
if data['art']: if data['art']:
listitem.setArt(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)) listitem.setProperty(key, cast(str, value))
if data['subtitles']: if data['subtitles']:
listitem.setSubtitles(data['subtitles']) listitem.setSubtitles(data['subtitles'])

View file

@ -4,13 +4,17 @@
Various functions and decorators for PKC Various functions and decorators for PKC
""" """
from __future__ import absolute_import, division, unicode_literals 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 logging import getLogger
from sqlite3 import OperationalError from sqlite3 import OperationalError
from datetime import datetime from datetime import datetime
from unicodedata import normalize from unicodedata import normalize
from threading import Lock from threading import Lock
import urllib import urllib.request, urllib.parse, urllib.error
import urlparse as _urlparse import urllib.parse as _urlparse
# Originally tried faster cElementTree, but does NOT work reliably with Kodi # Originally tried faster cElementTree, but does NOT work reliably with Kodi
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
# etree parse unsafe; make sure we're always receiving unicode # etree parse unsafe; make sure we're always receiving unicode
@ -191,7 +195,7 @@ def dialog(typus, *args, **kwargs):
'{warning}': xbmcgui.NOTIFICATION_WARNING, '{warning}': xbmcgui.NOTIFICATION_WARNING,
'{error}': xbmcgui.NOTIFICATION_ERROR '{error}': xbmcgui.NOTIFICATION_ERROR
} }
for key, value in types.iteritems(): for key, value in types.items():
kwargs['icon'] = kwargs['icon'].replace(key, value) kwargs['icon'] = kwargs['icon'].replace(key, value)
if 'type' in kwargs: if 'type' in kwargs:
types = { types = {
@ -291,15 +295,15 @@ def cast(func, value):
return value return value
elif func == bool: elif func == bool:
return bool(int(value)) return bool(int(value))
elif func == unicode: elif func == str:
if isinstance(value, (int, long, float)): if isinstance(value, (int, float)):
return unicode(value) return str(value)
elif isinstance(value, unicode): elif isinstance(value, str):
return value return value
else: else:
return value.decode('utf-8') return value.decode('utf-8')
elif func == str: elif func == str:
if isinstance(value, (int, long, float)): if isinstance(value, (int, float)):
return str(value) return str(value)
elif isinstance(value, str): elif isinstance(value, str):
return value return value
@ -329,7 +333,7 @@ def extend_url(url, params):
in unicode in unicode
""" """
params = encode_dict(params) if params else {} 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: if '?' in url:
return '%s&%s' % (url, params) return '%s&%s' % (url, params)
else: else:
@ -343,10 +347,10 @@ def encode_dict(dictionary):
Useful for urllib.urlencode or urllib.(un)quote Useful for urllib.urlencode or urllib.(un)quote
""" """
for key, value in dictionary.iteritems(): for key, value in dictionary.items():
if isinstance(key, unicode): if isinstance(key, str):
dictionary[key.encode('utf-8')] = dictionary.pop(key) dictionary[key.encode('utf-8')] = dictionary.pop(key)
if isinstance(value, unicode): if isinstance(value, str):
dictionary[key] = value.encode('utf-8') dictionary[key] = value.encode('utf-8')
return dictionary return dictionary
@ -357,11 +361,11 @@ def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
either as str or unicode either as str or unicode
Returns a dict with lists as values; all entires 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 = qs.encode('utf-8')
qs = _urlparse.parse_qs(qs, keep_blank_values, strict_parsing) qs = _urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
return {k.decode('utf-8'): [e.decode('utf-8') for e in v] 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): 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 unicode-safe way to use urlparse.parse_qsl(). Pass in either str or unicode
Returns a list of unicode tuples Returns a list of unicode tuples
""" """
if isinstance(qs, unicode): if isinstance(qs, str):
qs = qs.encode('utf-8') qs = qs.encode('utf-8')
qs = _urlparse.parse_qsl(qs, keep_blank_values, strict_parsing) qs = _urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
return [(x.decode('utf-8'), y.decode('utf-8')) for (x, y) in qs] 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 unicode-safe way to use urlparse.urlparse(). Pass in either str or unicode
CAREFUL: returns an encoded urlparse.ParseResult()! CAREFUL: returns an encoded urlparse.ParseResult()!
""" """
if isinstance(url, unicode): if isinstance(url, str):
url = url.encode('utf-8') url = url.encode('utf-8')
return _urlparse.urlparse(url, scheme, allow_fragments) 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) user = is_http_dav_ftp.group(6)
psswd = is_http_dav_ftp.group(7) psswd = is_http_dav_ftp.group(7)
if user and psswd: if user and psswd:
user = urllib.quote(user.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.quote(psswd.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) host = is_http_dav_ftp.group(8)
port = is_http_dav_ftp.group(10) port = is_http_dav_ftp.group(10)
url_path = path.replace(is_http_dav_ftp.group(), '', 1) url_path = path.replace(is_http_dav_ftp.group(), '', 1)
if url_path: 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') safe=safe_url_char).decode('utf-8')
return protocol + \ return protocol + \
u'://' + \ u'://' + \
@ -422,7 +426,7 @@ def escape_path(path, safe_url_char=SAFE_URL_CHARACTERS):
else: else:
# If paths does not seem to be a http(s), dav(s) or (s)ftp url (e.g. plugin://) # If paths does not seem to be a http(s), dav(s) or (s)ftp url (e.g. plugin://)
# escape path as before # 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') 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 unicode-safe way to use urllib.quote(). Pass in either str or unicode
Returns unicode Returns unicode
""" """
if isinstance(s, unicode): if isinstance(s, str):
s = s.encode('utf-8') 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') 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 unicode-safe way to use urllib.quote(). Pass in either str or unicode
Returns unicode Returns unicode
""" """
if isinstance(s, unicode): if isinstance(s, str):
s = s.encode('utf-8') 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') 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 unicode-safe way to use urllib.unquote(). Pass in either str or unicode
Returns unicode Returns unicode
""" """
if isinstance(s, unicode): if isinstance(s, str):
s = s.encode('utf-8') s = s.encode('utf-8')
s = urllib.unquote(s) s = urllib.parse.unquote(s)
return s.decode('utf-8') 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 fails with e.g. Android TV's Python, which does not accept arguments for
string.encode() string.encode()
""" """
if isinstance(string, unicode): if isinstance(string, str):
# already decoded # already decoded
return string return string
try: try:
@ -496,9 +500,9 @@ def slugify(text):
Normalizes text (in unicode or string) to e.g. enable safe filenames. Normalizes text (in unicode or string) to e.g. enable safe filenames.
Returns unicode Returns unicode
""" """
if not isinstance(text, unicode): if not isinstance(text, str):
text = unicode(text) text = str(text)
return unicode(normalize('NFKD', text).encode('ascii', 'ignore')) return str(normalize('NFKD', text).encode('ascii', 'ignore'))
def valid_filename(text): def valid_filename(text):
@ -542,7 +546,7 @@ def escape_html(string):
'>': '&gt;', '>': '&gt;',
'&': '&amp;' '&': '&amp;'
} }
for key, value in escapes.iteritems(): for key, value in escapes.items():
string = string.replace(key, value) string = string.replace(key, value)
return string return string
@ -690,7 +694,7 @@ def normalize_string(text):
# Remove dots from the last character as windows can not have directories # Remove dots from the last character as windows can not have directories
# with dots at the end # with dots at the end
text = text.rstrip('.') text = text.rstrip('.')
text = try_encode(normalize('NFKD', unicode(text, 'utf-8'))) text = try_encode(normalize('NFKD', str(text, 'utf-8')))
return text return text
@ -713,7 +717,7 @@ def normalize_nodes(text):
# Remove dots from the last character as windows can not have directories # Remove dots from the last character as windows can not have directories
# with dots at the end # with dots at the end
text = text.rstrip('.') text = text.rstrip('.')
text = normalize('NFKD', unicode(text, 'utf-8')) text = normalize('NFKD', str(text, 'utf-8'))
return text return text
@ -936,7 +940,7 @@ class XmlKodiSetting(object):
# Write new values # Write new values
element.text = value element.text = value
if attrib: if attrib:
for key, attribute in attrib.iteritems(): for key, attribute in attrib.items():
element.set(key, attribute) element.set(key, attribute)
return element return element
@ -958,7 +962,7 @@ def process_method_on_list(method_to_run, items):
pool.join() pool.join()
else: else:
all_items = [method_to_run(item) for item in items] 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 return all_items

View file

@ -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 fails with e.g. Android TV's Python, which does not accept arguments for
string.encode() string.encode()
""" """
if isinstance(string, unicode): if isinstance(string, str):
# already decoded # already decoded
return string return string
try: try:

View file

@ -85,6 +85,7 @@ Event Handler Classes
""" """
from builtins import object
import os.path import os.path
import logging import logging
import re import re

View file

@ -16,6 +16,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from builtins import object
from __future__ import with_statement from __future__ import with_statement
import threading import threading
from ..utils import BaseThread from ..utils import BaseThread

View file

@ -150,7 +150,7 @@ class FSEventsObserver(BaseObserver):
def schedule(self, event_handler, path, recursive=False): def schedule(self, event_handler, path, recursive=False):
# Python 2/3 compat # Python 2/3 compat
try: try:
str_class = unicode str_class = str
except NameError: except NameError:
str_class = str str_class = str

View file

@ -19,7 +19,11 @@
:synopsis: FSEvents based emitter implementation. :synopsis: FSEvents based emitter implementation.
:platforms: Mac OS X :platforms: Mac OS X
""" """
from __future__ import absolute_import
from builtins import hex
from builtins import zip
from builtins import object
import os import os
import logging import logging
import unicodedata import unicodedata
@ -45,7 +49,7 @@ from ..observers.api import (
# pyobjc # pyobjc
import AppKit import AppKit
from FSEvents import ( from .FSEvents import (
FSEventStreamCreate, FSEventStreamCreate,
CFRunLoopGetCurrent, CFRunLoopGetCurrent,
FSEventStreamScheduleWithRunLoop, FSEventStreamScheduleWithRunLoop,
@ -57,7 +61,7 @@ from FSEvents import (
FSEventStreamRelease, FSEventStreamRelease,
) )
from FSEvents import ( from .FSEvents import (
kCFAllocatorDefault, kCFAllocatorDefault,
kCFRunLoopDefaultMode, kCFRunLoopDefaultMode,
kFSEventStreamEventIdSinceNow, kFSEventStreamEventIdSinceNow,

View file

@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from builtins import object
from __future__ import with_statement from __future__ import with_statement
import os import os
import errno import errno

View file

@ -77,6 +77,7 @@ Collections and Utility Classes
""" """
from builtins import object
from __future__ import with_statement from __future__ import with_statement
from ..utils import platform from ..utils import platform

View file

@ -36,6 +36,7 @@
# Portions of this code were taken from pyfilesystem, which uses the above # Portions of this code were taken from pyfilesystem, which uses the above
# new BSD license. # new BSD license.
from builtins import object
from __future__ import with_statement from __future__ import with_statement
import ctypes.wintypes import ctypes.wintypes
@ -308,7 +309,7 @@ def read_directory_changes(handle, recursive):
# Python 2/3 compat # Python 2/3 compat
try: try:
int_class = long int_class = int
except NameError: except NameError:
int_class = int int_class = int
return event_buffer.raw, int_class(nbytes.value) return event_buffer.raw, int_class(nbytes.value)

View file

@ -30,6 +30,7 @@ Classes
:inherited-members: :inherited-members:
""" """
from __future__ import absolute_import
import os import os
import sys import sys
import threading import threading
@ -39,7 +40,7 @@ from .compat import Event
if sys.version_info[0] == 2 and platform.is_windows(): if sys.version_info[0] == 2 and platform.is_windows():
# st_ino is not implemented in os.stat on this platform # st_ino is not implemented in os.stat on this platform
import win32stat from . import win32stat
stat = win32stat.stat stat = win32stat.stat
else: else:
stat = os.stat stat = os.stat

View file

@ -36,6 +36,8 @@ Classes
""" """
from builtins import next
from builtins import range
import sys import sys
import collections import collections
from .compat import queue from .compat import queue

View file

@ -13,6 +13,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from future import standard_library
standard_library.install_aliases()
import sys import sys
__all__ = ['queue', 'Event'] __all__ = ['queue', 'Event']
@ -20,7 +22,7 @@ __all__ = ['queue', 'Event']
try: try:
import queue import queue
except ImportError: except ImportError:
import Queue as queue import queue as queue
if sys.version_info < (2, 7): if sys.version_info < (2, 7):

View file

@ -14,6 +14,7 @@ decorators:
- deprecated - deprecated
""" """
from builtins import zip
import functools import functools
import warnings import warnings
import threading import threading

View file

@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from builtins import object
import time import time
import threading import threading
from collections import deque from collections import deque

View file

@ -44,6 +44,8 @@ Classes
""" """
from builtins import str
from builtins import object
import errno import errno
import os import os
from stat import S_ISDIR from stat import S_ISDIR

View file

@ -32,6 +32,8 @@ Example:
def my_function(args): def my_function(args):
pass pass
""" """
from builtins import map
from builtins import zip
import inspect import inspect
import sys import sys

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Backport of Event from py2.7 (method wait in py2.6 returns None) # Backport of Event from py2.7 (method wait in py2.6 returns None)
from builtins import object
from threading import Condition, Lock from threading import Condition, Lock

View file

@ -31,7 +31,7 @@ def import_module(target, relative_to=None):
relative_parts = relative_to.split('.') relative_parts = relative_to.split('.')
relative_to = '.'.join(relative_parts[:-(target_depth - 1) or None]) relative_to = '.'.join(relative_parts[:-(target_depth - 1) or None])
if len(target_path) > 1: 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:] fromlist = target_path[-1:]
target = fromlist[0] target = fromlist[0]
elif not relative_to: elif not relative_to:

View file

@ -28,7 +28,7 @@ from . import platform
try: try:
# Python 2 # Python 2
str_cls = unicode str_cls = str
bytes_cls = str bytes_cls = str
except NameError: except NameError:
# Python 3 # Python 3

View file

@ -24,7 +24,9 @@ Functions
.. autofunction:: stat .. autofunction:: stat
""" """
from __future__ import division
from past.utils import old_div
import ctypes import ctypes
import ctypes.wintypes import ctypes.wintypes
import stat as stdstat import stat as stdstat
@ -99,7 +101,7 @@ def _to_mode(attr):
def _to_unix_time(ft): def _to_unix_time(ft):
t = (ft.dwHighDateTime) << 32 | ft.dwLowDateTime t = (ft.dwHighDateTime) << 32 | ft.dwLowDateTime
return (t / 10000000) - 11644473600 return (old_div(t, 10000000)) - 11644473600
def stat(path): def stat(path):
hfile = CreateFile(path, hfile = CreateFile(path,

View file

@ -22,6 +22,8 @@
:synopsis: ``watchmedo`` shell script utility. :synopsis: ``watchmedo`` shell script utility.
""" """
from future import standard_library
standard_library.install_aliases()
import os.path import os.path
import sys import sys
import yaml import yaml
@ -29,10 +31,10 @@ import time
import logging import logging
try: try:
from cStringIO import StringIO from io import StringIO
except ImportError: except ImportError:
try: try:
from StringIO import StringIO from io import StringIO
except ImportError: except ImportError:
from io import StringIO from io import StringIO

View file

@ -20,6 +20,12 @@ Copyright (C) 2010 Hiroki Ohtani(liris)
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 import socket
try: try:
@ -35,7 +41,7 @@ except ImportError:
HAVE_SSL = False HAVE_SSL = False
from urlparse import urlparse from urllib.parse import urlparse
import os import os
import array import array
import struct import struct
@ -228,7 +234,7 @@ def create_connection(url, timeout=None, **options):
_MAX_INTEGER = (1 << 32) - 1 _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 _MAX_CHAR_BYTE = (1 << 8) - 1
# ref. Websocket gets an update, and it breaks stuff. # ref. Websocket gets an update, and it breaks stuff.
@ -308,7 +314,7 @@ class ABNF(object):
opcode: operation code. please see OPCODE_XXX. 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) data = utils.try_encode(data)
# mask must be set if send data from client # mask must be set if send data from client
return ABNF(1, 0, 0, 0, opcode, 1, data) return ABNF(1, 0, 0, 0, opcode, 1, data)
@ -358,7 +364,7 @@ class ABNF(object):
""" """
_m = array.array("B", mask_key) _m = array.array("B", mask_key)
_d = array.array("B", data) _d = array.array("B", data)
for i in xrange(len(_d)): for i in range(len(_d)):
_d[i] ^= _m[i % 4] _d[i] ^= _m[i % 4]
return _d.tostring() return _d.tostring()
@ -529,7 +535,7 @@ class WebSocket(object):
@staticmethod @staticmethod
def _validate_header(headers, key): 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) r = headers.get(k, None)
if not r: if not r:
return False return False
@ -882,11 +888,11 @@ class WebSocketApp(object):
if data is None or self.keep_running is False: if data is None or self.keep_running is False:
break break
self._callback(self.on_message, data) self._callback(self.on_message, data)
except Exception, e: except Exception as e:
if "timed out" not in e.args[0]: if "timed out" not in e.args[0]:
raise e raise e
except Exception, e: except Exception as e:
self._callback(self.on_error, e) self._callback(self.on_error, e)
finally: finally:
if thread: if thread:
@ -899,7 +905,7 @@ class WebSocketApp(object):
if callback: if callback:
try: try:
callback(self, *args) callback(self, *args)
except Exception, e: except Exception as e:
LOG.error(e) LOG.error(e)
_, _, tb = sys.exc_info() _, _, tb = sys.exc_info()
traceback.print_tb(tb) traceback.print_tb(tb)

View file

@ -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. e.g. plugin://... calls. Hence be careful to only rely on window variables.
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
import xbmc import xbmc
@ -296,7 +297,7 @@ def prepare_listitem(item):
if "imdbnumber" not in properties and "imdbnumber" in item: if "imdbnumber" not in properties and "imdbnumber" in item:
properties["imdbnumber"] = item["imdbnumber"] properties["imdbnumber"] = item["imdbnumber"]
if "imdbnumber" not in properties and "uniqueid" in item: 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"): if value.startswith("tt"):
properties["imdbnumber"] = value properties["imdbnumber"] = value
@ -421,8 +422,8 @@ def prepare_listitem(item):
item["thumbnail"] = art["thumb"] item["thumbnail"] = art["thumb"]
# clean art # clean art
for key, value in art.iteritems(): for key, value in art.items():
if not isinstance(value, (str, unicode)): if not isinstance(value, str):
art[key] = "" art[key] = ""
elif value: elif value:
art[key] = get_clean_image(value) art[key] = get_clean_image(value)
@ -473,7 +474,7 @@ def create_listitem(item, as_tuple=True, offscreen=True,
nodetype = "Music" nodetype = "Music"
# extra properties # extra properties
for key, value in item["extraproperties"].iteritems(): for key, value in item["extraproperties"].items():
liz.setProperty(key, value) liz.setProperty(key, value)
# video infolabels # video infolabels

View file

@ -6,10 +6,12 @@
e.g. smb paths e.g. smb paths
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from future import standard_library
standard_library.install_aliases()
from logging import getLogger from logging import getLogger
import re import re
import socket import socket
import urllib import urllib.request, urllib.parse, urllib.error
import xbmc import xbmc
@ -156,7 +158,7 @@ def start():
xml.write_xml = False xml.write_xml = False
return return
user = user.strip() user = user.strip()
user = urllib.quote(user) user = urllib.parse.quote(user)
user = user.decode('utf-8') user = user.decode('utf-8')
# "Password" # "Password"
# May also be blank!! (=user aborts dialog) # May also be blank!! (=user aborts dialog)
@ -165,7 +167,7 @@ def start():
'', '',
type='{alphanum}', type='{alphanum}',
option='{hide}') option='{hide}')
password = urllib.quote(password) password = urllib.parse.quote(password)
password = password.decode('utf-8') password = password.decode('utf-8')
utils.etree.SubElement(entry, utils.etree.SubElement(entry,
'from', 'from',

View file

@ -1,6 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals 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 xbmc
import xbmcgui import xbmcgui
import time import time
@ -12,7 +16,7 @@ from .. import app
MONITOR = None MONITOR = None
class BaseFunctions: class BaseFunctions(object):
xmlFile = '' xmlFile = ''
path = '' path = ''
theme = '' theme = ''
@ -187,7 +191,7 @@ class BaseDialog(xbmcgui.WindowXMLDialog, BaseFunctions):
pass pass
class ControlledBase: class ControlledBase(object):
def doModal(self): def doModal(self):
self.show() self.show()
self.wait() self.wait()
@ -242,10 +246,10 @@ class ManagedListItem(object):
self._manager = None self._manager = None
self._valid = True self._valid = True
if properties: if properties:
for k, v in properties.items(): for k, v in list(properties.items()):
self.setProperty(k, v) self.setProperty(k, v)
def __nonzero__(self): def __bool__(self):
return self._valid return self._valid
@property @property
@ -281,7 +285,7 @@ class ManagedListItem(object):
self.listItem.setIconImage(self.iconImage) self.listItem.setIconImage(self.iconImage)
self.listItem.setThumbnailImage(self.thumbnailImage) self.listItem.setThumbnailImage(self.thumbnailImage)
self.listItem.setPath(self.path) 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 '') self.listItem.setProperty(k, self.properties.get(k) or '')
def clear(self): def clear(self):
@ -615,9 +619,9 @@ class ManagedControlList(object):
def getViewRange(self): def getViewRange(self):
viewPosition = self.getViewPosition() viewPosition = self.getViewPosition()
selected = self.getSelectedPosition() selected = self.getSelectedPosition()
return range(max(selected - viewPosition, 0), return list(range(max(selected - viewPosition, 0),
min(selected + (self._maxViewIndex - viewPosition) + 1, min(selected + (self._maxViewIndex - viewPosition) + 1,
self.size() - 1)) self.size() - 1)))
def positionIsValid(self, pos): def positionIsValid(self, pos):
return 0 <= pos < self.size() return 0 <= pos < self.size()
@ -751,7 +755,7 @@ class MultiWindow(object):
self._current.setProperty(key, value) self._current.setProperty(key, value)
def _onFirstInit(self): def _onFirstInit(self):
for k, v in self._properties.items(): for k, v in list(self._properties.items()):
self._current.setProperty(k, v) self._current.setProperty(k, v)
self.onFirstInit() self.onFirstInit()
@ -897,7 +901,7 @@ class SafeControlEdit(object):
self._setText(self.getText()[:-1]) 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): def __init__(self, window_id, timeout, property_, value='', init_value='1', addon_id=None, callback=None):
self._winID = window_id self._winID = window_id
self._timeout = timeout self._timeout = timeout
@ -976,7 +980,7 @@ class PropertyTimer():
self._start() self._start()
class WindowProperty(): class WindowProperty(object):
def __init__(self, win, prop, val='1', end=None): def __init__(self, win, prop, val='1', end=None):
self.win = win self.win = win
self.prop = prop self.prop = prop
@ -995,7 +999,7 @@ class WindowProperty():
self.win.setProperty(self.prop, self.end or self.old) self.win.setProperty(self.prop, self.end or self.old)
class GlobalProperty(): class GlobalProperty(object):
def __init__(self, prop, val='1', end=None): def __init__(self, prop, val='1', end=None):
import xbmcaddon import xbmcaddon
self._addonID = xbmcaddon.Addon().getAddonInfo('id') self._addonID = xbmcaddon.Addon().getAddonInfo('id')

View file

@ -6,6 +6,7 @@
(home) users (home) users
""" """
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from builtins import str
from logging import getLogger from logging import getLogger
import xbmc import xbmc
import xbmcgui import xbmcgui