def get_profile_ids(self, profileId, activityId, since=None): ids = [] #make sure activityId exists try: activity = models.activity.objects.get(activity_id=activityId) except models.activity.DoesNotExist: err_msg = 'There is no activity associated with the id: %s' % activityId log_message(self.log_dict, err_msg, __name__, self.get_profile_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) #If there is a since param return all profileIds since then if since: try: profs = models.activity_profile.objects.filter(updated__gte=since, profileId=profileId, activity=activity) except ValidationError: since_i = int(float(since)) since_dt = datetime.datetime.fromtimestamp(since_i) profs = models.activity_profile_set.filter(update__gte=since_dt, profileId=profileId, activity=activity) ids = [p.profileId for p in profs] else: #Return all IDs of profiles associated with this activity b/c there is no since param ids = models.activity_profile.objects.filter(activity=activity).values_list('profileId', flat=True) return ids
def get_profile_ids(self, activityId, since=None): ids = [] #make sure activityId exists try: # Always want global version activity = models.activity.objects.get(activity_id=activityId, global_representation=True) except models.activity.DoesNotExist: err_msg = 'There is no activity associated with the id: %s' % activityId log_message(self.log_dict, err_msg, __name__, self.get_profile_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) #If there is a since param return all profileIds since then if since: try: # this expects iso6801 date/time format "2013-02-15T12:00:00+00:00" profs = models.activity_profile.objects.filter(updated__gte=since, activity=activity) except ValidationError: from django.utils import timezone since_i = int(float(since))# this handles timestamp like str(time.time()) since_dt = datetime.datetime.fromtimestamp(since_i).replace(tzinfo=timezone.get_default_timezone()) profs = models.activity_profile.objects.filter(updated__gte=since_dt, activity=activity) ids = [p.profileId for p in profs] else: #Return all IDs of profiles associated with this activity b/c there is no since param ids = models.activity_profile.objects.filter(activity=activity).values_list('profileId', flat=True) return ids
def populateResult(self, stmt_data, verb): log_message(self.log_dict, "Populating result", __name__, self.populateResult.__name__) resultExts = {} #Catch contradictory results if 'extensions' in stmt_data['result']: result = {key: value for key, value in stmt_data['result'].items() if not key == 'extensions'} resultExts = stmt_data['result']['extensions'] else: result = stmt_data['result'] self.validateVerbResult(result, verb, stmt_data['object']) # Validate duration, throw error if duration is not formatted correctly if 'duration' in result: try: dur = parse_duration(result['duration']) except ISO8601Error as e: log_message(self.log_dict, e.message, __name__, self.populateResult.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(e.message) #Once found that the results are valid against the verb, check score object and save if 'score' in result.keys(): result['score'] = self.validateScoreResult(result['score']) result['score'] = self.saveScoreToDB(result['score']) #Save result return self.saveResultToDB(result, resultExts)
def populateResult(self, stmt_data): log_message(self.log_dict, "Populating result", __name__, self.populateResult.__name__) resultExts = {} #Catch contradictory results if 'extensions' in stmt_data['result']: result = dict((key, value) for (key, value) in stmt_data['result'].items() if not key == 'extensions') resultExts = stmt_data['result']['extensions'] else: result = stmt_data['result'] # Validate duration, throw error if duration is not formatted correctly if 'duration' in result: try: dur = parse_duration(result['duration']) except ISO8601Error as e: log_message(self.log_dict, e.message, __name__, self.populateResult.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(e.message) if 'score' in result.keys(): result['score'] = self.validateScoreResult(result['score']) result['score'] = self.saveScoreToDB(result['score']) #Save result return self.saveResultToDB(result, resultExts)
def parse(self,data): try: params = json.loads(data) except Exception, e: err_msg = "Error parsing the Statement object. Expecting json. Received: %s which is %s" % (data, type(data)) log_message(self.log_dict, err_msg, __name__, self.parse.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg)
def validate_incoming_uuid(self, incoming_uuid): regex = re.compile("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}") match = regex.match(incoming_uuid) if not match: err_msg = "%s is not a valid UUID" % incoming_uuid log_message(self.log_dict, err_msg, __name__, self.validate_incoming_uuid.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg)
def get_profile(self, profileId): try: return self.agent.agent_profile_set.get(profileId=profileId) except: err_msg = 'There is no profile associated with the id: %s' % profileId log_message(self.log_dict, err_msg, __name__, self.get_profile.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg)
def get_ids(self, auth): try: state_set = self.get_set(auth) except models.activity_state.DoesNotExist: err_msg = 'There is no activity state associated with the ID: %s' % self.stateId log_message(self.log_dict, err_msg, __name__, self.get_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) if self.since: state_set = state_set.filter(updated__gte=self.since) return state_set.values_list('state_id', flat=True)
def populate_extensions(self, act_def): for k, v in act_def['extensions'].items(): if not uri.validate_uri(k): err_msg = "Extension ID %s is not a valid URI" % k log_message(self.log_dict, err_msg, __name__, self.populate_extensions.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) act_def_ext = models.extensions(key=k, value=v, content_object=self.activity.activity_definition) act_def_ext.save()
def get(self, auth): agent = self.__get_agent() try: if self.registrationId: return models.activity_state.objects.get(state_id=self.stateId, agent=agent, activity=self.activity, registration_id=self.registrationId) return models.activity_state.objects.get(state_id=self.stateId, agent=agent, activity=self.activity) except models.activity_state.DoesNotExist: err_msg = 'There is no activity state associated with the id: %s' % self.stateId log_message(self.log_dict, err_msg, __name__, self.get.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg)
def validateID(self,act_id): validXML = False resolves = True log_message(self.log_dict, "Validating Activity ID", __name__, self.validateID.__name__) #Retrieve XML doc since function is only called when not a link. ID should either not resolve or #only conform to the TC schema - if it fails that means the URL didn't resolve at all try: act_resp = urllib2.urlopen(act_id, timeout=10) except Exception, e: resolves = False
def __init__(self, initial=None, create=False, log_dict=None): self.initial = initial self.log_dict = log_dict params = self.initial if isinstance(params, dict): self.initial = json.dumps(self.initial) else: try: params = ast.literal_eval(params) except: params = json.loads(params) if 'objectType' in params and params['objectType'] == 'Group': obj = group else: obj = agent if create: self.agent, created = obj.objects.gen(**params) if created: log_message(self.log_dict, "Created %s in database" % self.agent.objectType, __name__, self.__init__.__name__) elif not created: log_message(self.log_dict, "Retrieved %s from database" % self.agent.objectType, __name__, self.__init__.__name__) else: try: if 'member' in params: params.pop('member', None) self.agent = obj.objects.get(**params) log_message(self.log_dict, "Retrieved %s from database" % self.agent.objectType, __name__, self.__init__.__name__) except: err_msg = "Error with Agent. The agent partial (%s) did not match any agents on record" % self.initial log_message(self.log_dict, err_msg, __name__, self.__init__.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg)
def validateVerbResult(self,result, verb, obj_data): completedVerbs = ['completed', 'mastered', 'passed', 'failed'] #If completion is false then verb cannot be completed, mastered, if 'completion' in result: if result['completion'] == False: if verb in completedVerbs: err_msg = "Completion must be True if using the verb %s" % verb log_message(self.log_dict, err_msg, __name__, self.validateVerbResult.__name__, True) #Throw exceptions b/c those verbs must have true completion update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) if verb == 'mastered' and result['success'] == False: err_msg = "Result success must be True if verb is %s" % verb log_message(self.log_dict, err_msg, __name__, self.validateVerbResult.__name__, True) #Throw exception b/c mastered and success contradict each other or completion is false update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) if verb == 'passed' and result['success'] == False: err_msg = "Result success must be True if verb is %s" % verb log_message(self.log_dict, err_msg, __name__, self.validateVerbResult.__name__, True) #Throw exception b/c passed and success contradict each other or completion is false update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) if verb == 'failed' and result['success'] == True: err_msg = "Result success must be False if verb is %s" % verb log_message(self.log_dict, err_msg, __name__, self.validateVerbResult.__name__, True) #Throw exception b/c failed and success contradict each other or completion is false update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg)
def __init__(self, initial=None, create=False, log_dict=None, define=True): self.initial = initial self.log_dict = log_dict self.define = define params = self.initial if not isinstance(params, dict): try: params = json.loads(self.initial) except Exception, e: err_msg = "Error parsing the Agent object. Expecting json. Received: %s which is %s" % (self.initial, type(self.initial)) log_message(self.log_dict, err_msg, __name__, self.__init__.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg)
def get(self, auth): agent = self.__get_agent() # if not agent.mbox is None: # if agent.mbox != auth.email: # raise Forbidden("Unauthorized to retrieve activity state with ID %s" % self.stateId) try: if self.registrationId: return models.activity_state.objects.get(state_id=self.stateId, agent=agent, activity=self.activity, registration_id=self.registrationId) return models.activity_state.objects.get(state_id=self.stateId, agent=agent, activity=self.activity) except models.activity_state.DoesNotExist: err_msg = 'There is no activity state associated with the id: %s' % self.stateId log_message(self.log_dict, err_msg, __name__, self.get.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg)
def saveResultToDB(self, result, resultExts): # Save the result with all of the args sc = result.pop('score', None) rslt = models.result(content_object=self.model_object, **result) rslt.save() if sc: sc.result = rslt sc.save() #If it has extensions, save them all if resultExts: for k, v in resultExts.items(): resExt = models.extensions(key=k, value=v, content_object=rslt) resExt.save() log_message(self.log_dict, "Result saved to database", __name__, self.saveResultToDB.__name__) return rslt
def saveContextToDB(self, context, contextExts): # Set context activities to context dict con_act_data = None if 'contextActivities' in context: con_act_data = context['contextActivities'] del context['contextActivities'] # Set context statement cs = None if 'cntx_statement' in context: cs = context['cntx_statement'] del context['cntx_statement'] # Save context cntx = models.context(content_object=self.model_object, **context) cntx.save() # Set context in context statement and save if cs: cs.context = cntx cs.save() # Save context activities if con_act_data: for con_act in con_act_data.items(): ca_id = con_act[1]['id'] if not uri.validate_uri(ca_id): raise exceptions.ParamError('Context Activity ID %s is not a valid URI' % ca_id) ca = models.ContextActivity(key=con_act[0], context_activity=ca_id, context=cntx) ca.save() cntx.save() # Save context extensions if contextExts: for k, v in contextExts.items(): if not uri.validate_uri(k): err_msg = "Extension ID %s is not a valid URI" % k log_message(self.log_dict, err_msg, __name__, self.saveContextToDB.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) conExt = models.extensions(key=k, value=v, content_object=cntx) conExt.save() log_message(self.log_dict, "Context saved to database", __name__, self.saveContextToDB.__name__) return cntx
def get_ids(self, auth): try: state_set = self.get_set(auth) except models.activity_state.DoesNotExist: err_msg = 'There is no activity state associated with the ID: %s' % self.stateId log_message(self.log_dict, err_msg, __name__, self.get_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) if self.since: try: # this expects iso6801 date/time format "2013-02-15T12:00:00+00:00" state_set = state_set.filter(updated__gte=self.since) except ValidationError: from django.utils import timezone since_i = int(float(since))# this handles timestamp like str(time.time()) since_dt = datetime.datetime.fromtimestamp(since_i).replace(tzinfo=timezone.get_default_timezone()) state_set = state_set.filter(updated__gte=since_dt) return state_set.values_list('state_id', flat=True)
def validate_definition(self, the_object, act_created): activity_definition = the_object['definition'] activity_id = self.activity.activity_id #Verify the given activity_id resolves if it is a link (has to resolve if link) xml_data = {} try: if activity_definition['type'] == 'link': try: Activity.validator(activity_id) except ValidationError, e: if act_created: self.activity.delete() self.activity = None err_msg = str(e) log_message(self.log_dict, err_msg, __name__, self.validate_definition.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) else:
def save_activity_definition_to_db(self,act_def_type, intType): created = True try: self.activity.activity_definition created = False except: actdef = models.activity_definition(activity_definition_type=act_def_type, interactionType=intType, activity=self.activity) actdef.save() if created: log_message(self.log_dict, "Activity definition saved to database", __name__, self.save_activity_definition_to_db.__name__) else: log_message(self.log_dict, "Activity definition retrieved from database", __name__,self.save_activity_definition_to_db.__name__) return created
def populateContext(self, stmt_data): instructor = False team = False revision = True platform = True contextExts = {} log_message(self.log_dict, "Populating context", __name__, self.populateContext.__name__) # Assign UUID if there is no registration for context if 'registration' not in stmt_data['context']: # raise Exception('Registration UUID required for context') stmt_data['context']['registration'] = uuid.uuid4() if 'instructor' in stmt_data['context']: stmt_data['context']['instructor'] = Agent(initial=stmt_data['context']['instructor'], create=True, log_dict=self.log_dict).agent # If there is an actor or object is a group in the stmt then remove the team if 'actor' in stmt_data or 'group' == stmt_data['object']['objectType'].lower(): if 'team' in stmt_data['context']: del stmt_data['context']['team'] # Revision and platform not applicable if object is agent if 'objectType' in stmt_data['object'] and ('agent' == stmt_data['object']['objectType'].lower() or 'group' == stmt_data['object']['objectType'].lower()): del stmt_data['context']['revision'] del stmt_data['context']['platform'] # Set extensions if 'extensions' in stmt_data['context']: context = {key: value for key, value in stmt_data['context'].items() if not key == 'extensions'} contextExts = stmt_data['context']['extensions'] else: context = stmt_data['context'] # Save context stmt if one if 'statement' in context: stmt_ref = models.StatementRef(ref_id=context['statement']['id']) stmt_ref.save() context['cntx_statement'] = stmt_ref del context['statement'] return self.saveContextToDB(context, contextExts)
def __init__(self, request_dict, log_dict=None): self.req_dict = request_dict self.log_dict = log_dict self.agent = request_dict['agent'] self.auth = request_dict.get('auth', None) self.user = get_user_from_auth(self.auth) try: self.activity = models.activity.objects.get(activity_id=request_dict['activityId']) except models.activity.DoesNotExist: err_msg = "Error with Activity State. The activity id (%s) did not match any activities on record" % (request_dict['activityId']) log_message(self.log_dict, err_msg, __name__, self.__init__.__name__, True) raise IDNotFoundError(err_msg) self.registrationId = request_dict.get('registrationId', None) self.stateId = request_dict.get('stateId', None) self.updated = request_dict.get('updated', None) self.content_type = request_dict.get('CONTENT_TYPE', None) self.state = request_dict.get('state', None) self.etag = request_dict.get('ETAG', None) self.since = request_dict.get('since', None)
def put_profile(self, request_dict): #Parse out profile from request_dict try: profile = ContentFile(request_dict['profile'].read()) except: try: profile = ContentFile(request_dict['profile']) except: profile = ContentFile(str(request_dict['profile'])) #Check if activity exists try: # Always want global version activity = models.activity.objects.get(activity_id=request_dict['activityId'], global_representation=True) except models.activity.DoesNotExist: err_msg = 'There is no activity associated with the id: %s' % request_dict['activityId'] log_message(self.log_dict, err_msg, __name__, self.put_profile.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) user = get_user_from_auth(request_dict.get('auth', None)) #Get the profile, or if not already created, create one p,created = models.activity_profile.objects.get_or_create(profileId=request_dict['profileId'],activity=activity, user=user) if created: log_message(self.log_dict, "Created Activity Profile", __name__, self.put_profile.__name__) else: #If it already exists delete it etag.check_preconditions(request_dict,p, required=True) p.profile.delete() log_message(self.log_dict, "Retrieved Activity Profile", __name__, self.put_profile.__name__) #Save profile content type based on incoming content type header and create etag p.content_type = request_dict['CONTENT_TYPE'] p.etag = etag.create_tag(profile.read()) #Set updated if request_dict['updated']: p.updated = request_dict['updated'] #Go to beginning of file profile.seek(0) #If it didn't exist, save it if created: p.save() #Set filename with the activityID and profileID and save fn = "%s_%s" % (p.activity_id,request_dict.get('filename', p.id)) p.profile.save(fn, profile) log_message(self.log_dict, "Saved Activity Profile", __name__, self.put_profile.__name__)
def get_profile_ids(self, since=None): ids = [] if since: try: profs = self.agent.agent_profile_set.filter(updated__gte=since) except ValidationError: since_i = int(float(since)) since_dt = datetime.datetime.fromtimestamp(since_i) profs = self.agent.agent_profile_set.filter(update__gte=since_dt) except: err_msg = 'There are no profiles associated with the id: %s' % profileId log_message(self.log_dict, err_msg, __name__, self.get_profile_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) ids = [p.profileId for p in profs] else: ids = self.agent.agent_profile_set.values_list('profileId', flat=True) return ids
def __init__(self, data, auth, log_dict=None): self.log_dict = log_dict unallowed_fields = ['id', 'stored', 'authority'] # Raise error if an unallowed field is present for field in unallowed_fields: if field in data: err_msg = "%s is not allowed in a SubStatement." % field log_message(self.log_dict, err_msg, __name__, self.__init__.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) # Make sure object isn't another substatement if 'objectType' in data['object']: if data['object']['objectType'].lower() == 'substatement': err_msg = "SubStatements cannot be nested inside of other SubStatements" log_message(self.log_dict, err_msg, __name__, self.__init__.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) Statement.__init__(self, data, auth)
def populateContext(self, stmt_data): instructor = False team = False revision = True platform = True contextExts = {} log_message(self.log_dict, "Populating context", __name__, self.populateContext.__name__) if 'registration' in stmt_data['context']: self.validate_incoming_uuid(stmt_data['context']['registration']) if 'instructor' in stmt_data['context']: stmt_data['context']['instructor'] = Agent(initial=stmt_data['context']['instructor'], create=True, log_dict=self.log_dict, define=self.define).agent # If there is an actor or object is a group in the stmt then remove the team if 'actor' in stmt_data or 'group' == stmt_data['object']['objectType'].lower(): if 'team' in stmt_data['context']: del stmt_data['context']['team'] # Revision and platform not applicable if object is agent if 'objectType' in stmt_data['object'] and ('agent' == stmt_data['object']['objectType'].lower() or 'group' == stmt_data['object']['objectType'].lower()): del stmt_data['context']['revision'] del stmt_data['context']['platform'] # Set extensions if 'extensions' in stmt_data['context']: context = dict((key, value) for (key, value) in stmt_data['context'].items() if not key == 'extensions') contextExts = stmt_data['context']['extensions'] else: context = stmt_data['context'] # Save context stmt if one if 'statement' in context: stmt_ref = models.StatementRef(ref_id=context['statement']['id']) stmt_ref.save() context['cntx_statement'] = stmt_ref del context['statement'] return self.saveContextToDB(context, contextExts)
def save_lang_map(self, lang_map, verb): # If verb is model object but not saved yet if not verb.id: try: verb.full_clean() verb.save() except ValidationError as e: err_msg = e.messages[0] log_message(self.log_dict, err_msg, __name__, self.save_lang_map.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) k = lang_map[0] v = lang_map[1] # Save lang map language_map = models.LanguageMap(key = k, value = v, content_object=verb) language_map.save() return language_map
def saveResultToDB(self, result, resultExts): # Save the result with all of the args sc = result.pop('score', None) rslt = models.result(content_object=self.model_object, **result) rslt.save() if sc: sc.result = rslt sc.save() #If it has extensions, save them all if resultExts: for k, v in resultExts.items(): if not uri.validate_uri(k): err_msg = "Extension ID %s is not a valid URI" % k log_message(self.log_dict, err_msg, __name__, self.saveResultToDB.__name__, True) update_parent_log_status(self.log_dict, 400) raise exceptions.ParamError(err_msg) resExt = models.extensions(key=k, value=v, content_object=rslt) resExt.save() log_message(self.log_dict, "Result saved to database", __name__, self.saveResultToDB.__name__) return rslt
def get_profile_ids(self, since=None): ids = [] if since: try: # this expects iso6801 date/time format "2013-02-15T12:00:00+00:00" profs = self.agent.agent_profile_set.filter(updated__gte=since) except ValidationError: from django.utils import timezone since_i = int(float(since))# this handles timestamp like str(time.time()) since_dt = datetime.datetime.fromtimestamp(since_i).replace(tzinfo=timezone.get_default_timezone()) profs = self.agent.agent_profile_set.filter(updated__gte=since_dt) except: err_msg = 'There are no profiles associated with the id: %s' % profileId log_message(self.log_dict, err_msg, __name__, self.get_profile_ids.__name__, True) update_parent_log_status(self.log_dict, 404) raise IDNotFoundError(err_msg) ids = [p.profileId for p in profs] else: ids = self.agent.agent_profile_set.values_list('profileId', flat=True) return ids
def voidStatement(self,stmt_id): str_id = str(stmt_id) log_message(self.log_dict, "Voiding Statement with ID %s" % str_id, __name__, self.voidStatement.__name__) # Retrieve statement, check if the verb is 'voided' - if not then set the voided flag to true else return error # since you cannot unvoid a statement and should just reissue the statement under a new ID. try: stmt = models.statement.objects.get(statement_id=stmt_id) except Exception: err_msg = "Statement with ID %s does not exist" % str(stmt_id) log_message(self.log_dict, err_msg, __name__, self.voidStatement.__name__, True) update_parent_log_status(self.log_dict, 404) raise exceptions.IDNotFoundError(err_msg) # Check if it is already voided if not stmt.voided: stmt.voided = True stmt.save() # Create statement ref stmt_ref = models.StatementRef(ref_id=stmt_id) stmt_ref.save() return stmt_ref else: err_msg = "Statement with ID: %s is already voided, cannot unvoid. Please re-issue the statement under a new ID." % str_id log_message(self.log_dict, err_msg, __name__, self.voidStatement.__name__, True) update_parent_log_status(self.log_dict, 403) raise exceptions.Forbidden(err_msg)