def clean_dict(target_dict, whitelist=None): """Convenience function that removes a dicts keys that have falsy values.""" assert isinstance(target_dict, dict) return { ustr(k).strip(): ustr(v).strip() for k, v in target_dict.items() if v not in (None, Ellipsis, [], (), "") and (not whitelist or k in whitelist) }
def _search_title(self, title, year): assert title found = False year_from, year_to = year_expand(year) page = 1 page_max = 5 # each page yields a maximum of 20 results while True: response = tmdb_search_movies(self.api_key, title, year, page=page, cache=self.cache) for entry in response["results"]: try: meta = MetadataMovie( title=entry["title"], date=entry["release_date"], synopsis=entry["overview"], id_tmdb=ustr(entry["id"]), ) except ValueError: continue if year_from <= int(meta["year"]) <= year_to: yield meta found = True if page == response["total_pages"]: break elif page >= page_max: break page += 1 if not found: raise MapiNotFoundException
def year_parse(s): """Parses a year from a string.""" regex = r"((?:19|20)\d{2})(?:$|[-/]\d{2}[-/]\d{2})" try: year = int(re.findall(regex, ustr(s))[0]) except IndexError: year = None return year
def year_expand(s): """Parses a year or dash-delimited year range.""" regex = r"^((?:19|20)\d{2})?(\s*-\s*)?((?:19|20)\d{2})?$" try: start, dash, end = re.match(regex, ustr(s)).groups() start = start or 1900 end = end or 2099 except AttributeError: return 1900, 2099 return (int(start), int(end)) if dash else (int(start), int(start))
def _search_id_tmdb(self, id_tmdb): assert id_tmdb response = tmdb_movies(self.api_key, id_tmdb, cache=self.cache) yield MetadataMovie( title=response["title"], date=response["release_date"], synopsis=response["overview"], media="movie", id_tmdb=ustr(id_tmdb), )
def __getitem__(self, key): # Case insensitive keys key = key.lower() value = self._dict.get(key) # Special case for year if key == "year" and not self._dict.get("year"): date = self._dict.get("date") value = year_parse(date) # Numeric keys elif key in self.fields_numeric and value != 0: value = int(value) if value else None # String keys else: value = ustr(value or "") return value
def _search_id_tvdb(self, id_tvdb, season=None, episode=None): assert id_tvdb found = False series_data = tvdb_series_id(self.token, id_tvdb, cache=self.cache) page = 1 while True: episode_data = tvdb_series_id_episodes_query( self.token, id_tvdb, episode, season, page=page, cache=self.cache, ) for entry in episode_data["data"]: try: yield MetadataTelevision( series=series_data["data"]["seriesName"], season=ustr(entry["airedSeason"]), episode=ustr(entry["airedEpisodeNumber"]), date=entry["firstAired"], title=entry["episodeName"].split(";", 1)[0], synopsis=(entry["overview"] or "").replace("\r\n", "").replace(" ", "").strip(), media="television", id_tvdb=ustr(id_tvdb), ) found = True except (AttributeError, ValueError): continue if page == episode_data["links"]["last"]: break page += 1 if not found: raise MapiNotFoundException
def request_json(url, parameters=None, body=None, headers=None, cache=True, agent=None): """ Queries a url for json data. Note: Requests are cached using requests_cached for a week, this is done transparently by using the package's monkey patching. """ assert url session = get_session() log.info("-" * 80) log.info("url: %s", url) if isinstance(headers, dict): headers = clean_dict(headers) else: headers = dict() if isinstance(parameters, dict): parameters = d2l(clean_dict(parameters)) if body: method = "POST" headers["content-type"] = "application/json" headers["user-agent"] = get_user_agent(agent) headers["content-length"] = ustr(len(body)) else: method = "GET" headers["user-agent"] = get_user_agent(agent) initial_cache_state = session._is_cache_disabled # yes, i'm a bad person try: session._is_cache_disabled = not cache response = session.request( url=url, params=parameters, json=body, headers=headers, method=method, timeout=1, ) status = response.status_code content = response.json() if status // 100 == 2 else None cache = getattr(response, "from_cache", False) except Exception as e: content = None status = 500 log.debug(e, exc_info=True) else: log.debug("method: %s", method) log.debug("headers: %r", headers) log.debug("parameters: %r", parameters) log.debug("cache: %r", cache) log.info("status: %d", status) log.debug("content: %s", content) finally: session._is_cache_disabled = initial_cache_state return status, content