From 9cb9270df3c479e0f266a85b363f20265dde6ad2 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Tue, 18 Sep 2012 22:37:53 +0200 Subject: [PATCH 01/19] Assignment: Fixed generating ballot pdf paper (typo: surfix). --- openslides/assignment/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 2b7ff4a71..832af4cea 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -567,8 +567,8 @@ class AssignmentPollPDF(PDFView): candidate = option.candidate cell.append(Paragraph(candidate.user.get_full_name(), stylesheet['Ballot_option_name'])) - if candidate.name_surfix: - cell.append(Paragraph("(%s)" % candidate.name_surfix, + if candidate.name_suffix: + cell.append(Paragraph("(%s)" % candidate.name_suffix, stylesheet['Ballot_option_group'])) else: cell.append(Paragraph(" ", From 12d8527255f3dff84816e496d71332d9471c6633 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Tue, 18 Sep 2012 22:40:30 +0200 Subject: [PATCH 02/19] Updated translations. --- openslides/locale/de/LC_MESSAGES/django.mo | Bin 32992 -> 33237 bytes openslides/locale/de/LC_MESSAGES/django.po | 536 +++++++++++---------- 2 files changed, 280 insertions(+), 256 deletions(-) diff --git a/openslides/locale/de/LC_MESSAGES/django.mo b/openslides/locale/de/LC_MESSAGES/django.mo index c4e9fae76280e9f976ab620238004b8d575a9d7a..454decced63ba46a5a328ba9ca4f31ae6edb2cbb 100644 GIT binary patch delta 10244 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 diff --git a/openslides/locale/de/LC_MESSAGES/django.po b/openslides/locale/de/LC_MESSAGES/django.po index c77f7c194..d863961d5 100644 --- a/openslides/locale/de/LC_MESSAGES/django.po +++ b/openslides/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSlides 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-09-11 20:48+0200\n" +"POT-Creation-Date: 2012-09-18 22:27+0200\n" "PO-Revision-Date: 2012-07-28 11:07+0200\n" "Last-Translator: Oskar Hahn \n" "Language-Team: Deutsch \n" @@ -29,19 +29,19 @@ msgstr "Englisch" msgid "Parent item" msgstr "Elternelement" -#: agenda/models.py:42 application/forms.py:22 application/models.py:540 -#: application/templates/application/view.html:249 config/forms.py:61 +#: agenda/models.py:42 application/forms.py:22 application/models.py:541 +#: application/templates/application/view.html:246 config/forms.py:61 #: projector/models.py:32 msgid "Title" msgstr "Titel" -#: agenda/models.py:43 application/forms.py:23 application/models.py:541 -#: application/templates/application/view.html:250 projector/models.py:33 +#: agenda/models.py:43 application/forms.py:23 application/models.py:542 +#: application/templates/application/view.html:247 projector/models.py:33 msgid "Text" msgstr "Text" #: agenda/models.py:44 agenda/templates/agenda/overview.html:65 -#: agenda/templates/agenda/view.html:13 participant/models.py:52 +#: agenda/templates/agenda/view.html:13 participant/models.py:53 #: participant/templates/participant/overview.html:72 msgid "Comment" msgstr "Kommentar" @@ -224,25 +224,25 @@ msgstr "Zusammenfassung für diesen Eintrag projizieren" msgid "Do you want to save the changed order of agenda items?" msgstr "Möchten Sie die geänderte Reihenfolge der Einträge speichern?" -#: agenda/templates/agenda/overview.html:46 application/models.py:574 -#: application/views.py:487 application/views.py:799 application/views.py:850 -#: application/templates/application/view.html:82 +#: agenda/templates/agenda/overview.html:46 application/models.py:575 +#: application/views.py:775 application/views.py:826 +#: application/templates/application/view.html:79 #: application/templates/projector/Application.html:37 -#: assignment/models.py:279 assignment/views.py:564 -#: assignment/templates/assignment/view.html:156 -#: assignment/templates/assignment/view.html:160 +#: assignment/models.py:297 assignment/views.py:576 +#: assignment/templates/assignment/view.html:166 +#: assignment/templates/assignment/view.html:170 #: assignment/templates/projector/Assignment.html:78 #: assignment/templates/projector/Assignment.html:82 utils/utils.py:53 #: utils/views.py:111 msgid "Yes" msgstr "Ja" -#: agenda/templates/agenda/overview.html:47 application/models.py:574 -#: application/views.py:487 application/views.py:799 application/views.py:851 -#: application/templates/application/view.html:83 +#: agenda/templates/agenda/overview.html:47 application/models.py:575 +#: application/views.py:775 application/views.py:827 +#: application/templates/application/view.html:80 #: application/templates/projector/Application.html:38 -#: assignment/models.py:279 assignment/views.py:565 -#: assignment/templates/assignment/view.html:157 +#: assignment/models.py:297 assignment/views.py:577 +#: assignment/templates/assignment/view.html:167 #: assignment/templates/projector/Assignment.html:79 utils/utils.py:53 #: utils/views.py:111 msgid "No" @@ -298,7 +298,7 @@ msgstr "Vorschau" #: agenda/templates/agenda/widget.html:23 #: application/templates/application/widget.html:11 -#: assignment/templates/assignment/view.html:120 +#: assignment/templates/assignment/view.html:130 #: assignment/templates/assignment/widget.html:11 #: projector/templates/projector/custom_slide_widget.html:24 msgid "Delete" @@ -306,15 +306,15 @@ msgstr "Löschen" #: agenda/templates/agenda/widget.html:26 #: application/templates/application/widget.html:14 -#: assignment/templates/assignment/view.html:119 +#: assignment/templates/assignment/view.html:129 #: assignment/templates/assignment/widget.html:14 #: projector/templates/projector/custom_slide_widget.html:27 msgid "Edit" msgstr "Bearbeiten" -#: application/forms.py:25 application/models.py:542 application/views.py:818 -#: application/templates/application/view.html:232 -#: application/templates/application/view.html:252 +#: application/forms.py:25 application/models.py:543 application/views.py:794 +#: application/templates/application/view.html:229 +#: application/templates/application/view.html:249 #: application/templates/projector/Application.html:77 msgid "Reason" msgstr "Begründung" @@ -327,8 +327,8 @@ msgstr "Triviale Änderung" msgid "Trivial changes don't create a new version." msgstr "Triviale Änderungen erzeugen keine neue Version." -#: application/forms.py:44 application/views.py:749 -#: application/templates/application/view.html:25 +#: application/forms.py:44 application/views.py:733 +#: application/templates/application/view.html:22 msgid "Supporters" msgstr "Unterstützer/innen" @@ -402,12 +402,12 @@ msgid "Permitted" msgstr "Zugelassen" #: application/models.py:47 application/templates/application/overview.html:24 -#: application/templates/application/view.html:170 +#: application/templates/application/view.html:167 msgid "Accepted" msgstr "Angenommen" #: application/models.py:48 application/templates/application/overview.html:25 -#: application/templates/application/view.html:175 +#: application/templates/application/view.html:172 msgid "Rejected" msgstr "Abgelehnt" @@ -415,17 +415,17 @@ msgstr "Abgelehnt" msgid "Withdrawed" msgstr "Zurückgezogen" -#: application/models.py:50 application/templates/application/view.html:183 +#: application/models.py:50 application/templates/application/view.html:180 msgid "Adjourned" msgstr "Vertagt" # please check! -#: application/models.py:51 application/templates/application/view.html:186 +#: application/models.py:51 application/templates/application/view.html:183 msgid "Not Concerned" msgstr "Nicht befasst" # please check! -#: application/models.py:52 application/templates/application/view.html:189 +#: application/models.py:52 application/templates/application/view.html:186 msgid "Commited a bill" msgstr "Verwiesen (in Ausschuss)" @@ -437,7 +437,7 @@ msgstr "Verworfen (nicht zulässig)" msgid "Needs Review" msgstr "Benötigt Review" -#: application/models.py:66 application/views.py:733 +#: application/models.py:66 application/views.py:713 #: application/templates/application/overview.html:41 #: application/templates/application/view.html:18 #: application/templates/projector/Application.html:55 @@ -508,7 +508,7 @@ msgstr "Version %s zugelassen" msgid "Version %s not authorized" msgstr "Version %s nicht zugelassen" -#: application/models.py:336 assignment/models.py:66 +#: application/models.py:336 assignment/models.py:69 #, python-format msgid "%s is not a valid status." msgstr "%s ist kein gültiger Status." @@ -535,7 +535,7 @@ msgstr "Status geändert" msgid "by" msgstr "von" -#: application/models.py:455 application/templates/application/view.html:213 +#: application/models.py:455 application/templates/application/view.html:210 #: application/templates/application/widget.html:27 #: application/templates/projector/Application.html:65 msgid "no number" @@ -567,47 +567,46 @@ msgstr "Darf Anträge unterstützen" msgid "Can manage motions" msgstr "Darf Anträge verwalten" -#: application/models.py:575 assignment/models.py:280 +#: application/models.py:576 assignment/models.py:298 msgid "Abstain" msgstr "Enthaltung" -#: application/models.py:601 -msgid "The Assembly may decide," +#: application/models.py:602 +msgid "The assembly may decide," msgstr "Die Versammlung möge beschließen," -#: application/models.py:604 +#: application/models.py:605 #: application/templates/application/base_application.html:9 #: application/templates/application/overview.html:7 #: application/templates/application/overview.html:10 msgid "Motions" msgstr "Anträge" -#: application/views.py:181 +#: application/views.py:179 msgid "You have not the necessary rights to create or edit motions." msgstr "" "Sie haben nicht die nötigen Rechte, um Anträge zu erstellen oder zu " "bearbeiten." -#: application/views.py:186 -msgid "You can not edit this motion. You are not the submitter." -msgstr "" -"Sie dürfen diesen Antrag nicht bearbeiten. Sie sind nicht der Antragsteller" +#: application/views.py:184 +msgid "You can not edit this motion." +msgstr "Sie dürfen diesen Antrag nicht bearbeiten." -#: application/views.py:249 +#: application/views.py:247 msgid "New motion was successfully created." msgstr "Neuer Antrag wurde erfolgreich angelegt." -#: application/views.py:251 +#: application/views.py:249 msgid "Motion was successfully modified." msgstr "Antrag wurde erfolgreich geändert." -#: application/views.py:258 application/views.py:657 assignment/views.py:136 -#: participant/views.py:459 participant/views.py:482 utils/views.py:210 +#: application/views.py:256 application/views.py:634 assignment/views.py:138 +#: participant/views.py:512 participant/views.py:535 utils/views.py:210 #: utils/views.py:228 utils/views.py:252 msgid "Please check the form for errors." msgstr "Bitte kontrollieren Sie das Formular nach Fehlern." -#: application/views.py:265 +#: application/views.py:263 msgid "" "Attention: Do you really want to edit this motion? The supporters will " "not be removed automatically because you can manage motions. Please " @@ -617,7 +616,7 @@ msgstr "" "werden nicht automatisch entfernt, da Sie Anträge verwalten dürfen. " "Prüfen Sie, ob die Unterstützungen noch gültig sind." -#: application/views.py:267 +#: application/views.py:265 #, python-format msgid "" "Attention: Do you really want to edit this motion? All %s supporters " @@ -626,141 +625,132 @@ msgstr "" "Wollen Sie den Antrag wirklich ändern? Alle %s Unterstützer/innen " "werden dann automatisch entfernt. Versuchen Sie diese erneut zu gewinnen." -#: application/views.py:299 +#: application/views.py:297 msgid "Motion number was successfully set." msgstr "Antragsnummer wurde erfolgreich gesetzt." -#: application/views.py:315 +#: application/views.py:313 msgid "Motion was successfully authorized." msgstr "Antrag wurde erfolgreich zugelassen." -#: application/views.py:330 +#: application/views.py:328 msgid "Motion was successfully rejected." msgstr "Antrag wurde erfolgreich verworfen." -#: application/views.py:346 +#: application/views.py:344 #, python-format msgid "Motion status was set to: %s." msgstr "Antragsstatus wurde gesetzt auf: %s." -#: application/views.py:362 +#: application/views.py:360 msgid "Motion status was reset." msgstr "Antragsstatus wurde zurückgesetzt." -#: application/views.py:376 +#: application/views.py:374 msgid "You have support the motion successfully." msgstr "Sie haben den Antrag erfolgreich unterstützt." -#: application/views.py:390 +#: application/views.py:388 msgid "You have unsupport the motion successfully." msgstr "Sie haben dem Antrag erfolgreich Ihre Unterstützung entzogen." -#: application/views.py:404 +#: application/views.py:402 msgid "New vote was successfully created." msgstr "Neue Abstimmung erfolgreich angelegt." -#: application/views.py:420 +#: application/views.py:418 msgid "Poll deleted" msgstr "Abstimmung gelöscht" -#: application/views.py:421 +#: application/views.py:419 msgid "Poll was successfully deleted." msgstr "Abstimmung wurde erfolgreich gelöscht." -#: application/views.py:423 +#: application/views.py:421 #, python-format msgid "the %s. poll" msgstr "die %s. Abstimmung" -#: application/views.py:461 application/views.py:470 +#: application/views.py:459 application/views.py:468 #, python-format msgid "You can not delete motion %s." msgstr "Sie können Antrag %s nicht löschen." -#: application/views.py:466 application/views.py:474 +#: application/views.py:464 application/views.py:472 #, python-format msgid "Motion %s was successfully deleted." msgstr "Antrag %s wurde erfolgreich gelöscht." -#: application/views.py:476 +#: application/views.py:474 msgid "Invalid request" msgstr "Ungültige Anfrage" -#: application/views.py:495 -msgid "Do you really want to delete multiple motions?" -msgstr "Wollen Sie wirklich mehrere Anträge löschen?" - -#: application/views.py:497 -#, python-format -msgid "Do you really want to delete %s?" -msgstr "Soll %s wirklich gelöscht werden?" - -#: application/views.py:521 +#: application/views.py:498 msgid "Poll was updated" msgstr "Abstimmung wurde aktualisiert" -#: application/views.py:538 +#: application/views.py:515 #, python-format msgid "Version %s accepted." msgstr "Version %s akzeptiert." -#: application/views.py:540 +#: application/views.py:517 #, python-format msgid "Do you really want to authorize version %s?" msgstr "Soll Version %s wirklich zugelassen werden?" -#: application/views.py:550 +#: application/views.py:527 #, python-format msgid "Version %s rejected." msgstr "Version %s zurückgewiesen." -#: application/views.py:552 +#: application/views.py:529 msgid "ERROR by rejecting the version." msgstr "FEHLER beim Zurückweisen der Version." -#: application/views.py:554 +#: application/views.py:531 #, python-format msgid "Do you really want to reject version %s?" msgstr "Soll Version %s wirklich zurückgewiesen werden?" -#: application/views.py:584 application/views.py:588 application/views.py:594 -#: application/views.py:597 participant/api.py:77 +#: application/views.py:561 application/views.py:565 application/views.py:571 +#: application/views.py:574 participant/api.py:76 #, python-format msgid "Ignoring malformed line %d in import file." msgstr "Fehlerhafte Zeile %d der Quelldatei wurde ignoriert." -#: application/views.py:643 +#: application/views.py:620 #, python-format msgid "%d motion was successfully imported." msgid_plural "%d motions were successfully imported." msgstr[0] "%d Antrag wurde erfolgreich importiert." msgstr[1] "%d Anträge wurden erfolgreich importiert." -#: application/views.py:646 +#: application/views.py:623 #, python-format msgid "%d motion was successfully modified." msgid_plural "%d motions were successfully modified." msgstr[0] "%d Antrag wurde erfolgreich geändert." msgstr[1] "%d Anträge wurden erfolgreich geändert." -#: application/views.py:649 +#: application/views.py:626 #, python-format msgid "%d new user was added." msgid_plural "%d new users were added." msgstr[0] "%d neuer Nutzer wurde erstellt." msgstr[1] "%d neue Nutzer wurden erstellt." -#: application/views.py:653 participant/api.py:93 +#: application/views.py:630 participant/api.py:92 msgid "Import aborted because of severe errors in the input file." msgstr "Import auf Grund von schweren Fehlern in der Quelldatei abgebrochen." -#: application/views.py:655 participant/api.py:95 +#: application/views.py:632 participant/api.py:94 msgid "Import file has wrong character encoding, only UTF-8 is supported!" msgstr "" "Die Quelldatei benutzt eine ungültige Zeichenkodierung, es wird nur UTF-8 " "wird unterstützt!" -#: application/views.py:659 +#: application/views.py:636 msgid "" "Attention: Existing motions will be modified if you import new motions with " "the same number." @@ -768,7 +758,7 @@ msgstr "" "Achtung: Existierende Anträge werden geändert wenn Sie neue Anträge mit " "identischer Nummer importieren." -#: application/views.py:660 +#: application/views.py:637 msgid "" "Attention: Importing an motions without a number multiple times will create " "duplicates." @@ -776,27 +766,31 @@ msgstr "" "Achtung: Bei mehrfachem Import eines Antrags ohne Nummer können Duplikate " "entstehen." -#: application/views.py:686 application/views.py:912 +#: application/views.py:663 application/views.py:888 msgid "Applications" msgstr "Anträge" -#: application/views.py:693 application/views.py:832 +#: application/views.py:670 application/views.py:808 msgid "Application" msgstr "Antrag" -#: application/views.py:707 application/templates/application/overview.html:84 +#: application/views.py:684 application/templates/application/overview.html:84 msgid "No motions available." msgstr "Keine Anträge vorhanden." -#: application/views.py:712 application/views.py:714 application/views.py:726 -#: application/views.py:728 +#: application/views.py:689 application/views.py:691 application/views.py:706 +#: application/views.py:708 #: application/templates/projector/Application.html:63 msgid "Motion No." msgstr "Antrag Nr." -#: application/views.py:763 application/templates/application/overview.html:20 +#: application/views.py:723 +msgid "Signature" +msgstr "" + +#: application/views.py:746 application/templates/application/overview.html:20 #: application/templates/application/overview.html:40 -#: application/templates/application/view.html:37 +#: application/templates/application/view.html:34 #: application/templates/projector/Application.html:11 #: assignment/templates/assignment/overview.html:14 #: assignment/templates/assignment/overview.html:27 @@ -806,71 +800,71 @@ msgstr "Antrag Nr." msgid "Status" msgstr "Status" -#: application/views.py:782 application/templates/application/view.html:217 -#: application/templates/application/view.html:247 config/models.py:131 +#: application/views.py:760 application/templates/application/view.html:214 +#: application/templates/application/view.html:244 config/models.py:131 #: config/templates/config/version.html:5 #: config/templates/config/version.html:8 #: config/templates/config/version.html:11 msgid "Version" msgstr "Version" -#: application/views.py:792 application/templates/application/view.html:47 -#: assignment/views.py:398 +#: application/views.py:768 application/templates/application/view.html:44 +#: assignment/views.py:410 msgid "Vote results" msgstr "Abstimmungsergebnis" -#: application/views.py:798 +#: application/views.py:774 #: application/templates/application/base_application.html:55 #: application/templates/application/poll_view.html:8 #: application/templates/application/poll_view.html:13 -#: application/templates/application/view.html:69 -#: application/templates/application/view.html:77 +#: application/templates/application/view.html:66 +#: application/templates/application/view.html:74 #: application/templates/projector/Application.html:33 msgid "Vote" msgstr "Abstimmung" -#: application/views.py:799 application/views.py:852 -#: application/templates/application/view.html:84 -#: application/templates/projector/Application.html:39 assignment/views.py:565 -#: assignment/templates/assignment/view.html:158 +#: application/views.py:775 application/views.py:828 +#: application/templates/application/view.html:81 +#: application/templates/projector/Application.html:39 assignment/views.py:577 +#: assignment/templates/assignment/view.html:168 #: assignment/templates/projector/Assignment.html:80 msgid "Abstention" msgstr "Enthaltung" -#: application/views.py:799 application/templates/application/view.html:85 +#: application/views.py:775 application/templates/application/view.html:82 #: application/templates/projector/Application.html:40 -#: assignment/templates/assignment/view.html:180 +#: assignment/templates/assignment/view.html:190 #: assignment/templates/projector/Assignment.html:101 msgid "Invalid" msgstr "Ungültig" -#: application/views.py:799 +#: application/views.py:775 #: application/templates/application/poll_view.html:35 -#: application/templates/application/view.html:87 -#: application/templates/projector/Application.html:42 assignment/views.py:449 +#: application/templates/application/view.html:84 +#: application/templates/projector/Application.html:42 assignment/views.py:461 #: assignment/templates/assignment/poll_view.html:45 -#: assignment/templates/assignment/view.html:192 -#: assignment/templates/assignment/view.html:197 +#: assignment/templates/assignment/view.html:202 +#: assignment/templates/assignment/view.html:207 #: assignment/templates/projector/Assignment.html:111 #: assignment/templates/projector/Assignment.html:117 poll/models.py:76 msgid "Votes cast" msgstr "Abgegebene Stimmen" -#: application/views.py:832 +#: application/views.py:808 msgid "Poll" msgstr "Abstimmung" -#: application/views.py:846 +#: application/views.py:822 #, python-format msgid "Application No. %s" msgstr "Antrag Nr. %s" -#: application/views.py:848 +#: application/views.py:824 #, python-format msgid "%d. Vote" msgstr "%d. Abstimmung" -#: application/views.py:905 +#: application/views.py:881 msgid "Motion settings successfully saved." msgstr "Antrags-Einstellungen wurden erfolgreich gespeichert." @@ -995,7 +989,7 @@ msgid "Number of supporters" msgstr "Anzahl der Unterstützer/innen" #: application/templates/application/overview.html:42 -#: application/templates/application/view.html:112 +#: application/templates/application/view.html:109 msgid "Creation Time" msgstr "Erstellungszeit" @@ -1006,8 +1000,8 @@ msgstr "Antrag projizieren" #: application/templates/application/poll_view.html:7 #: application/templates/application/poll_view.html:12 #: application/templates/application/view.html:7 -#: application/templates/application/view.html:209 -#: application/templates/application/view.html:228 +#: application/templates/application/view.html:206 +#: application/templates/application/view.html:225 #: application/templates/projector/Application.html:7 #: application/templates/projector/Application.html:65 msgid "Motion" @@ -1025,6 +1019,7 @@ msgstr "Mehrheit" #: application/templates/application/poll_view.html:14 #: assignment/templates/assignment/poll_view.html:12 poll/models.py:237 +#: poll/models.py:239 msgid "undocumented" msgstr "nicht erfasst" @@ -1033,13 +1028,13 @@ msgid "Option" msgstr "Wahlmöglichkeit" #: application/templates/application/poll_view.html:22 -#: assignment/models.py:282 +#: assignment/models.py:300 msgid "Votes" msgstr "Stimmen" -#: application/templates/application/poll_view.html:31 assignment/views.py:442 +#: application/templates/application/poll_view.html:31 assignment/views.py:454 #: assignment/templates/assignment/poll_view.html:35 -#: assignment/templates/assignment/view.html:175 +#: assignment/templates/assignment/view.html:185 #: assignment/templates/projector/Assignment.html:97 msgid "Invalid votes" msgstr "Ungültige Stimmen" @@ -1049,131 +1044,127 @@ msgstr "Ungültige Stimmen" msgid "Ballot paper as PDF" msgstr "Stimmzettel als PDF" -#: application/templates/application/view.html:21 -msgid "You!" -msgstr "Sie!" - -#: application/templates/application/view.html:54 -#: application/templates/application/view.html:94 +#: application/templates/application/view.html:51 +#: application/templates/application/view.html:91 msgid "New vote" msgstr "Neue Abstimmung" -#: application/templates/application/view.html:70 +#: application/templates/application/view.html:67 msgid "Edit Vote" msgstr "Abstimmung bearbeiten" -#: application/templates/application/view.html:73 +#: application/templates/application/view.html:70 msgid "Delete Vote" msgstr "Abstimmung löschen" -#: application/templates/application/view.html:102 +#: application/templates/application/view.html:99 msgid "Enter result" msgstr "Ergebnis eingeben" -#: application/templates/application/view.html:119 +#: application/templates/application/view.html:116 msgid "Withdraw" msgstr "Zurückziehen" -#: application/templates/application/view.html:127 +#: application/templates/application/view.html:124 msgid "Unsupport" msgstr "Nicht unterstützen" -#: application/templates/application/view.html:133 +#: application/templates/application/view.html:130 msgid "Support" msgstr "Unterstützen" -#: application/templates/application/view.html:139 +#: application/templates/application/view.html:136 msgid "minimum required supporters" msgstr "minimal erforderliche Unterstützer/innen" -#: application/templates/application/view.html:146 +#: application/templates/application/view.html:143 msgid "Manage motion" msgstr "Antrag Verwalten" -#: application/templates/application/view.html:149 +#: application/templates/application/view.html:146 msgid "Formal validation" msgstr "Formale Gültigkeitsprüfung" -#: application/templates/application/view.html:151 +#: application/templates/application/view.html:148 msgid "Publish" msgstr "Veröffentlichen" -#: application/templates/application/view.html:154 +#: application/templates/application/view.html:151 msgid "Permit" msgstr "Zulassen" -#: application/templates/application/view.html:157 +#: application/templates/application/view.html:154 msgid "Not permit (reject)" msgstr "Nicht zulassen (verwerfen)" -#: application/templates/application/view.html:160 +#: application/templates/application/view.html:157 msgid "Set Number" msgstr "Setze Nummer" -#: application/templates/application/view.html:167 +#: application/templates/application/view.html:164 msgid "Result after vote" msgstr "Ergebnis nach der Abstimmung" -#: application/templates/application/view.html:181 +#: application/templates/application/view.html:178 msgid "Result after debate" msgstr "Ergebnis nach der Debatte" -#: application/templates/application/view.html:192 +#: application/templates/application/view.html:189 msgid "Withdrawed by Submitter" msgstr "Zurückgezogen durch Antragsteller/in" -#: application/templates/application/view.html:197 +#: application/templates/application/view.html:194 msgid "For Administration only:" msgstr "Nur zur Administration:" -#: application/templates/application/view.html:199 +#: application/templates/application/view.html:196 msgid "Reset" msgstr "Zurücksetzen" -#: application/templates/application/view.html:222 +#: application/templates/application/view.html:219 msgid "This is not the newest version." msgstr "Dies ist nicht die neuste Version." -#: application/templates/application/view.html:222 -#: application/templates/application/view.html:224 +#: application/templates/application/view.html:219 +#: application/templates/application/view.html:221 msgid "Go to version" msgstr "Gehe zu Version" -#: application/templates/application/view.html:224 +#: application/templates/application/view.html:221 msgid "This is not the authorized version." msgstr "Dies ist nicht die zugelassene Version." -#: application/templates/application/view.html:242 +#: application/templates/application/view.html:239 msgid "Version History" msgstr "Versionshistorie" -#: application/templates/application/view.html:248 +#: application/templates/application/view.html:245 msgid "Time" msgstr "Zeit" -#: application/templates/application/view.html:259 +#: application/templates/application/view.html:256 msgid "Version authorized" msgstr "Version %d zugelassen" -#: application/templates/application/view.html:262 +#: application/templates/application/view.html:259 msgid "Permit Version" msgstr "Version zulassen" -#: application/templates/application/view.html:265 +#: application/templates/application/view.html:262 msgid "Reject Version" msgstr "Version verwerfen" -#: application/templates/application/view.html:269 +#: application/templates/application/view.html:266 msgid "Version rejected" msgstr "Version verworfen" -#: application/templates/application/view.html:279 -#: application/templates/application/view.html:286 -#: application/templates/application/view.html:293 +#: application/templates/application/view.html:276 +#: application/templates/application/view.html:283 +#: application/templates/application/view.html:290 msgid "unchanged" msgstr "unverändert" -#: application/templates/application/view.html:302 +#: application/templates/application/view.html:299 msgid "Log" msgstr "Log" @@ -1189,7 +1180,7 @@ msgstr "Abstimmungsergebnis" msgid "No poll results available." msgstr "Keine Abstimmungen vorhanden." -#: assignment/forms.py:24 assignment/models.py:54 assignment/views.py:371 +#: assignment/forms.py:24 assignment/models.py:57 assignment/views.py:383 #: assignment/templates/assignment/view.html:13 #: assignment/templates/projector/Assignment.html:21 msgid "Number of available posts" @@ -1228,79 +1219,79 @@ msgstr "Eine Stimme pro Kandidat/in." msgid "Always Yes-No-Abstain per candidate." msgstr "Ja, Nein, Enthaltung pro Kandidat/in." -#: assignment/models.py:45 assignment/templates/assignment/overview.html:15 +#: assignment/models.py:48 assignment/templates/assignment/overview.html:15 #: assignment/templates/assignment/view.html:23 msgid "Searching for candidates" msgstr "Auf Kandidatensuche" -#: assignment/models.py:46 assignment/templates/assignment/overview.html:16 +#: assignment/models.py:49 assignment/templates/assignment/overview.html:16 #: assignment/templates/assignment/view.html:25 msgid "Voting" msgstr "Im Wahlvorgang" -#: assignment/models.py:47 assignment/templates/assignment/overview.html:17 +#: assignment/models.py:50 assignment/templates/assignment/overview.html:17 #: assignment/templates/assignment/view.html:27 msgid "Finished" msgstr "Abgeschlossen" -#: assignment/models.py:50 +#: assignment/models.py:53 msgid "Name" msgstr "Name" -#: assignment/models.py:52 +#: assignment/models.py:55 msgid "Description" msgstr "Beschreibung" -#: assignment/models.py:56 +#: assignment/models.py:59 msgid "Comment on the ballot paper" msgstr "Kommentar für den Stimmzettel" -#: assignment/models.py:68 +#: assignment/models.py:71 #, python-format msgid "The assignment status is already %s." msgstr "Der Wahlstatus ist bereits %s." -#: assignment/models.py:82 +#: assignment/models.py:85 #, python-format msgid "%s is already a candidate." msgstr "%s ist bereits ein/e Kandidat/in." -#: assignment/models.py:84 assignment/views.py:192 +#: assignment/models.py:87 assignment/views.py:200 msgid "The candidate list is already closed." msgstr "Die Kandidatenliste ist bereits geschlossen." -#: assignment/models.py:90 +#: assignment/models.py:94 #, python-format msgid "%s does not want to be a candidate." msgstr "%s möchte nicht kandidieren." -#: assignment/models.py:110 +#: assignment/models.py:109 #, python-format msgid "%s is no candidate" msgstr "%s ist kein/e Kandidat/in" -#: assignment/models.py:233 +#: assignment/models.py:250 msgid "Can see assignment" msgstr "Darf Wahlen sehen" -#: assignment/models.py:235 +#: assignment/models.py:252 msgid "Can nominate another person" msgstr "Darf andere Personen für Wahlen vorschlagen" -#: assignment/models.py:236 +#: assignment/models.py:253 msgid "Can nominate themselves" msgstr "Darf selbst für Wahlen kandidieren" -#: assignment/models.py:237 +#: assignment/models.py:254 msgid "Can manage assignment" msgstr "Darf Wahlen verwalten" -#: assignment/models.py:299 +#: assignment/models.py:317 #, python-format msgid "Ballot %d" msgstr "Wahlgang %d" -#: assignment/models.py:308 assignment/views.py:328 assignment/views.py:651 +#: assignment/models.py:326 assignment/views.py:340 assignment/views.py:663 #: assignment/templates/assignment/base_assignment.html:14 #: assignment/templates/assignment/overview.html:6 #: assignment/templates/assignment/overview.html:9 @@ -1312,110 +1303,121 @@ msgstr "Wahlen" msgid "Candidate %s was nominated successfully." msgstr "Kandidat/in %s wurde erfolgreich vorgeschlagen." -#: assignment/views.py:128 +#: assignment/views.py:130 msgid "New election was successfully created." msgstr "Neue Wahl wurde erfolgreich angelegt." -#: assignment/views.py:130 +#: assignment/views.py:132 msgid "Election was successfully modified." msgstr "Wahl wurde erfolgreich geändert." -#: assignment/views.py:155 +#: assignment/views.py:157 #, python-format msgid "Election %s was successfully deleted." msgstr "Wahl %s wurde erfolgreich gelöscht." -#: assignment/views.py:168 +#: assignment/views.py:170 #, python-format msgid "Election status was set to: %s." msgstr "Wahlstatus wurde gesetzt auf: %s." -#: assignment/views.py:179 +#: assignment/views.py:181 msgid "You have set your candidature successfully." msgstr "Sie haben Ihre Kandidatur erfolgreich gesetzt." -#: assignment/views.py:196 -msgid "You have withdrawn your candidature successfully." -msgstr "Sie haben Ihre Kandidatur erfolgreich zurückgezogen." +#: assignment/views.py:197 +msgid "" +"You have withdrawn your candidature successfully. You can not be nominated " +"by other participants anymore." +msgstr "Sie haben Ihre Kandidatur erfolgreich zurückgezogen. Sie können nun " +"von anderen Teilnehmer/innen nicht mehr vorgeschlagen werden." -#: assignment/views.py:211 +#: assignment/views.py:218 #, python-format msgid "Candidate %s was withdrawn successfully." msgstr "Die Kandidatur von %s wurde erfolgreich zurückgezogen." -#: assignment/views.py:214 +#: assignment/views.py:220 +msgid "%s was unblocked successfully." +msgstr "%s wurde erfolgreich freigegeben." + +#: assignment/views.py:224 #, python-format msgid "Do you really want to withdraw %s from the election?" msgstr "Soll %s wirklich von der Wahl zurückgezogen werden?" -#: assignment/views.py:229 +#: assignment/views.py:226 +msgid "Do you really want to unblock %s from the election?" +msgstr "Soll %s wirklich für die Wahl freigegeben werden?" + +#: assignment/views.py:241 msgid "New ballot was successfully created." msgstr "Neuer Wahlgang erfolgreich angelegt." -#: assignment/views.py:261 +#: assignment/views.py:273 #, python-format msgid "Ballot ID %d does not exist." msgstr "Wahlgang-ID %d existiert nicht." -#: assignment/views.py:268 +#: assignment/views.py:280 msgid "Ballot successfully published." msgstr "Wahlgang wurde erfolgreich veröffentlicht." -#: assignment/views.py:270 +#: assignment/views.py:282 msgid "Ballot successfully unpublished." msgstr "Wahlgang wurde erfolgreich unveröffentlicht." -#: assignment/views.py:283 +#: assignment/views.py:295 msgid "not elected" msgstr "nicht gewählt" -#: assignment/views.py:286 assignment/views.py:469 +#: assignment/views.py:298 assignment/views.py:481 msgid "elected" msgstr "gewählt" -#: assignment/views.py:314 +#: assignment/views.py:326 msgid "Ballot was successfully deleted." msgstr "Abstimmung wurde erfolgreich gelöscht." -#: assignment/views.py:325 +#: assignment/views.py:337 msgid "Assignment" msgstr "Wahl" -#: assignment/views.py:346 assignment/templates/assignment/overview.html:53 +#: assignment/views.py:358 assignment/templates/assignment/overview.html:53 #: assignment/templates/assignment/widget.html:23 msgid "No assignments available." msgstr "Keine Wahlen vorhanden." -#: assignment/views.py:365 +#: assignment/views.py:377 #, python-format msgid "Election: %s" msgstr "Wahlen: %s" -#: assignment/views.py:377 assignment/views.py:410 +#: assignment/views.py:389 assignment/views.py:422 #: assignment/templates/assignment/overview.html:26 #: assignment/templates/assignment/poll_view.html:18 #: assignment/templates/assignment/view.html:36 -#: assignment/templates/assignment/view.html:108 +#: assignment/templates/assignment/view.html:118 #: assignment/templates/projector/Assignment.html:38 #: assignment/templates/projector/Assignment.html:56 msgid "Candidates" msgstr "Kandidaten/innen" -#: assignment/views.py:402 +#: assignment/views.py:414 #: assignment/templates/assignment/base_assignment.html:71 #: assignment/templates/assignment/poll_view.html:5 #: assignment/templates/assignment/poll_view.html:8 -#: assignment/templates/assignment/view.html:102 -#: assignment/templates/assignment/view.html:111 +#: assignment/templates/assignment/view.html:112 +#: assignment/templates/assignment/view.html:121 #: assignment/templates/projector/Assignment.html:59 msgid "ballot" msgstr "Wahlgang" -#: assignment/views.py:405 +#: assignment/views.py:417 msgid "ballots" msgstr "Wahlgänge" -#: assignment/views.py:431 +#: assignment/views.py:443 #, python-format msgid "" "Y: %(YES)s\n" @@ -1426,7 +1428,7 @@ msgstr "" "N: %(NO)s\n" "E: %(ABSTAIN)s" -#: assignment/views.py:508 assignment/views.py:524 +#: assignment/views.py:520 assignment/views.py:536 #: assignment/templates/assignment/overview.html:25 #: assignment/templates/assignment/poll_view.html:5 #: assignment/templates/assignment/view.html:6 @@ -1434,28 +1436,28 @@ msgstr "" msgid "Election" msgstr "Wahl" -#: assignment/views.py:530 +#: assignment/views.py:542 #, python-format msgid "%d. ballot" msgstr "%d. Wahlgang" -#: assignment/views.py:531 +#: assignment/views.py:543 #, python-format msgid "%d candidate" msgid_plural "%d candidates" msgstr[0] "%d Kandidat/in" msgstr[1] "%d Kandidaten/innen" -#: assignment/views.py:533 +#: assignment/views.py:545 #, python-format msgid "%d available posts" msgstr "%d verfügbare Posten" -#: assignment/views.py:644 +#: assignment/views.py:656 msgid "Election settings successfully saved." msgstr "Wahl-Einstellungen wurden erfolgreich gespeichert." -#: assignment/views.py:664 +#: assignment/views.py:676 msgid "Assignments" msgstr "Wahlen" @@ -1522,6 +1524,7 @@ msgid "Change status" msgstr "Status ändern" #: assignment/templates/assignment/view.html:43 +#: assignment/templates/assignment/view.html:96 msgid "Remove candidate" msgstr "Kandidate/in entfernen" @@ -1542,31 +1545,39 @@ msgstr "Selbst kandidieren" msgid "Add new participant" msgstr "Neue/n Teilnehmer/in hinzufügen" -#: assignment/templates/assignment/view.html:93 +#: assignment/templates/assignment/view.html:92 +msgid "Blocked Candidates" +msgstr "Blockierte Kandidaten/innen" + +#: assignment/templates/assignment/view.html:99 +msgid "There are no blocked candidates." +msgstr "Keine blockierten Kandidaten verfügbar." + +#: assignment/templates/assignment/view.html:103 #: assignment/templates/projector/Assignment.html:52 msgid "Election results" msgstr "Wahlergebnisse" -#: assignment/templates/assignment/view.html:116 +#: assignment/templates/assignment/view.html:126 msgid "Publish/unpublish results" msgstr "Ergebnisse veröffentlichen/unveröffentlichen" -#: assignment/templates/assignment/view.html:128 -#: assignment/templates/assignment/view.html:216 +#: assignment/templates/assignment/view.html:138 +#: assignment/templates/assignment/view.html:226 msgid "New ballot" msgstr "Neuer Wahlgang" -#: assignment/templates/assignment/view.html:143 +#: assignment/templates/assignment/view.html:153 #: assignment/templates/projector/Assignment.html:69 msgid "Candidate is elected" msgstr "Kandidat/in ist gewählt" -#: assignment/templates/assignment/view.html:162 +#: assignment/templates/assignment/view.html:172 #: assignment/templates/projector/Assignment.html:84 msgid "was not a
candidate" msgstr "war kein Kandidat" -#: assignment/templates/assignment/view.html:211 +#: assignment/templates/assignment/view.html:221 #: assignment/templates/projector/Assignment.html:126 msgid "No ballots available." msgstr "Keine Wahlgänge vorhanden." @@ -1611,7 +1622,7 @@ msgstr "Präsentationssystem für Tagesordnung, Anträge und Wahlen" msgid "Welcome" msgstr "Willkommen" -#: config/models.py:90 participant/models.py:171 +#: config/models.py:90 participant/models.py:189 msgid "Welcome to OpenSlides!" msgstr "Willkommen bei OpenSlides!" @@ -1692,145 +1703,149 @@ msgstr "System URL" msgid "Printed in PDF of first time passwords only." msgstr "Erscheint nur im PDF der Erst-Passwörter" -#: participant/models.py:28 participant/templates/participant/overview.html:25 +#: participant/forms.py:118 +msgid "Sort users by first name" +msgstr "" + +#: participant/models.py:29 participant/templates/participant/overview.html:25 msgid "Male" msgstr "Männlich" -#: participant/models.py:29 participant/templates/participant/overview.html:26 +#: participant/models.py:30 participant/templates/participant/overview.html:26 msgid "Female" msgstr "Weiblich" -#: participant/models.py:32 participant/templates/participant/overview.html:38 +#: participant/models.py:33 participant/templates/participant/overview.html:38 msgid "Delegate" msgstr "Delegierter" -#: participant/models.py:33 participant/templates/participant/overview.html:39 +#: participant/models.py:34 participant/templates/participant/overview.html:39 msgid "Observer" msgstr "Beobachter" -#: participant/models.py:34 participant/templates/participant/overview.html:40 +#: participant/models.py:35 participant/templates/participant/overview.html:40 msgid "Staff" msgstr "Mitarbeiter" -#: participant/models.py:35 participant/templates/participant/overview.html:41 +#: participant/models.py:36 participant/templates/participant/overview.html:41 msgid "Guest" msgstr "Gast" -#: participant/models.py:40 participant/templates/participant/overview.html:30 +#: participant/models.py:41 participant/templates/participant/overview.html:30 #: participant/templates/participant/overview.html:68 msgid "Category" msgstr "Kategorie" -#: participant/models.py:41 +#: participant/models.py:42 msgid "Will be shown behind the name." msgstr "Wird nach dem Namen angezeigt." -#: participant/models.py:44 participant/templates/participant/overview.html:24 +#: participant/models.py:45 participant/templates/participant/overview.html:24 msgid "Gender" msgstr "Geschlecht" -#: participant/models.py:44 participant/models.py:47 participant/models.py:50 +#: participant/models.py:45 participant/models.py:48 participant/models.py:51 msgid "Only for filter the userlist." msgstr "Nur zum Filtern der Benutzerliste." -#: participant/models.py:47 +#: participant/models.py:48 msgid "Typ" msgstr "Typ" -#: participant/models.py:49 participant/views.py:216 +#: participant/models.py:50 participant/views.py:219 #: participant/templates/participant/overview.html:45 #: participant/templates/participant/overview.html:70 msgid "Committee" msgstr "Amt" -#: participant/models.py:53 +#: participant/models.py:54 msgid "Only for notes." msgstr "Nur für Notizen." -#: participant/models.py:56 +#: participant/models.py:57 msgid "Default password" msgstr "Vorgegebenes Passwort" -#: participant/models.py:98 +#: participant/models.py:99 msgid "Can see participant" msgstr "Darf die Teilnehmer/inen sehen" -#: participant/models.py:100 +#: participant/models.py:101 msgid "Can manage participant" msgstr "Darf die Teilnehmer/inen verwalten" -#: participant/views.py:211 +#: participant/views.py:214 msgid "Participant-list" msgstr "Teilnehmerliste" -#: participant/views.py:212 +#: participant/views.py:215 msgid "List of Participants" msgstr "Teilnehmerliste" -#: participant/views.py:215 participant/templates/participant/overview.html:67 +#: participant/views.py:218 participant/templates/participant/overview.html:67 msgid "Last Name" msgstr "Nachname" -#: participant/views.py:215 participant/templates/participant/overview.html:66 +#: participant/views.py:218 participant/templates/participant/overview.html:66 msgid "First Name" msgstr "Vorname" -#: participant/views.py:215 +#: participant/views.py:218 msgid "Group" msgstr "Gruppe" -#: participant/views.py:215 participant/templates/participant/overview.html:37 +#: participant/views.py:218 participant/templates/participant/overview.html:37 #: participant/templates/participant/overview.html:69 msgid "Type" msgstr "Typ" -#: participant/views.py:244 +#: participant/views.py:247 msgid "Participant-passwords" msgstr "Teilnehmer-Passwoerter" -#: participant/views.py:262 +#: participant/views.py:269 msgid "Account for OpenSlides" msgstr "Zugang für OpenSlides" -#: participant/views.py:264 +#: participant/views.py:271 #, python-format msgid "for %s" msgstr "für %s" -#: participant/views.py:267 +#: participant/views.py:274 #, python-format msgid "User: %s" msgstr "Nutzername: %s" -#: participant/views.py:271 +#: participant/views.py:278 #, python-format msgid "Password: %s" msgstr "Passwort: %s" -#: participant/views.py:276 +#: participant/views.py:283 #, python-format msgid "URL: %s" msgstr "URL: %s" -#: participant/views.py:318 +#: participant/views.py:368 #, python-format msgid "%d new participants were successfully imported." msgstr "%d neue Teilnehmer/innen wurden erfolgreich importiert." -#: participant/views.py:329 +#: participant/views.py:379 msgid "Do you really want to reset the password?" msgstr "Soll das Passwort wirklich zurückgesetzt werden?" -#: participant/views.py:345 +#: participant/views.py:395 #, python-format msgid "The Password for %s was successfully reset." msgstr "Das Passwort für %s wurde erfolgreich zurückgesetzt." -#: participant/views.py:424 +#: participant/views.py:477 msgid "Participants settings successfully saved." msgstr "Teilnehmer/innen-Einstellungen wurden erfolgreich gespeichert." -#: participant/views.py:434 +#: participant/views.py:487 #, python-format msgid "" "Installation was successfully! Use %(user)s (password: %(password)s) for " @@ -1843,15 +1858,15 @@ msgstr "" "Sie das Passwort nach der ersten Anmeldung! Anderenfalls erscheint diese " "Meldung weiterhin für alle und ist ein Sicherheitsrisiko." -#: participant/views.py:457 +#: participant/views.py:510 msgid "User settings successfully saved." msgstr "Nutzereinstellungen wurden erfolgreich gespeichert." -#: participant/views.py:479 +#: participant/views.py:532 msgid "Password successfully changed." msgstr "Password wurde erfolgreich geändert." -#: participant/views.py:497 +#: participant/views.py:550 #: participant/templates/participant/base_participant.html:12 #: participant/templates/participant/overview.html:7 #: participant/templates/participant/overview.html:18 @@ -2172,16 +2187,16 @@ msgstr "Abmelden" msgid "You have access to the following pages:" msgstr "Sie haben Zugriff auf folgende Seiten:" -#: utils/pdf.py:225 +#: utils/pdf.py:224 msgid "%Y-%m-%d %H:%Mh" msgstr "%d.%m.%Y %H:%Mh" -#: utils/pdf.py:226 +#: utils/pdf.py:225 #, python-format msgid "Printed: %s" msgstr "Gedruckt am: %s" -#: utils/pdf.py:237 utils/pdf.py:246 +#: utils/pdf.py:236 utils/pdf.py:245 #, python-format msgid "Page %s" msgstr "Seite %s" @@ -2225,3 +2240,12 @@ msgstr "undefinierter-dateiname" #: utils/jsonfield/fields.py:21 msgid "Enter valid JSON" msgstr "Gebe valides JSON ein" + +#~ msgid "Do you really want to delete multiple motions?" +#~ msgstr "Wollen Sie wirklich mehrere Anträge löschen?" + +#~ msgid "Do you really want to delete %s?" +#~ msgstr "Soll %s wirklich gelöscht werden?" + +#~ msgid "You!" +#~ msgstr "Sie!" From 154847906902021c06c74115c6ac76859ce24ea1 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Tue, 18 Sep 2012 22:47:12 +0200 Subject: [PATCH 03/19] Fixed application and assigment ballot paper: don't use old profile object. --- openslides/application/views.py | 4 ++-- openslides/assignment/views.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openslides/application/views.py b/openslides/application/views.py index 87eca0f1a..5b8e3dcce 100644 --- a/openslides/application/views.py +++ b/openslides/application/views.py @@ -833,9 +833,9 @@ class ApplicationPollPDF(PDFView): # set number of ballot papers if ballot_papers_selection == "NUMBER_OF_DELEGATES": - number = User.objects.filter(profile__type__iexact="delegate").count() + number = User.objects.filter(type__iexact="delegate").count() elif ballot_papers_selection == "NUMBER_OF_ALL_PARTICIPANTS": - number = int(Profile.objects.count()) + number = int(User.objects.count()) else: # ballot_papers_selection == "CUSTOM_NUMBER" number = int(ballot_papers_number) number = max(1, number) diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 832af4cea..68f561c87 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -554,9 +554,9 @@ class AssignmentPollPDF(PDFView): # set number of ballot papers if ballot_papers_selection == "NUMBER_OF_DELEGATES": - number = User.objects.filter(profile__type__iexact="delegate").count() + number = User.objects.filter(type__iexact="delegate").count() elif ballot_papers_selection == "NUMBER_OF_ALL_PARTICIPANTS": - number = int(Profile.objects.count()) + number = int(User.objects.count()) else: # ballot_papers_selection == "CUSTOM_NUMBER" number = int(ballot_papers_number) number = max(1, number) From 613956b62acefaad72f2b55849d4f203976dfcc0 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Tue, 18 Sep 2012 22:55:31 +0200 Subject: [PATCH 04/19] Fixed missing blue 'candidate elected' line in assignment projector template. --- openslides/assignment/templates/projector/Assignment.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openslides/assignment/templates/projector/Assignment.html b/openslides/assignment/templates/projector/Assignment.html index 8627d6022..8a5c50b0e 100644 --- a/openslides/assignment/templates/projector/Assignment.html +++ b/openslides/assignment/templates/projector/Assignment.html @@ -63,8 +63,8 @@ {% for candidate, poll_list in vote_results.items %} - - {% if candidate in assignment.elected.all %} + + {% if candidate in assignment.elected %} @@ -72,8 +72,8 @@ {{ candidate }} {% for vote in poll_list %} - - {% if not assignment_publish_winner_results_only or candidate in assignment.elected.all %} + + {% if not assignment_publish_winner_results_only or candidate in assignment.elected %} {% if 'Yes' in vote and 'No' in vote and 'Abstain' in vote %} {{ vote.Yes }}
{{ vote.No }}
From 4cd1ad5954c030eaee573d5e760ce87553cb2747 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Wed, 19 Sep 2012 11:58:24 +0200 Subject: [PATCH 05/19] Fixed missing supporters number --- openslides/application/templates/application/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openslides/application/templates/application/overview.html b/openslides/application/templates/application/overview.html index 2291b55ac..45bc6a619 100644 --- a/openslides/application/templates/application/overview.html +++ b/openslides/application/templates/application/overview.html @@ -49,7 +49,7 @@ {% if application.number %}{{ application.number }}{% else %}-{% endif %} {{ application.public_version.title }} {% if min_supporters > 0 %} - {{ application.supporter.count }} + {{ application.count_supporters }} {% endif %} {% if application.status != "pub" %} {{ application.get_status_display }}
From 9f9ea81fc698c5ec0adfbeb06eef90328a795d3b Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Wed, 19 Sep 2012 14:16:17 +0200 Subject: [PATCH 06/19] Fixed attribute error if anonymous opens application/assignment view. --- openslides/application/models.py | 5 ++++- openslides/assignment/models.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openslides/application/models.py b/openslides/application/models.py index df1d8195f..bac0f47f0 100644 --- a/openslides/application/models.py +++ b/openslides/application/models.py @@ -164,7 +164,10 @@ class Application(models.Model, SlideMixin): yield object.person def is_supporter(self, person): - return self.applicationsupporter_set.filter(person=person).exists() + try: + return self.applicationsupporter_set.filter(person=person).exists() + except AttributeError: + return False @property def enough_supporters(self): diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index dcd8a6e15..19c9886bf 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -122,8 +122,11 @@ class Assignment(models.Model, SlideMixin): """ return True, if person is a candidate. """ - return self.assignment_candidats.filter(person=person) \ + try: + return self.assignment_candidats.filter(person=person) \ .exclude(blocked=True).exists() + except AttributeError: + return False def is_blocked(self, person): """ From a60f03aebc0a08ea724363425979107ff22855f7 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Wed, 19 Sep 2012 17:00:40 +0200 Subject: [PATCH 07/19] Fixed: Application is deleted if user clicks 'No' in confirm form. --- openslides/application/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openslides/application/views.py b/openslides/application/views.py index 5b8e3dcce..cc9b18bd5 100644 --- a/openslides/application/views.py +++ b/openslides/application/views.py @@ -466,7 +466,7 @@ class ApplicationDelete(DeleteView): elif self.object: if not 'delete' in self.object.get_allowed_actions(user=request.user): messages.error(request, _("You can not delete motion %s.") % self.object) - else: + elif self.get_answer() == 'yes': title = self.object.title self.object.delete(force=True) messages.success(request, _("Motion %s was successfully deleted.") % title) From 5b97250df2393506c082a43603de7ccacad0c240 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Thu, 20 Sep 2012 09:55:27 +0200 Subject: [PATCH 08/19] Small fix with the overlay message --- openslides/projector/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openslides/projector/views.py b/openslides/projector/views.py index 862044b97..6a71ad637 100644 --- a/openslides/projector/views.py +++ b/openslides/projector/views.py @@ -73,6 +73,7 @@ class Projector(TemplateView, AjaxMixin): except AttributeError: #TODO: It has to be an Slide.DoesNotExist data = None ajax = 'on' + active_sid = get_active_slide(True) else: data = get_slide_from_sid(sid) ajax = 'off' @@ -88,7 +89,7 @@ class Projector(TemplateView, AjaxMixin): # Projector Overlays if self.kwargs['sid'] is None: active_defs = ProjectorOverlay.objects.filter(active=True) \ - .filter(Q(sid=sid) | Q(sid=None)).values_list('def_name', + .filter(Q(sid=active_sid) | Q(sid=None)).values_list('def_name', flat=True) for receiver, response in projector_overlays.send(sender=sid, register=False, call=active_defs): From fe69973dccfa728e617365aea0de29589a6d10fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Tue, 23 Oct 2012 02:03:47 +0200 Subject: [PATCH 09/19] Change version number to 1.3a1. Insert git hash as suffix of the version number. (Ticket #388) --- openslides/__init__.py | 84 +++++++++++------------------------------- 1 file changed, 22 insertions(+), 62 deletions(-) diff --git a/openslides/__init__.py b/openslides/__init__.py index f3f4c88a3..17d119cf0 100644 --- a/openslides/__init__.py +++ b/openslides/__init__.py @@ -5,11 +5,14 @@ :license: GNU GPL, see LICENSE for more details. """ -VERSION = (1, 2, 0, 'final', 1) +VERSION = (1, 3, 0, 'alpha', 1) + def get_version(version=None): - """Derives a PEP386-compliant version number from VERSION.""" - # TODO: Get the Version Hash from GIT. + """ + Derives a PEP386-compliant version number from VERSION. Adds id of + the current git commit. + """ if version is None: version = VERSION assert len(version) == 5 @@ -17,67 +20,24 @@ def get_version(version=None): # Now build the two parts of the version number: # main = X.Y[.Z] - # sub = .devN - for pre-alpha releases - # | {a|b|c}N - for alpha, beta and rc releases + # sub = {a|b|c}N for alpha, beta and rc releases + # git's commit id is added - parts = 2 if version[2] == 0 else 3 - main = '.'.join(str(x) for x in version[:parts]) + main_parts = 2 if version[2] == 0 else 3 + main = '.'.join(str(x) for x in version[:main_parts]) - sub = '' - if version[3] == 'alpha' and version[4] == 0: - mercurial_version = hg_version() - if mercurial_version != 'unknown': - sub = '.dev%s' % mercurial_version + if version[3] != 'final': + mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'} + sub = mapping[version[3]] + str(version[4]) + try: + git_head_path = '.git/' + open('.git/HEAD', 'r').read()[5:].rstrip() + except IOError: + git_commit_id = 'unknown' else: - sub = '.dev' - - elif version[3] != 'final': - sub = "-" + version[3] + str(version[4]) + import os + git_commit_id = open(os.path.abspath(git_head_path), 'r').read().rstrip() + sub = '%s commit %s' % (sub, git_commit_id) + else: + sub = '' return main + sub - - -def hg_version(): - import socket - import os - import sys - from os.path import realpath, join, dirname - try: - from mercurial import ui as hgui - from mercurial.localrepo import localrepository - from mercurial.node import short as shorthex - from mercurial.error import RepoError - nomercurial = False - except ImportError: - return 'unknown' - - os.environ['HGRCPATH'] = '' - conts = realpath(join(dirname(__file__))) - try: - ui = hgui.ui() - repository = localrepository(ui, join(conts, '..')) - ctx = repository['.'] - if ctx.tags() and ctx.tags() != ['tip']: - version = ' '.join(ctx.tags()) - else: - version = '%(num)s:%(id)s' % { - 'num': ctx.rev(), 'id': shorthex(ctx.node()) - } - except TypeError: - version = 'unknown' - except RepoError: - return 0 - - # This value defines the timeout for sockets in seconds. Per default python - # sockets do never timeout and as such we have blocking workers. - # Socket timeouts are set globally within the whole application. - # The value *must* be a floating point value. - socket.setdefaulttimeout(10.0) - - return version - - -## import os, site -## -## SITE_ROOT = os.path.realpath(os.path.dirname(__file__)) -## site.addsitedir(SITE_ROOT) From 681d909fa383e583abf67d6d31599aeced393118 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 11:04:23 +0200 Subject: [PATCH 10/19] rename application to motion --- .../application/base_application.html | 66 -- .../templates/application/widget.html | 34 - openslides/application/urls.py | 141 ---- openslides/assignment/models.py | 2 +- openslides/config/views.py | 2 +- .../{application => motion}/__init__.py | 0 openslides/{application => motion}/forms.py | 32 +- openslides/{application => motion}/models.py | 188 +++--- .../motion/templates/motion/base_motion.html | 66 ++ .../templates/motion}/config.html | 8 +- .../templates/motion}/edit.html | 10 +- .../templates/motion}/import.html | 6 +- .../templates/motion}/overview.html | 38 +- .../templates/motion}/poll_view.html | 16 +- .../templates/motion}/view.html | 106 +-- .../motion/templates/motion/widget.html | 34 + .../templates/projector/Motion.html} | 28 +- openslides/{application => motion}/tests.py | 12 +- openslides/motion/urls.py | 141 ++++ openslides/{application => motion}/views.py | 606 +++++++++--------- openslides/openslides_global_settings.py | 2 +- .../templates/participant/config.html | 4 +- openslides/urls.py | 2 +- openslides/utils/templatetags/tags.py | 2 +- 24 files changed, 773 insertions(+), 773 deletions(-) delete mode 100644 openslides/application/templates/application/base_application.html delete mode 100644 openslides/application/templates/application/widget.html delete mode 100644 openslides/application/urls.py rename openslides/{application => motion}/__init__.py (100%) rename openslides/{application => motion}/forms.py (77%) rename openslides/{application => motion}/models.py (73%) create mode 100644 openslides/motion/templates/motion/base_motion.html rename openslides/{application/templates/application => motion/templates/motion}/config.html (67%) rename openslides/{application/templates/application => motion/templates/motion}/edit.html (83%) rename openslides/{application/templates/application => motion/templates/motion}/import.html (89%) rename openslides/{application/templates/application => motion/templates/motion}/overview.html (71%) rename openslides/{application/templates/application => motion/templates/motion}/poll_view.html (79%) rename openslides/{application/templates/application => motion/templates/motion}/view.html (64%) create mode 100644 openslides/motion/templates/motion/widget.html rename openslides/{application/templates/projector/Application.html => motion/templates/projector/Motion.html} (74%) rename openslides/{application => motion}/tests.py (77%) create mode 100644 openslides/motion/urls.py rename openslides/{application => motion}/views.py (54%) diff --git a/openslides/application/templates/application/base_application.html b/openslides/application/templates/application/base_application.html deleted file mode 100644 index c886215ef..000000000 --- a/openslides/application/templates/application/base_application.html +++ /dev/null @@ -1,66 +0,0 @@ -{% extends "base.html" %} - -{% load tags %} -{% load i18n %} -{% load staticfiles %} - -{% block submenu %} - {% url application_overview as url_applicationoverview %} -

{% trans "Motions" %}

- - - {# second submenu #} - {% if application %} -
-

{% trans "Application No." %} - {% if application.number != None %} - {{ application.number }} - {% else %} - [-] - {% endif %} -

- - {% endif %} -{% endblock %} diff --git a/openslides/application/templates/application/widget.html b/openslides/application/templates/application/widget.html deleted file mode 100644 index e41c7b370..000000000 --- a/openslides/application/templates/application/widget.html +++ /dev/null @@ -1,34 +0,0 @@ -{% load staticfiles %} -{% load i18n %} -{% load tags %} - - - diff --git a/openslides/application/urls.py b/openslides/application/urls.py deleted file mode 100644 index 3b3e83e9e..000000000 --- a/openslides/application/urls.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" - openslides.application.urls - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - URL list for the application app. - - :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. - :license: GNU GPL, see LICENSE for more details. -""" - -from django.conf.urls.defaults import url, patterns - -from openslides.application.views import (ApplicationDelete, ViewPoll, - ApplicationPDF, ApplicationPollPDF, CreateAgendaItem) - -urlpatterns = patterns('openslides.application.views', - url(r'^$', - 'overview', - name='application_overview', - ), - - url(r'^(?P\d+)/$', - 'view', - name='application_view', - ), - - url(r'^(?P\d+)/agenda/$', - CreateAgendaItem.as_view(), - name='application_create_agenda', - ), - - url(r'^(?P\d+)/newest/$', - 'view', - {'newest': True}, - name='application_view_newest', - ), - - url(r'^new/$', - 'edit', - name='application_new', - ), - - url(r'^import/$', - 'application_import', - name='application_import', - ), - - url(r'^(?P\d+)/edit/$', - 'edit', - name='application_edit', - ), - - url(r'^(?P\d+)/del/$', - ApplicationDelete.as_view(), - name='application_delete', - ), - - url(r'^del/$', - ApplicationDelete.as_view(), - { 'application_id' : None , 'application_ids' : None }, - name='application_delete', - ), - - url(r'^(?P\d+)/setnumber/$', - 'set_number', - name='application_set_number', - ), - - url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', - 'set_status', - name='application_set_status', - ), - - url(r'^(?P\d+)/permit/$', - 'permit', - name='application_permit', - ), - - url(r'^version/(?P\d+)/permit/$', - 'permit_version', - name='application_version_permit', - ), - - url(r'^version/(?P\d+)/reject/$', - 'reject_version', - name='application_version_reject', - ), - - url(r'^(?P\d+)/notpermit/$', - 'notpermit', - name='application_notpermit', - ), - - url(r'^(?P\d+)/reset/$', - 'reset', - name='application_reset', - ), - - url(r'^(?P\d+)/support/$', - 'support', - name='application_support', - ), - - url(r'^(?P\d+)/unsupport/$', - 'unsupport', - name='application_unsupport', - ), - - url(r'^(?P\d+)/gen_poll/$', - 'gen_poll', - name='application_gen_poll', - ), - - url(r'^print/$', - ApplicationPDF.as_view(), - {'application_id': None}, - name='print_applications', - ), - - url(r'^(?P\d+)/print/$', - ApplicationPDF.as_view(), - name='print_application', - ), - - url(r'^poll/(?P\d+)/print/$', - ApplicationPollPDF.as_view(), - name='print_application_poll', - ), - - url(r'^poll/(?P\d+)/$', - ViewPoll.as_view(), - name='application_poll_view', - ), - - url(r'^poll/(?P\d+)/del/$', - 'delete_poll', - name='application_poll_delete', - ), -) diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 19c9886bf..af67411a6 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -218,7 +218,7 @@ class Assignment(models.Model, SlideMixin): return self.name def delete(self): - # Remove any Agenda-Item, which is related to this application. + # Remove any Agenda-Item, which is related to this assignment. for item in Item.objects.filter(related_sid=self.sid): item.delete() super(Assignment, self).delete() diff --git a/openslides/config/views.py b/openslides/config/views.py index fc2d5037e..19b7b9953 100644 --- a/openslides/config/views.py +++ b/openslides/config/views.py @@ -67,7 +67,7 @@ class GeneralConfig(FormView): anonymous = Group.objects.get(name='Anonymous') except Group.DoesNotExist: default_perms = [u'can_see_agenda', u'can_see_projector', - u'can_see_application', u'can_see_assignment'] + u'can_see_motion', u'can_see_assignment'] anonymous = Group() anonymous.name = 'Anonymous' anonymous.save() diff --git a/openslides/application/__init__.py b/openslides/motion/__init__.py similarity index 100% rename from openslides/application/__init__.py rename to openslides/motion/__init__.py diff --git a/openslides/application/forms.py b/openslides/motion/forms.py similarity index 77% rename from openslides/application/forms.py rename to openslides/motion/forms.py index a6cc0bfad..cf144feec 100644 --- a/openslides/application/forms.py +++ b/openslides/motion/forms.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.forms + openslides.motion.forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Forms for the application app. + Forms for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -15,36 +15,36 @@ from django.utils.translation import ugettext_lazy as _, ugettext_noop from openslides.utils.forms import CssClassMixin from openslides.utils.person import PersonFormField, MultiplePersonFormField -from openslides.application.models import Application +from openslides.motion.models import Motion -class ApplicationForm(forms.Form, CssClassMixin): +class MotionForm(forms.Form, CssClassMixin): title = forms.CharField(widget=forms.TextInput(), label=_("Title")) text = forms.CharField(widget=forms.Textarea(), label=_("Text")) reason = forms.CharField(widget=forms.Textarea(), required=False, label=_("Reason")) -class ApplicationFormTrivialChanges(ApplicationForm): +class MotionFormTrivialChanges(MotionForm): trivial_change = forms.BooleanField(required=False, label=_("Trivial change"), help_text=_("Trivial changes don't create a new version.")) -class ApplicationManagerForm(forms.ModelForm, CssClassMixin): +class MotionManagerForm(forms.ModelForm, CssClassMixin): submitter = PersonFormField() class Meta: - model = Application + model = Motion exclude = ('number', 'status', 'permitted', 'log', 'supporter') -class ApplicationManagerFormSupporter(ApplicationManagerForm): +class MotionManagerFormSupporter(MotionManagerForm): # TODO: Do not show the submitter in the user-list supporter = MultiplePersonFormField(required=False, label=_("Supporters")) -class ApplicationImportForm(forms.Form, CssClassMixin): +class MotionImportForm(forms.Form, CssClassMixin): csvfile = forms.FileField( widget=forms.FileInput(attrs={'size':'50'}), label=_("CSV File"), @@ -58,7 +58,7 @@ class ApplicationImportForm(forms.Form, CssClassMixin): class ConfigForm(forms.Form, CssClassMixin): - application_min_supporters = forms.IntegerField( + motion_min_supporters = forms.IntegerField( widget=forms.TextInput(attrs={'class':'small-input'}), label=_("Number of (minimum) required supporters for a motion"), initial=4, @@ -66,12 +66,12 @@ class ConfigForm(forms.Form, CssClassMixin): max_value=8, help_text=_("Choose 0 to disable the supporting system"), ) - application_preamble = forms.CharField( + motion_preamble = forms.CharField( widget=forms.TextInput(), required=False, label=_("Motion preamble") ) - application_pdf_ballot_papers_selection = forms.ChoiceField( + motion_pdf_ballot_papers_selection = forms.ChoiceField( widget=forms.Select(), required=False, label=_("Number of ballot papers (selection)"), @@ -81,24 +81,24 @@ class ConfigForm(forms.Form, CssClassMixin): ("CUSTOM_NUMBER", _("Use the following custom number")), ] ) - application_pdf_ballot_papers_number = forms.IntegerField( + motion_pdf_ballot_papers_number = forms.IntegerField( widget=forms.TextInput(attrs={'class':'small-input'}), required=False, min_value=1, label=_("Custom number of ballot papers") ) - application_pdf_title = forms.CharField( + motion_pdf_title = forms.CharField( widget=forms.TextInput(), required=False, label=_("Title for PDF document (all motions)") ) - application_pdf_preamble = forms.CharField( + motion_pdf_preamble = forms.CharField( widget=forms.Textarea(), required=False, label=_("Preamble text for PDF document (all motions)") ) - application_allow_trivial_change = forms.BooleanField( + motion_allow_trivial_change = forms.BooleanField( label=_("Allow trivial changes"), help_text=_('Warning: Trivial changes undermine the motions ' 'autorisation system.'), diff --git a/openslides/application/models.py b/openslides/motion/models.py similarity index 73% rename from openslides/application/models.py rename to openslides/motion/models.py index bac0f47f0..4a06dc492 100644 --- a/openslides/application/models.py +++ b/openslides/motion/models.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.models + openslides.motion.models ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Models for the application app. + Models for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -34,13 +34,13 @@ from openslides.projector.models import SlideMixin from openslides.agenda.models import Item -class ApplicationSupporter(models.Model): - application = models.ForeignKey("Application") +class MotionSupporter(models.Model): + motion = models.ForeignKey("Motion") person = PersonField() -class Application(models.Model, SlideMixin): - prefix = "application" +class Motion(models.Model, SlideMixin): + prefix = "motion" STATUS = ( ('pub', _('Published')), ('per', _('Permitted')), @@ -74,10 +74,10 @@ class Application(models.Model, SlideMixin): @property def last_version(self): """ - Return last version of the application. + Return last version of the motion. """ try: - return AVersion.objects.filter(application=self).order_by('id') \ + return AVersion.objects.filter(motion=self).order_by('id') \ .reverse()[0] except IndexError: return None @@ -85,7 +85,7 @@ class Application(models.Model, SlideMixin): @property def public_version(self): """ - Return permitted, if the application was permitted, else last_version + Return permitted, if the motion was permitted, else last_version """ if self.permitted is not None: return self.permitted @@ -115,14 +115,14 @@ class Application(models.Model, SlideMixin): @property def versions(self): """ - Return a list of all versions of the application. + Return a list of all versions of the motion. """ - return AVersion.objects.filter(application=self) + return AVersion.objects.filter(motion=self) @property def creation_time(self): """ - Return the time of the creation of the application. + Return the time of the creation of the motion. """ try: return self.versions[0].time @@ -132,7 +132,7 @@ class Application(models.Model, SlideMixin): @property def notes(self): """ - Return some information of the application. + Return some information of the motion. """ note = [] if self.status == "pub" and not self.enough_supporters: @@ -146,9 +146,9 @@ class Application(models.Model, SlideMixin): @property def unpermitted_changes(self): """ - Return True if the application has unpermitted changes. + Return True if the motion has unpermitted changes. - The application has unpermitted changes, if the permitted-version + The motion has unpermitted changes, if the permitted-version is not the lastone and the lastone is not rejected. TODO: rename the property in unchecked__changes """ @@ -160,35 +160,35 @@ class Application(models.Model, SlideMixin): @property def supporters(self): - for object in self.applicationsupporter_set.all(): + for object in self.motionsupporter_set.all(): yield object.person def is_supporter(self, person): try: - return self.applicationsupporter_set.filter(person=person).exists() + return self.motionsupporter_set.filter(person=person).exists() except AttributeError: return False @property def enough_supporters(self): """ - Return True, if the application has enough supporters + Return True, if the motion has enough supporters """ - min_supporters = int(config['application_min_supporters']) + min_supporters = int(config['motion_min_supporters']) if self.status == "pub": return self.count_supporters() >= min_supporters else: return True def count_supporters(self): - return self.applicationsupporter_set.count() + return self.motionsupporter_set.count() @property def missing_supporters(self): """ Return number of missing supporters """ - min_supporters = int(config['application_min_supporters']) + min_supporters = int(config['motion_min_supporters']) delta = min_supporters - self.count_supporters() if delta > 0: return delta @@ -197,9 +197,9 @@ class Application(models.Model, SlideMixin): def save(self, user=None, nonewversion=False, trivial_change=False): """ - Save the Application, and create a new AVersion if necessary + Save the Motion, and create a new AVersion if necessary """ - super(Application, self).save() + super(Motion, self).save() if nonewversion: return last_version = self.last_version @@ -229,14 +229,14 @@ class Application(models.Model, SlideMixin): version = AVersion(title=getattr(self, 'title', ''), text=getattr(self, 'text', ''), reason=getattr(self, 'reason', ''), - application=self) + motion=self) version.save() self.writelog(_("Version %s created") % version.aid, user) - is_manager = user.has_perm('application.can_manage_application') + is_manager = user.has_perm('motion.can_manage_motion') except AttributeError: is_manager = False - supporters = self.applicationsupporter_set.all() + supporters = self.motionsupporter_set.all() if (self.status == "pub" and supporters and not is_manager): @@ -245,7 +245,7 @@ class Application(models.Model, SlideMixin): def reset(self, user): """ - Reset the application. + Reset the motion. """ self.status = "pub" self.permitted = None @@ -254,43 +254,43 @@ class Application(models.Model, SlideMixin): def support(self, person): """ - Add a Supporter to the list of supporters of the application. + Add a Supporter to the list of supporters of the motion. """ if person == self.submitter: # TODO: Use own Exception raise NameError('Supporter can not be the submitter of a ' \ - 'application.') + 'motion.') if self.permitted is not None: # TODO: Use own Exception - raise NameError('This application is already permitted.') + raise NameError('This motion is already permitted.') if not self.is_supporter(person): - ApplicationSupporter(application=self, person=person).save() + MotionSupporter(motion=self, person=person).save() self.writelog(_("Supporter: +%s") % (person)) def unsupport(self, person): """ - remove a supporter from the list of supporters of the application + remove a supporter from the list of supporters of the motion """ if self.permitted is not None: # TODO: Use own Exception - raise NameError('This application is already permitted.') + raise NameError('This motion is already permitted.') try: - object = self.applicationsupporter_set.get(person=person).delete() - except ApplicationSupporter.DoesNotExist: + object = self.motionsupporter_set.get(person=person).delete() + except MotionSupporter.DoesNotExist: pass else: self.writelog(_("Supporter: -%s") % (person)) def set_number(self, number=None, user=None): """ - Set a number for ths application. + Set a number for ths motion. """ if self.number is not None: # TODO: Use own Exception - raise NameError('This application has already a number.') + raise NameError('This motion has already a number.') if number is None: try: - number = Application.objects.aggregate(Max('number')) \ + number = Motion.objects.aggregate(Max('number')) \ ['number__max'] + 1 except TypeError: number = 1 @@ -301,7 +301,7 @@ class Application(models.Model, SlideMixin): def permit(self, user=None): """ - Change the status of this application to permit. + Change the status of this motion to permit. """ self.set_status(user, "per") aversion = self.last_version @@ -314,7 +314,7 @@ class Application(models.Model, SlideMixin): def notpermit(self, user=None): """ - Change the status of this application to 'not permitted (rejected)'. + Change the status of this motion to 'not permitted (rejected)'. """ self.set_status(user, "nop") #TODO: reject last version @@ -327,10 +327,10 @@ class Application(models.Model, SlideMixin): def set_status(self, user, status, force=False): """ - Set the status of the application. + Set the status of the motion. """ error = True - for a, b in Application.STATUS: + for a, b in Motion.STATUS: if status == a: error = False break @@ -364,25 +364,25 @@ class Application(models.Model, SlideMixin): """ actions = [] - # check if user allowed to withdraw an application + # check if user allowed to withdraw an motion if ((self.status == "pub" and self.number and user == self.submitter) or (self.status == "pub" and self.number - and user.has_perm("application.can_manage_application")) + and user.has_perm("motion.can_manage_motion")) or (self.status == "per" and user == self.submitter) or (self.status == "per" - and user.has_perm("application.can_manage_application"))): + and user.has_perm("motion.can_manage_motion"))): actions.append("wit") - #Check if the user can review the application + #Check if the user can review the motion if (self.status == "rev" and (self.submitter == user - or user.has_perm("application.can_manage_application"))): + or user.has_perm("motion.can_manage_motion"))): actions.append("pub") - # Check if the user can support and unspoort the application + # Check if the user can support and unspoort the motion if (self.status == "pub" and user != self.submitter and not self.is_supporter(user)): @@ -391,22 +391,22 @@ class Application(models.Model, SlideMixin): if self.status == "pub" and self.is_supporter(user): actions.append("unsupport") - #Check if the user can edit the application + #Check if the user can edit the motion if (user == self.submitter \ and (self.status in ('pub', 'per'))) \ - or user.has_perm("application.can_manage_application"): + or user.has_perm("motion.can_manage_motion"): actions.append("edit") - # Check if the user can delete the application (admin, manager, owner) + # Check if the user can delete the motion (admin, manager, owner) # reworked as requiered in #100 - if (user.has_perm("applicatoin.can_delete_all_applications") or - (user.has_perm("application.can_manage_application") and + if (user.has_perm("applicatoin.can_delete_all_motions") or + (user.has_perm("motion.can_manage_motion") and self.number is None) or (self.submitter == user and self.number is None)): actions.append("delete") #For the rest, all actions need the manage permission - if not user.has_perm("application.can_manage_application"): + if not user.has_perm("motion.can_manage_motion"): return actions if self.status == "pub": @@ -430,17 +430,17 @@ class Application(models.Model, SlideMixin): def delete(self, force=False): """ - Delete the application. It is not possible, if the application has + Delete the motion. It is not possible, if the motion has allready a number """ if self.number and not force: - raise NameError('The application has already a number. ' \ + raise NameError('The motion has already a number. ' \ 'You can not delete it.') for item in Item.objects.filter(related_sid=self.sid): item.delete() - super(Application, self).delete() + super(Motion, self).delete() def writelog(self, text, user=None): if not self.log: @@ -461,7 +461,7 @@ class Application(models.Model, SlideMixin): def __getattr__(self, name): """ if name is title, text, reason or time, - Return this attribute from the newest version of the application + Return this attribute from the newest version of the motion """ if name in ('title', 'text', 'reason', 'time', 'aid'): try: @@ -476,9 +476,9 @@ class Application(models.Model, SlideMixin): def gen_poll(self, user=None): """ - Generates a poll object for the application + Generates a poll object for the motion """ - poll = ApplicationPoll(application=self) + poll = MotionPoll(motion=self) poll.save() poll.set_options() self.writelog(_("Poll created"), user) @@ -486,7 +486,7 @@ class Application(models.Model, SlideMixin): @property def polls(self): - return self.applicationpoll_set.all() + return self.motionpoll_set.all() @property def results(self): @@ -510,19 +510,19 @@ class Application(models.Model, SlideMixin): """ return the slide dict """ - data = super(Application, self).slide() - data['application'] = self + data = super(Motion, self).slide() + data['motion'] = self data['title'] = self.title - data['template'] = 'projector/Application.html' + data['template'] = 'projector/Motion.html' return data def get_absolute_url(self, link='view'): if link == 'view': - return reverse('application_view', args=[str(self.id)]) + return reverse('motion_view', args=[str(self.id)]) if link == 'edit': - return reverse('application_edit', args=[str(self.id)]) + return reverse('motion_edit', args=[str(self.id)]) if link == 'delete': - return reverse('application_delete', args=[str(self.id)]) + return reverse('motion_delete', args=[str(self.id)]) def __unicode__(self): try: @@ -532,10 +532,10 @@ class Application(models.Model, SlideMixin): class Meta: permissions = ( - ('can_see_application', ugettext_noop("Can see motions")), - ('can_create_application', ugettext_noop("Can create motions")), - ('can_support_application', ugettext_noop("Can support motions")), - ('can_manage_application', ugettext_noop("Can manage motions")), + ('can_see_motion', ugettext_noop("Can see motions")), + ('can_create_motion', ugettext_noop("Can create motions")), + ('can_support_motion', ugettext_noop("Can support motions")), + ('can_manage_motion', ugettext_noop("Can manage motions")), ) ordering = ('number',) @@ -546,7 +546,7 @@ class AVersion(models.Model): reason = models.TextField(null=True, blank=True, verbose_name = _("Reason")) rejected = models.BooleanField() # = Not Permitted time = models.DateTimeField(auto_now=True) - application = models.ForeignKey(Application) + motion = models.ForeignKey(Motion) def __unicode__(self): return "%s %s" % (self.id, self.title) @@ -557,31 +557,31 @@ class AVersion(models.Model): return self._aid except AttributeError: self._aid = AVersion.objects \ - .filter(application=self.application) \ + .filter(motion=self.motion) \ .filter(id__lte=self.id).count() return self._aid -register_slidemodel(Application) +register_slidemodel(Motion) -class ApplicationVote(BaseVote): - option = models.ForeignKey('ApplicationOption') +class MotionVote(BaseVote): + option = models.ForeignKey('MotionOption') -class ApplicationOption(BaseOption): - poll = models.ForeignKey('ApplicationPoll') - vote_class = ApplicationVote +class MotionOption(BaseOption): + poll = models.ForeignKey('MotionPoll') + vote_class = MotionVote -class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast): - option_class = ApplicationOption +class MotionPoll(BasePoll, CountInvalid, CountVotesCast): + option_class = MotionOption vote_values = [ugettext_noop('Yes'), ugettext_noop('No'), ugettext_noop('Abstain')] - application = models.ForeignKey(Application) + motion = models.ForeignKey(Motion) - def get_application(self): - return self.application + def get_motion(self): + return self.motion def set_options(self): #TODO: maybe it is possible with .create() to call this without poll=self @@ -592,20 +592,20 @@ class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast): CountVotesCast.append_pollform_fields(self, fields) def get_absolute_url(self): - return reverse('application_poll_view', args=[self.id]) + return reverse('motion_poll_view', args=[self.id]) def get_ballot(self): - return self.application.applicationpoll_set.filter(id__lte=self.id).count() + return self.motion.motionpoll_set.filter(id__lte=self.id).count() -@receiver(default_config_value, dispatch_uid="application_default_config") +@receiver(default_config_value, dispatch_uid="motion_default_config") def default_config(sender, key, **kwargs): return { - 'application_min_supporters': 0, - 'application_preamble': _('The assembly may decide,'), - 'application_pdf_ballot_papers_selection': 'CUSTOM_NUMBER', - 'application_pdf_ballot_papers_number': '8', - 'application_pdf_title': _('Motions'), - 'application_pdf_preamble': '', - 'application_allow_trivial_change': False, + 'motion_min_supporters': 0, + 'motion_preamble': _('The assembly may decide,'), + 'motion_pdf_ballot_papers_selection': 'CUSTOM_NUMBER', + 'motion_pdf_ballot_papers_number': '8', + 'motion_pdf_title': _('Motions'), + 'motion_pdf_preamble': '', + 'motion_allow_trivial_change': False, }.get(key) diff --git a/openslides/motion/templates/motion/base_motion.html b/openslides/motion/templates/motion/base_motion.html new file mode 100644 index 000000000..1466bfcf2 --- /dev/null +++ b/openslides/motion/templates/motion/base_motion.html @@ -0,0 +1,66 @@ +{% extends "base.html" %} + +{% load tags %} +{% load i18n %} +{% load staticfiles %} + +{% block submenu %} + {% url motion_overview as url_motionoverview %} +

{% trans "Motions" %}

+ + + {# second submenu #} + {% if motion %} +
+

{% trans "Motion No." %} + {% if motion.number != None %} + {{ motion.number }} + {% else %} + [-] + {% endif %} +

+ + {% endif %} +{% endblock %} diff --git a/openslides/application/templates/application/config.html b/openslides/motion/templates/motion/config.html similarity index 67% rename from openslides/application/templates/application/config.html rename to openslides/motion/templates/motion/config.html index 8dd65eddf..8f2ac89b8 100644 --- a/openslides/application/templates/application/config.html +++ b/openslides/motion/templates/motion/config.html @@ -2,18 +2,18 @@ {% load i18n %} -{% block title %}{{ block.super }} – {% trans "Application settings" %}{% endblock %} +{% block title %}{{ block.super }} – {% trans "Motion settings" %}{% endblock %} {% block content %} -

{% trans "Application settings" %}

+

{% trans "Motion settings" %}

{% csrf_token %} {{ form.as_p }}

- - diff --git a/openslides/application/templates/application/edit.html b/openslides/motion/templates/motion/edit.html similarity index 83% rename from openslides/application/templates/application/edit.html rename to openslides/motion/templates/motion/edit.html index aa97ecc04..ec56a07a1 100644 --- a/openslides/application/templates/application/edit.html +++ b/openslides/motion/templates/motion/edit.html @@ -1,10 +1,10 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load i18n %} {% block title %} {{ block.super }} – - {% if application %} + {% if motion %} {% trans "Edit motion" %} {% else %} {% trans "New motion" %} @@ -12,7 +12,7 @@ {% endblock %} {% block content %} - {% if application %} + {% if motion %}

{% trans "Edit motion" %}

{% else %}

{% trans "New motion" %}

@@ -28,8 +28,8 @@ - - diff --git a/openslides/application/templates/application/import.html b/openslides/motion/templates/motion/import.html similarity index 89% rename from openslides/application/templates/application/import.html rename to openslides/motion/templates/motion/import.html index a3bf756a7..828f9a00e 100644 --- a/openslides/application/templates/application/import.html +++ b/openslides/motion/templates/motion/import.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load i18n %} @@ -22,8 +22,8 @@ - - diff --git a/openslides/application/templates/application/overview.html b/openslides/motion/templates/motion/overview.html similarity index 71% rename from openslides/application/templates/application/overview.html rename to openslides/motion/templates/motion/overview.html index 45bc6a619..8d6b92613 100644 --- a/openslides/application/templates/application/overview.html +++ b/openslides/motion/templates/motion/overview.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load tags %} {% load i18n %} @@ -28,8 +28,8 @@

- {{ applications|length }} - {% blocktrans count counter=applications|length %}motion{% plural %}motions{% endblocktrans %} + {{ motions|length }} + {% blocktrans count counter=motions|length %}motion{% plural %}motions{% endblocktrans %} @@ -42,39 +42,39 @@ - {% for app_info in applications %} - {% with application=app_info.application useractions=app_info.actions %} + {% for app_info in motions %} + {% with motion=app_info.motion useractions=app_info.actions %} - - + {% if motion.active %}activeline{% endif %}"> + + {% if min_supporters > 0 %} - + {% endif %} - - - + + diff --git a/openslides/application/templates/application/poll_view.html b/openslides/motion/templates/motion/poll_view.html similarity index 79% rename from openslides/application/templates/application/poll_view.html rename to openslides/motion/templates/motion/poll_view.html index 67facddf5..b21236f23 100644 --- a/openslides/application/templates/application/poll_view.html +++ b/openslides/motion/templates/motion/poll_view.html @@ -1,16 +1,16 @@ -{% extends 'application/base_application.html' %} +{% extends 'motion/base_motion.html' %} {% load i18n %} {% load staticfiles %} {% block title %} - {{ block.super }} – {% trans "Motion" %} "{{ application.public_version.title }}" + {{ block.super }} – {% trans "Motion" %} "{{ motion.public_version.title }}" – {{ ballot }}. {% trans "Vote" %} {% endblock %} {% block content %} -

{{ application.public_version.title }} ({% trans "Motion" %} - {{ application.number }}) – {{ ballot }}. {% trans "Vote" %}

+

{{ motion.public_version.title }} ({% trans "Motion" %} + {{ motion.number }}) – {{ ballot }}. {% trans "Vote" %}

{% trans "Special values" %}: -1 = {% trans 'majority' %}; -2 = {% trans 'undocumented' %}{% csrf_token %} {{ pre_form }} @@ -40,8 +40,8 @@ {{ post_form }}

- - @@ -54,8 +54,8 @@ - - diff --git a/openslides/application/templates/application/view.html b/openslides/motion/templates/motion/view.html similarity index 64% rename from openslides/application/templates/application/view.html rename to openslides/motion/templates/motion/view.html index bce03af57..28cf76881 100644 --- a/openslides/application/templates/application/view.html +++ b/openslides/motion/templates/motion/view.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load tags %} {% load i18n %} @@ -16,15 +16,15 @@

@@ -204,8 +204,8 @@

{{ version.title }} ({% trans "Motion" %} - {% if application.number != None %} - {{ application.number }}) + {% if motion.number != None %} + {{ motion.number }}) {% else %} [{% trans "no number" %}]) {% endif %} @@ -213,12 +213,12 @@ {% trans "Version" %} {{ version.aid }} - {% if application.public_version != application.last_version %} + {% if motion.public_version != motion.last_version %} ⋅ - {% if version == application.public_version %} - {% trans "This is not the newest version." %} {% trans "Go to version" %} {{ application.last_version.aid }}. + {% if version == motion.public_version %} + {% trans "This is not the newest version." %} {% trans "Go to version" %} {{ motion.last_version.aid }}. {% else %} - {% trans "This is not the authorized version." %} {% trans "Go to version" %} {{ application.public_version.aid }}. + {% trans "This is not the authorized version." %} {% trans "Go to version" %} {{ motion.public_version.aid }}. {% endif %} {% endif %} @@ -235,7 +235,7 @@ {% endif %} - {% if application.versions|length > 1 %} + {% if motion.versions|length > 1 %}

{% trans "Version History" %}:

{% trans "Number" %}{% trans "Creation Time" %} {% trans "Actions" %}
{% if application.number %}{{ application.number }}{% else %}-{% endif %}{{ application.public_version.title }}{% if motion.number %}{{ motion.number }}{% else %}-{% endif %}{{ motion.public_version.title }}{{ application.count_supporters }}{{ motion.count_supporters }}{% if application.status != "pub" %} - {{ application.get_status_display }}
+
{% if motion.status != "pub" %} + {{ motion.get_status_display }}
{% endif %} - {% for note in application.notes %} + {% for note in motion.notes %} {{ note }} {% if not forloop.last %}
{%endif%} {% endfor %}
{{ application.submitter }}{{ application.creation_time }}{{ motion.submitter }}{{ motion.creation_time }} {% if perms.projector.can_manage_projector %} - + {% endif %} - {% if perms.application.can_manage_application %} - + {% if perms.motion.can_manage_motion %} + {% if "delete" in useractions %} - + {% endif %} {% endif %} - +
@@ -248,18 +248,18 @@ - {% for revision in application.versions %} + {% for revision in motion.versions %}
{% trans "Reason" %}
- {% if application.status != "pub" %} - {% if revision == application.permitted %} + {% if motion.status != "pub" %} + {% if revision == motion.permitted %} {% else %} - {% if perms.application.can_manage_application %} - + {% if perms.motion.can_manage_motion %} + {% endif %} - {% if not revision.rejected and revision.id > application.permitted.id and perms.application.can_manage_application %} - + {% if not revision.rejected and revision.id > motion.permitted.id and perms.motion.can_manage_motion %} + {% endif %} {% endif %} {% if revision.rejected %} @@ -295,9 +295,9 @@
{% endif %} - {% if perms.application.can_manage_application %} + {% if perms.motion.can_manage_motion %}

{% trans "Log" %}:

- {{ application.log|linebreaks }} + {{ motion.log|linebreaks }} {% endif %} {% endblock %} diff --git a/openslides/motion/templates/motion/widget.html b/openslides/motion/templates/motion/widget.html new file mode 100644 index 000000000..0495d7ac9 --- /dev/null +++ b/openslides/motion/templates/motion/widget.html @@ -0,0 +1,34 @@ +{% load staticfiles %} +{% load i18n %} +{% load tags %} + + + diff --git a/openslides/application/templates/projector/Application.html b/openslides/motion/templates/projector/Motion.html similarity index 74% rename from openslides/application/templates/projector/Application.html rename to openslides/motion/templates/projector/Motion.html index 8f6ff6401..ab094313f 100644 --- a/openslides/application/templates/projector/Application.html +++ b/openslides/motion/templates/projector/Motion.html @@ -4,27 +4,27 @@ {% load i18n %} {% load staticfiles %} -{% block title %}{{ block.super }} - {% trans "Motion" %} {{ application.number }}{% endblock %} +{% block title %}{{ block.super }} - {% trans "Motion" %} {{ motion.number }}{% endblock %} {% block content %}

- {% if application.number != None %} - {% trans "Motion No." %} {{ application.number }} + {% if motion.number != None %} + {% trans "Motion No." %} {{ motion.number }} {% else %} {% trans "Motion" %} [{% trans "no number" %}] {% endif %}

- {{ application.public_version.title }} + {{ motion.public_version.title }}
{% endblock %} {% block scrollcontent %}

-

{{ application.public_version.text|linebreaks }}
- {% if application.public_version.reason %} +
{{ motion.public_version.text|linebreaks }}
+ {% if motion.public_version.reason %}

{% trans "Reason" %}:

- {{ application.public_version.reason|linebreaks }}
+ {{ motion.public_version.reason|linebreaks }} {% endif %}

{% endblock %} diff --git a/openslides/application/tests.py b/openslides/motion/tests.py similarity index 77% rename from openslides/application/tests.py rename to openslides/motion/tests.py index bd3ecb73a..1fb387951 100644 --- a/openslides/application/tests.py +++ b/openslides/motion/tests.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.tests + openslides.motion.tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Unit tests for the application app. + Unit tests for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -14,19 +14,19 @@ from django.test import TestCase from django.test.client import Client from openslides.participant.models import User -from openslides.application.models import Application, AVersion +from openslides.motion.models import Motion, AVersion -class ApplicationTest(TestCase): +class MotionTest(TestCase): def setUp(self): self.admin = User(username='testadmin') self.admin.save() self.anonym = User(username='testanoym') self.anonym.save() - self.app1 = Application(submitter=self.admin) + self.app1 = Motion(submitter=self.admin) self.app1.save() def refresh(self): - self.app1 = Application.objects.get(pk=self.app1.id) + self.app1 = Motion.objects.get(pk=self.app1.id) def testVersion(self): self.assertTrue(self.app1.versions.exists()) diff --git a/openslides/motion/urls.py b/openslides/motion/urls.py new file mode 100644 index 000000000..55543d615 --- /dev/null +++ b/openslides/motion/urls.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + openslides.motion.urls + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + URL list for the motion app. + + :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. + :license: GNU GPL, see LICENSE for more details. +""" + +from django.conf.urls.defaults import url, patterns + +from openslides.motion.views import (MotionDelete, ViewPoll, + MotionPDF, MotionPollPDF, CreateAgendaItem) + +urlpatterns = patterns('openslides.motion.views', + url(r'^$', + 'overview', + name='motion_overview', + ), + + url(r'^(?P\d+)/$', + 'view', + name='motion_view', + ), + + url(r'^(?P\d+)/agenda/$', + CreateAgendaItem.as_view(), + name='motion_create_agenda', + ), + + url(r'^(?P\d+)/newest/$', + 'view', + {'newest': True}, + name='motion_view_newest', + ), + + url(r'^new/$', + 'edit', + name='motion_new', + ), + + url(r'^import/$', + 'motion_import', + name='motion_import', + ), + + url(r'^(?P\d+)/edit/$', + 'edit', + name='motion_edit', + ), + + url(r'^(?P\d+)/del/$', + MotionDelete.as_view(), + name='motion_delete', + ), + + url(r'^del/$', + MotionDelete.as_view(), + { 'motion_id' : None , 'motion_ids' : None }, + name='motion_delete', + ), + + url(r'^(?P\d+)/setnumber/$', + 'set_number', + name='motion_set_number', + ), + + url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', + 'set_status', + name='motion_set_status', + ), + + url(r'^(?P\d+)/permit/$', + 'permit', + name='motion_permit', + ), + + url(r'^version/(?P\d+)/permit/$', + 'permit_version', + name='motion_version_permit', + ), + + url(r'^version/(?P\d+)/reject/$', + 'reject_version', + name='motion_version_reject', + ), + + url(r'^(?P\d+)/notpermit/$', + 'notpermit', + name='motion_notpermit', + ), + + url(r'^(?P\d+)/reset/$', + 'reset', + name='motion_reset', + ), + + url(r'^(?P\d+)/support/$', + 'support', + name='motion_support', + ), + + url(r'^(?P\d+)/unsupport/$', + 'unsupport', + name='motion_unsupport', + ), + + url(r'^(?P\d+)/gen_poll/$', + 'gen_poll', + name='motion_gen_poll', + ), + + url(r'^print/$', + MotionPDF.as_view(), + {'motion_id': None}, + name='print_motions', + ), + + url(r'^(?P\d+)/print/$', + MotionPDF.as_view(), + name='print_motion', + ), + + url(r'^poll/(?P\d+)/print/$', + MotionPollPDF.as_view(), + name='print_motion_poll', + ), + + url(r'^poll/(?P\d+)/$', + ViewPoll.as_view(), + name='motion_poll_view', + ), + + url(r'^poll/(?P\d+)/del/$', + 'delete_poll', + name='motion_poll_delete', + ), +) diff --git a/openslides/application/views.py b/openslides/motion/views.py similarity index 54% rename from openslides/application/views.py rename to openslides/motion/views.py index cc9b18bd5..9be63f5ed 100644 --- a/openslides/application/views.py +++ b/openslides/motion/views.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.views + openslides.motion.views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Views for the application app. + Views for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -55,17 +55,17 @@ from openslides.participant.models import User from openslides.agenda.models import Item -from openslides.application.models import Application, AVersion, ApplicationPoll -from openslides.application.forms import (ApplicationForm, - ApplicationFormTrivialChanges, ApplicationManagerForm, - ApplicationManagerFormSupporter, ApplicationImportForm, ConfigForm) +from openslides.motion.models import Motion, AVersion, MotionPoll +from openslides.motion.forms import (MotionForm, + MotionFormTrivialChanges, MotionManagerForm, + MotionManagerFormSupporter, MotionImportForm, ConfigForm) -@permission_required('application.can_see_application') -@template('application/overview.html') +@permission_required('motion.can_see_motion') +@template('motion/overview.html') def overview(request): """ - View all applications + View all motions """ try: sortfilter = parse_qs(request.COOKIES['votecollector_sortfilter']) @@ -84,7 +84,7 @@ def overview(request): else: sortfilter[value] = request.REQUEST[value] - query = Application.objects.all() + query = Motion.objects.all() if 'number' in sortfilter: query = query.filter(number=None) if 'status' in sortfilter: @@ -100,101 +100,101 @@ def overview(request): sort = sortfilter['sort'] query = query.order_by(sort) if sort.startswith('aversion_'): - # limit result to last version of an application - query = query.filter(aversion__id__in=[x.last_version.id for x in Application.objects.all()]) + # limit result to last version of an motion + query = query.filter(aversion__id__in=[x.last_version.id for x in Motion.objects.all()]) if 'reverse' in sortfilter: query = query.reverse() # todo: rewrite this with a .filter() if 'needsup' in sortfilter: - applications = [] - for application in query.all(): - if not application.enough_supporters: - applications.append(application) + motions = [] + for motion in query.all(): + if not motion.enough_supporters: + motions.append(motion) else: - applications = query + motions = query - if type(applications) is not list: - applications = list(query.all()) + if type(motions) is not list: + motions = list(query.all()) # not the most efficient way to do this but 'get_allowed_actions' # is not callable from within djangos templates.. - for (i, application) in enumerate(applications): + for (i, motion) in enumerate(motions): try: - applications[i] = { - 'actions' : application.get_allowed_actions(request.user), - 'application' : application + motions[i] = { + 'actions' : motion.get_allowed_actions(request.user), + 'motion' : motion } except: # todo: except what? - applications[i] = { + motions[i] = { 'actions' : [], - 'application' : application + 'motion' : motion } return { - 'applications': applications, - 'min_supporters': int(config['application_min_supporters']), + 'motions': motions, + 'min_supporters': int(config['motion_min_supporters']), } -@permission_required('application.can_see_application') -@template('application/view.html') -def view(request, application_id, newest=False): +@permission_required('motion.can_see_motion') +@template('motion/view.html') +def view(request, motion_id, newest=False): """ - View one application. + View one motion. """ - application = Application.objects.get(pk=application_id) + motion = Motion.objects.get(pk=motion_id) if newest: - version = application.last_version + version = motion.last_version else: - version = application.public_version - revisions = application.versions - actions = application.get_allowed_actions(user=request.user) + version = motion.public_version + revisions = motion.versions + actions = motion.get_allowed_actions(user=request.user) return { - 'application': application, + 'motion': motion, 'revisions': revisions, 'actions': actions, - 'min_supporters': int(config['application_min_supporters']), + 'min_supporters': int(config['motion_min_supporters']), 'version': version, - #'results': application.results + #'results': motion.results } @login_required -@template('application/edit.html') -def edit(request, application_id=None): +@template('motion/edit.html') +def edit(request, motion_id=None): """ - View a form to edit or create a application. + View a form to edit or create a motion. """ - if request.user.has_perm('application.can_manage_application'): + if request.user.has_perm('motion.can_manage_motion'): is_manager = True else: is_manager = False if not is_manager \ - and not request.user.has_perm('application.can_create_application'): + and not request.user.has_perm('motion.can_create_motion'): messages.error(request, _("You have not the necessary rights to create or edit motions.")) - return redirect(reverse('application_overview')) - if application_id is not None: - application = Application.objects.get(id=application_id) - if not 'edit' in application.get_allowed_actions(request.user): + return redirect(reverse('motion_overview')) + if motion_id is not None: + motion = Motion.objects.get(id=motion_id) + if not 'edit' in motion.get_allowed_actions(request.user): messages.error(request, _("You can not edit this motion.")) - return redirect(reverse('application_view', args=[application.id])) - actions = application.get_allowed_actions(user=request.user) + return redirect(reverse('motion_view', args=[motion.id])) + actions = motion.get_allowed_actions(user=request.user) else: - application = None + motion = None actions = None - formclass = ApplicationFormTrivialChanges \ - if config['application_allow_trivial_change'] and application_id \ - else ApplicationForm + formclass = MotionFormTrivialChanges \ + if config['motion_allow_trivial_change'] and motion_id \ + else MotionForm - managerformclass = ApplicationManagerFormSupporter \ - if config['application_min_supporters'] \ - else ApplicationManagerForm + managerformclass = MotionManagerFormSupporter \ + if config['motion_min_supporters'] \ + else MotionManagerForm if request.method == 'POST': dataform = formclass(request.POST, prefix="data") @@ -202,7 +202,7 @@ def edit(request, application_id=None): if is_manager: managerform = managerformclass(request.POST, - instance=application, + instance=motion, prefix="manager") valid = valid and managerform.is_valid() else: @@ -211,23 +211,23 @@ def edit(request, application_id=None): if valid: del_supporters = True if is_manager: - if application: # Edit application - original_supporters = list(application.supporters) + if motion: # Edit motion + original_supporters = list(motion.supporters) else: original_supporters = [] - application = managerform.save(commit=False) - elif application_id is None: - application = Application(submitter=request.user) - application.title = dataform.cleaned_data['title'] - application.text = dataform.cleaned_data['text'] - application.reason = dataform.cleaned_data['reason'] + motion = managerform.save(commit=False) + elif motion_id is None: + motion = Motion(submitter=request.user) + motion.title = dataform.cleaned_data['title'] + motion.text = dataform.cleaned_data['text'] + motion.reason = dataform.cleaned_data['reason'] try: - trivial_change = config['application_allow_trivial_change'] \ + trivial_change = config['motion_allow_trivial_change'] \ and dataform.cleaned_data['trivial_change'] except KeyError: trivial_change = False - application.save(request.user, trivial_change=trivial_change) + motion.save(request.user, trivial_change=trivial_change) if is_manager: try: new_supporters = set(managerform.cleaned_data['supporter']) @@ -235,232 +235,232 @@ def edit(request, application_id=None): # The managerform has no field for the supporters pass else: - old_supporters = set(application.supporters) + old_supporters = set(motion.supporters) # add new supporters for supporter in new_supporters.difference(old_supporters): - application.support(supporter) + motion.support(supporter) # remove old supporters for supporter in old_supporters.difference(new_supporters): - application.unsupport(supporter) + motion.unsupport(supporter) - if application_id is None: + if motion_id is None: messages.success(request, _('New motion was successfully created.')) else: messages.success(request, _('Motion was successfully modified.')) if not 'apply' in request.POST: - return redirect(reverse('application_view', args=[application.id])) - if application_id is None: - return redirect(reverse('application_edit', args=[application.id])) + return redirect(reverse('motion_view', args=[motion.id])) + if motion_id is None: + return redirect(reverse('motion_edit', args=[motion.id])) else: messages.error(request, _('Please check the form for errors.')) else: - if application_id is None: - initial = {'text': config['application_preamble']} + if motion_id is None: + initial = {'text': config['motion_preamble']} else: - if application.status == "pub" and application.supporters: - if request.user.has_perm('application.can_manage_application'): + if motion.status == "pub" and motion.supporters: + if request.user.has_perm('motion.can_manage_motion'): messages.warning(request, _("Attention: Do you really want to edit this motion? The supporters will not be removed automatically because you can manage motions. Please check if the supports are valid after your changing!")) else: - messages.warning(request, _("Attention: Do you really want to edit this motion? All %s supporters will be removed! Try to convince the supporters again.") % application.count_supporters() ) - initial = {'title': application.title, - 'text': application.text, - 'reason': application.reason} + messages.warning(request, _("Attention: Do you really want to edit this motion? All %s supporters will be removed! Try to convince the supporters again.") % motion.count_supporters() ) + initial = {'title': motion.title, + 'text': motion.text, + 'reason': motion.reason} dataform = formclass(initial=initial, prefix="data") if is_manager: - if application_id is None: + if motion_id is None: initial = {'submitter': request.user.person_id} else: - initial = {'submitter': application.submitter.person_id, - 'supporter': [supporter.person_id for supporter in application.supporters]} + initial = {'submitter': motion.submitter.person_id, + 'supporter': [supporter.person_id for supporter in motion.supporters]} managerform = managerformclass(initial=initial, - instance=application, prefix="manager") + instance=motion, prefix="manager") else: managerform = None return { 'form': dataform, 'managerform': managerform, - 'application': application, + 'motion': motion, 'actions': actions, } -@permission_required('application.can_manage_application') -@template('application/view.html') -def set_number(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def set_number(request, motion_id): """ - set a number for an application. + set a number for an motion. """ try: - Application.objects.get(pk=application_id).set_number(user=request.user) + Motion.objects.get(pk=motion_id).set_number(user=request.user) messages.success(request, _("Motion number was successfully set.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def permit(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def permit(request, motion_id): """ - permit an application. + permit an motion. """ try: - Application.objects.get(pk=application_id).permit(user=request.user) + Motion.objects.get(pk=motion_id).permit(user=request.user) messages.success(request, _("Motion was successfully authorized.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def notpermit(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def notpermit(request, motion_id): """ - reject (not permit) an application. + reject (not permit) an motion. """ try: - Application.objects.get(pk=application_id).notpermit(user=request.user) + Motion.objects.get(pk=motion_id).notpermit(user=request.user) messages.success(request, _("Motion was successfully rejected.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@template('application/view.html') -def set_status(request, application_id=None, status=None): +@template('motion/view.html') +def set_status(request, motion_id=None, status=None): """ - set a status of an application. + set a status of an motion. """ try: if status is not None: - application = Application.objects.get(pk=application_id) - application.set_status(user=request.user, status=status) - messages.success(request, _("Motion status was set to: %s.") % application.get_status_display()) - except Application.DoesNotExist: + motion = Motion.objects.get(pk=motion_id) + motion.set_status(user=request.user, status=status) + messages.success(request, _("Motion status was set to: %s.") % motion.get_status_display()) + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def reset(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def reset(request, motion_id): """ - reset an application. + reset an motion. """ try: - Application.objects.get(pk=application_id).reset(user=request.user) + Motion.objects.get(pk=motion_id).reset(user=request.user) messages.success(request, _("Motion status was reset.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_support_application') -@template('application/view.html') -def support(request, application_id): +@permission_required('motion.can_support_motion') +@template('motion/view.html') +def support(request, motion_id): """ - support an application. + support an motion. """ try: - Application.objects.get(pk=application_id).support(person=request.user) + Motion.objects.get(pk=motion_id).support(person=request.user) messages.success(request, _("You have support the motion successfully.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_support_application') -@template('application/view.html') -def unsupport(request, application_id): +@permission_required('motion.can_support_motion') +@template('motion/view.html') +def unsupport(request, motion_id): """ - unsupport an application. + unsupport an motion. """ try: - Application.objects.get(pk=application_id).unsupport(person=request.user) + Motion.objects.get(pk=motion_id).unsupport(person=request.user) messages.success(request, _("You have unsupport the motion successfully.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def gen_poll(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def gen_poll(request, motion_id): """ - gen a poll for this application. + gen a poll for this motion. """ try: - poll = Application.objects.get(pk=application_id).gen_poll(user=request.user) + poll = Motion.objects.get(pk=motion_id).gen_poll(user=request.user) messages.success(request, _("New vote was successfully created.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass # TODO: do not call poll after this excaption - return redirect(reverse('application_poll_view', args=[poll.id])) + return redirect(reverse('motion_poll_view', args=[poll.id])) -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def delete_poll(request, poll_id): """ - delete a poll from this application + delete a poll from this motion """ - poll = ApplicationPoll.objects.get(pk=poll_id) - application = poll.application - count = application.polls.filter(id__lte=poll_id).count() + poll = MotionPoll.objects.get(pk=poll_id) + motion = poll.motion + count = motion.polls.filter(id__lte=poll_id).count() if request.method == 'POST': poll.delete() - application.writelog(_("Poll deleted"), request.user) + motion.writelog(_("Poll deleted"), request.user) messages.success(request, _('Poll was successfully deleted.')) else: - del_confirm_form(request, poll, name=_("the %s. poll") % count, delete_link=reverse('application_poll_delete', args=[poll_id])) - return redirect(reverse('application_view', args=[application.id])) + del_confirm_form(request, poll, name=_("the %s. poll") % count, delete_link=reverse('motion_poll_delete', args=[poll_id])) + return redirect(reverse('motion_view', args=[motion.id])) -class ApplicationDelete(DeleteView): +class MotionDelete(DeleteView): """ - Delete one or more Applications. + Delete one or more Motions. """ - permission_required = 'application.can_manage_application' - model = Application - url = 'application_overview' + permission_required = 'motion.can_manage_motion' + model = Motion + url = 'motion_overview' def get_object(self): - self.applications = [] + self.motions = [] - if self.kwargs.get('application_id', None): + if self.kwargs.get('motion_id', None): try: - return Application.objects.get(id=int(self.kwargs['application_id'])) - except Application.DoesNotExist: + return Motion.objects.get(id=int(self.kwargs['motion_id'])) + except Motion.DoesNotExist: return None - if self.kwargs.get('application_ids', []): - for appid in self.kwargs['application_ids']: + if self.kwargs.get('motion_ids', []): + for appid in self.kwargs['motion_ids']: try: - self.applications.append(Application.objects.get(id=int(appid))) - except Application.DoesNotExist: + self.motions.append(Motion.objects.get(id=int(appid))) + except Motion.DoesNotExist: pass - if self.applications: - return self.applications[0] + if self.motions: + return self.motions[0] return None def pre_post_redirect(self, request, *args, **kwargs): self.object = self.get_object() - if len(self.applications): - for application in self.applications: - if not 'delete' in application.get_allowed_actions(user=request.user): - messages.error(request, _("You can not delete motion %s.") % application) + if len(self.motions): + for motion in self.motions: + if not 'delete' in motion.get_allowed_actions(user=request.user): + messages.error(request, _("You can not delete motion %s.") % motion) continue - title = application.title - application.delete(force=True) + title = motion.title + motion.delete(force=True) messages.success(request, _("Motion %s was successfully deleted.") % title) elif self.object: @@ -475,16 +475,16 @@ class ApplicationDelete(DeleteView): class ViewPoll(PollFormView): - permission_required = 'application.can_manage_application' - poll_class = ApplicationPoll - template_name = 'application/poll_view.html' + permission_required = 'motion.can_manage_motion' + poll_class = MotionPoll + template_name = 'motion/poll_view.html' def get_context_data(self, **kwargs): context = super(ViewPoll, self).get_context_data(**kwargs) - self.application = self.poll.get_application() - context['application'] = self.application + self.motion = self.poll.get_motion() + context['motion'] = self.motion context['ballot'] = self.poll.get_ballot() - context['actions'] = self.application.get_allowed_actions(user=self.request.user) + context['actions'] = self.motion.get_allowed_actions(user=self.request.user) return context def get_modelform_class(self): @@ -494,49 +494,49 @@ class ViewPoll(PollFormView): class ViewPollFormClass(cls): def save(self, commit = True): instance = super(ViewPollFormClass, self).save(commit) - application = instance.application - application.writelog(_("Poll was updated"), user) + motion = instance.motion + motion.writelog(_("Poll was updated"), user) return instance return ViewPollFormClass def get_success_url(self): if not 'apply' in self.request.POST: - return reverse('application_view', args=[self.poll.application.id]) + return reverse('motion_view', args=[self.poll.motion.id]) return '' -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def permit_version(request, aversion_id): aversion = AVersion.objects.get(pk=aversion_id) - application = aversion.application + motion = aversion.motion if request.method == 'POST': - application.accept_version(aversion, user=request.user) + motion.accept_version(aversion, user=request.user) messages.success(request, _("Version %s accepted.") % (aversion.aid)) else: - gen_confirm_form(request, _('Do you really want to authorize version %s?') % aversion.aid, reverse('application_version_permit', args=[aversion.id])) - return redirect(reverse('application_view', args=[application.id])) + gen_confirm_form(request, _('Do you really want to authorize version %s?') % aversion.aid, reverse('motion_version_permit', args=[aversion.id])) + return redirect(reverse('motion_view', args=[motion.id])) -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def reject_version(request, aversion_id): aversion = AVersion.objects.get(pk=aversion_id) - application = aversion.application + motion = aversion.motion if request.method == 'POST': - if application.reject_version(aversion, user=request.user): + if motion.reject_version(aversion, user=request.user): messages.success(request, _("Version %s rejected.") % (aversion.aid)) else: messages.error(request, _("ERROR by rejecting the version.") ) else: - gen_confirm_form(request, _('Do you really want to reject version %s?') % aversion.aid, reverse('application_version_reject', args=[aversion.id])) - return redirect(reverse('application_view', args=[application.id])) + gen_confirm_form(request, _('Do you really want to reject version %s?') % aversion.aid, reverse('motion_version_reject', args=[aversion.id])) + return redirect(reverse('motion_view', args=[motion.id])) -@permission_required('application.can_manage_application') -@template('application/import.html') -def application_import(request): +@permission_required('motion.can_manage_motion') +@template('motion/import.html') +def motion_import(request): if request.method == 'POST': - form = ApplicationImportForm(request.POST, request.FILES) + form = MotionImportForm(request.POST, request.FILES) if form.is_valid(): import_permitted = form.cleaned_data['import_permitted'] try: @@ -545,8 +545,8 @@ def application_import(request): request.FILES['csvfile'].seek(0) users_generated = 0 - applications_generated = 0 - applications_modified = 0 + motions_generated = 0 + motions_modified = 0 with transaction.commit_on_success(): dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline()) dialect = csv_ext.patchup(dialect) @@ -560,7 +560,7 @@ def application_import(request): except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue - form = ApplicationForm({'title': title, 'text': text, 'reason': reason}) + form = MotionForm({'title': title, 'text': text, 'reason': reason}) if not form.is_valid(): messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue @@ -594,37 +594,37 @@ def application_import(request): profile.user.set_password(profile.firstpassword) profile.save() users_generated += 1 - # create / modify the application - application = None + # create / modify the motion + motion = None if number: try: - application = Application.objects.get(number=number) - applications_modified += 1 - except Application.DoesNotExist: - application = None - if application is None: - application = Application(submitter=user) + motion = Motion.objects.get(number=number) + motions_modified += 1 + except Motion.DoesNotExist: + motion = None + if motion is None: + motion = Motion(submitter=user) if number: - application.number = number - applications_generated += 1 + motion.number = number + motions_generated += 1 - application.title = form.cleaned_data['title'] - application.text = form.cleaned_data['text'] - application.reason = form.cleaned_data['reason'] + motion.title = form.cleaned_data['title'] + motion.text = form.cleaned_data['text'] + motion.reason = form.cleaned_data['reason'] if import_permitted: - application.status = 'per' + motion.status = 'per' - application.save(user, trivial_change=True) + motion.save(user, trivial_change=True) - if applications_generated: + if motions_generated: messages.success(request, ungettext('%d motion was successfully imported.', - '%d motions were successfully imported.', applications_generated) % applications_generated) - if applications_modified: + '%d motions were successfully imported.', motions_generated) % motions_generated) + if motions_modified: messages.success(request, ungettext('%d motion was successfully modified.', - '%d motions were successfully modified.', applications_modified) % applications_modified) + '%d motions were successfully modified.', motions_modified) % motions_modified) if users_generated: messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated) - return redirect(reverse('application_overview')) + return redirect(reverse('motion_overview')) except csv.Error: message.error(request, _('Import aborted because of severe errors in the input file.')) @@ -635,7 +635,7 @@ def application_import(request): else: messages.warning(request, _("Attention: Existing motions will be modified if you import new motions with the same number.")) messages.warning(request, _("Attention: Importing an motions without a number multiple times will create duplicates.")) - form = ApplicationImportForm() + form = MotionImportForm() return { 'form': form, } @@ -645,65 +645,65 @@ class CreateAgendaItem(RedirectView): permission_required = 'agenda.can_manage_agenda' def pre_redirect(self, request, *args, **kwargs): - self.application = Application.objects.get(pk=kwargs['application_id']) - self.item = Item(related_sid=self.application.sid) + self.motion = Motion.objects.get(pk=kwargs['motion_id']) + self.item = Item(related_sid=self.motion.sid) self.item.save() def get_redirect_url(self, **kwargs): return reverse('item_overview') -class ApplicationPDF(PDFView): - permission_required = 'application.can_see_application' +class MotionPDF(PDFView): + permission_required = 'motion.can_see_motion' top_space = 0 def get_filename(self): - application_id = self.kwargs['application_id'] - if application_id is None: - filename = _("Applications") + motion_id = self.kwargs['motion_id'] + if motion_id is None: + filename = _("Motions") else: - application = Application.objects.get(id=application_id) - if application.number: - number = application.number + motion = Motion.objects.get(id=motion_id) + if motion.number: + number = motion.number else: number = "" - filename = u'%s%s' % (_("Application"), str(number)) + filename = u'%s%s' % (_("Motion"), str(number)) return filename def append_to_pdf(self, story): - application_id = self.kwargs['application_id'] - if application_id is None: #print all applications - title = config["application_pdf_title"] + motion_id = self.kwargs['motion_id'] + if motion_id is None: #print all motions + title = config["motion_pdf_title"] story.append(Paragraph(title, stylesheet['Heading1'])) - preamble = config["application_pdf_preamble"] + preamble = config["motion_pdf_preamble"] if preamble: story.append(Paragraph("%s" % preamble.replace('\r\n','
'), stylesheet['Paragraph'])) story.append(Spacer(0,0.75*cm)) - applications = Application.objects.all() - if not applications: # No applications existing + motions = Motion.objects.all() + if not motions: # No motions existing story.append(Paragraph(_("No motions available."), stylesheet['Heading3'])) - else: # Print all Applications - # List of applications - for application in applications: - if application.number: - story.append(Paragraph(_("Motion No.")+" %s: %s" % (application.number, application.title), stylesheet['Heading3'])) + else: # Print all Motions + # List of motions + for motion in motions: + if motion.number: + story.append(Paragraph(_("Motion No.")+" %s: %s" % (motion.number, motion.title), stylesheet['Heading3'])) else: - story.append(Paragraph(_("Motion No.")+"   : %s" % (application.title), stylesheet['Heading3'])) - # Applications details (each application on single page) - for application in applications: + story.append(Paragraph(_("Motion No.")+"   : %s" % (motion.title), stylesheet['Heading3'])) + # Motions details (each motion on single page) + for motion in motions: story.append(PageBreak()) - story = self.get_application(application, story) - else: # print selected application - application = Application.objects.get(id=application_id) - story = self.get_application(application, story) + story = self.get_motion(motion, story) + else: # print selected motion + motion = Motion.objects.get(id=motion_id) + story = self.get_motion(motion, story) - def get_application(self, application, story): + def get_motion(self, motion, story): # Preparing Table data = [] - # application number - if application.number: - story.append(Paragraph(_("Motion No.")+" %s" % application.number, stylesheet['Heading1'])) + # motion number + if motion.number: + story.append(Paragraph(_("Motion No.")+" %s" % motion.number, stylesheet['Heading1'])) else: story.append(Paragraph(_("Motion No."), stylesheet['Heading1'])) @@ -713,10 +713,10 @@ class ApplicationPDF(PDFView): cell1a.append(Paragraph("%s:" % _("Submitter"), stylesheet['Heading4'])) cell1b = [] cell1b.append(Spacer(0, 0.2 * cm)) - cell1b.append(Paragraph("%s" % application.submitter, stylesheet['Normal'])) + cell1b.append(Paragraph("%s" % motion.submitter, stylesheet['Normal'])) data.append([cell1a, cell1b]) - if application.status == "pub": + if motion.status == "pub": # Cell for the signature cell2a = [] cell2b = [] @@ -727,14 +727,14 @@ class ApplicationPDF(PDFView): data.append([cell2a, cell2b]) # supporters - if config['application_min_supporters']: + if config['motion_min_supporters']: cell3a = [] cell3b = [] cell3a.append(Paragraph("%s:" % _("Supporters"), stylesheet['Heading4'])) - for supporter in application.supporters: + for supporter in motion.supporters: cell3b.append(Paragraph(".  %s" % supporter, stylesheet['Signaturefield'])) - if application.status == "pub": - for x in range(application.missing_supporters): + if motion.status == "pub": + for x in range(motion.missing_supporters): cell3b.append(Paragraph(".  __________________________________________",stylesheet['Signaturefield'])) cell3b.append(Spacer(0, 0.2 * cm)) data.append([cell3a, cell3b]) @@ -742,27 +742,27 @@ class ApplicationPDF(PDFView): # status cell4a = [] cell4b = [] - note = " ".join(application.notes) + note = " ".join(motion.notes) cell4a.append(Paragraph("%s:" % _("Status"), stylesheet['Heading4'])) if note != "": - if application.status == "pub": + if motion.status == "pub": cell4b.append(Paragraph(note, stylesheet['Normal'])) else: - cell4b.append(Paragraph("%s | %s" % (application.get_status_display(), note), stylesheet['Normal'])) + cell4b.append(Paragraph("%s | %s" % (motion.get_status_display(), note), stylesheet['Normal'])) else: - cell4b.append(Paragraph("%s" % application.get_status_display(), stylesheet['Normal'])) + cell4b.append(Paragraph("%s" % motion.get_status_display(), stylesheet['Normal'])) data.append([cell4a, cell4b]) # Version number (aid) - if application.public_version.aid > 1: + if motion.public_version.aid > 1: cell5a = [] cell5b = [] cell5a.append(Paragraph("%s:" % _("Version"), stylesheet['Heading4'])) - cell5b.append(Paragraph("%s" % application.public_version.aid, stylesheet['Normal'])) + cell5b.append(Paragraph("%s" % motion.public_version.aid, stylesheet['Normal'])) data.append([cell5a, cell5b]) # voting results - poll_results = application.get_poll_results() + poll_results = motion.get_poll_results() if poll_results: cell6a = [] cell6a.append(Paragraph("%s:" % _("Vote results"), stylesheet['Heading4'])) @@ -786,26 +786,26 @@ class ApplicationPDF(PDFView): story.append(Spacer(0, 1 * cm)) # title - story.append(Paragraph(application.public_version.title, stylesheet['Heading3'])) + story.append(Paragraph(motion.public_version.title, stylesheet['Heading3'])) # text - story.append(Paragraph("%s" % application.public_version.text.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % motion.public_version.text.replace('\r\n','
'), stylesheet['Paragraph'])) # reason - if application.public_version.reason: + if motion.public_version.reason: story.append(Paragraph(_("Reason")+":", stylesheet['Heading3'])) - story.append(Paragraph("%s" % application.public_version.reason.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % motion.public_version.reason.replace('\r\n','
'), stylesheet['Paragraph'])) return story -class ApplicationPollPDF(PDFView): - permission_required = 'application.can_manage_application' +class MotionPollPDF(PDFView): + permission_required = 'motion.can_manage_motion' top_space = 0 def get(self, request, *args, **kwargs): - self.poll = ApplicationPoll.objects.get(id=self.kwargs['poll_id']) - return super(ApplicationPollPDF, self).get(request, *args, **kwargs) + self.poll = MotionPoll.objects.get(id=self.kwargs['poll_id']) + return super(MotionPollPDF, self).get(request, *args, **kwargs) def get_filename(self): - filename = u'%s%s_%s' % (_("Application"), str(self.poll.application.number), _("Poll")) + filename = u'%s%s_%s' % (_("Motion"), str(self.poll.motion.number), _("Poll")) return filename def get_template(self, buffer): @@ -819,8 +819,8 @@ class ApplicationPollPDF(PDFView): circle = "  " % imgpath cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(_("Application No. %s") % self.poll.application.number, stylesheet['Ballot_title'])) - cell.append(Paragraph(self.poll.application.title, stylesheet['Ballot_subtitle'])) + cell.append(Paragraph(_("Motion No. %s") % self.poll.motion.number, stylesheet['Ballot_title'])) + cell.append(Paragraph(self.poll.motion.title, stylesheet['Ballot_subtitle'])) cell.append(Paragraph(_("%d. Vote") % self.poll.get_ballot(), stylesheet['Ballot_description'])) cell.append(Spacer(0,0.5*cm)) cell.append(Paragraph(circle + unicode(_("Yes")), stylesheet['Ballot_option'])) @@ -828,8 +828,8 @@ class ApplicationPollPDF(PDFView): cell.append(Paragraph(circle + unicode(_("Abstention")), stylesheet['Ballot_option'])) data= [] # get ballot papers config values - ballot_papers_selection = config["application_pdf_ballot_papers_selection"] - ballot_papers_number = config["application_pdf_ballot_papers_number"] + ballot_papers_selection = config["motion_pdf_ballot_papers_selection"] + ballot_papers_number = config["motion_pdf_ballot_papers_number"] # set number of ballot papers if ballot_papers_selection == "NUMBER_OF_DELEGATES": @@ -857,37 +857,37 @@ class ApplicationPollPDF(PDFView): class Config(FormView): permission_required = 'config.can_manage_config' form_class = ConfigForm - template_name = 'application/config.html' + template_name = 'motion/config.html' def get_initial(self): return { - 'application_min_supporters': config['application_min_supporters'], - 'application_preamble': config['application_preamble'], - 'application_pdf_ballot_papers_selection': config['application_pdf_ballot_papers_selection'], - 'application_pdf_ballot_papers_number': config['application_pdf_ballot_papers_number'], - 'application_pdf_title': config['application_pdf_title'], - 'application_pdf_preamble': config['application_pdf_preamble'], - 'application_allow_trivial_change': config['application_allow_trivial_change'], + 'motion_min_supporters': config['motion_min_supporters'], + 'motion_preamble': config['motion_preamble'], + 'motion_pdf_ballot_papers_selection': config['motion_pdf_ballot_papers_selection'], + 'motion_pdf_ballot_papers_number': config['motion_pdf_ballot_papers_number'], + 'motion_pdf_title': config['motion_pdf_title'], + 'motion_pdf_preamble': config['motion_pdf_preamble'], + 'motion_allow_trivial_change': config['motion_allow_trivial_change'], } def form_valid(self, form): - config['application_min_supporters'] = form.cleaned_data['application_min_supporters'] - config['application_preamble'] = form.cleaned_data['application_preamble'] - config['application_pdf_ballot_papers_selection'] = form.cleaned_data['application_pdf_ballot_papers_selection'] - config['application_pdf_ballot_papers_number'] = form.cleaned_data['application_pdf_ballot_papers_number'] - config['application_pdf_title'] = form.cleaned_data['application_pdf_title'] - config['application_pdf_preamble'] = form.cleaned_data['application_pdf_preamble'] - config['application_allow_trivial_change'] = form.cleaned_data['application_allow_trivial_change'] + config['motion_min_supporters'] = form.cleaned_data['motion_min_supporters'] + config['motion_preamble'] = form.cleaned_data['motion_preamble'] + config['motion_pdf_ballot_papers_selection'] = form.cleaned_data['motion_pdf_ballot_papers_selection'] + config['motion_pdf_ballot_papers_number'] = form.cleaned_data['motion_pdf_ballot_papers_number'] + config['motion_pdf_title'] = form.cleaned_data['motion_pdf_title'] + config['motion_pdf_preamble'] = form.cleaned_data['motion_pdf_preamble'] + config['motion_allow_trivial_change'] = form.cleaned_data['motion_allow_trivial_change'] messages.success(self.request, _('Motion settings successfully saved.')) return super(Config, self).form_valid(form) def register_tab(request): - selected = True if request.path.startswith('/application/') else False + selected = True if request.path.startswith('/motion/') else False return Tab( - title=_('Applications'), - url=reverse('application_overview'), - permission=request.user.has_perm('application.can_see_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_manage_application'), + title=_('Motions'), + url=reverse('motion_overview'), + permission=request.user.has_perm('motion.can_see_motion') or request.user.has_perm('motion.can_support_motion') or request.user.has_perm('motion.can_support_motion') or request.user.has_perm('motion.can_manage_motion'), selected=selected, ) @@ -895,7 +895,7 @@ def register_tab(request): def get_widgets(request): return [ Widget( - name='applications', - template='application/widget.html', - context={'applications': Application.objects.all()}, - permission_required='application.can_manage_application')] + name='motions', + template='motion/widget.html', + context={'motions': Motion.objects.all()}, + permission_required='motion.can_manage_motion')] diff --git a/openslides/openslides_global_settings.py b/openslides/openslides_global_settings.py index 1da9f28fe..5d3348e9c 100644 --- a/openslides/openslides_global_settings.py +++ b/openslides/openslides_global_settings.py @@ -119,7 +119,7 @@ INSTALLED_APPS = ( 'openslides.poll', 'openslides.projector', 'openslides.agenda', - 'openslides.application', + 'openslides.motion', 'openslides.assignment', 'openslides.participant', 'openslides.config', diff --git a/openslides/participant/templates/participant/config.html b/openslides/participant/templates/participant/config.html index 83a33eae2..1a68ca591 100644 --- a/openslides/participant/templates/participant/config.html +++ b/openslides/participant/templates/participant/config.html @@ -12,8 +12,8 @@ - - diff --git a/openslides/urls.py b/openslides/urls.py index 0a21c503e..ce763b3f2 100644 --- a/openslides/urls.py +++ b/openslides/urls.py @@ -26,7 +26,7 @@ urlpatterns = patterns('', (r'^$', FrontPage.as_view()), (r'^agenda/', include('openslides.agenda.urls')), - (r'^application/', include('openslides.application.urls')), + (r'^motion/', include('openslides.motion.urls')), (r'^assignment/', include('openslides.assignment.urls')), (r'^participant/', include('openslides.participant.urls')), (r'^config/', include('openslides.config.urls')), diff --git a/openslides/utils/templatetags/tags.py b/openslides/utils/templatetags/tags.py index 187c900f3..96809af10 100644 --- a/openslides/utils/templatetags/tags.py +++ b/openslides/utils/templatetags/tags.py @@ -18,7 +18,7 @@ register = template.Library() @register.simple_tag def get_min_supporters(): - return config['application_min_supporters'] + return config['motion_min_supporters'] @register.simple_tag From 17afa3c5d11dd2ee74175a021bdf4f81bfdbd195 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 11:35:07 +0200 Subject: [PATCH 11/19] fixed #326 whitespace in allready used names --- openslides/participant/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openslides/participant/api.py b/openslides/participant/api.py index 05b5c8bf4..3e5856391 100644 --- a/openslides/participant/api.py +++ b/openslides/participant/api.py @@ -47,7 +47,7 @@ def gen_username(first_name, last_name): i = 0 while True: i += 1 - testname = "%s%s%s" % (first_name, last_name, i) + testname = "%s %s %s" % (first_name, last_name, i) try: User.objects.get(username=testname) except User.DoesNotExist: From c58d47815133f286f27de2f498c17ac691e184cd Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 11:39:27 +0200 Subject: [PATCH 12/19] rename render_to_forbitten to render_to_forbidden. #370 --- openslides/utils/utils.py | 4 ++-- openslides/utils/views.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openslides/utils/utils.py b/openslides/utils/utils.py index 6d14b35a6..41aaf7544 100644 --- a/openslides/utils/utils.py +++ b/openslides/utils/utils.py @@ -101,13 +101,13 @@ def permission_required(perm, login_url=None): if request.user.has_perm(perm): return func(request, *args, **kw) if request.user.is_authenticated(): - return render_to_forbitten(request) + return render_to_forbidden(request) return redirect(reverse('user_login')) return wrapper return renderer -def render_to_forbitten(request, error= +def render_to_forbidden(request, error= ugettext_lazy("Sorry, you have no rights to see this page.")): return HttpResponseForbidden(render_to_string('403.html', {'error': error}, context_instance=RequestContext(request))) diff --git a/openslides/utils/views.py b/openslides/utils/views.py index becdbfc8b..be40f9062 100644 --- a/openslides/utils/views.py +++ b/openslides/utils/views.py @@ -52,7 +52,7 @@ from django.views.generic.list import TemplateResponseMixin from openslides.config.models import config -from openslides.utils.utils import render_to_forbitten, html_strong +from openslides.utils.utils import render_to_forbidden, html_strong from openslides.utils.signals import template_manipulation from openslides.utils.pdf import firstPage, laterPages @@ -93,7 +93,7 @@ class PermissionMixin(object): return HttpResponseRedirect("%s?next=%s" % (settings.LOGIN_URL, path)) else: - return render_to_forbitten(request) + return render_to_forbidden(request) return _View.dispatch(self, request, *args, **kwargs) From f99fdc69817cb1931371fc6f38323b3237cbd468 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 12:00:51 +0200 Subject: [PATCH 13/19] fixed inital_data --- initial_data.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/initial_data.json b/initial_data.json index 5f7c8e30c..9b25d1a34 100644 --- a/initial_data.json +++ b/initial_data.json @@ -11,14 +11,14 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ "can_nominate_other", @@ -60,19 +60,19 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ - "can_support_application", - "application", - "application" + "can_support_motion", + "motion", + "motion" ], [ "can_nominate_other", @@ -119,19 +119,19 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_manage_application", - "application", - "application" + "can_manage_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ "can_manage_assignment", From 3e1938941fa8a2e7bcd063fc05892b6a67691c56 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 12:15:29 +0200 Subject: [PATCH 14/19] Append a default class for the person-api. Also fixed the assignment-ballot-paper for group-persons --- openslides/assignment/views.py | 8 ++++---- openslides/participant/models.py | 15 ++++++++------ openslides/utils/person/__init__.py | 3 ++- openslides/utils/person/api.py | 31 +++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 68f561c87..a65d10997 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -430,7 +430,7 @@ class AssignmentPDF(PDFView): for candidate, poll_list in vote_results.iteritems(): row = [] - candidate_string = candidate.user.get_full_name() + candidate_string = candidate.clean_name if candidate in elected_candidates: candidate_string = "* " + candidate_string if candidate.category: @@ -565,7 +565,7 @@ class AssignmentPollPDF(PDFView): if self.poll.yesnoabstain: for option in options: candidate = option.candidate - cell.append(Paragraph(candidate.user.get_full_name(), + cell.append(Paragraph(candidate.clean_name, stylesheet['Ballot_option_name'])) if candidate.name_suffix: cell.append(Paragraph("(%s)" % candidate.name_suffix, @@ -591,9 +591,9 @@ class AssignmentPollPDF(PDFView): else: for option in options: candidate = option.candidate - cell.append(Paragraph(circle + candidate.user.get_full_name(), + cell.append(Paragraph(circle + candidate.clean_name, stylesheet['Ballot_option_name'])) - if candidate.category: + if candidate.name_suffix: cell.append(Paragraph("(%s)" % candidate.category, stylesheet['Ballot_option_group_right'])) else: diff --git a/openslides/participant/models.py b/openslides/participant/models.py index 42b965f69..2cce07709 100644 --- a/openslides/participant/models.py +++ b/openslides/participant/models.py @@ -16,14 +16,14 @@ from django.db.models import signals from django.dispatch import receiver from django.utils.translation import ugettext_lazy as _, ugettext_noop -from openslides.utils.person import PersonMixin +from openslides.utils.person import PersonMixin, Person from openslides.utils.person.signals import receive_persons from openslides.config.models import config from openslides.config.signals import default_config_value -class User(DjangoUser, PersonMixin): +class User(DjangoUser, PersonMixin, Person): person_prefix = 'user' GENDER_CHOICES = ( ('male', _('Male')), @@ -56,6 +56,10 @@ class User(DjangoUser, PersonMixin): max_length=100, null=True, blank=True, verbose_name=_("Default password")) + @property + def clean_name(self): + return self.get_full_name() or self.username + def get_name_suffix(self): return self.category @@ -88,10 +92,9 @@ class User(DjangoUser, PersonMixin): return ('user_delete', [str(self.id)]) def __unicode__(self): - name = self.get_full_name() or self.username if self.name_suffix: - return u"%s (%s)" % (name, self.name_suffix) - return u"%s" % name + return u"%s (%s)" % (self.clean_name, self.name_suffix) + return u"%s" % self.clean_name class Meta: # Rename permissions @@ -103,7 +106,7 @@ class User(DjangoUser, PersonMixin): ordering = ('last_name',) -class Group(DjangoGroup, PersonMixin): +class Group(DjangoGroup, PersonMixin, Person): person_prefix = 'group' django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True) diff --git a/openslides/utils/person/__init__.py b/openslides/utils/person/__init__.py index cc983caf9..7a69e8f25 100644 --- a/openslides/utils/person/__init__.py +++ b/openslides/utils/person/__init__.py @@ -11,7 +11,8 @@ """ from openslides.utils.person.signals import receive_persons -from openslides.utils.person.api import generate_person_id, get_person, Persons +from openslides.utils.person.api import (generate_person_id, get_person, + Person, Persons) from openslides.utils.person.forms import PersonFormField, MultiplePersonFormField from openslides.utils.person.models import PersonField, PersonMixin diff --git a/openslides/utils/person/api.py b/openslides/utils/person/api.py index 49d901f28..5c842dea2 100644 --- a/openslides/utils/person/api.py +++ b/openslides/utils/person/api.py @@ -13,6 +13,37 @@ from openslides.utils.person.signals import receive_persons +class Person(object): + """ + Meta-class for all person objects + """ + def person_id(self): + """ + Return an id for representation of ths person. Has to be unique. + """ + raise NotImplementedError('Any person object needs a person_id') + + def __repr__(self): + """ + Return a string for this person. + """ + return str(self.person_id) + + @property + def clean_name(self): + """ + Return the name of this person without a suffix + """ + return unicode(self) + + @property + def name_suffix(self): + """ + Return a suffix for the person-name. + """ + return '' + + class Persons(object): """ A Storage for a multiplicity of different Person-Objects. From 56b9e831c838be5e71bc94f63bf4354e7708c754 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 12:21:44 +0200 Subject: [PATCH 15/19] Allowd access to the dashboard per default. #361 --- initial_data.json | 20 ++++++++++++++++++++ openslides/config/views.py | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/initial_data.json b/initial_data.json index 9b25d1a34..a0d786baf 100644 --- a/initial_data.json +++ b/initial_data.json @@ -44,6 +44,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -98,6 +103,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -177,6 +187,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -206,6 +221,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } diff --git a/openslides/config/views.py b/openslides/config/views.py index 19b7b9953..908ac7db6 100644 --- a/openslides/config/views.py +++ b/openslides/config/views.py @@ -66,8 +66,9 @@ class GeneralConfig(FormView): try: anonymous = Group.objects.get(name='Anonymous') except Group.DoesNotExist: - default_perms = [u'can_see_agenda', u'can_see_projector', - u'can_see_motion', u'can_see_assignment'] + default_perms = ['can_see_agenda', 'can_see_projector', + 'can_see_motion', 'can_see_assignment', + 'can_see_dashboard'] anonymous = Group() anonymous.name = 'Anonymous' anonymous.save() From 57d591fee88b0b3ce563cc01a9504ca64f691a64 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 24 Oct 2012 12:30:45 +0200 Subject: [PATCH 16/19] Renamed category to detail --- openslides/assignment/views.py | 6 +++--- openslides/participant/forms.py | 4 ++-- openslides/participant/models.py | 14 +++++++------- .../templates/participant/overview.html | 14 +++++++------- openslides/participant/tests.py | 6 +++--- openslides/participant/views.py | 18 +++++++++--------- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index a65d10997..0c1e1f969 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -433,8 +433,8 @@ class AssignmentPDF(PDFView): candidate_string = candidate.clean_name if candidate in elected_candidates: candidate_string = "* " + candidate_string - if candidate.category: - candidate_string += "\n(%s)" % candidate.category + if candidate.name_suffix: + candidate_string += "\n(%s)" % candidate.name_suffix row.append(candidate_string) for vote in poll_list: if vote == None: @@ -594,7 +594,7 @@ class AssignmentPollPDF(PDFView): cell.append(Paragraph(circle + candidate.clean_name, stylesheet['Ballot_option_name'])) if candidate.name_suffix: - cell.append(Paragraph("(%s)" % candidate.category, + cell.append(Paragraph("(%s)" % candidate.name_suffix, stylesheet['Ballot_option_group_right'])) else: cell.append(Paragraph(" ", diff --git a/openslides/participant/forms.py b/openslides/participant/forms.py index 4687432fe..153285d8f 100644 --- a/openslides/participant/forms.py +++ b/openslides/participant/forms.py @@ -27,7 +27,7 @@ class UserCreateForm(forms.ModelForm, CssClassMixin): class Meta: model = User - fields = ('first_name', 'last_name', 'is_active', 'groups', 'category', + fields = ('first_name', 'last_name', 'is_active', 'groups', 'detail', 'gender', 'type', 'committee', 'comment', 'default_password') @@ -35,7 +35,7 @@ class UserUpdateForm(UserCreateForm): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'is_active', 'groups', - 'category', 'gender', 'type', 'committee', 'comment', + 'detail', 'gender', 'type', 'committee', 'comment', 'default_password') diff --git a/openslides/participant/models.py b/openslides/participant/models.py index 2cce07709..cabb54b7a 100644 --- a/openslides/participant/models.py +++ b/openslides/participant/models.py @@ -37,8 +37,8 @@ class User(DjangoUser, PersonMixin, Person): ) django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True) - category = models.CharField( - max_length=100, null=True, blank=True, verbose_name=_("Category"), + detail = models.CharField( + max_length=100, blank=True, default='', verbose_name=_("Detail"), help_text=_('Will be shown behind the name.')) gender = models.CharField( max_length=50, choices=GENDER_CHOICES, blank=True, @@ -47,13 +47,13 @@ class User(DjangoUser, PersonMixin, Person): max_length=100, choices=TYPE_CHOICES, blank=True, verbose_name=_("Typ"), help_text=_('Only for filter the userlist.')) committee = models.CharField( - max_length=100, null=True, blank=True, verbose_name=_("Committee"), + max_length=100, blank=True, default='', verbose_name=_("Committee"), help_text=_('Only for filter the userlist.')) comment = models.TextField( - null=True, blank=True, verbose_name=_('Comment'), + blank=True, default='', verbose_name=_('Comment'), help_text=_('Only for notes.')) default_password = models.CharField( - max_length=100, null=True, blank=True, + max_length=100, blank=True, default='', verbose_name=_("Default password")) @property @@ -61,10 +61,10 @@ class User(DjangoUser, PersonMixin, Person): return self.get_full_name() or self.username def get_name_suffix(self): - return self.category + return self.detail def set_name_suffix(self, value): - self.category = value + self.detail = value name_suffix = property(get_name_suffix, set_name_suffix) diff --git a/openslides/participant/templates/participant/overview.html b/openslides/participant/templates/participant/overview.html index 452bdcb53..f950bc302 100644 --- a/openslides/participant/templates/participant/overview.html +++ b/openslides/participant/templates/participant/overview.html @@ -26,11 +26,11 @@ - + + {% for detail in details %} + {% endfor %}