Compare commits

..

No commits in common. "c5830aeadcf8738f01deeb8b64ce67bc3a9d6329" and "98d307db73d9f930f554d47ef9f754194dbc99cd" have entirely different histories.

7 changed files with 23 additions and 106 deletions

View File

@ -1,6 +1,5 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Default" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>

View File

@ -7,11 +7,9 @@ import requests
import inflect
from rich.logging import RichHandler
from rich.traceback import install
from rich import print
import typing as t
from rich.console import Console
from type_def.mvw_json_request import MVWJSONRequest
from type_def.mvw_json_response import MVWJSONResponse
# Without width
console = Console(width=180)
p = inflect.engine()
@ -75,8 +73,7 @@ log_connectionpool.setLevel(logging.WARNING)
install(show_locals=True)
class ConfigParser(
configparser.ConfigParser):
class ConfigParser(configparser.ConfigParser):
"""Can get options() without defaults
Taken from https://stackoverflow.com/a/12600066.
@ -98,13 +95,11 @@ config = ConfigParser(defaults=internal_defaults)
config.read(CONST.CFG_DEFAULT_FILENAME)
def print_section_header(
header: str) -> str:
def print_section_header(header: str) -> str:
return f"Loading config section '[{header}]' ..."
def validate_default_section(
config_obj: configparser.ConfigParser()) -> None:
def validate_default_section(config_obj: configparser.ConfigParser()) -> None:
log.debug(f"Loading config from file '{CONST.CFG_DEFAULT_ABS_PATH}' ...")
if not config_obj.sections():
log.error(f"No config sections found in '{CONST.CFG_DEFAULT_ABS_PATH}'. Exiting 1 ...")
@ -123,8 +118,7 @@ def validate_default_section(
log.debug(f"No defaults defined")
def config_has_valid_section(
config_obj: configparser.ConfigParser()) -> bool:
def config_has_valid_section(config_obj: configparser.ConfigParser()) -> bool:
has_valid_section = False
for config_obj_section in config_obj.sections():
if set(CONST.CFG_MANDATORY).issubset(config_obj.options(config_obj_section)):
@ -133,18 +127,15 @@ def config_has_valid_section(
return has_valid_section
def is_default(
config_key: str) -> bool:
def is_default(config_key: str) -> bool:
return any(config_key in ini_default for ini_default in ini_defaults)
def is_same_as_default(
config_kv_pair: dict) -> bool:
def is_same_as_default(config_kv_pair: dict) -> bool:
return config_kv_pair in ini_defaults
def validate_config_sections(
config_obj: configparser.ConfigParser()) -> None:
def validate_config_sections(config_obj: configparser.ConfigParser()) -> None:
for this_section in config_obj.sections():
log.debug(print_section_header(this_section))
if not set(CONST.CFG_MANDATORY).issubset(config_obj.options(this_section, no_defaults=True)):
@ -161,29 +152,22 @@ def validate_config_sections(
log.debug(f"{kv_prefix} {key} = {config_obj[this_section][key]}")
def query_string_from_file(
filename: str) -> str:
def query_string_from_file(filename: str) -> str:
with open(filename, "r") as jsonfile:
query_string = jsonfile.read()
return query_string
def get_query_payload(
section_name: str,
config_obj: configparser.ConfigParser()) -> MVWJSONRequest:
def get_query_payload(section_name: str, config_obj: configparser.ConfigParser()) -> JSONType:
log.debug(f"Generating HTTP POST JSON payload ...")
query = config_obj.get(section_name, "query")
if query[0] == "@":
query = query.split("@", 1)[1]
query = query_string_from_file(query)
got_query_payload = MVWJSONRequest(**json.loads(query))
return got_query_payload
return json.loads(query)
def get_json_response(
section_name: str,
config_obj: configparser.ConfigParser(),
payload: MVWJSONRequest) -> MVWJSONResponse:
def get_json_response(section_name: str, config_obj: configparser.ConfigParser(), payload: JSONType) -> JSONType:
log.debug(f"Downloading JSON list of Mediathek files that match search criteria")
serialized_payload = json.dumps(payload)
url = config_obj.get(section_name, "mvw_endpoint")
@ -197,24 +181,19 @@ def get_json_response(
f"""{newline.join(f"Header '{header}': '{value}'" for header, value in list(req.headers.items()))}\n"""
f"Payload: {payload}")
with s.send(prepped) as s:
# return json.loads(s.content)
got_json_response = MVWJSONResponse(**json.loads(s.content))
return got_json_response
return json.loads(s.content)
def filter_json_by_duration(
section_name: str,
config_obj: configparser.ConfigParser(),
json_obj: MVWJSONResponse) -> MVWJSONResponse:
def filter_json_by_duration(section_name: str, config_obj: configparser.ConfigParser(), json_obj: JSONType) -> JSONType:
min_length = config_obj.getint(section_name, "min_duration")
if min_length >= 0:
log.debug(f"""Filtering JSON for minimum length of {min_length} {p.plural("second", min_length)}""")
console.log(json_obj)
#for result in json_obj["result"]["results"]:
# console.log(result)
# console.log(f"0000000000000000000000")
# if not result["duration"] >= min_length:
# pass
# console.print(json_obj["result"]["results"][0])
for result in json_obj["result"]["results"]:
console.log(result)
console.log(f"0000000000000000000000")
if not result["duration"] >= min_length:
pass
# json_str.
# console.log(f"{result}\n......................")
# console.log(json_obj)
@ -238,8 +217,6 @@ if __name__ == '__main__':
log.debug(f"Processing section '[{section}]' ...")
query_payload = get_query_payload(section, config)
json_response = get_json_response(section, config, query_payload)
log.debug(json_response)
quit()
log.debug(CONST.CFG_KNOWN_SECTION[0])
if config.has_option(section, "min_duration") or config.has_option(section, "max_duration"):
json_matches_duration = filter_json_by_duration(section, config, json_response)

View File

@ -1,4 +1,3 @@
rich
requests
inflect
pydantic

View File

@ -14,15 +14,11 @@ idna==3.3
# via requests
inflect==5.4.0
# via -r requirements.in
pydantic==1.9.0
# via -r requirements.in
pygments==2.11.2
# via rich
requests==2.27.1
# via -r requirements.in
rich==12.0.0
# via -r requirements.in
typing-extensions==4.1.1
# via pydantic
urllib3==1.26.8
# via requests

View File

View File

@ -1,17 +0,0 @@
from __future__ import annotations
from typing import List
from pydantic import BaseModel
class Query(BaseModel):
fields: List[str]
query: str
class MVWJSONRequest(BaseModel):
queries: List[Query]
sortBy: str
sortOrder: str
future: bool
offset: int
size: int

View File

@ -1,37 +0,0 @@
from __future__ import annotations
from typing import List, Optional
from pydantic import BaseModel
class Show(BaseModel):
channel: str
topic: str
title: str
description: str
timestamp: int
duration: int
size: int
url_website: str
url_subtitle: str
url_video: str
url_video_low: str
url_video_hd: str
filmlisteTimestamp: str
id: str
class QueryInfo(BaseModel):
filmlisteTimestamp: str
searchEngineTime: str
resultCount: int
totalResults: int
class Result(BaseModel):
results: List[Show] = []
queryInfo: QueryInfo
class MVWJSONResponse(BaseModel):
result: Result
err: Optional[str] = None