add enable_fast_connect configuration parameter (#288)

This commit is contained in:
Andrey Yantsen 2018-09-14 19:28:35 +01:00 committed by Hellowlol
parent 057967a8ae
commit 93ec86d746
4 changed files with 35 additions and 8 deletions

View file

@ -55,6 +55,15 @@ Section [plexapi] Options
Timeout in seconds to use when making requests to the Plex Media Server or Plex Client
resources (default: 30).
**enable_fast_connect**
By default Plex will be trying to connect with all available connection methods simultaneously,
combining local and remote addresses, http and https, and be waiting for all connection to
establish (or fail due to timeout / any other error), this can take long time when you're trying
to connect to your Plex Server outside of your home network.
When the options is set to `true` the connection procedure will be aborted with first successfully
established connection.
Section [auth] Options
----------------------

View file

@ -17,6 +17,7 @@ PROJECT = 'PlexAPI'
VERSION = '3.0.6'
TIMEOUT = CONFIG.get('plexapi.timeout', 30, int)
X_PLEX_CONTAINER_SIZE = CONFIG.get('plexapi.container_size', 100, int)
X_PLEX_ENABLE_FAST_CONNECT = CONFIG.get('plexapi.enable_fast_connect', False, bool)
# Plex Header Configuation
X_PLEX_PROVIDES = CONFIG.get('header.provides', 'controller')

View file

@ -3,7 +3,7 @@ import copy
import requests
import time
from requests.status_codes import _codes as codes
from plexapi import BASE_HEADERS, CONFIG, TIMEOUT, X_PLEX_IDENTIFIER
from plexapi import BASE_HEADERS, CONFIG, TIMEOUT, X_PLEX_IDENTIFIER, X_PLEX_ENABLE_FAST_CONNECT
from plexapi import log, logfilter, utils
from plexapi.base import PlexObject
from plexapi.exceptions import BadRequest, NotFound
@ -809,15 +809,28 @@ class MyPlexDevice(PlexObject):
return self._server.syncItems(client=self)
def _connect(cls, url, token, timeout, results, i):
def _connect(cls, url, token, timeout, results, i, job_is_done_event=None):
""" Connects to the specified cls with url and token. Stores the connection
information to results[i] in a threadsafe way.
Arguments:
cls: the class which is responsible for establishing connection, basically it's
:class:`~plexapi.client.PlexClient` or :class:`~plexapi.server.PlexServer`
url (str): url which should be passed as `baseurl` argument to cls.__init__()
token (str): authentication token which should be passed as `baseurl` argument to cls.__init__()
timeout (int): timeout which should be passed as `baseurl` argument to cls.__init__()
results (list): pre-filled list for results
i (int): index of current job, should be less than len(results)
job_is_done_event (:class:`~threading.Event`): is X_PLEX_ENABLE_FAST_CONNECT is True then the
event would be set as soon the connection is established
"""
starttime = time.time()
try:
device = cls(baseurl=url, token=token, timeout=timeout)
runtime = int(time.time() - starttime)
results[i] = (url, token, device, runtime)
if X_PLEX_ENABLE_FAST_CONNECT and job_is_done_event:
job_is_done_event.set()
except Exception as err:
runtime = int(time.time() - starttime)
log.error('%s: %s', url, err)

View file

@ -7,7 +7,7 @@ import time
import zipfile
from datetime import datetime
from getpass import getpass
from threading import Thread
from threading import Thread, Event
from tqdm import tqdm
from plexapi import compat
from plexapi.exceptions import NotFound
@ -145,22 +145,26 @@ def searchType(libtype):
def threaded(callback, listargs):
""" Returns the result of <callback> for each set of \*args in listargs. Each call
to <callback. is called concurrently in their own separate threads.
to <callback> is called concurrently in their own separate threads.
Parameters:
callback (func): Callback function to apply to each set of \*args.
listargs (list): List of lists; \*args to pass each thread.
"""
threads, results = [], []
job_is_done_event = Event()
for args in listargs:
args += [results, len(results)]
results.append(None)
threads.append(Thread(target=callback, args=args))
threads.append(Thread(target=callback, args=args, kwargs=dict(job_is_done_event=job_is_done_event)))
threads[-1].setDaemon(True)
threads[-1].start()
for thread in threads:
thread.join()
return results
while not job_is_done_event.is_set():
if all([not t.is_alive() for t in threads]):
break
time.sleep(0.05)
return [r for r in results if r is not None]
def toDatetime(value, format=None):