Position.py 5.42 KB
#! /usr/bin/python
# -*- coding: utf-8 -*-

from importer.Phrase import phrase_from_tree
from syntax.models import SyntacticFunction, Control
import syntax.models

class Function:

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

    @classmethod
    def fromTree(cls, tree):
        value = tree._children[0]._attrs['value']
        return cls(value)

# @TODO: dwa rodzaje kontroli        
class Control:

    def __init__(self, function):
        self._function = function
        
        
class Position:

    def __init__(self, position_id, function, controls, phrases, phrase_ids):
        self._id = position_id
        self._function = function
        self._control = controls 
        self._phrases = phrases
        self._phrase_ids = phrase_ids
        self._db_id = None

    @classmethod
    def fromTree(cls, tree):
        function = None
        controls = None
        phrases = []
        phrase_ids = {}

        position_id = []
        for subtree in tree._children:
            if subtree._attrs['name'] == 'function':
                function = Function.fromTree(subtree)
            elif subtree._attrs['name'] == 'control':
                controls = [Control(c._attrs['value']) for c in subtree._children[0]._children]
            elif subtree._attrs['name'] == 'phrases':
                for phrase_tree in subtree._children[0]._children:
                    phrase = phrase_from_tree(phrase_tree)
                    phrases.append(phrase)
                    if phrase.getId() is not None:
                        phrase_ids[phrase.getId()] = phrase
                        position_id.append(int(phrase.getId().split('-')[0].split('.')[-1]))

        position_id.sort()
        position_id = tuple(position_id)
        result = cls(position_id, function, controls, phrases, phrase_ids)
        for phrase in phrases:
            phrase._position = result
        return result

    def store(self, schema, stored_positions):
        # self._id is None for parts of lex atr
        if self._id is not None and self._id in stored_positions:
            position = syntax.models.Position.objects.get(id = stored_positions[self._id])
            self._db_id = position.id
            schema.positions.add(position)
        else:
            if self._function is not None:
                function = SyntacticFunction.objects.get(name=self._function._value)
            else:
                function = None
            control = None
            pred_control = None
            if self._control is not None:
                for c in self._control:
                    if c._function[:4] == 'pred':
                        if pred_control is None:
                            pred_control = syntax.models.PredicativeControl.objects.get(name=c._function)
                        else:
                            raise(DoublePredControlError)
                    else:
                        if control is None:
                            control = syntax.models.Control.objects.get(name=c._function)
                        else:
                            raise(DoubleControlError)

            position = schema.positions.create(function=function,
                                               control=control,
                                               pred_control=pred_control)
            self._db_id = position.id
            for phrase in self._phrases:
                phrase.store(position)
            if self._id is not None:
                stored_positions[self._id] = position.id
    
    def getPhraseIds(self):
        return self._phrase_ids

    def __unicode__(self):
        if self._function is None:
            return '[' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + ']'
        else:
            return self._function._value + '([' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + '])'

    def toUnicode(self, function, phrases=None):
        pre = ''
        post = ''
        if self._control is not None:
            for control in self._control:
                pre += control._function + '('
                post += ')'
        if phrases is None:
            if self._function is None or self._function._value == 'obj':
                return pre + '[' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + ']' + post
            elif self._function._value == 'subj':
                return pre + 'subj([' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + '])' + post
            elif self._function._value == 'obj':
                return pre + 'obj([' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + '])' + post
            elif self._function._value == 'head':
                return pre + 'head([' + ','.join([phrase.toUnicode(self._function) for phrase in self._phrases]) + '])' + post
        else:
            temp = []
            for phrase in self._phrases:
                if phrase in phrases:
                    temp.append(phrase.toUnicode(self._function))
            if self._function is None:
                return pre + '[' + ','.join(temp) + ']' + post
            elif self._function._value == 'subj':
                return pre + 'subj([' + ','.join(temp) + '])' + post   
            elif self._function._value == 'obj':
                return pre + 'obj([' + ','.join(temp) + '])' + post
            elif self._function._value == 'head':
                return pre + 'head([' + ','.join(temp) + '])' + post