mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-09-16 14:12:20 +02:00
hrti: dynamic endpoint config
This commit is contained in:
@@ -15,11 +15,11 @@ from .models import HRTiAuthToken, HRTiCredentials
|
||||
|
||||
class HRTiAuthenticator(BaseAuthenticator):
|
||||
def __init__(
|
||||
self,
|
||||
credentials=None,
|
||||
config_dir=None,
|
||||
proxy_config: Optional[ProxyConfig] = None,
|
||||
http_manager=None,
|
||||
self,
|
||||
credentials=None,
|
||||
config_dir=None,
|
||||
proxy_config: Optional[ProxyConfig] = None,
|
||||
http_manager=None,
|
||||
):
|
||||
|
||||
# Initialize configuration FIRST
|
||||
@@ -80,7 +80,7 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
@property
|
||||
def auth_endpoint(self) -> str:
|
||||
"""HRTi authentication endpoint"""
|
||||
return self.config.api_endpoints["grant_access"]
|
||||
return self.config.api_endpoints.get("grant_access", "")
|
||||
|
||||
def _get_auth_headers(self) -> Dict[str, str]:
|
||||
"""Get headers specifically for authentication endpoint"""
|
||||
@@ -96,7 +96,6 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
"Content-Type": "application/json",
|
||||
"deviceid": device_id,
|
||||
"devicetypeid": self.config.device_reference_id,
|
||||
# REMOVED: 'host': 'hrti.hrt.hr', # Let HTTP library set this automatically
|
||||
"ipaddress": self._ip_address,
|
||||
"operatorreferenceid": self.config.operator_reference_id,
|
||||
"origin": self.config.base_website,
|
||||
@@ -122,7 +121,6 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
"Content-Type": "application/json",
|
||||
"deviceid": device_id,
|
||||
"devicetypeid": self.config.device_reference_id,
|
||||
# REMOVED: 'host': 'hrti.hrt.hr', # Let HTTP library set this automatically
|
||||
"ipaddress": self._ip_address,
|
||||
"operatorreferenceid": self.config.operator_reference_id,
|
||||
"origin": self.config.base_website,
|
||||
@@ -255,7 +253,13 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
# Priority 2: Fall back to API fetch if no configured IP
|
||||
try:
|
||||
logger.debug("No configured IP found, fetching from API...")
|
||||
response = self.http_manager.get(self.config.api_endpoints["get_ip"], operation="api")
|
||||
get_ip_endpoint = self.config.api_endpoints.get("get_ip", "")
|
||||
if not get_ip_endpoint:
|
||||
logger.warning("No get_ip endpoint configured, using fallback")
|
||||
self._ip_address = "0.0.0.0"
|
||||
return self._ip_address
|
||||
|
||||
response = self.http_manager.get(get_ip_endpoint, operation="api")
|
||||
response.raise_for_status()
|
||||
self._ip_address = response.text.strip().strip('"') # Remove quotes if present
|
||||
logger.info(f"Retrieved IP address from API: {self._ip_address}")
|
||||
@@ -311,6 +315,8 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Error loading HRTi environment config: {e}")
|
||||
# Ensure API endpoints are built even if config fetch fails
|
||||
self.config._build_fallback_endpoints()
|
||||
|
||||
def _perform_grant_access(self) -> Dict[str, Any]:
|
||||
"""Perform grant access authentication with proper headers and debugging"""
|
||||
@@ -340,8 +346,12 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
safe_payload["Password"] = "***" if safe_payload["Password"] else "<empty>"
|
||||
logger.debug(f"HRTi Auth Payload: {safe_payload}")
|
||||
|
||||
auth_endpoint = self.auth_endpoint
|
||||
if not auth_endpoint:
|
||||
raise Exception("No grant_access endpoint configured")
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.auth_endpoint,
|
||||
auth_endpoint,
|
||||
operation="auth",
|
||||
headers=headers,
|
||||
data=json.dumps(payload),
|
||||
@@ -362,8 +372,8 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
logger.error(f"HRTi grant access failed: {e}")
|
||||
# Only fallback to anonymous if we're not already using it
|
||||
if (
|
||||
not isinstance(self.credentials, HRTiCredentials)
|
||||
or self.credentials.username != "anonymoushrt"
|
||||
not isinstance(self.credentials, HRTiCredentials)
|
||||
or self.credentials.username != "anonymoushrt"
|
||||
):
|
||||
logger.info("Falling back to anonymous credentials")
|
||||
self.credentials = self.get_fallback_credentials()
|
||||
@@ -402,8 +412,13 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
|
||||
logger.debug(f"HRTi Device Registration Payload: {payload}")
|
||||
|
||||
register_endpoint = self.config.api_endpoints.get("register_device", "")
|
||||
if not register_endpoint:
|
||||
logger.warning("No register_device endpoint configured")
|
||||
return
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.config.api_endpoints["register_device"],
|
||||
register_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps(payload),
|
||||
@@ -428,22 +443,26 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
headers["referer"] = f"{self.config.base_website}/"
|
||||
|
||||
# Get content ratings
|
||||
content_response = self.http_manager.post(
|
||||
self.config.api_endpoints["content_ratings"],
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps({}),
|
||||
)
|
||||
content_response.raise_for_status()
|
||||
content_endpoint = self.config.api_endpoints.get("content_ratings", "")
|
||||
if content_endpoint:
|
||||
content_response = self.http_manager.post(
|
||||
content_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps({}),
|
||||
)
|
||||
content_response.raise_for_status()
|
||||
|
||||
# Get profiles
|
||||
profiles_response = self.http_manager.post(
|
||||
self.config.api_endpoints["profiles"],
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps({}),
|
||||
)
|
||||
profiles_response.raise_for_status()
|
||||
profiles_endpoint = self.config.api_endpoints.get("profiles", "")
|
||||
if profiles_endpoint:
|
||||
profiles_response = self.http_manager.post(
|
||||
profiles_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps({}),
|
||||
)
|
||||
profiles_response.raise_for_status()
|
||||
|
||||
logger.debug("HRTi initial data loaded")
|
||||
|
||||
@@ -503,14 +522,14 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
self._user_id = self._user_id or ""
|
||||
|
||||
def authorize_session(
|
||||
self,
|
||||
content_type: str,
|
||||
content_ref_id: str,
|
||||
content_drm_id: str = None,
|
||||
video_store_ids: list = None,
|
||||
channel_id: str = None,
|
||||
start_time: str = None,
|
||||
end_time: str = None,
|
||||
self,
|
||||
content_type: str,
|
||||
content_ref_id: str,
|
||||
content_drm_id: str = None,
|
||||
video_store_ids: list = None,
|
||||
channel_id: str = None,
|
||||
start_time: str = None,
|
||||
end_time: str = None,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""Authorize a playback session"""
|
||||
try:
|
||||
@@ -542,8 +561,13 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
f"Authorizing session - type: {content_type}, ref: {content_ref_id}, drm: {content_drm_id}"
|
||||
)
|
||||
|
||||
auth_endpoint = self.config.api_endpoints.get("authorize_session", "")
|
||||
if not auth_endpoint:
|
||||
logger.error("No authorize_session endpoint configured")
|
||||
return None
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.config.api_endpoints["authorize_session"],
|
||||
auth_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps(payload),
|
||||
@@ -584,8 +608,13 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
|
||||
payload = {"SessionEventId": 1, "SessionId": session_id} # 1 = play start
|
||||
|
||||
report_endpoint = self.config.api_endpoints.get("report_session", "")
|
||||
if not report_endpoint:
|
||||
logger.warning("No report_session endpoint configured")
|
||||
return False
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.config.api_endpoints["report_session"],
|
||||
report_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps(payload),
|
||||
@@ -602,14 +631,17 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
def get_license_data(self, session_id: str) -> str:
|
||||
"""Generate license data for DRM - returns base64 encoded string"""
|
||||
try:
|
||||
# Use merchant from config (now dynamically loaded)
|
||||
merchant = self.config.merchant or "aviion2"
|
||||
|
||||
drm_license = {
|
||||
"userId": self._user_id or "",
|
||||
"sessionId": session_id,
|
||||
"merchant": self.config.merchant,
|
||||
"merchant": merchant,
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
f"Creating license data - userId: {self._user_id}, sessionId: {session_id}, merchant: {self.config.merchant}"
|
||||
f"Creating license data - userId: {self._user_id}, sessionId: {session_id}, merchant: {merchant}"
|
||||
)
|
||||
|
||||
# Encode to JSON then to base64
|
||||
@@ -652,14 +684,14 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
stored_creds = self.settings_manager.get_provider_credentials(self.provider_name)
|
||||
|
||||
has_user_creds = (
|
||||
isinstance(stored_creds, UserPasswordCredentials) and stored_creds.validate()
|
||||
isinstance(stored_creds, UserPasswordCredentials) and stored_creds.validate()
|
||||
)
|
||||
|
||||
# Check current credentials
|
||||
if not has_user_creds:
|
||||
has_user_creds = (
|
||||
isinstance(self.credentials, UserPasswordCredentials)
|
||||
and self.credentials.validate()
|
||||
isinstance(self.credentials, UserPasswordCredentials)
|
||||
and self.credentials.validate()
|
||||
)
|
||||
|
||||
# If we have user credentials and token has a real user_id, it's user authenticated
|
||||
@@ -672,9 +704,9 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
|
||||
# If we have user credentials, consider it user authenticated
|
||||
if (
|
||||
hasattr(self.credentials, "username")
|
||||
and self.credentials.username
|
||||
and self.credentials.username != "anonymoushrt"
|
||||
hasattr(self.credentials, "username")
|
||||
and self.credentials.username
|
||||
and self.credentials.username != "anonymoushrt"
|
||||
):
|
||||
return TokenAuthLevel.USER_AUTHENTICATED
|
||||
|
||||
@@ -704,13 +736,13 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
stored_creds = self.settings_manager.get_provider_credentials(self.provider_name)
|
||||
|
||||
has_stored_user_creds = (
|
||||
isinstance(stored_creds, UserPasswordCredentials) and stored_creds.validate()
|
||||
isinstance(stored_creds, UserPasswordCredentials) and stored_creds.validate()
|
||||
)
|
||||
|
||||
# Check current credentials
|
||||
has_current_user_creds = (
|
||||
isinstance(self.credentials, UserPasswordCredentials)
|
||||
and self.credentials.validate()
|
||||
isinstance(self.credentials, UserPasswordCredentials)
|
||||
and self.credentials.validate()
|
||||
)
|
||||
|
||||
# Upgrade if we have any user credentials
|
||||
@@ -795,4 +827,4 @@ class HRTiAuthenticator(BaseAuthenticator):
|
||||
return self._perform_authentication()
|
||||
except Exception as e:
|
||||
logger.error(f"HRTi token refresh failed: {e}")
|
||||
return None
|
||||
return None
|
||||
@@ -14,36 +14,34 @@ class HRTiDefaults:
|
||||
# Website and base URLs
|
||||
BASE_WEBSITE = "https://hrti.hrt.hr"
|
||||
BASE_URL = "https://hrti.hrt.hr"
|
||||
HSAPI_BASE_URL = "https://hsapi.aviion.tv/client.svc/json"
|
||||
|
||||
# Configuration endpoints
|
||||
ENV_ENDPOINT = f"{BASE_URL}/assets/config/env.json"
|
||||
CONFIG_ENDPOINT = f"{BASE_URL}/assets/config/config.production.json"
|
||||
|
||||
# API endpoints
|
||||
API_ENDPOINTS = {
|
||||
"get_ip": f"{BASE_URL}/api/api/ott/getIPAddress",
|
||||
"grant_access": f"{BASE_URL}/api/api/ott/GrantAccess",
|
||||
"channels": f"{BASE_URL}/api/api/ott/GetChannels",
|
||||
"programme": f"{BASE_URL}/api/api/ott/GetProgramme",
|
||||
"authorize_session": f"{BASE_URL}/api/api/ott/AuthorizeSession",
|
||||
"report_session": f"{BASE_URL}/api/api/ott/ReportSessionEvent",
|
||||
"register_device": f"{HSAPI_BASE_URL}/RegisterDevice",
|
||||
"content_ratings": f"{HSAPI_BASE_URL}/ContentRatingsGet",
|
||||
"profiles": f"{HSAPI_BASE_URL}/ProfilesGet",
|
||||
# VOD endpoints
|
||||
"catalogue_structure": f"{BASE_URL}/api/api/ott/GetCatalogueStructure",
|
||||
"catalogue": f"{BASE_URL}/api/api/ott/GetCatalogue",
|
||||
"vod_details": f"{BASE_URL}/api/api/ott/GetVodDetails",
|
||||
"episodes": f"{BASE_URL}/api/api/ott/GetSeries",
|
||||
"watch_later": f"{BASE_URL}/api/api/ott/GetWatchLater",
|
||||
"editors_choice": f"{BASE_URL}/api/api/ott/GetEditorsChoice",
|
||||
# API endpoint path templates (will be combined with dynamic base URLs)
|
||||
# These are the path parts only - base URLs come from API config
|
||||
API_ENDPOINT_PATHS = {
|
||||
"get_ip": "/getIPAddress",
|
||||
"grant_access": "/GrantAccess",
|
||||
"channels": "/GetChannels",
|
||||
"programme": "/GetProgramme",
|
||||
"authorize_session": "/AuthorizeSession",
|
||||
"report_session": "/ReportSessionEvent",
|
||||
"register_device": "/RegisterDevice",
|
||||
"content_ratings": "/ContentRatingsGet",
|
||||
"profiles": "/ProfilesGet",
|
||||
"catalogue_structure": "/GetCatalogueStructure",
|
||||
"catalogue": "/GetCatalogue",
|
||||
"vod_details": "/GetVodDetails",
|
||||
"episodes": "/GetSeries",
|
||||
"watch_later": "/GetWatchLater",
|
||||
"editors_choice": "/GetEditorsChoice",
|
||||
}
|
||||
|
||||
# Device information
|
||||
# Device information (static defaults, may be overridden by config)
|
||||
DEVICE_REFERENCE_ID = "6" # String '6' as required by headers
|
||||
OPERATOR_REFERENCE_ID = "hrt"
|
||||
MERCHANT = "aviion2"
|
||||
CONNECTION_TYPE = "LAN/WiFi"
|
||||
APPLICATION_VERSION = "5.97.6"
|
||||
OS_VERSION = "Linux"
|
||||
@@ -72,12 +70,20 @@ class HRTiConfig:
|
||||
# Website and base URLs
|
||||
self.base_website = config.get("base_website", HRTiDefaults.BASE_WEBSITE)
|
||||
self.base_url = config.get("base_url", HRTiDefaults.BASE_URL)
|
||||
self.hsapi_base_url = config.get("hsapi_base_url", HRTiDefaults.HSAPI_BASE_URL)
|
||||
|
||||
# Dynamic URLs - will be populated from API
|
||||
self.hsapi_base_url = config.get("hsapi_base_url", None)
|
||||
self.web_api_url = config.get("web_api_url", None)
|
||||
|
||||
# Configuration endpoints
|
||||
self.env_endpoint = config.get("env_endpoint", HRTiDefaults.ENV_ENDPOINT)
|
||||
self.config_endpoint = config.get("config_endpoint", HRTiDefaults.CONFIG_ENDPOINT)
|
||||
|
||||
# API endpoints configuration
|
||||
self.api_endpoints = config.get("api_endpoints", HRTiDefaults.API_ENDPOINTS.copy())
|
||||
# API endpoints - start with paths only, build full URLs after API call
|
||||
self.api_endpoint_paths = config.get(
|
||||
"api_endpoint_paths", HRTiDefaults.API_ENDPOINT_PATHS.copy()
|
||||
)
|
||||
self.api_endpoints = {} # Will be populated in update_from_api
|
||||
|
||||
# Device configuration
|
||||
self.device_reference_id = config.get(
|
||||
@@ -86,7 +92,8 @@ class HRTiConfig:
|
||||
self.operator_reference_id = config.get(
|
||||
"operator_reference_id", HRTiDefaults.OPERATOR_REFERENCE_ID
|
||||
)
|
||||
self.merchant = config.get("merchant", HRTiDefaults.MERCHANT)
|
||||
self.merchant = config.get("merchant", None) # Will be set from API
|
||||
self.player_license_key = config.get("player_license_key", None) # Will be set from API
|
||||
self.connection_type = config.get("connection_type", HRTiDefaults.CONNECTION_TYPE)
|
||||
self.application_version = config.get(
|
||||
"application_version", HRTiDefaults.APPLICATION_VERSION
|
||||
@@ -98,12 +105,35 @@ class HRTiConfig:
|
||||
self.user_agent = config.get("user_agent", HRTiDefaults.USER_AGENT)
|
||||
self.timeout = config.get("timeout", HRTiDefaults.DEFAULT_TIMEOUT)
|
||||
|
||||
# Web API URL (can be updated from config)
|
||||
self.web_api_url = config.get("web_api_url", "api/api/ott")
|
||||
|
||||
# VOD settings
|
||||
self.vod_items_per_page = config.get("vod_items_per_page", HRTiDefaults.VOD_ITEMS_PER_PAGE)
|
||||
|
||||
def _build_api_endpoints(self):
|
||||
"""Build full API endpoints from dynamic base URLs and static paths"""
|
||||
endpoints = {}
|
||||
|
||||
# Build endpoints using webApiUrl (for OTT endpoints)
|
||||
if self.web_api_url:
|
||||
base_api_url = f"{self.base_url}/{self.web_api_url}"
|
||||
ott_endpoints = [
|
||||
"get_ip", "grant_access", "channels", "programme",
|
||||
"authorize_session", "report_session", "catalogue_structure",
|
||||
"catalogue", "vod_details", "episodes", "watch_later",
|
||||
"editors_choice"
|
||||
]
|
||||
for key in ott_endpoints:
|
||||
if key in self.api_endpoint_paths:
|
||||
endpoints[key] = f"{base_api_url}{self.api_endpoint_paths[key]}"
|
||||
|
||||
# Build endpoints using hsapi_base_url (for HSAPI endpoints)
|
||||
if self.hsapi_base_url:
|
||||
hsapi_endpoints = ["register_device", "content_ratings", "profiles"]
|
||||
for key in hsapi_endpoints:
|
||||
if key in self.api_endpoint_paths:
|
||||
endpoints[key] = f"{self.hsapi_base_url}{self.api_endpoint_paths[key]}"
|
||||
|
||||
return endpoints
|
||||
|
||||
def update_from_api(self, env_data: dict, config_data: dict):
|
||||
"""Update configuration from API responses"""
|
||||
try:
|
||||
@@ -117,36 +147,48 @@ class HRTiConfig:
|
||||
|
||||
if "webApiUrl" in config_data:
|
||||
self.web_api_url = config_data["webApiUrl"]
|
||||
# Update API endpoints with new web API URL
|
||||
base_api_url = f"{self.base_url}/{self.web_api_url}"
|
||||
self.api_endpoints.update(
|
||||
{
|
||||
"get_ip": f"{base_api_url}/getIPAddress",
|
||||
"grant_access": f"{base_api_url}/GrantAccess",
|
||||
"channels": f"{base_api_url}/GetChannels",
|
||||
"programme": f"{base_api_url}/GetProgramme",
|
||||
"authorize_session": f"{base_api_url}/AuthorizeSession",
|
||||
"catalogue_structure": f"{base_api_url}/GetCatalogueStructure",
|
||||
"catalogue": f"{base_api_url}/GetCatalogue",
|
||||
"vod_details": f"{base_api_url}/GetVodDetails",
|
||||
"episodes": f"{base_api_url}/GetSeries",
|
||||
"watch_later": f"{base_api_url}/GetWatchLater",
|
||||
"editors_choice": f"{base_api_url}/GetEditorsChoice",
|
||||
}
|
||||
)
|
||||
|
||||
# Update operator-specific settings
|
||||
if "operators" in config_data and config_data["operators"]:
|
||||
operator = config_data["operators"][0]
|
||||
if "playerMerchant" in operator:
|
||||
self.merchant = operator["playerMerchant"]
|
||||
if "playerLicenseKey" in operator:
|
||||
self.player_license_key = operator["playerLicenseKey"]
|
||||
if "selfcareUrl" in operator:
|
||||
# Store selfcare URL if needed
|
||||
pass
|
||||
self.selfcare_url = operator["selfcareUrl"]
|
||||
if "homepageUrl" in operator:
|
||||
self.homepage_url = operator["homepageUrl"]
|
||||
|
||||
# Build API endpoints from dynamic URLs
|
||||
self.api_endpoints = self._build_api_endpoints()
|
||||
|
||||
# Log what we got from API (debug)
|
||||
import logging
|
||||
logging.debug(f"HRTi config updated from API - hsapi_url: {self.hsapi_base_url}, "
|
||||
f"web_api_url: {self.web_api_url}, merchant: {self.merchant}")
|
||||
|
||||
except Exception as e:
|
||||
# Log error but don't raise - use defaults if update fails
|
||||
import logging
|
||||
logging.debug(f"Error updating HRTi config from API: {e}")
|
||||
# Fallback to build endpoints with defaults if API update fails
|
||||
self._build_fallback_endpoints()
|
||||
|
||||
def _build_fallback_endpoints(self):
|
||||
"""Build fallback API endpoints if dynamic config fails"""
|
||||
# Use default hsapi URL if not set
|
||||
if not self.hsapi_base_url:
|
||||
self.hsapi_base_url = "https://hsapi.aviion.tv/client.svc/json"
|
||||
|
||||
# Use default web API URL if not set
|
||||
if not self.web_api_url:
|
||||
self.web_api_url = "api/api/ott"
|
||||
|
||||
# Use default merchant if not set
|
||||
if not self.merchant:
|
||||
self.merchant = "aviion2"
|
||||
|
||||
self.api_endpoints = self._build_api_endpoints()
|
||||
|
||||
def get_base_headers(self) -> dict:
|
||||
"""Get base HTTP headers"""
|
||||
|
||||
@@ -287,8 +287,13 @@ class HRTiProvider(StreamingProvider):
|
||||
f"{'Client ...' if 'authorization' in headers else 'NO AUTHORIZATION'}"
|
||||
)
|
||||
|
||||
channels_endpoint = self.hrti_config.api_endpoints.get("channels", "")
|
||||
if not channels_endpoint:
|
||||
logger.error("No channels endpoint configured")
|
||||
return []
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.hrti_config.api_endpoints["channels"],
|
||||
channels_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps({}),
|
||||
@@ -539,8 +544,13 @@ class HRTiProvider(StreamingProvider):
|
||||
"EndTime": f"/Date({end_time})/",
|
||||
}
|
||||
|
||||
programme_endpoint = self.hrti_config.api_endpoints.get("programme", "")
|
||||
if not programme_endpoint:
|
||||
logger.error("No programme endpoint configured")
|
||||
return []
|
||||
|
||||
response = self.http_manager.post(
|
||||
self.hrti_config.api_endpoints["programme"],
|
||||
programme_endpoint,
|
||||
operation="api",
|
||||
headers=headers,
|
||||
data=json.dumps(payload),
|
||||
|
||||
Reference in New Issue
Block a user