Commit e28ad80d42b1c90b95dbae82bc8b6474fa5d8105

Authored by janek@kublik
1 parent 319b10d0

migracja Pattern

--HG--
branch : beta
common/models.py
1 1 # -*- coding: utf-8 -*-
2 2  
3   -from django.db.models import Model, CharField, TextField
  3 +from django.db.models import Model, CharField, TextField, Manager
4 4 from django.utils.translation import ugettext_lazy as _
5 5  
6 6  
... ... @@ -8,3 +8,11 @@ class FlatPage(Model):
8 8 text_id = CharField(max_length=20, verbose_name=_(u'id'))
9 9 title = CharField(max_length=160, verbose_name=_(u'title'))
10 10 html_content = TextField(verbose_name=_(u'HTML content'), blank=True)
  11 +
  12 +
  13 +class NotDeletedManager(Manager):
  14 + use_for_related_field = True
  15 +
  16 + def get_queryset(self):
  17 + return super(NotDeletedManager, self).get_queryset().filter(
  18 + deleted=False)
11 19 \ No newline at end of file
... ...
common/templates/main_menu.html
... ... @@ -6,7 +6,7 @@
6 6 {% if perms.dictionary.view_lexeme %}
7 7 <li><a href="{% url 'lexeme_view' %}">{% trans 'Lexemes' %}</a></li>
8 8 {% endif %}
9   - {% if perms.dictionary.view_pattern %}
  9 + {% if perms.patterns.view_pattern %}
10 10 <li><a href="{% url 'pattern_view' %}">{% trans 'Patterns' %}</a></li>
11 11 {% endif %}
12 12 {% if user.is_authenticated %}
... ...
dictionary/ajax_lexeme_view.py
... ... @@ -10,10 +10,12 @@ from django.db.models import Max
10 10 from dictionary.ajax_lexeme_slickgrid import LexemeQuery
11 11 from dictionary.auto_derivatives import lexeme_derivatives, create_derivative
12 12 from dictionary.models import Lexeme, LexemeInflectionPattern, PartOfSpeech, \
13   - Pattern, Vocabulary, Qualifier, prepare_table, ClassificationValue, \
  13 + Vocabulary, Qualifier, ClassificationValue, \
14 14 CrossReference, InputLexeme, CrossReferenceType, editable_vocabularies, \
15 15 visible_qualifiers, LexemeAttributeValue, Gender, LexemeAttribute, \
16 16 LexemeAV, LexemeCV, visible_vocabularies, LexemeList, filter_visible, Ending
  17 +from dictionary.util import prepare_table
  18 +from patterns.models import Pattern
17 19 from dictionary.forms import LexemeEditForm, LIPEditForm, ClassificationForm, \
18 20 CrossReferenceForm, ActionFieldForm, ACTION_FIELDS,\
19 21 LexemeOpenAttributeForm, LexemeClosedAttributeForm, \
... ...
dictionary/auto_derivatives.py
1 1 # -*- coding: utf-8 -*-
2 2 from django.db.models import Max
3 3 from dictionary.models import Ending, Lexeme, LexemeInflectionPattern, \
4   - Pattern, Gender, LexemeAttributeValue, LexemeAttribute, REVERSE_CR_TYPE
  4 + Gender, LexemeAttributeValue, LexemeAttribute, REVERSE_CR_TYPE
  5 +from patterns.models import Pattern
5 6  
6 7 VOWELS = u'aeiouyąęó'
7 8  
... ...
dictionary/forms.py
... ... @@ -8,9 +8,10 @@ from django.utils.translation import ugettext_lazy as _
8 8  
9 9 from common.forms import disable_field
10 10 from common.util import GroupDict
11   -from dictionary.models import Lexeme, LexemeInflectionPattern, Pattern, \
12   - Vocabulary, CrossReference, Qualifier, editable_vocabularies, \
13   - editable_qualifiers, LexemeAttributeValue
  11 +from dictionary.models import Lexeme, LexemeInflectionPattern, Vocabulary, \
  12 + CrossReference, Qualifier, editable_vocabularies, editable_qualifiers, \
  13 + LexemeAttributeValue
  14 +from patterns.models import Pattern
14 15  
15 16  
16 17 # ze StackOverflow, http://stackoverflow.com/questions/3737116/
... ...
dictionary/management/commands/create_pattern_examples.py
... ... @@ -3,7 +3,8 @@
3 3 from django.core.management.base import BaseCommand
4 4 from django.db.transaction import atomic
5 5  
6   -from dictionary.models import Pattern, PatternExample, Gender
  6 +from dictionary.models import PatternExample, Gender
  7 +from patterns.models import Pattern
7 8  
8 9  
9 10 class Command(BaseCommand):
... ...
dictionary/management/commands/import_data.py
... ... @@ -14,7 +14,7 @@ from dictionary.models import CrossReference, Ending, LexemeInflectionPattern, \
14 14 PartOfSpeech, Pattern, Qualifier, Vocabulary, \
15 15 LexemeAttribute, Gender, LexemeAttributeValue, ClassificationValue, \
16 16 LexemeCV, LexemeAV, Variant, Classification, History
17   -from patterns.models import InflectionType, BaseFormLabel, PatternType
  17 +from patterns.models import InflectionType, BaseFormLabel, PatternType, Pattern
18 18  
19 19 MINI_MODE = True # do debugowania
20 20 MINI_LEXEME_COUNT = 1000
... ...
dictionary/management/commands/import_skr.py
... ... @@ -7,8 +7,8 @@ from django.db.transaction import atomic
7 7  
8 8 from common.util import no_history
9 9 from dictionary.management.commands.import_data import get_cursor
10   -from dictionary.models import Vocabulary, Qualifier, Lexeme, Pattern, \
11   - LexemeAttribute, LexemeInflectionPattern
  10 +from dictionary.models import Vocabulary, Qualifier, Lexeme, LexemeAttribute, LexemeInflectionPattern
  11 +from patterns.models import Pattern
12 12  
13 13  
14 14 class Command(BaseCommand):
... ...
dictionary/management/commands/import_witek.py
... ... @@ -6,8 +6,9 @@ from django.db.transaction import atomic
6 6  
7 7 from common.util import uniopen, no_history
8 8 from dictionary.models import Lexeme, Vocabulary, LexemeInflectionPattern, \
9   - Pattern, Qualifier, ClassificationValue, LexemeCV, Gender, \
  9 + Qualifier, ClassificationValue, LexemeCV, Gender, \
10 10 LexemeAttributeValue, CrossReferenceType, CrossReference
  11 +from patterns.models import Pattern
11 12  
12 13  
13 14 class Command(BaseCommand):
... ...
dictionary/management/commands/load_import.py
... ... @@ -6,9 +6,9 @@ from django.core.management.base import BaseCommand
6 6 from django.db.transaction import atomic
7 7  
8 8 from common.util import no_history, debug, uniopen
9   -from dictionary.models import Lexeme, Pattern, \
10   - LexemeInflectionPattern, PartOfSpeech, Vocabulary, InflectionCharacteristic, \
  9 +from dictionary.models import Lexeme, LexemeInflectionPattern, PartOfSpeech, Vocabulary, InflectionCharacteristic, \
11 10 CrossReference, CrossReferenceType, ClassificationValue
  11 +from patterns.models import Pattern
12 12  
13 13 START_ID = 500000
14 14 END_ID = 1000000
... ...
dictionary/management/commands/stale/convert_derivatives.py
... ... @@ -2,7 +2,8 @@
2 2 from django.core.management.base import BaseCommand
3 3 import itertools
4 4 from common.util import no_history
5   -from dictionary.models import PartOfSpeech, Pattern, Gender
  5 +from dictionary.models import PartOfSpeech, Gender
  6 +from patterns.models import Pattern
6 7  
7 8  
8 9 class Command(BaseCommand):
... ...
dictionary/management/commands/stale/fix_morfologik.py
... ... @@ -2,8 +2,9 @@
2 2  
3 3 from django.core.management.base import BaseCommand
4 4 from common.util import no_history, debug
5   -from dictionary.models import Lexeme, Pattern, Vocabulary, \
  5 +from dictionary.models import Lexeme, Vocabulary, \
6 6 Qualifier, InflectionCharacteristic
  7 +from patterns.models import Pattern
7 8  
8 9  
9 10 class Command(BaseCommand):
... ...
dictionary/management/commands/stale/import_kipi.py
... ... @@ -4,7 +4,7 @@ from django.core.management.base import BaseCommand
4 4 from common.util import debug, suffixes, cut_end, uniopen
5 5 from dictionary.models import Lexeme, Pattern, InflectionCharacteristic, \
6 6 Ending
7   -from patterns.models import BaseFormLabel
  7 +from patterns.models import BaseFormLabel, Pattern
8 8 from dictionary.management.commands.import_morfologik import create_lexeme, \
9 9 create_lip, print_data, find_minimal_sets, blacklist_filter, join_many, \
10 10 join, print_forms
... ...
dictionary/management/commands/stale/import_morfologik.py
... ... @@ -8,7 +8,7 @@ from django.core.management.base import BaseCommand
8 8 from common.util import suffixes, cut_end, debug, GroupDict, uniopen
9 9 from dictionary.models import Pattern, Lexeme, InflectionCharacteristic, \
10 10 Ending, CrossReference, BaseFormLabel, Vocabulary
11   -from patterns.models import InflectionType, BaseFormLabel
  11 +from patterns.models import InflectionType, BaseFormLabel, Pattern
12 12 from dictionary.util import expand_tag, compare_patterns
13 13 from patterns.pattern_blacklist import blacklist
14 14  
... ...
dictionary/management/commands/stale/import_resztki.py
... ... @@ -7,7 +7,7 @@ from django.core.management.base import BaseCommand
7 7 from common.util import suffixes, cut_end, debug, GroupDict
8 8 from dictionary.models import Pattern, Lexeme, InflectionCharacteristic, \
9 9 Ending, BaseFormLabel
10   -from patterns.models import InflectionType, BaseFormLabel
  10 +from patterns.models import InflectionType, BaseFormLabel, Pattern
11 11 from patterns.pattern_blacklist import blacklist
12 12 from dictionary.management.commands.import_morfologik import join, join_many, \
13 13 relevant_subst, relevant_adj, find_minimal_sets
... ...
dictionary/management/commands/stale/import_sejfek.py
... ... @@ -4,7 +4,7 @@ from django.core.management.base import BaseCommand
4 4 from common.util import debug, suffixes, cut_end, uniopen
5 5 from dictionary.models import Lexeme, Pattern, InflectionCharacteristic, \
6 6 Ending
7   -from patterns.models import BaseFormLabel
  7 +from patterns.models import BaseFormLabel, Pattern
8 8 from dictionary.management.commands.import_morfologik import create_lexeme, \
9 9 create_lip, print_data, find_minimal_sets, blacklist_filter, join_many, \
10 10 join, get_sgjp
... ...
dictionary/management/commands/wrong_derivatives.py
... ... @@ -4,8 +4,9 @@ from django.db.transaction import atomic
4 4  
5 5 from common.util import uniprint, no_history
6 6 from dictionary.auto_derivatives import ppas_data, pact_data, create_derivative
7   -from dictionary.models import Pattern, Lexeme, LexemeAttributeValue, Ending, \
  7 +from dictionary.models import Lexeme, LexemeAttributeValue, Ending, \
8 8 LexemeForm
  9 +from patterns.models import Pattern
9 10  
10 11  
11 12 class Command(BaseCommand):
... ...
dictionary/migrations/0008_auto_20151212_2313.py 0 → 100644
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import migrations, models
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('dictionary', '0007_auto_20151212_2218'),
  11 + ('patterns', '0004_pattern'),
  12 + ]
  13 +
  14 + state_operations = [
  15 + migrations.DeleteModel(
  16 + name='Pattern',
  17 + ),
  18 + ]
  19 +
  20 + def update_content_type(apps, schema_editor):
  21 + ContentType = apps.get_model(
  22 + 'django.contrib.contenttypes', 'ContentType')
  23 + ContentType.objects.filter(
  24 + app_label='patterns', model='pattern').delete()
  25 + ct = ContentType.objects.get(app_label='dictionary', model='pattern')
  26 + ct.app_label = 'patterns'
  27 + ct.save()
  28 +
  29 + operations = [
  30 + migrations.RunPython(update_content_type),
  31 + # migrations.RemoveField(
  32 + # model_name='pattern',
  33 + # name='type',
  34 + # ),
  35 + migrations.AlterField(
  36 + model_name='ending',
  37 + name='pattern',
  38 + field=models.ForeignKey(related_name='endings', db_column=b'w_id', to='patterns.Pattern'),
  39 + ),
  40 + migrations.AlterField(
  41 + model_name='history',
  42 + name='pattern',
  43 + field=models.ForeignKey(db_column=b'pattern_id_', blank=True, to='patterns.Pattern', null=True),
  44 + ),
  45 + migrations.AlterField(
  46 + model_name='lexeme',
  47 + name='patterns',
  48 + field=models.ManyToManyField(to='patterns.Pattern', through='dictionary.LexemeInflectionPattern'),
  49 + ),
  50 + migrations.AlterField(
  51 + model_name='lexemeinflectionpattern',
  52 + name='pattern',
  53 + field=models.ForeignKey(db_column=b'w_id', verbose_name='pattern', to='patterns.Pattern'),
  54 + ),
  55 + migrations.AlterField(
  56 + model_name='patternexample',
  57 + name='pattern',
  58 + field=models.ForeignKey(to='patterns.Pattern'),
  59 + ),
  60 + migrations.SeparateDatabaseAndState(state_operations=state_operations),
  61 + ]
... ...
dictionary/models.py
... ... @@ -10,16 +10,10 @@ from django.db.models import Manager, Model, CharField, ForeignKey, \
10 10 from django.utils.translation import ugettext_lazy as _, get_language
11 11  
12 12 from accounts.util import users_with_perm
13   -from common.util import no_history, GroupDict
14   -from patterns.models import InflectionType, BaseFormLabel, PatternType
15   -
16   -
17   -class NotDeletedManager(Manager):
18   - use_for_related_field = True
19   -
20   - def get_queryset(self):
21   - return super(NotDeletedManager, self).get_queryset().filter(
22   - deleted=False)
  13 +from common.models import NotDeletedManager
  14 +from common.util import no_history
  15 +from dictionary.util import prepare_table
  16 +from patterns.models import InflectionType, BaseFormLabel, PatternType, Pattern
23 17  
24 18  
25 19 class LexemeNotDeletedManager(Manager):
... ... @@ -293,137 +287,6 @@ class Gender(Model):
293 287 return self.symbol
294 288  
295 289  
296   -# patterns
297   -class Pattern(Model):
298   - STATUS_NEW = 'nowy'
299   - STATUS_CONFIRMED = 'conf'
300   - STATUS_CANDIDATE = 'cand'
301   - STATUS_CHOICES = (
302   - (STATUS_NEW, _(u'new')),
303   - (STATUS_CONFIRMED, _(u'confirmed')),
304   - (STATUS_CANDIDATE, _(u'candidate')),
305   - )
306   - HIDDEN_STATUSES = (STATUS_CANDIDATE, STATUS_NEW)
307   - name = CharField(
308   - max_length=32, unique=True, db_column='w_id', verbose_name=_(u'name'))
309   - old_name = CharField(
310   - max_length=32, verbose_name=_(u'old name'), null=True)
311   - type = ForeignKey(
312   - PatternType, db_column='typ', verbose_name=_(u'type'))
313   - # rdzeń przykładowej formy hasłowej
314   - example = CharField(
315   - max_length=64, db_column='przyklad', verbose_name=_(u'example'),
316   - blank=True)
317   - basic_form_ending = CharField(
318   - max_length=32, db_column='zakp', blank=True,
319   - verbose_name=_(u'basic form ending'))
320   - status = CharField(
321   - max_length=8, choices=STATUS_CHOICES, verbose_name=_(u'status'))
322   - comment = TextField(
323   - blank=True, db_column='komentarz', verbose_name=_(u'comment'))
324   - deleted = BooleanField(default=False)
325   -
326   - objects = NotDeletedManager()
327   - all_objects = Manager()
328   -
329   - def ending_set(self, subroot='', tag_prefix=None):
330   - endings = self.endings
331   - if tag_prefix:
332   - endings = endings.filter(
333   - base_form_label__symbol__startswith=tag_prefix)
334   - return set(subroot + e
335   - for e in endings.values_list('string', flat=True))
336   -
337   - def base_endings(self, label_filter=None):
338   - bfls = self.type.base_form_labels.all()
339   - endings = Ending.objects.filter(
340   - base_form_label__patterntype=self.type, pattern=self) \
341   - .select_related('base_form_label').prefetch_related('qualifiers')
342   - if label_filter is not None:
343   - endings = endings.filter(
344   - base_form_label__symbol__regex=label_filter)
345   - bfl_dict = GroupDict((bfl, []) for bfl in bfls)
346   - for ending in endings:
347   - bfl_dict.add(ending.base_form_label, ending)
348   - return bfl_dict
349   -
350   - def create_example(self, gender):
351   - lexemes = Lexeme.objects.filter(
352   - patterns=self,
353   - lexemeinflectionpattern__gender=gender)
354   - public_lexemes = reader_lexemes(lexemes)
355   - if public_lexemes:
356   - lexeme = public_lexemes[0]
357   - PatternExample.objects.create(
358   - lexeme=lexeme, pattern=self, gender=gender)
359   -
360   - def get_example(self, gender, refresh=False):
361   - examples = PatternExample.objects.filter(pattern=self, gender=gender)
362   - if not examples or refresh:
363   - examples.delete()
364   - self.create_example(gender)
365   - examples = PatternExample.objects.filter(
366   - pattern=self, gender=gender)
367   - if examples:
368   - lexeme = examples.get().lexeme
369   - example_lips = lexeme.lexemeinflectionpattern_set.filter(
370   - pattern=self, gender=gender)
371   - if example_lips:
372   - return lexeme, example_lips[0].root
373   - else:
374   - return self.get_example(gender, refresh=True)
375   -
376   - def is_public(self):
377   - return self.status not in Pattern.HIDDEN_STATUSES
378   -
379   - def __unicode__(self):
380   - return self.name
381   -
382   - class Meta:
383   - db_table = 'wzory'
384   - ordering = ['name']
385   - permissions = (
386   - ('view_pattern', _(u'Can view patterns')),
387   - )
388   -
389   -
390   -def reader_patterns(patterns):
391   - return patterns.exclude(status__in=Pattern.HIDDEN_STATUSES)
392   -
393   -
394   -def prepare_table(table):
395   - for row in table:
396   - for cell in row:
397   - if type(cell) == dict and 'forms' in cell:
398   - cell['forms'].sort()
399   - seen_forms = []
400   - unique_forms = []
401   - form_patterns = {}
402   - for form in cell['forms']:
403   - if form[1] not in seen_forms:
404   - seen_forms.append(form[1])
405   - unique_forms.append(form)
406   - form_patterns[form[1]] = set()
407   - form_patterns[form[1]].add(form[3])
408   - cell['forms'] = [
409   - {
410   - 'form': form,
411   - 'qualifiers': qualifiers,
412   - 'patterns': form_patterns[form],
413   - }
414   - for (key, form, qualifiers, pattern) in unique_forms]
415   - elif type(cell) == dict and 'label' in cell:
416   - seen_labels = []
417   -
418   - def is_new(label):
419   - new = label not in seen_labels
420   - seen_labels.append(label)
421   - return new
422   -
423   - cell['label'] = filter(is_new, cell['label'])
424   - return table
425   -
426   -
427 290 # zakonczenie formy bazowej
428 291 # patterns
429 292 class Ending(Model):
... ... @@ -1686,7 +1549,7 @@ class History(Model):
1686 1549 lexeme = ForeignKey(
1687 1550 Lexeme, db_column='lexeme_id_', null=True, blank=True, db_index=True)
1688 1551 pattern = ForeignKey(
1689   - Pattern, db_column='pattern_id_', null=True, blank=True, db_index=True)
  1552 + Pattern, db_column='pattern_id_', null=True, blank=True, db_index=True)
1690 1553 row_id = IntegerField(db_column='id_')
1691 1554 operation = CharField(max_length=120, db_column='operation_')
1692 1555 table_oid = IntegerField(db_column='table_oid_')
... ...
dictionary/reports.py
1 1 # -*- coding: utf-8 -*-
2 2 from django.utils.translation import ugettext as _
3 3  
4   -from dictionary.models import Lexeme, LexemeAttributeValue, Pattern, \
5   - CrossReferenceType
  4 +from dictionary.models import Lexeme, LexemeAttributeValue, CrossReferenceType
  5 +from patterns.models import Pattern
6 6  
7 7 report_functions = []
8 8  
... ...
dictionary/util.py
... ... @@ -58,3 +58,36 @@ def check_query_params(request, query_params):
58 58 reader = query_params.get('reader', True)
59 59 if not request.user.is_authenticated() and not reader:
60 60 raise AjaxError('access denied')
  61 +
  62 +
  63 +def prepare_table(table):
  64 + for row in table:
  65 + for cell in row:
  66 + if type(cell) == dict and 'forms' in cell:
  67 + cell['forms'].sort()
  68 + seen_forms = []
  69 + unique_forms = []
  70 + form_patterns = {}
  71 + for form in cell['forms']:
  72 + if form[1] not in seen_forms:
  73 + seen_forms.append(form[1])
  74 + unique_forms.append(form)
  75 + form_patterns[form[1]] = set()
  76 + form_patterns[form[1]].add(form[3])
  77 + cell['forms'] = [
  78 + {
  79 + 'form': form,
  80 + 'qualifiers': qualifiers,
  81 + 'patterns': form_patterns[form],
  82 + }
  83 + for (key, form, qualifiers, pattern) in unique_forms]
  84 + elif type(cell) == dict and 'label' in cell:
  85 + seen_labels = []
  86 +
  87 + def is_new(label):
  88 + new = label not in seen_labels
  89 + seen_labels.append(label)
  90 + return new
  91 +
  92 + cell['label'] = filter(is_new, cell['label'])
  93 + return table
61 94 \ No newline at end of file
... ...
dictionary/views.py
... ... @@ -26,7 +26,7 @@ def main_page(request):
26 26 def main(request):
27 27 if request.user.has_perm('dictionary.view_lexeme'):
28 28 return HttpResponseRedirect(reverse('lexeme_view'))
29   - if request.user.has_perm('dictionary.view_pattern'):
  29 + if request.user.has_perm('patterns.view_pattern'):
30 30 return HttpResponseRedirect(reverse('pattern_view'))
31 31 if request.user.has_perm('dictionary.manage_vocabulary') or \
32 32 request.user.has_perm('auth.add_user'):
... ...
history/lexeme_history.py
... ... @@ -6,8 +6,9 @@ from django.utils.translation import ugettext_lazy as _
6 6  
7 7 from common.util import GroupDict
8 8 from dictionary.models import Lexeme, LexemeInflectionPattern, \
9   - Pattern, InflectionCharacteristic, ClassificationValue, Qualifier, History, \
  9 + InflectionCharacteristic, ClassificationValue, Qualifier, History, \
10 10 CrossReferenceType, LexemeAttributeValue, Gender, BorrowingSource
  11 +from patterns.models import Pattern
11 12  
12 13 attribute_translation_list = [
13 14 # Leksem
... ...
history/pagination_types.py
... ... @@ -7,7 +7,8 @@ from django.forms import Form, ChoiceField, Select, ModelChoiceField, \
7 7 DateField, DateInput
8 8 from django.utils.translation import ugettext_lazy as _
9 9  
10   -from dictionary.models import History, Lexeme, filter_visible, Pattern
  10 +from dictionary.models import History, Lexeme, filter_visible
  11 +from patterns.models import Pattern
11 12  
12 13 types = {}
13 14  
... ...
history/pattern_history.py
... ... @@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _, string_concat
4 4  
5 5 from common.util import GroupDict
6 6 from dictionary.models import Qualifier, Pattern, Ending, History
7   -from patterns.models import BaseFormLabel, PatternType
  7 +from patterns.models import BaseFormLabel, PatternType, Pattern
8 8  
9 9 # FIXME dużo copypasty, można kiedyś zrefaktoryzować
10 10  
... ...
patterns/ajax_pattern_view.py
... ... @@ -12,10 +12,11 @@ from common.decorators import render, ajax, AjaxError, render_ajax
12 12 from common.util import error_messages, format_date, json_encode
13 13 from dictionary.ajax_lexeme_view import refresh_derivatives
14 14 from dictionary.ajax_slickgrid import SlickGridQuery
15   -from dictionary.models import Pattern, Ending, editable_qualifiers, \
  15 +from dictionary.models import Ending, editable_qualifiers, \
16 16 readonly_vocabularies, Gender, PatternExample, filter_visible_lips, \
17   - Lexeme, reader_lexemes, reader_patterns
18   -from patterns.models import InflectionType, BaseFormLabel, PatternType
  17 + Lexeme, reader_lexemes
  18 +from patterns.models import InflectionType, BaseFormLabel, PatternType, \
  19 + Pattern, reader_patterns
19 20 from dictionary.util import check_query_params
20 21 from patterns.forms import PatternEditForm, QualifierForm
21 22  
... ... @@ -154,10 +155,10 @@ def pattern_preview(request, id, reader=False):
154 155  
155 156  
156 157 @render_ajax(template='pattern_edit_form.html', method='get',
157   - permission_required='dictionary.view_pattern')
  158 + permission_required='patterns.view_pattern')
158 159 def pattern_edit_form(request, id):
159 160 p = Pattern.all_objects.get(pk=id)
160   - editable = request.user.has_perm('dictionary.change_pattern')
  161 + editable = request.user.has_perm('patterns.change_pattern')
161 162 ending_groups = OrderedDict(
162 163 (bfl, []) for bfl in p.type.base_form_labels.all())
163 164 endings = p.endings.order_by('index')
... ... @@ -197,7 +198,7 @@ def new_ending_table_row(request, bfl_id):
197 198 }
198 199  
199 200  
200   -@ajax(method='post', permission_required='dictionary.change_pattern')
  201 +@ajax(method='post', permission_required='patterns.change_pattern')
201 202 def update_pattern(request, form_data):
202 203 form_dict = dict((x['name'], x['value']) for x in form_data)
203 204 p = Pattern.all_objects.get(pk=form_dict['id'])
... ... @@ -263,7 +264,7 @@ def update_pattern(request, form_data):
263 264 return {}
264 265  
265 266  
266   -@ajax(method='post', permission_required='dictionary.change_pattern')
  267 +@ajax(method='post', permission_required='patterns.change_pattern')
267 268 def create_pattern(request):
268 269 new_name = u'nowy wzór %s'
269 270 i = 1
... ... @@ -282,7 +283,7 @@ def get_name(request, pattern_id):
282 283 return {'name': pattern.name}
283 284  
284 285  
285   -@ajax(method='post', permission_required='dictionary.change_pattern')
  286 +@ajax(method='post', permission_required='patterns.change_pattern')
286 287 def clone_pattern(request, pattern_id):
287 288 try:
288 289 pattern = Pattern.objects.get(id=pattern_id)
... ...
patterns/forms.py
... ... @@ -2,8 +2,8 @@
2 2 from django.forms import ModelForm, Form, SelectMultiple
3 3 from common.forms import disable_field
4 4 from dictionary.forms import QualifiersField
5   -from dictionary.models import Pattern, Qualifier
6   -from patterns.models import PatternType
  5 +from dictionary.models import Qualifier
  6 +from patterns.models import PatternType, Pattern
7 7  
8 8  
9 9 class PatternEditForm(ModelForm):
... ...
patterns/migrations/0004_pattern.py 0 → 100644
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import migrations, models
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('patterns', '0003_patterntype'),
  11 + ('dictionary', '0007_auto_20151212_2218'),
  12 + ]
  13 +
  14 + state_operations = [
  15 + migrations.CreateModel(
  16 + name='Pattern',
  17 + fields=[
  18 + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
  19 + ('name', models.CharField(unique=True, max_length=32, verbose_name='name', db_column=b'w_id')),
  20 + ('old_name', models.CharField(max_length=32, null=True, verbose_name='old name')),
  21 + ('example', models.CharField(max_length=64, verbose_name='example', db_column=b'przyklad', blank=True)),
  22 + ('basic_form_ending', models.CharField(max_length=32, verbose_name='basic form ending', db_column=b'zakp', blank=True)),
  23 + ('status', models.CharField(max_length=8, verbose_name='status', choices=[(b'nowy', 'new'), (b'conf', 'confirmed'), (b'cand', 'candidate')])),
  24 + ('comment', models.TextField(verbose_name='comment', db_column=b'komentarz', blank=True)),
  25 + ('deleted', models.BooleanField(default=False)),
  26 + ('type', models.ForeignKey(db_column=b'typ', verbose_name='type', to='patterns.PatternType')),
  27 + ],
  28 + options={
  29 + 'ordering': ['name'],
  30 + 'db_table': 'wzory',
  31 + 'permissions': (('view_pattern', 'Can view patterns'),),
  32 + },
  33 + ),
  34 + ]
  35 +
  36 + operations = [
  37 + migrations.SeparateDatabaseAndState(state_operations=state_operations)
  38 + ]
... ...
patterns/models.py
1 1 # -*- coding: utf-8 -*-
2 2 from django.db.models import Model, CharField, IntegerField, ForeignKey, \
3   - ManyToManyField
  3 + ManyToManyField, TextField, BooleanField, Manager
4 4 from django.utils.translation import ugettext_lazy as _
5 5  
6 6 from common.util import GroupDict
  7 +from common.models import NotDeletedManager
7 8  
8 9  
9 10 class InflectionType(Model):
... ... @@ -69,3 +70,103 @@ class PatternType(Model):
69 70 class Meta:
70 71 db_table = 'typywzorow'
71 72 ordering = ['symbol']
  73 +
  74 +
  75 +class Pattern(Model):
  76 + STATUS_NEW = 'nowy'
  77 + STATUS_CONFIRMED = 'conf'
  78 + STATUS_CANDIDATE = 'cand'
  79 + STATUS_CHOICES = (
  80 + (STATUS_NEW, _(u'new')),
  81 + (STATUS_CONFIRMED, _(u'confirmed')),
  82 + (STATUS_CANDIDATE, _(u'candidate')),
  83 + )
  84 + HIDDEN_STATUSES = (STATUS_CANDIDATE, STATUS_NEW)
  85 + name = CharField(
  86 + max_length=32, unique=True, db_column='w_id', verbose_name=_(u'name'))
  87 + old_name = CharField(
  88 + max_length=32, verbose_name=_(u'old name'), null=True)
  89 + type = ForeignKey(
  90 + PatternType, db_column='typ', verbose_name=_(u'type'))
  91 + # rdzeń przykładowej formy hasłowej
  92 + example = CharField(
  93 + max_length=64, db_column='przyklad', verbose_name=_(u'example'),
  94 + blank=True)
  95 + basic_form_ending = CharField(
  96 + max_length=32, db_column='zakp', blank=True,
  97 + verbose_name=_(u'basic form ending'))
  98 + status = CharField(
  99 + max_length=8, choices=STATUS_CHOICES, verbose_name=_(u'status'))
  100 + comment = TextField(
  101 + blank=True, db_column='komentarz', verbose_name=_(u'comment'))
  102 + deleted = BooleanField(default=False)
  103 +
  104 + objects = NotDeletedManager()
  105 + all_objects = Manager()
  106 +
  107 + def ending_set(self, subroot='', tag_prefix=None):
  108 + endings = self.endings
  109 + if tag_prefix:
  110 + endings = endings.filter(
  111 + base_form_label__symbol__startswith=tag_prefix)
  112 + return set(subroot + e
  113 + for e in endings.values_list('string', flat=True))
  114 +
  115 + def base_endings(self, label_filter=None):
  116 + bfls = self.type.base_form_labels.all()
  117 + from dictionary.models import Ending
  118 + endings = Ending.objects.filter(
  119 + base_form_label__patterntype=self.type, pattern=self) \
  120 + .select_related('base_form_label').prefetch_related('qualifiers')
  121 + if label_filter is not None:
  122 + endings = endings.filter(
  123 + base_form_label__symbol__regex=label_filter)
  124 + bfl_dict = GroupDict((bfl, []) for bfl in bfls)
  125 + for ending in endings:
  126 + bfl_dict.add(ending.base_form_label, ending)
  127 + return bfl_dict
  128 +
  129 + def create_example(self, gender):
  130 + from dictionary.models import Lexeme, reader_lexemes, PatternExample
  131 + lexemes = Lexeme.objects.filter(
  132 + patterns=self,
  133 + lexemeinflectionpattern__gender=gender)
  134 + public_lexemes = reader_lexemes(lexemes)
  135 + if public_lexemes:
  136 + lexeme = public_lexemes[0]
  137 + PatternExample.objects.create(
  138 + lexeme=lexeme, pattern=self, gender=gender)
  139 +
  140 + def get_example(self, gender, refresh=False):
  141 + from dictionary.models import PatternExample
  142 + examples = PatternExample.objects.filter(pattern=self, gender=gender)
  143 + if not examples or refresh:
  144 + examples.delete()
  145 + self.create_example(gender)
  146 + examples = PatternExample.objects.filter(
  147 + pattern=self, gender=gender)
  148 + if examples:
  149 + lexeme = examples.get().lexeme
  150 + example_lips = lexeme.lexemeinflectionpattern_set.filter(
  151 + pattern=self, gender=gender)
  152 + if example_lips:
  153 + return lexeme, example_lips[0].root
  154 + else:
  155 + return self.get_example(gender, refresh=True)
  156 +
  157 + def is_public(self):
  158 + return self.status not in Pattern.HIDDEN_STATUSES
  159 +
  160 + def __unicode__(self):
  161 + return self.name
  162 +
  163 + class Meta:
  164 + db_table = 'wzory'
  165 + ordering = ['name']
  166 + permissions = (
  167 + ('view_pattern', _(u'Can view patterns')),
  168 + )
  169 +
  170 +
  171 +def reader_patterns(patterns):
  172 + return patterns.exclude(status__in=Pattern.HIDDEN_STATUSES)
... ...
patterns/templates/pattern_view.html
... ... @@ -42,7 +42,7 @@
42 42 <button id="search-button" title="{% trans 'search' %}">
43 43 <span class="ui-icon ui-icon-search">{% trans 'search' %}</span>
44 44 </button>
45   - {% if perms.dictionary.change_pattern %}
  45 + {% if perms.patterns.change_pattern %}
46 46 <button id="add-button" title="{% trans 'create pattern' %}">
47 47 <span class="ui-icon ui-icon-plus">{% trans 'create pattern' %}</span>
48 48 </button>
... ...
patterns/views.py
... ... @@ -35,7 +35,7 @@ def common_pattern_js_vars(request, reader=False):
35 35 return js_vars
36 36  
37 37  
38   -@permission_required('dictionary.view_pattern')
  38 +@permission_required('patterns.view_pattern')
39 39 @render('pattern_view.html')
40 40 def pattern_view(request):
41 41 editable_vocabs = editable_vocabularies(request.user)
... ...