Skip to content
This repository was archived by the owner on Nov 17, 2022. It is now read-only.
Merged
35 changes: 31 additions & 4 deletions elemental/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,25 @@ def stop_event(self, event_id):
self.send_request(http_method="POST", url=url,
headers=headers, body=body)

def describe_event(self, event_id):
url = f'{self.server_ip}/live_events/{event_id}'

headers = self.generate_headers(url)

response = self.send_request(http_method="GET", url=url,
headers=headers)
# print(response.text)
event_info = {}

destinations = ET.fromstring(response.text).iter('destination')
event_info['origin_url'] = next(destinations).find('uri').text
event_info['backup_url'] = next(destinations).find('uri').text

status = ET.fromstring(response.text).find('status')
event_info['status'] = status.text

return event_info

def find_devices_in_use(self):
events_url = f'{self.server_ip}/live_events?filter=active'
events_headers = self.generate_headers(events_url)
Expand Down Expand Up @@ -173,7 +192,7 @@ def get_input_devices(self):
devices_info, key=lambda d: int(d["id"]))
return [dict(d) for d in devices_info]

def get_input_devices_by_id(self, input_device_id):
def get_input_device_by_id(self, input_device_id):
devices_url = f'{self.server_ip}/devices/{input_device_id}'
devices_headers = self.generate_headers(devices_url)
devices = self.send_request(
Expand All @@ -185,7 +204,7 @@ def get_input_devices_by_id(self, input_device_id):
device_info.pop('@href')
return dict(device_info)

def generate_preview(self, source_type, input_id):
def generate_preview(self, input_id):
url = f'{self.server_ip}/inputs/generate_preview'
headers = self.generate_headers(url)

Expand All @@ -195,7 +214,7 @@ def generate_preview(self, source_type, input_id):

# generate body
data = f"input_key=0&live_event[inputs_attributes][0][source_type]=" \
f"{source_type}&live_event[inputs_attributes][0]" \
f"DeviceInput&live_event[inputs_attributes][0]" \
f"[device_input_attributes][sdi_settings_attributes]" \
f"[input_format]=Auto&live_event[inputs_attributes][0]" \
f"[device_input_attributes][device_id]={input_id}"
Expand All @@ -204,10 +223,18 @@ def generate_preview(self, source_type, input_id):

response_parse = ast.literal_eval(response.text)

if 'preview_image_id' not in response_parse:
if 'type' in response_parse and response_parse['type'] == 'error':
raise ElementalException(
f"Response: {response.status_code}\n{response.text}")
else:
preview_url = f'{self.server_ip}/images/thumbs/' \
f'p_{response_parse["preview_image_id"]}_job_0.jpg'
return {'preview_url': preview_url}

def event_can_delete(self, channel_id):
channel_info = self.describe_event(channel_id)
if channel_info['status'] in ('pending', 'running',
'preprocessing', 'postprocessing'):
return {'deletable': False}
else:
return {'deletable': True}
93 changes: 86 additions & 7 deletions elemental/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,17 @@ def test_create_event_should_call_send_request_as_expect_and_return_event_id():
'mediastore_container_backup':
'https://hu5n3jjiyi2jev.data.medias'
'tore.us-east-1.amazonaws.com/backup',
'channel': "1", 'device_name': "0"})
'input_device': {'id': '1',
'name': None,
'device_name': 'HD-SDI 1',
'device_number': '0',
'device_type': 'AJA',
'description':
'AJA Capture Card',
'channel': '1',
'channel_type': 'HD-SDI',
'quad': 'false',
'availability': False}})

response_from_elemental_api = client.send_request.call_args_list[0][1]
assert response_from_elemental_api['http_method'] == 'POST'
Expand Down Expand Up @@ -293,7 +303,7 @@ def test_get_input_devices_will_get_right_devices_info():
"quad": "false", "availability": True}]


def test_get_input_devices_by_id_will_call_send_request_as_expect():
def test_get_input_device_by_id_will_call_send_request_as_expect():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)

client.generate_headers = mock.Mock()
Expand All @@ -306,15 +316,15 @@ def test_get_input_devices_by_id_will_call_send_request_as_expect():
mock_response(status=200,
text=file_fixture('sample_single_device.xml'))

client.get_input_devices_by_id('2')
client.get_input_device_by_id('2')

client.send_request.\
assert_called_with(http_method="GET",
url=f'{ELEMENTAL_ADDRESS}/devices/2',
headers=HEADERS)


def test_get_input_devices_by_id_will_get_right_devices_info():
def test_get_input_device_by_id_will_get_right_devices_info():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)

client.generate_headers = mock.Mock()
Expand All @@ -327,7 +337,7 @@ def test_get_input_devices_by_id_will_get_right_devices_info():
mock_response(status=200,
text=file_fixture('sample_single_device.xml'))

res = client.get_input_devices_by_id('2')
res = client.get_input_device_by_id('2')
assert res == {"id": "2",
"name": None, "device_name": "HD-SDI 2",
"device_number": "0", "device_type": "AJA",
Expand All @@ -347,7 +357,7 @@ def test_get_preview_will_parse_response_json_as_expect():
status=200, text=file_fixture(
'success_response_for_generate_preview.json'))

response = client.generate_preview('DeviceInput', '2')
response = client.generate_preview('2')

assert response == {
'preview_url': f'{ELEMENTAL_ADDRESS}/'
Expand All @@ -367,11 +377,80 @@ def test_get_preview_will_raise_ElementalException_if_preview_unavaliable():
"Device already in use."}))

with pytest.raises(ElementalException) as exc_info:
client.generate_preview('DeviceInput', '1')
client.generate_preview('1')

respond_text = json.dumps({'type': 'error',
'message': 'Input is invalid. '
'Device already in use.'})
assert str(exc_info.value).endswith(
f"Response: 200\n"
f"{respond_text}")


def test_describe_event_will_call_send_request_as_expect():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)

client.generate_headers = mock.Mock()
client.generate_headers.return_value = HEADERS

client.send_request = mock.Mock()
response_from_elemental_api = file_fixture('sample_event.xml')
client.send_request.return_value = mock_response(
status=200, text=response_from_elemental_api)

event_id = 999
client.describe_event(event_id)
client.send_request.assert_called_once_with(
http_method='GET',
url=f'{ELEMENTAL_ADDRESS}/live_events/{event_id}',
headers=HEADERS)


def test_describe_event_will_return_event_info_as_expect():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)
client.generate_headers = mock.Mock()
client.generate_headers.return_value = HEADERS
client.send_request = mock.Mock()
response_from_elemental_api = file_fixture('sample_event.xml')
client.send_request.return_value = mock_response(
status=200, text=response_from_elemental_api)

event_id = '139'
event_info = client.describe_event(event_id)
assert event_info == {'origin_url':
'https://vmjhch43nfkghi.data.mediastore.us-east-1.'
'amazonaws.com/mortyg3b4/master/mortyg3b4.m3u8',
'backup_url':
'https://vmjhch43nfkghi.data.mediastore.us-east-1.'
'amazonaws.com/mortyg3b4/backup/mortyg3b4.m3u8',
'status': 'complete'}


def test_event_can_delete_will_return_False_if_pending():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)

client.describe_event = mock.Mock()
client.describe_event.return_value = {
'status': 'pending',
'origin_url': 'fake_origin',
'backup_url': 'fake_backup'
}
d = client.event_can_delete('123')
assert d == {
'deletable': False
}


def test_event_can_delete_will_return_True_if_complete():
client = ElementalLive(ELEMENTAL_ADDRESS, USER, API_KEY)

client.describe_event = mock.Mock()
client.describe_event.return_value = {
'status': 'complete',
'origin_url': 'fake_origin',
'backup_url': 'fake_backup'
}
d = client.event_can_delete('321')
assert d == {
'deletable': True
}
14 changes: 7 additions & 7 deletions elemental/templates/qvbr_mediastore.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<live_event href="/live_events/3" product="Elemental Live + HEVC Package" version="2.14.4.308149">
<name>SuperBowl AVC Live (FLL - Dev)</name>
<name>{{channel_name}}</name>
<input>
<deblock_selected>true</deblock_selected>
<denoise_selected>false</denoise_selected>
Expand All @@ -18,11 +18,11 @@
<service_provider_name nil="true"/>
<timecode_source>embedded</timecode_source>
<device_input>
<device_type>AJA</device_type>
<device_number>{{ device_number }}</device_number>
<channel>{{ channel }}</channel>
<channel_type>HD-SDI</channel_type>
<device_name>HD-SDI 1</device_name>
<device_type>{{ input_device["device_type"] }}</device_type>
<device_number>{{ input_device["device_number"] }}</device_number>
<channel>{{ input_device["channel"] }}</channel>
<channel_type>{{ input_device["channel_type"] }}</channel_type>
<device_name>{{ input_device["device_name"] }}</device_name>
<name nil="true"/>
<sdi_settings>
<input_format>Auto</input_format>
Expand Down Expand Up @@ -835,7 +835,7 @@
<destination>
<password>{{ password }}</password>
<username>{{ username }}</username>
<uri>{{ mediastore_container_master}}</uri>
<uri>{{ mediastore_container_master }}</uri>
</destination>
</apple_live_group_settings>
<type>apple_live_group_settings</type>
Expand Down
Loading