def api_media_post(auth_user=None, api_core=None, request=None): u""" Register a media asset and add informations about it. This method only register already uploaded media asset to the shared storage. For example, the WebUI will upload a media asset to uploads path **before** registering it with this method. Medias in the shared storage are renamed with the following convention: ``storage_root``/medias/``user_id``/``media_id`` When published or downloaded, media asset file-name will be ``filename``. Spaces ( ) are not allowed and they will be converted to underscores (_). Media asset's ``metadata`` must contain any valid JSON string. Only the ``title`` key is required. The orchestrator will automatically add ``add_date`` and ``duration`` to ``metadata``. .. note:: Registration of external media assets (aka. http://) will be an interesting improvement. """ data = get_request_data(request, qs_only_first_value=True) media = Media(user_id=auth_user._id, uri=data[u'uri'], filename=data[u'filename'], metadata=data[u'metadata'], status=Media.READY) api_core.save_media(media) return ok_200(media, include_properties=True)
def api_user_id_delete(id=None, auth_user=None, api_core=None, request=None): u"""Delete a user.""" user = api_core.get_user(spec={u'_id': id}) if not user: raise IndexError(to_bytes(u'No user with id {0}.'.format(id))) api_core.delete_user(user) return ok_200(u'The user "{0}" has been deleted.'.format(user.name), include_properties=False)
def api_user_post(auth_user=None, api_core=None, request=None): u"""Add a user.""" data = get_request_data(request, qs_only_first_value=True) user = User(first_name=data[u'first_name'], last_name=data[u'last_name'], mail=data[u'mail'], secret=data[u'secret'], admin_platform=data[u'admin_platform']) api_core.save_user(user, hash_secret=True) delattr(user, u'secret') # do not send back user's secret return ok_200(user, include_properties=True)
def api_publisher_task_head(auth_user=None, api_core=None, request=None): u""" Return an array containing the publication tasks serialized as JSON. The publication tasks attributes are appended with the Celery's ``async result`` of the tasks. """ data = get_request_data(request, accepted_keys=api_core.db_find_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_publisher_tasks(**data), include_properties=True)
def api_transform_profile_id_delete(id=None, auth_user=None, api_core=None, request=None): u"""Delete a transformation profile.""" profile = api_core.get_transform_profile(spec={u'_id': id}) if not profile: raise IndexError(to_bytes(u'No transformation profile with id {0}.'.format(id))) api_core.delete_transform_profile(profile) return ok_200(u'The transformation profile "{0}" has been deleted.'.format(profile.title), include_properties=False)
def api_media_get(auth_user=None, api_core=None, request=None): u""" Return an array containing the informations about the media assets serialized to JSON. All ``thing_id`` fields are replaced by corresponding ``thing``. For example ``user_id`` is replaced by ``user``'s data. """ data = get_request_data(request, accepted_keys=api_core.db_find_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_medias(load_fields=True, **data), include_properties=True)
def api_media_id_delete(id=None, auth_user=None, api_core=None, request=None): u"""Remove a media asset from the shared storage and update informations about it (set status to DELETED).""" media = api_core.get_media(spec={u'_id': id}) if not media: raise IndexError(to_bytes(u'No media asset with id {0}.'.format(id))) if auth_user._id != media.user_id: flask.abort(403, u'You are not allowed to delete media asset with id {0}.'.format(id)) api_core.delete_media(media) return ok_200(u'The media asset "{0}" has been deleted.'.format(media.metadata[u'title']), include_properties=False)
def api_publisher_task_id_head(id=None, auth_user=None, api_core=None, request=None): u""" Return a publication task serialized to JSON. The publication task attributes are appended with the Celery's ``async result`` of the task. """ task = api_core.get_publisher_task(spec={u'_id': id}) if not task: raise IndexError(to_bytes(u'No publication task with id {0}.'.format(id))) return ok_200(task, include_properties=True)
def api_publisher_task_get(auth_user=None, api_core=None, request=None): u""" Return an array containing the publication tasks serialized to JSON. The publication tasks attributes are appended with the Celery's ``async result`` of the tasks. All ``thing_id`` fields are replaced by corresponding ``thing``. For example ``user_id`` is replaced by ``user``'s data. """ data = get_request_data(request, accepted_keys=api_core.db_find_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_publisher_tasks(load_fields=True, **data), include_properties=True)
def api_media_id_get(id=None, auth_user=None, api_core=None, request=None): u""" Return the informations about a media asset serialized to JSON. All ``thing_id`` fields are replaced by corresponding ``thing``. For example ``user_id`` is replaced by ``user``'s data. """ media = api_core.get_media(spec={'_id': id}, load_fields=True) if not media: raise IndexError(to_bytes(u'No media asset with id {0}.'.format(id))) return ok_200(media, include_properties=True)
def api_user_login(auth_user=None, api_core=None, request=None): u""" Return authenticated user serialized to JSON if authentication passed (without ``secret`` field). This method is useful for WebUI to simulate stateful login scheme and get informations about the user. .. note:: This is kind of duplicate with API's GET /user/id/`id` method ... """ delattr(auth_user, u'secret') # do not send back user's secret return ok_200(auth_user, include_properties=True)
def api_revoke_publisher_task_hook(auth_user=None, api_core=None, request=None): u""" This method is called by publication workers when they finish their work (revoke). If the task is successful, the orchestrator will update media asset's ``status`` and ``public_uris`` attribute. Else, the orchestrator will append ``error_details`` to ``statistic`` attribute of the task. """ data = get_request_data(request, qs_only_first_value=True) task_id, publish_uri, status = data[u'task_id'], data.get(u'publish_uri'), data[u'status'] logging.debug(u'task {0}, revoked publish_uri {1}, status {2}'.format(task_id, publish_uri, status)) api_core.publisher_revoke_callback(task_id, publish_uri, status) return ok_200(u'Your work is much appreciated, thanks !', include_properties=False)
def api_media_id_patch(id=None, auth_user=None, api_core=None, request=None): u"""Update the informations of a media asset (only metadata field can be updated).""" media = api_core.get_media(spec={u'_id': id}) data = get_request_data(request, qs_only_first_value=True) if not media: raise IndexError(to_bytes(u'No media asset with id {0}.'.format(id))) if auth_user._id != media.user_id: flask.abort(403, u'You are not allowed to modify media asset with id {0}.'.format(id)) if u'metadata' in data: media.metadata = data[u'metadata'] api_core.save_media(media) return ok_200(u'The media asset "{0}" has been updated.'.format(media.filename), include_properties=False)
def api_publisher_task_id_get(id=None, auth_user=None, api_core=None, request=None): u""" Return a publication task serialized to JSON. The publication task attributes are appended with the Celery's ``async result`` of the task. All ``thing_id`` fields are replaced by corresponding ``thing``. For example ``user_id`` is replaced by ``user``'s data. """ task = api_core.get_publisher_task(spec={u'_id': id}, load_fields=True) if not task: raise IndexError(to_bytes(u'No publication task with id {0}.'.format(id))) return ok_200(task, include_properties=True)
def api_transform_task_hook(auth_user=None, api_core=None, request=None): u""" This method is called by transformation workers when they finish their work. If task is successful, the orchestrator will set media's status to READY. Else, the orchestrator will append ``error_details`` to ``statistic`` attribute of task. The media asset will be deleted if task failed (even the worker already take care of that). """ data = get_request_data(request, qs_only_first_value=True) task_id, status = data[u'task_id'], data[u'status'] logging.debug(u'task {0}, status {1}'.format (task_id, status)) api_core.transform_callback(task_id, status) return ok_200(u'Your work is much appreciated, thanks !', include_properties=False)
def api_transform_profile_post(auth_user=None, api_core=None, request=None): u""" Add a transformation profile. The transformation profile's ``encoder_name`` attribute can be the following : * **copy** to bypass FFmpeg and do a simple file block copy ; * **ffmpeg** to transcode a media asset to another with FFMpeg ; * **dashcast** to transcode a media asset to MPEG-DASH with DashCast ; """ data = get_request_data(request, qs_only_first_value=True) profile = TransformProfile(title=data[u'title'], description=data[u'description'], encoder_name=data[u'encoder_name'], encoder_string=data[u'encoder_string']) api_core.save_transform_profile(profile) return ok_200(profile, include_properties=True)
def api_publisher_task_id_delete(id=None, auth_user=None, api_core=None, request=None): u""" Revoke a publication task. This method do not delete tasks from tasks database but set ``revoked`` attribute in tasks database and broadcast revoke request to publication units with Celery. If the task is actually running it will be canceled. The media asset will be removed from the publication unit. """ task = api_core.get_publisher_task(spec={u'_id': id}) if not task: raise IndexError(to_bytes(u'No publication task with id {0}.'.format(id))) if auth_user._id != task.user_id: flask.abort(403, u'You are not allowed to revoke publication task with id {0}.'.format(id)) api_core.revoke_publisher_task(task=task, callback_url=u'/publisher/revoke/callback', terminate=True, remove=False) return ok_200(u'The publication task "{0}" has been revoked. Corresponding media asset will be unpublished from' ' here.'.format(task._id), include_properties=False)
def api_transform_task_id_delete(id=None, auth_user=None, api_core=None, request=None): u""" Revoke a transformation task. This method do not delete tasks from tasks database but set ``revoked`` attribute in tasks database and broadcast revoke request to transformation units with Celery. If the task is actually running it will be canceled. The output media asset will be deleted. """ task = api_core.get_transform_task(spec={u'_id': id}) if not task: raise IndexError(to_bytes(u'No transformation task with id {0}.'.format(id))) if auth_user._id != task.user_id: flask.abort(403, u'You are not allowed to revoke transformation task with id {0}.'.format(id)) api_core.revoke_transform_task(task=task, terminate=True, remove=False, delete_media=True) return ok_200(u'The transformation task "{0}" has been revoked. Corresponding output media asset will be' ' deleted.'.format(task._id), include_properties=False)
def api_publisher_task_post(auth_user=None, api_core=None, request=None): u""" Launch a publication task. Any user can launch a publication task using any media asset as input. This is linked to media asset API methods access policy. The orchestrator will automatically add ``add_date`` to ``statistic``. .. note:: Interesting enhancements would be to : * Schedule tasks by specifying start time (...) * Handle the registration of tasks related to PENDING medias * Permit to publication a media asset on more than one (1) publication queue """ data = get_request_data(request, qs_only_first_value=True) task_id = api_core.launch_publisher_task(auth_user._id, data[u'media_id'], data[u'send_email'], data[u'queue'], u'/publisher/callback') return ok_200(task_id, include_properties=True)
def api_user_id_patch(id=None, auth_user=None, api_core=None, request=None): u""" Update an user. User's admin_platform attribute can only be modified by root or any authenticated user with admin_platform attribute set. """ user = api_core.get_user(spec={u'_id': id}) data = get_request_data(request, qs_only_first_value=True) if not user: raise IndexError(to_bytes(u'No user with id {0}.'.format(id))) old_name = user.name if u'first_name' in data: user.first_name = data[u'first_name'] if u'last_name' in data: user.last_name = data[u'last_name'] if u'mail' in data: user.mail = data[u'mail'] if u'secret' in data: user.secret = data[u'secret'] if auth_user.admin_platform and u'admin_platform' in data: user.admin_platform = data[u'admin_platform'] api_core.save_user(user, hash_secret=True) return ok_200(u'The user "{0}" has been updated.'.format(old_name), include_properties=False)
def api_transform_task_post(auth_user=None, api_core=None, request=None): u""" Launch a transformation task. Any user can launch a transformation task using any media asset as input and any transformation profile. This is linked to media assets and transformation profile API methods access policies. The output media asset is registered to the database with the PENDING status and the ``parent_id`` field is set to input media asset's ``id``. This permit to know relation between media assets ! The orchestrator will automatically add ``add_date`` to ``statistic``. .. note:: Interesting enhancement would be to : * Schedule obs by specifying start time (...) ; * Handle the registration of tasks related to PENDING medias ; """ data = get_request_data(request, qs_only_first_value=True) task_id = api_core.launch_transform_task( auth_user._id, data[u'media_in_id'], data[u'profile_id'], data[u'filename'], data[u'metadata'], data[u'send_email'], data[u'queue'], u'/transform/callback') return ok_200(task_id, include_properties=True)
def api_publisher_unit_number_delete(environment=None, number=None, auth_user=None, api_core=None, request=None): u"""Remove publication unit number ``number`` from environment ``environment``.""" api_core.destroy_publisher_unit(environment, number, terminate=True) return ok_200(u'The publication unit {0} has been removed of environment {1}.'.format(number, environment), include_properties=False)
def api_user_id_get(id=None, auth_user=None, api_core=None, request=None): u"""Return a user serialized to JSON (without ``secret`` field).""" user = api_core.get_user(spec={u'_id': id}, fields={u'secret': 0}) if not user: raise IndexError(to_bytes(u'No user with id {0}.'.format(id))) return ok_200(user, include_properties=True)
def api_user_count(auth_user=None, api_core=None, request=None): u"""Return the number of users.""" data = get_request_data(request, accepted_keys=api_core.db_count_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_users_count(**data), include_properties=False)
def api_user_get(auth_user=None, api_core=None, request=None): u"""Return an array containing the users serialized to JSON (without ``secret`` fields).""" data = get_request_data(request, accepted_keys=api_core.db_find_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_users(**data), include_properties=True)
def api_publisher_queue(auth_user=None, api_core=None, request=None): u"""Return an array containing the publication queues.""" return ok_200(api_core.get_publisher_queues(), include_properties=True)
def api_root(api_core=None, request=None): u""" Return an about string. This method is actually used by Orchestra charm's hooks to check API's status. """ return ok_200(api_core.about, include_properties=False)
def api_media_id_head(id=None, auth_user=None, api_core=None, request=None): u"""Return the informations about a media asset serialized to JSON.""" media = api_core.get_media(spec={u'_id': id}) if not media: raise IndexError(to_bytes(u'No media asset with id {0}.'.format(id))) return ok_200(media, include_properties=True)
def api_flush(auth_user=None, api_core=None, request=None): u"""Flush Orchestrator's database. This method is useful for testing and development purposes.""" api_core.flush_db() return ok_200(u'Orchestra database flushed !', include_properties=False)
def api_media_head(auth_user=None, api_core=None, request=None): u"""Return an array containing the informations about the media assets serialized to JSON.""" data = get_request_data(request, accepted_keys=api_core.db_find_keys, qs_only_first_value=True, optional=True) return ok_200(api_core.get_medias(**data), include_properties=True)