Schema.py 6.85 KB
#! /usr/bin/python
# -*- coding: utf-8 -*-

from importer.Position import Position
from syntax.models import SchemaOpinion, Aspect, InherentSie, Negativity, Predicativity, Subentry

class ControlError(Exception):
    pass

class Characteristic:

    def __init__(self, name, value):
        self._name = name
        self._value = value

    @classmethod
    def fromTree(cls, tree):
        name = tree._attrs['name']
        if name == 'text_rep':
            value = tree._children[0]._content
        elif len(tree._children) == 0:
            value = None
        else:
            value = tree._children[0]._attrs['value']
        return cls(name, value)


class SchemaCharacteristic:
    def __init__(self, opinion, aspect, inherent_sie, negativity, predicativity):
        self._opinion = opinion
        self._aspect = aspect
        self._inherent_sie = inherent_sie
        self._negativity = negativity
        self._predicativity = predicativity

    @classmethod
    def fromCharacteristics(cls, characteristics):
        data = {
            "aspect": None,
            "inherent_sie": None,
            "negativity": None,
            "predicativity": None,
            "opinion": None
        }
        for characteristic in characteristics:
            data[characteristic._name] = characteristic._value
        return cls(data["opinion"], data["aspect"], data["inherent_sie"], data["negativity"], data["predicativity"])


def analyze_tree(tree):
    positions = []
    phrases = {}

    for position_tree in tree._children[0]._children:
        position = Position.fromTree(position_tree)
        positions.append(position)
        phrases.update(position.getPhraseIds())

    return positions, phrases


class Schema:

    def __init__(self, id, characteristics, positions, phrases):
        self._id = id
        self._characteristics = characteristics
        self._positions = positions
        self._phrases = phrases
        self._db_id = None

    @classmethod
    def fromTree(cls, schema_tree):
        characteristics = []
        positions = []
        phrases = {}
        id = schema_tree._attrs['xml:id']
        for subtree in schema_tree._children:
            if subtree._attrs['name'] != 'positions':
                characteristics.append(Characteristic.fromTree(subtree))
            else:
                positions, phrases = analyze_tree(subtree)
        result = cls(id, characteristics, positions, phrases)
        for position in positions:
            position._schema = result
        return result

    def getPhraseIds(self):
        return self._phrases

    def hasInherentSie(self):
        for characteristic in self._characteristics:
            if characteristic._name == 'inherent_sie':
                if characteristic._value == 'true':
                    return True
                else:
                    return False
        return False

    def getAspect(self):
        for characteristic in self._characteristics:
            if characteristic._name == 'aspect':
                return characteristic._value
        return None

    def getSubentry(self, entry):
        se = SchemaCharacteristic.fromCharacteristics(self._characteristics)
        if se._opinion is not None:
            opinion = SchemaOpinion.objects.get(key=se._opinion)
        else:
            opinion = None
        if se._aspect is not None:
            aspect = Aspect.objects.get(name=se._aspect)
        else:
            aspect = None
        if se._inherent_sie is not None:
            inherent_sie = InherentSie.objects.get(name=se._inherent_sie)
        else:
            inherent_sie = None
        if se._negativity is not None:
            negativity = Negativity.objects.get(name=se._negativity)
        else:
            negativity = None
        if se._predicativity is not None:
            predicativity = Predicativity.objects.get(name=se._predicativity)
        else:
            predicativity = None
        subentry = Subentry.objects.get(entry=entry,
                                        aspect=aspect,
                                        inherent_sie=inherent_sie,
                                        negativity=negativity,
                                        predicativity=predicativity)
        return subentry

    def getController(self, control):
        assert(control in ('controllee', 'pred_controllee'))
        control2 = 'controller'
        if control == 'pred_controllee':
            control2 = 'pred_' + control2
        controllers = []
        for position in self._positions:
            if position._control:
                for c in position._control:
                    if c._function == control2:
                        controllers.append(position)
        if len(controllers) != 1:
            raise ControlError('incorrect number of controllers for {}: {}'.format(control, len(controllers)))
        return controllers[0]

    def store(self, entry, stored_positions):
        se = SchemaCharacteristic.fromCharacteristics(self._characteristics)
        # @TODO: czy opinia jest w odpowiednim miejscu xml-a?
        if se._opinion is not None:
            opinion = SchemaOpinion.objects.get(key=se._opinion)
        else:
            opinion = None
        if se._aspect is not None:
            aspect = Aspect.objects.get(name=se._aspect)
        else:
            aspect = None
        if se._inherent_sie is not None:
            inherent_sie = InherentSie.objects.get(name=se._inherent_sie)
        else:
            inherent_sie = None
        if se._negativity is not None:
            negativity = Negativity.objects.get(name=se._negativity)
        else:
            negativity = None
        if se._predicativity is not None:
            predicativity = Predicativity.objects.get(name=se._predicativity)
        else:
            predicativity = None
        subentry, _ = Subentry.objects.get_or_create(entry=entry,
                                                     aspect=aspect,
                                                     inherent_sie=inherent_sie,
                                                     negativity=negativity,
                                                     predicativity=predicativity)

        schema = subentry.schemata.create(opinion=opinion,
                                          phraseologic=False,
                                          positions_count=len(self._positions))
        subentry.schemata_count = subentry.schemata_count + 1
        subentry.save()
        self._db_id = schema.id

        schema_positions = set()
        for position in self._positions:
            position.store(schema, stored_positions, schema_positions, negativity)


    def __unicode__(self):
        inherent_sie = []
        if self.hasInherentSie():
            inherent_sie = ['[sie]']
        return '[' + ','.join(inherent_sie + [unicode(position) for position in self._positions if position._function is None or position._function._value != 'head']) + ']'