Commit 5721a00d579a789a83ed001c7638aab38b80e3ab

Authored by Katarzyna Krasnowska
1 parent f1bc2874

updated fiter forms, refactored Phrase.py in importer, added lex lemmata and modifications to DB

common/static/common/css/common.css
... ... @@ -33,6 +33,10 @@ legend {
33 33 z-index: 2000;
34 34 }
35 35  
  36 +.collapse-button {
  37 + float: right;
  38 +}
  39 +
36 40 .remove-button {
37 41 float: right;
38 42 }
... ... @@ -104,6 +108,16 @@ legend {
104 108 background-color: #f6ce95;
105 109 }
106 110  
  111 +.to-collapse {
  112 + background-color: white;
  113 +}
  114 +
  115 +
  116 +.negated {
  117 + background-image: url("/static/common/img/negated.png");
  118 + background-repeat: repeat;
  119 +}
  120 +
107 121 .form-group {
108 122 margin-bottom: 2px;
109 123  
... ...
common/static/common/img/negated.png 0 → 100644

202 Bytes

entries/autocompletes.py
1 1 from django.http import JsonResponse
2 2  
3   -from syntax.models_phrase import PhraseType, FixedAttributes
  3 +from syntax.models_phrase import PhraseType, FixedAttributes, Lemma
4 4 from connections.models import Entry
5 5 from meanings.models import LexicalUnit
6 6  
... ... @@ -9,6 +9,7 @@ from entries.form_fields.query_managers import RegexQueryManager
9 9 lookups = {
10 10 'phrasetype' : (PhraseType, 'text_rep'),
11 11 'lemma' : (Entry, 'name'),
  12 + 'lex_lemma' : (Lemma, 'name'),
12 13 'fixed' : (FixedAttributes, 'text'),
13 14 'lu' : (LexicalUnit, 'text_rep')
14 15 }
... ...
entries/form_fields/generic_fields.py
... ... @@ -126,7 +126,7 @@ class ModelChoiceFilter(forms.ModelChoiceField, SelectLayoutField):
126 126 else:
127 127 return self.key(obj)
128 128  
129   -
  129 +'''
130 130 # MultiValueField is an abstract class, must be subclassed and implement compress
131 131 class ComboFilter(forms.MultiValueField, LayoutField):
132 132  
... ... @@ -165,6 +165,7 @@ class ComboFilter(forms.MultiValueField, LayoutField):
165 165  
166 166 def compress(self, data_list):
167 167 return data_list
  168 +'''
168 169  
169 170  
170 171 class OperatorField(forms.ChoiceField, RadiosLayoutField):
... ... @@ -187,8 +188,12 @@ class OperatorField(forms.ChoiceField, RadiosLayoutField):
187 188  
188 189 class SwitchField(forms.BooleanField, LayoutField):
189 190  
190   - def __init__(self, label):
  191 + def __init__(self, label, css_class=None):
191 192 super().__init__(label=label, required=False)
  193 + self.css_class = css_class
192 194  
193 195 def layout(self, x, **kwargs):
194   - return layout.Field(x, wrapper_class='custom-switch float-right font-weight-bold', **kwargs)
  196 + wrapper_class = 'custom-switch float-right font-weight-bold'
  197 + if self.css_class:
  198 + wrapper_class += ' ' + self.css_class
  199 + return layout.Field(x, wrapper_class=wrapper_class, **kwargs)
... ...
entries/form_fields/specialised_fields.py
... ... @@ -16,7 +16,7 @@ from .generic_fields import (
16 16 RadiosLayoutField,
17 17 SingleRegexFilter,
18 18 ModelChoiceFilter,
19   - ComboFilter,
  19 + #ComboFilter,
20 20 )
21 21  
22 22 from .query_managers import (
... ... @@ -26,13 +26,13 @@ from .query_managers import (
26 26  
27 27 from entries.polish_strings import PHRASE_TYPE
28 28  
29   -# TODO what else, apart from comprepnp, can’t be a lex?
30 29 class PhraseTypeFilter(ModelChoiceFilter):
31 30  
32 31 def __init__(self, lex=False, **kwargs):
  32 +
33 33 super().__init__(
34 34 label=('Typ frazeologizmu' if lex else 'Typ frazy'),
35   - queryset=(PhraseTypeModel.objects.exclude(name__in=('lex', 'comprepnp')) if lex else PhraseTypeModel.objects.all()),
  35 + queryset=PhraseTypeModel.objects.filter(main_phrase_types__lex_phrases__isnull=(not lex)).distinct(),
36 36 key='name',
37 37 #lookup='phrase_types__main_type',
38 38 # this field is not used for filtering, only for choosing subform type
... ... @@ -46,6 +46,7 @@ class PhraseTypeFilter(ModelChoiceFilter):
46 46 pt = obj.name
47 47 return '{} ({})'.format(pt, PHRASE_TYPE.get(pt, '...'))
48 48  
  49 +'''
49 50 class ArgumentFilter(ComboFilter):
50 51  
51 52 def __init__(self):
... ... @@ -71,7 +72,9 @@ class ArgumentFilter(ComboFilter):
71 72 ],
72 73 negation_field=True,
73 74 )
  75 +'''
74 76  
  77 +'''
75 78 class PredefinedPreferenceFilter(ComboFilter):
76 79 def __init__(self):
77 80 super().__init__(
... ... @@ -89,7 +92,9 @@ class PredefinedPreferenceFilter(ComboFilter):
89 92 ],
90 93 negation_field=True,
91 94 )
  95 +'''
92 96  
  97 +'''
93 98 class RelationalPreferenceFilter(ComboFilter):
94 99 def __init__(self):
95 100 super().__init__(
... ... @@ -120,6 +125,7 @@ class RelationalPreferenceFilter(ComboFilter):
120 125 ),
121 126 ]
122 127 )
  128 +'''
123 129  
124 130 '''
125 131 class SynsetPreferenceFilter(ComboFilter):
... ...
entries/forms.py
... ... @@ -13,12 +13,12 @@ from syntax.models import (
13 13 Schema, SchemaOpinion, InherentSie, Negativity, Predicativity, Aspect,
14 14 Position, SyntacticFunction, Control, PredicativeControl,
15 15 )
16   -from syntax.models_phrase import PhraseType, EmptyAttributes
  16 +from syntax.models_phrase import PhraseType, EmptyAttributes, LemmaOperator, LemmaCooccur, Lemma
17 17  
18 18 from semantics.models import (
19 19 Frame, FrameOpinion,
20 20 Argument, SemanticRole, RoleAttribute,
21   - PredefinedSelectionalPreference, RelationalSelectionalPreference,
  21 + PredefinedSelectionalPreference, RelationalSelectionalPreference, SelectionalPreferenceRelation,
22 22 )
23 23  
24 24 from meanings.models import Synset
... ... @@ -36,10 +36,6 @@ from .form_fields.generic_fields import (
36 36 from .form_fields.specialised_fields import (
37 37 PhraseoFilter,
38 38 PhraseTypeFilter,
39   - ArgumentFilter,
40   - PredefinedPreferenceFilter,
41   - RelationalPreferenceFilter,
42   - #SynsetPreferenceFilter,
43 39 )
44 40  
45 41 from .form_fields.query_managers import SingleValueQueryManager
... ... @@ -50,7 +46,6 @@ from importer.PhraseAttributes import attrs_helpers
50 46 from . import polish_strings
51 47  
52 48  
53   -# TODO get_queries probably needs refactoring now that QueryForm is subclassed
54 49 class QueryForm(forms.Form):
55 50  
56 51 def __init__(self, *args, **kwargs):
... ... @@ -63,24 +58,25 @@ class QueryForm(forms.Form):
63 58  
64 59 @staticmethod
65 60 def get_child_form_prefix(child_form):
  61 + print(type(child_form))
66 62 raise NotImplementedError
67 63  
68 64 def get_queries(self):
69 65 queries = []
70 66 for key, value in self.cleaned_data.items():
71 67 #print('========', key, value)
72   - if value and not key.startswith('operator') and not key.startswith('filter'):
73   - #if filter_type is not None and key.split('_')[0] != filter_type:
74   - # continue
  68 + if value and not key.startswith('filter') and not key.startswith('negate'):
75 69 form_field = self.fields[key]
76   - operator_key = 'operator_{}'.format(key)
77   - # TODO conjunction variable is only needed if filter_type is None?
78   - conjunction = self.cleaned_data.get(operator_key)
79   - if conjunction is None:
80   - conjunction = form_field.query_manager.default_conjunction
  70 + conjunction = form_field.query_manager.default_conjunction
81 71 queries += form_field.query_manager.make_queries(value, conjunction)
82 72 return queries
83 73  
  74 + def is_negated(self):
  75 + for key, value in self.cleaned_data.items():
  76 + if key.startswith('negate') and value:
  77 + return True
  78 + return False
  79 +
84 80 @classmethod
85 81 def make_field(cls, field_name):
86 82 field_object = cls.base_fields[field_name]
... ... @@ -101,37 +97,11 @@ def and_or_form_creator(button_label, field_name=None, data_add=None, *args, **k
101 97 add_button = bootstrap.StrictButton('+ {}'.format(button_label), css_class='add-button btn-sm btn-success', data_add=data_add, *args, **kwargs)
102 98 return [
103 99 #layout.HTML('<div class="and-or-forms py-1 pl-1 mb-1 border-top border-bottom border-danger" data-formtype="{}">'.format(data_add)),
104   - layout.HTML('<div class="and-or-forms py-1 pl-1 mb-1" data-formtype="{}">'.format(data_add)),
  100 + layout.HTML('<div class="and-or-forms py-1 pl-1" data-formtype="{}">'.format(data_add)),
105 101 add_button,
106 102 or_button(button_label),
107 103 layout.HTML('</div>'),
108 104 ]
109   -
110   -
111   -'''
112   -class MainEntryForm(QueryForm):
113   -
114   - def __init__(self, *args, **kwargs):
115   - super().__init__(*args, **kwargs)
116   - self.helper.form_method = 'get'
117   - # TODO remove if this form is to be used with different views
118   - self.helper.form_action = 'entries:get_entries'
119   - self.helper.form_id = 'main-form'
120   - self.helper.attrs = { 'data_formtype' : 'entry-main' }
121   - self.model_class = Entry
122   -
123   - components = []
124   - components.append(layout.Submit('main-submit', 'Filtruj'))
125   - self.helper.layout = layout.Layout(*components)
126   -
127   - @staticmethod
128   - def get_child_form_prefix(child_form):
129   - if child_form.model_class == Schema:
130   - return 'subentries__schemata__in'
131   - if child_form.model_class == Frame:
132   - return 'subentries__schema_hooks__argument_connections__argument__frame__in'
133   - raise KeyError(type(child_form))
134   -'''
135 105  
136 106 class EntryForm(QueryForm):
137 107  
... ... @@ -169,7 +139,7 @@ class EntryForm(QueryForm):
169 139 ]
170 140  
171 141 components = [
172   - layout.Fieldset('Własności haseł', *entry_components),
  142 + #layout.Fieldset('Własności haseł', *entry_components),
173 143 layout.Fieldset('Własności składniowe', *schema_components),
174 144 layout.Fieldset('Własności semantyczne', *frame_components),
175 145 layout.Submit('main-submit', 'Filtruj'),
... ... @@ -227,6 +197,11 @@ class EntryForm(QueryForm):
227 197 # and retrieving the field values in views
228 198 class FormFactory(object):
229 199  
  200 + form_class_name = None
  201 + form_model = None
  202 + form_formtype = None
  203 + form_header = None
  204 +
230 205 @staticmethod
231 206 def unique_number():
232 207 return randint(1000, 12345678)
... ... @@ -242,53 +217,79 @@ class FormFactory(object):
242 217 @staticmethod
243 218 def make_layout(title, components):
244 219 return layout.Layout(layout.Fieldset(
245   - '{} <button class="btn remove-button btn-sm btn-warning" type="button">Usuń</button>'.format(title),
  220 + '{} <span class="collapsed-info"></span> <button class="btn collapse-button btn-sm btn-secondary" data-collapsed="false" type="button">zwiń</button><button class="btn remove-button btn-sm btn-warning" type="button">Usuń</button>'.format(title),
246 221 *components
247 222 ))
248 223  
249 224 @classmethod
250 225 def get_form(cls, unique_number=None, *args, **kwargs):
251 226 unique_number = cls.unique_number() if unique_number is None else unique_number
252   - form_class = cls.make_form_class(n=unique_number)
253   - for field_name, field_maker in cls.field_makers:
254   - form_class.base_fields[FormFactory.unique_name(field_name, unique_number)] = field_maker()
  227 +
  228 + assert(cls.form_class_name is not None)
  229 + assert(cls.form_model is not None)
  230 + assert(cls.form_formtype is not None)
  231 + assert(cls.form_header is not None)
  232 +
  233 + def form_init(self, *args, **kwargs):
  234 + super(type(self), self).__init__(*args, **kwargs)
  235 + self.helper.attrs = cls.make_helper_attrs(cls.form_formtype, unique_number)
  236 + self.model_class = cls.form_model
  237 +
  238 + components = [self.make_field(cls.unique_name('negated', unique_number))]
  239 + for field_name, field_maker, component_maker in cls.field_makers:
  240 + if component_maker:
  241 + component = component_maker(unique_number)
  242 + else:
  243 + component = self.make_field(cls.unique_name(field_name, unique_number))
  244 + if type(component) == list:
  245 + components += component
  246 + else:
  247 + components.append(component)
  248 + self.helper.layout = cls.make_layout(cls.form_header, components)
  249 +
  250 + form_class = type(cls.form_class_name, (QueryForm,), {
  251 + '__init__' : form_init,
  252 + 'get_child_form_prefix' : lambda self, child_form: cls.get_child_form_prefix(child_form),
  253 + })
  254 +
  255 + form_class.base_fields[cls.unique_name('negated', unique_number)] = SwitchField('Zaneguj', css_class='negate-switch')
  256 + for field_name, field_maker, layout_maker in cls.field_makers:
  257 + if field_name is not None:
  258 + form_class.base_fields[FormFactory.unique_name(field_name, unique_number)] = field_maker()
255 259 return form_class(*args, **kwargs)
256   -
257   - # n – unique number for this form used for creating globally unique field names
258   - @classmethod
259   - def make_form_class(cls, n):
  260 + @staticmethod
  261 + def get_child_form_prefix():
260 262 raise NotImplementedError
261 263  
262 264 class SchemaFormFactory(FormFactory):
263 265  
  266 + form_class_name = 'SchemaForm'
  267 + form_model = Schema
  268 + form_formtype = 'schema'
  269 + form_header = 'Schemat składniowy'
  270 +
264 271 field_makers = (
265 272 (
266 273 'opinion',
267 274 lambda: ModelMultipleChoiceFilter(
268 275 label='Opinia o schemacie',
269   - queryset=SchemaOpinion.objects.all(),
  276 + queryset=SchemaOpinion.objects.filter(schemata__isnull=False).distinct(),
270 277 key='key',
271 278 human_values=polish_strings.SCHEMA_OPINION,
272 279 lookup='opinion',
273 280 #initial=SchemaOpinion.objects.filter(key__in=('col', 'vul')),
274   - )
  281 + ),
  282 + None,
275 283 ),
276   - #(
277   - # 'operator_opinion',
278   - # lambda: OperatorField()
279   - #),
280 284 (
281 285 'type',
282 286 lambda: MultipleChoiceFilter(
283 287 label='Typ',
284 288 choices=((False, 'zwykły'), (True, 'frazeologiczny'),),
285 289 lookup='phraseologic',
286   - )
  290 + ),
  291 + None,
287 292 ),
288   - #(
289   - # 'operator_type',
290   - # lambda: OperatorField()
291   - #),
292 293 (
293 294 'sie',
294 295 lambda: ModelMultipleChoiceFilter(
... ... @@ -297,13 +298,10 @@ class SchemaFormFactory(FormFactory):
297 298 key='name',
298 299 human_values=polish_strings.TRUE_FALSE_YES_NO,
299 300 lookup='inherent_sie',
300   - )
  301 + ),
  302 + None,
301 303 ),
302 304 #(
303   - # 'operator_sie',
304   - # lambda: OperatorField()
305   - #),
306   - #(
307 305 # 'neg',
308 306 # lambda: ModelMultipleChoiceFilter(
309 307 # label='Negatywność',
... ... @@ -317,10 +315,6 @@ class SchemaFormFactory(FormFactory):
317 315 # )
318 316 #),
319 317 #(
320   - # 'operator_neg',
321   - # lambda: OperatorField()
322   - #),
323   - #(
324 318 # 'pred',
325 319 # lambda: ModelMultipleChoiceFilter(
326 320 # label='Predykatywność',
... ... @@ -334,10 +328,6 @@ class SchemaFormFactory(FormFactory):
334 328 # )
335 329 #),
336 330 #(
337   - # 'operator_pred',
338   - # lambda: OperatorField()
339   - #),
340   - #(
341 331 # 'aspect',
342 332 # lambda: ModelMultipleChoiceFilter(
343 333 # label='Aspekt',
... ... @@ -350,10 +340,6 @@ class SchemaFormFactory(FormFactory):
350 340 # object_lookup=None,
351 341 # )
352 342 #),
353   - #(
354   - # 'operator_aspect',
355   - # lambda: OperatorField()
356   - #),
357 343 #phrase = RegexFilter(
358 344 #label='Fraza',
359 345 #max_length=200,
... ... @@ -378,40 +364,26 @@ class SchemaFormFactory(FormFactory):
378 364 # object_lookup='positions__phrases_count',
379 365 # )
380 366 #),
  367 + (
  368 + None, None,
  369 + lambda n: and_or_form_creator('Pozycja', data_add='position'),
  370 + ),
381 371 )
382 372  
383   - @classmethod
384   - def make_form_class(cls, n):
385   -
386   - class SchemaForm(QueryForm):
387   -
388   - def __init__(self, *args, **kwargs):
389   - super().__init__(*args, **kwargs)
390   - self.helper.attrs = cls.make_helper_attrs('schema', n)
391   - self.model_class = Schema
392   -
393   - components = [
394   - #remove_button('Usuń schemat'),
395   - self.make_field(cls.unique_name('opinion', n)),
396   - #self.make_field(cls.unique_name('operator_opinion', n)),
397   - self.make_field(cls.unique_name('type', n)),
398   - self.make_field(cls.unique_name('sie', n)),
399   - #self.make_field(cls.unique_name('phrase', n)),
400   - ] + \
401   - and_or_form_creator('Pozycja', data_add='position')
402   - self.helper.layout = cls.make_layout('Schemat składniowy', components)
403   -
404   - @staticmethod
405   - def get_child_form_prefix(child_form):
406   - if child_form.model_class == Position:
407   - return 'positions__in'
408   - raise KeyError(type(child_form))
409   -
410   - return SchemaForm
  373 + @staticmethod
  374 + def get_child_form_prefix(child_form):
  375 + if child_form.model_class == Position:
  376 + return 'positions__in'
  377 + raise KeyError(type(child_form))
411 378  
412 379  
413 380 class PositionFormFactory(FormFactory):
414 381  
  382 + form_class_name = 'PositionForm'
  383 + form_model = Position
  384 + form_formtype = 'position'
  385 + form_header = 'Pozycja schematu'
  386 +
415 387 field_makers = (
416 388 (
417 389 'gram_function',
... ... @@ -419,17 +391,19 @@ class PositionFormFactory(FormFactory):
419 391 label='Funkcja gramatyczna',
420 392 queryset=SyntacticFunction.objects.all(),
421 393 key='name',
  394 + human_values=polish_strings.GRAM_FUNCTION,
422 395 lookup='function',
423   - )
  396 + ), None,
424 397 ),
425 398 (
426 399 'control',
427 400 lambda: ModelMultipleChoiceFilter(
428 401 label='Kontrola',
429   - queryset=Control.objects.all(),
  402 + queryset=Control.objects.filter(positions__isnull=False).distinct(),
430 403 key='name',
  404 + human_values=polish_strings.CONTROL,
431 405 lookup='control',
432   - )
  406 + ), None,
433 407 ),
434 408 (
435 409 'pred_control',
... ... @@ -437,129 +411,128 @@ class PositionFormFactory(FormFactory):
437 411 label='Kontrola predykatywna',
438 412 queryset=PredicativeControl.objects.all(),
439 413 key='name',
  414 + human_values=polish_strings.CONTROL,
440 415 lookup='pred_control',
441   - )
  416 + ), None,
442 417 ),
443 418 (
444 419 'phrase_type',
445   - lambda: PhraseTypeFilter(help_text='Typ frazy występujący na pozycji.')
  420 + lambda: PhraseTypeFilter(help_text='Typ frazy występujący na pozycji.'),
  421 + lambda n: and_or_form_creator('Fraza', field_name=(FormFactory.unique_name('phrase_type', n)), data_prefix='phrase_'),
446 422 ),
447 423 )
448   -
449   - @classmethod
450   - def make_form_class(cls, n):
451   -
452   - class PositionForm(QueryForm):
453   -
454   - def __init__(self, *args, **kwargs):
455   - super().__init__(*args, **kwargs)
456   - self.helper.attrs = cls.make_helper_attrs('position', n)
457   - self.model_class = Position
458   -
459   - components = [
460   - self.make_field(cls.unique_name('gram_function', n)),
461   - self.make_field(cls.unique_name('control', n)),
462   - self.make_field(cls.unique_name('pred_control', n)),
463   - ] + \
464   - and_or_form_creator('Fraza', field_name=(cls.unique_name('phrase_type', n)), data_prefix='phrase_')
465   - self.helper.layout = cls.make_layout('Pozycja schematu', components)
466   -
467   - @staticmethod
468   - def get_child_form_prefix(child_form):
469   - if child_form.model_class == PhraseType:
470   - return 'phrase_types__in'
471   - raise KeyError(type(child_form))
472   -
473   - return PositionForm
  424 +
  425 + @staticmethod
  426 + def get_child_form_prefix(child_form):
  427 + if child_form.model_class == PhraseType:
  428 + return 'phrase_types__in'
  429 + raise KeyError(type(child_form))
474 430  
475 431  
476 432 class LexFormFactory(FormFactory):
477 433  
  434 + form_class_name = 'LexForm'
  435 + form_model = PhraseType
  436 + form_formtype = 'phrase_lex'
  437 + form_header = 'Frazeologizm'
  438 +
478 439 field_makers = (
479 440 (
480 441 'lex_type',
481   - lambda: PhraseTypeFilter(lex=True, help_text='Typ składniowy frazeologizmu.')
  442 + lambda: PhraseTypeFilter(lex=True, help_text='Typ składniowy frazeologizmu.'),
  443 + lambda n: and_or_form_creator('Typ frazeologizmu', field_name=FormFactory.unique_name('lex_type', n), data_prefix='phrase_lex')
482 444 ),
483 445 )
  446 +
  447 + @staticmethod
  448 + def get_child_form_prefix(child_form):
  449 + if child_form.model_class == PhraseType:
  450 + return 'id__in'
  451 + raise KeyError(type(child_form))
484 452  
485   - @classmethod
486   - def make_form_class(cls, n):
487   -
488   - class LexForm(QueryForm):
489   -
490   - def __init__(self, *args, **kwargs):
491   - super().__init__(*args, **kwargs)
492   - self.helper.attrs = cls.make_helper_attrs('lex', n)
493   - self.model_class = PhraseType
494   -
495   - components = and_or_form_creator('Typ frazeologizmu', field_name=cls.unique_name('lex_type', n), data_prefix='phrase_lex')
496   - self.helper.layout = cls.make_layout('Frazeologizm', components)
497   -
498   - return LexForm
  453 +class LemmaFormFactory(FormFactory):
  454 +
  455 + form_class_name = 'LemmaForm'
  456 + form_model = Lemma
  457 + form_formtype = 'lemma'
  458 + form_header = 'Lemat'
  459 +
  460 + field_makers = (
  461 + (
  462 + 'lemma',
  463 + lambda: RegexFilter(
  464 + label='Lemat',
  465 + max_length=32,
  466 + lookup='name',
  467 + autocomplete='lex_lemma'
  468 + ), None,
  469 + ),
  470 + )
499 471  
500 472 class FrameFormFactory(FormFactory):
501 473  
  474 + form_class_name = 'FrameForm'
  475 + form_model = Frame
  476 + form_formtype = 'frame'
  477 + form_header = 'Rama semantyczna'
  478 +
502 479 field_makers = (
503 480 (
504 481 'opinion',
505 482 lambda: ModelMultipleChoiceFilter(
506 483 label='Opinia',
507   - queryset=FrameOpinion.objects.exclude(key='unk'),
  484 + queryset=FrameOpinion.objects.exclude(key='unk').filter(frame__isnull=False).distinct(),
508 485 key='key',
509 486 human_values=polish_strings.FRAME_OPINION,
510 487 lookup='opinion',
511   - )
  488 + ), None,
512 489 ),
513   - #(
514   - # 'operator_opinion',
515   - # lambda: OperatorField()
516   - #),
517 490 (
518 491 'num_arguments',
519 492 lambda: RangeFilter(
520 493 label='Liczba argumentów',
521 494 lookup='arguments_count',
522   - )
  495 + ), None
523 496 ),
524 497 (
525 498 'num_preferences',
526 499 lambda: RangeFilter(
527 500 label='Liczba preferencyj selekcyjnych argumentu',
528 501 lookup='argument__preferences_count',
529   - )
  502 + ), None
  503 + ),
  504 + (
  505 + None, None,
  506 + lambda n: and_or_form_creator('Argument', data_add='argument'),
530 507 ),
531   - # TODO move this to the entry form
532   - #filter_frame_ = SwitchField('Filtruj ramy')
533 508 )
534   -
535   - @classmethod
536   - def make_form_class(cls, n):
537   -
538   - class FrameForm(QueryForm):
539   -
540   - def __init__(self, *args, **kwargs):
541   - super().__init__(*args, **kwargs)
542   - self.helper.attrs = cls.make_helper_attrs('frame', n)
543   - self.model_class = Frame
544   -
545   - components = [
546   - self.make_field(cls.unique_name('opinion', n)),
547   - #self.make_field(cls.unique_name('operator_opinion', n)),
548   - self.make_field(cls.unique_name('num_arguments', n)),
549   - self.make_field(cls.unique_name('num_preferences', n)),
550   - ] + \
551   - and_or_form_creator('Argument', data_add='argument')
552   - self.helper.layout = cls.make_layout('Rama semantyczna', components)
553   -
554   - return FrameForm
555 509  
556 510  
557 511 class ArgumentFormFactory(FormFactory):
558 512  
  513 + form_class_name = 'ArgumentForm'
  514 + form_model = Argument
  515 + form_formtype = 'argument'
  516 + form_header = 'Argument ramy'
  517 +
559 518 field_makers = (
560 519 (
561 520 'role',
562   - lambda: ArgumentFilter(),
  521 + lambda: ModelMultipleChoiceFilter(
  522 + label='Rola',
  523 + queryset=SemanticRole.objects.filter(argumentrole__argument__isnull=False).distinct(),
  524 + key='role',
  525 + lookup='role__role',
  526 + ), None,
  527 + ),
  528 + (
  529 + 'role_attribute',
  530 + lambda: ModelMultipleChoiceFilter(
  531 + label='Atrybut roli',
  532 + queryset=RoleAttribute.objects.filter(argumentrole__argument__isnull=False).distinct(),
  533 + key='attribute',
  534 + lookup='role__attribute',
  535 + ), None,
563 536 ),
564 537 (
565 538 'preference_type',
... ... @@ -567,148 +540,127 @@ class ArgumentFormFactory(FormFactory):
567 540 label='Preferencja selekcyjna',
568 541 choices=(('predefined', 'Predefinowana grupa znaczeń'), ('relational', 'Wyrażona przez relację'), ('synset', 'Wyrażona przez jednostkę leksykalną Słowosieci')),
569 542 required=False,
570   - )
  543 + ),
  544 + lambda n: and_or_form_creator('Preferencja selekcyjna', field_name=FormFactory.unique_name('preference_type', n))
  545 + ),
  546 + (
  547 + None, None,
  548 + lambda n: and_or_form_creator('Pozycja', data_add='position'),
571 549 ),
572 550 (
573 551 'phrase_type',
574   - lambda: PhraseTypeFilter(help_text='Typ frazy, przez którą może być realizowany argument.')
  552 + lambda: PhraseTypeFilter(help_text='Typ frazy, przez którą może być realizowany argument.'),
  553 + lambda n: and_or_form_creator('Fraza', field_name=FormFactory.unique_name('phrase_type', n), data_prefix='phrase_'),
575 554 ),
576 555 )
577   -
578   - @classmethod
579   - def make_form_class(cls, n):
580   -
581   - class ArgumentForm(QueryForm):
582   -
583   - def __init__(self, *args, **kwargs):
584   - super().__init__(*args, **kwargs)
585   - self.helper.attrs = cls.make_helper_attrs('argument', n)
586   - self.model_class = Argument
587   -
588   - components = [
589   - self.make_field(cls.unique_name('role', n)),
590   - ] + \
591   - and_or_form_creator('Preferencja selekcyjna', field_name=cls.unique_name('preference_type', n)) + \
592   - and_or_form_creator('Pozycja', data_add='position') + \
593   - and_or_form_creator('Fraza', field_name=cls.unique_name('phrase_type', n), data_prefix='phrase_')
594   - self.helper.layout = cls.make_layout('Argument ramy', components)
595   -
596   - return ArgumentForm
597 556  
598 557  
599 558 class PredefinedPreferenceFormFactory(FormFactory):
600 559  
  560 + form_class_name = 'PredefinedPreferenceForm'
  561 + form_model = PredefinedSelectionalPreference
  562 + form_formtype = 'predefined'
  563 + form_header = 'Preferencja predefiniowana'
  564 +
601 565 field_makers = (
602 566 (
603 567 'predefined',
604   - lambda: PredefinedPreferenceFilter()
  568 + lambda: ModelMultipleChoiceFilter(
  569 + label='Predefiniowane',
  570 + queryset=PredefinedSelectionalPreference.objects.all(),
  571 + key='key',
  572 + # TODO
  573 + lookup='predefined',
  574 + ), None,
605 575 ),
606 576 )
607   -
608   - @classmethod
609   - def make_form_class(cls, n):
610   -
611   - class PredefinedPreferenceForm(QueryForm):
612 577  
613   - def __init__(self, *args, **kwargs):
614   - super().__init__(*args, **kwargs)
615   - self.helper.attrs = cls.make_helper_attrs('predefined', n)
616   - self.model_class = PredefinedSelectionalPreference
617   -
618   - components = [
619   - self.make_field(cls.unique_name('predefined', n)),
620   - ]
621   - self.helper.layout = cls.make_layout('Preferencja predefiniowana', components)
622   -
623   - return PredefinedPreferenceForm
624   -
625 578  
626 579 class RelationalPreferenceFormFactory(FormFactory):
627 580  
  581 + form_class_name = 'RelationalPreferenceForm'
  582 + form_model = RelationalSelectionalPreference
  583 + form_formtype = 'relational'
  584 + form_header = 'Preferencja – relacja'
  585 +
628 586 field_makers = (
629 587 (
630   - 'relational',
631   - lambda: RelationalPreferenceFilter()
  588 + 'relation',
  589 + lambda: ModelMultipleChoiceFilter(
  590 + label='Relacja',
  591 + queryset=SelectionalPreferenceRelation.objects.all(),
  592 + key='key',
  593 + # TODO
  594 + lookup='relation',
  595 + ), None,
632 596 ),
  597 + (
  598 + 'to_role',
  599 + lambda : ModelMultipleChoiceFilter(
  600 + label='Do: rola',
  601 + queryset=SemanticRole.objects.all(),
  602 + key='role',
  603 + lookup='to__role__role',
  604 + ), None,
  605 + ),
  606 + (
  607 + 'to_attribute',
  608 + lambda: ModelMultipleChoiceFilter(
  609 + label='Do: atrybut',
  610 + queryset=RoleAttribute.objects.all(),
  611 + key='attribute',
  612 + lookup='to__role__attribute',
  613 + ), None,
  614 + )
633 615 )
634   -
635   - @classmethod
636   - def make_form_class(cls, n):
637   -
638   - class RelationalPreferenceForm(QueryForm):
639   -
640   - def __init__(self, *args, **kwargs):
641   - super().__init__(*args, **kwargs)
642   - self.helper.attrs = cls.make_helper_attrs('relational', n)
643   - self.model_class = RelationalSelectionalPreference
644   -
645   - components = [
646   - self.make_field(cls.unique_name('relational', n)),
647   - ]
648   - self.helper.layout = cls.make_layout('Preferencja – relacja', components)
649   -
650   - return RelationalPreferenceForm
651   -
  616 +
652 617  
653 618 class SynsetPreferenceFormFactory(FormFactory):
654 619  
  620 + form_class_name = 'SynsetPreferenceForm'
  621 + # TODO
  622 + form_model = Synset
  623 + form_formtype = 'synset'
  624 + form_header = 'Preferencja – Słowosieć'
  625 +
655 626 field_makers = (
656 627 (
657 628 'synset',
658   - #lambda: SynsetPreferenceFilter()
659 629 lambda: RegexFilter(
660 630 label='Jednostka leksykalna',
661 631 max_length=200,
662 632 lookup='lexical_units__text_rep',
663 633 autocomplete='lu'
664   - )
  634 + ), None,
665 635 ),
666 636 )
667   -
668   - @classmethod
669   - def make_form_class(cls, n):
670 637  
671   - class SynsetPreferenceForm(QueryForm):
672   -
673   - def __init__(self, *args, **kwargs):
674   - super().__init__(*args, **kwargs)
675   - self.helper.attrs = cls.make_helper_attrs('synset', n)
676   - # TODO
677   - self.model_class = Synset
678   -
679   - components = [
680   - self.make_field(cls.unique_name('synset', n)),
681   - ]
682   - self.helper.layout = cls.make_layout('Preferencja – Słowosieć', components)
683   -
684   - return SynsetPreferenceForm
685   -
686 638  
687 639 class PhraseAttributesFormFactory(FormFactory):
688 640  
689 641 # field types are dynamic here
690 642 field_makers = None
691 643  
692   - qm = SingleValueQueryManager(lookup='main_type__name')
693   -
694 644 @classmethod
695 645 def make_form_class(cls, n, model, lex_model, phrase_type):
  646 + print('*****************', n, model, lex_model, phrase_type)
  647 + lex_phrase = lex_model is not None
696 648 fields = list(filter(lambda x: type(x) in (OneToOneField, ForeignKey, CharField, ManyToManyField) and not x.name.endswith('_ptr'), model._meta.get_fields()))
697   - if lex_model is not None:
  649 + if lex_phrase:
698 650 lex_fields = list(filter(lambda x: type(x) in (OneToOneField, ForeignKey, CharField, ManyToManyField) and not x.name.endswith('_ptr'), lex_model._meta.get_fields()))
699 651 else:
700 652 lex_fields = []
701   - all_fields = [(f, 'phrase_{}'.format(f.name)) for f in fields] + [(f, 'lex_phrase_{}'.format(f.name)) for f in lex_fields]
  653 + all_fields = [(f, '{}'.format(f.name)) for f in fields] + [(f, 'lex_{}'.format(f.name)) for f in lex_fields]
702 654  
703 655 class AttributesForm(QueryForm):
704 656  
705 657 def __init__(self, *args, **kwargs):
706 658 super().__init__(*args, **kwargs)
707   - self.helper.attrs = cls.make_helper_attrs('phrase_{}'.format(phrase_type), n)
  659 + self.helper.attrs = cls.make_helper_attrs('phrase_{}{}'.format('lex' if lex_model else '', phrase_type), n)
708 660 self.helper.form_id = 'phrase-form'
709 661 self.model_class = PhraseType
710 662  
711   - components = []
  663 + components = [self.make_field(cls.unique_name('negated', n))]
712 664 for _, name in all_fields:
713 665 uniq_name = cls.unique_name(name, n)
714 666 if name.endswith('_lexes'):
... ... @@ -720,23 +672,34 @@ class PhraseAttributesFormFactory(FormFactory):
720 672 else:
721 673 flds = [self.make_field(uniq_name)]
722 674 components += flds
  675 + if lex_model:
  676 + components += [
  677 + self.make_field(cls.unique_name('lex_lemma_operator', n)),
  678 + self.make_field(cls.unique_name('lex_lemma_cooccur', n)),
  679 + ] + and_or_form_creator('Lemat', data_add='lemma')
723 680 pt = polish_strings.PHRASE_TYPE[phrase_type]
724 681 header = pt.capitalize() if phrase_type in polish_strings.NO_PHRASE_NAME else 'Fraza {}'.format(pt)
725 682 if lex_model:
726 683 header += ' (frazeologizm)'
727 684 self.helper.layout = cls.make_layout(
728 685 header,
729   - #'{} {}'.format('Frazeologizm' if lex_model else 'Fraza', polish_strings.PHRASE_TYPE[phrase_type]),
730 686 components
731 687 )
732 688  
733 689 # add a phrase type query
734 690 def get_queries(self):
735   - return super().get_queries() + cls.qm.make_queries(phrase_type, None)
736   -
  691 + pt_q = Q(('{}main_type__name'.format('lexicalized_phrase__' if lex_phrase else ''), phrase_type))
  692 + return super().get_queries() + [pt_q]
  693 +
  694 + @staticmethod
  695 + def get_child_form_prefix(child_form):
  696 + if child_form.model_class == Lemma:
  697 + return 'lemmata__in'
  698 + raise KeyError(type(child_form))
737 699  
  700 + AttributesForm.base_fields[cls.unique_name('negated', n)] = SwitchField('Zaneguj', css_class='negate-switch')
738 701 for field, name in all_fields:
739   - #print('***', name, field.name, type(field))
  702 + print('***', name, field.name, type(field))
740 703 if field.name == 'lexes':
741 704 form_field = PhraseTypeFilter(help_text='Fraza składowa frazeologizmu porównawczego.', lex=True)
742 705 elif field.name == 'lex':
... ... @@ -753,32 +716,36 @@ class PhraseAttributesFormFactory(FormFactory):
753 716 autocomplete=autocomplete,
754 717 )
755 718 else:
756   - queryset_q = Q(('{}{}attributes__isnull'.format('lex' if name.startswith('lex') else '', phrase_type), False))
  719 + lex_attr = name.startswith('lex')
  720 + queryset_q = Q(('{}{}attributes__isnull'.format('lex' if lex_attr else '', phrase_type), False))
757 721 form_field = ModelMultipleChoiceFilter(
758 722 label=polish_strings.PHRASE_ATTRIBUTE.get(field.name, field.name),
759 723 queryset=type(field.related_model()).objects.filter(queryset_q).distinct(),
760 724 key='name',
761   - lookup='attributes__{}attributes__{}'.format(phrase_type, field.name),
762   - )
  725 + human_values=polish_strings.PHRASE_ATTRIBUTE_VALUE,
  726 + lookup='{}attributes__{}{}attributes__{}'.format(
  727 + 'lexicalized_phrase__' if lex_phrase and not lex_attr else '',
  728 + 'lexphrasetypeattributes__lex' if lex_attr else '',
  729 + phrase_type,
  730 + field.name,
  731 + ),
  732 + )
763 733 AttributesForm.base_fields[cls.unique_name(name, n)] = form_field
  734 + if lex_model:
  735 + AttributesForm.base_fields[cls.unique_name('lex_lemma_operator', n)] = ModelMultipleChoiceFilter(
  736 + label='Operator lematów',
  737 + queryset=LemmaOperator.objects.all(),
  738 + key='name',
  739 + lookup='lemma_operator',
  740 + )
  741 + AttributesForm.base_fields[cls.unique_name('lex_lemma_cooccur', n)] = ModelMultipleChoiceFilter(
  742 + label='Łączenie lematów',
  743 + queryset=LemmaCooccur.objects.all(),
  744 + key='name',
  745 + lookup='lemma_cooccur',
  746 + )
764 747  
765 748 return AttributesForm
766   -
767   - '''
768   - @staticmethod
769   - def PhraseAttributesForm(phrase_type, *args, **kwargs):
770   - lex = phrase_type.startswith('lex')
771   - phrase_type = phrase_type[3:] if lex else phrase_type
772   - if phrase_type in attrs_helpers:
773   - helper = attrs_helpers[phrase_type]
774   - cls, lex_cls = helper.attrs_cls, helper.lex_attrs_cls
775   - if lex:
776   - assert(lex_cls is not None)
777   - return PhraseAttributesFormFactory.get_attributes_form(cls, lex_cls, phrase_type, *args, **kwargs)
778   - else:
779   - return PhraseAttributesFormFactory.get_attributes_form(cls, None, phrase_type, *args, **kwargs)
780   - return PhraseAttributesFormFactory.get_attributes_form(EmptyAttributes, None, phrase_type)
781   - '''
782 749  
783 750 @classmethod
784 751 def get_form(cls, phrase_type, unique_number=None, *args, **kwargs):
... ...
entries/phrase_descriptions/descriptions.py
... ... @@ -32,7 +32,7 @@ def phrase_description2(phrase, position, negativity):
32 32 return desc
33 33  
34 34 def phrase_description(phrase, function, negativity, desc_case='nom', inside_lex=False):
35   - print('******', function, '***', negativity, '***', str(phrase))
  35 + #print('******', function, '***', negativity, '***', str(phrase))
36 36 if str(phrase) in (
37 37 # malowany -> ppas in in Morfeusz
38 38 'lex(adjp(agr),agr,agr,pos,malować,natr)',
... ... @@ -52,6 +52,8 @@ def phrase_description(phrase, function, negativity, desc_case=&#39;nom&#39;, inside_lex
52 52 'lex(cp(rel[co]),_,XOR(przychodzić,przyjść),,ratr({lex(np(dat),_,XOR(ja,my,on,ty,wy),natr)}+{lex(prepnp(na,acc),sg,myśl,natr)}))',
53 53 'lex(np(str),sg,wszystko,ratr(subj{lex(np(str),sg,co,natr)}+{lex(cp(rel[co]),aff,być,,ratr1({lex(prepnp(w,loc),sg,moc,atr({lex(adjp(agr),agr,agr,pos,ludzki,natr)}))}))}))',
54 54 'lex(np(str),sg,wszystko,ratr(subj{lex(np(str),sg,co,natr)}+{lex(cp(rel[co]),aff,być,,ratr1({lex(prepnp(w,loc),sg,moc,atr({possp}))}))}))',
  55 + 'lex(cp(rel[co]),aff,być,,ratr1({lex(prepnp(w,loc),sg,moc,atr({lex(adjp(agr),agr,agr,pos,ludzki,natr)}))}))',
  56 + 'lex(cp(rel[co]),aff,być,,ratr1({lex(prepnp(w,loc),sg,moc,atr({possp}))}))',
55 57 # „jakby” nie ma wśród modyfikacyj
56 58 'lex(xp(mod[cp(rel[jakby])]),aff,strzelić,,ratr({prepnp(w,acc)}+{lex(np(str),sg,XOR(grom,piorun),natr)}))',
57 59 ):
... ... @@ -228,7 +230,7 @@ def combine(phrase, texts):
228 230 if phrase._words._selection == 'xor':
229 231 return list(chain.from_iterable(texts))
230 232 else:
231   - joiner = ' ' if phrase._words._coocur == 'concat' else ' i/lub '
  233 + joiner = ' ' if phrase._words._cooccur == 'concat' else ' i/lub '
232 234 return list(chain.from_iterable(map(joiner.join, powerset_nonempty(x)) for x in product(*texts)))
233 235  
234 236 def make_phraseologisms(phrase, function, negativity, attrs={}):
... ... @@ -455,6 +457,7 @@ def make_phraseologisms(phrase, function, negativity, attrs={}):
455 457 pron.append(dep_phr)
456 458 else:
457 459 rest.append(dep_phr)
  460 + # all realisations should have been matched by modifications
458 461 assert (not realisations)
459 462 #print()
460 463 #print('--- FIRST:', list(map(str, first)))
... ...
entries/polish_strings.py
... ... @@ -33,6 +33,21 @@ FRAME_OPINION = {
33 33 'unk' : 'nieznana',
34 34 }
35 35  
  36 +GRAM_FUNCTION = {
  37 + 'subj' : 'podmiot',
  38 + 'obj' : 'dopełnienie',
  39 + 'head' : 'centrum',
  40 +}
  41 +
  42 +CONTROL = {
  43 + 'controller' : 'kontrolujący',
  44 + 'controllee' : 'kontrolowany',
  45 + 'controller2' : 'kontrolujący #2',
  46 + 'controllee2' : 'kontrolowany #2',
  47 + 'pred_controller' : 'kontrolujący',
  48 + 'pred_controllee' : 'kontrolowany',
  49 +}
  50 +
36 51 PHRASE_ATTRIBUTE = {
37 52 'case' : 'Przypadek',
38 53 'num' : 'Liczba',
... ... @@ -49,6 +64,31 @@ PHRASE_ATTRIBUTE = {
49 64 'text' : 'Postać frazeologizmu',
50 65 }
51 66  
  67 +PHRASE_ATTRIBUTE_VALUE = {
  68 + 'str' : 'strukturalny',
  69 + 'nom' : 'mianownik',
  70 + 'gen' : 'dopełniacz',
  71 + 'dat' : 'celownik',
  72 + 'acc' : 'biernik',
  73 + 'inst' : 'narzędnik',
  74 + 'loc' : 'miejscownik',
  75 + 'pred' : 'predykatywny',
  76 + 'part' : 'partytytwny',
  77 + 'postp' : 'poprzyimkowy',
  78 + 'agr' : 'uzgodnienie',
  79 + '_' : 'dowolnie',
  80 + 'sg' : 'pojedyncza',
  81 + 'pl' : 'mnoga',
  82 + 'm1' : 'męski osobowy',
  83 + 'm2' : 'męski żywotny',
  84 + 'm3' : 'męski nieżywotny',
  85 + 'f' : 'żenski',
  86 + 'n' : 'nijaki',
  87 + 'pos' : 'równy',
  88 + 'com' : 'wyższy',
  89 + 'sup' : 'najwyższy',
  90 +}
  91 +
52 92 PHRASE_TYPE = {
53 93 'adjp' : 'przymiotnikowa',
54 94 'advp' : 'przysłówkowa',
... ...
entries/static/entries/js/entries.js
... ... @@ -89,6 +89,37 @@ function bind_remove_subforms(selector) {
89 89 });
90 90 }
91 91  
  92 +function bind_collapse_subforms(selector) {
  93 + selector.find('.collapse-button').mouseenter(function() {
  94 + $(this).closest('.subform').addClass('to-collapse').find('.subform').addClass('to-collapse');
  95 + }).mouseleave(function() {
  96 + $(this).closest('.subform').removeClass('to-collapse').find('.subform').removeClass('to-collapse');
  97 + }).click(function() {
  98 + if ($(this).data('collapsed')) {
  99 + $(this).closest('legend').nextAll().show();
  100 + $(this).closest('legend').find('.collapsed-info').html('');
  101 + $(this).html('zwiń');
  102 + $(this).data('collapsed', false);
  103 + } else {
  104 + $(this).closest('legend').nextAll().hide();
  105 + $(this).closest('legend').find('.collapsed-info').html('[...]');
  106 + $(this).html('rozwiń');
  107 + $(this).data('collapsed', true);
  108 + }
  109 + });
  110 +}
  111 +
  112 +function bind_negations(selector) {
  113 + selector.find('.negate-switch').find('.checkboxinput').change(function() {
  114 + var checked = $(this).prop('checked');
  115 + if (checked) {
  116 + $(this).closest('.subform').addClass('negated');
  117 + } else {
  118 + $(this).closest('.subform').removeClass('negated');
  119 + }
  120 + });
  121 +}
  122 +
92 123 function bind_ors(selector) {
93 124 selector.find('.or-button').click(function() {
94 125 // if there is no subform yet, nothing will be inserted
... ... @@ -144,6 +175,8 @@ function bind_clickable_labels(selector) {
144 175 function bind_form_events(selector) {
145 176 bind_add_subforms(selector);
146 177 bind_remove_subforms(selector);
  178 + bind_collapse_subforms(selector);
  179 + bind_negations(selector);
147 180 bind_ors(selector);
148 181 bind_autocompletes(selector);
149 182 bind_clickable_labels(selector);
... ... @@ -257,6 +290,8 @@ function initialize_main_form() {
257 290 // in addition to resetting the form, remove all subforms and ors
258 291 $('#main-form').find('.subform').remove();
259 292 $('#main-form').find('.form-or').remove();
  293 + // and submit
  294 + $('#main-form').submit();
260 295 });
261 296 }
262 297  
... ...
entries/views.py
... ... @@ -28,6 +28,7 @@ from .forms import (
28 28 PositionFormFactory,
29 29 PhraseAttributesFormFactory,
30 30 LexFormFactory,
  31 + LemmaFormFactory,
31 32 ArgumentFormFactory,
32 33 PredefinedPreferenceFormFactory,
33 34 RelationalPreferenceFormFactory,
... ... @@ -54,6 +55,7 @@ FORM_FACTORY_TYPES = {
54 55 'schema' : SchemaFormFactory,
55 56 'position' : PositionFormFactory,
56 57 'phrase_lex' : LexFormFactory,
  58 + 'lemma' : LemmaFormFactory,
57 59 'frame' : FrameFormFactory,
58 60 'argument' : ArgumentFormFactory,
59 61 'predefined' : PredefinedPreferenceFormFactory,
... ... @@ -146,8 +148,11 @@ def get_filtered_objects(forms, initial_objects=None, tab=&#39; &#39;):
146 148 objects = form.model_class.objects.all() if initial_objects is None else initial_objects.all()
147 149 queries = form.get_queries()
148 150 print(tab, type(form), 'FOR FILTERING:', form.model_class)
  151 + print(tab, queries)
149 152 objects = filter_objects(objects, queries, tab=tab)
  153 + print(tab, 'OK')
150 154 for children_group in children:
  155 + print(tab, 'CHILD FORMS')
151 156 object_ids_or = []
152 157 prefixes = set()
153 158 for or_children in children_group[1]:
... ... @@ -159,12 +164,17 @@ def get_filtered_objects(forms, initial_objects=None, tab=&#39; &#39;):
159 164 prefixes.add(prefix)
160 165 child_ids = [co.id for co in child_objects]
161 166 q = Q((prefix, child_ids))
162   - objects_and = objects_and.filter(q)
  167 + if child[0].is_negated():
  168 + objects_and = objects_and.exclude(q)
  169 + else:
  170 + objects_and = objects_and.filter(q)
163 171 object_ids_or.append({o.id for o in objects_and})
164 172 assert(len(prefixes) == 1)
165 173 object_ids = reduce(operator.or_, object_ids_or)
166 174 objects = objects.filter(id__in=object_ids)
167   - return objects.distinct()
  175 + objects = objects.distinct()
  176 + print(tab, 'FILTERED:', form.model_class)
  177 + return objects
168 178  
169 179  
170 180 # forms – an ‘or’ list of ‘and’ lists of forms, the forms are flattened and treated as one ‘or’ list.
... ... @@ -330,7 +340,7 @@ def get_entry(request):
330 340 schemata.append(schema2dict(schema, phr2arg, subentry.negativity))
331 341 if schemata:
332 342 subentries.append({ 'str' : subentry2str(subentry), 'schemata' : schemata })
333   - frame_objects = Frame.objects.filter(argument__argument_connections__schema_connections__subentry__entry=entry)
  343 + frame_objects = Frame.objects.filter(argument__argument_connections__schema_connections__subentry__entry=entry).distinct()
334 344 if filter_frames:
335 345 frame_objects = get_filtered_objects2(frame_objects, frame_forms)
336 346 frames = [frame2dict(frame, arg2phr) for frame in frame_objects]
... ...
importer/Phrase.py
... ... @@ -2,9 +2,9 @@
2 2 # -*- coding: utf-8 -*-
3 3  
4 4 from importer.PhraseAttributes import get_attributes, get_lex_attributes, empty_attributes
5   -from syntax.models_phrase import PhraseTypeModel, PhraseType
  5 +from syntax.models_phrase import PhraseTypeModel, PhraseType, LemmaOperator, LemmaCooccur, Lemma, Modification as DBModification, ModificationType
  6 +
6 7  
7   -
8 8 class Case:
9 9  
10 10 values = ['nom', 'gen', 'dat', 'acc', 'inst', 'loc', 'voc', 'str', 'part', 'agr', 'pred', 'postp']
... ... @@ -17,7 +17,7 @@ class Case:
17 17  
18 18 def __str__(self):
19 19 return self._value
20   -
  20 +
21 21  
22 22 class Preposition:
23 23  
... ... @@ -31,7 +31,7 @@ class Preposition:
31 31 def __str__(self):
32 32 return self._value + ',' + str(self._case)
33 33  
34   -
  34 +
35 35 class ComplexPreposition:
36 36  
37 37 def __init__(self, value):
... ... @@ -83,7 +83,7 @@ class Aspect:
83 83  
84 84 def __str__(self):
85 85 return self._value
86   -
  86 +
87 87  
88 88 class AdverbialCategory:
89 89  
... ... @@ -114,7 +114,7 @@ class AdverbialCategory:
114 114 limitations = [phrase_from_tree(subtree) for subtree in tree._children[0]._children[0]._children[1]._children[0]._children]
115 115 limitation_tree = tree._children[0]._children[0]._children[1]._children[0]._children[0]
116 116 return cls(value, limitations, limitation_tree)
117   -
  117 +
118 118 def __str__(self):
119 119 if self._limitations is not None:
120 120 return self._value + '[' + ','.join([str(limitation) for limitation in self._limitations]) + ']'
... ... @@ -133,31 +133,31 @@ class ComparCategory:
133 133  
134 134 class Words:
135 135  
136   - def __init__(self, coocur, selection, lemmas):
137   - self._coocur = coocur
  136 + def __init__(self, cooccur, selection, lemmas):
  137 + self._cooccur = cooccur
138 138 self._selection = selection
139 139 self._lemmas = lemmas
140 140  
141 141 @classmethod
142 142 def fromTree(cls, tree):
143   - coocur = tree._children[0]._children[1]._children[0]._attrs['value']
  143 + cooccur = tree._children[0]._children[1]._children[0]._attrs['value']
144 144 selection = tree._children[0]._children[0]._children[0]._attrs['value'].lower()
145 145 lemmas = []
146 146 for string in tree._children[0]._children[2]._children[0]._children:
147 147 lemmas.append(string._content)
148   - return cls(coocur, selection, lemmas)
  148 + return cls(cooccur, selection, lemmas)
149 149  
150 150 def __str__(self):
151 151 if len(self._lemmas) < 2:
152 152 return ','.join(self._lemmas)
153 153 elif self._selection == 'xor':
154 154 return 'XOR(' + ','.join(self._lemmas) + ')'
155   - elif self._coocur == 'concat':
  155 + elif self._cooccur == 'concat':
156 156 return 'OR(' + ','.join(self._lemmas) + ')'
157 157 else:
158 158 return 'OR(' + ';'.join(self._lemmas) + ')'
159 159  
160   -
  160 +
161 161 class Modification:
162 162  
163 163 def __init__(self, atr, dependents):
... ... @@ -181,79 +181,127 @@ class Modification:
181 181 return self._atr
182 182  
183 183  
184   -class Adverb:
185   -
186   - def __init__(self, base, id):
187   - self._base = base
  184 +class Phrase(object):
  185 +
  186 + def __init__(self, name, id, no_attributes=False):
  187 + self._name = name
  188 + self._no_attributes = no_attributes
188 189 self._id = id
189   -
190   - @classmethod
191   - def fromTree(cls, tree, id):
192   - base = tree._children[0]._children[0]._attrs['value']
193   - return cls(base, id)
194   -
  190 +
  191 + def store(self, position, stored_positions):
  192 + raise NotImplementedError
  193 +
195 194 def getId(self):
196 195 return self._id
197 196  
198   - def store(self, position):
  197 +class NonLexPhrase(Phrase):
  198 +
  199 + def __init__(self, *args, **kwargs):
  200 + super().__init__(*args, **kwargs)
  201 +
  202 + def store(self, position, stored_positions):
  203 + #phrase = get_phrase_db_object(self, self._name, no_attributes=self._no_attributes)
  204 +
  205 + main_type, _ = PhraseTypeModel.objects.get_or_create(name=self._name,
  206 + phraseologic=False,
  207 + defaults={'priority': 0})
  208 + attributes = empty_attributes() if self._no_attributes else get_attributes(self, stored_positions)
  209 + phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
  210 + attributes=attributes,
  211 + lexicalized_phrase=None,
  212 + text_rep=str(self))
  213 +
  214 + # position is None for nested lex phrases
  215 + if position is not None:
  216 + position.phrase_types.add(phrase)
  217 + return phrase
  218 +
  219 +stored_modifications = dict()
  220 +
  221 +class LexPhrase(Phrase):
  222 +
  223 + def __init__(self, *args, **kwargs):
  224 + super().__init__(*args, **kwargs)
  225 +
  226 + def _lex_phrase(self):
  227 + raise NotImplementedError
  228 +
  229 + def store(self, position, stored_positions):
  230 + #phrase = get_lex_phrase_db_object(self, self._lex_phrase(), self._name, stored_positions, no_attributes=self._no_attributes, no_lex_attributes=self._no_lex_attributes)
  231 + #def get_lex_phrase_db_object(phrase, lex_phrase, name, stored_positions, no_attributes=False, no_lex_attributes=False):
  232 +
  233 + lex = self._lex_phrase().store(None, None)
  234 +
199 235 main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
200   - phraseologic=True,
201   - defaults={'priority': 0})
202   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='advp',
203   - phraseologic=False,
204   - default={'priority':0})
205   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
206   - lexicalized_phrase=None,
207   - text_rep='advp(misc)')
  236 + phraseologic=True,
  237 + defaults={'priority': 0})
  238 +
  239 + if self._name not in ('compar', 'xp'):
  240 + assert(len(self._words._lemmas) > 0)
  241 + lemma_operator = LemmaOperator.objects.get(name=self._words._selection)
  242 + lemma_cooccur = LemmaCooccur.objects.get(name=self._words._cooccur)
  243 + lemmata = [Lemma.objects.get_or_create(name=lemma)[0] for lemma in self._words._lemmas]
  244 + mod_key = str(self._modification)
  245 + #print('\n*****************************', mod_key)
  246 + if mod_key in stored_modifications:
  247 + modification = stored_modifications[mod_key]
  248 + #print('*************** already stored:', modification)
  249 + else:
  250 + mod_type = ModificationType.objects.get(name=self._modification._atr)
  251 + modification = DBModification.objects.create(mod_type=mod_type)
  252 + # TODO? this is hacky: done like in Schema, taking advantage of the fact
  253 + # that both Schema and Modifications have a m2m field ‘positions’
  254 + # TODO ask TB what exactly the 3rd argument to Position.store does
  255 + mod_positions = set()
  256 + for mod_position in self._modification._dependents:
  257 + mod_position.store(modification, stored_positions, mod_positions, None)
  258 + stored_modifications[mod_key] = modification
  259 + #print('*************** now stored:', modification)
  260 + else:
  261 + lemma_operator, lemma_cooccur, lemmata, modification = None, None, None, None
  262 +
  263 + attributes = empty_attributes() if self._no_attributes else get_lex_attributes(self, stored_positions)
208 264 phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
  265 + attributes=attributes,
209 266 lexicalized_phrase=lex,
  267 + lemma_operator=lemma_operator,
  268 + lemma_cooccur=lemma_cooccur,
  269 + modification=modification,
210 270 text_rep=str(self))
211   - position.phrase_types.add(phrase)
212   - # @TODO: powinno być tylko dla obecnej,
213   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
214   - for schema in position.schemata.all():
215   - schema.phraseologic=True
216   - schema.save()
217   -
218   - def __str__(self):
219   - return 'lex(advp, [_,' + str(self._base) + '], atr)'
  271 + if lemmata:
  272 + phrase.lemmata.set(lemmata)
220 273  
221   -
222   -class NP:
  274 + if position is not None:
  275 + position.phrase_types.add(phrase)
  276 + # @TODO: powinno być tylko dla obecnej,
  277 + # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
  278 + for schema in position.schemata.all():
  279 + schema.phraseologic=True
  280 + schema.save()
  281 + return phrase
  282 +
  283 +class NP(NonLexPhrase):
223 284  
224 285 def __init__(self, case, id):
  286 + super().__init__('np', id)
225 287 self._case = case
226   - self._id = id
227 288  
228 289 @classmethod
229 290 def fromTree(cls, tree, id):
230 291 case = Case(tree._children[0]._children[0]._attrs['value'])
231 292 return cls(case, id)
232 293  
233   - def getId(self):
234   - return self._id
235   -
236   - def store(self, position):
237   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='np',
238   - phraseologic=False,
239   - defaults={'priority': 0})
240   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
241   - attributes=get_attributes(main_type.name, self),
242   - lexicalized_phrase=None,
243   - text_rep=str(self))
244   - position.phrase_types.add(phrase)
245   -
246 294 def __str__(self):
247 295 return 'np(' + str(self._case) + ')'
248 296  
249   -class LexNP:
  297 +class LexNP(LexPhrase):
250 298  
251 299 def __init__(self, np, number, words, modification, id):
  300 + super().__init__('np', id)
252 301 self._np = np
253 302 self._number = number
254 303 self._words = words
255 304 self._modification = modification
256   - self._id = id
257 305  
258 306 @classmethod
259 307 def fromTree(cls, tree, id):
... ... @@ -262,32 +310,10 @@ class LexNP:
262 310 words = Words.fromTree(tree._children[2])
263 311 modifications = Modification.fromTree(tree._children[3])
264 312 return cls(np, number, words, modifications, id)
265   -
266   - def getId(self):
267   - return self._id
268   -
269   - def store(self, position):
270   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
271   - phraseologic=True,
272   - defaults={'priority': 0})
273   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='np',
274   - phraseologic=False,
275   - defaults={'priority':0})
276   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
277   - attributes=get_attributes(lex_type.name, self._np),
278   - lexicalized_phrase=None,
279   - text_rep=str(self._np))
280   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
281   - attributes=get_lex_attributes(lex_type.name, self),
282   - lexicalized_phrase=lex,
283   - text_rep=str(self))
284   - position.phrase_types.add(phrase)
285   - # @TODO: powinno być tylko dla obecnej,
286   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
287   - for schema in position.schemata.all():
288   - schema.phraseologic=True
289   - schema.save()
290 313  
  314 + def _lex_phrase(self):
  315 + return self._np
  316 +
291 317 def __str__(self):
292 318 return 'lex(' + str(self._np) + ',' + self._number + ',' + str(self._words) + ',' + str(self._modification) + ')'
293 319  
... ... @@ -295,43 +321,29 @@ class LexNP:
295 321 return 'lex(' + str(new_type) + ',' + self._number + ',' + str(self._words) + ',' + str(self._modification) + ')'
296 322  
297 323  
298   -class PrepNP:
  324 +class PrepNP(NonLexPhrase):
299 325  
300 326 def __init__(self, prep, id):
  327 + super().__init__('prepnp', id)
301 328 self._prep = prep
302   - self._id = id
303 329  
304 330 @classmethod
305 331 def fromTree(cls, tree, id):
306 332 case = Case(tree._children[1]._children[0]._attrs['value'])
307 333 prep = Preposition(tree._children[0]._children[0]._attrs['value'], case)
308 334 return cls(prep, id)
309   -
310   - def getId(self):
311   - return self._id
312 335  
313   - def store(self, position):
314   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepnp',
315   - phraseologic=False,
316   - defaults={'priority': 0})
317   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
318   - attributes=get_attributes(main_type.name, self),
319   - lexicalized_phrase=None,
320   - text_rep=str(self))
321   - position.phrase_types.add(phrase)
322   -
323 336 def __str__(self):
324 337 return 'prepnp(' + str(self._prep) + ')'
325 338  
326   -
327   -class LexPrepNP:
  339 +class LexPrepNP(LexPhrase):
328 340  
329 341 def __init__(self, prepnp, number, words, modification, id):
  342 + super().__init__('prepnp', id)
330 343 self._prepnp = prepnp
331 344 self._number = number
332 345 self._words = words
333 346 self._modification = modification
334   - self._id = id
335 347  
336 348 @classmethod
337 349 def fromTree(cls, tree, id):
... ... @@ -341,74 +353,39 @@ class LexPrepNP:
341 353 modifications = Modification.fromTree(tree._children[3])
342 354 return cls(prepnp, number, words, modifications, id)
343 355  
344   - def getId(self):
345   - return self._id
  356 + def _lex_phrase(self):
  357 + return self._prepnp
346 358  
347   - def store(self, position):
348   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
349   - phraseologic=True,
350   - defaults={'priority': 0})
351   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='prepnp',
352   - phraseologic=False,
353   - defaults={'priority':0})
354   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
355   - attributes=get_attributes(lex_type.name, self._prepnp),
356   - lexicalized_phrase=None,
357   - text_rep=str(self._prepnp))
358   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
359   - attributes=get_lex_attributes(lex_type.name, self),
360   - lexicalized_phrase=lex,
361   - text_rep=str(self))
362   - position.phrase_types.add(phrase)
363   - # @TODO: powinno być tylko dla obecnej,
364   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
365   - for schema in position.schemata.all():
366   - schema.phraseologic=True
367   - schema.save()
368   -
369 359 def __str__(self):
370 360 return 'lex(' + str(self._prepnp) + ',' + self._number + ',' + str(self._words) + ',' + str(self._modification) + ')'
371 361  
372 362 def retyped(self, new_type):
373 363 return 'lex(' + str(new_type) + ',' + self._number + ',' + str(self._words) + ',' + str(self._modification) + ')'
374   -
375 364  
376   -class PrepNumP:
  365 +
  366 +class PrepNumP(NonLexPhrase):
377 367  
378 368 def __init__(self, prep, id):
  369 + super().__init__('prepnump', id)
379 370 self._prep = prep
380   - self._id = id
381 371  
382 372 @classmethod
383 373 def fromTree(cls, tree, id):
384 374 case = Case(tree._children[1]._children[0]._attrs['value'])
385 375 prep = Preposition(tree._children[0]._children[0]._attrs['value'], case)
386 376 return cls(prep, id)
387   -
388   - def getId(self):
389   - return self._id
390 377  
391   - def store(self, position):
392   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepnump',
393   - phraseologic=False,
394   - defaults={'priority': 0})
395   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
396   - attributes=get_attributes(main_type.name, self),
397   - lexicalized_phrase=None,
398   - text_rep=str(self))
399   - position.phrase_types.add(phrase)
400   -
401 378 def __str__(self):
402 379 return 'prepnump(' + str(self._prep) + ')'
403 380  
404   -class LexPrepNumP:
  381 +class LexPrepNumP(LexPhrase):
405 382  
406 383 def __init__(self, prepnump, nums, words, modification, id):
  384 + super().__init__('prepnump', id, no_attributes=True)
407 385 self._prepnump = prepnump
408 386 self._nums = nums
409 387 self._words = words
410 388 self._modification = modification
411   - self._id = id
412 389  
413 390 @classmethod
414 391 def fromTree(cls, tree, id):
... ... @@ -417,76 +394,38 @@ class LexPrepNumP:
417 394 words = Words.fromTree(tree._children[2])
418 395 modifications = Modification.fromTree(tree._children[3])
419 396 return cls(prepnp, nums, words, modifications, id)
420   -
421   - def getId(self):
422   - return self._id
423   -
424   - def store(self, position):
425   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
426   - phraseologic=True,
427   - defaults={'priority': 0})
428   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='prepnump',
429   - phraseologic=False,
430   - defaults={'priority': 0})
431   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
432   - lexicalized_phrase=None,
433   - attributes=get_attributes(lex_type.name, self._prepnump),
434   - text_rep=str(self._prepnump))
435   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
436   - # TODO!!!
437   - attributes=empty_attributes(),
438   - lexicalized_phrase=lex,
439   - text_rep=str(self))
440   - position.phrase_types.add(phrase)
441   - # @TODO: powinno być tylko dla obecnej,
442   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
443   - for schema in position.schemata.all():
444   - schema.phraseologic=True
445   - schema.save()
446 397  
  398 + def _lex_phrase(self):
  399 + return self._prepnump
  400 +
447 401 def __str__(self):
448 402 return 'lex(' + str(self._prepnump) + ',' + str(self._nums) + ',' + str(self._words) + ',' + str(self._modification) + ')'
449 403  
450 404 def retyped(self, new_type):
451 405 return 'lex(' + str(new_type) + ',' + str(self._nums) + ',' + str(self._words) + ',' + str(self._modification) + ')'
452   -
453 406  
454   -class NumP:
  407 +
  408 +class NumP(NonLexPhrase):
455 409  
456 410 def __init__(self, case, id):
  411 + super().__init__('nump', id)
457 412 self._case = case
458   - self._id = id
459 413  
460 414 @classmethod
461 415 def fromTree(cls, tree, id):
462 416 case = Case(tree._children[0]._children[0]._attrs['value'])
463 417 return cls(case, id)
464   -
465   - def getId(self):
466   - return self._id
467 418  
468   - def store(self, position):
469   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='nump',
470   - phraseologic=False,
471   - defaults={'priority': 0})
472   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
473   - attributes=get_attributes(main_type.name, self),
474   - lexicalized_phrase=None,
475   - text_rep=str(self))
476   - position.phrase_types.add(phrase)
477   -
478 419 def __str__(self):
479 420 return 'nump(' + str(self._case) + ')'
480 421  
481   -
482   -class LexNumP:
483   -
  422 +class LexNumP(LexPhrase):
484 423 def __init__(self, nump, nums, words, modification, id):
  424 + super().__init__('nump', id, no_attributes=True)
485 425 self._nump = nump
486 426 self._nums = nums
487 427 self._words = words
488 428 self._modification = modification
489   - self._id = id
490 429  
491 430 @classmethod
492 431 def fromTree(cls, tree, id):
... ... @@ -496,79 +435,42 @@ class LexNumP:
496 435 modifications = Modification.fromTree(tree._children[3])
497 436 return cls(nump, nums, words, modifications, id)
498 437  
499   - def getId(self):
500   - return self._id
  438 + def _lex_phrase(self):
  439 + return self._nump
501 440  
502   - def store(self, position):
503   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
504   - phraseologic=True,
505   - defaults={'priority': 0})
506   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='nump',
507   - phraseologic=False,
508   - defaults={'priority': 0})
509   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
510   - attributes=get_attributes(lex_type.name, self._nump),
511   - lexicalized_phrase=None,
512   - text_rep=str(self._nump))
513   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
514   - # TODO !!!
515   - attributes=empty_attributes(),
516   - lexicalized_phrase=lex,
517   - text_rep=str(self))
518   - position.phrase_types.add(phrase)
519   - # @TODO: powinno być tylko dla obecnej,
520   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
521   - for schema in position.schemata.all():
522   - schema.phraseologic=True
523   - schema.save()
524   -
525 441 def __str__(self):
526 442 return 'lex(' + str(self._nump) + ',' + str(self._nums) + ',' + str(self._words) + ',' + str(self._modification) + ')'
527 443  
528 444 def retyped(self, new_type):
529 445 return 'lex(' + str(new_type) + ',' + str(self._nums) + ',' + str(self._words) + ',' + str(self._modification) + ')'
530 446  
531   -
532 447  
533   -class PrepAdjP:
  448 +
  449 +class PrepAdjP(NonLexPhrase):
534 450  
535 451 def __init__(self, prep, id):
  452 + super().__init__('prepadjp', id)
536 453 self._prep = prep
537   - self._id = id
538 454  
539 455 @classmethod
540 456 def fromTree(cls, tree, id):
541 457 case = Case(tree._children[1]._children[0]._attrs['value'])
542 458 prep = Preposition(tree._children[0]._children[0]._attrs['value'], case)
543 459 return cls(prep, id)
544   -
545   - def getId(self):
546   - return self._id
547 460  
548   - def store(self, position):
549   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepadjp',
550   - phraseologic=False,
551   - defaults={'priority': 0})
552   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
553   - attributes=get_attributes(main_type.name, self),
554   - lexicalized_phrase=None,
555   - text_rep=str(self))
556   - position.phrase_types.add(phrase)
557   -
558 461 def __str__(self):
559 462 return 'prepadjp(' + str(self._prep) + ')'
560   -
561 463  
562   -class LexPrepAdjP:
  464 +class LexPrepAdjP(LexPhrase):
563 465  
564 466 def __init__(self, prepadjp, number, gender, degree, words, modification, id):
  467 + super().__init__('prepadjp', id)
565 468 self._prepadjp = prepadjp
566 469 self._number = number
567 470 self._gender = gender
568 471 self._degree = degree
569 472 self._words = words
570 473 self._modification = modification
571   - self._id = id
572 474  
573 475 @classmethod
574 476 def fromTree(cls, tree, id):
... ... @@ -580,103 +482,54 @@ class LexPrepAdjP:
580 482 modifications = Modification.fromTree(tree._children[5])
581 483 return cls(prepadjp, number, gender, degree, words, modifications, id)
582 484  
583   - def getId(self):
584   - return self._id
  485 + def _lex_phrase(self):
  486 + return self._prepadjp
585 487  
586   - def store(self, position):
587   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
588   - phraseologic=True,
589   - defaults={'priority': 0})
590   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='prepadjp',
591   - phraseologic=False,
592   - defaults={'priority': 0})
593   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
594   - attributes=get_attributes(lex_type.name, self._prepadjp),
595   - lexicalized_phrase=None,
596   - text_rep=str(self._prepadjp))
597   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
598   - attributes=get_lex_attributes(lex_type.name, self),
599   - lexicalized_phrase=lex,
600   - text_rep=str(self))
601   - position.phrase_types.add(phrase)
602   - # @TODO: powinno być tylko dla obecnej,
603   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
604   - for schema in position.schemata.all():
605   - schema.phraseologic=True
606   - schema.save()
607   -
608 488 def __str__(self):
609 489 return 'lex(' + str(self._prepadjp) + ',' + self._number + ',' + self._gender + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
610 490  
611 491 def retyped(self, new_type):
612 492 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._gender + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
613   -
614 493  
615   -class ComPrepNP:
  494 +
  495 +class ComPrepNP(NonLexPhrase):
616 496  
617 497 def __init__(self, prep, id):
  498 + super().__init__('comprepnp', id)
618 499 self._prep = prep
619   - self._id = id
620 500  
621 501 @classmethod
622 502 def fromTree(cls, tree, id):
623 503 prep = ComplexPreposition(tree._children[-1]._children[0]._content)
624 504 return cls(prep, id)
625   -
626   - def getId(self):
627   - return self._id
628 505  
629   - def store(self, position):
630   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='comprepnp',
631   - phraseologic=False,
632   - defaults={'priority': 0})
633   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
634   - attributes=get_attributes(main_type.name, self),
635   - lexicalized_phrase=None,
636   - text_rep=str(self))
637   - position.phrase_types.add(phrase)
638   -
639 506 def __str__(self):
640 507 return 'comprepnp(' + str(self._prep) + ')'
641 508  
642 509  
643   -class CP:
  510 +class CP(NonLexPhrase):
644 511  
645 512 def __init__(self, type, id):
  513 + super().__init__('cp', id)
646 514 self._type = type
647   - self._id = id
648 515  
649 516 @classmethod
650 517 def fromTree(cls, tree, id):
651 518 type = ClauseType.fromTree(tree._children[0])
652 519 return cls(type, id)
653 520  
654   - def getId(self):
655   - return self._id
656   -
657   - def store(self, position):
658   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='cp',
659   - phraseologic=False,
660   - defaults={'priority': 0})
661   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
662   - attributes = get_attributes(main_type.name, self),
663   - lexicalized_phrase=None,
664   - text_rep=str(self))
665   - position.phrase_types.add(phrase)
666   -
667 521 def __str__(self):
668 522 return 'cp(' + str(self._type) + ')'
669   -
670 523  
671   -class LexCP:
  524 +class LexCP(LexPhrase):
672 525  
673 526 def __init__(self, cp, negativity, words, inherent_sie, modification, id):
  527 + super().__init__('cp', id)
674 528 self._cp = cp
675 529 self._negativity = negativity
676 530 self._words = words
677 531 self._inherent_sie = inherent_sie
678 532 self._modification = modification
679   - self._id = id
680 533  
681 534 @classmethod
682 535 def fromTree(cls, tree, id):
... ... @@ -690,44 +543,21 @@ class LexCP:
690 543 modifications = Modification.fromTree(tree._children[4])
691 544 return cls(cp, negativity, words, inherent_sie, modifications, id)
692 545  
693   - def getId(self):
694   - return self._id
  546 + def _lex_phrase(self):
  547 + return self._cp
695 548  
696   - def store(self, position):
697   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
698   - phraseologic=True,
699   - defaults={'priority': 0})
700   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='cp',
701   - phraseologic=False,
702   - defaults={'priority': 0})
703   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
704   - attributes = get_attributes(lex_type.name, self._cp),
705   - lexicalized_phrase=None,
706   - text_rep=str(self._cp))
707   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
708   - attributes = get_lex_attributes(lex_type.name, self),
709   - lexicalized_phrase=lex,
710   - text_rep=str(self))
711   - position.phrase_types.add(phrase)
712   - # @TODO: powinno być tylko dla obecnej,
713   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
714   - for schema in position.schemata.all():
715   - schema.phraseologic=True
716   - schema.save()
717   -
718   -
719 549 def __str__(self):
720 550 return 'lex(' + str(self._cp) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
721 551  
722 552 def retyped(self, new_type):
723 553 return 'lex(' + str(new_type) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
724 554  
725   -class NCP:
  555 +class NCP(NonLexPhrase):
726 556  
727 557 def __init__(self, case, type, id):
  558 + super().__init__('ncp', id)
728 559 self._case = case
729 560 self._type = type
730   - self._id = id
731 561  
732 562 @classmethod
733 563 def fromTree(cls, tree, id):
... ... @@ -735,31 +565,18 @@ class NCP:
735 565 type = ClauseType.fromTree(tree._children[1])
736 566 return cls(case, type, id)
737 567  
738   - def getId(self):
739   - return self._id
740   -
741   - def store(self, position):
742   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='ncp',
743   - phraseologic=False,
744   - defaults={'priority': 0})
745   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
746   - attributes=get_attributes(main_type.name, self),
747   - lexicalized_phrase=None,
748   - text_rep=str(self))
749   - position.phrase_types.add(phrase)
750   -
751 568 def __str__(self):
752 569 return 'ncp(' + str(self._case) + ',' + str(self._type) + ')'
753 570  
754   -class LexNCP:
  571 +class LexNCP(LexPhrase):
755 572  
756 573 def __init__(self, ncp, negativity, words, inherent_sie, modification, id):
  574 + super().__init__('ncp', id)
757 575 self._ncp = ncp
758 576 self._negativity = negativity
759 577 self._words = words
760 578 self._inherent_sie = inherent_sie
761 579 self._modification = modification
762   - self._id = id
763 580  
764 581 @classmethod
765 582 def fromTree(cls, tree, id):
... ... @@ -773,44 +590,22 @@ class LexNCP:
773 590 modifications = Modification.fromTree(tree._children[4])
774 591 return cls(ncp, negativity, words, inherent_sie, modifications, id)
775 592  
776   - def getId(self):
777   - return self._id
  593 + def _lex_phrase(self):
  594 + return self._ncp
778 595  
779   - def store(self, position):
780   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
781   - phraseologic=True,
782   - defaults={'priority': 0})
783   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='ncp',
784   - phraseologic=False,
785   - defaults={'priority': 0})
786   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
787   - attributes=get_attributes(lex_type.name, self._ncp),
788   - lexicalized_phrase=None,
789   - text_rep=str(self._ncp))
790   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
791   - attributes=get_lex_attributes(lex_type.name, self),
792   - lexicalized_phrase=lex,
793   - text_rep=str(self))
794   - position.phrase_types.add(phrase)
795   - # @TODO: powinno być tylko dla obecnej,
796   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
797   - for schema in position.schemata.all():
798   - schema.phraseologic=True
799   - schema.save()
800   -
801 596 def __str__(self):
802 597 return 'lex(' + str(self._ncp) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
803 598  
804 599 def retyped(self, new_type):
805 600 return 'lex(' + str(new_type) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
806   -
807 601  
808   -class PrepNCP:
  602 +
  603 +class PrepNCP(NonLexPhrase):
809 604  
810 605 def __init__(self, prep, type, id):
  606 + super().__init__('prepncp', id)
811 607 self._prep = prep
812 608 self._type = type
813   - self._id = id
814 609  
815 610 @classmethod
816 611 def fromTree(cls, tree, id):
... ... @@ -819,52 +614,27 @@ class PrepNCP:
819 614 type = ClauseType.fromTree(tree._children[2])
820 615 return cls(prep, type, id)
821 616  
822   - def getId(self):
823   - return self._id
824   -
825   - def store(self, position):
826   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepncp',
827   - phraseologic=False,
828   - defaults={'priority': 0})
829   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
830   - attributes=get_attributes(main_type.name, self),
831   - lexicalized_phrase=None,
832   - text_rep=str(self))
833   - position.phrase_types.add(phrase)
834   -
835 617 def __str__(self):
836 618 return 'prepncp(' + str(self._prep) + ',' + str(self._type) + ')'
837 619  
838 620  
839   -class Nonch:
  621 +class Nonch(NonLexPhrase):
840 622  
841 623 def __init__(self, id):
842   - self._id = id
  624 + super().__init__('nonch', id, no_attributes=True)
843 625  
844 626 @classmethod
845 627 def fromTree(cls, tree, id):
846 628 return cls(id)
847 629  
848   - def getId(self):
849   - return self._id
850   -
851   - def store(self, position):
852   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='nonch',
853   - phraseologic=False,
854   - defaults={'priority': 0})
855   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
856   - attributes=empty_attributes(),
857   - lexicalized_phrase=None,
858   - text_rep=str(self))
859   - position.phrase_types.add(phrase)
860   -
861 630 def __str__(self):
862 631 return 'nonch'
863 632  
864 633  
865   -class InfP:
  634 +class InfP(NonLexPhrase):
866 635  
867 636 def __init__(self, aspect, id):
  637 + super().__init__('infp', id)
868 638 self._aspect = aspect
869 639 self._id = id
870 640  
... ... @@ -873,32 +643,18 @@ class InfP:
873 643 aspect = Aspect(tree._children[0]._children[0]._attrs['value'])
874 644 return cls(aspect, id)
875 645  
876   - def getId(self):
877   - return self._id
878   -
879   - def store(self, position):
880   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='infp',
881   - phraseologic=False,
882   - defaults={'priority': 0})
883   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
884   - attributes=get_attributes(main_type.name, self),
885   - lexicalized_phrase=None,
886   - text_rep=str(self))
887   - position.phrase_types.add(phrase)
888   -
889 646 def __str__(self):
890 647 return 'infp(' + str(self._aspect) + ')'
891 648  
892   -
893   -class LexInfP:
  649 +class LexInfP(LexPhrase):
894 650  
895 651 def __init__(self, infp, negativity, words, inherent_sie, modification, id):
  652 + super().__init__('infp', id)
896 653 self._infp = infp
897 654 self._negativity = negativity
898 655 self._words = words
899 656 self._inherent_sie = inherent_sie
900 657 self._modification = modification
901   - self._id = id
902 658  
903 659 @classmethod
904 660 def fromTree(cls, tree, id):
... ... @@ -912,43 +668,21 @@ class LexInfP:
912 668 modifications = Modification.fromTree(tree._children[4])
913 669 return cls(infp, negativity, words, inherent_sie, modifications, id)
914 670  
915   - def getId(self):
916   - return self._id
  671 + def _lex_phrase(self):
  672 + return self._infp
917 673  
918   - def store(self, position):
919   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
920   - phraseologic=True,
921   - defaults={'priority': 0})
922   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='infp',
923   - phraseologic=False,
924   - defaults={'priority': 0})
925   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
926   - attributes=get_attributes(lex_type.name, self._infp),
927   - lexicalized_phrase=None,
928   - text_rep=str(self._infp))
929   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
930   - attributes=get_lex_attributes(lex_type.name, self),
931   - lexicalized_phrase=lex,
932   - text_rep=str(self))
933   - position.phrase_types.add(phrase)
934   - # @TODO: powinno być tylko dla obecnej,
935   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
936   - for schema in position.schemata.all():
937   - schema.phraseologic=True
938   - schema.save()
939   -
940 674 def __str__(self):
941 675 return 'lex(' + str(self._infp) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
942 676  
943 677 def retyped(self, new_type):
944 678 return 'lex(' + str(new_type) + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._inherent_sie) + ',' + str(self._modification) + ')'
945   -
946 679  
947   -class PrepGerP:
  680 +
  681 +class PrepGerP(NonLexPhrase):
948 682  
949 683 def __init__(self, prep, id):
  684 + super().__init__('prepgerp', id)
950 685 self._prep = prep
951   - self._id = id
952 686  
953 687 @classmethod
954 688 def fromTree(cls, tree, id):
... ... @@ -956,32 +690,19 @@ class PrepGerP:
956 690 prep = Preposition(tree._children[0]._children[0]._attrs['value'], case)
957 691 return cls(prep, id)
958 692  
959   - def getId(self):
960   - return self._id
961   -
962   - def store(self, position):
963   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepgerp',
964   - phraseologic=True,
965   - defaults={'priority': 0})
966   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
967   - attributes=get_attributes(main_type.name, self),
968   - lexicalized_phrase=None,
969   - text_rep=str(self))
970   - position.phrase_types.add(phrase)
971   -
972 693 def __str__(self):
973 694 return 'prepgerp(' + str(self._prep) + ')'
974 695  
975   -class LexPrepGerP:
  696 +class LexPrepGerP(LexPhrase):
976 697  
977 698 def __init__(self, prepgerp, number, negativity, words, inherent_sie, modification, id):
  699 + super().__init__('prepgerp', id)
978 700 self._prepgerp = prepgerp
979 701 self._number = number
980 702 self._negativity = negativity
981 703 self._words = words
982 704 self._inherent_sie = inherent_sie
983 705 self._modification = modification
984   - self._id = id
985 706  
986 707 @classmethod
987 708 def fromTree(cls, tree, id):
... ... @@ -996,75 +717,40 @@ class LexPrepGerP:
996 717 modifications = Modification.fromTree(tree._children[5])
997 718 return cls(prepgerp, number, negativity, words, inherent_sie, modifications, id)
998 719  
999   - def getId(self):
1000   - return self._id
1001   -
1002   - def store(self, position):
1003   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1004   - phraseologic=True,
1005   - defaults={'priority': 0})
1006   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='prepgerp',
1007   - phraseologic=False,
1008   - defaults={'priority': 0})
1009   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1010   - attributes=get_attributes(lex_type.name, self._prepgerp),
1011   - lexicalized_phrase=None,
1012   - text_rep=str(self._prepgerp))
1013   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1014   - attributes=get_lex_attributes(lex_type.name, self),
1015   - lexicalized_phrase=lex,
1016   - text_rep=str(self))
1017   - position.phrase_types.add(phrase)
1018   - # @TODO: powinno być tylko dla obecnej,
1019   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1020   - for schema in position.schemata.all():
1021   - schema.phraseologic=True
1022   - schema.save()
  720 + def _lex_phrase(self):
  721 + return self._prepgerp
1023 722  
1024   -
1025 723 def __str__(self):
1026 724 return 'lex(' + str(self._prepgerp) + ',' + self._number + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1027 725  
1028 726 def retyped(self, new_type):
1029 727 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1030   -
1031   -class PPasP:
  728 +
  729 +
  730 +class PPasP(NonLexPhrase):
1032 731  
1033 732 def __init__(self, case, id):
  733 + super().__init__('ppasp', id)
1034 734 self._case = case
1035   - self._id = id
1036 735  
1037 736 @classmethod
1038 737 def fromTree(cls, tree, id):
1039 738 case = Case(tree._children[0]._children[0]._attrs['value'])
1040 739 return cls(case, id)
1041 740  
1042   - def getId(self):
1043   - return self._id
1044   -
1045   - def store(self, position):
1046   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='ppasp',
1047   - phraseologic=True,
1048   - defaults={'priority': 0})
1049   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1050   - attributes=get_attributes(main_type.name, self),
1051   - lexicalized_phrase=None,
1052   - text_rep=str(self))
1053   - position.phrase_types.add(phrase)
1054   -
1055 741 def __str__(self):
1056 742 return 'ppasp(' + str(self._case) + ')'
1057 743  
1058   -class LexPPasP:
  744 +class LexPPasP(LexPhrase):
1059 745  
1060 746 def __init__(self, ppasp, number, gender, negativity, words, modification, id):
  747 + super().__init__('ppasp', id)
1061 748 self._ppasp = ppasp
1062 749 self._number = number
1063 750 self._gender = gender
1064 751 self._negativity = negativity
1065 752 self._words = words
1066 753 self._modification = modification
1067   - self._id = id
1068 754  
1069 755 @classmethod
1070 756 def fromTree(cls, tree, id):
... ... @@ -1076,44 +762,21 @@ class LexPPasP:
1076 762 modifications = Modification.fromTree(tree._children[5])
1077 763 return cls(ppasp, number, gender, negativity, words, modifications, id)
1078 764  
1079   - def getId(self):
1080   - return self._id
  765 + def _lex_phrase(self):
  766 + return self._ppasp
1081 767  
1082   - def store(self, position):
1083   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1084   - phraseologic=True,
1085   - defaults={'priority': 0})
1086   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='ppasp',
1087   - phraseologic=False,
1088   - defaults={'priority': 0})
1089   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1090   - attributes=get_attributes(lex_type.name, self._ppasp),
1091   - lexicalized_phrase=None,
1092   - text_rep=str(self._ppasp))
1093   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1094   - attributes=get_lex_attributes(lex_type.name, self),
1095   - lexicalized_phrase=lex,
1096   - text_rep=str(self))
1097   - position.phrase_types.add(phrase)
1098   - # @TODO: powinno być tylko dla obecnej,
1099   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1100   - for schema in position.schemata.all():
1101   - schema.phraseologic=True
1102   - schema.save()
1103   -
1104   -
1105 768 def __str__(self):
1106 769 return 'lex(' + str(self._ppasp) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1107 770  
1108 771 def retyped(self, new_type):
1109 772 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1110 773  
1111   -
1112   -class PrepPPasP:
  774 +
  775 +class PrepPPasP(NonLexPhrase):
1113 776  
1114 777 def __init__(self, prep, id):
  778 + super().__init__('prepppasp', id)
1115 779 self._prep = prep
1116   - self._id = id
1117 780  
1118 781 @classmethod
1119 782 def fromTree(cls, tree, id):
... ... @@ -1121,32 +784,19 @@ class PrepPPasP:
1121 784 prep = Preposition(tree._children[0]._children[0]._attrs['value'], case)
1122 785 return cls(prep, id)
1123 786  
1124   - def getId(self):
1125   - return self._id
1126   -
1127   - def store(self, position):
1128   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='prepppasp',
1129   - phraseologic=False,
1130   - defaults={'priority': 0})
1131   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1132   - attributes=get_attributes(main_type.name, self),
1133   - lexicalized_phrase=None,
1134   - text_rep=str(self))
1135   - position.phrase_types.add(phrase)
1136   -
1137 787 def __str__(self):
1138 788 return 'prepppasp(' + str(self._prep) + ')'
1139 789  
1140   -class LexPrepPPasP:
  790 +class LexPrepPPasP(LexPhrase):
1141 791  
1142 792 def __init__(self, prepppasp, number, gender, negativity, words, modification, id):
  793 + super().__init__('prepppasp', id)
1143 794 self._prepppasp = prepppasp
1144 795 self._number = number
1145 796 self._gender = gender
1146 797 self._negativity = negativity
1147 798 self._words = words
1148 799 self._modification = modification
1149   - self._id = id
1150 800  
1151 801 @classmethod
1152 802 def fromTree(cls, tree, id):
... ... @@ -1158,32 +808,9 @@ class LexPrepPPasP:
1158 808 modifications = Modification.fromTree(tree._children[5])
1159 809 return cls(prepppasp, number, gender, negativity, words, modifications, id)
1160 810  
1161   - def getId(self):
1162   - return self._id
  811 + def _lex_phrase(self):
  812 + return self._prepppasp
1163 813  
1164   - def store(self, position):
1165   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1166   - phraseologic=True,
1167   - defaults={'priority': 0})
1168   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='prepppasp',
1169   - phraseologic=False,
1170   - defaults={'priority': 0})
1171   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1172   - attributes=get_attributes(lex_type.name, self._prepppasp),
1173   - lexicalized_phrase=None,
1174   - text_rep=str(self._prepppasp))
1175   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1176   - attributes=get_lex_attributes(lex_type.name, self),
1177   - lexicalized_phrase=lex,
1178   - text_rep=str(self))
1179   - position.phrase_types.add(phrase)
1180   - # @TODO: powinno być tylko dla obecnej,
1181   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1182   - for schema in position.schemata.all():
1183   - schema.phraseologic=True
1184   - schema.save()
1185   -
1186   -
1187 814 def __str__(self):
1188 815 return 'lex(' + str(self._prepppasp) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1189 816  
... ... @@ -1191,35 +818,24 @@ class LexPrepPPasP:
1191 818 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + str(self._modification) + ')'
1192 819  
1193 820  
1194   -class PActP:
  821 +class PActP(NonLexPhrase):
1195 822  
1196 823 def __init__(self, case, id):
  824 + super().__init__('pactp', id)
1197 825 self._case = case
1198   - self._id = id
1199 826  
1200 827 @classmethod
1201 828 def fromTree(cls, tree, id):
1202 829 case = Case(tree._children[0]._children[0]._attrs['value'])
1203 830 return cls(case, id)
1204 831  
1205   - def getId(self):
1206   - return self._id
1207   -
1208   - def store(self, position):
1209   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='pactp',
1210   - phraseologic=False,
1211   - defaults={'priority': 0})
1212   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1213   - lexicalized_phrase=None,
1214   - text_rep=str(self))
1215   - position.phrase_types.add(phrase)
1216   -
1217 832 def __str__(self):
1218 833 return 'pactp(' + str(self._case) + ')'
1219 834  
1220   -class LexPActP:
  835 +class LexPActP(LexPhrase):
1221 836  
1222 837 def __init__(self, pactp, number, gender, negativity, words, inherent_sie, modification, id):
  838 + super().__init__('pactp', id)
1223 839 self._pactp = pactp
1224 840 self._number = number
1225 841 self._gender = gender
... ... @@ -1227,7 +843,6 @@ class LexPActP:
1227 843 self._words = words
1228 844 self._inherent_sie = inherent_sie
1229 845 self._modification = modification
1230   - self._id = id
1231 846  
1232 847 @classmethod
1233 848 def fromTree(cls, tree, id):
... ... @@ -1243,65 +858,31 @@ class LexPActP:
1243 858 modifications = Modification.fromTree(tree._children[6])
1244 859 return cls(pactp, number, gender, negativity, words, inherent_sie, modifications, id)
1245 860  
1246   - def getId(self):
1247   - return self._id
1248   -
1249   - def store(self, position):
1250   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1251   - phraseologic=True,
1252   - defaults={'priority': 0})
1253   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='pactp',
1254   - phraseologic=False,
1255   - defaults={'priority': 0})
1256   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1257   - lexicalized_phrase=None,
1258   - text_rep=str(self._pactp))
1259   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1260   - lexicalized_phrase=lex,
1261   - text_rep=str(self))
1262   - position.phrase_types.add(phrase)
1263   - # @TODO: powinno być tylko dla obecnej,
1264   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1265   - for schema in position.schemata.all():
1266   - schema.phraseologic=True
1267   - schema.save()
  861 + def _lex_phrase(self):
  862 + return self._pactp
1268 863  
1269   -
1270 864 def __str__(self):
1271 865 return 'lex(' + str(self._pactp) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + self._inherent_sie + ',' + str(self._modification) + ')'
1272 866  
1273 867 def retyped(self, new_type):
1274 868 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._gender + ',' + self._negativity + ',' + str(self._words) + ',' + self._inherent_sie + ',' + str(self._modification) + ')'
1275   -
1276   -
1277   -class XP:
  869 +
  870 +
  871 +class XP(NonLexPhrase):
1278 872  
1279 873 def __init__(self, category, id):
  874 + super().__init__('xp', id)
1280 875 self._category = category
1281   - self._id = id
1282 876  
1283 877 @classmethod
1284 878 def fromTree(cls, tree, id):
1285 879 category = AdverbialCategory.fromTree(tree)
1286 880 return cls(category, id)
1287   -
1288   - def getId(self):
1289   - return self._id
1290 881  
1291   - def store(self, position):
1292   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='xp',
1293   - phraseologic=False,
1294   - defaults={'priority': 0})
1295   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1296   - attributes=get_attributes(main_type.name, self),
1297   - lexicalized_phrase=None,
1298   - text_rep=str(self))
1299   - position.phrase_types.add(phrase)
1300   -
1301 882 def __str__(self):
1302 883 return 'xp(' + str(self._category) + ')'
1303 884  
1304   -
  885 +
1305 886 class Dummy:
1306 887  
1307 888 def __init__(self):
... ... @@ -1310,13 +891,13 @@ class Dummy:
1310 891  
1311 892 def __str__(self):
1312 893 return str(self._attrs) + str(self._children)
1313   -
1314   -class LexXP:
  894 +
  895 +class LexXP(LexPhrase):
1315 896  
1316 897 def __init__(self, xp, lex, id):
  898 + super().__init__('xp', id)
1317 899 self._xp = xp
1318 900 self._lex = lex
1319   - self._id = id
1320 901  
1321 902 @classmethod
1322 903 def fromTree(cls, tree, id):
... ... @@ -1329,74 +910,35 @@ class LexXP:
1329 910 lex = phrase_from_tree(fake_node)
1330 911 return cls(xp, lex, id)
1331 912  
1332   - def getId(self):
1333   - return self._id
1334   -
1335   - def store(self, position):
1336   - print(self)
1337   - print(self._xp)
1338   - print(self._lex)
1339   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1340   - phraseologic=True,
1341   - defaults={'priority': 0})
1342   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='xp',
1343   - phraseologic=False,
1344   - defaults={'priority': 0})
1345   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1346   - attributes=get_attributes(lex_type.name, self._xp),
1347   - lexicalized_phrase=None,
1348   - text_rep=str(self._xp))
1349   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1350   - attributes=get_lex_attributes(lex_type.name, self),
1351   - lexicalized_phrase=lex,
1352   - text_rep=str(self))
1353   - position.phrase_types.add(phrase)
1354   - # @TODO: powinno być tylko dla obecnej,
1355   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1356   - for schema in position.schemata.all():
1357   - schema.phraseologic=True
1358   - schema.save()
1359   -
  913 + def _lex_phrase(self):
  914 + return self._xp
1360 915  
1361 916 def __str__(self):
1362 917 return self._lex.retyped(self._xp)
1363 918  
1364 919  
1365   -class AdvP:
  920 +class AdvP(NonLexPhrase):
1366 921  
1367 922 def __init__(self, category, id):
  923 + super().__init__('advp', id)
1368 924 self._category = category
1369   - self._id = id
1370 925  
1371 926 @classmethod
1372 927 def fromTree(cls, tree, id):
1373 928 category = AdverbialCategory.fromTree(tree)
1374 929 return cls(category, id)
1375   -
1376   - def getId(self):
1377   - return self._id
1378 930  
1379   - def store(self, position):
1380   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='advp',
1381   - phraseologic=False,
1382   - defaults={'priority': 0})
1383   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1384   - attributes=get_attributes(main_type.name, self),
1385   - lexicalized_phrase=None,
1386   - text_rep=str(self))
1387   - position.phrase_types.add(phrase)
1388   -
1389 931 def __str__(self):
1390 932 return 'advp(' + str(self._category) + ')'
1391   -
1392   -class LexAdvP:
  933 +
  934 +class LexAdvP(LexPhrase):
1393 935  
1394 936 def __init__(self, advp, degree, words, modification, id):
  937 + super().__init__('advp', id)
1395 938 self._advp = advp
1396 939 self._degree = degree
1397 940 self._words = words
1398 941 self._modification = modification
1399   - self._id = id
1400 942  
1401 943 @classmethod
1402 944 def fromTree(cls, tree, id):
... ... @@ -1406,75 +948,40 @@ class LexAdvP:
1406 948 modifications = Modification.fromTree(tree._children[3])
1407 949 return cls(advp, degree, words, modifications, id)
1408 950  
1409   - def getId(self):
1410   - return self._id
1411   -
1412   - def store(self, position):
1413   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1414   - phraseologic=True,
1415   - defaults={'priority': 0})
1416   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='advp',
1417   - phraseologic=False,
1418   - defaults={'priority': 0})
1419   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1420   - attributes=get_attributes(lex_type.name, self._advp),
1421   - lexicalized_phrase=None,
1422   - text_rep=str(self._advp))
1423   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1424   - attributes=get_lex_attributes(lex_type.name, self),
1425   - lexicalized_phrase=lex,
1426   - text_rep=str(self))
1427   - position.phrase_types.add(phrase)
1428   - # @TODO: powinno być tylko dla obecnej,
1429   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1430   - for schema in position.schemata.all():
1431   - schema.phraseologic=True
1432   - schema.save()
  951 + def _lex_phrase(self):
  952 + return self._advp
1433 953  
1434 954 def __str__(self):
1435 955 return 'lex(' + str(self._advp) + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
1436 956  
1437 957 def retyped(self, new_type):
1438 958 return 'lex(' + str(new_type) + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
1439   -
1440 959  
1441   -class AdjP:
  960 +
  961 +class AdjP(NonLexPhrase):
1442 962  
1443 963 def __init__(self, case, id):
  964 + super().__init__('adjp', id)
1444 965 self._case = case
1445   - self._id = id
1446 966  
1447 967 @classmethod
1448 968 def fromTree(cls, tree, id):
1449 969 case = Case(tree._children[0]._children[0]._attrs['value'])
1450 970 return cls(case, id)
1451   -
1452   - def getId(self):
1453   - return self._id
1454 971  
1455   - def store(self, position):
1456   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='adjp',
1457   - phraseologic=False,
1458   - defaults={'priority': 0})
1459   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1460   - attributes=get_attributes(main_type.name, self),
1461   - lexicalized_phrase=None,
1462   - text_rep=str(self))
1463   - position.phrase_types.add(phrase)
1464   -
1465 972 def __str__(self):
1466 973 return 'adjp(' + str(self._case) + ')'
1467 974  
1468   -class LexAdjP:
  975 +class LexAdjP(LexPhrase):
1469 976  
1470 977 def __init__(self, adjp, number, gender, degree, words, modification, id):
  978 + super().__init__('adjp', id)
1471 979 self._adjp = adjp
1472 980 self._number = number
1473 981 self._gender = gender
1474 982 self._degree = degree
1475 983 self._words = words
1476 984 self._modification = modification
1477   - self._id = id
1478 985  
1479 986 @classmethod
1480 987 def fromTree(cls, tree, id):
... ... @@ -1486,72 +993,36 @@ class LexAdjP:
1486 993 modifications = Modification.fromTree(tree._children[5])
1487 994 return cls(adjp, number, gender, degree, words, modifications, id)
1488 995  
1489   - def getId(self):
1490   - return self._id
  996 + def _lex_phrase(self):
  997 + return self._adjp
1491 998  
1492   - def store(self, position):
1493   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1494   - phraseologic=True,
1495   - defaults={'priority': 0})
1496   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='adjp',
1497   - phraseologic=False,
1498   - defaults={'priority': 0})
1499   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1500   - attributes=get_attributes(lex_type.name, self._adjp),
1501   - lexicalized_phrase=None,
1502   - text_rep=str(self._adjp))
1503   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1504   - attributes=get_lex_attributes(lex_type.name, self),
1505   - lexicalized_phrase=lex,
1506   - text_rep=str(self))
1507   - position.phrase_types.add(phrase)
1508   - # @TODO: powinno być tylko dla obecnej,
1509   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1510   - for schema in position.schemata.all():
1511   - schema.phraseologic=True
1512   - schema.save()
1513   -
1514   -
1515 999 def __str__(self):
1516 1000 return 'lex(' + str(self._adjp) + ',' + self._number + ',' + self._gender + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
1517 1001  
1518 1002 def retyped(self, new_type):
1519 1003 return 'lex(' + str(new_type) + ',' + self._number + ',' + self._gender + ',' + self._degree + ',' + str(self._words) + ',' + str(self._modification) + ')'
1520   -
1521 1004  
1522   -class Compar:
  1005 +
  1006 +class Compar(NonLexPhrase):
1523 1007  
1524 1008 def __init__(self, category, id):
  1009 + super().__init__('compar', id)
1525 1010 self._category = category
1526   - self._id = id
1527 1011  
1528 1012 @classmethod
1529 1013 def fromTree(cls, tree, id):
1530 1014 category = ComparCategory(tree._children[0]._children[0]._attrs['value'])
1531 1015 return cls(category, id)
1532   -
1533   - def getId(self):
1534   - return self._id
1535 1016  
1536   - def store(self, position):
1537   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='compar',
1538   - phraseologic=False,
1539   - defaults={'priority': 0})
1540   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1541   - attributes=get_attributes(main_type.name, self),
1542   - lexicalized_phrase=None,
1543   - text_rep=str(self))
1544   - position.phrase_types.add(phrase)
1545   -
1546 1017 def __str__(self):
1547 1018 return 'compar(' + str(self._category) + ')'
1548 1019  
1549   -class LexCompar:
  1020 +class LexCompar(LexPhrase):
1550 1021  
1551 1022 def __init__(self, compar, lexes, id):
  1023 + super().__init__('compar', id)
1552 1024 self._compar = compar
1553 1025 self._lexes = lexes
1554   - self._id = id
1555 1026  
1556 1027 @classmethod
1557 1028 def fromTree(cls, tree, id):
... ... @@ -1559,71 +1030,35 @@ class LexCompar:
1559 1030 lexes = [phrase_from_tree(subtree) for subtree in tree._children[1]._children[0]._children]
1560 1031 return cls(compar, lexes, id)
1561 1032  
1562   - def getId(self):
1563   - return self._id
  1033 + def _lex_phrase(self):
  1034 + return self._compar
1564 1035  
1565   - def store(self, position):
1566   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1567   - phraseologic=True,
1568   - defaults={'priority': 0})
1569   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='compar',
1570   - phraseologic=False,
1571   - defaults={'priority': 0})
1572   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1573   - attributes=get_attributes(lex_type.name, self._compar),
1574   - lexicalized_phrase=None,
1575   - text_rep=str(self._compar))
1576   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1577   - attributes=get_lex_attributes(lex_type.name, self),
1578   - lexicalized_phrase=lex,
1579   - text_rep=str(self))
1580   - position.phrase_types.add(phrase)
1581   - # @TODO: powinno być tylko dla obecnej,
1582   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1583   - for schema in position.schemata.all():
1584   - schema.phraseologic=True
1585   - schema.save()
1586   -
1587   -
1588 1036 def __str__(self):
1589 1037 return 'lex(' + str(self._compar) + ',' + ','.join([str(lex) for lex in self._lexes]) + ',natr)'
1590 1038  
1591 1039 def retyped(self, new_type):
1592 1040 return 'lex(' + str(new_type) + ',' + ','.join([str(lex) for lex in self._lexes]) + ',natr)'
1593   -
1594 1041  
1595   -class Qub:
  1042 +
  1043 +class Qub(NonLexPhrase):
1596 1044  
1597 1045 def __init__(self, id):
1598   - self._id = id
  1046 + super().__init__('qub', id, no_attributes=True)
1599 1047  
1600 1048 @classmethod
1601 1049 def fromTree(cls, tree, id):
1602 1050 return cls(id)
1603 1051  
1604   - def getId(self):
1605   - return self._id
1606   -
1607   - def store(self, position):
1608   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='qub',
1609   - phraseologic=False,
1610   - defaults={'priority': 0})
1611   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1612   - attributes=empty_attributes(),
1613   - lexicalized_phrase=None,
1614   - text_rep=str(self))
1615   - position.phrase_types.add(phrase)
1616   -
1617 1052 def __str__(self):
1618 1053 return 'qub'
1619 1054  
1620   -class LexQub:
  1055 +class LexQub(LexPhrase):
1621 1056  
1622 1057 def __init__(self, qub, words, modification, id):
  1058 + super().__init__('qub', id, no_attributes=True)
1623 1059 self._qub = qub
1624 1060 self._words = words
1625 1061 self._modification = modification
1626   - self._id = id
1627 1062  
1628 1063 @classmethod
1629 1064 def fromTree(cls, tree, id):
... ... @@ -1632,198 +1067,99 @@ class LexQub:
1632 1067 modifications = Modification.fromTree(tree._children[2])
1633 1068 return cls(qub, words, modifications, id)
1634 1069  
1635   - def getId(self):
1636   - return self._id
  1070 + def _lex_phrase(self):
  1071 + return self._qub
1637 1072  
1638   - def store(self, position):
1639   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
1640   - phraseologic=True,
1641   - defaults={'priority': 0})
1642   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name='qub',
1643   - phraseologic=False,
1644   - defaults={'priority': 0})
1645   - lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1646   - attributes=empty_attributes(),
1647   - lexicalized_phrase=None,
1648   - text_rep=str(self._qub))
1649   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1650   - attributes=empty_attributes(),
1651   - lexicalized_phrase=lex,
1652   - text_rep=str(self))
1653   - position.phrase_types.add(phrase)
1654   - # @TODO: powinno być tylko dla obecnej,
1655   - # choć lexy się w zasadzie nie powtarzają, więc to mały narzut
1656   - for schema in position.schemata.all():
1657   - schema.phraseologic=True
1658   - schema.save()
1659   -
1660 1073 def __str__(self):
1661 1074 return 'lex(' + str(self._qub) + ',' + str(self._words) + ',' + str(self._modification) + ')'
1662 1075  
1663 1076 def retyped(self, new_type):
1664 1077 return 'lex(' + str(new_type) + ',' + str(self._words) + ',' + str(self._modification) + ')'
1665   -
1666 1078  
1667   -class Refl:
  1079 +
  1080 +class Refl(NonLexPhrase):
1668 1081  
1669 1082 def __init__(self, id):
1670   - self._id = id
  1083 + super().__init__('refl', id, no_attributes=True)
1671 1084  
1672 1085 @classmethod
1673 1086 def fromTree(cls, tree, id):
1674 1087 return cls(id)
1675 1088  
1676   - def getId(self):
1677   - return self._id
1678   -
1679   - def store(self, position):
1680   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='refl',
1681   - phraseologic=False,
1682   - defaults={'priority': 0})
1683   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1684   - attributes=empty_attributes(),
1685   - lexicalized_phrase=None,
1686   - text_rep=str(self))
1687   - position.phrase_types.add(phrase)
1688   -
1689 1089 def __str__(self):
1690 1090 return 'refl'
1691 1091  
1692 1092  
1693   -class Recip:
  1093 +class Recip(NonLexPhrase):
1694 1094  
1695 1095 def __init__(self, id):
1696   - self._id = id
  1096 + super().__init__('recip', id, no_attributes=True)
1697 1097  
1698 1098 @classmethod
1699 1099 def fromTree(cls, tree, id):
1700 1100 return cls(id)
1701 1101  
1702   - def getId(self):
1703   - return self._id
1704   -
1705   - def store(self, position):
1706   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='recip',
1707   - phraseologic=False,
1708   - defaults={'priority': 0})
1709   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1710   - attributes=empty_attributes(),
1711   - lexicalized_phrase=None,
1712   - text_rep=str(self))
1713   - position.phrase_types.add(phrase)
1714   -
1715 1102 def __str__(self):
1716 1103 return 'recip'
1717   -
1718 1104  
1719   -class OR:
  1105 +
  1106 +class OR(NonLexPhrase):
1720 1107  
1721 1108 def __init__(self, id):
1722   - self._id = id
  1109 + super().__init__('or', id, no_attributes=True)
1723 1110  
1724 1111 @classmethod
1725 1112 def fromTree(cls, tree, id):
1726 1113 return cls(id)
1727 1114  
1728   - def getId(self):
1729   - return self._id
1730   -
1731   - def store(self, position):
1732   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='or',
1733   - phraseologic=False,
1734   - defaults={'priority': 0})
1735   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1736   - attributes=empty_attributes(),
1737   - lexicalized_phrase=None,
1738   - text_rep=str(self))
1739   - position.phrase_types.add(phrase)
1740   -
1741   -
1742 1115 def __str__(self):
1743 1116 return 'or'
1744   -
1745 1117  
1746   -class E:
  1118 +
  1119 +class E(NonLexPhrase):
1747 1120  
1748 1121 def __init__(self, id):
1749   - self._id = id
  1122 + super().__init__('E', id, no_attributes=True)
1750 1123  
1751 1124 @classmethod
1752 1125 def fromTree(cls, tree, id):
1753 1126 return cls(id)
1754 1127  
1755   - def getId(self):
1756   - return self._id
1757   -
1758   - def store(self, position):
1759   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='E',
1760   - phraseologic=False,
1761   - defaults={'priority': 0})
1762   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1763   - attributes=empty_attributes(),
1764   - lexicalized_phrase=None,
1765   - text_rep=str(self))
1766   - position.phrase_types.add(phrase)
1767   -
1768 1128 def __str__(self):
1769 1129 return 'E'
1770 1130  
1771 1131  
1772   -class PossP:
  1132 +class PossP(NonLexPhrase):
1773 1133  
1774 1134 def __init__(self, id):
1775   - self._id = id
  1135 + super().__init__('possp', id, no_attributes=True)
1776 1136  
1777 1137 @classmethod
1778 1138 def fromTree(cls, tree, id):
1779 1139 return cls(id)
1780 1140  
1781   - def getId(self):
1782   - return self._id
1783   -
1784   - def store(self, position):
1785   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='possp',
1786   - phraseologic=False,
1787   - defaults={'priority': 0})
1788   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1789   - attributes=empty_attributes(),
1790   - lexicalized_phrase=None,
1791   - text_rep=str(self))
1792   - position.phrase_types.add(phrase)
1793   -
1794 1141 def __str__(self):
1795 1142 return 'possp'
1796 1143  
1797 1144  
1798   -class DistrP:
  1145 +class DistrP(NonLexPhrase):
1799 1146  
1800 1147 def __init__(self, id):
1801   - self._id = id
  1148 + super().__init__('distrp', id, no_attributes=True)
1802 1149  
1803 1150 @classmethod
1804 1151 def fromTree(cls, tree, id):
1805 1152 return cls(id)
1806 1153  
1807   - def getId(self):
1808   - return self._id
1809   -
1810   - def store(self, position):
1811   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='distrp',
1812   - phraseologic=False,
1813   - defaults={'priority': 0})
1814   - phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1815   - attributes=empty_attributes(),
1816   - lexicalized_phrase=None,
1817   - text_rep=str(self))
1818   - position.phrase_types.add(phrase)
1819   -
1820 1154 def __str__(self):
1821 1155 return 'distrp'
1822 1156  
1823 1157  
1824   -class Fixed:
  1158 +# TODO subclass?
  1159 +class Fixed(Phrase):
1825 1160  
1826 1161 def __init__(self, phrase, text, id):
  1162 + super().__init__('fixed', id)
1827 1163 self._phrase = phrase
1828 1164 self._text = text
1829 1165 self._id = id
... ... @@ -1835,24 +1171,27 @@ class Fixed:
1835 1171 if ' ' in text or text[0].isupper():
1836 1172 text = '\'' + text + '\''
1837 1173 return cls(phrase, text, id)
1838   -
1839   - def getId(self):
1840   - return self._id
1841 1174  
1842   - def store(self, position):
1843   - main_type, _ = PhraseTypeModel.objects.get_or_create(name='fixed',
1844   - phraseologic=True,
1845   - defaults={'priority': 0})
  1175 + def store(self, position, stored_positions):
  1176 + main_type, _ = PhraseTypeModel.objects.get_or_create(name=self._name,
  1177 + phraseologic=True,
  1178 + defaults={'priority': 0})
1846 1179 # @TODO: to nie powinno być phrase
1847   - lex_type, _ = PhraseTypeModel.objects.get_or_create(name=str(self._phrase).split('(')[0],
  1180 +
  1181 +
  1182 + '''lex_type, _ = PhraseTypeModel.objects.get_or_create(name=str(self._phrase).split('(')[0],
1848 1183 phraseologic=False,
1849 1184 defaults={'priority': 0})
1850 1185 lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
1851 1186 attributes=get_attributes(lex_type.name, self._phrase),
1852 1187 lexicalized_phrase=None,
1853 1188 text_rep=str(self._phrase))
  1189 + '''
  1190 +
  1191 + lex = self._phrase.store(None, None)
  1192 +
1854 1193 phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
1855   - attributes=get_attributes('fixed', self),
  1194 + attributes=get_attributes(self, stored_positions),
1856 1195 lexicalized_phrase=lex,
1857 1196 text_rep=str(self))
1858 1197 position.phrase_types.add(phrase)
... ... @@ -1861,19 +1200,80 @@ class Fixed:
1861 1200 for schema in position.schemata.all():
1862 1201 schema.phraseologic=True
1863 1202 schema.save()
1864   -
  1203 +
1865 1204 def __str__(self):
1866 1205 return 'fixed(' + str(self._phrase) + ',' + self._text + ')'
1867 1206  
  1207 +'''def get_phrase_db_object(phrase, name, no_attributes=False):
  1208 + main_type, _ = PhraseTypeModel.objects.get_or_create(name=name,
  1209 + phraseologic=False,
  1210 + defaults={'priority': 0})
  1211 + attributes = empty_attributes() if no_attributes else get_attributes(main_type.name, phrase)
  1212 + phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
  1213 + attributes=attributes,
  1214 + lexicalized_phrase=None,
  1215 + text_rep=str(phrase))
  1216 + return phrase
  1217 +
  1218 +stored_modifications = dict()
  1219 +
  1220 +def get_lex_phrase_db_object(phrase, lex_phrase, name, stored_positions, no_attributes=False, no_lex_attributes=False):
  1221 + main_type, _ = PhraseTypeModel.objects.get_or_create(name='lex',
  1222 + phraseologic=True,
  1223 + defaults={'priority': 0})
  1224 + lex_type, _ = PhraseTypeModel.objects.get_or_create(name=name,
  1225 + phraseologic=False,
  1226 + defaults={'priority':0})
  1227 +
  1228 + attributes = empty_attributes() if no_attributes else get_attributes(lex_type.name, lex_phrase)
  1229 + lex, _ = PhraseType.objects.get_or_create(main_type=lex_type,
  1230 + attributes=attributes,
  1231 + lexicalized_phrase=None,
  1232 + text_rep=str(lex_phrase))
  1233 +
  1234 + if name not in ('compar', 'xp'):
  1235 + assert(len(phrase._words._lemmas) > 0)
  1236 + lemma_operator = LemmaOperator.objects.get(name=phrase._words._selection)
  1237 + lemma_cooccur = LemmaCooccur.objects.get(name=phrase._words._cooccur)
  1238 + lemmata = [Lemma.objects.get_or_create(name=lemma)[0] for lemma in phrase._words._lemmas]
  1239 + mod_key = str(phrase._modification)
  1240 + #print('\n*****************************', mod_key)
  1241 + if mod_key in stored_modifications:
  1242 + modification = stored_modifications[mod_key]
  1243 + #print('*************** already stored:', modification)
  1244 + else:
  1245 + mod_type = ModificationType.objects.get(name=phrase._modification._atr)
  1246 + modification = DBModification.objects.create(mod_type=mod_type)
  1247 + # TODO? this is hacky: done like in Schema, taking advantage of the fact
  1248 + # that both Schema and Modifications have a m2m field ‘positions’
  1249 + # TODO ask TB what exactly the 3rd argument to Position.store does
  1250 + mod_positions = set()
  1251 + for position in phrase._modification._dependents:
  1252 + position.store(modification, stored_positions, mod_positions, None)
  1253 + stored_modifications[mod_key] = modification
  1254 + #print('*************** now stored:', modification)
  1255 + else:
  1256 + lemma_operator, lemma_cooccur, lemmata, modification = None, None, None, None
  1257 +
  1258 + attributes = empty_attributes() if no_lex_attributes else get_lex_attributes(lex_type.name, phrase)
  1259 + phrase, _ = PhraseType.objects.get_or_create(main_type=main_type,
  1260 + attributes=attributes,
  1261 + lexicalized_phrase=lex,
  1262 + lemma_operator=lemma_operator,
  1263 + lemma_cooccur=lemma_cooccur,
  1264 + modification=modification,
  1265 + text_rep=str(phrase))
  1266 + if lemmata:
  1267 + phrase.lemmata.set(lemmata)
  1268 + return phrase
  1269 +'''
1868 1270  
1869 1271 def phrase_from_tree(tree):
1870 1272 if 'xml:id' in tree._attrs:
1871 1273 id = tree._attrs['xml:id']
1872 1274 else:
1873 1275 id = None
1874   - if tree._attrs['type'] == 'adverb':
1875   - return Adverb.fromTree(tree, id)
1876   - elif tree._attrs['type'] == 'np':
  1276 + if tree._attrs['type'] == 'np':
1877 1277 return NP.fromTree(tree, id)
1878 1278 elif tree._attrs['type'] == 'adjp':
1879 1279 return AdjP.fromTree(tree, id)
... ... @@ -1882,13 +1282,13 @@ def phrase_from_tree(tree):
1882 1282 elif tree._attrs['type'] == 'pactp':
1883 1283 return PActP.fromTree(tree, id)
1884 1284 elif tree._attrs['type'] == 'prepppasp':
1885   - return PrepPPasP.fromTree(tree, id)
  1285 + return PrepPPasP.fromTree(tree, id)
1886 1286 elif tree._attrs['type'] == 'prepnp':
1887 1287 return PrepNP.fromTree(tree, id)
1888 1288 elif tree._attrs['type'] == 'nump':
1889   - return NumP.fromTree(tree, id)
  1289 + return NumP.fromTree(tree, id)
1890 1290 elif tree._attrs['type'] == 'prepnump':
1891   - return PrepNumP.fromTree(tree, id)
  1291 + return PrepNumP.fromTree(tree, id)
1892 1292 elif tree._attrs['type'] == 'prepadjp':
1893 1293 return PrepAdjP.fromTree(tree, id)
1894 1294 elif tree._attrs['type'] == 'comprepnp':
... ... @@ -1904,7 +1304,7 @@ def phrase_from_tree(tree):
1904 1304 elif tree._attrs['type'] == 'infp':
1905 1305 return InfP.fromTree(tree, id)
1906 1306 elif tree._attrs['type'] == 'prepgerp':
1907   - return PrepGerP.fromTree(tree, id)
  1307 + return PrepGerP.fromTree(tree, id)
1908 1308 elif tree._attrs['type'] == 'xp':
1909 1309 return XP.fromTree(tree, id)
1910 1310 elif tree._attrs['type'] == 'advp':
... ... @@ -1920,7 +1320,7 @@ def phrase_from_tree(tree):
1920 1320 elif tree._attrs['type'] == 'or':
1921 1321 return OR.fromTree(tree, id)
1922 1322 elif tree._attrs['type'] == 'E':
1923   - return E.fromTree(tree, id)
  1323 + return E.fromTree(tree, id)
1924 1324 elif tree._attrs['type'] == 'qub':
1925 1325 return Qub.fromTree(tree, id)
1926 1326 elif tree._attrs['type'] == 'possp':
... ...
importer/PhraseAttributes.py
... ... @@ -4,22 +4,22 @@
4 4 from syntax.models_phrase import *
5 5 from syntax.models import Position
6 6  
7   -def get_case(name):
  7 +def get_case(name, **kwargs):
8 8 return Case.objects.get(name=name)
9 9  
10   -def get_prep(name):
  10 +def get_prep(name, **kwargs):
11 11 prep, _ = Preposition.objects.get_or_create(name=name)
12 12 return prep
13 13  
14   -def get_comprep(name):
  14 +def get_comprep(name, **kwargs):
15 15 prep, _ = ComplexPreposition.objects.get_or_create(name=name)
16 16 return prep
17 17  
18   -def get_cptype(name):
  18 +def get_cptype(name, **kwargs):
19 19 cptype, _ = CPType.objects.get_or_create(name=name)
20 20 return cptype
21 21  
22   -def get_cpreals(names):
  22 +def get_cpreals(names, **kwargs):
23 23 cpreals = []
24 24 if names:
25 25 for name in names:
... ... @@ -27,51 +27,49 @@ def get_cpreals(names):
27 27 cpreals.append(cpreal)
28 28 return cpreals
29 29  
30   -def get_aspect(name):
  30 +def get_aspect(name, **kwargs):
31 31 return PhraseAspect.objects.get(name=name)
32 32  
33   -def get_neg(name):
  33 +def get_neg(name, **kwargs):
34 34 return PhraseNegativity.objects.get(name=name)
35 35  
36   -def get_inhsie(name):
  36 +def get_inhsie(name, **kwargs):
37 37 return PhraseInherentSie.objects.get(name=name)
38 38  
39   -def get_advcat(name):
  39 +def get_advcat(name, **kwargs):
40 40 return AdverbialCategory.objects.get(name=name)
41 41  
42   -def get_comparcat(name):
  42 +def get_comparcat(name, **kwargs):
43 43 comparcat, _ = ComparCategory.objects.get_or_create(name=name)
44 44 return comparcat
45 45  
46   -def get_num(name):
  46 +def get_num(name, **kwargs):
47 47 return Number.objects.get(name=name)
48 48  
49   -def get_gend(name):
  49 +def get_gend(name, **kwargs):
50 50 return Gender.objects.get(name=name)
51 51  
52   -def get_deg(name):
  52 +def get_deg(name, **kwargs):
53 53 return Degree.objects.get(name=name)
54 54  
55   -def store_phrase(phrase):
56   - dummy_postition = Position.objects.get(id=1)
57   - phrase.store(dummy_postition)
58   - # TODO? a better solution: make store() return the stored object?
59   - # this is ugly: retrieving the just-stored phrase by its text_rep...
60   - return PhraseType.objects.get(text_rep=str(phrase))
  55 +#def store_phrase(phrase):
  56 +# dummy_postition = Position.objects.get(id=1)
  57 +# return phrase.store(dummy_postition, dict())
61 58  
62 59 # for compar
63   -def get_lexes(lexes):
64   - return [store_phrase(lex) for lex in lexes]
  60 +def get_lexes(phrases, stored_positions=None):
  61 + #return [store_phrase(lex) for lex in lexes]
  62 + return [lex.store(None, stored_positions) for lex in phrases]
65 63  
66 64 # for lex(xp), lex(advp)
67   -def get_lex(phrase):
68   - return store_phrase(phrase)
  65 +def get_lex(phrase, stored_positions=None):
  66 + return phrase.store(None, stored_positions)
69 67  
70 68 # for fixed phrases
71   -def get_phrase(phrase):
72   - return store_phrase(phrase)
  69 +def get_phrase(phrase, stored_positions=None):
  70 + return phrase.store(None, stored_positions)
73 71  
74   -def get_text(text):
  72 +def get_text(text, **kwargs):
75 73 return text
76 74  
77 75 #-------------------------------------------------------------------------------
... ... @@ -149,6 +147,18 @@ attrs_helpers = {
149 147 'gend' : lambda x: x._gender,
150 148 'neg' : lambda x: x._negativity,
151 149 }),
  150 + 'pactp' : AttributesHelper(
  151 + attrs_cls=PActPAttributes,
  152 + lex_attrs_cls=LexPActPAttributes,
  153 + attr_getters={
  154 + 'case' : lambda x: x._case._value,
  155 + },
  156 + lex_attr_getters={
  157 + 'num' : lambda x: x._number,
  158 + 'gend' : lambda x: x._gender,
  159 + 'neg' : lambda x: x._negativity,
  160 + 'inhsie' : lambda x: x._inherent_sie,
  161 + }),
152 162 'prepnp' : AttributesHelper(
153 163 attrs_cls=PrepNPAttributes,
154 164 lex_attrs_cls=LexPrepNPAttributes,
... ... @@ -302,24 +312,35 @@ def empty_attributes():
302 312 attr, _ = EmptyAttributes.objects.get_or_create(empty='_')
303 313 return attr
304 314  
305   -def do_get_attributes(phrase_type, phrase_obj, lex):
306   - helper = attrs_helpers[phrase_type]
  315 +stored_attributes = dict()
  316 +
  317 +def do_get_attributes(phrase, stored_positions, lex):
  318 + helper = attrs_helpers[phrase._name]
307 319 cls = helper.lex_attrs_cls if lex else helper.attrs_cls
308 320 attr_getters = helper.lex_attr_getters if lex else helper.attr_getters
309 321 m2m_attr_getters = helper.lex_m2m_attr_getters if lex else helper.m2m_attr_getters
310   - kwargs = { key : eval('get_{}'.format(key))(getter(phrase_obj)) for key, getter in attr_getters.items() }
311   - m2m_attrs = { key : eval('get_{}'.format(key))(getter(phrase_obj)) for key, getter in m2m_attr_getters.items() }
  322 + kwargs = { key : eval('get_{}'.format(key))(getter(phrase), stored_positions=stored_positions) for key, getter in attr_getters.items() }
  323 + m2m_attrs = { key : eval('get_{}'.format(key))(getter(phrase), stored_positions=stored_positions) for key, getter in m2m_attr_getters.items() }
312 324 if cls is not None:
313   - attrs, _ = cls.objects.get_or_create(**kwargs)
314   - for key, values in m2m_attrs.items():
315   - if values:
316   - getattr(attrs, key).set(values)
317   - print(attrs)
  325 + if not m2m_attrs:
  326 + # atomic attributes only – uniqueness of attr objects assured by get_or_create
  327 + attrs, _ = cls.objects.get_or_create(**kwargs)
  328 + else:
  329 + # multi-valued attributes (m2m fields) – can’t use get_or_create to assure uniqueness
  330 + attrs_key = str(sorted(kwargs.items()) + sorted(m2m_attrs.items()))
  331 + if attrs_key in stored_attributes:
  332 + attrs = stored_attributes[attrs_key]
  333 + else:
  334 + attrs = cls.objects.create(**kwargs)
  335 + for key, values in m2m_attrs.items():
  336 + if values:
  337 + getattr(attrs, key).set(values)
  338 + stored_attributes[attrs_key] = attrs
318 339 return attrs
319 340 return None
320 341  
321   -def get_attributes(phrase_type, phrase_obj, **kwargs):
322   - return do_get_attributes(phrase_type, phrase_obj, False, **kwargs)
  342 +def get_attributes(phrase, stored_positions):
  343 + return do_get_attributes(phrase, stored_positions, False)
323 344  
324   -def get_lex_attributes(phrase_type, phrase_obj, **kwargs):
325   - return do_get_attributes(phrase_type, phrase_obj, True, **kwargs)
  345 +def get_lex_attributes(phrase, stored_positions):
  346 + return do_get_attributes(phrase, stored_positions, True)
... ...
importer/Position.py
... ... @@ -17,13 +17,13 @@ class Function:
17 17 value = tree._children[0]._attrs['value']
18 18 return cls(value)
19 19  
20   -# @TODO: dwa rodzaje kontroli
  20 +# @TODO: dwa rodzaje kontroli
21 21 class Control:
22 22  
23 23 def __init__(self, function):
24 24 self._function = function
25   -
26   -
  25 +
  26 +
27 27 class Position:
28 28  
29 29 def __init__(self, position_id, function, controls, phrases, phrase_ids):
... ... @@ -54,6 +54,15 @@ class Position:
54 54 if phrase.getId() is not None:
55 55 phrase_ids[phrase.getId()] = phrase
56 56 position_id.append(int(phrase.getId().split('-')[0].split('.')[-1]))
  57 + # TODO So far, only schema positions were stored in database
  58 + # and all phrases had an id from xml:id attribute. Now we add
  59 + # modification positions where phrases have no id, so the
  60 + # text_rep is used. Is this enough? Perhaps text_rep could also be used
  61 + # for schema position phrases?
  62 + else:
  63 + phr_id = str(phrase)
  64 + phrase_ids[phr_id] = phrase
  65 + position_id.append(phr_id)
57 66  
58 67 position_id.sort()
59 68 position_id = tuple(position_id)
... ... @@ -91,7 +100,8 @@ class Position:
91 100 i += 1
92 101 extended_id = (tuple(label), self._id, i)
93 102 schema_positions.add(extended_id)
94   - # self._id is None for parts of lex atr
  103 + # self._id is None for parts of lex atr
  104 + # TODO (KK) ^^^
95 105 if self._id is not None and extended_id in stored_positions:
96 106 position = syntax.models.Position.objects.get(id = stored_positions[extended_id])
97 107 self._db_id = position.id
... ... @@ -103,8 +113,8 @@ class Position:
103 113 phrases_count=len(self._phrases))
104 114 self._db_id = position.id
105 115 for phrase in self._phrases:
106   - print('==============', phrase)
107   - phrase.store(position)
  116 + #print('=================', type(phrase), phrase)
  117 + phrase.store(position, stored_positions)
108 118 phrase_text = str(phrase)
109 119 desc_count = NaturalLanguageDescription.objects.filter(
110 120 negativity=negativity,
... ... @@ -124,7 +134,7 @@ class Position:
124 134 desc.save()
125 135 if self._id is not None:
126 136 stored_positions[extended_id] = position.id
127   -
  137 +
128 138 def getPhraseIds(self):
129 139 return self._phrase_ids
130 140  
... ... @@ -158,7 +168,7 @@ class Position:
158 168 if self._function is None:
159 169 return pre + '[' + ','.join(temp) + ']' + post
160 170 elif self._function._value == 'subj':
161   - return pre + 'subj([' + ','.join(temp) + '])' + post
  171 + return pre + 'subj([' + ','.join(temp) + '])' + post
162 172 elif self._function._value == 'obj':
163 173 return pre + 'obj([' + ','.join(temp) + '])' + post
164 174 elif self._function._value == 'head':
... ...
semantics/models.py
... ... @@ -38,6 +38,7 @@ class Argument(models.Model):
38 38 def __str__(self):
39 39 return str(self.role)
40 40  
  41 +
41 42 class ArgumentRole(models.Model):
42 43 role = models.ForeignKey('SemanticRole', on_delete=models.PROTECT)
43 44 attribute = models.ForeignKey('RoleAttribute', null=True, on_delete=models.PROTECT)
... ... @@ -47,7 +48,8 @@ class ArgumentRole(models.Model):
47 48 return str(self.role)
48 49 else:
49 50 return str(self.role) + " " + str(self.attribute)
50   -
  51 +
  52 +
51 53 class SemanticRole(models.Model):
52 54 role = models.CharField(max_length=20)
53 55 color = models.CharField(max_length=11, null=True)
... ... @@ -59,6 +61,7 @@ class SemanticRole(models.Model):
59 61 def __str__(self):
60 62 return self.role
61 63  
  64 +
62 65 class RoleAttribute(models.Model):
63 66 attribute = models.CharField(max_length=20)
64 67 gradient = models.CharField(max_length=10, null=True)
... ... @@ -70,6 +73,7 @@ class RoleAttribute(models.Model):
70 73 def __str__(self):
71 74 return self.attribute
72 75  
  76 +
73 77 class PredefinedSelectionalPreference(models.Model):
74 78 key = models.CharField(max_length=20, unique=True)
75 79 # name = TODO: wymaga lokalizacji
... ...
syntax/admin.py
... ... @@ -3,7 +3,7 @@ from django.contrib import admin
3 3 from .models import Aspect, Control, InherentSie, Negativity, Position, \
4 4 PredicativeControl, Predicativity, Schema, SchemaOpinion, Subentry, SyntacticFunction
5 5  
6   -from .models_phrase import PhraseType, PhraseTypeModel
  6 +from .models_phrase import PhraseType, PhraseTypeModel, Modification
7 7  
8 8 admin.site.register(Aspect)
9 9 admin.site.register(Control)
... ... @@ -11,6 +11,7 @@ admin.site.register(InherentSie)
11 11 admin.site.register(Negativity)
12 12 admin.site.register(PhraseType)
13 13 admin.site.register(PhraseTypeModel)
  14 +admin.site.register(Modification)
14 15 admin.site.register(Position)
15 16 admin.site.register(PredicativeControl)
16 17 admin.site.register(Predicativity)
... ...
syntax/management/commands/import_tei.py
... ... @@ -14,6 +14,8 @@ from syntax.models import SchemaOpinion, Aspect, InherentSie, Negativity, Predic
14 14 from syntax.models_phrase import (
15 15 Case, PhraseAspect, AdverbialCategory, PhraseNegativity, PhraseInherentSie,
16 16 Number, Gender, Degree,
  17 + LemmaOperator, LemmaCooccur,
  18 + ModificationType,
17 19 )
18 20 from semantics.models import FrameOpinion, ArgumentRole, SemanticRole, RoleAttribute, PredefinedSelectionalPreference, SelectionalPreferenceRelation
19 21  
... ... @@ -27,6 +29,8 @@ class Command(BaseCommand):
27 29  
28 30 def import_tei():
29 31 xml_file = os.path.join(BASE_DIR, 'data', 'tei', 'walenty_tei.xml')
  32 + #xml_file = os.path.join(BASE_DIR, 'data', 'walenty', 'walenty_20200801.xml')
  33 + #xml_file = os.path.join(BASE_DIR, 'data', 'walenty', 'walenty_20200801_smaller.xml')
30 34  
31 35 xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), xml_file)
32 36  
... ... @@ -62,6 +66,8 @@ def import_constants():
62 66 import_examples_sources()
63 67 import_examples_opinions()
64 68 import_phrase_attributes()
  69 + import_lemma_operators()
  70 + import_modification_types()
65 71 pass
66 72  
67 73 def import_poses():
... ... @@ -232,3 +238,19 @@ def import_degrees():
232 238 for pri, name in degrees:
233 239 degree = Degree(name=name, priority=pri)
234 240 degree.save()
  241 +
  242 +def import_lemma_operators():
  243 + operators = [(1, u'xor'), (2, u'or')]
  244 + for pri, name in operators:
  245 + operator = LemmaOperator(name=name, priority=pri)
  246 + operator.save()
  247 + cooccurs = [(1, u'concat'), (2, u'coord')]
  248 + for pri, name in cooccurs:
  249 + cooccur = LemmaCooccur(name=name, priority=pri)
  250 + cooccur.save()
  251 +
  252 +def import_modification_types():
  253 + modtypes = [(1, u'ratr'), (2, u'ratr1'), (3, u'atr'), (4, u'atr1'), (5, u'natr')]
  254 + for pri, name in modtypes:
  255 + modtype = ModificationType(name=name, priority=pri)
  256 + modtype.save()
... ...
syntax/models_phrase.py
1 1 from django.db import models
2 2  
  3 +from syntax.models import Position
3 4  
4 5 # === Atomic phrase attributes =================================================
5 6  
... ... @@ -115,13 +116,9 @@ class ComparCategory(models.Model):
115 116  
116 117 class PhraseTypeAttributes(models.Model):
117 118 pass
118   - #class Meta:
119   - # abstract = True
120 119  
121 120 class LexPhraseTypeAttributes(PhraseTypeAttributes):
122 121 pass
123   - #class Meta:
124   - # abstract = True
125 122  
126 123 # TODO a better solution for possp, E, qub etc.?
127 124 class EmptyAttributes(PhraseTypeAttributes):
... ... @@ -192,6 +189,26 @@ class LexPPasPAttributes(LexPhraseTypeAttributes):
192 189  
193 190 #-------------------------------------------------------------------------------
194 191  
  192 +class PActPAttributes(PhraseTypeAttributes):
  193 + case = models.OneToOneField(Case, on_delete=models.PROTECT)
  194 +
  195 + def __str__(self):
  196 + return '({})'.format(self.case)
  197 +
  198 +class LexPActPAttributes(LexPhraseTypeAttributes):
  199 + num = models.ForeignKey(Number, on_delete=models.PROTECT)
  200 + gend = models.ForeignKey(Gender, on_delete=models.PROTECT)
  201 + neg = models.ForeignKey(PhraseNegativity, on_delete=models.PROTECT)
  202 + inhsie = models.ForeignKey(PhraseInherentSie, on_delete=models.PROTECT)
  203 +
  204 + class Meta:
  205 + unique_together = ['num', 'gend', 'neg', 'inhsie']
  206 +
  207 + def __str__(self):
  208 + return '({},{},{})'.format(self.num, self.gend, self.neg, self.inhsie)
  209 +
  210 +#-------------------------------------------------------------------------------
  211 +
195 212 class PrepNPAttributes(PhraseTypeAttributes):
196 213 case = models.ForeignKey(Case, on_delete=models.PROTECT)
197 214 prep = models.ForeignKey(Preposition, on_delete=models.PROTECT)
... ... @@ -421,8 +438,46 @@ class FixedAttributes(PhraseTypeAttributes):
421 438 def __str__(self):
422 439 return '({},{})'.format(self.phrase, self.text)
423 440  
424   -# ------------------------------------------------------------------------------
  441 +# === Lex lemmata ==============================================================
  442 +
  443 +class LemmaOperator(models.Model):
  444 + name = models.CharField(max_length=16, unique=True)
  445 + priority = models.PositiveIntegerField()
  446 + class Meta:
  447 + ordering = ['priority']
  448 + def __str__(self):
  449 + return self.name
  450 +
  451 +class LemmaCooccur(models.Model):
  452 + name = models.CharField(max_length=16, unique=True)
  453 + priority = models.PositiveIntegerField()
  454 + class Meta:
  455 + ordering = ['priority']
  456 + def __str__(self):
  457 + return self.name
  458 +
  459 +class Lemma(models.Model):
  460 + name = models.CharField(max_length=32, unique=True)
  461 + class Meta:
  462 + ordering = ['name']
  463 + def __str__(self):
  464 + return self.name
  465 +
  466 +# === Lex modifications ========================================================
425 467  
  468 +class ModificationType(models.Model):
  469 + name = models.CharField(max_length=16, unique=True)
  470 + priority = models.PositiveIntegerField()
  471 + class Meta:
  472 + ordering = ['priority']
  473 + def __str__(self):
  474 + return self.name
  475 +
  476 +class Modification(models.Model):
  477 + mod_type = models.ForeignKey(ModificationType, on_delete=models.PROTECT)
  478 + positions = models.ManyToManyField(Position)
  479 + def __str__(self):
  480 + return '{}({})'.format(self.mod_type, '+'.join(map(str, self.positions.all())))
426 481  
427 482 # === Phrase objects ===========================================================
428 483  
... ... @@ -432,10 +487,14 @@ class PhraseType(models.Model):
432 487 attributes = models.ForeignKey(PhraseTypeAttributes, on_delete=models.PROTECT)
433 488 lexicalized_phrase = models.ForeignKey('PhraseType', related_name='lex_phrases', null=True,
434 489 on_delete=models.PROTECT)
  490 + lemma_operator = models.ForeignKey(LemmaOperator, null=True, on_delete=models.PROTECT)
  491 + lemma_cooccur = models.ForeignKey(LemmaCooccur, null=True, on_delete=models.PROTECT)
  492 + lemmata = models.ManyToManyField(Lemma)
  493 + modification = models.ForeignKey(Modification, null=True, on_delete=models.PROTECT)
435 494 text_rep = models.TextField(unique=True)
436 495  
437 496 class Meta:
438   - ordering = ['main_type__priority']
  497 + ordering = ['main_type__priority', 'text_rep']
439 498  
440 499 def __str__(self):
441 500 return self.text_rep
... ...