def edit_character (request, id): character = session.query(Character).get(int(id)) response = storyteller_or_editing_owner(request, character, 'edit') if response: return response character_traits = set(chain( character.attributes, character.skills, character.skill_specialties, character.powers, )) traits = set(chain( (char_power.trait.power_group for char_power in character.powers), (cht.trait for cht in character_traits), )) if character.creature_type : traits.add(character.creature_type) if character.genealogy : traits.add(character.genealogy) if character.affiliation : traits.add(character.affiliation) if character.subgroup : traits.add(character.subgroup) return render(request, 'characters/character_edit.html', { 'character': character, 'models': list(chain( [character.user, character.chronicle], session.query(AttributeType), session.query(SkillType), traits, character_traits )), })
def submit_character (request, id): character = session.query(Character).get(int(id)) # Must own the character to submit it. if character.user_id != request.user.id: return HttpResponseUnauthorized( "Must be the character's owner to submit.", content_type = 'application/json' ) # Character must be in 'EDITING' mode to submit it. if character.status != Character.Status.EDITING: return HttpResponseForbidden( "Character must have a status of 'EDITING' to submit.", content_type = 'application/json' ) character.status = Character.Status.SUBMITTED character.date_submitted = datetime.now() return JsonResponse( character.to_dict(), safe = False, encoder = ModelEncoder )
def show_character (request, id): character = session.query(Character).get(int(id)) response = storyteller_or_owner(request, character, 'view') if response: return response return render(request, 'characters/show_character.html', { 'character': character, })
def character_list (request): characters = session.query(Character) return render(request, 'characters/character_list.html', { 'characters': characters, 'records': chain( set(character.creature_type for character in characters), set(character.genealogy for character in characters), set(character.affiliation for character in characters), set(character.subgroup for character in characters), ), })
def available_traits (request, id): character = session.query(Character).get(int(id)) response = storyteller_or_editing_owner(request, character, 'edit') if response: return response chronicle_ids = [c.id for c in character.chronicle.all_chronicles] availabilities = calculate_availabilities( character, session.query(Trait).filter( Trait.chronicle_id.in_(chronicle_ids) ) ) return JsonResponse( { 'availabilities': availabilities, }, encoder = ModelEncoder )
def recalculate_access (self, trait): affected_traits = set() chronicle_ids = [c.id for c in self.character.chronicle.all_chronicles] # Rule: character-has-trait for rule in session.query(CharacterHasTrait).filter( CharacterHasTrait.chronicle_id.in_(chronicle_ids), CharacterHasTrait.other_trait_id == trait.id ): affected_traits.add(rule.trait) # Rule: character-does-not-have-trait for rule in session.query(CharacterDoesNotHaveTrait).filter( CharacterDoesNotHaveTrait.chronicle_id.in_(chronicle_ids), CharacterDoesNotHaveTrait.other_trait_id == trait.id ): affected_traits.add(rule.trait) # Recalculate availabilities for affected traits. availabilities = calculate_availabilities(self.character, affected_traits) return availabilities
def patch (self, request, character_trait_id): character_trait = session.query(CharacterTrait).get(character_trait_id) trait = character_trait.trait for field, value in request.data.items(): setattr(character_trait, field, value) self.character.date_last_edited = datetime.now() session.commit() return JsonResponse( { 'character': self.character, 'model': character_trait, 'availabilities': self.recalculate_access(trait), }, encoder = ModelEncoder )
def delete (self, request, character_trait_id): character_trait = session.query(CharacterTrait).get(character_trait_id) trait = character_trait.trait self.character.date_last_edited = datetime.now() character_trait_attrs = character_trait.to_dict() # Delete the model and commit the change so that the deletion propagates # to any relationship collections that might reference this model. session.delete(character_trait) session.commit() return JsonResponse( { 'character': self.character, 'model': character_trait_attrs, 'availabilities': self.recalculate_access(trait), }, encoder = ModelEncoder )
def enable_character (request, id): character = session.query(Character).get(int(id)) if character.enabled is False: return HttpResponseForbidden( 'Character already enabled.', content_type = 'application/json' ) response = storyteller_or_editing_owner(request, character, 'enable', content_type = 'application/json') if response: return response character.enabled = True return JsonResponse( character.to_dict(), safe = False, encoder = ModelEncoder )
def handle (self, *args, **options): session.bind.echo = options['debug'] filepath = options['filepath'] model_info = {} with open(filepath, 'r') as data_file: content = ''.join(line.split('//')[0] for line in data_file) full_data = json.loads(content, object_pairs_hook = OrderedDict) for data_block in full_data: Model = get_model(data_block['application'], data_block['Model']) unique_indexes = {} # Prepare indeces of unique-constraints. for table in Model.__mapper__.tables: for constraint in table.constraints: if isinstance(constraint, UniqueConstraint): unique_indexes[constraint] = set() for datum in data_block['data']: datum = prepare(session, Model, datum) update_target = None for constraint, index in unique_indexes.items(): # Look for item in index. key = key_from_constraint(constraint, datum) if key in index: self.stderr.write("ERROR: Second import of '{}' " + "record with unique constraint:".format(Model)) for column, value in zip(constraint.columns, key): self.stderr.write(" {} = {}".format( column, value)) return # Look for item in database. target = session.query(Model).filter( *filter_from_constraint(constraint, datum)).scalar() if update_target and update_target != target: self.stderr.write('ERROR: Second unique-index match does not yield the same model.') self.stderr.write(" Model: {}".format(Model)) self.stderr.write(" constraint: {}".format(constraint)) self.stderr.write(" data: {}".format(datum)) return update_target = target if update_target: updated = False for field, value in datum.items(): if getattr(update_target, field) != value: updated = True setattr(update_target, field, value) if updated: self.stdout.write("updating {}".format(update_target)) else: model = Model(**datum) session.add(model) self.stdout.write("adding {}".format(model)) session.flush() session.commit()
def character (self): if hasattr(self, '_character') and self._character and self._character.id is self._id: return self._character character = session.query(Character).get(self._id) self._character = character return character
def update_character_summary (request, id): character = session.query(Character).get(int(id)) response = storyteller_or_editing_owner(request, character, 'edit') if response: return response chronicle_ids = [c.id for c in character.chronicle.all_chronicles] affected_traits = set() data = json.loads(request.body.decode('ascii')) for key, value in data.items(): column = Character.__table__.columns[key] if len(column.foreign_keys) == 0: old_value = getattr(character, key) new_value = value # TODO (Emery): Check rules for character_summary attributes. (Name, last_edited, ...) else: TraitType = get_referenced_model(column) key = key[:-3] # assumes key in format "<key>_id" old_value = getattr(character, key) new_value = None if value is None else session.query(TraitType).get(value) if old_value: changing_trait_ids = (old_value.id,) else: changing_trait_ids = tuple() if new_value: changing_trait_ids += (new_value.id,) # Rule: character-has-trait for rule in session.query(CharacterHasTrait).filter( CharacterHasTrait.chronicle_id.in_(chronicle_ids), CharacterHasTrait.other_trait_id.in_(changing_trait_ids) ): affected_traits.add(rule.trait) # Rule: character-does-not-have-trait for rule in session.query(CharacterDoesNotHaveTrait).filter( CharacterDoesNotHaveTrait.chronicle_id.in_(chronicle_ids), CharacterDoesNotHaveTrait.other_trait_id.in_(changing_trait_ids) ): affected_traits.add(rule.trait) # Set attribute on character. setattr(character, key, new_value) session.flush() # Recalculate availabilities for affected traits. availabilities = calculate_availabilities(character, affected_traits) return JsonResponse( { 'character': character, 'availabilities': availabilities, }, encoder = ModelEncoder )
def get (self, request): return JsonResponse( [model.to_dict() for model in session.query(self.Model)], encoder = ModelEncoder, safe = False )
def model (self): if not hasattr(self, '_model'): self._model = session.query(self.Model).get(self._id) return self._model