Exemplo n.º 1
0
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
        )),
    })
Exemplo n.º 2
0
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
    )
Exemplo n.º 3
0
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,
    })
Exemplo n.º 4
0
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),
        ),
    })
Exemplo n.º 5
0
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
    )
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
        )
Exemplo n.º 8
0
    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
        )
Exemplo n.º 9
0
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
    )
Exemplo n.º 10
0
    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()
Exemplo n.º 11
0
 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
Exemplo n.º 12
0
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
    )
Exemplo n.º 13
0
 def get (self, request):
     return JsonResponse(
         [model.to_dict() for model in session.query(self.Model)],
         encoder = ModelEncoder,
         safe = False
     )
Exemplo n.º 14
0
 def model (self):
     if not hasattr(self, '_model'):
         self._model = session.query(self.Model).get(self._id)
     return self._model