Source code for api.views

# -*- coding: utf-8 -*-
from datetime import datetime
from subprocess import Popen
import os

from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404

from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

from core.utils import (validate_status, write_log, get_path_folder_run, execute_fe_command)
from gsi.models import Run, RunStep, CardSequence, OrderedCardItem, SubCardItem
from gsi.settings import EXECUTE_FE_COMMAND
from cards.models import CardItem


[docs]def is_finished(run_id, card_id, cur_counter, last, run_parallel): """Function to determine the last card in a running list of cards. :Arguments: * *run_id*: run id * *card_id*: card id * *cur_counter*: the current cards position in the running list of cards * *last*: the last position in the running list of cards * *run_parallel*: boolean value that parallel card opledelyaet running or sequentially """ # if the card is running in parallel if run_parallel: # get all the sub-cards for the card sub_card_item = SubCardItem.objects.filter( run_id=int(run_id), card_id=int(card_id) ).values_list('state', flat=True) # if there is no "running" status and the "pending" in the list of sub-cards, the card is finished the Run if 'running' not in sub_card_item and 'pending' not in sub_card_item: return True # if the card is running in successively else: # if the current number of card coincides with the latter number, the card is finished the Run if cur_counter == last: return True return False
[docs]def set_state_fail(obj, state): """Set a card execution status if it does not 'fail'. :Arguments: * *obj*: card object * *state*: the current status of the card """ if obj.state != 'fail': obj.state = state obj.save()
@api_view(['GET']) @authentication_classes((SessionAuthentication, BasicAuthentication)) @permission_classes((IsAuthenticated,))
[docs]def update_run(request, run_id): """Update the status of the card. The function receives the request and the card data. If the launched the card is last, the process stops. :Arguments: * *request*: request * *run_id*: card details. Presented as a string: <run_id>.<card_sequence_id>.<order_card_item_id>.<current_position>.<the_last_card_number> """ data = validate_status(request.query_params.get('status', False)) value_list = str(run_id).split('.') run_card_id = value_list[0] card_sequence_id = value_list[1] order_card_item_id = value_list[2] last = value_list[-1] last_but_one = value_list[-2:-1] cur_counter = last_but_one[0] name_sub_card = '{0}_{1}'.format(order_card_item_id, cur_counter) finished = False # if the status is valid if data['status']: state = data['status'] # get the data of Run try: run = Run.objects.get(id=run_card_id) sequence = CardSequence.objects.get(id=card_sequence_id) card = OrderedCardItem.objects.get(id=order_card_item_id) step = RunStep.objects.get( parent_run=run, card_item=card) cur_state = step.state run_parallel = False # if the run is parallel # get name of sub-card try: if card.run_parallel: run_parallel = True name_sub_card = '{0}_{1}'.format(card.id, cur_counter) except Exception, e: pass # check the status and perform card processing if state == 'fail': params = [] if run_parallel: sub_card_item = SubCardItem.objects.filter( name=name_sub_card, run_id=int(run_card_id), card_id=int(order_card_item_id) ) for n in sub_card_item: n.state = state n.save() step.state = state step.save() run.state = state run.save() elif state == 'running': if run_parallel: sub_card_item = SubCardItem.objects.filter( name=name_sub_card, run_id=int(run_card_id), card_id=int(order_card_item_id) ) for n in sub_card_item: if n.state == 'running': n.state = 'fail' n.save() else: n.state = state n.save() run_state = set_state_fail(run, state) step_state = set_state_fail(step, state) elif state == 'success': next_step, is_last_step = step.get_next_step() new_sub_card_item = None params = [] if run_parallel: sub_card_item = get_object_or_404( SubCardItem, name=name_sub_card, run_id=int(run_card_id), card_id=int(order_card_item_id) ) sub_card_item.state = state sub_card_item.save() if next_step: data['next_step'] = next_step.id run_parallel_next_step = next_step.card_item.run_parallel # CHECK ALL THE SUB CARDS!!!!!!! finished = is_finished(int(run_card_id), int(order_card_item_id), cur_counter, last, run_parallel) if finished: step_state = set_state_fail(step, state) if run_parallel_next_step: master_script_name = '{0}_master'.format(next_step.card_item.id) ex_fe_com = Popen( 'nohup {0} {1} {2} &'.format( EXECUTE_FE_COMMAND, next_step.parent_run.id, master_script_name ), shell=True, ) else: ex_fe_com = Popen( 'nohup {0} {1} {2} &'.format( EXECUTE_FE_COMMAND, next_step.parent_run.id, next_step.card_item.id ), shell=True, ) log_name = '{0}_{1}.log'.format(value_list[0], value_list[2]) path_log = get_path_folder_run(run) write_log(log_name, run, path_log) # this end if is_last_step: data['is_last_step'] = True finished = is_finished(int(run_card_id), int(order_card_item_id), cur_counter, last, run_parallel) if finished: if run_parallel: sub_card_item = get_object_or_404( SubCardItem, name=name_sub_card, run_id=int(run_card_id), card_id=int(order_card_item_id) ) sub_card_item.state = 'success' sub_card_item.save() run_state = set_state_fail(run, state) step_state = set_state_fail(step, state) else: if run_parallel: sub_card_item = SubCardItem.objects.filter( name=name_sub_card, run_id=int(run_card_id), card_id=int(order_card_item_id) ) for n in sub_card_item: n.state = state n.save() run_state = set_state_fail(run, state) step_state = set_state_fail(step, state) except Exception, e: data['status'] = False data['message'] = str(e) except ObjectDoesNotExist as e: data['status'] = False data['message'] = str(e) else: return Response(data, status=status.HTTP_400_BAD_REQUEST) return Response(data, status=status.HTTP_200_OK)
@api_view(['GET']) @authentication_classes((SessionAuthentication, BasicAuthentication)) @permission_classes((IsAuthenticated,))
[docs]def api_gsi_maps(request): """API to get ready card images.""" data = {} path_to_map_images = '/home/gsi/Web_GeoChart/GSiMaps/png' root_url_gsimap = 'http://indy41.epcc.ed.ac.uk/' url_status = status.HTTP_200_OK if request.GET: data_get = request.GET if data_get.get('param1', ''): data['param 1'] = data_get.get('param1', '') else: data['message error param1'] = 'Invalid or missing the param1 in the request GET.' url_status = status.HTTP_400_BAD_REQUEST if data_get.get('param2', ''): data['param 2'] = data_get.get('param2', '') else: data['message error param2'] = 'Invalid or missing the param2 in the request GET.' url_status = status.HTTP_400_BAD_REQUEST if data_get.get('param3', ''): data['param 3'] = data_get.get('param3', '') else: data['message error param3'] = 'Invalid or missing the param3 in the request GET.' url_status = status.HTTP_400_BAD_REQUEST if url_status == status.HTTP_200_OK: try: root, dirs, files = os.walk(path_to_map_images).next() data['results'] = [] for f in files: dict_tmp = {} file_without_ext = f.split('.png')[0] dict_tmp['file'] = f dict_tmp['url'] = root_url_gsimap + 'GSiMap.php?q=images/{0}'.format(file_without_ext) dict_tmp['description'] = 'a brief description of the map' data['results'].append(dict_tmp) except Exception, e: data['message error'] = 'No such file or directory: {0}'.format(path_to_map_images) url_status = status.HTTP_500_INTERNAL_SERVER_ERROR else: data['message error'] = 'Invalid or missing the parameters for request GET.' url_status = status.HTTP_400_BAD_REQUEST return Response(data, status=url_status)