示例#1
0
文件: nfl.py 项目: toddrob99/nflapi
class NFLClientCredentials(requests.auth.AuthBase):
    """
    A requests Auth object that maintains a token for the nfl.com api

    The token is cached using a file cache that may or may not work
    across multiple processes. The worst that can happen is that it
    is refreshed unnecessarily.
    """
    def __init__(self, cache_name: str = 'nflapi'):
        self.cache = FileCache(cache_name, flag='cs')
        self.cache.clear()

    def __call__(self, r: requests.Request):
        r.headers['Authorization'] = self.__get_token(
            ua=r.headers.get('User-Agent', None))
        return r

    def __get_token(self, ua):
        if self.cache.get('expire', EPOCH) < pendulum.now():
            self.__update_token(ua)
        token = self.cache.get('token')
        logger.debug("Using token: %s" % token)
        return token

    def __update_token(self, ua):
        logger.debug('Updating auth token')
        data = {'grant_type': 'client_credentials'}
        response = self.__token_request(ENDPOINT_V1_REROUTE, data, ua)
        token = '{token_type} {access_token}'.format(**response)
        expire = pendulum.now().add(seconds=response['expires_in'] - 30)
        self.cache['token'] = token
        self.cache['expire'] = expire
        logger.debug('Updated token: %s - expires %s', token, expire)

    @staticmethod
    def __token_request(path, data, ua):
        headers = {'X-Domain-Id': '100', 'User-Agent': ua}
        logger.debug('Request: POST %s, data=<%s>', path, pformat(data))

        url = API_HOST + path
        logger.debug('Request headers: %s', pformat(headers))
        response = requests.request('POST', url, data=data, headers=headers)
        try:
            js = response.json()
            response.raise_for_status()
            logger.debug('Response: %s', pformat(js))
            return js
        except HTTPError as e:
            raise Exception("Unsuccessful response: %r" % response.data) from e
        except ValueError as e:
            raise Exception("Response from API was not json: %s" %
                            response.data) from e
示例#2
0
class SZFileBackend(CacheBackend):
    def __init__(self, arguments):
        self._cache = FileCache(arguments.pop("appname", None),
                                flag=arguments.pop("flag", "c"),
                                serialize=arguments.pop("serialize", True),
                                app_cache_dir=arguments.pop(
                                    "app_cache_dir", None))

    def get(self, key):
        value = self._cache.get(key, NO_VALUE)

        return value

    def get_multi(self, keys):
        ret = [self._cache.get(key, NO_VALUE) for key in keys]

        return ret

    def set(self, key, value):
        self._cache[key] = value

    def set_multi(self, mapping):
        for key, value in mapping.items():
            self._cache[key] = value

    def delete(self, key):
        self._cache.pop(key, None)

    def delete_multi(self, keys):
        for key in keys:
            self._cache.pop(key, None)

    @property
    def all_filenames(self):
        return self._cache._all_filenames()

    def sync(self, force=False):
        if (hasattr(self._cache, "_buffer") and self._cache._buffer) or force:
            self._cache.sync()

    def clear(self):
        self._cache.clear()
        if not hasattr(self._cache, "_buffer") or self._cache._sync:
            self._cache._sync = False
            self._cache._buffer = {}
示例#3
0
class SZFileBackend(CacheBackend):
    def __init__(self, arguments):
        self._cache = FileCache(arguments.pop("appname", None), flag=arguments.pop("flag", "c"),
                                serialize=arguments.pop("serialize", True),
                                app_cache_dir=arguments.pop("app_cache_dir", None))

    def get(self, key):
        value = self._cache.get(key, NO_VALUE)

        return value

    def get_multi(self, keys):
        ret = [
            self._cache.get(key, NO_VALUE)
            for key in keys]

        return ret

    def set(self, key, value):
        self._cache[key] = value

    def set_multi(self, mapping):
        for key, value in mapping.items():
            self._cache[key] = value

    def delete(self, key):
        self._cache.pop(key, None)

    def delete_multi(self, keys):
        for key in keys:
            self._cache.pop(key, None)

    @property
    def all_filenames(self):
        return self._cache._all_filenames()

    def sync(self, force=False):
        if (hasattr(self._cache, "_buffer") and self._cache._buffer) or force:
            self._cache.sync()

    def clear(self):
        self._cache.clear()
        if not hasattr(self._cache, "_buffer") or self._cache._sync:
            self._cache._sync = False
            self._cache._buffer = {}
示例#4
0
class ConfigFinder:
    def __init__(self, config_file: str = "SpotiBot.json") -> None:
        """Instantiates instances of environment configuration from .ini file.

        Args:
            config_file: Name of .ini configuration file following the
                format of SpotiBot_SAMPLE.ini
        """
        self.cache = FileCache(config_file.split(r".")[0], flag="cs")
        self.config_file = config_file
        self.path_to_config = self.cache.get(r"path_to_config")

    def clear_cache(self) -> object:
        """Clears cached path to configuration file."""
        self.cache.clear()
        return self

    @property
    def cache_exists(self) -> bool:
        """Checks to see if a cached file path exists to a valid file."""
        try:
            return os.path.isfile(self.path_to_config)
        except:
            return False

    @property
    def cache_is_valid(self) -> bool:
        """Checks to see if the valid file path contains the config file."""
        try:
            return self.config_file == os.path.basename(self.path_to_config)
        except:
            return False

    def locate_config(self):
        """Traverse file system from bottom up to locate config file."""
        for dirpath, dirnames, files in os.walk(os.path.expanduser("~"),
                                                topdown=False):

            if self.config_file in files:
                self.path_to_config = os.path.join(dirpath, self.config_file)
                break

            else:
                self.path_to_config = None

        return self.path_to_config

    def get_path(self) -> str:
        """Checks for cache existence and validates - traverses OS if not."""
        print("Locating configuration...")

        print("\t<1 of 2> Checking for cached path...")

        if self.cache_exists and self.cache_is_valid:
            print(f"\t<2 of 2> Found cached path: {self.path_to_config}")

        else:
            print("\t<2 of 2> Cached path not found")
            print(f"\nLooking for {self.config_file} in local file system..")

            self.path_to_config = self.locate_config()

            if self.path_to_config:
                print(f"\t<1 of 1> '{self.config_file}' found at: "
                      f"{self.path_to_config}")
            else:
                print(f"\t<1 of 1> Could not find config file"
                      f" {self.config_file} please double check the name of "
                      f"your configuration file or value passed in the"
                      f"'config_file' argument")

        return self.path_to_config

    def read_file(self) -> object:
        """Locates creds file and caches location.

        Returns:
            Dictionary containing SpotiBot configuration params

        """
        self.path_to_config = self.get_path()
        self.cache["path_to_config"] = self.path_to_config

        try:
            with open(self.path_to_config, "r") as r:
                self.cfg = json.load(r)

        except IOError as e:
            print(e)

        return self
示例#5
0
class Cache(object):
    _cache = {}
    _cachedir = None
    _cache_lock = None

    @property
    def cache_lock(self):
        return self._cache_lock

    def __init__(self, environment):
        """
        Initializes the cache so that kraft does not have to constantly
        retrieve informational lists about unikraft, its available
        architectures, platforms, libraries and supported applications.
        """

        self._cachedir = environment.get('UK_CACHEDIR')

        # Initiaize a cache instance
        self._cache = FileCache(app_cache_dir=self._cachedir,
                                appname=__program__,
                                flag='cs')

        self._cache_lock = threading.Lock()

    @property
    def cache(self):
        ret = None
        with self._cache_lock:
            ret = self._cache
        return ret

    def get(self, origin=None):
        ret = None
        if isinstance(origin, six.string_types) and origin in self._cache:
            logger.debug("Retrieving %s from cache..." % origin)
            with self._cache_lock:
                ret = self._cache[origin]

        return ret

    def find_item_by_name(self, type=None, name=None):
        for origin in self._cache:
            for item in self._cache[origin].items():
                if ((type is not None and item[1].type.shortname == type)
                        or type is None) and item[1].name == name:
                    return item[1]

        return None

    def all(self):
        return self.cache

    def save(self, origin, manifest):
        if not isinstance(origin, six.string_types):
            raise TypeError("origin is not string")
        if not isinstance(manifest, Manifest):
            raise TypeError("Invalid manifest")

        with self._cache_lock:
            logger.debug("Saving %s into cache..." % manifest)
            self._cache[origin] = manifest

    def sync(self):
        logger.debug("Synchronizing cache with filesystem...")

        with self._cache_lock:
            self._cache.sync()

    def purge(self):
        logger.debug("Purging cache...")

        with self._cache_lock:
            self._cache.clear()

    def is_stale(self):
        """
        Determine if the list of remote repositories is stale.  Return a boolean
        value if at least one repository is marked as stale.
        """

        logger.debug("Checking cache for staleness...")
        return True if len(self.all()) == 0 else False