Commit e29bb514e1a967ba48fa48df9bdae25fd7be94bd
1 parent
85716dbc
zmiana formatowania, poprawka do dodawania zakończeń, ostrzeganie przed zamknięciem
Showing
189 changed files
with
53113 additions
and
37346 deletions
Too many changes to show.
To preserve performance only 44 of 189 files are displayed.
accounts/ajax.py
... | ... | @@ -4,19 +4,21 @@ from django.contrib.auth.models import User, Group |
4 | 4 | from common.decorators import ajax |
5 | 5 | from dictionary.models import Vocabulary |
6 | 6 | |
7 | + | |
7 | 8 | @ajax(method='post') |
8 | 9 | def set_group(request, user_id, group_id, set): |
9 | - user = User.objects.get(pk=user_id) | |
10 | - group = Group.objects.get(pk=group_id) | |
11 | - if set: | |
12 | - user.groups.add(group) | |
13 | - else: | |
14 | - user.groups.remove(group) | |
15 | - return {} | |
10 | + user = User.objects.get(pk=user_id) | |
11 | + group = Group.objects.get(pk=group_id) | |
12 | + if set: | |
13 | + user.groups.add(group) | |
14 | + else: | |
15 | + user.groups.remove(group) | |
16 | + return {} | |
17 | + | |
16 | 18 | |
17 | 19 | @ajax(method='post') |
18 | 20 | def save_default_owner(request, vocab_id): |
19 | - us = request.user.usersettings | |
20 | - us.default_owner = Vocabulary.objects.get(pk=vocab_id) | |
21 | - us.save() | |
22 | - return {} | |
21 | + us = request.user.usersettings | |
22 | + us.default_owner = Vocabulary.objects.get(pk=vocab_id) | |
23 | + us.save() | |
24 | + return {} | |
... | ... |
accounts/forms.py
... | ... | @@ -3,35 +3,38 @@ |
3 | 3 | import random |
4 | 4 | import string |
5 | 5 | from django.forms import * |
6 | -from django.utils.translation import ugettext_lazy as _ | |
7 | 6 | from django.contrib.auth.forms import PasswordResetForm |
8 | 7 | from django.contrib.auth.models import User |
9 | 8 | from accounts.models import UserSettings |
10 | 9 | |
10 | + | |
11 | 11 | class AddUserForm(ModelForm): |
12 | - def save(self, commit=True, request=None): | |
13 | - user = super(AddUserForm, self).save(commit=False) | |
14 | - password = ''.join(random.choice(string.printable) for i in range(32)) | |
15 | - user.set_password(password) | |
16 | - if commit: | |
17 | - user.save() | |
18 | - fakeform = PasswordResetForm(data={'email': user.email}) | |
19 | - if fakeform.is_valid(): # oczywiście, że jest | |
20 | - fakeform.save(request=request) | |
21 | - UserSettings.objects.create(user=user) | |
22 | - user.groups.add(*self.cleaned_data['groups']) | |
23 | - return user | |
24 | - class Meta: | |
25 | - model = User | |
26 | - fields = ['username', 'first_name', 'last_name', 'email', 'groups'] | |
12 | + def save(self, commit=True, request=None): | |
13 | + user = super(AddUserForm, self).save(commit=False) | |
14 | + password = ''.join(random.choice(string.printable) for i in range(32)) | |
15 | + user.set_password(password) | |
16 | + if commit: | |
17 | + user.save() | |
18 | + fakeform = PasswordResetForm(data={'email': user.email}) | |
19 | + if fakeform.is_valid(): # oczywiście, że jest | |
20 | + fakeform.save(request=request) | |
21 | + UserSettings.objects.create(user=user) | |
22 | + user.groups.add(*self.cleaned_data['groups']) | |
23 | + return user | |
24 | + | |
25 | + class Meta: | |
26 | + model = User | |
27 | + fields = ['username', 'first_name', 'last_name', 'email', 'groups'] | |
28 | + | |
27 | 29 | |
28 | 30 | class SettingsForm(ModelForm): |
29 | - def __init__(self, vocabularies=None, **kwargs): | |
30 | - super(SettingsForm, self).__init__(**kwargs) | |
31 | - if vocabularies: | |
32 | - self.fields['default_owner'].queryset = vocabularies | |
33 | - else: | |
34 | - self.fields['default_owner'].widget = HiddenInput() | |
35 | - class Meta: | |
36 | - model = UserSettings | |
37 | - fields = ['incremental_search', 'filter_search', 'default_owner'] | |
31 | + def __init__(self, vocabularies=None, **kwargs): | |
32 | + super(SettingsForm, self).__init__(**kwargs) | |
33 | + if vocabularies: | |
34 | + self.fields['default_owner'].queryset = vocabularies | |
35 | + else: | |
36 | + self.fields['default_owner'].widget = HiddenInput() | |
37 | + | |
38 | + class Meta: | |
39 | + model = UserSettings | |
40 | + fields = ['incremental_search', 'filter_search', 'default_owner'] | |
... | ... |
accounts/management/commands/create_groups.py
1 | 1 | #-*- coding:utf-8 -*- |
2 | 2 | |
3 | 3 | from django.contrib.auth.models import Permission, Group |
4 | -from django.core.management.base import BaseCommand, CommandError | |
4 | +from django.core.management.base import BaseCommand | |
5 | + | |
5 | 6 | |
6 | 7 | class Command(BaseCommand): |
7 | - args = 'none' | |
8 | - help = 'Creates default groups' | |
8 | + args = 'none' | |
9 | + help = 'Creates default groups' | |
9 | 10 | |
10 | - def handle(self, **options): | |
11 | - create_groups() | |
11 | + def handle(self, **options): | |
12 | + create_groups() | |
12 | 13 | |
13 | 14 | |
14 | 15 | def get_permission(codename): |
15 | - return Permission.objects.get(codename=codename) | |
16 | + return Permission.objects.get(codename=codename) | |
17 | + | |
16 | 18 | |
17 | 19 | def create_groups(): |
18 | - Group.objects.all().delete() | |
19 | - observers = Group.objects.create(name=u'Obserwator') | |
20 | - lexicographers = Group.objects.create(name=u'Leksykograf') | |
21 | - superlexicographers = Group.objects.create(name=u'Superleksykograf') | |
22 | - patternmakers = Group.objects.create(name=u'Wzorzysta') | |
23 | - managers = Group.objects.create(name=u'Wydawca') | |
24 | - admins = Group.objects.create(name=u'Administrator') | |
25 | - | |
26 | - observers.permissions.add(get_permission('view_lexeme')) | |
27 | - #observers.permissions.add(get_permission('add_comment')) | |
28 | - observers.permissions.add(get_permission('view_pattern')) | |
29 | - lexicographers.permissions.add(get_permission('view_lexeme')) | |
30 | - lexicographers.permissions.add(get_permission('change_lexeme')) | |
31 | - lexicographers.permissions.add(get_permission('export_lexemes')) | |
32 | - lexicographers.permissions.add(get_permission('view_pattern')) | |
33 | - superlexicographers.permissions.add(get_permission('view_lexeme')) | |
34 | - superlexicographers.permissions.add(get_permission('change_lexeme')) | |
35 | - superlexicographers.permissions.add(get_permission('export_lexemes')) | |
36 | - superlexicographers.permissions.add(get_permission('lexeme_priority')) | |
37 | - superlexicographers.permissions.add(get_permission('view_pattern')) | |
38 | - # może dokonywać zmian w Banku błędów | |
39 | - # może dokonywać zmian w zakładce Etykiety | |
40 | - patternmakers.permissions.add(get_permission('view_pattern')) | |
41 | - patternmakers.permissions.add(get_permission('change_pattern')) | |
42 | - managers.permissions.add(get_permission('manage_vocabulary')) | |
43 | - managers.permissions.add(get_permission('view_lexeme')) | |
44 | - managers.permissions.add(get_permission('view_all_lexemes')) | |
45 | - managers.permissions.add(get_permission('view_pattern')) | |
46 | - managers.permissions.add(get_permission('add_user')) | |
47 | - managers.permissions.add(get_permission('export_lexemes')) | |
48 | - # zarządzanie rolami użytkowników: | |
49 | - managers.permissions.add(get_permission('change_group')) | |
50 | - admins.permissions.add(get_permission('add_user')) | |
51 | - admins.permissions.add(get_permission('change_group')) | |
52 | - admins.permissions.add(get_permission('create_admin')) | |
53 | - admins.permissions.add(get_permission('manage_vocabulary')) | |
54 | - admins.permissions.add(get_permission('manage_all_vocabularies')) | |
20 | + Group.objects.all().delete() | |
21 | + observers = Group.objects.create(name=u'Obserwator') | |
22 | + lexicographers = Group.objects.create(name=u'Leksykograf') | |
23 | + superlexicographers = Group.objects.create(name=u'Superleksykograf') | |
24 | + patternmakers = Group.objects.create(name=u'Wzorzysta') | |
25 | + managers = Group.objects.create(name=u'Wydawca') | |
26 | + admins = Group.objects.create(name=u'Administrator') | |
27 | + | |
28 | + observers.permissions.add(get_permission('view_lexeme')) | |
29 | + #observers.permissions.add(get_permission('add_comment')) | |
30 | + observers.permissions.add(get_permission('view_pattern')) | |
31 | + lexicographers.permissions.add(get_permission('view_lexeme')) | |
32 | + lexicographers.permissions.add(get_permission('change_lexeme')) | |
33 | + lexicographers.permissions.add(get_permission('export_lexemes')) | |
34 | + lexicographers.permissions.add(get_permission('view_pattern')) | |
35 | + superlexicographers.permissions.add(get_permission('view_lexeme')) | |
36 | + superlexicographers.permissions.add(get_permission('change_lexeme')) | |
37 | + superlexicographers.permissions.add(get_permission('export_lexemes')) | |
38 | + superlexicographers.permissions.add(get_permission('lexeme_priority')) | |
39 | + superlexicographers.permissions.add(get_permission('view_pattern')) | |
40 | + # może dokonywać zmian w Banku błędów | |
41 | + # może dokonywać zmian w zakładce Etykiety | |
42 | + patternmakers.permissions.add(get_permission('view_pattern')) | |
43 | + patternmakers.permissions.add(get_permission('change_pattern')) | |
44 | + managers.permissions.add(get_permission('manage_vocabulary')) | |
45 | + managers.permissions.add(get_permission('view_lexeme')) | |
46 | + managers.permissions.add(get_permission('view_all_lexemes')) | |
47 | + managers.permissions.add(get_permission('view_pattern')) | |
48 | + managers.permissions.add(get_permission('add_user')) | |
49 | + managers.permissions.add(get_permission('export_lexemes')) | |
50 | + # zarządzanie rolami użytkowników: | |
51 | + managers.permissions.add(get_permission('change_group')) | |
52 | + admins.permissions.add(get_permission('add_user')) | |
53 | + admins.permissions.add(get_permission('change_group')) | |
54 | + admins.permissions.add(get_permission('create_admin')) | |
55 | + admins.permissions.add(get_permission('manage_vocabulary')) | |
56 | + admins.permissions.add(get_permission('manage_all_vocabularies')) | |
... | ... |
accounts/management/commands/create_users.py
... | ... | @@ -5,92 +5,97 @@ from django.core.management.base import BaseCommand, CommandError |
5 | 5 | from dictionary.models import Vocabulary |
6 | 6 | from accounts.models import UserSettings |
7 | 7 | |
8 | + | |
8 | 9 | class Command(BaseCommand): |
9 | - args = 'none' | |
10 | - help = 'Creates default users' | |
10 | + args = 'none' | |
11 | + help = 'Creates default users' | |
11 | 12 | |
12 | - def handle(self, **options): | |
13 | - create_users() | |
13 | + def handle(self, **options): | |
14 | + create_users() | |
14 | 15 | |
15 | 16 | |
16 | 17 | def create_users(): |
17 | - observers = Group.objects.get(name=u'Obserwator') | |
18 | - lexicographers = Group.objects.get(name=u'Leksykograf') | |
19 | - superlexicographers = Group.objects.get(name=u'Superleksykograf') | |
20 | - patternmakers = Group.objects.get(name=u'Wzorzysta') | |
21 | - managers = Group.objects.get(name=u'Wydawca') | |
22 | - admins = Group.objects.get(name=u'Administrator') | |
23 | - | |
24 | - SGJP = Vocabulary.objects.get(id='SGJP') | |
25 | - SJPDor = Vocabulary.objects.get(id='SJPDor') | |
26 | - zmiotki = Vocabulary.objects.get(id='zmiotki') | |
27 | - try: | |
28 | - WSJP = Vocabulary.objects.get(id='WSJP') | |
29 | - except Vocabulary.DoesNotExist: | |
30 | - WSJP = None | |
31 | - Morfologik, created = Vocabulary.objects.get_or_create(id='Morfologik') | |
32 | - PoliMorf, created = Vocabulary.objects.get_or_create(id='PoliMorf') | |
33 | - | |
34 | - User.objects.all().delete() | |
35 | - sgjp = User.objects.create_user('sgjp', 'sgjp@example.com', 'sgjp') | |
36 | - nzm = User.objects.create_user('nzm', 'nzm@example.com', 'nzm') | |
37 | - redsgjp = User.objects.create_user('redsgjp', 'redsgjp@example.com', 'redsgjp') | |
38 | - rednzm = User.objects.create_user('rednzm', 'rednzm@example.com', 'rednzm') | |
39 | - supersgjp = User.objects.create_user('supersgjp', 'supersgjp@example.com', 'supersgjp') | |
40 | - supernzm = User.objects.create_user('supernzm', 'supernzm@example.com', 'supernzm') | |
41 | - wzornik = User.objects.create_user('wzornik', 'wzornik@example.com', 'wzornik') | |
42 | - admin = User.objects.create_user('admin', 'admin@example.com', 'admin') | |
43 | - | |
44 | - users = (sgjp, nzm, redsgjp, rednzm, supersgjp, supernzm, wzornik, admin) | |
45 | - for user in users: | |
46 | - UserSettings.objects.create(user=user) | |
47 | - | |
48 | - admin.groups.add(admins) | |
49 | - | |
50 | - sgjp_vocabs = (SGJP, SJPDor, zmiotki) | |
51 | - if WSJP: sgjp_vocabs += (WSJP,) | |
52 | - nzm_vocabs = (zmiotki, Morfologik, PoliMorf) | |
53 | - | |
54 | - sgjp.groups.add(managers) | |
55 | - for vocab in sgjp_vocabs: | |
56 | - sgjp.managed_vocabularies.add(vocab) | |
57 | - nzm.groups.add(managers) | |
58 | - for vocab in nzm_vocabs: | |
59 | - nzm.managed_vocabularies.add(vocab) | |
60 | - | |
61 | - redsgjp.groups.add(lexicographers) | |
62 | - for vocab in sgjp_vocabs: | |
63 | - redsgjp.visible_vocabularies.add(vocab) | |
64 | - redsgjp.editable_vocabularies.add(vocab) | |
65 | - redsgjp.visible_vocabularies.add(PoliMorf) | |
66 | - | |
67 | - rednzm.groups.add(lexicographers) | |
68 | - for vocab in nzm_vocabs: | |
69 | - rednzm.visible_vocabularies.add(vocab) | |
70 | - rednzm.editable_vocabularies.add(vocab) | |
71 | - rednzm.visible_vocabularies.add(SGJP) | |
72 | - if WSJP: | |
73 | - rednzm.visible_vocabularies.add(WSJP) | |
74 | - rednzm.visible_vocabularies.add(SJPDor) | |
75 | - | |
76 | - supersgjp.groups.add(superlexicographers) | |
77 | - for vocab in sgjp_vocabs: | |
78 | - supersgjp.visible_vocabularies.add(vocab) | |
79 | - supersgjp.editable_vocabularies.add(vocab) | |
80 | - supersgjp.visible_vocabularies.add(PoliMorf) | |
81 | - | |
82 | - supernzm.groups.add(superlexicographers) | |
83 | - for vocab in nzm_vocabs: | |
84 | - supernzm.visible_vocabularies.add(vocab) | |
85 | - supernzm.editable_vocabularies.add(vocab) | |
86 | - supernzm.visible_vocabularies.add(SGJP) | |
87 | - if WSJP: | |
88 | - supernzm.visible_vocabularies.add(WSJP) | |
89 | - supernzm.visible_vocabularies.add(SJPDor) | |
90 | - | |
91 | - wzornik.groups.add(superlexicographers) | |
92 | - for vocab in sgjp_vocabs: | |
93 | - wzornik.visible_vocabularies.add(vocab) | |
94 | - wzornik.editable_vocabularies.add(vocab) | |
95 | - wzornik.visible_vocabularies.add(PoliMorf) | |
96 | - wzornik.groups.add(patternmakers) | |
18 | + observers = Group.objects.get(name=u'Obserwator') | |
19 | + lexicographers = Group.objects.get(name=u'Leksykograf') | |
20 | + superlexicographers = Group.objects.get(name=u'Superleksykograf') | |
21 | + patternmakers = Group.objects.get(name=u'Wzorzysta') | |
22 | + managers = Group.objects.get(name=u'Wydawca') | |
23 | + admins = Group.objects.get(name=u'Administrator') | |
24 | + | |
25 | + SGJP = Vocabulary.objects.get(id='SGJP') | |
26 | + SJPDor = Vocabulary.objects.get(id='SJPDor') | |
27 | + zmiotki = Vocabulary.objects.get(id='zmiotki') | |
28 | + try: | |
29 | + WSJP = Vocabulary.objects.get(id='WSJP') | |
30 | + except Vocabulary.DoesNotExist: | |
31 | + WSJP = None | |
32 | + Morfologik, created = Vocabulary.objects.get_or_create(id='Morfologik') | |
33 | + PoliMorf, created = Vocabulary.objects.get_or_create(id='PoliMorf') | |
34 | + | |
35 | + User.objects.all().delete() | |
36 | + sgjp = User.objects.create_user('sgjp', 'sgjp@example.com', 'sgjp') | |
37 | + nzm = User.objects.create_user('nzm', 'nzm@example.com', 'nzm') | |
38 | + redsgjp = User.objects.create_user('redsgjp', 'redsgjp@example.com', | |
39 | + 'redsgjp') | |
40 | + rednzm = User.objects.create_user('rednzm', 'rednzm@example.com', 'rednzm') | |
41 | + supersgjp = User.objects.create_user('supersgjp', 'supersgjp@example.com', | |
42 | + 'supersgjp') | |
43 | + supernzm = User.objects.create_user('supernzm', 'supernzm@example.com', | |
44 | + 'supernzm') | |
45 | + wzornik = User.objects.create_user('wzornik', 'wzornik@example.com', | |
46 | + 'wzornik') | |
47 | + admin = User.objects.create_user('admin', 'admin@example.com', 'admin') | |
48 | + | |
49 | + users = (sgjp, nzm, redsgjp, rednzm, supersgjp, supernzm, wzornik, admin) | |
50 | + for user in users: | |
51 | + UserSettings.objects.create(user=user) | |
52 | + | |
53 | + admin.groups.add(admins) | |
54 | + | |
55 | + sgjp_vocabs = (SGJP, SJPDor, zmiotki) | |
56 | + if WSJP: sgjp_vocabs += (WSJP,) | |
57 | + nzm_vocabs = (zmiotki, Morfologik, PoliMorf) | |
58 | + | |
59 | + sgjp.groups.add(managers) | |
60 | + for vocab in sgjp_vocabs: | |
61 | + sgjp.managed_vocabularies.add(vocab) | |
62 | + nzm.groups.add(managers) | |
63 | + for vocab in nzm_vocabs: | |
64 | + nzm.managed_vocabularies.add(vocab) | |
65 | + | |
66 | + redsgjp.groups.add(lexicographers) | |
67 | + for vocab in sgjp_vocabs: | |
68 | + redsgjp.visible_vocabularies.add(vocab) | |
69 | + redsgjp.editable_vocabularies.add(vocab) | |
70 | + redsgjp.visible_vocabularies.add(PoliMorf) | |
71 | + | |
72 | + rednzm.groups.add(lexicographers) | |
73 | + for vocab in nzm_vocabs: | |
74 | + rednzm.visible_vocabularies.add(vocab) | |
75 | + rednzm.editable_vocabularies.add(vocab) | |
76 | + rednzm.visible_vocabularies.add(SGJP) | |
77 | + if WSJP: | |
78 | + rednzm.visible_vocabularies.add(WSJP) | |
79 | + rednzm.visible_vocabularies.add(SJPDor) | |
80 | + | |
81 | + supersgjp.groups.add(superlexicographers) | |
82 | + for vocab in sgjp_vocabs: | |
83 | + supersgjp.visible_vocabularies.add(vocab) | |
84 | + supersgjp.editable_vocabularies.add(vocab) | |
85 | + supersgjp.visible_vocabularies.add(PoliMorf) | |
86 | + | |
87 | + supernzm.groups.add(superlexicographers) | |
88 | + for vocab in nzm_vocabs: | |
89 | + supernzm.visible_vocabularies.add(vocab) | |
90 | + supernzm.editable_vocabularies.add(vocab) | |
91 | + supernzm.visible_vocabularies.add(SGJP) | |
92 | + if WSJP: | |
93 | + supernzm.visible_vocabularies.add(WSJP) | |
94 | + supernzm.visible_vocabularies.add(SJPDor) | |
95 | + | |
96 | + wzornik.groups.add(superlexicographers) | |
97 | + for vocab in sgjp_vocabs: | |
98 | + wzornik.visible_vocabularies.add(vocab) | |
99 | + wzornik.editable_vocabularies.add(vocab) | |
100 | + wzornik.visible_vocabularies.add(PoliMorf) | |
101 | + wzornik.groups.add(patternmakers) | |
... | ... |
accounts/management/commands/dummy_passwords.py
... | ... | @@ -3,15 +3,16 @@ |
3 | 3 | from django.contrib.auth.models import User |
4 | 4 | from django.core.management.base import BaseCommand |
5 | 5 | |
6 | + | |
6 | 7 | class Command(BaseCommand): |
7 | - args = 'none' | |
8 | - help = 'Sets dummy passwords' | |
8 | + args = 'none' | |
9 | + help = 'Sets dummy passwords' | |
9 | 10 | |
10 | - def handle(self, **options): | |
11 | - dummy_passwords() | |
11 | + def handle(self, **options): | |
12 | + dummy_passwords() | |
12 | 13 | |
13 | 14 | |
14 | 15 | def dummy_passwords(): |
15 | - for user in User.objects.all(): | |
16 | - user.set_password(user.username) | |
17 | - user.save() | |
18 | 16 | \ No newline at end of file |
17 | + for user in User.objects.all(): | |
18 | + user.set_password(user.username) | |
19 | + user.save() | |
19 | 20 | \ No newline at end of file |
... | ... |
accounts/models.py
... | ... | @@ -6,45 +6,48 @@ from dictionary.models import Vocabulary |
6 | 6 | |
7 | 7 | MANAGER_GROUPS = ('Obserwator', 'Leksykograf', 'Superleksykograf') |
8 | 8 | |
9 | + | |
9 | 10 | def manager_groups(): |
10 | - return Group.objects.filter(name__in=MANAGER_GROUPS) | |
11 | + return Group.objects.filter(name__in=MANAGER_GROUPS) | |
12 | + | |
11 | 13 | |
12 | 14 | class UserSettings(Model): |
13 | - user = OneToOneField(User) | |
14 | - incremental_search = BooleanField( | |
15 | - default=True, | |
16 | - verbose_name=u'wyszukiwanie przyrostowe', | |
17 | - help_text=u'Wyszukiwanie odbywa się automatycznie w miarę wpisywania ' | |
18 | - u'szukanego hasła. Sugerujemy wyłączenie w wypadku wolnego ' | |
19 | - u'połączenia internetowego.') | |
20 | - filter_search = BooleanField( | |
21 | - default=False, | |
22 | - verbose_name=u'wyszukiwanie przez filtrowanie', | |
23 | - help_text=u'Wyszukiwanie powoduje zawężenie listy haseł do pasujących ' | |
24 | - u'do zapytania.') | |
25 | - default_owner = ForeignKey( | |
26 | - Vocabulary, blank=True, null=True, | |
27 | - verbose_name=u'domyślny słownik właściciel dodawanych leksemów') | |
28 | - | |
29 | - def views_lexeme(self): | |
30 | - return self.user.has_perm('dictionary.view_lexeme') | |
31 | - | |
32 | - def views_all_lexemes(self): | |
33 | - return self.user.has_perm('dictionary.view_all_lexemes') | |
34 | - | |
35 | - def changes_lexeme(self): | |
36 | - return self.user.has_perm('dictionary.change_lexeme') | |
37 | - | |
38 | - def manages_vocabulary(self): | |
39 | - return self.user.has_perm('dictionary.manage_vocabulary') | |
40 | - | |
41 | - def manages_all_vocabs(self): | |
42 | - return self.user.has_perm('dictionary.manage_all_vocabularies') | |
43 | - | |
44 | - class Meta: | |
45 | - permissions = ( | |
46 | - ('create_admin', u'Może nadawać dowolne role'), | |
47 | - ) | |
15 | + user = OneToOneField(User) | |
16 | + incremental_search = BooleanField( | |
17 | + default=True, | |
18 | + verbose_name=u'wyszukiwanie przyrostowe', | |
19 | + help_text=u'Wyszukiwanie odbywa się automatycznie w miarę wpisywania ' | |
20 | + u'szukanego hasła. Sugerujemy wyłączenie w wypadku wolnego ' | |
21 | + u'połączenia internetowego.') | |
22 | + filter_search = BooleanField( | |
23 | + default=False, | |
24 | + verbose_name=u'wyszukiwanie przez filtrowanie', | |
25 | + help_text=u'Wyszukiwanie powoduje zawężenie listy haseł do pasujących ' | |
26 | + u'do zapytania.') | |
27 | + default_owner = ForeignKey( | |
28 | + Vocabulary, blank=True, null=True, | |
29 | + verbose_name=u'domyślny słownik właściciel dodawanych leksemów') | |
30 | + | |
31 | + def views_lexeme(self): | |
32 | + return self.user.has_perm('dictionary.view_lexeme') | |
33 | + | |
34 | + def views_all_lexemes(self): | |
35 | + return self.user.has_perm('dictionary.view_all_lexemes') | |
36 | + | |
37 | + def changes_lexeme(self): | |
38 | + return self.user.has_perm('dictionary.change_lexeme') | |
39 | + | |
40 | + def manages_vocabulary(self): | |
41 | + return self.user.has_perm('dictionary.manage_vocabulary') | |
42 | + | |
43 | + def manages_all_vocabs(self): | |
44 | + return self.user.has_perm('dictionary.manage_all_vocabularies') | |
45 | + | |
46 | + class Meta: | |
47 | + permissions = ( | |
48 | + ('create_admin', u'Może nadawać dowolne role'), | |
49 | + ) | |
50 | + | |
48 | 51 | |
49 | 52 | def filtering_mode(user): |
50 | - return user.usersettings.filter_search | |
53 | + return user.usersettings.filter_search | |
... | ... |
accounts/templates/manage_groups.html
... | ... | @@ -2,32 +2,33 @@ |
2 | 2 | {% load ingroup %} |
3 | 3 | |
4 | 4 | {% block extrahead %} |
5 | - <script type="text/javascript" src="{{ MEDIA_URL }}js/manage-groups.js"></script> | |
5 | + <script type="text/javascript" | |
6 | + src="{{ MEDIA_URL }}js/manage-groups.js"></script> | |
6 | 7 | {% endblock %} |
7 | 8 | |
8 | 9 | {% block title %}Role użytkowników{% endblock %} |
9 | 10 | |
10 | 11 | {% block content %} |
11 | - <h3>Role użytkowników</h3> | |
12 | - <table id="user-groups"> | |
13 | - <tr> | |
14 | - <th>nazwa</th> | |
15 | - {% for group in groups %} | |
16 | - <th>{{ group.name }}</th> | |
17 | - {% endfor %} | |
18 | - </tr> | |
19 | - {% for u in users %} | |
20 | - <tr> | |
21 | - <td>{{ u.username }}</td> | |
22 | - {% for group in groups %} | |
23 | - <td> | |
24 | - <input | |
25 | - type="checkbox" | |
26 | - id="group-{{ group.pk }}-{{ u.pk }}" | |
27 | - {% if u|ingroup:group %}checked="checked"{% endif %}/> | |
28 | - </td> | |
12 | + <h3>Role użytkowników</h3> | |
13 | + <table id="user-groups"> | |
14 | + <tr> | |
15 | + <th>nazwa</th> | |
16 | + {% for group in groups %} | |
17 | + <th>{{ group.name }}</th> | |
18 | + {% endfor %} | |
19 | + </tr> | |
20 | + {% for u in users %} | |
21 | + <tr> | |
22 | + <td>{{ u.username }}</td> | |
23 | + {% for group in groups %} | |
24 | + <td> | |
25 | + <input | |
26 | + type="checkbox" | |
27 | + id="group-{{ group.pk }}-{{ u.pk }}" | |
28 | + {% if u|ingroup:group %}checked="checked"{% endif %}/> | |
29 | + </td> | |
30 | + {% endfor %} | |
31 | + </tr> | |
29 | 32 | {% endfor %} |
30 | - </tr> | |
31 | - {% endfor %} | |
32 | - </table> | |
33 | + </table> | |
33 | 34 | {% endblock %} |
... | ... |
accounts/templates/registration/activate.html
... | ... | @@ -4,10 +4,11 @@ |
4 | 4 | |
5 | 5 | {% block content %} |
6 | 6 | |
7 | -{% blocktrans %} | |
8 | -<h1>Activation</h1> | |
9 | -<p>Your account is now activated. Go <a href="{% url 'main' %}">here</a> to continue.</p> | |
7 | + {% blocktrans %} | |
8 | + <h1>Activation</h1> | |
9 | + <p>Your account is now activated. Go <a href="{% url 'main' %}">here</a> | |
10 | + to continue.</p> | |
10 | 11 | |
11 | -{% endblocktrans %} | |
12 | + {% endblocktrans %} | |
12 | 13 | |
13 | 14 | {% endblock %} |
... | ... |
accounts/templates/registration/login.html
... | ... | @@ -3,32 +3,35 @@ |
3 | 3 | {% load url from future %} |
4 | 4 | |
5 | 5 | {% block content %} |
6 | -{% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %} | |
7 | -<p class="errornote"> | |
8 | -{% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} | |
9 | -</p> | |
10 | -{% endif %} | |
6 | + {% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %} | |
7 | + <p class="errornote"> | |
8 | + {% blocktrans count form.errors.items|length as counter %}Please | |
9 | + correct the error below.{% plural %}Please correct the errors | |
10 | + below.{% endblocktrans %} | |
11 | + </p> | |
12 | + {% endif %} | |
11 | 13 | |
12 | -{% if form.non_field_errors or form.this_is_the_login_form.errors %} | |
13 | -{% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %} | |
14 | -<p class="errornote"> | |
15 | - {{ error }} | |
16 | -</p> | |
17 | -{% endfor %} | |
18 | -{% endif %} | |
14 | + {% if form.non_field_errors or form.this_is_the_login_form.errors %} | |
15 | + {% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %} | |
16 | + <p class="errornote"> | |
17 | + {{ error }} | |
18 | + </p> | |
19 | + {% endfor %} | |
20 | + {% endif %} | |
19 | 21 | |
20 | -<div id="content-main"> | |
21 | -<form action="" method="post" id="login-form">{% csrf_token %} | |
22 | - {{ form.as_p }} | |
23 | - <div class="submit-row"> | |
24 | - <label> </label><input type="submit" value="{% trans 'Log in' %}" /> | |
25 | - </div> | |
26 | -</form> | |
22 | + <div id="content-main"> | |
23 | + <form action="" method="post" id="login-form">{% csrf_token %} | |
24 | + {{ form.as_p }} | |
25 | + <div class="submit-row"> | |
26 | + <label> </label><input type="submit" | |
27 | + value="{% trans 'Log in' %}"/> | |
28 | + </div> | |
29 | + </form> | |
27 | 30 | |
28 | -<a href="{% url 'auth_password_reset' %}">Nie pamiętam hasła</a> | |
31 | + <a href="{% url 'auth_password_reset' %}">Nie pamiętam hasła</a> | |
29 | 32 | |
30 | -<script type="text/javascript"> | |
31 | -document.getElementById('id_username').focus() | |
32 | -</script> | |
33 | -</div> | |
33 | + <script type="text/javascript"> | |
34 | + document.getElementById('id_username').focus() | |
35 | + </script> | |
36 | + </div> | |
34 | 37 | {% endblock %} |
... | ... |
accounts/templates/registration/logout.html
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | |
5 | 5 | {% block content %} |
6 | 6 | |
7 | -<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p> | |
7 | + <p>{% trans "Thanks for spending some quality time with the Web site today." %}</p> | |
8 | 8 | |
9 | -<p><a href="{% url 'auth_login' %}">{% trans 'Log in again' %}</a></p> | |
9 | + <p><a href="{% url 'auth_login' %}">{% trans 'Log in again' %}</a></p> | |
10 | 10 | |
11 | 11 | {% endblock %} |
... | ... |
accounts/templates/registration/password_change_done.html
... | ... | @@ -2,14 +2,15 @@ |
2 | 2 | {% load i18n %} |
3 | 3 | {% load url from future %} |
4 | 4 | |
5 | -{% block userlinks %}{% trans 'Change password' %} / <a href="{{ url 'auth_logout' }}">{% trans 'Log out' %}</a>{% endblock %} | |
5 | +{% block userlinks %}{% trans 'Change password' %} / | |
6 | + <a href="{{ url 'auth_logout' }}">{% trans 'Log out' %}</a>{% endblock %} | |
6 | 7 | |
7 | 8 | {% block title %}{% trans 'Password change successful' %}{% endblock %} |
8 | 9 | |
9 | 10 | {% block content %} |
10 | 11 | |
11 | -<h1>{% trans 'Password change successful' %}</h1> | |
12 | + <h1>{% trans 'Password change successful' %}</h1> | |
12 | 13 | |
13 | -<p>{% trans 'Your password was changed.' %}</p> | |
14 | + <p>{% trans 'Your password was changed.' %}</p> | |
14 | 15 | |
15 | 16 | {% endblock %} |
... | ... |
accounts/templates/registration/password_change_form.html
1 | 1 | {% extends "base.html" %} |
2 | 2 | {% load i18n %} |
3 | 3 | {% load url from future %} |
4 | -{% block userlinks %}{% trans 'Change password' %} / <a href="{% url 'auth_logout' %}">{% trans 'Log out' %}</a>{% endblock %} | |
4 | +{% block userlinks %}{% trans 'Change password' %} / | |
5 | + <a href="{% url 'auth_logout' %}">{% trans 'Log out' %}</a>{% endblock %} | |
5 | 6 | |
6 | 7 | {% block title %}{% trans 'Password change' %}{% endblock %} |
7 | 8 | |
8 | -{% block content %}<div id="content-main"> | |
9 | - | |
10 | -<form action="" method="post">{% csrf_token %} | |
11 | -<div> | |
12 | -{% if form.errors %} | |
13 | - <p class="errornote"> | |
14 | - {% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} | |
15 | - </p> | |
16 | -{% endif %} | |
17 | - | |
18 | -<h1>{% trans 'Password change' %}</h1> | |
19 | - | |
20 | -<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p> | |
21 | - | |
22 | -<fieldset class="module aligned wide"> | |
23 | - | |
24 | -<div class="form-row"> | |
25 | - {{ form.old_password.errors }} | |
26 | - <label for="id_old_password" class="required">{% trans 'Old password' %}:</label>{{ form.old_password }} | |
27 | -</div> | |
28 | - | |
29 | -<div class="form-row"> | |
30 | - {{ form.new_password1.errors }} | |
31 | - <label for="id_new_password1" class="required">{% trans 'New password' %}:</label>{{ form.new_password1 }} | |
32 | -</div> | |
33 | - | |
34 | -<div class="form-row"> | |
35 | -{{ form.new_password2.errors }} | |
36 | - <label for="id_new_password2" class="required">{% trans 'Password (again)' %}:</label>{{ form.new_password2 }} | |
37 | -</div> | |
38 | - | |
39 | -</fieldset> | |
40 | - | |
41 | -<div class="submit-row"> | |
42 | - <input type="submit" value="{% trans 'Change my password' %}" class="default" /> | |
43 | -</div> | |
44 | - | |
45 | -<script type="text/javascript">document.getElementById("id_old_password").focus();</script> | |
46 | -</div> | |
47 | -</form></div> | |
9 | +{% block content %} | |
10 | + <div id="content-main"> | |
11 | + | |
12 | + <form action="" method="post">{% csrf_token %} | |
13 | + <div> | |
14 | + {% if form.errors %} | |
15 | + <p class="errornote"> | |
16 | + {% blocktrans count form.errors.items|length as counter %} | |
17 | + Please correct the error below.{% plural %}Please | |
18 | + correct the errors below.{% endblocktrans %} | |
19 | + </p> | |
20 | + {% endif %} | |
21 | + | |
22 | + <h1>{% trans 'Password change' %}</h1> | |
23 | + | |
24 | + <p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p> | |
25 | + | |
26 | + <fieldset class="module aligned wide"> | |
27 | + | |
28 | + <div class="form-row"> | |
29 | + {{ form.old_password.errors }} | |
30 | + <label for="id_old_password" | |
31 | + class="required">{% trans 'Old password' %}:</label>{{ form.old_password }} | |
32 | + </div> | |
33 | + | |
34 | + <div class="form-row"> | |
35 | + {{ form.new_password1.errors }} | |
36 | + <label for="id_new_password1" | |
37 | + class="required">{% trans 'New password' %}:</label>{{ form.new_password1 }} | |
38 | + </div> | |
39 | + | |
40 | + <div class="form-row"> | |
41 | + {{ form.new_password2.errors }} | |
42 | + <label for="id_new_password2" | |
43 | + class="required">{% trans 'Password (again)' %}:</label>{{ form.new_password2 }} | |
44 | + </div> | |
45 | + | |
46 | + </fieldset> | |
47 | + | |
48 | + <div class="submit-row"> | |
49 | + <input type="submit" value="{% trans 'Change my password' %}" | |
50 | + class="default"/> | |
51 | + </div> | |
52 | + | |
53 | + <script type="text/javascript">document.getElementById("id_old_password").focus();</script> | |
54 | + </div> | |
55 | + </form></div> | |
48 | 56 | |
49 | 57 | {% endblock %} |
... | ... |
accounts/templates/registration/password_reset_complete.html
... | ... | @@ -5,10 +5,10 @@ |
5 | 5 | |
6 | 6 | {% block content %} |
7 | 7 | |
8 | -<h1>{% trans 'Password reset complete' %}</h1> | |
8 | + <h1>{% trans 'Password reset complete' %}</h1> | |
9 | 9 | |
10 | -<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p> | |
10 | + <p>{% trans "Your password has been set. You may go ahead and log in now." %}</p> | |
11 | 11 | |
12 | -<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p> | |
12 | + <p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p> | |
13 | 13 | |
14 | 14 | {% endblock %} |
... | ... |
accounts/templates/registration/password_reset_confirm.html
... | ... | @@ -5,26 +5,32 @@ |
5 | 5 | |
6 | 6 | {% block content %} |
7 | 7 | |
8 | -{% if validlink %} | |
8 | + {% if validlink %} | |
9 | 9 | |
10 | -<h1>{% trans 'Enter new password' %}</h1> | |
10 | + <h1>{% trans 'Enter new password' %}</h1> | |
11 | 11 | |
12 | -<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p> | |
12 | + <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p> | |
13 | 13 | |
14 | -<form action="" method="post">{% csrf_token %} | |
15 | -{{ form.new_password1.errors }} | |
16 | -<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p> | |
17 | -{{ form.new_password2.errors }} | |
18 | -<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p> | |
19 | -<p><input type="submit" value="{% trans 'Change my password' %}" /></p> | |
20 | -</form> | |
14 | + <form action="" method="post">{% csrf_token %} | |
15 | + {{ form.new_password1.errors }} | |
16 | + <p class="aligned wide"><label | |
17 | + for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }} | |
18 | + </p> | |
19 | + {{ form.new_password2.errors }} | |
20 | + <p class="aligned wide"><label | |
21 | + for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }} | |
22 | + </p> | |
21 | 23 | |
22 | -{% else %} | |
24 | + <p><input type="submit" value="{% trans 'Change my password' %}"/> | |
25 | + </p> | |
26 | + </form> | |
23 | 27 | |
24 | -<h1>{% trans 'Password reset unsuccessful' %}</h1> | |
28 | + {% else %} | |
25 | 29 | |
26 | -<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p> | |
30 | + <h1>{% trans 'Password reset unsuccessful' %}</h1> | |
27 | 31 | |
28 | -{% endif %} | |
32 | + <p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p> | |
33 | + | |
34 | + {% endif %} | |
29 | 35 | |
30 | 36 | {% endblock %} |
... | ... |
accounts/templates/registration/password_reset_done.html
... | ... | @@ -5,8 +5,8 @@ |
5 | 5 | |
6 | 6 | {% block content %} |
7 | 7 | |
8 | -<h1>{% trans 'Password reset successful' %}</h1> | |
8 | + <h1>{% trans 'Password reset successful' %}</h1> | |
9 | 9 | |
10 | -<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p> | |
10 | + <p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p> | |
11 | 11 | |
12 | 12 | {% endblock %} |
... | ... |
accounts/templates/registration/password_reset_email.html
1 | 1 | {% load i18n %}{% load url from future %}{% autoescape off %} |
2 | 2 | |
3 | -Szanowny Użytkowniku! | |
3 | + Szanowny Użytkowniku! | |
4 | 4 | |
5 | -Ten list jest częścią procedury ustanawiania lub zmiany hasła w systemie Kuźnia. | |
6 | -Jeżeli fakt, że masz konto w systemie Kuźnia jest dla Ciebie | |
7 | -zaskoczeniem, zechciej ten list uznać za doniesienie, że właśnie | |
8 | -założyliśmy Ci konto. | |
5 | + Ten list jest częścią procedury ustanawiania lub zmiany hasła w systemie | |
6 | + Kuźnia. | |
7 | + Jeżeli fakt, że masz konto w systemie Kuźnia jest dla Ciebie | |
8 | + zaskoczeniem, zechciej ten list uznać za doniesienie, że właśnie | |
9 | + założyliśmy Ci konto. | |
9 | 10 | |
10 | -Aby wprowadzić nowe hasło, przejdź na następującą stronę: | |
11 | -{% block reset_link %} | |
12 | -{{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %} | |
13 | -{% endblock %} | |
11 | + Aby wprowadzić nowe hasło, przejdź na następującą stronę: | |
12 | + {% block reset_link %} | |
13 | + {{ protocol }}:// | |
14 | + {{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %} | |
15 | + {% endblock %} | |
14 | 16 | |
15 | -Twoja nazwa użytkownika: {{ user.username }} | |
17 | + Twoja nazwa użytkownika: {{ user.username }} | |
16 | 18 | |
17 | -Z wyrazami szacunku | |
18 | -Zespół Kuźni | |
19 | + Z wyrazami szacunku | |
20 | + Zespół Kuźni | |
19 | 21 | {% endautoescape %} |
... | ... |
accounts/templates/registration/password_reset_form.html
... | ... | @@ -5,13 +5,15 @@ |
5 | 5 | |
6 | 6 | {% block content %} |
7 | 7 | |
8 | -<h1>{% trans "Password reset" %}</h1> | |
8 | + <h1>{% trans "Password reset" %}</h1> | |
9 | 9 | |
10 | -<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p> | |
10 | + <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p> | |
11 | 11 | |
12 | -<form action="" method="post">{% csrf_token %} | |
13 | -{{ form.email.errors }} | |
14 | -<p><label for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p> | |
15 | -</form> | |
12 | + <form action="" method="post">{% csrf_token %} | |
13 | + {{ form.email.errors }} | |
14 | + <p><label | |
15 | + for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} | |
16 | + <input type="submit" value="{% trans 'Reset my password' %}"/></p> | |
17 | + </form> | |
16 | 18 | |
17 | 19 | {% endblock %} |
... | ... |
accounts/templates/registration/registration_complete.html
... | ... | @@ -3,9 +3,10 @@ |
3 | 3 | |
4 | 4 | {% block content %} |
5 | 5 | |
6 | -{% blocktrans %} | |
7 | -<h1>Thank you</h1> | |
8 | -<p>An email has been sent to you. You need to click link in it to activate your account.</p> | |
9 | -{% endblocktrans %} | |
6 | + {% blocktrans %} | |
7 | + <h1>Thank you</h1> | |
8 | + <p>An email has been sent to you. You need to click link in it to | |
9 | + activate your account.</p> | |
10 | + {% endblocktrans %} | |
10 | 11 | |
11 | 12 | {% endblock %} |
... | ... |
accounts/templates/registration/registration_form.html
... | ... | @@ -3,36 +3,40 @@ |
3 | 3 | {% load url from future %} |
4 | 4 | |
5 | 5 | {% block extrahead %} |
6 | - <style> | |
7 | - label { | |
8 | - vertical-align: top; | |
9 | - width: 100px; | |
10 | - display: inline-block; | |
11 | - } | |
12 | - </style> | |
6 | + <style> | |
7 | + label { | |
8 | + vertical-align: top; | |
9 | + width: 100px; | |
10 | + display: inline-block; | |
11 | + } | |
12 | + </style> | |
13 | 13 | {% endblock %} |
14 | 14 | |
15 | 15 | {% block title %}{% trans 'Registration' %}{% endblock %} |
16 | 16 | |
17 | -{% block content %}<div id="content-main"> | |
17 | +{% block content %} | |
18 | + <div id="content-main"> | |
18 | 19 | |
19 | -<form action="" method="post">{% csrf_token %} | |
20 | -<div> | |
21 | -{% if form.errors %} | |
22 | - <p class="errornote"> | |
23 | - {% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} | |
24 | - </p> | |
25 | -{% endif %} | |
20 | + <form action="" method="post">{% csrf_token %} | |
21 | + <div> | |
22 | + {% if form.errors %} | |
23 | + <p class="errornote"> | |
24 | + {% blocktrans count form.errors.items|length as counter %} | |
25 | + Please correct the error below.{% plural %}Please | |
26 | + correct the errors below.{% endblocktrans %} | |
27 | + </p> | |
28 | + {% endif %} | |
26 | 29 | |
27 | -<h1>{% trans 'Registration' %}</h1> | |
30 | + <h1>{% trans 'Registration' %}</h1> | |
28 | 31 | |
29 | -{{ form.as_p }} | |
32 | + {{ form.as_p }} | |
30 | 33 | |
31 | -<div class="submit-row"> | |
32 | - <input type="submit" value="{% trans 'Add user' %}" class="default" /> | |
33 | -</div> | |
34 | + <div class="submit-row"> | |
35 | + <input type="submit" value="{% trans 'Add user' %}" | |
36 | + class="default"/> | |
37 | + </div> | |
34 | 38 | |
35 | -</div> | |
36 | -</form></div> | |
39 | + </div> | |
40 | + </form></div> | |
37 | 41 | |
38 | 42 | {% endblock %} |
... | ... |
accounts/templates/settings.html
... | ... | @@ -4,16 +4,16 @@ |
4 | 4 | {% block title %}Ustawienia{% endblock %} |
5 | 5 | |
6 | 6 | {% block content %} |
7 | -<h1>Ustawienia użytkownika</h1> | |
8 | -<form method="post" action=""> | |
9 | - {{ form.as_p }} | |
10 | - {% csrf_token %} | |
11 | - <input type="hidden" name="next" value="{{ next }}"/> | |
12 | - <button type="submit"> | |
13 | - Zapisz | |
14 | - </button> | |
15 | -</form> | |
16 | -<p> | |
17 | - <a href="{% url 'auth_password_change' %}">Zmiana hasła</a> | |
18 | -</p> | |
7 | + <h1>Ustawienia użytkownika</h1> | |
8 | + <form method="post" action=""> | |
9 | + {{ form.as_p }} | |
10 | + {% csrf_token %} | |
11 | + <input type="hidden" name="next" value="{{ next }}"/> | |
12 | + <button type="submit"> | |
13 | + Zapisz | |
14 | + </button> | |
15 | + </form> | |
16 | + <p> | |
17 | + <a href="{% url 'auth_password_change' %}">Zmiana hasła</a> | |
18 | + </p> | |
19 | 19 | {% endblock %} |
... | ... |
accounts/util.py
... | ... | @@ -6,13 +6,15 @@ from django.contrib.auth.models import User |
6 | 6 | |
7 | 7 | |
8 | 8 | def set_history(user): |
9 | - cursor = connection.cursor() | |
10 | - cursor.execute("SELECT set_config('var.user_id', %s, true)", [str(user.id)]) | |
9 | + cursor = connection.cursor() | |
10 | + cursor.execute("SELECT set_config('var.user_id', %s, true)", [str(user.id)]) | |
11 | + | |
11 | 12 | |
12 | 13 | def bot_history(): |
13 | - set_history(User.objects.get(username=u'Kuźniobot')) | |
14 | + set_history(User.objects.get(username=u'Kuźniobot')) | |
15 | + | |
14 | 16 | |
15 | 17 | def users_with_perm(perm): |
16 | - return User.objects.filter( | |
17 | - Q(groups__permissions=perm) | Q(user_permissions=perm) | | |
18 | - Q(is_superuser=True)).distinct() | |
19 | 18 | \ No newline at end of file |
19 | + return User.objects.filter( | |
20 | + Q(groups__permissions=perm) | Q(user_permissions=perm) | | |
21 | + Q(is_superuser=True)).distinct() | |
20 | 22 | \ No newline at end of file |
... | ... |
accounts/views.py
... | ... | @@ -9,43 +9,47 @@ from accounts.forms import AddUserForm, SettingsForm |
9 | 9 | from accounts.models import UserSettings, manager_groups |
10 | 10 | from dictionary.models import editable_vocabularies |
11 | 11 | |
12 | + | |
12 | 13 | @permission_required('auth.add_user') |
13 | 14 | @render('registration/registration_form.html') |
14 | 15 | def register(request): |
15 | - if request.method == 'POST': | |
16 | - form = AddUserForm(data=request.POST) | |
17 | - if form.is_valid(): | |
18 | - form.save(request=request) | |
19 | - return HttpResponseRedirect(reverse('registration_complete')) | |
20 | - else: | |
21 | - form = AddUserForm() | |
22 | - if not request.user.has_perm('accounts.create_admin'): | |
23 | - choices = ((g.pk, g.name) for g in manager_groups()) | |
24 | - form.fields['groups'].choices = choices | |
25 | - return {'form': form} | |
16 | + if request.method == 'POST': | |
17 | + form = AddUserForm(data=request.POST) | |
18 | + if form.is_valid(): | |
19 | + form.save(request=request) | |
20 | + return HttpResponseRedirect(reverse('registration_complete')) | |
21 | + else: | |
22 | + form = AddUserForm() | |
23 | + if not request.user.has_perm('accounts.create_admin'): | |
24 | + choices = ((g.pk, g.name) for g in manager_groups()) | |
25 | + form.fields['groups'].choices = choices | |
26 | + return {'form': form} | |
27 | + | |
26 | 28 | |
27 | 29 | @login_required |
28 | 30 | @render() |
29 | 31 | def settings(request): |
30 | - user_settings, created = UserSettings.objects.get_or_create(user=request.user) | |
31 | - if request.method == 'POST': | |
32 | - form = SettingsForm(data=request.POST, instance=user_settings) | |
33 | - if form.is_valid(): | |
34 | - form.save() | |
35 | - return HttpResponseRedirect(request.POST['next']) | |
36 | - else: | |
37 | - form = SettingsForm( | |
38 | - instance=user_settings, | |
39 | - vocabularies=editable_vocabularies(request.user)) | |
40 | - return {'form': form, 'next': request.META.get('HTTP_REFERER', '')} | |
32 | + user_settings, created = UserSettings.objects.get_or_create( | |
33 | + user=request.user) | |
34 | + if request.method == 'POST': | |
35 | + form = SettingsForm(data=request.POST, instance=user_settings) | |
36 | + if form.is_valid(): | |
37 | + form.save() | |
38 | + return HttpResponseRedirect(request.POST['next']) | |
39 | + else: | |
40 | + form = SettingsForm( | |
41 | + instance=user_settings, | |
42 | + vocabularies=editable_vocabularies(request.user)) | |
43 | + return {'form': form, 'next': request.META.get('HTTP_REFERER', '')} | |
44 | + | |
41 | 45 | |
42 | 46 | @permission_required('auth.add_user') |
43 | 47 | @render() |
44 | 48 | def manage_groups(request): |
45 | - users = User.objects.filter(is_superuser=False) | |
46 | - if request.user.has_perm('accounts.create_admin'): | |
47 | - groups = Group.objects.all() | |
48 | - else: | |
49 | - groups = manager_groups() | |
50 | - js_vars = {'ajax_set_group': reverse('set_group')} | |
51 | - return {'users': users, 'groups': groups, 'js_vars': js_vars} | |
49 | + users = User.objects.filter(is_superuser=False) | |
50 | + if request.user.has_perm('accounts.create_admin'): | |
51 | + groups = Group.objects.all() | |
52 | + else: | |
53 | + groups = manager_groups() | |
54 | + js_vars = {'ajax_set_group': reverse('set_group')} | |
55 | + return {'users': users, 'groups': groups, 'js_vars': js_vars} | |
... | ... |
common/context_processors.py
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | |
3 | 3 | def error_proc(request): |
4 | - if request.session.get('error', ''): | |
5 | - error = request.session.pop('error') | |
6 | - return {'error': error} | |
7 | - else: | |
8 | - return {} | |
4 | + if request.session.get('error', ''): | |
5 | + error = request.session.pop('error') | |
6 | + return {'error': error} | |
7 | + else: | |
8 | + return {} | |
9 | + | |
9 | 10 | |
10 | 11 | def message_proc(request): |
11 | - if request.session.get('message', ''): | |
12 | - message = request.session.pop('message') | |
13 | - return {'alert_message': message} | |
14 | - else: | |
15 | - return {} | |
12 | + if request.session.get('message', ''): | |
13 | + message = request.session.pop('message') | |
14 | + return {'alert_message': message} | |
15 | + else: | |
16 | + return {} | |
... | ... |
common/decorators.py
... | ... | @@ -15,70 +15,84 @@ from common.util import stringify_keys |
15 | 15 | |
16 | 16 | |
17 | 17 | class AjaxError(Exception): |
18 | - pass | |
18 | + pass | |
19 | + | |
19 | 20 | |
20 | 21 | def json_decode_fallback(value): |
21 | - try: | |
22 | - return json_decode(value) | |
23 | - except ValueError: | |
24 | - return value | |
22 | + try: | |
23 | + return json_decode(value) | |
24 | + except ValueError: | |
25 | + return value | |
26 | + | |
25 | 27 | |
26 | 28 | def ajax(login_required=True, method=None, encode_result=True, template=None): |
27 | - def decorator(fun): | |
28 | - @wraps(fun) | |
29 | - def ajax_view(request): | |
30 | - kwargs = {} | |
31 | - request_params = None | |
32 | - if method == 'post': | |
33 | - request_params = request.POST | |
34 | - elif method == 'get': | |
35 | - request_params = request.GET | |
36 | - fun_params, xx, fun_kwargs, xxxx = getargspec(fun) | |
37 | - if request_params: | |
38 | - request_params = dict((key, json_decode_fallback(value)) | |
39 | - for key, value in request_params.iteritems() | |
40 | - if fun_kwargs or key in fun_params) | |
41 | - kwargs.update(stringify_keys(request_params)) | |
42 | - res = None | |
43 | - if login_required and not request.user.is_authenticated(): | |
44 | - res = {'result': 'logout'} | |
45 | - if not res: | |
46 | - try: | |
47 | - res = fun(request, **kwargs) | |
48 | - except AjaxError as e: | |
49 | - transaction.rollback() | |
50 | - res = {'result': e.args[0]} | |
51 | - if template: | |
52 | - res = {'html': render_to_string(template, res, RequestContext(request))} | |
53 | - if encode_result: | |
54 | - if 'result' not in res: | |
55 | - res['result'] = 'ok' | |
56 | - return HttpResponse(json_encode(res), mimetype='application/json') | |
57 | - else: | |
58 | - return res | |
59 | - return ajax_view | |
60 | - return decorator | |
29 | + def decorator(fun): | |
30 | + @wraps(fun) | |
31 | + def ajax_view(request): | |
32 | + kwargs = {} | |
33 | + request_params = None | |
34 | + if method == 'post': | |
35 | + request_params = request.POST | |
36 | + elif method == 'get': | |
37 | + request_params = request.GET | |
38 | + fun_params, xx, fun_kwargs, xxxx = getargspec(fun) | |
39 | + if request_params: | |
40 | + request_params = dict((key, json_decode_fallback(value)) | |
41 | + for key, value in | |
42 | + request_params.iteritems() | |
43 | + if fun_kwargs or key in fun_params) | |
44 | + kwargs.update(stringify_keys(request_params)) | |
45 | + res = None | |
46 | + if login_required and not request.user.is_authenticated(): | |
47 | + res = {'result': 'logout'} | |
48 | + if not res: | |
49 | + try: | |
50 | + res = fun(request, **kwargs) | |
51 | + except AjaxError as e: | |
52 | + transaction.rollback() | |
53 | + res = {'result': e.args[0]} | |
54 | + if template: | |
55 | + res = {'html': render_to_string(template, res, | |
56 | + RequestContext(request))} | |
57 | + if encode_result: | |
58 | + if 'result' not in res: | |
59 | + res['result'] = 'ok' | |
60 | + return HttpResponse(json_encode(res), | |
61 | + mimetype='application/json') | |
62 | + else: | |
63 | + return res | |
64 | + | |
65 | + return ajax_view | |
66 | + | |
67 | + return decorator | |
68 | + | |
61 | 69 | |
62 | 70 | def render(template=None, mimetype=None): |
63 | - mimetype = mimetype or settings.DEFAULT_CONTENT_TYPE | |
64 | - template1 = template | |
65 | - def decorator(func): | |
66 | - template = template1 # no cóż... | |
67 | - if not template: | |
68 | - template = func.__name__ + '.html' | |
69 | - @wraps(func) | |
70 | - def renderer(request, *args, **kw): | |
71 | - output = func(request, *args, **kw) | |
72 | - if isinstance(output, (list, tuple)): | |
73 | - return render_to_response( | |
74 | - output[1], output[0], RequestContext(request), mimetype=mimetype) | |
75 | - elif isinstance(output, dict): | |
76 | - return render_to_response( | |
77 | - template, output, RequestContext(request), mimetype=mimetype) | |
78 | - return output | |
79 | - return renderer | |
80 | - return decorator | |
71 | + mimetype = mimetype or settings.DEFAULT_CONTENT_TYPE | |
72 | + template1 = template | |
73 | + | |
74 | + def decorator(func): | |
75 | + template = template1 # no cóż... | |
76 | + if not template: | |
77 | + template = func.__name__ + '.html' | |
78 | + | |
79 | + @wraps(func) | |
80 | + def renderer(request, *args, **kw): | |
81 | + output = func(request, *args, **kw) | |
82 | + if isinstance(output, (list, tuple)): | |
83 | + return render_to_response( | |
84 | + output[1], output[0], RequestContext(request), | |
85 | + mimetype=mimetype) | |
86 | + elif isinstance(output, dict): | |
87 | + return render_to_response( | |
88 | + template, output, RequestContext(request), | |
89 | + mimetype=mimetype) | |
90 | + return output | |
91 | + | |
92 | + return renderer | |
93 | + | |
94 | + return decorator | |
81 | 95 | |
82 | 96 | # żeby były linki do szablonów w PyCharm przy ajaxach |
83 | 97 | def render_template(t): |
84 | - return lambda x: x | |
85 | 98 | \ No newline at end of file |
99 | + return lambda x: x | |
86 | 100 | \ No newline at end of file |
... | ... |
common/forms.py
... | ... | @@ -3,12 +3,14 @@ |
3 | 3 | from django import forms |
4 | 4 | from django.utils.encoding import force_unicode |
5 | 5 | |
6 | + | |
6 | 7 | def hidden_id(id): |
7 | - return forms.CharField(initial=id, widget=forms.HiddenInput()) | |
8 | + return forms.CharField(initial=id, widget=forms.HiddenInput()) | |
8 | 9 | |
9 | 10 | # http://www.djangosnippets.org/snippets/863/ z moimi zmianami |
10 | 11 | class ChoiceWithOtherRenderer(forms.RadioSelect.renderer): |
11 | 12 | """RadioFieldRenderer that renders its last choice with a placeholder.""" |
13 | + | |
12 | 14 | def __init__(self, *args, **kwargs): |
13 | 15 | super(ChoiceWithOtherRenderer, self).__init__(*args, **kwargs) |
14 | 16 | self.choices, self.other = self.choices[:-1], self.choices[-1] |
... | ... | @@ -16,17 +18,22 @@ class ChoiceWithOtherRenderer(forms.RadioSelect.renderer): |
16 | 18 | def __iter__(self): |
17 | 19 | for input in super(ChoiceWithOtherRenderer, self).__iter__(): |
18 | 20 | yield input |
19 | - id = '%s_%s' % (self.attrs['id'], self.other[0]) if 'id' in self.attrs else '' | |
21 | + id = '%s_%s' % ( | |
22 | + self.attrs['id'], self.other[0]) if 'id' in self.attrs else '' | |
20 | 23 | label_for = ' for="%s"' % id if id else '' |
21 | - checked = '' if not force_unicode(self.other[0]) == self.value else 'checked="true" ' | |
24 | + checked = '' if not force_unicode( | |
25 | + self.other[0]) == self.value else 'checked="true" ' | |
22 | 26 | yield '<label%s><input type="radio" id="%s" value="%s" name="%s" %s/> %s</label> %%s' % ( |
23 | 27 | label_for, id, self.other[0], self.name, checked, self.other[1]) |
24 | 28 | |
29 | + | |
25 | 30 | class ChoiceWithOtherWidget(forms.MultiWidget): |
26 | 31 | """MultiWidget for use with ChoiceWithOtherField.""" |
32 | + | |
27 | 33 | def __init__(self, choices): |
28 | 34 | widgets = [ |
29 | - forms.RadioSelect(choices=choices, renderer=ChoiceWithOtherRenderer), | |
35 | + forms.RadioSelect(choices=choices, | |
36 | + renderer=ChoiceWithOtherRenderer), | |
30 | 37 | forms.TextInput |
31 | 38 | ] |
32 | 39 | super(ChoiceWithOtherWidget, self).__init__(widgets) |
... | ... | @@ -40,20 +47,25 @@ class ChoiceWithOtherWidget(forms.MultiWidget): |
40 | 47 | """Format the output by substituting the "other" choice into the first widget.""" |
41 | 48 | return rendered_widgets[0] % rendered_widgets[1] |
42 | 49 | |
50 | + | |
43 | 51 | class ChoiceWithOtherField(forms.MultiValueField): |
44 | 52 | """ |
45 | 53 | ChoiceField with an option for a user-submitted "other" value. |
46 | 54 | """ |
55 | + | |
47 | 56 | def __init__(self, *args, **kwargs): |
48 | 57 | fields = [ |
49 | - forms.ChoiceField(widget=forms.RadioSelect(renderer=ChoiceWithOtherRenderer), *args, **kwargs), | |
58 | + forms.ChoiceField( | |
59 | + widget=forms.RadioSelect(renderer=ChoiceWithOtherRenderer), | |
60 | + *args, **kwargs), | |
50 | 61 | forms.CharField(required=False) |
51 | 62 | ] |
52 | 63 | widget = ChoiceWithOtherWidget(choices=kwargs['choices']) |
53 | 64 | kwargs.pop('choices') |
54 | 65 | self._was_required = kwargs.pop('required', True) |
55 | 66 | kwargs['required'] = False |
56 | - super(ChoiceWithOtherField, self).__init__(widget=widget, fields=fields, *args, **kwargs) | |
67 | + super(ChoiceWithOtherField, self).__init__(widget=widget, fields=fields, | |
68 | + *args, **kwargs) | |
57 | 69 | |
58 | 70 | def compress(self, value): |
59 | 71 | if self._was_required and (not value or value[0] in (None, '')): |
... | ... | @@ -61,5 +73,6 @@ class ChoiceWithOtherField(forms.MultiValueField): |
61 | 73 | if not value: |
62 | 74 | return [None, u''] |
63 | 75 | return (value[0], value[1] |
64 | - if force_unicode(value[0]) == force_unicode(self.fields[0].choices[-1][0]) | |
65 | - else self.fields[0].choices[int(value[0]) - 1][1]) | |
66 | 76 | \ No newline at end of file |
77 | + if force_unicode(value[0]) == force_unicode( | |
78 | + self.fields[0].choices[-1][0]) | |
79 | + else self.fields[0].choices[int(value[0]) - 1][1]) | |
67 | 80 | \ No newline at end of file |
... | ... |
common/middleware.py
1 | 1 | #-*- coding:utf-8 -*- |
2 | 2 | |
3 | -from django.db import connection | |
4 | 3 | from decimal import Decimal |
5 | 4 | |
5 | +from django.db import connection | |
6 | + | |
6 | 7 | from accounts.util import set_history |
7 | 8 | |
9 | + | |
8 | 10 | class MyMiddleware(object): |
9 | - def process_request(self, request): | |
10 | - if request.user.is_authenticated(): | |
11 | - set_history(request.user) | |
11 | + def process_request(self, request): | |
12 | + if request.user.is_authenticated(): | |
13 | + set_history(request.user) | |
12 | 14 | |
13 | - def process_response(self, request, response): | |
14 | - if False: | |
15 | - if len(connection.queries) > 0: | |
16 | - print 'Queries for %s:' % request.path_info | |
17 | - for query in connection.queries: | |
18 | - print query['time'], query['sql'] | |
19 | - print 'Total of %s queries for %s.' % ( | |
20 | - len(connection.queries), request.path) | |
21 | - print 'Total time: %s' % sum(Decimal(q['time']) | |
22 | - for q in connection.queries) | |
23 | - return response | |
24 | 15 | \ No newline at end of file |
16 | + def process_response(self, request, response): | |
17 | + if False: | |
18 | + if len(connection.queries) > 0: | |
19 | + print 'Queries for %s:' % request.path_info | |
20 | + for query in connection.queries: | |
21 | + print query['time'], query['sql'] | |
22 | + print 'Total of %s queries for %s.' % ( | |
23 | + len(connection.queries), request.path) | |
24 | + print 'Total time: %s' % sum(Decimal(q['time']) | |
25 | + for q in connection.queries) | |
26 | + return response | |
25 | 27 | \ No newline at end of file |
... | ... |
common/templates/error.html
common/templates/message.html
common/templates/navigation.html
common/templatetags/format_date.py
... | ... | @@ -4,10 +4,12 @@ from django.template import Library |
4 | 4 | |
5 | 5 | register = Library() |
6 | 6 | |
7 | + | |
7 | 8 | @register.filter |
8 | 9 | def format_date(date): |
9 | - return date.strftime('%d.%m.%Y %H:%M') | |
10 | + return date.strftime('%d.%m.%Y %H:%M') | |
11 | + | |
10 | 12 | |
11 | 13 | @register.filter |
12 | 14 | def format_date_exact(date): |
13 | - return date.strftime('%d.%m.%Y %H:%M:%S.%f') | |
15 | + return date.strftime('%d.%m.%Y %H:%M:%S.%f') | |
... | ... |
common/templatetags/get.py
common/templatetags/ingroup.py
common/templatetags/jsonify.py
common/templatetags/script.py
... | ... | @@ -3,10 +3,12 @@ from django import template |
3 | 3 | |
4 | 4 | register = template.Library() |
5 | 5 | |
6 | + | |
6 | 7 | @register.simple_tag |
7 | 8 | def script(): |
8 | - return '<script type="text/javascript"> /* <![CDATA[ */' | |
9 | + return '<script type="text/javascript"> /* <![CDATA[ */' | |
10 | + | |
9 | 11 | |
10 | 12 | @register.simple_tag |
11 | 13 | def endscript(): |
12 | - return '/* ]]> */ </script>' | |
14 | + return '/* ]]> */ </script>' | |
... | ... |
common/util.py
... | ... | @@ -7,96 +7,116 @@ from django.http import HttpResponseRedirect, Http404 |
7 | 7 | |
8 | 8 | |
9 | 9 | def debug(entry, text): |
10 | - print>>sys.stderr, (u'%s: %s' % (entry, text)).encode('utf-8') | |
10 | + print>> sys.stderr, (u'%s: %s' % (entry, text)).encode('utf-8') | |
11 | + | |
11 | 12 | |
12 | 13 | def error_redirect(request, error, url='/'): |
13 | - request.session['error'] = error | |
14 | - return HttpResponseRedirect(url) | |
14 | + request.session['error'] = error | |
15 | + return HttpResponseRedirect(url) | |
16 | + | |
15 | 17 | |
16 | 18 | def message_redirect(request, message, url='/'): |
17 | - request.session['message'] = message | |
18 | - return HttpResponseRedirect(url) | |
19 | + request.session['message'] = message | |
20 | + return HttpResponseRedirect(url) | |
21 | + | |
19 | 22 | |
20 | 23 | def make_form(request, form_class, **kwargs): |
21 | - if request.POST.get('det', '') == form_class.base_fields['det'].initial: | |
22 | - return form_class(data=request.POST, files=request.FILES, **kwargs) | |
23 | - else: | |
24 | - return form_class(**kwargs) | |
24 | + if request.POST.get('det', '') == form_class.base_fields['det'].initial: | |
25 | + return form_class(data=request.POST, files=request.FILES, **kwargs) | |
26 | + else: | |
27 | + return form_class(**kwargs) | |
28 | + | |
25 | 29 | |
26 | 30 | def invert(l): |
27 | - return dict((e,nr) for (nr,e) in enumerate(l)) | |
31 | + return dict((e, nr) for (nr, e) in enumerate(l)) | |
32 | + | |
28 | 33 | |
29 | 34 | def generator_slice(generator, count): |
30 | - res = [] | |
31 | - try: | |
32 | - for i in range(count): | |
33 | - res.append(generator.next()) | |
34 | - except StopIteration: | |
35 | - pass | |
36 | - return res | |
35 | + res = [] | |
36 | + try: | |
37 | + for i in range(count): | |
38 | + res.append(generator.next()) | |
39 | + except StopIteration: | |
40 | + pass | |
41 | + return res | |
42 | + | |
37 | 43 | |
38 | 44 | def url(regex, view, **kwargs): |
39 | - if 'name' not in kwargs: | |
40 | - kwargs['name'] = view.rsplit('.', 1)[-1] | |
41 | - return urls.url(regex, view, **kwargs) | |
45 | + if 'name' not in kwargs: | |
46 | + kwargs['name'] = view.rsplit('.', 1)[-1] | |
47 | + return urls.url(regex, view, **kwargs) | |
48 | + | |
42 | 49 | |
43 | 50 | def stringify_keys(dictionary): |
44 | - return dict((keyword.encode('ascii'), value) | |
45 | - for keyword, value in dictionary.iteritems()) | |
51 | + return dict((keyword.encode('ascii'), value) | |
52 | + for keyword, value in dictionary.iteritems()) | |
46 | 53 | |
47 | 54 | # copypasta ze standardowego modułu bisect |
48 | 55 | def bisect_left(a, x, lo=0, hi=None, cmp=None): |
49 | - if cmp is None: | |
50 | - cmp = __builtins__.cmp | |
51 | - if lo < 0: | |
52 | - raise ValueError('lo must be non-negative') | |
53 | - if hi is None: | |
54 | - hi = len(a) | |
55 | - while lo < hi: | |
56 | - mid = (lo+hi)//2 | |
57 | - if cmp(a[mid], x) < 0: lo = mid+1 | |
58 | - else: hi = mid | |
59 | - return lo | |
56 | + if cmp is None: | |
57 | + cmp = __builtins__.cmp | |
58 | + if lo < 0: | |
59 | + raise ValueError('lo must be non-negative') | |
60 | + if hi is None: | |
61 | + hi = len(a) | |
62 | + while lo < hi: | |
63 | + mid = (lo + hi) // 2 | |
64 | + if cmp(a[mid], x) < 0: | |
65 | + lo = mid + 1 | |
66 | + else: | |
67 | + hi = mid | |
68 | + return lo | |
69 | + | |
60 | 70 | |
61 | 71 | def no_history(): |
62 | - from django.db import connection | |
63 | - cursor = connection.cursor() | |
64 | - cursor.execute("SELECT set_config('var.user_id', '0', false)") | |
72 | + from django.db import connection | |
73 | + | |
74 | + cursor = connection.cursor() | |
75 | + cursor.execute("SELECT set_config('var.user_id', '0', false)") | |
76 | + | |
65 | 77 | |
66 | 78 | def reverse(seq): |
67 | - return seq[::-1] | |
79 | + return seq[::-1] | |
80 | + | |
68 | 81 | |
69 | 82 | def flatten(seq): |
70 | - return [item for subseq in seq for item in subseq] | |
83 | + return [item for subseq in seq for item in subseq] | |
84 | + | |
71 | 85 | |
72 | 86 | def suffix(string, length): |
73 | - return string[-length:] if length > 0 else '' | |
87 | + return string[-length:] if length > 0 else '' | |
88 | + | |
74 | 89 | |
75 | 90 | def suffixes(s): |
76 | - return [s[i:] for i in range(len(s)+1)] | |
91 | + return [s[i:] for i in range(len(s) + 1)] | |
92 | + | |
77 | 93 | |
78 | 94 | def cut_end(s, end): |
79 | - assert s.endswith(end) | |
80 | - n = len(end) | |
81 | - if n == 0: | |
82 | - return s | |
83 | - else: | |
84 | - return s[:-n] | |
95 | + assert s.endswith(end) | |
96 | + n = len(end) | |
97 | + if n == 0: | |
98 | + return s | |
99 | + else: | |
100 | + return s[:-n] | |
101 | + | |
85 | 102 | |
86 | 103 | def error_messages(form): |
87 | - return '\n'.join( | |
88 | - '%s: %s' % (form.fields[k].label, ' '.join(v)) if k != '__all__' | |
89 | - else ' '.join(v) | |
90 | - for k, v in form.errors.iteritems()) | |
104 | + return '\n'.join( | |
105 | + '%s: %s' % (form.fields[k].label, ' '.join(v)) if k != '__all__' | |
106 | + else ' '.join(v) | |
107 | + for k, v in form.errors.iteritems()) | |
108 | + | |
91 | 109 | |
92 | 110 | class GroupDict(dict): |
93 | - def add(self, key, value): | |
94 | - if key not in self: | |
95 | - self[key] = [] | |
96 | - self[key].append(value) | |
111 | + def add(self, key, value): | |
112 | + if key not in self: | |
113 | + self[key] = [] | |
114 | + self[key].append(value) | |
115 | + | |
97 | 116 | |
98 | 117 | def json_encode(obj): |
99 | - return json.dumps(obj, sort_keys=True) | |
118 | + return json.dumps(obj, sort_keys=True) | |
119 | + | |
100 | 120 | |
101 | 121 | def json_decode(obj): |
102 | - return json.loads(obj) | |
103 | 122 | \ No newline at end of file |
123 | + return json.loads(obj) | |
104 | 124 | \ No newline at end of file |
... | ... |
dictionary/ajax_export.py
... | ... | @@ -4,42 +4,46 @@ from common.decorators import render, ajax, AjaxError |
4 | 4 | from dictionary.forms import MagicQualifierForm |
5 | 5 | from dictionary.models import SavedExportData |
6 | 6 | |
7 | + | |
7 | 8 | @render() |
8 | 9 | @ajax(method='get', encode_result=False) |
9 | 10 | def magic_qualifier_row(request): |
10 | - return {'form': MagicQualifierForm(prefix='magic_NUM')} | |
11 | + return {'form': MagicQualifierForm(prefix='magic_NUM')} | |
12 | + | |
11 | 13 | |
12 | 14 | @ajax(method='post') |
13 | 15 | def save_export_data(request, name, serialized_data, force=False): |
14 | - existing_data = SavedExportData.objects.filter(name=name) | |
15 | - if force or not existing_data: | |
16 | - if existing_data: | |
17 | - data = existing_data[0] | |
16 | + existing_data = SavedExportData.objects.filter(name=name) | |
17 | + if force or not existing_data: | |
18 | + if existing_data: | |
19 | + data = existing_data[0] | |
20 | + else: | |
21 | + data = SavedExportData() | |
22 | + data.name = name | |
23 | + data.serialized_data = serialized_data | |
24 | + try: | |
25 | + data.save() | |
26 | + except ValueError as e: | |
27 | + raise AjaxError(e.data) | |
18 | 28 | else: |
19 | - data = SavedExportData() | |
20 | - data.name = name | |
21 | - data.serialized_data = serialized_data | |
22 | - try: | |
23 | - data.save() | |
24 | - except ValueError as e: | |
25 | - raise AjaxError(e.data) | |
26 | - else: | |
27 | - return {'exists': True} | |
28 | - return {} | |
29 | + return {'exists': True} | |
30 | + return {} | |
31 | + | |
29 | 32 | |
30 | 33 | @ajax(method='get') |
31 | 34 | def get_export_data(request): |
32 | - data_list = [{ | |
33 | - 'id': 'export%s' % data.pk, | |
34 | - 'name': data.name, | |
35 | - 'json': data.serialized_data, | |
36 | - } | |
37 | - for data in SavedExportData.objects.all()] | |
38 | - return {'data_list': data_list} | |
35 | + data_list = [{ | |
36 | + 'id': 'export%s' % data.pk, | |
37 | + 'name': data.name, | |
38 | + 'json': data.serialized_data, | |
39 | + } | |
40 | + for data in SavedExportData.objects.all()] | |
41 | + return {'data_list': data_list} | |
42 | + | |
39 | 43 | |
40 | 44 | @ajax(method='post') |
41 | 45 | def delete_export_data(request, data_id): |
42 | - export_data_id = data_id[len('export'):] | |
43 | - data = SavedExportData.objects.get(pk=export_data_id) | |
44 | - data.delete() | |
45 | - return {} | |
46 | + export_data_id = data_id[len('export'):] | |
47 | + data = SavedExportData.objects.get(pk=export_data_id) | |
48 | + data.delete() | |
49 | + return {} | |
... | ... |
dictionary/ajax_filters.py
... | ... | @@ -3,41 +3,44 @@ |
3 | 3 | from common.decorators import ajax, AjaxError |
4 | 4 | from dictionary.models import SavedFilter |
5 | 5 | |
6 | + | |
6 | 7 | @ajax(method='post') |
7 | 8 | def save_filter(request, name, serialized_filter, super=False, force=False): |
8 | - existing_filter = SavedFilter.objects.filter(user=request.user, name=name) | |
9 | - if force or not existing_filter: | |
10 | - if existing_filter: | |
11 | - filter = existing_filter[0] | |
9 | + existing_filter = SavedFilter.objects.filter(user=request.user, name=name) | |
10 | + if force or not existing_filter: | |
11 | + if existing_filter: | |
12 | + filter = existing_filter[0] | |
13 | + else: | |
14 | + filter = SavedFilter() | |
15 | + filter.name = name | |
16 | + filter.user = request.user | |
17 | + filter.serialized_filter = serialized_filter | |
18 | + filter.super = super | |
19 | + try: | |
20 | + filter.save() | |
21 | + except ValueError as e: | |
22 | + raise AjaxError(e.data) | |
12 | 23 | else: |
13 | - filter = SavedFilter() | |
14 | - filter.name = name | |
15 | - filter.user = request.user | |
16 | - filter.serialized_filter = serialized_filter | |
17 | - filter.super = super | |
18 | - try: | |
19 | - filter.save() | |
20 | - except ValueError as e: | |
21 | - raise AjaxError(e.data) | |
22 | - else: | |
23 | - return {'exists': True} | |
24 | - return {} | |
24 | + return {'exists': True} | |
25 | + return {} | |
26 | + | |
25 | 27 | |
26 | 28 | @ajax(method='get') |
27 | 29 | def get_filters(request): |
28 | - filters = [{ | |
29 | - 'id': 'filter%s' % filter.pk, | |
30 | - 'name': filter.name, | |
31 | - 'json': filter.serialized_filter, | |
32 | - } | |
33 | - for filter in SavedFilter.objects.filter(user=request.user)] | |
34 | - return {'filters': filters} | |
30 | + filters = [{ | |
31 | + 'id': 'filter%s' % filter.pk, | |
32 | + 'name': filter.name, | |
33 | + 'json': filter.serialized_filter, | |
34 | + } | |
35 | + for filter in SavedFilter.objects.filter(user=request.user)] | |
36 | + return {'filters': filters} | |
37 | + | |
35 | 38 | |
36 | 39 | @ajax(method='post') |
37 | 40 | def delete_filter(request, id): |
38 | - filter_id = id[len('filter'):] | |
39 | - filter = SavedFilter.objects.get(pk=filter_id) | |
40 | - if filter.user != request.user: | |
41 | - raise AjaxError('access denied') | |
42 | - filter.delete() | |
43 | - return {} | |
41 | + filter_id = id[len('filter'):] | |
42 | + filter = SavedFilter.objects.get(pk=filter_id) | |
43 | + if filter.user != request.user: | |
44 | + raise AjaxError('access denied') | |
45 | + filter.delete() | |
46 | + return {} | |
... | ... |
dictionary/ajax_history.py
... | ... | @@ -4,10 +4,11 @@ from common.decorators import ajax, render_template |
4 | 4 | from dictionary.models import History |
5 | 5 | from dictionary.history import lexeme_tables |
6 | 6 | |
7 | + | |
7 | 8 | @render_template('history_table.html') |
8 | 9 | @ajax(method='get', template='history_table.html') |
9 | 10 | def history_table(request, lexeme_id): |
10 | - history_items = History.objects.filter( | |
11 | - lexeme__pk=lexeme_id).order_by('-transaction_began') | |
12 | - transaction_tables = lexeme_tables(history_items) | |
13 | - return {'transaction_tables': transaction_tables} | |
11 | + history_items = History.objects.filter( | |
12 | + lexeme__pk=lexeme_id).order_by('-transaction_began') | |
13 | + transaction_tables = lexeme_tables(history_items) | |
14 | + return {'transaction_tables': transaction_tables} | |
... | ... |
dictionary/ajax_jqgrid.py
... | ... | @@ -4,267 +4,270 @@ import math |
4 | 4 | from accounts.models import filtering_mode |
5 | 5 | from common.decorators import render, ajax |
6 | 6 | |
7 | + | |
7 | 8 | class JqGridQuery(object): |
8 | - def __init__(self, filters, sort_rules, mask, user): | |
9 | - self.filters = filters | |
10 | - self.sort_rules = sort_rules | |
11 | - self.mask = mask | |
12 | - self.user = user | |
9 | + def __init__(self, filters, sort_rules, mask, user): | |
10 | + self.filters = filters | |
11 | + self.sort_rules = sort_rules | |
12 | + self.mask = mask | |
13 | + self.user = user | |
14 | + | |
15 | + def filtering_mode(self): | |
16 | + return filtering_mode(self.user) | |
13 | 17 | |
14 | - def filtering_mode(self): | |
15 | - return filtering_mode(self.user) | |
16 | 18 | |
17 | 19 | class JqGridAjax(object): |
18 | - model = None | |
19 | - search_field = None | |
20 | - field_translation = {} | |
20 | + model = None | |
21 | + search_field = None | |
22 | + field_translation = {} | |
21 | 23 | |
22 | - @classmethod | |
23 | - def translate_field(cls, field): | |
24 | - if field in cls.field_translation: | |
25 | - return cls.field_translation[field] | |
26 | - else: | |
27 | - return field | |
24 | + @classmethod | |
25 | + def translate_field(cls, field): | |
26 | + if field in cls.field_translation: | |
27 | + return cls.field_translation[field] | |
28 | + else: | |
29 | + return field | |
28 | 30 | |
29 | - @staticmethod | |
30 | - def sort_field_special_case(rule): | |
31 | - return rule['field'] | |
31 | + @staticmethod | |
32 | + def sort_field_special_case(rule): | |
33 | + return rule['field'] | |
32 | 34 | |
33 | - @classmethod | |
34 | - def get_sort_field(cls, rule): | |
35 | - field = cls.sort_field_special_case(rule) | |
36 | - field = cls.translate_field(field) | |
37 | - if rule['order'] == 'desc': | |
38 | - field = '-' + field | |
39 | - return field | |
35 | + @classmethod | |
36 | + def get_sort_field(cls, rule): | |
37 | + field = cls.sort_field_special_case(rule) | |
38 | + field = cls.translate_field(field) | |
39 | + if rule['order'] == 'desc': | |
40 | + field = '-' + field | |
41 | + return field | |
40 | 42 | |
41 | - @staticmethod | |
42 | - def sort_queryset_special_case(queryset, field): | |
43 | - return queryset | |
43 | + @staticmethod | |
44 | + def sort_queryset_special_case(queryset, field): | |
45 | + return queryset | |
44 | 46 | |
45 | - @classmethod | |
46 | - def sort_queryset(cls, queryset, sort_rules): | |
47 | - order_list = [] | |
48 | - for rule in sort_rules: | |
49 | - queryset = cls.sort_queryset_special_case(queryset, rule) | |
50 | - order_list.append(cls.get_sort_field(rule)) | |
51 | - return queryset.extra(order_by=order_list) | |
47 | + @classmethod | |
48 | + def sort_queryset(cls, queryset, sort_rules): | |
49 | + order_list = [] | |
50 | + for rule in sort_rules: | |
51 | + queryset = cls.sort_queryset_special_case(queryset, rule) | |
52 | + order_list.append(cls.get_sort_field(rule)) | |
53 | + return queryset.extra(order_by=order_list) | |
52 | 54 | |
53 | - lookup_translation = { | |
54 | - 'eq': 'exact', | |
55 | - 'ne': '-exact', | |
56 | - 'bw': 'startswith', | |
57 | - 'bn': '-startswith', | |
58 | - 'ew': 'endswith', | |
59 | - 'en': '-endswith', | |
60 | - 'cn': 'contains', | |
61 | - 'nc': '-contains', | |
62 | - 're': 'regex', | |
63 | - 'nr': '-regex', | |
64 | - #'se': 'surely', | |
65 | - #'sd': '-maybe', | |
66 | - #'me': 'maybe', | |
67 | - #'md': '-surely', | |
68 | - 'le': 'lte', | |
69 | - 'ge': 'gte', | |
70 | - } | |
55 | + lookup_translation = { | |
56 | + 'eq': 'exact', | |
57 | + 'ne': '-exact', | |
58 | + 'bw': 'startswith', | |
59 | + 'bn': '-startswith', | |
60 | + 'ew': 'endswith', | |
61 | + 'en': '-endswith', | |
62 | + 'cn': 'contains', | |
63 | + 'nc': '-contains', | |
64 | + 're': 'regex', | |
65 | + 'nr': '-regex', | |
66 | + #'se': 'surely', | |
67 | + #'sd': '-maybe', | |
68 | + #'me': 'maybe', | |
69 | + #'md': '-surely', | |
70 | + 'le': 'lte', | |
71 | + 'ge': 'gte', | |
72 | + } | |
71 | 73 | |
72 | - @staticmethod | |
73 | - def filter_special_case(filter, lookup, negated, queryset): | |
74 | - return False, filter['field'], queryset | |
74 | + @staticmethod | |
75 | + def filter_special_case(filter, lookup, negated, queryset): | |
76 | + return False, filter['field'], queryset | |
75 | 77 | |
76 | - @classmethod | |
77 | - def apply_filter(cls, queryset, filter): | |
78 | - lookup = cls.lookup_translation[filter['op']] | |
79 | - negated = (lookup[0] == '-') | |
80 | - lookup = lookup.lstrip('-') | |
81 | - data = filter['data'] | |
82 | - special, field, queryset = cls.filter_special_case( | |
83 | - filter, lookup, negated, queryset) | |
84 | - if not special: | |
85 | - arg = {(field + '__' + lookup): data} | |
86 | - if negated: | |
87 | - queryset = queryset.exclude(**arg) | |
88 | - else: | |
89 | - queryset = queryset.filter(**arg).distinct() | |
90 | - return queryset | |
78 | + @classmethod | |
79 | + def apply_filter(cls, queryset, filter): | |
80 | + lookup = cls.lookup_translation[filter['op']] | |
81 | + negated = (lookup[0] == '-') | |
82 | + lookup = lookup.lstrip('-') | |
83 | + data = filter['data'] | |
84 | + special, field, queryset = cls.filter_special_case( | |
85 | + filter, lookup, negated, queryset) | |
86 | + if not special: | |
87 | + arg = {(field + '__' + lookup): data} | |
88 | + if negated: | |
89 | + queryset = queryset.exclude(**arg) | |
90 | + else: | |
91 | + queryset = queryset.filter(**arg).distinct() | |
92 | + return queryset | |
91 | 93 | |
92 | - @classmethod | |
93 | - def get_queryset(cls, query): | |
94 | - return cls.model.objects.all() | |
94 | + @classmethod | |
95 | + def get_queryset(cls, query): | |
96 | + return cls.model.objects.all() | |
95 | 97 | |
96 | - @classmethod | |
97 | - def get_empty_queryset(cls): | |
98 | - return cls.model.objects.none() | |
98 | + @classmethod | |
99 | + def get_empty_queryset(cls): | |
100 | + return cls.model.objects.none() | |
99 | 101 | |
100 | - @classmethod | |
101 | - def apply_filters(cls, query): | |
102 | - filters = query.filters | |
103 | - queryset = cls.get_queryset(query) | |
104 | - if filters: | |
105 | - if filters['groupOp'] == 'AND': | |
106 | - for filter in filters['rules']: | |
107 | - queryset = cls.apply_filter(queryset, filter) | |
108 | - elif filters['groupOp'] == 'OR': | |
109 | - new_queryset = cls.get_empty_queryset() | |
110 | - for filter in filters['rules']: | |
111 | - new_queryset |= cls.apply_filter(queryset, filter) | |
112 | - queryset = new_queryset | |
113 | - return queryset | |
102 | + @classmethod | |
103 | + def apply_filters(cls, query): | |
104 | + filters = query.filters | |
105 | + queryset = cls.get_queryset(query) | |
106 | + if filters: | |
107 | + if filters['groupOp'] == 'AND': | |
108 | + for filter in filters['rules']: | |
109 | + queryset = cls.apply_filter(queryset, filter) | |
110 | + elif filters['groupOp'] == 'OR': | |
111 | + new_queryset = cls.get_empty_queryset() | |
112 | + for filter in filters['rules']: | |
113 | + new_queryset |= cls.apply_filter(queryset, filter) | |
114 | + queryset = new_queryset | |
115 | + return queryset | |
114 | 116 | |
115 | - @staticmethod | |
116 | - def apply_mask(queryset, mask, sort_rules): | |
117 | - pass # abstract | |
117 | + @staticmethod | |
118 | + def apply_mask(queryset, mask, sort_rules): | |
119 | + pass # abstract | |
118 | 120 | |
119 | - @staticmethod | |
120 | - def filter_value_special_case(queryset, rule, from_value, upward): | |
121 | - return False, queryset | |
121 | + @staticmethod | |
122 | + def filter_value_special_case(queryset, rule, from_value, upward): | |
123 | + return False, queryset | |
122 | 124 | |
123 | - # filtruje queryset według pola z reguły rule od wartości from, | |
124 | - # wartości dalsze w porządku jeśli upward, w przeciwnym razie bliższe | |
125 | - @classmethod | |
126 | - def filter_value(cls, queryset, rule, from_value, upward): | |
127 | - greater = (rule['order'] == 'asc') == upward | |
128 | - special, queryset = cls.filter_value_special_case( | |
129 | - queryset, rule, from_value, upward) | |
130 | - if special: | |
131 | - return queryset | |
132 | - if greater: | |
133 | - lookup = '__gte' | |
134 | - else: | |
135 | - lookup = '__lte' | |
136 | - field = cls.translate_field(rule['field']) | |
137 | - return queryset.filter(**{field + lookup: from_value}) | |
125 | + # filtruje queryset według pola z reguły rule od wartości from, | |
126 | + # wartości dalsze w porządku jeśli upward, w przeciwnym razie bliższe | |
127 | + @classmethod | |
128 | + def filter_value(cls, queryset, rule, from_value, upward): | |
129 | + greater = (rule['order'] == 'asc') == upward | |
130 | + special, queryset = cls.filter_value_special_case( | |
131 | + queryset, rule, from_value, upward) | |
132 | + if special: | |
133 | + return queryset | |
134 | + if greater: | |
135 | + lookup = '__gte' | |
136 | + else: | |
137 | + lookup = '__lte' | |
138 | + field = cls.translate_field(rule['field']) | |
139 | + return queryset.filter(**{field + lookup: from_value}) | |
138 | 140 | |
139 | - # id instancji z search_field rownym mask badz takiej, ktora bylaby nastepna | |
140 | - # po instancji z search_field równym mask w danym sortowaniu. | |
141 | - # Jezeli nie ma 'wiekszej' instancji badz reguly sortowania nie uwzgledniaja | |
142 | - # search_field, metoda zwroci pierwsza instancje w danym sortowaniu | |
143 | - # | |
144 | - # beznadziejna nazwa metody... | |
145 | - @classmethod | |
146 | - def get_pk(cls, query): | |
147 | - whole_queryset = cls.apply_filters(query) | |
148 | - queryset = whole_queryset | |
149 | - matching = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
150 | - if matching.count() > 0: | |
151 | - matching = cls.sort_queryset(matching, query.sort_rules) | |
152 | - return matching[0].pk | |
153 | - else: | |
154 | - #gdy nie ma pasującego | |
155 | - rule = query.sort_rules[0] | |
156 | - if rule['field'] == cls.search_field: | |
157 | - queryset = cls.filter_value( | |
158 | - queryset, rule, from_value=query.mask, upward=True) | |
159 | - if queryset.count() == 0: | |
160 | - queryset = whole_queryset | |
161 | - queryset = cls.sort_queryset(queryset, query.sort_rules) | |
162 | - return queryset[0].pk | |
141 | + # id instancji z search_field rownym mask badz takiej, ktora bylaby nastepna | |
142 | + # po instancji z search_field równym mask w danym sortowaniu. | |
143 | + # Jezeli nie ma 'wiekszej' instancji badz reguly sortowania nie uwzgledniaja | |
144 | + # search_field, metoda zwroci pierwsza instancje w danym sortowaniu | |
145 | + # | |
146 | + # beznadziejna nazwa metody... | |
147 | + @classmethod | |
148 | + def get_pk(cls, query): | |
149 | + whole_queryset = cls.apply_filters(query) | |
150 | + queryset = whole_queryset | |
151 | + matching = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
152 | + if matching.count() > 0: | |
153 | + matching = cls.sort_queryset(matching, query.sort_rules) | |
154 | + return matching[0].pk | |
155 | + else: | |
156 | + #gdy nie ma pasującego | |
157 | + rule = query.sort_rules[0] | |
158 | + if rule['field'] == cls.search_field: | |
159 | + queryset = cls.filter_value( | |
160 | + queryset, rule, from_value=query.mask, upward=True) | |
161 | + if queryset.count() == 0: | |
162 | + queryset = whole_queryset | |
163 | + queryset = cls.sort_queryset(queryset, query.sort_rules) | |
164 | + return queryset[0].pk | |
163 | 165 | |
164 | - @staticmethod | |
165 | - def get_field_special_case(field, instance): | |
166 | - return False, None | |
166 | + @staticmethod | |
167 | + def get_field_special_case(field, instance): | |
168 | + return False, None | |
167 | 169 | |
168 | - @classmethod | |
169 | - def get_field(cls, field, instance): | |
170 | - special, value = cls.get_field_special_case(field, instance) | |
171 | - if not special: | |
172 | - value = getattr(instance, field) | |
173 | - return cls.translate_field(field), value | |
170 | + @classmethod | |
171 | + def get_field(cls, field, instance): | |
172 | + special, value = cls.get_field_special_case(field, instance) | |
173 | + if not special: | |
174 | + value = getattr(instance, field) | |
175 | + return cls.translate_field(field), value | |
174 | 176 | |
175 | - # indeks wiersza w danym sortowaniu, w którym | |
176 | - # znajdzie się instancja o danym id | |
177 | - @classmethod | |
178 | - def row_index(cls, pk, query): | |
179 | - selected = cls.model.objects.get(pk=pk) | |
180 | - queryset = cls.apply_filters(query) | |
181 | - if query.filtering_mode(): | |
182 | - queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
183 | - count = queryset.count() | |
184 | - if count == 0: | |
185 | - return 0, 0 | |
186 | - preceding = None | |
187 | - assert len(query.sort_rules) > 0 | |
188 | - for rule in query.sort_rules: | |
189 | - field = rule['field'] | |
190 | - field, data = cls.get_field(field, selected) | |
191 | - preceding = cls.filter_value( | |
192 | - queryset, rule, from_value=data, upward=False) | |
193 | - return preceding.count(), count | |
177 | + # indeks wiersza w danym sortowaniu, w którym | |
178 | + # znajdzie się instancja o danym id | |
179 | + @classmethod | |
180 | + def row_index(cls, pk, query): | |
181 | + selected = cls.model.objects.get(pk=pk) | |
182 | + queryset = cls.apply_filters(query) | |
183 | + if query.filtering_mode(): | |
184 | + queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
185 | + count = queryset.count() | |
186 | + if count == 0: | |
187 | + return 0, 0 | |
188 | + preceding = None | |
189 | + assert len(query.sort_rules) > 0 | |
190 | + for rule in query.sort_rules: | |
191 | + field = rule['field'] | |
192 | + field, data = cls.get_field(field, selected) | |
193 | + preceding = cls.filter_value( | |
194 | + queryset, rule, from_value=data, upward=False) | |
195 | + return preceding.count(), count | |
194 | 196 | |
195 | - # też beznadziejna nazwa | |
196 | - @classmethod | |
197 | - def find_id(cls, selected_pk, query): | |
198 | - index, count = cls.row_index(selected_pk, query) | |
199 | - return { | |
200 | - 'rowIndex': index, | |
201 | - 'records': count, | |
202 | - } | |
197 | + # też beznadziejna nazwa | |
198 | + @classmethod | |
199 | + def find_id(cls, selected_pk, query): | |
200 | + index, count = cls.row_index(selected_pk, query) | |
201 | + return { | |
202 | + 'rowIndex': index, | |
203 | + 'records': count, | |
204 | + } | |
203 | 205 | |
204 | - @classmethod | |
205 | - def get_location(cls, query): | |
206 | - queryset = cls.apply_filters(query) | |
207 | - count = queryset.count() | |
208 | - # nie wiem, czy ma sens - wzorów i tak jest mało, a leksemy są keszowane | |
209 | - if count > 0 and query.mask == '': | |
210 | - return { | |
211 | - 'rowIndex': 0, | |
212 | - 'selected_id': queryset[0].pk, | |
213 | - 'records': count, | |
214 | - } | |
215 | - if query.filtering_mode(): | |
216 | - queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
217 | - if queryset.count() > 0: | |
218 | - selected_pk = cls.get_pk(query) | |
219 | - index, _count = cls.row_index(selected_pk, query) | |
220 | - else: | |
221 | - index = None | |
222 | - selected_pk = None | |
223 | - return { | |
224 | - 'rowIndex': index, | |
225 | - 'selected_id': selected_pk, | |
226 | - 'records': count, | |
227 | - } | |
206 | + @classmethod | |
207 | + def get_location(cls, query): | |
208 | + queryset = cls.apply_filters(query) | |
209 | + count = queryset.count() | |
210 | + # nie wiem, czy ma sens - wzorów i tak jest mało, a leksemy są keszowane | |
211 | + if count > 0 and query.mask == '': | |
212 | + return { | |
213 | + 'rowIndex': 0, | |
214 | + 'selected_id': queryset[0].pk, | |
215 | + 'records': count, | |
216 | + } | |
217 | + if query.filtering_mode(): | |
218 | + queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
219 | + if queryset.count() > 0: | |
220 | + selected_pk = cls.get_pk(query) | |
221 | + index, _count = cls.row_index(selected_pk, query) | |
222 | + else: | |
223 | + index = None | |
224 | + selected_pk = None | |
225 | + return { | |
226 | + 'rowIndex': index, | |
227 | + 'selected_id': selected_pk, | |
228 | + 'records': count, | |
229 | + } | |
228 | 230 | |
229 | - @classmethod | |
230 | - def get_sorted_queryset(cls, query): | |
231 | - queryset = cls.apply_filters(query) | |
232 | - if query.filtering_mode(): | |
233 | - queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
234 | - return cls.sort_queryset(queryset, query.sort_rules) | |
231 | + @classmethod | |
232 | + def get_sorted_queryset(cls, query): | |
233 | + queryset = cls.apply_filters(query) | |
234 | + if query.filtering_mode(): | |
235 | + queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) | |
236 | + return cls.sort_queryset(queryset, query.sort_rules) | |
235 | 237 | |
236 | - @staticmethod | |
237 | - def count_pages(count, page, limit): | |
238 | - total_pages = int(math.ceil(float(count) / limit)) | |
239 | - if limit < 0: | |
240 | - limit = 0 | |
241 | - page = min(page, total_pages) | |
242 | - start = limit * (page - 1) | |
243 | - start = max(start, 0) | |
244 | - response_rowcount = min(limit, count - start) | |
245 | - return total_pages, start, response_rowcount | |
238 | + @staticmethod | |
239 | + def count_pages(count, page, limit): | |
240 | + total_pages = int(math.ceil(float(count) / limit)) | |
241 | + if limit < 0: | |
242 | + limit = 0 | |
243 | + page = min(page, total_pages) | |
244 | + start = limit * (page - 1) | |
245 | + start = max(start, 0) | |
246 | + response_rowcount = min(limit, count - start) | |
247 | + return total_pages, start, response_rowcount | |
246 | 248 | |
247 | - @staticmethod | |
248 | - def response_row(instance): | |
249 | - pass # abstract | |
249 | + @staticmethod | |
250 | + def response_row(instance): | |
251 | + pass # abstract | |
250 | 252 | |
251 | - @classmethod | |
252 | - def make_response(cls, response_qs, count, page, total_pages): | |
253 | - rows = [{ | |
254 | - 'id': instance.pk, | |
255 | - 'cell': cls.response_row(instance), | |
256 | - } for instance in response_qs] | |
257 | - return { | |
258 | - 'page': page, | |
259 | - 'total': total_pages, | |
260 | - 'records': count, | |
261 | - 'rows': rows, | |
262 | - } | |
253 | + @classmethod | |
254 | + def make_response(cls, response_qs, count, page, total_pages): | |
255 | + rows = [{ | |
256 | + 'id': instance.pk, | |
257 | + 'cell': cls.response_row(instance), | |
258 | + } for instance in response_qs] | |
259 | + return { | |
260 | + 'page': page, | |
261 | + 'total': total_pages, | |
262 | + 'records': count, | |
263 | + 'rows': rows, | |
264 | + } | |
263 | 265 | |
264 | - @classmethod | |
265 | - def get_page(cls, page, limit, query): | |
266 | - queryset = cls.get_sorted_queryset(query) | |
267 | - count = queryset.count() | |
268 | - total_pages, start, response_rowcount = cls.count_pages(count, page, limit) | |
269 | - response_qs = queryset[start:start + response_rowcount] | |
270 | - return cls.make_response(response_qs, count, page, total_pages) | |
271 | 266 | \ No newline at end of file |
267 | + @classmethod | |
268 | + def get_page(cls, page, limit, query): | |
269 | + queryset = cls.get_sorted_queryset(query) | |
270 | + count = queryset.count() | |
271 | + total_pages, start, response_rowcount = cls.count_pages(count, page, | |
272 | + limit) | |
273 | + response_qs = queryset[start:start + response_rowcount] | |
274 | + return cls.make_response(response_qs, count, page, total_pages) | |
272 | 275 | \ No newline at end of file |
... | ... |
dictionary/ajax_lexeme_jqgrid.py
... | ... | @@ -2,60 +2,62 @@ |
2 | 2 | from hashlib import md5 |
3 | 3 | |
4 | 4 | from django.db.models import Count |
5 | +from django.core.cache import cache | |
6 | + | |
5 | 7 | from dictionary.models import Lexeme, filter_visible, visible_vocabularies, LexemeInflectionPattern, LexemeAssociation |
6 | 8 | from dictionary.ajax_jqgrid import JqGridAjax, JqGridQuery |
7 | 9 | from common.decorators import ajax |
8 | 10 | from common.util import bisect_left, reverse, GroupDict, json_encode |
9 | -from django.core.cache import cache | |
10 | - | |
11 | -class LexemeGrid(JqGridAjax): | |
12 | - model = Lexeme | |
13 | - search_field = 'entry' | |
14 | - field_translation = { | |
15 | - 'part_of_speech': 'part_of_speech__symbol', | |
16 | - } | |
17 | - | |
18 | - @staticmethod | |
19 | - def sort_field_special_case(rule): | |
20 | - if rule['field'] == 'entry' and rule['a_tergo']: | |
21 | - return 'rev' | |
22 | - else: | |
23 | - return rule['field'] | |
24 | 11 | |
25 | - @staticmethod | |
26 | - def sort_queryset_special_case(queryset, rule): | |
27 | - if rule['field'] == 'entry' and rule['a_tergo']: | |
28 | - return queryset.extra(select={'rev': "reverse(haslo)"}) | |
29 | - else: | |
30 | - return queryset | |
31 | 12 | |
32 | - @staticmethod | |
33 | - def filter_special_case(filter, lookup, negated, queryset): | |
34 | - field, data = filter['field'], filter['data'] | |
35 | - special = False | |
13 | +class LexemeGrid(JqGridAjax): | |
14 | + model = Lexeme | |
15 | + search_field = 'entry' | |
36 | 16 | field_translation = { |
37 | - 'form': 'lexemeform__form', | |
38 | - 'lexeme_qualifier': 'qualifiers__pk', | |
39 | - 'lip_qualifier': 'lexemeinflectionpattern__qualifiers__pk', | |
40 | - 'classification_value': 'classificationvalue__pk', | |
41 | - 'pattern_name': 'lexemeinflectionpattern__pattern__name', | |
42 | - 'inflection_characteristic': | |
43 | - 'lexemeinflectionpattern__inflection_characteristic__symbol', | |
44 | - 'containing_vocabulary': 'vocabularies__pk', | |
45 | - 'owner_vocabulary': 'owner_vocabulary__pk', | |
46 | - 'pattern_count': 'pc', | |
47 | - 'ic_count': 'icc', | |
48 | - 'cr_type': 'refs_to__type__pk', | |
17 | + 'part_of_speech': 'part_of_speech__symbol', | |
49 | 18 | } |
50 | - if field == 'pattern_count': | |
51 | - queryset = queryset.annotate( | |
52 | - pc=Count('lexemeinflectionpattern__pattern', distinct=True)) | |
53 | - elif field == 'ic_count': | |
54 | - queryset = queryset.annotate( | |
55 | - icc=Count('lexemeinflectionpattern__inflection_characteristic', | |
56 | - distinct=True)) | |
57 | - elif field == 'qualifier': | |
58 | - where = '''( | |
19 | + | |
20 | + @staticmethod | |
21 | + def sort_field_special_case(rule): | |
22 | + if rule['field'] == 'entry' and rule['a_tergo']: | |
23 | + return 'rev' | |
24 | + else: | |
25 | + return rule['field'] | |
26 | + | |
27 | + @staticmethod | |
28 | + def sort_queryset_special_case(queryset, rule): | |
29 | + if rule['field'] == 'entry' and rule['a_tergo']: | |
30 | + return queryset.extra(select={'rev': "reverse(haslo)"}) | |
31 | + else: | |
32 | + return queryset | |
33 | + | |
34 | + @staticmethod | |
35 | + def filter_special_case(filter, lookup, negated, queryset): | |
36 | + field, data = filter['field'], filter['data'] | |
37 | + special = False | |
38 | + field_translation = { | |
39 | + 'form': 'lexemeform__form', | |
40 | + 'lexeme_qualifier': 'qualifiers__pk', | |
41 | + 'lip_qualifier': 'lexemeinflectionpattern__qualifiers__pk', | |
42 | + 'classification_value': 'classificationvalue__pk', | |
43 | + 'pattern_name': 'lexemeinflectionpattern__pattern__name', | |
44 | + 'inflection_characteristic': | |
45 | + 'lexemeinflectionpattern__inflection_characteristic__symbol', | |
46 | + 'containing_vocabulary': 'vocabularies__pk', | |
47 | + 'owner_vocabulary': 'owner_vocabulary__pk', | |
48 | + 'pattern_count': 'pc', | |
49 | + 'ic_count': 'icc', | |
50 | + 'cr_type': 'refs_to__type__pk', | |
51 | + } | |
52 | + if field == 'pattern_count': | |
53 | + queryset = queryset.annotate( | |
54 | + pc=Count('lexemeinflectionpattern__pattern', distinct=True)) | |
55 | + elif field == 'ic_count': | |
56 | + queryset = queryset.annotate( | |
57 | + icc=Count('lexemeinflectionpattern__inflection_characteristic', | |
58 | + distinct=True)) | |
59 | + elif field == 'qualifier': | |
60 | + where = '''( | |
59 | 61 | exists ( |
60 | 62 | select * from kwalifikatory_leksemow where lexeme_id = leksemy.id and |
61 | 63 | qualifier_id = %s) or |
... | ... | @@ -75,200 +77,209 @@ class LexemeGrid(JqGridAjax): |
75 | 77 | where o.l_id = leksemy.id and s.wariant = '1' and |
76 | 78 | kz.qualifier_id = %s) |
77 | 79 | )''' |
78 | - if negated: | |
79 | - where = 'not ' + where | |
80 | - queryset = queryset.extra(where=[where], params=[data] * 3) | |
81 | - special = True | |
82 | - return special, field_translation.get(field, field), queryset | |
83 | - | |
84 | - @classmethod | |
85 | - def get_queryset(cls, query): | |
86 | - lexemes = super(LexemeGrid, cls).get_queryset(query) | |
87 | - return filter_visible(lexemes, query.user) | |
88 | - | |
89 | - @staticmethod | |
90 | - def apply_mask(lexemes, mask, sort_rules): | |
91 | - if mask == '': | |
92 | - return lexemes | |
93 | - for rule in sort_rules: | |
94 | - if rule['field'] == 'entry': | |
95 | - if not rule['a_tergo']: | |
96 | - matching_lexemes = lexemes.filter(entry__istartswith=mask) | |
80 | + if negated: | |
81 | + where = 'not ' + where | |
82 | + queryset = queryset.extra(where=[where], params=[data] * 3) | |
83 | + special = True | |
84 | + return special, field_translation.get(field, field), queryset | |
85 | + | |
86 | + @classmethod | |
87 | + def get_queryset(cls, query): | |
88 | + lexemes = super(LexemeGrid, cls).get_queryset(query) | |
89 | + return filter_visible(lexemes, query.user) | |
90 | + | |
91 | + @staticmethod | |
92 | + def apply_mask(lexemes, mask, sort_rules): | |
93 | + if mask == '': | |
94 | + return lexemes | |
95 | + for rule in sort_rules: | |
96 | + if rule['field'] == 'entry': | |
97 | + if not rule['a_tergo']: | |
98 | + matching_lexemes = lexemes.filter(entry__istartswith=mask) | |
99 | + else: | |
100 | + matching_lexemes = lexemes.filter(entry__iendswith=mask) | |
101 | + break | |
97 | 102 | else: |
98 | - matching_lexemes = lexemes.filter(entry__iendswith=mask) | |
99 | - break | |
100 | - else: | |
101 | - matching_lexemes = lexemes.filter(entry__istartswith=mask) | |
102 | - return matching_lexemes | |
103 | - | |
104 | - @staticmethod | |
105 | - def filter_value_special_case(queryset, rule, from_value, greater): | |
106 | - if rule['field'] == 'entry' and rule['a_tergo']: | |
107 | - if greater: | |
108 | - comp = '>=' | |
109 | - else: | |
110 | - comp = '<=' | |
111 | - queryset = queryset.extra(where=["reverse(haslo) " + comp + " %s"], | |
112 | - params=[reverse(from_value)]) | |
113 | - return True, queryset | |
114 | - else: | |
115 | - return False, queryset | |
103 | + matching_lexemes = lexemes.filter(entry__istartswith=mask) | |
104 | + return matching_lexemes | |
105 | + | |
106 | + @staticmethod | |
107 | + def filter_value_special_case(queryset, rule, from_value, greater): | |
108 | + if rule['field'] == 'entry' and rule['a_tergo']: | |
109 | + if greater: | |
110 | + comp = '>=' | |
111 | + else: | |
112 | + comp = '<=' | |
113 | + queryset = queryset.extra(where=["reverse(haslo) " + comp + " %s"], | |
114 | + params=[reverse(from_value)]) | |
115 | + return True, queryset | |
116 | + else: | |
117 | + return False, queryset | |
118 | + | |
119 | + @staticmethod | |
120 | + def get_field_special_case(field, lexeme): | |
121 | + if field == 'part_of_speech': | |
122 | + return True, lexeme.part_of_speech.symbol | |
123 | + else: | |
124 | + return False, None | |
125 | + | |
126 | + @staticmethod | |
127 | + def response_row(lexeme): | |
128 | + lip_data = lexeme.lip_data() | |
129 | + cont_vocabs = '/'.join(v.id for v in lexeme.vocabularies.all()) | |
130 | + return [ | |
131 | + lexeme.id, | |
132 | + lexeme.entry, | |
133 | + lexeme.part_of_speech.symbol, | |
134 | + lip_data['patterns'], | |
135 | + '', # brak liczby wzorów | |
136 | + lip_data['inflection_characteristics'], | |
137 | + '', # brak liczby charfli | |
138 | + '', # brak formy | |
139 | + cont_vocabs, | |
140 | + lexeme.owner_vocabulary.id, | |
141 | + dict(Lexeme.STATUS_CHOICES).get(lexeme.status), | |
142 | + '', # brak komentarza | |
143 | + ] | |
144 | + | |
145 | + # indeks wiersza w danym sortowaniu, w którym | |
146 | + # znajdzie się instancja o danym id | |
147 | + @classmethod | |
148 | + def row_index(cls, pk, query): | |
149 | + pk_list = get_pk_list(query) | |
150 | + count = len(pk_list) | |
151 | + if count == 0: | |
152 | + return 0, 0 | |
153 | + return pk_list.index(pk), count | |
154 | + | |
155 | + # id instancji z search_field rownym mask badz takiej, ktora bylaby nastepna | |
156 | + # po instancji z search_field równym mask w danym sortowaniu. | |
157 | + # Jezeli nie ma 'wiekszej' instancji badz reguly sortowania nie uwzgledniaja | |
158 | + # search_field, metoda zwroci pierwsza instancje w danym sortowaniu | |
159 | + @classmethod | |
160 | + def get_pk(cls, query): | |
161 | + pk_list = get_pk_list(query) | |
162 | + count = len(pk_list) | |
163 | + if count == 0: | |
164 | + return None, None, 0 | |
165 | + # nie podoba mi się w ogóle cała ta idea | |
166 | + sort_rules = query.sort_rules | |
167 | + assert len(sort_rules) >= 0 | |
168 | + if sort_rules[0]['field'] != cls.search_field: | |
169 | + selected_pk = super(cls, LexemeGrid).get_pk(query) | |
170 | + index, count = cls.row_index(selected_pk, query) | |
171 | + return selected_pk, index, count | |
172 | + | |
173 | + index = bisect_left(pk_list, query.mask, | |
174 | + cmp=make_lexeme_cmp(sort_rules[0])) | |
175 | + if index == count: | |
176 | + index -= 1 | |
177 | + return pk_list[index], index, count | |
178 | + | |
179 | + @classmethod | |
180 | + def get_location(cls, query): | |
181 | + selected_pk, index, count = cls.get_pk(query) | |
182 | + return { | |
183 | + 'rowIndex': index, | |
184 | + 'selected_id': selected_pk, | |
185 | + 'records': count, | |
186 | + } | |
116 | 187 | |
117 | - @staticmethod | |
118 | - def get_field_special_case(field, lexeme): | |
119 | - if field == 'part_of_speech': | |
120 | - return True, lexeme.part_of_speech.symbol | |
121 | - else: | |
122 | - return False, None | |
123 | - | |
124 | - @staticmethod | |
125 | - def response_row(lexeme): | |
126 | - lip_data = lexeme.lip_data() | |
127 | - cont_vocabs = '/'.join(v.id for v in lexeme.vocabularies.all()) | |
128 | - return [ | |
129 | - lexeme.id, | |
130 | - lexeme.entry, | |
131 | - lexeme.part_of_speech.symbol, | |
132 | - lip_data['patterns'], | |
133 | - '', # brak liczby wzorów | |
134 | - lip_data['inflection_characteristics'], | |
135 | - '', # brak liczby charfli | |
136 | - '', # brak formy | |
137 | - cont_vocabs, | |
138 | - lexeme.owner_vocabulary.id, | |
139 | - dict(Lexeme.STATUS_CHOICES).get(lexeme.status), | |
140 | - '', # brak komentarza | |
141 | - ] | |
142 | - | |
143 | - # indeks wiersza w danym sortowaniu, w którym | |
144 | - # znajdzie się instancja o danym id | |
145 | - @classmethod | |
146 | - def row_index(cls, pk, query): | |
147 | - pk_list = get_pk_list(query) | |
148 | - count = len(pk_list) | |
149 | - if count == 0: | |
150 | - return 0, 0 | |
151 | - return pk_list.index(pk), count | |
152 | - | |
153 | - # id instancji z search_field rownym mask badz takiej, ktora bylaby nastepna | |
154 | - # po instancji z search_field równym mask w danym sortowaniu. | |
155 | - # Jezeli nie ma 'wiekszej' instancji badz reguly sortowania nie uwzgledniaja | |
156 | - # search_field, metoda zwroci pierwsza instancje w danym sortowaniu | |
157 | - @classmethod | |
158 | - def get_pk(cls, query): | |
159 | - pk_list = get_pk_list(query) | |
160 | - count = len(pk_list) | |
161 | - if count == 0: | |
162 | - return None, None, 0 | |
163 | - # nie podoba mi się w ogóle cała ta idea | |
164 | - sort_rules = query.sort_rules | |
165 | - assert len(sort_rules) >= 0 | |
166 | - if sort_rules[0]['field'] != cls.search_field: | |
167 | - selected_pk = super(cls, LexemeGrid).get_pk(query) | |
168 | - index, count = cls.row_index(selected_pk, query) | |
169 | - return selected_pk, index, count | |
170 | - | |
171 | - index = bisect_left(pk_list, query.mask, cmp=make_lexeme_cmp(sort_rules[0])) | |
172 | - if index == count: | |
173 | - index -= 1 | |
174 | - return pk_list[index], index, count | |
175 | - | |
176 | - @classmethod | |
177 | - def get_location(cls, query): | |
178 | - selected_pk, index, count = cls.get_pk(query) | |
179 | - return { | |
180 | - 'rowIndex': index, | |
181 | - 'selected_id': selected_pk, | |
182 | - 'records': count, | |
183 | - } | |
184 | 188 | |
185 | 189 | import locale |
190 | + | |
186 | 191 | locale.setlocale(locale.LC_ALL, 'pl_PL.UTF-8') |
187 | 192 | |
193 | + | |
188 | 194 | def make_lexeme_cmp(rule): |
189 | - def lexeme_cmp(pk, mask): | |
190 | - e1 = Lexeme.objects.get(pk=pk).entry | |
191 | - e2 = mask | |
192 | - if rule['a_tergo']: | |
193 | - e1 = reverse(e1) | |
194 | - e2 = reverse(e2) | |
195 | - result = locale.strcoll(e1, e2) | |
196 | - if rule['order'] == 'desc' and e2 != '': | |
197 | - result = -result | |
198 | - return result | |
199 | - return lexeme_cmp | |
195 | + def lexeme_cmp(pk, mask): | |
196 | + e1 = Lexeme.objects.get(pk=pk).entry | |
197 | + e2 = mask | |
198 | + if rule['a_tergo']: | |
199 | + e1 = reverse(e1) | |
200 | + e2 = reverse(e2) | |
201 | + result = locale.strcoll(e1, e2) | |
202 | + if rule['order'] == 'desc' and e2 != '': | |
203 | + result = -result | |
204 | + return result | |
205 | + | |
206 | + return lexeme_cmp | |
200 | 207 | |
201 | 208 | # Zapytanie o indeks wiersza o pewnym id przy danym sortowaniu |
202 | 209 | @ajax(method='get') |
203 | 210 | def find_id(request, id, sort_rules, mask, filters=None): |
204 | - query = JqGridQuery( | |
205 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
206 | - return LexemeGrid.find_id(id, query) | |
211 | + query = JqGridQuery( | |
212 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
213 | + return LexemeGrid.find_id(id, query) | |
207 | 214 | |
208 | 215 | # Zapytanie o id oraz indeks pierwszego wiersza przy danym sortowaniu, |
209 | 216 | # którego hasło rozpoczyna się od mask. |
210 | 217 | # 'selected_id' == None, jeśli takiego nie ma |
211 | 218 | @ajax(method='get') |
212 | 219 | def get_location(request, sort_rules, mask='', filters=None): |
213 | - query = JqGridQuery( | |
214 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
215 | - return LexemeGrid.get_location(query) | |
220 | + query = JqGridQuery( | |
221 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
222 | + return LexemeGrid.get_location(query) | |
216 | 223 | |
217 | 224 | # twór Miłosza - trzeba kiedyś poprawić |
218 | 225 | def cache_key(query): |
219 | - key = json_encode(query.sort_rules) + json_encode(query.filters) | |
220 | - for vocabulary in visible_vocabularies(query.user): | |
221 | - key += vocabulary.id | |
222 | - if query.filtering_mode(): | |
223 | - key += query.mask | |
224 | - return md5(key).hexdigest() | |
226 | + key = json_encode(query.sort_rules) + json_encode(query.filters) | |
227 | + for vocabulary in visible_vocabularies(query.user): | |
228 | + key += vocabulary.id | |
229 | + if query.filtering_mode(): | |
230 | + key += query.mask | |
231 | + return md5(key).hexdigest() | |
232 | + | |
225 | 233 | |
226 | 234 | def get_cached_lexemes(query): |
227 | - key = cache_key(query) | |
228 | - return cache.get(key) | |
235 | + key = cache_key(query) | |
236 | + return cache.get(key) | |
237 | + | |
229 | 238 | |
230 | 239 | def cache_lexemes(pk_list, query): |
231 | - key = cache_key(query) | |
232 | - cache.set(key, pk_list) | |
233 | - key_list = cache.get('key_list', []) | |
234 | - if key not in key_list: | |
235 | - key_list.append(key) | |
236 | - cache.set('key_list', key_list) | |
240 | + key = cache_key(query) | |
241 | + cache.set(key, pk_list) | |
242 | + key_list = cache.get('key_list', []) | |
243 | + if key not in key_list: | |
244 | + key_list.append(key) | |
245 | + cache.set('key_list', key_list) | |
246 | + | |
237 | 247 | |
238 | 248 | def get_pk_list(query, force_reload=False): |
239 | - if not force_reload: | |
240 | - pk_list = get_cached_lexemes(query) | |
241 | - else: | |
242 | - pk_list = None | |
243 | - if pk_list is None: | |
244 | - lexemes = LexemeGrid.get_sorted_queryset(query) | |
245 | - if 'rev' in lexemes.query.extra_select: | |
246 | - pk_list = list(row[0] for row in lexemes.values_list('pk', 'rev')) | |
249 | + if not force_reload: | |
250 | + pk_list = get_cached_lexemes(query) | |
247 | 251 | else: |
248 | - #print lexemes.values_list('pk', flat=True).query | |
249 | - pk_list = list(lexemes.values_list('pk', flat=True)) | |
250 | - cache_lexemes(pk_list, query) | |
251 | - return pk_list | |
252 | + pk_list = None | |
253 | + if pk_list is None: | |
254 | + lexemes = LexemeGrid.get_sorted_queryset(query) | |
255 | + if 'rev' in lexemes.query.extra_select: | |
256 | + pk_list = list(row[0] for row in lexemes.values_list('pk', 'rev')) | |
257 | + else: | |
258 | + #print lexemes.values_list('pk', flat=True).query | |
259 | + pk_list = list(lexemes.values_list('pk', flat=True)) | |
260 | + cache_lexemes(pk_list, query) | |
261 | + return pk_list | |
262 | + | |
252 | 263 | |
253 | 264 | @ajax(method='get') |
254 | 265 | def get_lexemes(request, page, rows, sort_rules, filters=None, mask='', |
255 | 266 | target_page=0, totalrows=0, force_reload=False): |
256 | - request.session['sort_rules'] = json_encode(sort_rules) | |
257 | - request.session['filters'] = json_encode(filters) | |
258 | - page = target_page or page | |
259 | - limit = totalrows or rows | |
260 | - query = JqGridQuery( | |
261 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
262 | - pk_list = get_pk_list(query, force_reload) | |
263 | - count = len(pk_list) | |
264 | - total_pages, start, response_rowcount = LexemeGrid.count_pages( | |
265 | - count, page, limit) | |
266 | - sublist = pk_list[start:start + response_rowcount] | |
267 | - lexemes_qs = Lexeme.objects.filter(pk__in=sublist).select_related( | |
268 | - 'owner_vocabulary', 'part_of_speech').prefetch_related( | |
269 | - 'lexemeinflectionpattern_set__pattern', | |
270 | - 'lexemeinflectionpattern_set__inflection_characteristic', | |
271 | - 'vocabularies') | |
272 | - lexemes_dict = dict((l.pk, l) for l in lexemes_qs) | |
273 | - lexemes = [lexemes_dict[pk] for pk in sublist] | |
274 | - return LexemeGrid.make_response(lexemes, count, page, total_pages) | |
267 | + request.session['sort_rules'] = json_encode(sort_rules) | |
268 | + request.session['filters'] = json_encode(filters) | |
269 | + page = target_page or page | |
270 | + limit = totalrows or rows | |
271 | + query = JqGridQuery( | |
272 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
273 | + pk_list = get_pk_list(query, force_reload) | |
274 | + count = len(pk_list) | |
275 | + total_pages, start, response_rowcount = LexemeGrid.count_pages( | |
276 | + count, page, limit) | |
277 | + sublist = pk_list[start:start + response_rowcount] | |
278 | + lexemes_qs = Lexeme.objects.filter(pk__in=sublist).select_related( | |
279 | + 'owner_vocabulary', 'part_of_speech').prefetch_related( | |
280 | + 'lexemeinflectionpattern_set__pattern', | |
281 | + 'lexemeinflectionpattern_set__inflection_characteristic', | |
282 | + 'vocabularies') | |
283 | + lexemes_dict = dict((l.pk, l) for l in lexemes_qs) | |
284 | + lexemes = [lexemes_dict[pk] for pk in sublist] | |
285 | + return LexemeGrid.make_response(lexemes, count, page, total_pages) | |
... | ... |
dictionary/ajax_lexeme_view.py
... | ... | @@ -7,552 +7,584 @@ from django.db.models import Max |
7 | 7 | from dictionary.ajax_jqgrid import JqGridQuery |
8 | 8 | from dictionary.ajax_lexeme_jqgrid import cache_key, get_pk_list |
9 | 9 | from dictionary.models import Lexeme, LexemeInflectionPattern, PartOfSpeech, \ |
10 | - Pattern, InflectionCharacteristic, Vocabulary, Qualifier, \ | |
11 | - prepare_table, ClassificationValue, CrossReference, TableTemplate, get_root, \ | |
12 | - InputLexeme, CrossReferenceType, filter_visible, \ | |
13 | - editable_vocabularies, visible_qualifiers, LexemeAttributeValue | |
10 | + Pattern, InflectionCharacteristic, Vocabulary, Qualifier, \ | |
11 | + prepare_table, ClassificationValue, CrossReference, TableTemplate, get_root, \ | |
12 | + InputLexeme, CrossReferenceType, filter_visible, \ | |
13 | + editable_vocabularies, visible_qualifiers, LexemeAttributeValue | |
14 | 14 | from dictionary.forms import LexemeEditForm, LIPEditForm, ClassificationForm, \ |
15 | - CrossReferenceForm, ActionFieldForm, ACTION_FIELDS, LexemeOpenAttributeForm, \ | |
16 | - LexemeClosedAttributeForm, LexemeMultipleAttributeForm | |
15 | + CrossReferenceForm, ActionFieldForm, ACTION_FIELDS, LexemeOpenAttributeForm, \ | |
16 | + LexemeClosedAttributeForm, LexemeMultipleAttributeForm | |
17 | 17 | from common.decorators import render, ajax, AjaxError, render_template |
18 | 18 | from common.util import error_messages |
19 | 19 | |
20 | + | |
20 | 21 | @ajax(method='get', template='inflection_tables.html') |
21 | 22 | def get_inflection_tables(request, variant, lexeme_id): |
22 | - lexeme = Lexeme.all_objects.get(pk=lexeme_id) # może być nowy | |
23 | - if not lexeme.perm(request.user, 'view'): | |
24 | - raise AjaxError('access denied') | |
25 | - qualifiers = visible_qualifiers(request.user) | |
26 | - tables = lexeme.inflection_tables(variant, qualifiers=qualifiers) | |
27 | - return { | |
28 | - 'tables': tables, | |
29 | - 'lexeme': lexeme, | |
30 | - 'cross_references': lexeme.refs_to.order_by('type__index'), | |
31 | - 'info': lexeme.sgjp_info(), | |
32 | - } | |
23 | + lexeme = Lexeme.all_objects.get(pk=lexeme_id) # może być nowy | |
24 | + if not lexeme.perm(request.user, 'view'): | |
25 | + raise AjaxError('access denied') | |
26 | + qualifiers = visible_qualifiers(request.user) | |
27 | + tables = lexeme.inflection_tables(variant, qualifiers=qualifiers) | |
28 | + return { | |
29 | + 'tables': tables, | |
30 | + 'lexeme': lexeme, | |
31 | + 'cross_references': lexeme.refs_to.order_by('type__index'), | |
32 | + 'info': lexeme.sgjp_info(), | |
33 | + } | |
34 | + | |
33 | 35 | |
34 | 36 | @ajax(method='get', template='inflection_table.html') |
35 | 37 | def table_preview(request, lexeme_id, pattern, inflection_characteristic, |
36 | 38 | lip_id, entry=None, pos=None): |
37 | - lexeme = Lexeme.all_objects.get(pk=lexeme_id) | |
38 | - if not lexeme.perm(request.user, 'view'): | |
39 | - raise AjaxError('access denied') | |
40 | - if entry is None: | |
41 | - entry = lexeme.entry | |
42 | - if pos is None: | |
43 | - pos = lexeme.part_of_speech.symbol | |
44 | - try: | |
45 | - pattern = Pattern.objects.get(name=pattern) | |
46 | - inflection_characteristic = InflectionCharacteristic.objects.get( | |
47 | - pk=inflection_characteristic) | |
48 | - if lip_id.startswith('lip_add'): | |
49 | - lip = LexemeInflectionPattern(lexeme=lexeme, index=0) | |
50 | - else: | |
51 | - lip = LexemeInflectionPattern.objects.get(pk=int(lip_id[3:])) | |
52 | - lip.pattern = pattern | |
53 | - lip.inflection_characteristic = inflection_characteristic | |
54 | - lip.root = get_root(entry, pos, pattern, inflection_characteristic) | |
55 | - qualifiers = visible_qualifiers(request.user) | |
56 | - table = lip.inflection_table('0', separated=True, qualifiers=qualifiers, | |
57 | - edit_view=True) | |
58 | - prepare_table(table) | |
59 | - except Pattern.DoesNotExist: | |
60 | - table = None | |
61 | - except TableTemplate.DoesNotExist: | |
62 | - table = None | |
63 | - return {'table': table} | |
39 | + lexeme = Lexeme.all_objects.get(pk=lexeme_id) | |
40 | + if not lexeme.perm(request.user, 'view'): | |
41 | + raise AjaxError('access denied') | |
42 | + if entry is None: | |
43 | + entry = lexeme.entry | |
44 | + if pos is None: | |
45 | + pos = lexeme.part_of_speech.symbol | |
46 | + try: | |
47 | + pattern = Pattern.objects.get(name=pattern) | |
48 | + inflection_characteristic = InflectionCharacteristic.objects.get( | |
49 | + pk=inflection_characteristic) | |
50 | + if lip_id.startswith('lip_add'): | |
51 | + lip = LexemeInflectionPattern(lexeme=lexeme, index=0) | |
52 | + else: | |
53 | + lip = LexemeInflectionPattern.objects.get(pk=int(lip_id[3:])) | |
54 | + lip.pattern = pattern | |
55 | + lip.inflection_characteristic = inflection_characteristic | |
56 | + lip.root = get_root(entry, pos, pattern, inflection_characteristic) | |
57 | + qualifiers = visible_qualifiers(request.user) | |
58 | + table = lip.inflection_table('0', separated=True, qualifiers=qualifiers, | |
59 | + edit_view=True) | |
60 | + prepare_table(table) | |
61 | + except Pattern.DoesNotExist: | |
62 | + table = None | |
63 | + except TableTemplate.DoesNotExist: | |
64 | + table = None | |
65 | + return {'table': table} | |
66 | + | |
64 | 67 | |
65 | 68 | @ajax(method='get', template="odm_forms.html") |
66 | 69 | def odm_forms(request, lexeme_id): |
67 | - to_return = {} | |
68 | - l = Lexeme.all_objects.get(pk=lexeme_id) | |
69 | - if not l.perm(request.user, 'view'): | |
70 | - raise AjaxError('access denied') | |
71 | - odm_lexemes = [] | |
72 | - for l in InputLexeme.objects.filter(entry=l.entry): | |
73 | - odm_lexemes.append(list(l.inputform_set.values_list('form', flat=True))) | |
74 | - to_return['odm_lexemes'] = odm_lexemes | |
75 | - return to_return | |
70 | + to_return = {} | |
71 | + l = Lexeme.all_objects.get(pk=lexeme_id) | |
72 | + if not l.perm(request.user, 'view'): | |
73 | + raise AjaxError('access denied') | |
74 | + odm_lexemes = [] | |
75 | + for l in InputLexeme.objects.filter(entry=l.entry): | |
76 | + odm_lexemes.append(list(l.inputform_set.values_list('form', flat=True))) | |
77 | + to_return['odm_lexemes'] = odm_lexemes | |
78 | + return to_return | |
79 | + | |
76 | 80 | |
77 | 81 | def attribute_forms(l, part_of_speech=None, ics=None): |
78 | - for attr, v in l.attributes_values(part_of_speech, ics): | |
79 | - if not attr.closed: | |
80 | - form_class = LexemeOpenAttributeForm | |
81 | - elif not attr.multiple: | |
82 | - form_class = LexemeClosedAttributeForm | |
83 | - else: | |
84 | - form_class = LexemeMultipleAttributeForm | |
85 | - prefix = 'attr%s' % attr.pk | |
86 | - yield form_class(attribute=attr, initial_value=v, prefix=prefix) | |
82 | + for attr, v in l.attributes_values(part_of_speech, ics): | |
83 | + if not attr.closed: | |
84 | + form_class = LexemeOpenAttributeForm | |
85 | + elif not attr.multiple: | |
86 | + form_class = LexemeClosedAttributeForm | |
87 | + else: | |
88 | + form_class = LexemeMultipleAttributeForm | |
89 | + prefix = 'attr%s' % attr.pk | |
90 | + yield form_class(attribute=attr, initial_value=v, prefix=prefix) | |
91 | + | |
87 | 92 | |
88 | 93 | @render_template('extra_attributes.html') |
89 | 94 | @ajax(method='get', template='extra_attributes.html') |
90 | 95 | def extra_attributes(request, lexeme_id, pos, ics): |
91 | - l = Lexeme.all_objects.get(pk=lexeme_id) | |
92 | - part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
93 | - ics = InflectionCharacteristic.objects.filter(pk__in=ics) | |
94 | - return { | |
95 | - 'forms': attribute_forms( | |
96 | - l, part_of_speech=part_of_speech, ics=ics), | |
97 | - } | |
96 | + l = Lexeme.all_objects.get(pk=lexeme_id) | |
97 | + part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
98 | + ics = InflectionCharacteristic.objects.filter(pk__in=ics) | |
99 | + return { | |
100 | + 'forms': attribute_forms( | |
101 | + l, part_of_speech=part_of_speech, ics=ics), | |
102 | + } | |
103 | + | |
98 | 104 | |
99 | 105 | @ajax(method='get') |
100 | 106 | def check_attributes(request, lexeme_id, pos, ics): |
101 | - l = Lexeme.all_objects.get(pk=lexeme_id) | |
102 | - part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
103 | - ics = InflectionCharacteristic.objects.filter( | |
104 | - part_of_speech=part_of_speech, symbol__in=ics) | |
105 | - attrs = list(l.attributes(part_of_speech, ics).values_list('pk', flat=True)) | |
106 | - return {'attrs': attrs} | |
107 | + l = Lexeme.all_objects.get(pk=lexeme_id) | |
108 | + part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
109 | + ics = InflectionCharacteristic.objects.filter( | |
110 | + part_of_speech=part_of_speech, symbol__in=ics) | |
111 | + attrs = list(l.attributes(part_of_speech, ics).values_list('pk', flat=True)) | |
112 | + return {'attrs': attrs} | |
113 | + | |
107 | 114 | |
108 | 115 | @render_template('lexeme_edit_form.html') |
109 | 116 | @ajax(method='get', template='lexeme_edit_form.html') |
110 | 117 | def lexeme_edit_form(request, id): |
111 | - to_return = {} | |
112 | - l = Lexeme.all_objects.get(pk=id) # bo może być świeżo utworzony | |
113 | - if not l.perm(request.user, 'view'): | |
114 | - raise AjaxError('access denied') | |
115 | - editable = l.perm(request.user, 'change') | |
116 | - to_return['editable'] = editable | |
117 | - owner = l.owner_vocabulary | |
118 | - | |
119 | - to_return['attribute_forms'] = attribute_forms(l) | |
120 | - | |
121 | - editable_vocabs = editable_vocabularies(request.user) | |
122 | - ro_owner = owner not in editable_vocabs | |
123 | - to_return['multiple_editable'] = editable and editable_vocabs.count() > 1 | |
124 | - if ro_owner: | |
125 | - # nie pokazujemy wszystkich, tylko te z właściciela | |
126 | - ro_qualifiers = l.qualifiers.filter(vocabulary=owner) | |
127 | - else: | |
128 | - ro_qualifiers = [] | |
129 | - to_return['owner'] = owner | |
130 | - ro_vocabularies = l.visible_vocabularies(request.user).exclude( | |
131 | - pk=owner.pk).exclude(pk__in=editable_vocabs) | |
132 | - to_return['ro_vocabularies'] = ro_vocabularies | |
133 | - to_return['ro_qualifiers'] = ro_qualifiers | |
134 | - | |
135 | - to_return['form'] = LexemeEditForm( | |
136 | - instance=l, editable=editable, user=request.user) | |
137 | - to_return['id'] = l.pk | |
138 | - to_return['part_of_speech'] = l.part_of_speech.symbol | |
139 | - to_return['classification_forms'] = make_classification_forms( | |
140 | - l, editable=editable) | |
141 | - | |
142 | - lips = l.lexemeinflectionpattern_set.all() | |
143 | - to_return['lip_forms'] = [ | |
144 | - (LIPEditForm( | |
145 | - lexeme=l, part_of_speech=l.part_of_speech, instance=lip, | |
146 | - prefix='lip' + str(lip.pk), user=request.user, editable=editable), | |
147 | - lip.qualifiers.filter(vocabulary=owner) if ro_owner else []) | |
148 | - for lip in lips] | |
149 | - crs = l.refs_to.order_by('type__index') | |
150 | - to_return['cross_references'] = crs | |
151 | - return to_return | |
118 | + to_return = {} | |
119 | + l = Lexeme.all_objects.get(pk=id) # bo może być świeżo utworzony | |
120 | + if not l.perm(request.user, 'view'): | |
121 | + raise AjaxError('access denied') | |
122 | + editable = l.perm(request.user, 'change') | |
123 | + to_return['editable'] = editable | |
124 | + owner = l.owner_vocabulary | |
125 | + | |
126 | + to_return['attribute_forms'] = attribute_forms(l) | |
127 | + | |
128 | + editable_vocabs = editable_vocabularies(request.user) | |
129 | + ro_owner = owner not in editable_vocabs | |
130 | + to_return['multiple_editable'] = editable and editable_vocabs.count() > 1 | |
131 | + if ro_owner: | |
132 | + # nie pokazujemy wszystkich, tylko te z właściciela | |
133 | + ro_qualifiers = l.qualifiers.filter(vocabulary=owner) | |
134 | + else: | |
135 | + ro_qualifiers = [] | |
136 | + to_return['owner'] = owner | |
137 | + ro_vocabularies = l.visible_vocabularies(request.user).exclude( | |
138 | + pk=owner.pk).exclude(pk__in=editable_vocabs) | |
139 | + to_return['ro_vocabularies'] = ro_vocabularies | |
140 | + to_return['ro_qualifiers'] = ro_qualifiers | |
141 | + | |
142 | + to_return['form'] = LexemeEditForm( | |
143 | + instance=l, editable=editable, user=request.user) | |
144 | + to_return['id'] = l.pk | |
145 | + to_return['part_of_speech'] = l.part_of_speech.symbol | |
146 | + to_return['classification_forms'] = make_classification_forms( | |
147 | + l, editable=editable) | |
148 | + | |
149 | + lips = l.lexemeinflectionpattern_set.all() | |
150 | + to_return['lip_forms'] = [ | |
151 | + (LIPEditForm( | |
152 | + lexeme=l, part_of_speech=l.part_of_speech, instance=lip, | |
153 | + prefix='lip' + str(lip.pk), user=request.user, editable=editable), | |
154 | + lip.qualifiers.filter(vocabulary=owner) if ro_owner else []) | |
155 | + for lip in lips] | |
156 | + crs = l.refs_to.order_by('type__index') | |
157 | + to_return['cross_references'] = crs | |
158 | + return to_return | |
159 | + | |
152 | 160 | |
153 | 161 | @ajax(method='get') |
154 | 162 | def check_classifications(request, owner_id, pos): |
155 | - part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
156 | - owner = Vocabulary.objects.get(pk=owner_id) | |
157 | - classifications = owner.classifications.filter( | |
158 | - parts_of_speech=part_of_speech) | |
159 | - return {'classifications': list(classifications.values_list('pk', flat=True))} | |
163 | + part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
164 | + owner = Vocabulary.objects.get(pk=owner_id) | |
165 | + classifications = owner.classifications.filter( | |
166 | + parts_of_speech=part_of_speech) | |
167 | + return { | |
168 | + 'classifications': list(classifications.values_list('pk', flat=True))} | |
169 | + | |
160 | 170 | |
161 | 171 | def make_classification_forms(lexeme, vocabulary=None, part_of_speech=None, |
162 | 172 | editable=True): |
163 | - if not vocabulary: | |
164 | - vocabulary = lexeme.owner_vocabulary | |
165 | - if not part_of_speech: | |
166 | - part_of_speech = lexeme.part_of_speech | |
167 | - classifications = vocabulary.classifications.filter( | |
168 | - parts_of_speech=part_of_speech) | |
169 | - classification_forms = [] | |
170 | - for c in classifications: | |
171 | - values = lexeme.classification_values(c) | |
172 | - classification_forms.append( | |
173 | - ClassificationForm( | |
174 | - classification=c, values=values, prefix='cl' + str(c.pk), | |
175 | - editable=editable)) | |
176 | - return classification_forms | |
173 | + if not vocabulary: | |
174 | + vocabulary = lexeme.owner_vocabulary | |
175 | + if not part_of_speech: | |
176 | + part_of_speech = lexeme.part_of_speech | |
177 | + classifications = vocabulary.classifications.filter( | |
178 | + parts_of_speech=part_of_speech) | |
179 | + classification_forms = [] | |
180 | + for c in classifications: | |
181 | + values = lexeme.classification_values(c) | |
182 | + classification_forms.append( | |
183 | + ClassificationForm( | |
184 | + classification=c, values=values, prefix='cl' + str(c.pk), | |
185 | + editable=editable)) | |
186 | + return classification_forms | |
187 | + | |
177 | 188 | |
178 | 189 | @render_template('classification_forms.html') |
179 | 190 | @ajax(method='get', template='classification_forms.html') |
180 | 191 | def classification_forms(request, lexeme_id, vocab_id, pos): |
181 | - l = Lexeme.objects.get(pk=lexeme_id) | |
182 | - part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
183 | - if vocab_id: | |
184 | - vocab = Vocabulary.objects.get(pk=vocab_id) | |
185 | - else: | |
186 | - vocab = None | |
187 | - forms = make_classification_forms(l, vocab, part_of_speech) | |
188 | - return {'forms': forms} | |
192 | + l = Lexeme.objects.get(pk=lexeme_id) | |
193 | + part_of_speech = PartOfSpeech.objects.get(symbol=pos) | |
194 | + if vocab_id: | |
195 | + vocab = Vocabulary.objects.get(pk=vocab_id) | |
196 | + else: | |
197 | + vocab = None | |
198 | + forms = make_classification_forms(l, vocab, part_of_speech) | |
199 | + return {'forms': forms} | |
200 | + | |
189 | 201 | |
190 | 202 | @render_template('lexeme_edit_form_row.html') |
191 | 203 | @ajax(method='get', template='lexeme_edit_form_row.html') |
192 | 204 | def new_lip_edit_row(request, lexeme_id, pos_id, num): |
193 | - l = Lexeme.all_objects.get(pk=lexeme_id) | |
194 | - if not l.perm(request.user, 'change'): | |
195 | - raise AjaxError('access denied') | |
196 | - if not pos_id: | |
197 | - raise AjaxError(u'Nieokreślona część mowy.') | |
198 | - pos = PartOfSpeech.objects.get(pk=pos_id) | |
199 | - lip_form = LIPEditForm( | |
200 | - lexeme=l, part_of_speech=pos, prefix='lip_add_%s' % num, user=request.user) | |
201 | - return {'lip_form': lip_form, 'editable': True} | |
205 | + l = Lexeme.all_objects.get(pk=lexeme_id) | |
206 | + if not l.perm(request.user, 'change'): | |
207 | + raise AjaxError('access denied') | |
208 | + if not pos_id: | |
209 | + raise AjaxError(u'Nieokreślona część mowy.') | |
210 | + pos = PartOfSpeech.objects.get(pk=pos_id) | |
211 | + lip_form = LIPEditForm( | |
212 | + lexeme=l, part_of_speech=pos, prefix='lip_add_%s' % num, | |
213 | + user=request.user) | |
214 | + return {'lip_form': lip_form, 'editable': True} | |
215 | + | |
202 | 216 | |
203 | 217 | @render('cross_reference_row.html') |
204 | 218 | @ajax(method='get', encode_result=False) |
205 | 219 | def new_cross_reference_row(request, id, pos_id): |
206 | - l = Lexeme.objects.get(pk=id) | |
207 | - if not l.perm(request.user, 'change'): | |
208 | - raise AjaxError('access denied') | |
209 | - pos = PartOfSpeech.objects.get(pk=pos_id) | |
210 | - cr_form = CrossReferenceForm(lexeme=l, pos=pos, prefix='cr_add_NUM') | |
211 | - return {'cr_form': cr_form, 'editable': True} | |
220 | + l = Lexeme.objects.get(pk=id) | |
221 | + if not l.perm(request.user, 'change'): | |
222 | + raise AjaxError('access denied') | |
223 | + pos = PartOfSpeech.objects.get(pk=pos_id) | |
224 | + cr_form = CrossReferenceForm(lexeme=l, pos=pos, prefix='cr_add_NUM') | |
225 | + return {'cr_form': cr_form, 'editable': True} | |
226 | + | |
212 | 227 | |
213 | 228 | @ajax(method='post') |
214 | 229 | def update_lexeme(request, form_data, mask=''): |
215 | - form_dict = dict((x['name'], x['value']) for x in form_data) | |
216 | - l = Lexeme.all_objects.get(pk=form_dict['id']) | |
217 | - if not l.perm(request.user, 'view'): | |
218 | - raise AjaxError('access denied') | |
219 | - owner = l.owner_vocabulary | |
220 | - created = l.entry == '' | |
221 | - if not l.perm(request.user, 'change'): | |
222 | - return update_lexeme_qualifiers( | |
223 | - l, request.user, form_dict, form_data) | |
224 | - form = LexemeEditForm(data=form_dict, instance=l, user=request.user) | |
225 | - if form.is_valid(): | |
226 | - l = form.save() | |
227 | - l.responsible = request.user | |
228 | - l.deleted = False | |
229 | - l.fix_homonym_number() | |
230 | - l.save() | |
231 | - else: | |
232 | - raise AjaxError(error_messages(form)) | |
233 | - | |
234 | - for vocab in editable_vocabularies(request.user): | |
235 | - if vocab != owner: | |
236 | - vocab.set_lexeme(l, vocab in form.cleaned_data['vocabularies']) | |
237 | - new_owner = form.cleaned_data.get('new_owner') | |
238 | - if new_owner and new_owner != owner: | |
239 | - l.change_owner(new_owner) | |
240 | - l.save() | |
241 | - for qualifier in form.fields['qualifiers'].queryset: | |
242 | - qualifier.set_for(l, qualifier in form.cleaned_data['qualifiers']) | |
243 | - | |
244 | - classifications = l.owner_vocabulary.classifications.filter( | |
245 | - parts_of_speech=l.part_of_speech) | |
246 | - for c in classifications: | |
247 | - classification_form = ClassificationForm( | |
248 | - data=form_dict, classification=c, prefix='cl' + str(c.pk)) | |
249 | - if classification_form.is_valid(): | |
250 | - cvs = ClassificationValue.objects.filter( | |
251 | - pk__in=classification_form.cleaned_data['values']) | |
252 | - l_cvs = l.classification_values(c) | |
253 | - for cv in l_cvs: | |
254 | - if cv.pk not in classification_form.cleaned_data['values']: | |
255 | - cv.remove_lexeme(l) | |
256 | - for cv in cvs: | |
257 | - if cv not in l_cvs: | |
258 | - cv.add_lexeme(l) | |
230 | + form_dict = dict((x['name'], x['value']) for x in form_data) | |
231 | + l = Lexeme.all_objects.get(pk=form_dict['id']) | |
232 | + if not l.perm(request.user, 'view'): | |
233 | + raise AjaxError('access denied') | |
234 | + owner = l.owner_vocabulary | |
235 | + created = l.entry == '' | |
236 | + if not l.perm(request.user, 'change'): | |
237 | + return update_lexeme_qualifiers( | |
238 | + l, request.user, form_dict, form_data) | |
239 | + form = LexemeEditForm(data=form_dict, instance=l, user=request.user) | |
240 | + if form.is_valid(): | |
241 | + l = form.save() | |
242 | + l.responsible = request.user | |
243 | + l.deleted = False | |
244 | + l.fix_homonym_number() | |
245 | + l.save() | |
259 | 246 | else: |
260 | - raise AjaxError(error_messages(classification_form)) | |
261 | - for cv in l.classificationvalue_set.all(): | |
262 | - if cv.classification not in classifications: | |
263 | - cv.remove_lexeme(l) | |
264 | - | |
265 | - extra_attributes = l.attributes() | |
266 | - for attr in extra_attributes: | |
267 | - prefix = 'attr' + str(attr.pk) | |
268 | - attr_values = attr.values.filter(lexemes=l) | |
269 | - if not attr.multiple: | |
270 | - assert len(attr_values) <= 1 | |
271 | - if not attr.closed: | |
272 | - attr_form = LexemeOpenAttributeForm( | |
273 | - attribute=attr, data=form_dict, prefix=prefix) | |
274 | - else: | |
275 | - attr_form = LexemeClosedAttributeForm( | |
276 | - attribute=attr, data=form_dict, prefix=prefix) | |
277 | - if attr_form.is_valid(): | |
278 | - if not attr.closed: | |
279 | - value = attr_form.cleaned_data['value'] | |
280 | - av = LexemeAttributeValue.objects.get_or_create( | |
281 | - attribute=attr, value=value) | |
247 | + raise AjaxError(error_messages(form)) | |
248 | + | |
249 | + for vocab in editable_vocabularies(request.user): | |
250 | + if vocab != owner: | |
251 | + vocab.set_lexeme(l, vocab in form.cleaned_data['vocabularies']) | |
252 | + new_owner = form.cleaned_data.get('new_owner') | |
253 | + if new_owner and new_owner != owner: | |
254 | + l.change_owner(new_owner) | |
255 | + l.save() | |
256 | + for qualifier in form.fields['qualifiers'].queryset: | |
257 | + qualifier.set_for(l, qualifier in form.cleaned_data['qualifiers']) | |
258 | + | |
259 | + classifications = l.owner_vocabulary.classifications.filter( | |
260 | + parts_of_speech=l.part_of_speech) | |
261 | + for c in classifications: | |
262 | + classification_form = ClassificationForm( | |
263 | + data=form_dict, classification=c, prefix='cl' + str(c.pk)) | |
264 | + if classification_form.is_valid(): | |
265 | + cvs = ClassificationValue.objects.filter( | |
266 | + pk__in=classification_form.cleaned_data['values']) | |
267 | + l_cvs = l.classification_values(c) | |
268 | + for cv in l_cvs: | |
269 | + if cv.pk not in classification_form.cleaned_data['values']: | |
270 | + cv.remove_lexeme(l) | |
271 | + for cv in cvs: | |
272 | + if cv not in l_cvs: | |
273 | + cv.add_lexeme(l) | |
282 | 274 | else: |
283 | - av = attr_form.cleaned_data['value'] | |
284 | - if not attr_values or attr_values.get() != av: | |
285 | - for av1 in attr_values: | |
286 | - av1.remove_lexeme(l) | |
287 | - av.add_lexeme(l) | |
288 | - else: | |
289 | - attr_form = LexemeMultipleAttributeForm( | |
290 | - attribute=attr, data=form_dict, prefix=prefix) | |
291 | - if attr_form.is_valid(): | |
292 | - new_values = attr_form.cleaned_data['value'] | |
293 | - for av in set(attr_values) - set(new_values): | |
294 | - av.remove_lexeme(l) | |
295 | - for av in set(new_values) - set(attr_values): | |
296 | - av.add_lexeme(l) | |
297 | - for av in l.lexemeattributevalue_set.all(): | |
298 | - if av.attribute not in extra_attributes: | |
299 | - av.remove_lexeme(l) | |
300 | - | |
301 | - for prefix in form_dict['deleted']: | |
302 | - pk = int(prefix[3:]) | |
303 | - LexemeInflectionPattern.objects.get(pk=pk).delete() | |
304 | - for cr_pk in form_dict['deleted_cr']: | |
305 | - CrossReference.objects.get(pk=cr_pk).delete() | |
306 | - submitted_lips = [] | |
307 | - submitted_crs = [] | |
308 | - for pair in form_data: | |
309 | - # może (?) się psuć, jeśli jest zły charfl | |
310 | - name = pair['name'] | |
311 | - prefix = name.split('-')[0] | |
312 | - if name.startswith('lip') and prefix not in submitted_lips: | |
313 | - submitted_lips.append(prefix) | |
314 | - if prefix.startswith('lip_add'): | |
315 | - lip = LexemeInflectionPattern() | |
316 | - lip.lexeme = l | |
317 | - else: | |
275 | + raise AjaxError(error_messages(classification_form)) | |
276 | + for cv in l.classificationvalue_set.all(): | |
277 | + if cv.classification not in classifications: | |
278 | + cv.remove_lexeme(l) | |
279 | + | |
280 | + extra_attributes = l.attributes() | |
281 | + for attr in extra_attributes: | |
282 | + prefix = 'attr' + str(attr.pk) | |
283 | + attr_values = attr.values.filter(lexemes=l) | |
284 | + if not attr.multiple: | |
285 | + assert len(attr_values) <= 1 | |
286 | + if not attr.closed: | |
287 | + attr_form = LexemeOpenAttributeForm( | |
288 | + attribute=attr, data=form_dict, prefix=prefix) | |
289 | + else: | |
290 | + attr_form = LexemeClosedAttributeForm( | |
291 | + attribute=attr, data=form_dict, prefix=prefix) | |
292 | + if attr_form.is_valid(): | |
293 | + if not attr.closed: | |
294 | + value = attr_form.cleaned_data['value'] | |
295 | + av = LexemeAttributeValue.objects.get_or_create( | |
296 | + attribute=attr, value=value) | |
297 | + else: | |
298 | + av = attr_form.cleaned_data['value'] | |
299 | + if not attr_values or attr_values.get() != av: | |
300 | + for av1 in attr_values: | |
301 | + av1.remove_lexeme(l) | |
302 | + av.add_lexeme(l) | |
303 | + else: | |
304 | + attr_form = LexemeMultipleAttributeForm( | |
305 | + attribute=attr, data=form_dict, prefix=prefix) | |
306 | + if attr_form.is_valid(): | |
307 | + new_values = attr_form.cleaned_data['value'] | |
308 | + for av in set(attr_values) - set(new_values): | |
309 | + av.remove_lexeme(l) | |
310 | + for av in set(new_values) - set(attr_values): | |
311 | + av.add_lexeme(l) | |
312 | + for av in l.lexemeattributevalue_set.all(): | |
313 | + if av.attribute not in extra_attributes: | |
314 | + av.remove_lexeme(l) | |
315 | + | |
316 | + for prefix in form_dict['deleted']: | |
318 | 317 | pk = int(prefix[3:]) |
319 | - lip = LexemeInflectionPattern.objects.get(pk=pk) | |
320 | - form_dict[prefix + '-qualifiers'] = get_list( | |
321 | - form_data, prefix + '-qualifiers') | |
322 | - lip_form = LIPEditForm( | |
323 | - lexeme=l, part_of_speech=l.part_of_speech, data=form_dict, prefix=prefix, | |
324 | - instance=lip, user=request.user, index=len(submitted_lips)) | |
325 | - if lip_form.is_valid(): | |
326 | - lip = lip_form.save() | |
327 | - lip.root = l.get_root(lip.pattern, lip.inflection_characteristic) | |
328 | - if lip.root is None: | |
329 | - raise AjaxError(u'Niepasujące zakończenie formy podstawowej.') | |
330 | - for qualifier in lip_form.fields['qualifiers'].queryset: | |
331 | - qualifier.set_for( | |
332 | - lip, qualifier in lip_form.cleaned_data['qualifiers']) | |
333 | - lip.save() | |
334 | - else: | |
335 | - raise AjaxError(error_messages(lip_form)) | |
336 | - if name.startswith('cr_add') and prefix not in submitted_crs: | |
337 | - submitted_crs.append(prefix) | |
338 | - cr_form = CrossReferenceForm(data=form_dict, prefix=prefix) | |
339 | - if cr_form.is_valid(): | |
340 | - cr_form.save() | |
341 | - else: | |
342 | - raise AjaxError(error_messages(cr_form)) | |
343 | - if len(submitted_lips) == 0 and l.status != 'cand': | |
344 | - raise AjaxError(u'Wybierz odmianę lub ustaw status "kandydat".') | |
345 | - l.refresh_forms() | |
346 | - if created: | |
347 | - sort_rules = json.loads(request.session['sort_rules']) | |
348 | - filters = json.loads(request.session['filters']) | |
349 | - query = JqGridQuery( | |
350 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
351 | - key = cache_key(query) | |
352 | - pk_list = cache.get(key) | |
353 | - if pk_list: | |
354 | - pk_list = [l.pk] + pk_list | |
355 | - cache.set(key, pk_list) | |
356 | - return {} | |
318 | + LexemeInflectionPattern.objects.get(pk=pk).delete() | |
319 | + for cr_pk in form_dict['deleted_cr']: | |
320 | + CrossReference.objects.get(pk=cr_pk).delete() | |
321 | + submitted_lips = [] | |
322 | + submitted_crs = [] | |
323 | + for pair in form_data: | |
324 | + # może (?) się psuć, jeśli jest zły charfl | |
325 | + name = pair['name'] | |
326 | + prefix = name.split('-')[0] | |
327 | + if name.startswith('lip') and prefix not in submitted_lips: | |
328 | + submitted_lips.append(prefix) | |
329 | + if prefix.startswith('lip_add'): | |
330 | + lip = LexemeInflectionPattern() | |
331 | + lip.lexeme = l | |
332 | + else: | |
333 | + pk = int(prefix[3:]) | |
334 | + lip = LexemeInflectionPattern.objects.get(pk=pk) | |
335 | + form_dict[prefix + '-qualifiers'] = get_list( | |
336 | + form_data, prefix + '-qualifiers') | |
337 | + lip_form = LIPEditForm( | |
338 | + lexeme=l, part_of_speech=l.part_of_speech, data=form_dict, | |
339 | + prefix=prefix, | |
340 | + instance=lip, user=request.user, index=len(submitted_lips)) | |
341 | + if lip_form.is_valid(): | |
342 | + lip = lip_form.save() | |
343 | + lip.root = l.get_root(lip.pattern, | |
344 | + lip.inflection_characteristic) | |
345 | + if lip.root is None: | |
346 | + raise AjaxError( | |
347 | + u'Niepasujące zakończenie formy podstawowej.') | |
348 | + for qualifier in lip_form.fields['qualifiers'].queryset: | |
349 | + qualifier.set_for( | |
350 | + lip, qualifier in lip_form.cleaned_data['qualifiers']) | |
351 | + lip.save() | |
352 | + else: | |
353 | + raise AjaxError(error_messages(lip_form)) | |
354 | + if name.startswith('cr_add') and prefix not in submitted_crs: | |
355 | + submitted_crs.append(prefix) | |
356 | + cr_form = CrossReferenceForm(data=form_dict, prefix=prefix) | |
357 | + if cr_form.is_valid(): | |
358 | + cr_form.save() | |
359 | + else: | |
360 | + raise AjaxError(error_messages(cr_form)) | |
361 | + if len(submitted_lips) == 0 and l.status != 'cand': | |
362 | + raise AjaxError(u'Wybierz odmianę lub ustaw status "kandydat".') | |
363 | + l.refresh_forms() | |
364 | + if created: | |
365 | + sort_rules = json.loads(request.session['sort_rules']) | |
366 | + filters = json.loads(request.session['filters']) | |
367 | + query = JqGridQuery( | |
368 | + filters=filters, sort_rules=sort_rules, mask=mask, | |
369 | + user=request.user) | |
370 | + key = cache_key(query) | |
371 | + pk_list = cache.get(key) | |
372 | + if pk_list: | |
373 | + pk_list = [l.pk] + pk_list | |
374 | + cache.set(key, pk_list) | |
375 | + return {} | |
376 | + | |
357 | 377 | |
358 | 378 | def update_lexeme_qualifiers(lexeme, user, form_dict, form_data): |
359 | - owner = lexeme.owner_vocabulary | |
360 | - editable_vocabs = editable_vocabularies(user).exclude(pk=owner.pk) | |
361 | - l_editable_vocabs = lexeme.editable_vocabularies(user) | |
362 | - qualifiers = Qualifier.objects.filter(vocabulary__in=l_editable_vocabs) | |
363 | - for qualifier in qualifiers: | |
364 | - qualifier.set_for( | |
365 | - lexeme, unicode(qualifier.pk) in form_dict['qualifiers']) | |
366 | - for vocab in editable_vocabs: | |
367 | - vocab.set_lexeme(lexeme, vocab.pk in form_dict['vocabularies']) | |
368 | - submitted_lips = [] | |
369 | - for pair in form_data: | |
370 | - name = pair['name'] | |
371 | - prefix = name.split('-')[0] | |
372 | - if name.startswith('lip') and prefix not in submitted_lips: | |
373 | - submitted_lips.append(prefix) | |
374 | - pk = int(prefix[3:]) | |
375 | - lip = LexemeInflectionPattern.objects.get(pk=pk) | |
376 | - lip_qualifiers = get_list(form_data, prefix + '-qualifiers') | |
377 | - for qualifier in qualifiers: | |
378 | - qualifier.set_for(lip, unicode(qualifier.pk) in lip_qualifiers) | |
379 | - return {} | |
379 | + owner = lexeme.owner_vocabulary | |
380 | + editable_vocabs = editable_vocabularies(user).exclude(pk=owner.pk) | |
381 | + l_editable_vocabs = lexeme.editable_vocabularies(user) | |
382 | + qualifiers = Qualifier.objects.filter(vocabulary__in=l_editable_vocabs) | |
383 | + for qualifier in qualifiers: | |
384 | + qualifier.set_for( | |
385 | + lexeme, unicode(qualifier.pk) in form_dict['qualifiers']) | |
386 | + for vocab in editable_vocabs: | |
387 | + vocab.set_lexeme(lexeme, vocab.pk in form_dict['vocabularies']) | |
388 | + submitted_lips = [] | |
389 | + for pair in form_data: | |
390 | + name = pair['name'] | |
391 | + prefix = name.split('-')[0] | |
392 | + if name.startswith('lip') and prefix not in submitted_lips: | |
393 | + submitted_lips.append(prefix) | |
394 | + pk = int(prefix[3:]) | |
395 | + lip = LexemeInflectionPattern.objects.get(pk=pk) | |
396 | + lip_qualifiers = get_list(form_data, prefix + '-qualifiers') | |
397 | + for qualifier in qualifiers: | |
398 | + qualifier.set_for(lip, unicode(qualifier.pk) in lip_qualifiers) | |
399 | + return {} | |
400 | + | |
380 | 401 | |
381 | 402 | def get_list(form_data, name): |
382 | - return [pair['value'] for pair in form_data if pair['name'] == name] | |
403 | + return [pair['value'] for pair in form_data if pair['name'] == name] | |
404 | + | |
383 | 405 | |
384 | 406 | @ajax(method='post') |
385 | 407 | def delete_lexeme(request, lexeme_id): |
386 | - lexeme_id = int(lexeme_id) | |
387 | - l = Lexeme.objects.get(pk=lexeme_id) | |
388 | - if not l.perm(request.user, 'change'): | |
389 | - raise AjaxError('access denied') | |
390 | - l.deleted = True | |
391 | - l.save() | |
392 | - key_list = cache.get('key_list', []) | |
393 | - for key in key_list: | |
394 | - pk_list = cache.get(key) | |
395 | - if pk_list and lexeme_id in pk_list: | |
396 | - pk_list.remove(lexeme_id) | |
397 | - cache.set(key, pk_list) | |
398 | - return {} | |
408 | + lexeme_id = int(lexeme_id) | |
409 | + l = Lexeme.objects.get(pk=lexeme_id) | |
410 | + if not l.perm(request.user, 'change'): | |
411 | + raise AjaxError('access denied') | |
412 | + l.deleted = True | |
413 | + l.save() | |
414 | + key_list = cache.get('key_list', []) | |
415 | + for key in key_list: | |
416 | + pk_list = cache.get(key) | |
417 | + if pk_list and lexeme_id in pk_list: | |
418 | + pk_list.remove(lexeme_id) | |
419 | + cache.set(key, pk_list) | |
420 | + return {} | |
421 | + | |
399 | 422 | |
400 | 423 | @ajax(method='get') |
401 | 424 | def check_pos(request, pos_id, ic_id): |
402 | - ic = InflectionCharacteristic.objects.get(pk=ic_id) | |
403 | - if InflectionCharacteristic.objects.filter( | |
404 | - symbol=ic.symbol, part_of_speech__pk=pos_id): | |
405 | - return {'answer': 'yes'} | |
406 | - else: | |
407 | - return {'answer': 'no'} | |
425 | + ic = InflectionCharacteristic.objects.get(pk=ic_id) | |
426 | + if InflectionCharacteristic.objects.filter( | |
427 | + symbol=ic.symbol, part_of_speech__pk=pos_id): | |
428 | + return {'answer': 'yes'} | |
429 | + else: | |
430 | + return {'answer': 'no'} | |
431 | + | |
408 | 432 | |
409 | 433 | @ajax(method='get') |
410 | 434 | def check_pattern(request, pattern_name, ic_id): |
411 | - lips = LexemeInflectionPattern.objects.filter( | |
412 | - inflection_characteristic__pk=ic_id, pattern__name=pattern_name) | |
413 | - lips = lips.exclude(lexeme__status='cand') | |
414 | - if lips.exists(): | |
415 | - return {'answer': 'yes'} | |
416 | - else: | |
417 | - return {'answer': 'no'} | |
435 | + lips = LexemeInflectionPattern.objects.filter( | |
436 | + inflection_characteristic__pk=ic_id, pattern__name=pattern_name) | |
437 | + lips = lips.exclude(lexeme__status='cand') | |
438 | + if lips.exists(): | |
439 | + return {'answer': 'yes'} | |
440 | + else: | |
441 | + return {'answer': 'no'} | |
442 | + | |
418 | 443 | |
419 | 444 | @ajax(method='get') |
420 | 445 | def get_ics(request, pos_id): |
421 | - return {'ics': list(InflectionCharacteristic.objects.filter( | |
422 | - part_of_speech__pk=pos_id).values_list('pk', 'symbol'))} | |
446 | + return {'ics': list(InflectionCharacteristic.objects.filter( | |
447 | + part_of_speech__pk=pos_id).values_list('pk', 'symbol'))} | |
448 | + | |
423 | 449 | |
424 | 450 | START_ID = 1000000 |
425 | 451 | |
452 | + | |
426 | 453 | @ajax(method='post') |
427 | 454 | def create_lexeme(request, vocab_id): |
428 | - owner = Vocabulary.objects.get(pk=vocab_id) | |
429 | - if request.user not in owner.all_editors(): | |
430 | - raise AjaxError('access denied') | |
431 | - next_id = Lexeme.all_objects.filter( | |
432 | - pk__gte=START_ID).aggregate(Max('id'))['id__max'] | |
433 | - next_id = next_id + 1 if next_id else START_ID | |
434 | - l = Lexeme() | |
435 | - l.id = next_id | |
436 | - l.homonym_number = 1 # zanim zostanie faktycznie stworzony | |
437 | - l.part_of_speech = PartOfSpeech.objects.get(symbol='subst') | |
438 | - l.owner_vocabulary = owner | |
439 | - l.status = 'cand' | |
440 | - l.responsible = request.user | |
441 | - l.deleted = True # proste i genialne! | |
442 | - l.save() | |
443 | - owner.add_lexeme(l) | |
444 | - return {'id': l.id} | |
455 | + owner = Vocabulary.objects.get(pk=vocab_id) | |
456 | + if request.user not in owner.all_editors(): | |
457 | + raise AjaxError('access denied') | |
458 | + next_id = Lexeme.all_objects.filter( | |
459 | + pk__gte=START_ID).aggregate(Max('id'))['id__max'] | |
460 | + next_id = next_id + 1 if next_id else START_ID | |
461 | + l = Lexeme() | |
462 | + l.id = next_id | |
463 | + l.homonym_number = 1 # zanim zostanie faktycznie stworzony | |
464 | + l.part_of_speech = PartOfSpeech.objects.get(symbol='subst') | |
465 | + l.owner_vocabulary = owner | |
466 | + l.status = 'cand' | |
467 | + l.responsible = request.user | |
468 | + l.deleted = True # proste i genialne! | |
469 | + l.save() | |
470 | + owner.add_lexeme(l) | |
471 | + return {'id': l.id} | |
472 | + | |
445 | 473 | |
446 | 474 | @ajax(method='get', login_required=True) |
447 | 475 | def homonym_count(request, entry, lexeme_id): |
448 | - lexemes = Lexeme.objects.filter(entry=entry).exclude(pk=lexeme_id) | |
449 | - lexemes = filter_visible(lexemes, request.user) | |
450 | - return {'count': lexemes.count()} | |
476 | + lexemes = Lexeme.objects.filter(entry=entry).exclude(pk=lexeme_id) | |
477 | + lexemes = filter_visible(lexemes, request.user) | |
478 | + return {'count': lexemes.count()} | |
479 | + | |
451 | 480 | |
452 | 481 | @ajax(method='get', login_required=True) |
453 | 482 | def cr_homonyms(request, entry, cr_type): |
454 | - cr_type = CrossReferenceType.objects.get(pk=cr_type) | |
455 | - lexemes = Lexeme.objects.filter(entry=entry, part_of_speech=cr_type.to_pos) | |
456 | - lexemes_data = [ | |
457 | - { | |
458 | - 'homonym_number': l.homonym_number, | |
459 | - 'lip_data': l.lip_data(), | |
460 | - } for l in lexemes.order_by('homonym_number') | |
461 | - ] | |
462 | - return {'lexemes': lexemes_data} | |
483 | + cr_type = CrossReferenceType.objects.get(pk=cr_type) | |
484 | + lexemes = Lexeme.objects.filter(entry=entry, part_of_speech=cr_type.to_pos) | |
485 | + lexemes_data = [ | |
486 | + { | |
487 | + 'homonym_number': l.homonym_number, | |
488 | + 'lip_data': l.lip_data(), | |
489 | + } for l in lexemes.order_by('homonym_number') | |
490 | + ] | |
491 | + return {'lexemes': lexemes_data} | |
463 | 492 | |
464 | 493 | |
465 | 494 | @render('new_action_row.html') |
466 | 495 | @ajax(method='get', login_required=True, encode_result=False) |
467 | 496 | def new_action_row(request): |
468 | - form = ActionFieldForm(prefix='action_NUM') | |
469 | - return {'form': form} | |
497 | + form = ActionFieldForm(prefix='action_NUM') | |
498 | + return {'form': form} | |
499 | + | |
470 | 500 | |
471 | 501 | @ajax(method='get', login_required=True) |
472 | 502 | def dynamic_action_fields(request, field_name): |
473 | - action_form, value_form = dict(ACTION_FIELDS)[field_name][1:3] | |
474 | - return { | |
475 | - 'action': action_form()['action'].as_widget(), | |
476 | - 'value': value_form(request)['value'].as_widget(), | |
477 | - } | |
503 | + action_form, value_form = dict(ACTION_FIELDS)[field_name][1:3] | |
504 | + return { | |
505 | + 'action': action_form()['action'].as_widget(), | |
506 | + 'value': value_form(request)['value'].as_widget(), | |
507 | + } | |
508 | + | |
478 | 509 | |
479 | 510 | @ajax(method='post', login_required=True) |
480 | 511 | def execute_group_actions(request, actions, filters): |
481 | - if not request.user.has_perm('dictionary.change_lexeme'): | |
482 | - raise AjaxError('access denied') | |
483 | - if isinstance(filters, basestring): | |
484 | - filters = json.loads(filters) | |
485 | - query = JqGridQuery( | |
486 | - filters=filters, sort_rules=[], mask='', user=request.user) | |
487 | - pk_list = get_pk_list(query) | |
488 | - lexemes = Lexeme.objects.filter(pk__in=pk_list) | |
489 | - for l in lexemes: | |
490 | - for action in actions: | |
491 | - field = action['field'] | |
492 | - if field == 'status': | |
493 | - # action['type'] == 'set' | |
494 | - l.status = action['value'] | |
495 | - elif field == 'using_vocabulary': | |
496 | - vocab = Vocabulary.objects.get(pk=action['value']) | |
497 | - if action['type'] == 'add': | |
498 | - vocab.add_lexeme(l) | |
499 | - else: # 'remove' | |
500 | - if vocab != l.owner_vocabulary: | |
501 | - vocab.remove_lexeme(l) | |
502 | - else: # field == 'lexeme_qualifier' | |
503 | - qual = Qualifier.objects.get(pk=action['value']) | |
504 | - # a co jeśli koliduje z innym? | |
505 | - if action['type'] == 'add': | |
506 | - l.qualifiers.add(qual) #add | |
507 | - else: | |
508 | - l.qualifiers.remove(qual) #add | |
509 | - l.save() | |
510 | - #print repr(actions), repr(filters) | |
511 | - return {} | |
512 | + if not request.user.has_perm('dictionary.change_lexeme'): | |
513 | + raise AjaxError('access denied') | |
514 | + if isinstance(filters, basestring): | |
515 | + filters = json.loads(filters) | |
516 | + query = JqGridQuery( | |
517 | + filters=filters, sort_rules=[], mask='', user=request.user) | |
518 | + pk_list = get_pk_list(query) | |
519 | + lexemes = Lexeme.objects.filter(pk__in=pk_list) | |
520 | + for l in lexemes: | |
521 | + for action in actions: | |
522 | + field = action['field'] | |
523 | + if field == 'status': | |
524 | + # action['type'] == 'set' | |
525 | + l.status = action['value'] | |
526 | + elif field == 'using_vocabulary': | |
527 | + vocab = Vocabulary.objects.get(pk=action['value']) | |
528 | + if action['type'] == 'add': | |
529 | + vocab.add_lexeme(l) | |
530 | + else: # 'remove' | |
531 | + if vocab != l.owner_vocabulary: | |
532 | + vocab.remove_lexeme(l) | |
533 | + else: # field == 'lexeme_qualifier' | |
534 | + qual = Qualifier.objects.get(pk=action['value']) | |
535 | + # a co jeśli koliduje z innym? | |
536 | + if action['type'] == 'add': | |
537 | + l.qualifiers.add(qual) #add | |
538 | + else: | |
539 | + l.qualifiers.remove(qual) #add | |
540 | + l.save() | |
541 | + #print repr(actions), repr(filters) | |
542 | + return {} | |
512 | 543 | |
513 | 544 | |
514 | 545 | @ajax(method='post') |
515 | 546 | def save_columns(request, col_model, col_names, remap): |
516 | - request.session['colModel'] = col_model | |
517 | - request.session['colNames'] = col_names | |
518 | - request.session['remap'] = remap | |
519 | - return {} | |
547 | + request.session['colModel'] = col_model | |
548 | + request.session['colNames'] = col_names | |
549 | + request.session['remap'] = remap | |
550 | + return {} | |
520 | 551 | |
521 | 552 | |
522 | 553 | @ajax(method='post') |
523 | 554 | def add_vocabulary(request, name): |
524 | - if not request.user.has_perm('dictionary.manage_vocabulary'): | |
525 | - raise AjaxError('access denied') | |
526 | - vocab = Vocabulary.objects.create(id=name) | |
527 | - vocab.managers.add(request.user) #add | |
528 | - return {} | |
555 | + if not request.user.has_perm('dictionary.manage_vocabulary'): | |
556 | + raise AjaxError('access denied') | |
557 | + vocab = Vocabulary.objects.create(id=name) | |
558 | + vocab.managers.add(request.user) #add | |
559 | + return {} | |
529 | 560 | |
530 | 561 | # nieużywane |
531 | 562 | @ajax(method='get') |
532 | 563 | def vocabulary_permissions(request, vocab_id): |
533 | - if not request.user.has_perm('dictionary.manage_vocabulary'): | |
534 | - raise AjaxError('access denied') | |
535 | - vocab = Vocabulary.objects.get(id=vocab_id) | |
536 | - return { | |
537 | - 'managers': list(vocab.all_managers().values_list('pk', flat=True)), | |
538 | - 'viewers': list(vocab.all_viewers().values_list('pk', flat=True)), | |
539 | - 'editors': list(vocab.editors.values_list('pk', flat=True)), | |
540 | - } | |
564 | + if not request.user.has_perm('dictionary.manage_vocabulary'): | |
565 | + raise AjaxError('access denied') | |
566 | + vocab = Vocabulary.objects.get(id=vocab_id) | |
567 | + return { | |
568 | + 'managers': list(vocab.all_managers().values_list('pk', flat=True)), | |
569 | + 'viewers': list(vocab.all_viewers().values_list('pk', flat=True)), | |
570 | + 'editors': list(vocab.editors.values_list('pk', flat=True)), | |
571 | + } | |
572 | + | |
541 | 573 | |
542 | 574 | @ajax(method='post') |
543 | 575 | def set_vocabulary_permission(request, name, vocab_id, perm, on): |
544 | - if not request.user.has_perm('dictionary.manage_vocabulary'): | |
545 | - raise AjaxError('access denied') | |
546 | - vocab = Vocabulary.objects.get(id=name) | |
547 | - user = User.objects.get(pk=vocab_id) | |
548 | - if perm == 'view': | |
549 | - related_manager = vocab.viewers | |
550 | - elif perm == 'change': | |
551 | - related_manager = vocab.editors | |
552 | - else: # type == 'manage' | |
553 | - related_manager = vocab.managers | |
554 | - if on: | |
555 | - related_manager.add(user) #add | |
556 | - else: | |
557 | - related_manager.remove(user) #add | |
558 | - return {} | |
559 | 576 | \ No newline at end of file |
577 | + if not request.user.has_perm('dictionary.manage_vocabulary'): | |
578 | + raise AjaxError('access denied') | |
579 | + vocab = Vocabulary.objects.get(id=name) | |
580 | + user = User.objects.get(pk=vocab_id) | |
581 | + if perm == 'view': | |
582 | + related_manager = vocab.viewers | |
583 | + elif perm == 'change': | |
584 | + related_manager = vocab.editors | |
585 | + else: # type == 'manage' | |
586 | + related_manager = vocab.managers | |
587 | + if on: | |
588 | + related_manager.add(user) #add | |
589 | + else: | |
590 | + related_manager.remove(user) #add | |
591 | + return {} | |
560 | 592 | \ No newline at end of file |
... | ... |
dictionary/ajax_pattern_view.py
... | ... | @@ -2,44 +2,44 @@ |
2 | 2 | |
3 | 3 | from common.util import json_encode |
4 | 4 | from dictionary.models import Pattern, Ending, BaseFormLabel, PatternType, \ |
5 | - editable_qualifiers, readonly_vocabularies | |
5 | + editable_qualifiers, readonly_vocabularies | |
6 | 6 | from dictionary.forms import PatternEditForm, PatternTypeForm, QualifierForm |
7 | 7 | from dictionary.ajax_jqgrid import JqGridAjax, JqGridQuery |
8 | 8 | from common.decorators import render, ajax, AjaxError, render_template |
9 | 9 | |
10 | 10 | |
11 | 11 | class PatternGrid(JqGridAjax): |
12 | - model = Pattern | |
13 | - search_field = 'name' | |
14 | - | |
15 | - @staticmethod | |
16 | - def filter_special_case(filter, lookup, negated, queryset): | |
17 | - field = filter['field'] | |
18 | - if field == 'part_of_speech': | |
19 | - field = 'type__lexical_class__symbol' | |
20 | - elif field == 'type': | |
21 | - field = 'type__symbol' | |
22 | - return False, field, queryset | |
23 | - | |
24 | - @staticmethod | |
25 | - def apply_mask(patterns, mask, sort_rules): | |
26 | - return patterns.filter(name__istartswith=mask) | |
27 | - | |
28 | - @staticmethod | |
29 | - def response_row(pattern): | |
30 | - return [ | |
31 | - pattern.name, | |
32 | - pattern.type.symbol, | |
33 | - pattern.type.lexical_class.symbol, | |
34 | - ] | |
12 | + model = Pattern | |
13 | + search_field = 'name' | |
14 | + | |
15 | + @staticmethod | |
16 | + def filter_special_case(filter, lookup, negated, queryset): | |
17 | + field = filter['field'] | |
18 | + if field == 'part_of_speech': | |
19 | + field = 'type__lexical_class__symbol' | |
20 | + elif field == 'type': | |
21 | + field = 'type__symbol' | |
22 | + return False, field, queryset | |
23 | + | |
24 | + @staticmethod | |
25 | + def apply_mask(patterns, mask, sort_rules): | |
26 | + return patterns.filter(name__istartswith=mask) | |
27 | + | |
28 | + @staticmethod | |
29 | + def response_row(pattern): | |
30 | + return [ | |
31 | + pattern.name, | |
32 | + pattern.type.symbol, | |
33 | + pattern.type.lexical_class.symbol, | |
34 | + ] | |
35 | 35 | |
36 | 36 | |
37 | 37 | # Zapytanie o indeks wiersza o pewnym id przy danym sortowaniu |
38 | 38 | @ajax(method='get') |
39 | 39 | def find_id(request, id, sort_rules, mask, filters=None): |
40 | - query = JqGridQuery( | |
41 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
42 | - return PatternGrid.find_id(id, query) | |
40 | + query = JqGridQuery( | |
41 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
42 | + return PatternGrid.find_id(id, query) | |
43 | 43 | |
44 | 44 | |
45 | 45 | # Zapytanie o id oraz indeks wiersza przy danym sortowaniu |
... | ... | @@ -47,104 +47,109 @@ def find_id(request, id, sort_rules, mask, filters=None): |
47 | 47 | # 'selected_id' < 0, jeśli takiego nie ma |
48 | 48 | @ajax(method='get') |
49 | 49 | def get_location(request, sort_rules, filters=None, mask=''): |
50 | - query = JqGridQuery( | |
51 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
52 | - return PatternGrid.get_location(query) | |
50 | + query = JqGridQuery( | |
51 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
52 | + return PatternGrid.get_location(query) | |
53 | 53 | |
54 | 54 | |
55 | 55 | @ajax(method='get') |
56 | 56 | def get_patterns(request, page, rows, sort_rules, filters=None, mask='', |
57 | 57 | target_page=0, totalrows=0): |
58 | - request.session['pattern-sort_rules'] = json_encode(sort_rules) | |
59 | - request.session['pattern-filters'] = json_encode(filters) | |
60 | - page = target_page or page | |
61 | - limit = totalrows or rows | |
62 | - query = JqGridQuery( | |
63 | - filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
64 | - return PatternGrid.get_page(page, limit, query) | |
58 | + request.session['pattern-sort_rules'] = json_encode(sort_rules) | |
59 | + request.session['pattern-filters'] = json_encode(filters) | |
60 | + page = target_page or page | |
61 | + limit = totalrows or rows | |
62 | + query = JqGridQuery( | |
63 | + filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) | |
64 | + return PatternGrid.get_page(page, limit, query) | |
65 | 65 | |
66 | 66 | |
67 | 67 | @render_template('pattern_edit_form.html') |
68 | 68 | @ajax(method='get', template='pattern_edit_form.html') |
69 | 69 | def pattern_edit_form(request, id): |
70 | - if not request.user.has_perm('dictionary.view_pattern'): | |
71 | - raise AjaxError('access denied') | |
72 | - to_return = {} | |
73 | - p = Pattern.objects.get(pk=id) | |
74 | - editable = request.user.has_perm('dictionary.change_pattern') | |
75 | - to_return['form'] = PatternEditForm(instance=p, editable=editable) | |
76 | - to_return['type_form'] = PatternTypeForm(instance=p.type, editable=editable) | |
77 | - to_return['id'] = p.pk | |
78 | - to_return['editable'] = editable | |
79 | - bfls = p.type.base_form_labels() | |
80 | - ending_groups = dict((bfl, []) for bfl in bfls) | |
81 | - endings = p.endings.order_by('base_form_label', 'index') | |
82 | - for e in endings: | |
83 | - ro_qualifers = e.qualifiers.filter( | |
84 | - vocabulary__in=readonly_vocabularies(request.user)) | |
85 | - q_form = QualifierForm( | |
86 | - qualified=e, user=request.user, editable=editable, prefix='end%s' % e.pk) | |
87 | - ending_groups[e.base_form_label].append((e, ro_qualifers, q_form)) | |
88 | - to_return['ending_groups'] = ending_groups | |
89 | - return to_return | |
70 | + if not request.user.has_perm('dictionary.view_pattern'): | |
71 | + raise AjaxError('access denied') | |
72 | + to_return = {} | |
73 | + p = Pattern.objects.get(pk=id) | |
74 | + editable = request.user.has_perm('dictionary.change_pattern') | |
75 | + to_return['pattern'] = p | |
76 | + to_return['form'] = PatternEditForm(instance=p, editable=editable) | |
77 | + to_return['type_form'] = PatternTypeForm(instance=p.type, editable=editable) | |
78 | + to_return['editable'] = editable | |
79 | + bfls = p.type.base_form_labels() | |
80 | + ending_groups = dict((bfl, []) for bfl in bfls) | |
81 | + endings = p.endings.order_by('base_form_label', 'index') | |
82 | + for e in endings: | |
83 | + ro_qualifers = e.qualifiers.filter( | |
84 | + vocabulary__in=readonly_vocabularies(request.user)) | |
85 | + q_form = QualifierForm( | |
86 | + qualified=e, user=request.user, editable=editable, | |
87 | + prefix='end%s' % e.pk) | |
88 | + ending_groups[e.base_form_label].append((e, ro_qualifers, q_form)) | |
89 | + to_return['ending_groups'] = ending_groups | |
90 | + return to_return | |
90 | 91 | |
91 | 92 | |
92 | 93 | # mogłoby iść przez js_vars... |
93 | 94 | @render('ending_row.html') |
94 | 95 | @ajax(method='get', encode_result=False) |
95 | -def new_ending_row(request): | |
96 | - ending = {'string': '', 'id': 'add-NUM'} | |
97 | - form = QualifierForm(user=request.user, prefix='add-NUM') | |
98 | - return {'ending': ending, 'editable': True, 'form': form} | |
96 | +def new_ending_row(request, pattern_id): | |
97 | + p = Pattern.objects.get(id=pattern_id) | |
98 | + ending = {'string': '', 'id': 'add-NUM'} | |
99 | + form = QualifierForm(user=request.user, prefix='add-NUM') | |
100 | + return {'ending': ending, 'editable': True, 'form': form, 'pattern': p} | |
99 | 101 | |
100 | 102 | |
101 | 103 | @ajax(method='post') |
102 | 104 | def update_pattern(request, form_data): |
103 | - if not request.user.has_perm('dictionary.change_pattern'): | |
104 | - raise AjaxError('access denied') | |
105 | - form_dict = dict((x['name'], x['value']) for x in form_data) | |
106 | - p = Pattern.objects.get(pk=form_dict['id']) | |
107 | - form = PatternEditForm(data=form_dict, instance=p) | |
108 | - type_form = PatternTypeForm(data=form_dict) | |
109 | - if type_form.is_valid(): | |
110 | - type_qs = PatternType.objects.filter( | |
111 | - symbol=type_form.cleaned_data['symbol'], | |
112 | - lexical_class=type_form.cleaned_data['lexical_class']) | |
113 | - else: | |
114 | - raise AjaxError('invalid data') | |
115 | - if form.is_valid() and len(type_qs) == 1: | |
116 | - form.save() | |
117 | - p.type = type_qs[0] | |
118 | - p.save() | |
119 | - for ending_pk in form_dict['deleted']: | |
120 | - Ending.objects.get(pk=int(ending_pk)).delete() | |
121 | - qualifiers = editable_qualifiers(request.user) | |
122 | - for bfl_endings in form_dict['ending_list']: | |
123 | - endings_data = bfl_endings['endings'] | |
124 | - bfl = BaseFormLabel.objects.get(symbol=bfl_endings['base_form_label']) | |
125 | - endings = [] | |
126 | - for index, ending_data in zip(range(1, len(endings_data) + 1), endings_data): | |
127 | - quals = set(int(q) for q in ending_data['qualifiers']) | |
128 | - if ending_data['id'] == 'add': | |
129 | - ending = Ending.objects.create( | |
130 | - pattern=p, base_form_label=bfl, string=ending_data['string'], | |
131 | - index=index) | |
132 | - else: | |
133 | - ending = Ending.objects.get(pk=int(ending_data['id'])) | |
134 | - ending.index = index | |
135 | - ending.string = ending_data['string'] | |
136 | - ending.save() | |
137 | - for qualifier in qualifiers: | |
138 | - qualifier.set_for(ending, qualifier.pk in quals) | |
139 | - endings.append(ending) | |
140 | - else: | |
141 | - raise AjaxError('invalid data') | |
142 | - return {} | |
105 | + if not request.user.has_perm('dictionary.change_pattern'): | |
106 | + raise AjaxError('access denied') | |
107 | + form_dict = dict((x['name'], x['value']) for x in form_data) | |
108 | + p = Pattern.objects.get(pk=form_dict['id']) | |
109 | + form = PatternEditForm(data=form_dict, instance=p) | |
110 | + type_form = PatternTypeForm(data=form_dict) | |
111 | + if type_form.is_valid(): | |
112 | + type_qs = PatternType.objects.filter( | |
113 | + symbol=type_form.cleaned_data['symbol'], | |
114 | + lexical_class=type_form.cleaned_data['lexical_class']) | |
115 | + else: | |
116 | + raise AjaxError('invalid data') | |
117 | + if form.is_valid() and len(type_qs) == 1: | |
118 | + form.save() | |
119 | + p.type = type_qs[0] | |
120 | + p.save() | |
121 | + for ending_pk in form_dict['deleted']: | |
122 | + Ending.objects.get(pk=int(ending_pk)).delete() | |
123 | + qualifiers = editable_qualifiers(request.user) | |
124 | + for bfl_endings in form_dict['ending_list']: | |
125 | + endings_data = bfl_endings['endings'] | |
126 | + bfl = BaseFormLabel.objects.get( | |
127 | + symbol=bfl_endings['base_form_label']) | |
128 | + endings = [] | |
129 | + for index, ending_data in zip(range(1, len(endings_data) + 1), | |
130 | + endings_data): | |
131 | + quals = set(int(q) for q in ending_data['qualifiers']) | |
132 | + if ending_data['id'] == 'add': | |
133 | + ending = Ending.objects.create( | |
134 | + pattern=p, base_form_label=bfl, | |
135 | + string=ending_data['string'], | |
136 | + index=index) | |
137 | + else: | |
138 | + ending = Ending.objects.get(pk=int(ending_data['id'])) | |
139 | + ending.index = index | |
140 | + ending.string = ending_data['string'] | |
141 | + ending.save() | |
142 | + for qualifier in qualifiers: | |
143 | + qualifier.set_for(ending, qualifier.pk in quals) | |
144 | + endings.append(ending) | |
145 | + else: | |
146 | + raise AjaxError('invalid data') | |
147 | + return {} | |
143 | 148 | |
144 | 149 | |
145 | 150 | @ajax(method='post') |
146 | 151 | def save_columns(request, col_model, col_names, remap): |
147 | - request.session['pattern-colModel'] = col_model | |
148 | - request.session['pattern-colNames'] = col_names | |
149 | - request.session['pattern-remap'] = remap | |
150 | - return {} | |
152 | + request.session['pattern-colModel'] = col_model | |
153 | + request.session['pattern-colNames'] = col_names | |
154 | + request.session['pattern-remap'] = remap | |
155 | + return {} | |
... | ... |
dictionary/ajax_prompter.py
... | ... | @@ -3,82 +3,84 @@ |
3 | 3 | from common.decorators import render, ajax, AjaxError |
4 | 4 | from common.util import suffix, cut_end |
5 | 5 | from dictionary.models import Lexeme, LexemeInflectionPattern, Pattern, \ |
6 | - InflectionCharacteristic, prepare_table, visible_vocabularies, get_root, \ | |
7 | - ClassificationValue, Classification, filter_visible_lips | |
6 | + InflectionCharacteristic, prepare_table, visible_vocabularies, get_root, \ | |
7 | + ClassificationValue, Classification, filter_visible_lips | |
8 | 8 | from dictionary.pattern_blacklist import blacklist |
9 | 9 | |
10 | 10 | commonness = Classification.objects.get(name=u'pospolitość') |
11 | 11 | |
12 | 12 | LIP_ROWS = 10 |
13 | 13 | |
14 | + | |
14 | 15 | def make_list(user, entry, pos, ic, cvs, bl_check): |
15 | - lips = LexemeInflectionPattern.objects.distinct() | |
16 | - lips = filter_visible_lips(lips, user) | |
17 | - lips = lips.filter( | |
18 | - lexeme__part_of_speech__symbol=pos).exclude(lexeme__status='cand') | |
19 | - if ic: | |
20 | - lips = lips.filter(inflection_characteristic=ic) | |
21 | - if cvs: | |
22 | - lips = lips.filter(lexeme__classificationvalue__in=cvs) | |
23 | - else: | |
24 | - lips = lips.exclude(lexeme__classificationvalue=None) | |
25 | - lips = lips.order_by('lexeme__entry') | |
26 | - feature_sets = set() | |
27 | - bad_inflections = set() | |
28 | - chosen_lips = [] | |
29 | - for suf_len in xrange(len(entry), 0, -1): | |
30 | - suf = suffix(entry, suf_len) | |
31 | - suf_lips = lips.filter(lexeme__entry__endswith=suf) | |
32 | - if suf_len < len(entry): | |
33 | - suf1 = suffix(entry, suf_len + 1) | |
34 | - suf_lips = suf_lips.exclude(lexeme__entry__endswith=suf1) | |
35 | - for p0, ic0 in bad_inflections: | |
36 | - suf_lips.exclude(pattern=p0, inflection_characteristic=ic0) | |
37 | - for p0, ic0 in feature_sets: | |
38 | - suf_lips = suf_lips.exclude( | |
39 | - pattern=p0, inflection_characteristic=ic0) | |
40 | - for lip in suf_lips: | |
41 | - #lip = suf_lips[0] | |
42 | - p = lip.pattern | |
43 | - #suf_lips = suf_lips.exclude(pattern=p) | |
44 | - if p.name in blacklist and bl_check: continue | |
45 | - if ic: | |
46 | - l_ic = ic | |
47 | - else: | |
48 | - l_ic = lip.inflection_characteristic | |
49 | - if (p, l_ic) in bad_inflections: continue | |
50 | - if (p, l_ic) in feature_sets: continue | |
51 | - if cvs: | |
52 | - l_cvs = lip.lexeme.classification_values(commonness) & cvs | |
53 | - else: | |
54 | - l_cvs = lip.lexeme.classification_values(commonness) | |
55 | - if get_root(entry, pos, p, l_ic) is not None: | |
56 | - l_root = lip.lexeme.get_root(p, l_ic) | |
57 | - l_end = lip.lexeme.entry[len(l_root):] | |
58 | - l_entry = u'%s·%s' % (l_root, l_end) | |
59 | - if len(l_end) < len(suf): | |
60 | - suf = suffix(l_entry, suf_len + 1) | |
61 | - chosen_lips.append((lip, l_cvs, cut_end(l_entry, suf), suf)) | |
62 | - feature_sets.add((p, l_ic)) | |
16 | + lips = LexemeInflectionPattern.objects.distinct() | |
17 | + lips = filter_visible_lips(lips, user) | |
18 | + lips = lips.filter( | |
19 | + lexeme__part_of_speech__symbol=pos).exclude(lexeme__status='cand') | |
20 | + if ic: | |
21 | + lips = lips.filter(inflection_characteristic=ic) | |
22 | + if cvs: | |
23 | + lips = lips.filter(lexeme__classificationvalue__in=cvs) | |
24 | + else: | |
25 | + lips = lips.exclude(lexeme__classificationvalue=None) | |
26 | + lips = lips.order_by('lexeme__entry') | |
27 | + feature_sets = set() | |
28 | + bad_inflections = set() | |
29 | + chosen_lips = [] | |
30 | + for suf_len in xrange(len(entry), 0, -1): | |
31 | + suf = suffix(entry, suf_len) | |
32 | + suf_lips = lips.filter(lexeme__entry__endswith=suf) | |
33 | + if suf_len < len(entry): | |
34 | + suf1 = suffix(entry, suf_len + 1) | |
35 | + suf_lips = suf_lips.exclude(lexeme__entry__endswith=suf1) | |
36 | + for p0, ic0 in bad_inflections: | |
37 | + suf_lips.exclude(pattern=p0, inflection_characteristic=ic0) | |
38 | + for p0, ic0 in feature_sets: | |
39 | + suf_lips = suf_lips.exclude( | |
40 | + pattern=p0, inflection_characteristic=ic0) | |
41 | + for lip in suf_lips: | |
42 | + #lip = suf_lips[0] | |
43 | + p = lip.pattern | |
44 | + #suf_lips = suf_lips.exclude(pattern=p) | |
45 | + if p.name in blacklist and bl_check: continue | |
46 | + if ic: | |
47 | + l_ic = ic | |
48 | + else: | |
49 | + l_ic = lip.inflection_characteristic | |
50 | + if (p, l_ic) in bad_inflections: continue | |
51 | + if (p, l_ic) in feature_sets: continue | |
52 | + if cvs: | |
53 | + l_cvs = lip.lexeme.classification_values(commonness) & cvs | |
54 | + else: | |
55 | + l_cvs = lip.lexeme.classification_values(commonness) | |
56 | + if get_root(entry, pos, p, l_ic) is not None: | |
57 | + l_root = lip.lexeme.get_root(p, l_ic) | |
58 | + l_end = lip.lexeme.entry[len(l_root):] | |
59 | + l_entry = u'%s·%s' % (l_root, l_end) | |
60 | + if len(l_end) < len(suf): | |
61 | + suf = suffix(l_entry, suf_len + 1) | |
62 | + chosen_lips.append((lip, l_cvs, cut_end(l_entry, suf), suf)) | |
63 | + feature_sets.add((p, l_ic)) | |
64 | + if len(chosen_lips) == LIP_ROWS: | |
65 | + break | |
66 | + else: | |
67 | + bad_inflections.add((p, l_ic)) | |
63 | 68 | if len(chosen_lips) == LIP_ROWS: |
64 | - break | |
65 | - else: | |
66 | - bad_inflections.add((p, l_ic)) | |
67 | - if len(chosen_lips) == LIP_ROWS: | |
68 | - break | |
69 | - return chosen_lips | |
69 | + break | |
70 | + return chosen_lips | |
71 | + | |
70 | 72 | |
71 | 73 | @ajax(method='get', template='prompter_list.html') |
72 | 74 | def prompter_list(request, entry, pos_id, ic_id, commonness_ids, |
73 | 75 | ic_check, cv_check, bl_check): |
74 | - if ic_check: | |
75 | - ic = InflectionCharacteristic.objects.get(pk=ic_id) | |
76 | - else: | |
77 | - ic = None | |
78 | - if cv_check: # and commonness not in ('undefined', 'None'): | |
79 | - cvs = ClassificationValue.objects.filter(pk__in=commonness_ids) | |
80 | - else: | |
81 | - cvs = None | |
82 | - lips = make_list(request.user, entry, pos_id, ic, cvs, bl_check) | |
83 | - # zakładamy, że symbol == pk | |
84 | - return {'lips': lips} | |
76 | + if ic_check: | |
77 | + ic = InflectionCharacteristic.objects.get(pk=ic_id) | |
78 | + else: | |
79 | + ic = None | |
80 | + if cv_check: # and commonness not in ('undefined', 'None'): | |
81 | + cvs = ClassificationValue.objects.filter(pk__in=commonness_ids) | |
82 | + else: | |
83 | + cvs = None | |
84 | + lips = make_list(request.user, entry, pos_id, ic, cvs, bl_check) | |
85 | + # zakładamy, że symbol == pk | |
86 | + return {'lips': lips} | |
... | ... |
dictionary/export.py
... | ... | @@ -7,32 +7,33 @@ from common.util import debug, flatten |
7 | 7 | from dictionary.models import CrossReferenceType, ClassificationValue, LexemeAttributeValue |
8 | 8 | |
9 | 9 | ADJPREDYKATYWNE = [ |
10 | - u'ciekaw', | |
11 | - u'godzien', | |
12 | - u'gotów', | |
13 | - u'łaskaw', | |
14 | - u'świadom', | |
15 | - u'winien', | |
16 | - u'zdrów', | |
17 | -# wątpliwe: | |
18 | - u'dłużen', | |
19 | - u'miłościw', | |
20 | - u'praw', | |
21 | - u'wesół', | |
22 | - u'żyw', | |
10 | + u'ciekaw', | |
11 | + u'godzien', | |
12 | + u'gotów', | |
13 | + u'łaskaw', | |
14 | + u'świadom', | |
15 | + u'winien', | |
16 | + u'zdrów', | |
17 | + # wątpliwe: | |
18 | + u'dłużen', | |
19 | + u'miłościw', | |
20 | + u'praw', | |
21 | + u'wesół', | |
22 | + u'żyw', | |
23 | 23 | ] |
24 | 24 | |
25 | 25 | REFL_TRANSLATION = { |
26 | - u'—': 'nonrefl', | |
27 | - u'się': 'refl', | |
28 | - u'sobie': 'refl', | |
29 | - u'się/sobie': 'refl', | |
30 | - u'(się)': 'refl.nonrefl', | |
31 | - u'(sobie)': 'refl.nonrefl', | |
26 | + u'—': 'nonrefl', | |
27 | + u'się': 'refl', | |
28 | + u'sobie': 'refl', | |
29 | + u'się/sobie': 'refl', | |
30 | + u'(się)': 'refl.nonrefl', | |
31 | + u'(sobie)': 'refl.nonrefl', | |
32 | 32 | } |
33 | 33 | |
34 | + | |
34 | 35 | def qualifier_clause(q_id): |
35 | - return '''not exists ( | |
36 | + return '''not exists ( | |
36 | 37 | select * from kwalifikatory_leksemow where lexeme_id = l.id and |
37 | 38 | qualifier_id = %(q)d) and not exists ( |
38 | 39 | select * from kwalifikatory_odmieniasiow where qualifier_id = %(q)d and |
... | ... | @@ -40,8 +41,9 @@ def qualifier_clause(q_id): |
40 | 41 | select * from kwalifikatory_zakonczen where qualifier_id = %(q)d and |
41 | 42 | ending_id = z.id) and ''' % {'q': q_id} |
42 | 43 | |
44 | + | |
43 | 45 | def magic_qualifier_clause(): |
44 | - return '''and not (tag like %s and exists ( | |
46 | + return '''and not (tag like %s and exists ( | |
45 | 47 | select kw.id |
46 | 48 | from kwalifikatory kw |
47 | 49 | join kwalifikatory_leksemow kwl on kw.id = kwl.qualifier_id |
... | ... | @@ -49,45 +51,45 @@ def magic_qualifier_clause(): |
49 | 51 | |
50 | 52 | |
51 | 53 | def export_lexemes(data=None, output_file=None): |
52 | - if not data: | |
53 | - data = { | |
54 | - 'vocabs': ['PoliMorf'], | |
55 | - 'antivocabs': [], | |
56 | - 'variant': 'Morfeusz', | |
57 | - 'excluding_qualifiers': [], | |
58 | - 'magic_qualifiers': [], | |
59 | - 'refl': False, | |
60 | - 'commonness': False, | |
61 | - } | |
62 | - if output_file is None: | |
63 | - output_file = sys.stdout | |
64 | - vocabs_placeholders = ', '.join('%s' for v in data['vocabs']) | |
54 | + if not data: | |
55 | + data = { | |
56 | + 'vocabs': ['PoliMorf'], | |
57 | + 'antivocabs': [], | |
58 | + 'variant': 'Morfeusz', | |
59 | + 'excluding_qualifiers': [], | |
60 | + 'magic_qualifiers': [], | |
61 | + 'refl': False, | |
62 | + 'commonness': False, | |
63 | + } | |
64 | + if output_file is None: | |
65 | + output_file = sys.stdout | |
66 | + vocabs_placeholders = ', '.join('%s' for v in data['vocabs']) | |
65 | 67 | |
66 | - if data['antivocabs']: | |
67 | - antivocabs_placeholders = ', '.join('%s' for v in data['antivocabs']) | |
68 | - antivocabs_clause = '''not exists ( | |
68 | + if data['antivocabs']: | |
69 | + antivocabs_placeholders = ', '.join('%s' for v in data['antivocabs']) | |
70 | + antivocabs_clause = '''not exists ( | |
69 | 71 | select * from leksemy_w_slownikach ls2 where ls2.l_id = l.id |
70 | 72 | and ls2.slownik in (%s)) and''' % antivocabs_placeholders |
71 | - else: | |
72 | - antivocabs_clause = '' | |
73 | + else: | |
74 | + antivocabs_clause = '' | |
73 | 75 | |
74 | - qualifier_clauses = ''.join( | |
75 | - qualifier_clause(q_id) for q_id in data['excluding_qualifiers']) | |
76 | - magic_qualifier_clauses = ''.join( | |
77 | - magic_qualifier_clause() for pattern, q_id in data['magic_qualifiers']) | |
76 | + qualifier_clauses = ''.join( | |
77 | + qualifier_clause(q_id) for q_id in data['excluding_qualifiers']) | |
78 | + magic_qualifier_clauses = ''.join( | |
79 | + magic_qualifier_clause() for pattern, q_id in data['magic_qualifiers']) | |
78 | 80 | |
79 | - crtypes = ['comadv', 'comadj', 'gerver', 'pactver', 'ppasver'] | |
80 | - crtype_ids = CrossReferenceType.objects.filter( | |
81 | - symbol__in=crtypes).values_list('pk', flat=True) | |
81 | + crtypes = ['comadv', 'comadj', 'gerver', 'pactver', 'ppasver'] | |
82 | + crtype_ids = CrossReferenceType.objects.filter( | |
83 | + symbol__in=crtypes).values_list('pk', flat=True) | |
82 | 84 | |
83 | - cv_ids = ClassificationValue.objects.filter( | |
84 | - classification__name=u'pospolitość').values_list('pk', flat=True) | |
85 | + cv_ids = ClassificationValue.objects.filter( | |
86 | + classification__name=u'pospolitość').values_list('pk', flat=True) | |
85 | 87 | |
86 | - refls = dict(LexemeAttributeValue.objects.filter( | |
87 | - attribute__name=u'zwrotność').values_list('pk', 'value')) | |
88 | + refls = dict(LexemeAttributeValue.objects.filter( | |
89 | + attribute__name=u'zwrotność').values_list('pk', 'value')) | |
88 | 90 | |
89 | - cursor = connection.cursor() | |
90 | - query = """ | |
91 | + cursor = connection.cursor() | |
92 | + query = """ | |
91 | 93 | select distinct haslo, prefiks||rdzen||zak||sufiks, l.pos, ch.charfl, tag, |
92 | 94 | l.id as leksem_id, refl.attribute_value_id %(clas_field)s |
93 | 95 | from leksemy l |
... | ... | @@ -133,46 +135,46 @@ def export_lexemes(data=None, output_file=None): |
133 | 135 | --and g.haslo < 'b' |
134 | 136 | order by haslo, leksem_id |
135 | 137 | """ % { |
136 | - 'vocabs': vocabs_placeholders, | |
137 | - 'antivocabs': antivocabs_clause, | |
138 | - 'x_qual': qualifier_clauses, | |
139 | - 'magic': magic_qualifier_clauses, | |
140 | - 'crtype_ids': ', '.join(str(pk) for pk in crtype_ids), # brzydko, oj tam | |
141 | - 'clas_field': ', classification_value_id' if data['commonness'] else '', | |
142 | - 'clas_join': | |
143 | - 'left outer join dictionary_lexemecv wkl ' | |
144 | - 'on (wkl.lexeme_id=l.id and wkl.classification_value_id in (%s))' | |
145 | - % ', '.join(str(pk) for pk in cv_ids) if data['commonness'] else '', | |
146 | - 'refl': | |
147 | - 'refl.attribute_value_id in (%s)' | |
148 | - % ', '.join(str(pk) for pk in refls), | |
138 | + 'vocabs': vocabs_placeholders, | |
139 | + 'antivocabs': antivocabs_clause, | |
140 | + 'x_qual': qualifier_clauses, | |
141 | + 'magic': magic_qualifier_clauses, | |
142 | + 'crtype_ids': ', '.join(str(pk) for pk in crtype_ids), # brzydko, oj tam | |
143 | + 'clas_field': ', classification_value_id' if data['commonness'] else '', | |
144 | + 'clas_join': | |
145 | + 'left outer join dictionary_lexemecv wkl ' | |
146 | + 'on (wkl.lexeme_id=l.id and wkl.classification_value_id in (%s))' | |
147 | + % ', '.join(str(pk) for pk in cv_ids) if data['commonness'] else '', | |
148 | + 'refl': | |
149 | + 'refl.attribute_value_id in (%s)' | |
150 | + % ', '.join(str(pk) for pk in refls), | |
149 | 151 | } |
150 | - params_part = (list(data['vocabs']) + list(data['antivocabs']) + | |
151 | - [data['variant']]) | |
152 | - params = params_part + flatten(data['magic_qualifiers']) + params_part | |
153 | - cursor.execute(query, params) | |
154 | - refl = data['refl'] | |
155 | - cv_table = dict(ClassificationValue.objects.values_list('id', 'label')) | |
156 | - for row in cursor: | |
157 | - if data['commonness']: | |
158 | - entry, form, pos, _ic, tag, _id, refl_id, cv_id = row | |
159 | - else: | |
160 | - entry, form, pos, _ic, tag, _id, refl_id = row | |
161 | - form = form.lstrip('+') # odmienne postfiksy | |
162 | - if tag == 'adja': | |
163 | - form = form.rstrip('+') | |
164 | - if tag == 'adjc': | |
165 | - if form not in ADJPREDYKATYWNE: | |
166 | - tag = "adj:sg:nom:m1.m2.m3:pos|adj:sg:acc:m3:pos" | |
167 | - if refl and pos in ('v', 'pact', 'ger'): | |
168 | - if refl_id in refls: | |
169 | - tag += ':' + REFL_TRANSLATION[refls[refl_id]] | |
170 | - else: | |
171 | - debug(entry, u'Nieznana zwrotność: %s' % refl_id) | |
172 | - if data['commonness']: | |
173 | - cv = cv_table[cv_id] if cv_id else '' | |
174 | - output_file.write((u'%s\t%s\t%s\t%s\n' % | |
175 | - (form, entry, tag, cv)).encode('utf-8')) | |
176 | - else: | |
177 | - output_file.write((u'%s\t%s\t%s\n' % | |
178 | - (form, entry, tag)).encode('utf-8')) | |
152 | + params_part = (list(data['vocabs']) + list(data['antivocabs']) + | |
153 | + [data['variant']]) | |
154 | + params = params_part + flatten(data['magic_qualifiers']) + params_part | |
155 | + cursor.execute(query, params) | |
156 | + refl = data['refl'] | |
157 | + cv_table = dict(ClassificationValue.objects.values_list('id', 'label')) | |
158 | + for row in cursor: | |
159 | + if data['commonness']: | |
160 | + entry, form, pos, _ic, tag, _id, refl_id, cv_id = row | |
161 | + else: | |
162 | + entry, form, pos, _ic, tag, _id, refl_id = row | |
163 | + form = form.lstrip('+') # odmienne postfiksy | |
164 | + if tag == 'adja': | |
165 | + form = form.rstrip('+') | |
166 | + if tag == 'adjc': | |
167 | + if form not in ADJPREDYKATYWNE: | |
168 | + tag = "adj:sg:nom:m1.m2.m3:pos|adj:sg:acc:m3:pos" | |
169 | + if refl and pos in ('v', 'pact', 'ger'): | |
170 | + if refl_id in refls: | |
171 | + tag += ':' + REFL_TRANSLATION[refls[refl_id]] | |
172 | + else: | |
173 | + debug(entry, u'Nieznana zwrotność: %s' % refl_id) | |
174 | + if data['commonness']: | |
175 | + cv = cv_table[cv_id] if cv_id else '' | |
176 | + output_file.write((u'%s\t%s\t%s\t%s\n' % | |
177 | + (form, entry, tag, cv)).encode('utf-8')) | |
178 | + else: | |
179 | + output_file.write((u'%s\t%s\t%s\n' % | |
180 | + (form, entry, tag)).encode('utf-8')) | |
... | ... |