summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2017-06-30 17:26:44 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2017-06-30 17:26:44 +0200
commit726713f95f91fa83a8e1473625162ae831309952 (patch)
tree2b8ab152e92a95948e9a038ebcef815bfd56aa38 /ishtar_common
parentfd21739351daf697188329948492c65b1a9bd7e6 (diff)
parent483fcd46fb60a597959bfde9d00bde4cc1822cd2 (diff)
downloadIshtar-726713f95f91fa83a8e1473625162ae831309952.tar.bz2
Ishtar-726713f95f91fa83a8e1473625162ae831309952.zip
Merge branch 'master' into develop
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/admin.py28
-rw-r--r--ishtar_common/data_importer.py41
-rw-r--r--ishtar_common/forms_common.py1
-rw-r--r--ishtar_common/locale/django.pot626
-rw-r--r--ishtar_common/management/commands/ishtar_excute_admin_tasks.py15
-rw-r--r--ishtar_common/migrations/0077_auto__add_administrationscript__add_administrationtask.py530
-rw-r--r--ishtar_common/models.py124
-rw-r--r--ishtar_common/templates/blocks/form_snippet.html5
-rw-r--r--ishtar_common/tests.py19
9 files changed, 1084 insertions, 305 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index cba10ea0d..9f8265033 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -306,6 +306,32 @@ class ItemKeyAdmin(admin.ModelAdmin):
admin.site.register(models.ItemKey, ItemKeyAdmin)
+class AdministrationScriptAdmin(admin.ModelAdmin):
+ list_display = ['name', 'path']
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj:
+ return ('path',)
+ return []
+
+admin.site.register(models.AdministrationScript, AdministrationScriptAdmin)
+
+
+class AdministrationTaskAdmin(admin.ModelAdmin):
+ readonly_fields = ('state', 'creation_date', 'launch_date',
+ 'finished_date', "result", )
+ list_display = ['script', 'state', 'creation_date', 'launch_date',
+ 'finished_date', "result"]
+ list_filter = ['script', 'state']
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj:
+ return ("script", ) + self.readonly_fields
+ return self.readonly_fields
+
+admin.site.register(models.AdministrationTask, AdministrationTaskAdmin)
+
+
basic_models = [models.DocumentTemplate, models.IshtarUser]
if settings.COUNTRY == 'fr':
basic_models += [models.Arrondissement, models.Canton]
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 1fe4ef45c..76b186038 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -1400,20 +1400,35 @@ class Importer(object):
# get all related fields
new_created = {}
- for attribute in list(data.keys()):
- c_c_path = c_path[:]
- if not attribute:
- data.pop(attribute)
- continue
- if not data[attribute]:
- field_object, model, direct, m2m = \
- cls._meta.get_field_by_name(attribute)
- if m2m:
+ try:
+ for attribute in list(data.keys()):
+ c_c_path = c_path[:]
+ if not attribute:
data.pop(attribute)
- continue
- if attribute != '__force_new':
- self.get_field(cls, attribute, data, m2ms, c_c_path,
- new_created)
+ continue
+ if not data[attribute]:
+ field_object, model, direct, m2m = \
+ cls._meta.get_field_by_name(attribute)
+ if m2m:
+ data.pop(attribute)
+ continue
+ if attribute != '__force_new':
+ self.get_field(cls, attribute, data, m2ms, c_c_path,
+ new_created)
+ except (ValueError, IntegrityError) as e:
+ message = e.message
+ try:
+ message = e.message.decode('utf-8')
+ except (UnicodeDecodeError, UnicodeDecodeError):
+ message = ''
+ try:
+ data = unicode(data)
+ except UnicodeDecodeError:
+ data = ''
+ raise ImporterError(
+ "Erreur d'import %s %s, contexte : %s, erreur : %s"
+ % (unicode(cls), unicode("__".join(path)),
+ unicode(data), message))
create_dict = copy.deepcopy(data)
for k in create_dict.keys():
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index b317f77e3..61e9f1a88 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -884,6 +884,7 @@ class AuthorFormSelection(forms.Form):
base_model = 'author'
associated_models = {'author': models.Author}
author = forms.IntegerField(
+ required=False,
widget=widgets.JQueryAutoComplete(
"/" + settings.URL_PATH + 'autocomplete-author',
associated_model=models.Author, new=True),
diff --git a/ishtar_common/locale/django.pot b/ishtar_common/locale/django.pot
index 26a06d0b8..4a7e66801 100644
--- a/ishtar_common/locale/django.pot
+++ b/ishtar_common/locale/django.pot
@@ -120,31 +120,31 @@ msgstr ""
msgid "Importer configuration error: field \"{}\" does not exist for {}."
msgstr ""
-#: data_importer.py:1559
+#: data_importer.py:1574
msgid "line"
msgstr ""
-#: data_importer.py:1559
+#: data_importer.py:1574
msgid "col"
msgstr ""
-#: data_importer.py:1559
+#: data_importer.py:1574
msgid "error"
msgstr ""
-#: data_importer.py:1565
+#: data_importer.py:1580
msgid "field"
msgstr ""
-#: data_importer.py:1565
+#: data_importer.py:1580
msgid "source"
msgstr ""
-#: data_importer.py:1565
+#: data_importer.py:1580
msgid "result"
msgstr ""
-#: data_importer.py:1581
+#: data_importer.py:1596
#, python-format
msgid "\"%(value)s\" not in %(values)s"
msgstr ""
@@ -177,12 +177,12 @@ msgstr ""
msgid "Add a new item"
msgstr ""
-#: forms.py:297 models.py:1556
+#: forms.py:297 models.py:1558
msgid "Template"
msgstr ""
#: forms_common.py:41 forms_common.py:59 forms_common.py:184
-#: forms_common.py:408 models.py:1622 models.py:3085
+#: forms_common.py:408 models.py:1624 models.py:3087
#: templates/blocks/JQueryAdvancedTown.html:19
#: templates/ishtar/sheet_organization.html:13
msgid "Town"
@@ -198,8 +198,8 @@ msgid ""
"french town Saint-Denis in the Seine-Saint-Denis department.</p>"
msgstr ""
-#: forms_common.py:68 forms_common.py:863 ishtar_menu.py:47 models.py:2685
-#: models.py:2878 models.py:2940 templates/ishtar/sheet_person.html:4
+#: forms_common.py:68 forms_common.py:863 ishtar_menu.py:47 models.py:2687
+#: models.py:2880 models.py:2942 templates/ishtar/sheet_person.html:4
msgid "Person"
msgstr ""
@@ -210,64 +210,65 @@ msgid ""
msgstr ""
#: forms_common.py:172 forms_common.py:329 forms_common.py:453
-#: ishtar_menu.py:75 models.py:2568 models.py:2659
+#: ishtar_menu.py:75 models.py:2570 models.py:2661
#: templates/ishtar/sheet_organization.html:4
msgid "Organization"
msgstr ""
#: forms_common.py:175 forms_common.py:212 forms_common.py:324
-#: forms_common.py:378 forms_common.py:448 models.py:1159 models.py:1555
-#: models.py:1824 models.py:1840 models.py:2078 models.py:2356 models.py:2562
-#: models.py:2671 models.py:3071 templates/ishtar/import_list.html:13
+#: forms_common.py:378 forms_common.py:448 models.py:1161 models.py:1557
+#: models.py:1826 models.py:1842 models.py:2080 models.py:2358 models.py:2564
+#: models.py:2673 models.py:3073 models.py:3170
+#: templates/ishtar/import_list.html:13
#: templates/ishtar/sheet_organization.html:8
#: templates/ishtar/sheet_organization.html:21
msgid "Name"
msgstr ""
-#: forms_common.py:176 models.py:1777 models.py:2209
+#: forms_common.py:176 models.py:1779 models.py:2211
msgid "Organization type"
msgstr ""
-#: forms_common.py:178 forms_common.py:402 models.py:1617
+#: forms_common.py:178 forms_common.py:402 models.py:1619
#: templates/ishtar/sheet_organization.html:10
msgid "Address"
msgstr ""
-#: forms_common.py:180 forms_common.py:405 models.py:1618
+#: forms_common.py:180 forms_common.py:405 models.py:1620
#: templates/ishtar/sheet_organization.html:11
msgid "Address complement"
msgstr ""
-#: forms_common.py:182 forms_common.py:406 models.py:1620
+#: forms_common.py:182 forms_common.py:406 models.py:1622
#: templates/ishtar/sheet_organization.html:12
msgid "Postal code"
msgstr ""
-#: forms_common.py:185 forms_common.py:409 models.py:1623
+#: forms_common.py:185 forms_common.py:409 models.py:1625
msgid "Country"
msgstr ""
#: forms_common.py:187 forms_common.py:326 forms_common.py:382
-#: forms_common.py:450 forms_common.py:574 models.py:1650
+#: forms_common.py:450 forms_common.py:574 models.py:1652
msgid "Email"
msgstr ""
-#: forms_common.py:188 forms_common.py:385 models.py:1635
+#: forms_common.py:188 forms_common.py:385 models.py:1637
#: templates/ishtar/sheet_organization.html:14
#: templates/ishtar/sheet_person.html:21
#: templates/ishtar/wizard/wizard_person.html:17
msgid "Phone"
msgstr ""
-#: forms_common.py:189 forms_common.py:394 models.py:1647
+#: forms_common.py:189 forms_common.py:394 models.py:1649
#: templates/ishtar/sheet_organization.html:15
#: templates/ishtar/sheet_person.html:39
#: templates/ishtar/wizard/wizard_person.html:35
msgid "Mobile phone"
msgstr ""
-#: forms_common.py:213 forms_common.py:327 forms_common.py:451 models.py:2247
-#: models.py:2564 models.py:3006 templates/sheet_ope.html:85
+#: forms_common.py:213 forms_common.py:327 forms_common.py:451 models.py:2249
+#: models.py:2566 models.py:3008 templates/sheet_ope.html:85
#: templates/sheet_ope.html.py:105 templates/sheet_ope.html:126
#: templates/ishtar/import_list.html:14
#: templates/ishtar/sheet_organization.html:23
@@ -291,7 +292,7 @@ msgstr ""
msgid "Organization to merge"
msgstr ""
-#: forms_common.py:325 forms_common.py:376 forms_common.py:449 models.py:2669
+#: forms_common.py:325 forms_common.py:376 forms_common.py:449 models.py:2671
#: templates/ishtar/sheet_organization.html:22
msgid "Surname"
msgstr ""
@@ -309,25 +310,25 @@ msgstr ""
msgid "Identity"
msgstr ""
-#: forms_common.py:373 forms_common.py:781 forms_common.py:830 models.py:2210
-#: models.py:2663 models.py:2665 models.py:3003 templates/sheet_ope.html:104
+#: forms_common.py:373 forms_common.py:781 forms_common.py:830 models.py:2212
+#: models.py:2665 models.py:2667 models.py:3005 templates/sheet_ope.html:104
#: templates/ishtar/blocks/window_tables/documents.html:7
msgid "Title"
msgstr ""
-#: forms_common.py:374 models.py:2667
+#: forms_common.py:374 models.py:2669
msgid "Salutation"
msgstr ""
-#: forms_common.py:380 models.py:2673
+#: forms_common.py:380 models.py:2675
msgid "Raw name"
msgstr ""
-#: forms_common.py:383 models.py:1636
+#: forms_common.py:383 models.py:1638
msgid "Phone description"
msgstr ""
-#: forms_common.py:386 models.py:1638 models.py:1640
+#: forms_common.py:386 models.py:1640 models.py:1642
msgid "Phone description 2"
msgstr ""
@@ -335,11 +336,11 @@ msgstr ""
msgid "Phone 2"
msgstr ""
-#: forms_common.py:390 models.py:1644
+#: forms_common.py:390 models.py:1646
msgid "Phone description 3"
msgstr ""
-#: forms_common.py:392 models.py:1642
+#: forms_common.py:392 models.py:1644
msgid "Phone 3"
msgstr ""
@@ -347,23 +348,23 @@ msgstr ""
msgid "Current organization"
msgstr ""
-#: forms_common.py:411 models.py:1625
+#: forms_common.py:411 models.py:1627
msgid "Other address: address"
msgstr ""
-#: forms_common.py:414 models.py:1628
+#: forms_common.py:414 models.py:1630
msgid "Other address: address complement"
msgstr ""
-#: forms_common.py:416 models.py:1629
+#: forms_common.py:416 models.py:1631
msgid "Other address: postal code"
msgstr ""
-#: forms_common.py:418 models.py:1631
+#: forms_common.py:418 models.py:1633
msgid "Other address: town"
msgstr ""
-#: forms_common.py:420 models.py:1633
+#: forms_common.py:420 models.py:1635
msgid "Other address: country"
msgstr ""
@@ -379,7 +380,7 @@ msgstr ""
msgid "Account search"
msgstr ""
-#: forms_common.py:512 forms_common.py:552 forms_common.py:556 models.py:2616
+#: forms_common.py:512 forms_common.py:552 forms_common.py:556 models.py:2618
msgid "Person type"
msgstr ""
@@ -411,7 +412,7 @@ msgstr ""
msgid "Send the new password by email?"
msgstr ""
-#: forms_common.py:636 forms_common.py:649 models.py:3086
+#: forms_common.py:636 forms_common.py:649 models.py:3088
msgid "Towns"
msgstr ""
@@ -427,7 +428,7 @@ msgstr ""
msgid "Documentation informations"
msgstr ""
-#: forms_common.py:783 forms_common.py:831 models.py:2211 models.py:2978
+#: forms_common.py:783 forms_common.py:831 models.py:2213 models.py:2980
msgid "Source type"
msgstr ""
@@ -439,37 +440,37 @@ msgstr ""
msgid "Internal reference"
msgstr ""
-#: forms_common.py:791 models.py:3017
+#: forms_common.py:791 models.py:3019
msgid "Numerical ressource (web address)"
msgstr ""
-#: forms_common.py:792 models.py:3019
+#: forms_common.py:792 models.py:3021
msgid "Receipt date"
msgstr ""
-#: forms_common.py:794 models.py:2382 models.py:3021
+#: forms_common.py:794 models.py:2384 models.py:3023
msgid "Creation date"
msgstr ""
-#: forms_common.py:797 models.py:3024
+#: forms_common.py:797 models.py:3026
msgid "Receipt date in documentation"
msgstr ""
-#: forms_common.py:799 forms_common.py:835 models.py:419 models.py:746
-#: models.py:2105 models.py:2677 models.py:3031
+#: forms_common.py:799 forms_common.py:835 models.py:421 models.py:748
+#: models.py:2107 models.py:2679 models.py:3033
msgid "Comment"
msgstr ""
-#: forms_common.py:801 forms_common.py:834 models.py:1161 models.py:1844
-#: models.py:2032 models.py:2079 models.py:3030 templates/sheet_ope.html:128
+#: forms_common.py:801 forms_common.py:834 models.py:1163 models.py:1846
+#: models.py:2034 models.py:2081 models.py:3032 templates/sheet_ope.html:128
msgid "Description"
msgstr ""
-#: forms_common.py:804 models.py:3032
+#: forms_common.py:804 models.py:3034
msgid "Additional information"
msgstr ""
-#: forms_common.py:806 forms_common.py:838 models.py:3034
+#: forms_common.py:806 forms_common.py:838 models.py:3036
msgid "Has a duplicate"
msgstr ""
@@ -484,7 +485,7 @@ msgid ""
"p>"
msgstr ""
-#: forms_common.py:827 forms_common.py:856 forms_common.py:890 models.py:2945
+#: forms_common.py:827 forms_common.py:856 forms_common.py:890 models.py:2947
#: templates/ishtar/wizard/wizard_person_deletion.html:124
msgid "Author"
msgstr ""
@@ -497,7 +498,7 @@ msgstr ""
msgid "Would you like to delete this documentation?"
msgstr ""
-#: forms_common.py:864 models.py:2212 models.py:2932 models.py:2942
+#: forms_common.py:864 models.py:2214 models.py:2934 models.py:2944
msgid "Author type"
msgstr ""
@@ -509,7 +510,7 @@ msgstr ""
msgid "There are identical authors."
msgstr ""
-#: forms_common.py:901 models.py:2946 models.py:3013
+#: forms_common.py:901 models.py:2948 models.py:3015
#: templates/sheet_ope.html:106
#: templates/ishtar/blocks/window_tables/documents.html:9
msgid "Authors"
@@ -527,7 +528,7 @@ msgstr ""
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:39 models.py:1338 views.py:1648
+#: ishtar_menu.py:39 models.py:1340 views.py:1648
msgid "Global variables"
msgstr ""
@@ -555,7 +556,7 @@ msgstr ""
msgid "Manual merge"
msgstr ""
-#: ishtar_menu.py:109 models.py:2390
+#: ishtar_menu.py:109 models.py:2392
msgid "Imports"
msgstr ""
@@ -571,280 +572,280 @@ msgstr ""
msgid "Old imports"
msgstr ""
-#: models.py:224
+#: models.py:226
msgid "Not a valid item."
msgstr ""
-#: models.py:239
+#: models.py:241
msgid "A selected item is not a valid item."
msgstr ""
-#: models.py:250
+#: models.py:252
msgid "This item already exists."
msgstr ""
-#: models.py:415 models.py:745 models.py:1590 models.py:1602 models.py:2028
+#: models.py:417 models.py:747 models.py:1592 models.py:1604 models.py:2030
msgid "Label"
msgstr ""
-#: models.py:417
+#: models.py:419
msgid "Textual ID"
msgstr ""
-#: models.py:420 models.py:748 models.py:1559
+#: models.py:422 models.py:750 models.py:1561
msgid "Available"
msgstr ""
-#: models.py:772 models.py:2151
+#: models.py:774 models.py:2153
msgid "Key"
msgstr ""
-#: models.py:778
+#: models.py:780
msgid "Specific key to an import"
msgstr ""
-#: models.py:874
+#: models.py:876
msgid "Last editor"
msgstr ""
-#: models.py:877
+#: models.py:879
msgid "Creator"
msgstr ""
-#: models.py:1019 models.py:2929 models.py:3097 models.py:3153
+#: models.py:1021 models.py:2931 models.py:3099 models.py:3155
msgid "Order"
msgstr ""
-#: models.py:1020
+#: models.py:1022
msgid "Symmetrical"
msgstr ""
-#: models.py:1021
+#: models.py:1023
msgid "Tiny label"
msgstr ""
-#: models.py:1035
+#: models.py:1037
msgid "Cannot have symmetrical and an inverse_relation"
msgstr ""
-#: models.py:1151
+#: models.py:1153
msgid "Euro"
msgstr ""
-#: models.py:1152
+#: models.py:1154
msgid "US dollar"
msgstr ""
-#: models.py:1153 views.py:1446 views.py:1508
+#: models.py:1155 views.py:1446 views.py:1508
msgid "Operations"
msgstr ""
-#: models.py:1154 views.py:1448 views.py:1512
+#: models.py:1156 views.py:1448 views.py:1512
msgid "Context records"
msgstr ""
-#: models.py:1160 models.py:1842
+#: models.py:1162 models.py:1844
msgid "Slug"
msgstr ""
-#: models.py:1163
+#: models.py:1165
msgid "CSS color code for base module"
msgstr ""
-#: models.py:1165
+#: models.py:1167
msgid "Files module"
msgstr ""
-#: models.py:1167
+#: models.py:1169
msgid "CSS color code for files module"
msgstr ""
-#: models.py:1169
+#: models.py:1171
msgid "Context records module"
msgstr ""
-#: models.py:1172
+#: models.py:1174
msgid "CSS color code for context record module"
msgstr ""
-#: models.py:1174
+#: models.py:1176
msgid "Finds module"
msgstr ""
-#: models.py:1175
+#: models.py:1177
msgid "Need context records module"
msgstr ""
-#: models.py:1177
+#: models.py:1179
msgid "Find index is based on"
msgstr ""
-#: models.py:1179
+#: models.py:1181
msgid ""
"To prevent irrelevant indexes, change this parameter only if there is no "
"find in the database"
msgstr ""
-#: models.py:1182
+#: models.py:1184
msgid "CSS color code for find module"
msgstr ""
-#: models.py:1185
+#: models.py:1187
msgid "Warehouses module"
msgstr ""
-#: models.py:1186
+#: models.py:1188
msgid "Need finds module"
msgstr ""
-#: models.py:1188
+#: models.py:1190
msgid "CSS code for warehouse module"
msgstr ""
-#: models.py:1190
+#: models.py:1192
msgid "Mapping module"
msgstr ""
-#: models.py:1192
+#: models.py:1194
msgid "CSS code for mapping module"
msgstr ""
-#: models.py:1195
+#: models.py:1197
msgid "Home page"
msgstr ""
-#: models.py:1196
+#: models.py:1198
#, python-brace-format
msgid ""
"Homepage of Ishtar - if not defined a default homepage will appear. Use the "
"markdown syntax. {random_image} can be used to display a random image."
msgstr ""
-#: models.py:1200
+#: models.py:1202
msgid "File external id"
msgstr ""
-#: models.py:1202
+#: models.py:1204
msgid ""
"Formula to manage file external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1207
+#: models.py:1209
msgid "Parcel external id"
msgstr ""
-#: models.py:1210
+#: models.py:1212
msgid ""
"Formula to manage parcel external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1215
+#: models.py:1217
msgid "Context record external id"
msgstr ""
-#: models.py:1217
+#: models.py:1219
msgid ""
"Formula to manage context record external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1222
+#: models.py:1224
msgid "Base find external id"
msgstr ""
-#: models.py:1224
+#: models.py:1226
msgid ""
"Formula to manage base find external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1229
+#: models.py:1231
msgid "Find external id"
msgstr ""
-#: models.py:1231
+#: models.py:1233
msgid ""
"Formula to manage find external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1236
+#: models.py:1238
msgid "Container external id"
msgstr ""
-#: models.py:1238
+#: models.py:1240
msgid ""
"Formula to manage container external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1243
+#: models.py:1245
msgid "Warehouse external id"
msgstr ""
-#: models.py:1245
+#: models.py:1247
msgid ""
"Formula to manage warehouse external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1250
+#: models.py:1252
msgid "Raw name for person"
msgstr ""
-#: models.py:1252
+#: models.py:1254
msgid ""
"Formula to manage person raw_name. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1256
+#: models.py:1258
msgid "Current active"
msgstr ""
-#: models.py:1257
+#: models.py:1259
msgid "Currency"
msgstr ""
-#: models.py:1261
+#: models.py:1263
msgid "Ishtar site profile"
msgstr ""
-#: models.py:1262
+#: models.py:1264
msgid "Ishtar site profiles"
msgstr ""
-#: models.py:1331
+#: models.py:1333
msgid "Variable name"
msgstr ""
-#: models.py:1332
+#: models.py:1334
msgid "Description of the variable"
msgstr ""
-#: models.py:1334 models.py:2152
+#: models.py:1336 models.py:2154
msgid "Value"
msgstr ""
-#: models.py:1337
+#: models.py:1339
msgid "Global variable"
msgstr ""
-#: models.py:1460 models.py:1490
+#: models.py:1462 models.py:1492
msgid "Total"
msgstr ""
-#: models.py:1467 models.py:1591 models.py:1603
+#: models.py:1469 models.py:1593 models.py:1605
#: templates/ishtar/sheet_person.html:24
#: templates/ishtar/dashboards/dashboard_main_detail.html:141
#: templates/ishtar/dashboards/dashboard_main_detail_users.html:26
@@ -852,666 +853,725 @@ msgstr ""
msgid "Number"
msgstr ""
-#: models.py:1554
+#: models.py:1556
msgid "Administrative Act"
msgstr ""
-#: models.py:1558
+#: models.py:1560
msgid "Associated object"
msgstr ""
-#: models.py:1562
+#: models.py:1564
msgid "Document template"
msgstr ""
-#: models.py:1563
+#: models.py:1565
msgid "Document templates"
msgstr ""
-#: models.py:1594 models.py:1604 models.py:2376
+#: models.py:1596 models.py:1606 models.py:2378 models.py:3193
msgid "State"
msgstr ""
-#: models.py:1608 templates/blocks/JQueryAdvancedTown.html:12
+#: models.py:1610 templates/blocks/JQueryAdvancedTown.html:12
msgid "Department"
msgstr ""
-#: models.py:1609
+#: models.py:1611
msgid "Departments"
msgstr ""
-#: models.py:1646
+#: models.py:1648
msgid "Raw phone"
msgstr ""
-#: models.py:1652
+#: models.py:1654
msgid "Alternative address is prefered"
msgstr ""
-#: models.py:1691
+#: models.py:1693
msgid "Tel: "
msgstr ""
-#: models.py:1695
+#: models.py:1697
msgid "Mobile: "
msgstr ""
-#: models.py:1699
+#: models.py:1701
msgid "Email: "
msgstr ""
-#: models.py:1704
+#: models.py:1706
msgid "Merge key"
msgstr ""
-#: models.py:1778
+#: models.py:1780
msgid "Organization types"
msgstr ""
-#: models.py:1825
+#: models.py:1827
msgid "Class name"
msgstr ""
-#: models.py:1828
+#: models.py:1830
msgid "Importer - Model"
msgstr ""
-#: models.py:1829
+#: models.py:1831
msgid "Importer - Models"
msgstr ""
-#: models.py:1846 templates/ishtar/dashboards/dashboard_main.html:34
+#: models.py:1848 templates/ishtar/dashboards/dashboard_main.html:34
msgid "Users"
msgstr ""
-#: models.py:1849
+#: models.py:1851
msgid "Associated model"
msgstr ""
-#: models.py:1852
+#: models.py:1854
msgid "Models that can accept new items"
msgstr ""
-#: models.py:1853
+#: models.py:1855
msgid "Leave blank for no restrictions"
msgstr ""
-#: models.py:1855
+#: models.py:1857
msgid "Is template"
msgstr ""
-#: models.py:1856
+#: models.py:1858
msgid "Unicity keys (separator \";\")"
msgstr ""
-#: models.py:1860
+#: models.py:1862
msgid "Importer - Type"
msgstr ""
-#: models.py:1861
+#: models.py:1863
msgid "Importer - Types"
msgstr ""
-#: models.py:1960
+#: models.py:1962
msgid "Importer - Default"
msgstr ""
-#: models.py:1961
+#: models.py:1963
msgid "Importer - Defaults"
msgstr ""
-#: models.py:1996
+#: models.py:1998
msgid "Importer - Default value"
msgstr ""
-#: models.py:1997
+#: models.py:1999
msgid "Importer - Default values"
msgstr ""
-#: models.py:2031
+#: models.py:2033
msgid "Column number"
msgstr ""
-#: models.py:2034
+#: models.py:2036
msgid "Required"
msgstr ""
-#: models.py:2036
+#: models.py:2038
msgid "Export field name"
msgstr ""
-#: models.py:2037
+#: models.py:2039
msgid ""
"Fill this field if the field name is ambiguous for export. For instance: "
"concatenated fields."
msgstr ""
-#: models.py:2042
+#: models.py:2044
msgid "Importer - Column"
msgstr ""
-#: models.py:2043
+#: models.py:2045
msgid "Importer - Columns"
msgstr ""
-#: models.py:2063
+#: models.py:2065
msgid "Field name"
msgstr ""
-#: models.py:2065 models.py:2099
+#: models.py:2067 models.py:2101
msgid "Force creation of new items"
msgstr ""
-#: models.py:2067 models.py:2101
+#: models.py:2069 models.py:2103
msgid "Concatenate with existing"
msgstr ""
-#: models.py:2069 models.py:2103
+#: models.py:2071 models.py:2105
msgid "Concatenate character"
msgstr ""
-#: models.py:2073
+#: models.py:2075
msgid "Importer - Duplicate field"
msgstr ""
-#: models.py:2074
+#: models.py:2076
msgid "Importer - Duplicate fields"
msgstr ""
-#: models.py:2081
+#: models.py:2083
msgid "Regular expression"
msgstr ""
-#: models.py:2084
+#: models.py:2086
msgid "Importer - Regular expression"
msgstr ""
-#: models.py:2085
+#: models.py:2087
msgid "Importer - Regular expressions"
msgstr ""
-#: models.py:2108
+#: models.py:2110
msgid "Importer - Target"
msgstr ""
-#: models.py:2109
+#: models.py:2111
msgid "Importer - Targets"
msgstr ""
-#: models.py:2133 views.py:578
+#: models.py:2135 views.py:578
msgid "True"
msgstr ""
-#: models.py:2134 views.py:580
+#: models.py:2136 views.py:580
msgid "False"
msgstr ""
-#: models.py:2153
+#: models.py:2155
msgid "Is set"
msgstr ""
-#: models.py:2160
+#: models.py:2162
msgid "Importer - Target key"
msgstr ""
-#: models.py:2161
+#: models.py:2163
msgid "Importer - Targets keys"
msgstr ""
-#: models.py:2213 models.py:3009
+#: models.py:2215 models.py:3011
msgid "Format"
msgstr ""
-#: models.py:2214 models.py:3101
+#: models.py:2216 models.py:3103
msgid "Operation type"
msgstr ""
-#: models.py:2215
+#: models.py:2217
msgid "Period"
msgstr ""
-#: models.py:2216
+#: models.py:2218
msgid "Report state"
msgstr ""
-#: models.py:2217
+#: models.py:2219
msgid "Remain type"
msgstr ""
-#: models.py:2218
+#: models.py:2220
msgid "Unit"
msgstr ""
-#: models.py:2220
+#: models.py:2222
msgid "Activity type"
msgstr ""
-#: models.py:2221
+#: models.py:2223
msgid "Material"
msgstr ""
-#: models.py:2223
+#: models.py:2225
msgid "Conservatory state"
msgstr ""
-#: models.py:2224
+#: models.py:2226
msgid "Container type"
msgstr ""
-#: models.py:2225
+#: models.py:2227
msgid "Preservation type"
msgstr ""
-#: models.py:2226
+#: models.py:2228
msgid "Object type"
msgstr ""
-#: models.py:2227
+#: models.py:2229
msgid "Integrity type"
msgstr ""
-#: models.py:2229
+#: models.py:2231
msgid "Remarkability type"
msgstr ""
-#: models.py:2230
+#: models.py:2232
msgid "Batch type"
msgstr ""
-#: models.py:2232
+#: models.py:2234
msgid "Identification type"
msgstr ""
-#: models.py:2234
+#: models.py:2236
msgid "Context record relation type"
msgstr ""
-#: models.py:2235 models.py:3159
+#: models.py:2237 models.py:3161
msgid "Spatial reference system"
msgstr ""
-#: models.py:2236 models.py:2987
+#: models.py:2238 models.py:2989
msgid "Support type"
msgstr ""
-#: models.py:2237 models.py:2628
+#: models.py:2239 models.py:2630
msgid "Title type"
msgstr ""
-#: models.py:2243
+#: models.py:2245
msgid "Integer"
msgstr ""
-#: models.py:2244
+#: models.py:2246
msgid "Float"
msgstr ""
-#: models.py:2245
+#: models.py:2247
msgid "String"
msgstr ""
-#: models.py:2246 templates/sheet_ope.html:86
+#: models.py:2248 templates/sheet_ope.html:86
msgid "Date"
msgstr ""
-#: models.py:2248 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83
+#: models.py:2250 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83
#: templates/ishtar/dashboards/dashboard_main_detail.html:126
msgid "Year"
msgstr ""
-#: models.py:2249
+#: models.py:2251
msgid "String to boolean"
msgstr ""
-#: models.py:2250
+#: models.py:2252
msgctxt "filesystem"
msgid "File"
msgstr ""
-#: models.py:2251
+#: models.py:2253
msgid "Unknow type"
msgstr ""
-#: models.py:2267
+#: models.py:2269
msgid "4 digit year. e.g.: \"2015\""
msgstr ""
-#: models.py:2268
+#: models.py:2270
msgid "4 digit year/month/day. e.g.: \"2015/02/04\""
msgstr ""
-#: models.py:2269
+#: models.py:2271
msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""
msgstr ""
-#: models.py:2279
+#: models.py:2281
msgid "Options"
msgstr ""
-#: models.py:2281
+#: models.py:2283
msgid "Split character(s)"
msgstr ""
-#: models.py:2285
+#: models.py:2287
msgid "Importer - Formater type"
msgstr ""
-#: models.py:2286
+#: models.py:2288
msgid "Importer - Formater types"
msgstr ""
-#: models.py:2338 templates/ishtar/dashboards/dashboard_main_detail.html:63
+#: models.py:2340 templates/ishtar/dashboards/dashboard_main_detail.html:63
msgid "Created"
msgstr ""
-#: models.py:2339
+#: models.py:2341
msgid "Analyse in progress"
msgstr ""
-#: models.py:2340
+#: models.py:2342
msgid "Analysed"
msgstr ""
-#: models.py:2341
+#: models.py:2343
msgid "Import pending"
msgstr ""
-#: models.py:2342
+#: models.py:2344
msgid "Import in progress"
msgstr ""
-#: models.py:2343
+#: models.py:2345 models.py:3184
msgid "Finished with errors"
msgstr ""
-#: models.py:2344
+#: models.py:2346 models.py:3185
msgid "Finished"
msgstr ""
-#: models.py:2345
+#: models.py:2347
msgid "Archived"
msgstr ""
-#: models.py:2360
+#: models.py:2362
msgid "Imported file"
msgstr ""
-#: models.py:2362
+#: models.py:2364
msgid "Associated images (zip file)"
msgstr ""
-#: models.py:2364
+#: models.py:2366
msgid "Encoding"
msgstr ""
-#: models.py:2366
+#: models.py:2368
msgid "Skip lines"
msgstr ""
-#: models.py:2367 templates/ishtar/import_list.html:51
+#: models.py:2369 templates/ishtar/import_list.html:51
msgid "Error file"
msgstr ""
-#: models.py:2370
+#: models.py:2372
msgid "Result file"
msgstr ""
-#: models.py:2373 templates/ishtar/import_list.html:57
+#: models.py:2375 templates/ishtar/import_list.html:57
msgid "Match file"
msgstr ""
-#: models.py:2379
+#: models.py:2381
msgid "Conservative import"
msgstr ""
-#: models.py:2383
+#: models.py:2385
msgid "End date"
msgstr ""
-#: models.py:2386
+#: models.py:2388
msgid "Remaining seconds"
msgstr ""
-#: models.py:2389
+#: models.py:2391
msgid "Import"
msgstr ""
-#: models.py:2418
+#: models.py:2420
msgid "Analyse"
msgstr ""
-#: models.py:2420 models.py:2423
+#: models.py:2422 models.py:2425
msgid "Re-analyse"
msgstr ""
-#: models.py:2421
+#: models.py:2423
msgid "Launch import"
msgstr ""
-#: models.py:2424
+#: models.py:2426
msgid "Re-import"
msgstr ""
-#: models.py:2425
+#: models.py:2427
msgid "Archive"
msgstr ""
-#: models.py:2427
+#: models.py:2429
msgid "Unarchive"
msgstr ""
-#: models.py:2428 widgets.py:198 templates/ishtar/form_delete.html:11
+#: models.py:2430 widgets.py:198 templates/ishtar/form_delete.html:11
msgid "Delete"
msgstr ""
-#: models.py:2569
+#: models.py:2571
msgid "Organizations"
msgstr ""
-#: models.py:2571
+#: models.py:2573
msgid "Can view all Organizations"
msgstr ""
-#: models.py:2572
+#: models.py:2574
msgid "Can view own Organization"
msgstr ""
-#: models.py:2573
+#: models.py:2575
msgid "Can add own Organization"
msgstr ""
-#: models.py:2575
+#: models.py:2577
msgid "Can change own Organization"
msgstr ""
-#: models.py:2577
+#: models.py:2579
msgid "Can delete own Organization"
msgstr ""
-#: models.py:2612
+#: models.py:2614
msgid "Groups"
msgstr ""
-#: models.py:2617
+#: models.py:2619
msgid "Person types"
msgstr ""
-#: models.py:2629
+#: models.py:2631
msgid "Title types"
msgstr ""
-#: models.py:2638
+#: models.py:2640
msgid "Mr"
msgstr ""
-#: models.py:2639
+#: models.py:2641
msgid "Miss"
msgstr ""
-#: models.py:2640
+#: models.py:2642
msgid "Mr and Mrs"
msgstr ""
-#: models.py:2641
+#: models.py:2643
msgid "Mrs"
msgstr ""
-#: models.py:2642
+#: models.py:2644
msgid "Doctor"
msgstr ""
-#: models.py:2675
+#: models.py:2677
msgid "Contact type"
msgstr ""
-#: models.py:2678 models.py:2742
+#: models.py:2680 models.py:2744
msgid "Types"
msgstr ""
-#: models.py:2681
+#: models.py:2683
msgid "Is attached to"
msgstr ""
-#: models.py:2686
+#: models.py:2688
msgid "Persons"
msgstr ""
-#: models.py:2688
+#: models.py:2690
msgid "Can view all Persons"
msgstr ""
-#: models.py:2689
+#: models.py:2691
msgid "Can view own Person"
msgstr ""
-#: models.py:2690
+#: models.py:2692
msgid "Can add own Person"
msgstr ""
-#: models.py:2691
+#: models.py:2693
msgid "Can change own Person"
msgstr ""
-#: models.py:2692
+#: models.py:2694
msgid "Can delete own Person"
msgstr ""
-#: models.py:2881
+#: models.py:2883
msgid "Advanced shortcut menu"
msgstr ""
-#: models.py:2884
+#: models.py:2886
msgid "Ishtar user"
msgstr ""
-#: models.py:2885
+#: models.py:2887
msgid "Ishtar users"
msgstr ""
-#: models.py:2925
+#: models.py:2927
msgid "To modify the password use the form in Auth > User"
msgstr ""
-#: models.py:2933
+#: models.py:2935
msgid "Author types"
msgstr ""
-#: models.py:2950
+#: models.py:2952
msgid "Can view all Authors"
msgstr ""
-#: models.py:2952
+#: models.py:2954
msgid "Can view own Author"
msgstr ""
-#: models.py:2954
+#: models.py:2956
msgid "Can add own Author"
msgstr ""
-#: models.py:2956
+#: models.py:2958
msgid "Can change own Author"
msgstr ""
-#: models.py:2958
+#: models.py:2960
msgid "Can delete own Author"
msgstr ""
-#: models.py:2979
+#: models.py:2981
msgid "Source types"
msgstr ""
-#: models.py:2988
+#: models.py:2990
msgid "Support types"
msgstr ""
-#: models.py:2995
+#: models.py:2997
msgid "Format type"
msgstr ""
-#: models.py:2996
+#: models.py:2998
msgid "Format types"
msgstr ""
-#: models.py:3004
+#: models.py:3006
msgid "External ID"
msgstr ""
-#: models.py:3007
+#: models.py:3009
msgid "Support"
msgstr ""
-#: models.py:3011
+#: models.py:3013
msgid "Scale"
msgstr ""
-#: models.py:3025
+#: models.py:3027
msgid "Item number"
msgstr ""
-#: models.py:3026
+#: models.py:3028
msgid "Ref."
msgstr ""
-#: models.py:3029
+#: models.py:3031
msgid "Internal ref."
msgstr ""
-#: models.py:3072
+#: models.py:3074
msgid "Surface (m2)"
msgstr ""
-#: models.py:3073 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107
+#: models.py:3075 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107
msgid "Localisation"
msgstr ""
-#: models.py:3098
+#: models.py:3100
msgid "Is preventive"
msgstr ""
-#: models.py:3102
+#: models.py:3104
msgid "Operation types"
msgstr ""
-#: models.py:3131
+#: models.py:3133
msgid "Preventive"
msgstr ""
-#: models.py:3132
+#: models.py:3134
msgid "Research"
msgstr ""
-#: models.py:3155
+#: models.py:3157
msgid "Authority name"
msgstr ""
-#: models.py:3156
+#: models.py:3158
msgid "Authority SRID"
msgstr ""
-#: models.py:3160
+#: models.py:3162
msgid "Spatial reference systems"
msgstr ""
+#: models.py:3169
+msgid "Filename"
+msgstr ""
+
+#: models.py:3174
+msgid "Administration script"
+msgstr ""
+
+#: models.py:3175
+msgid "Administration scripts"
+msgstr ""
+
+#: models.py:3182
+msgid "Scheduled"
+msgstr ""
+
+#: models.py:3183
+msgid "In progress"
+msgstr ""
+
+#: models.py:3198
+msgid "Result"
+msgstr ""
+
+#: models.py:3201
+msgid "Administration task"
+msgstr ""
+
+#: models.py:3202
+msgid "Administration tasks"
+msgstr ""
+
+#: models.py:3206
+msgid "Unknown"
+msgstr ""
+
+#: models.py:3221
+msgid ""
+"ISHTAR_SCRIPT_DIR is not set in your local_settings. Contact your "
+"administrator."
+msgstr ""
+
+#: models.py:3230
+msgid ""
+"Your ISHTAR_SCRIPT_DIR is containing dots \"..\". As it can refer to "
+"relative paths, it can be a security issue and this is not allowed. Only put "
+"a full path."
+msgstr ""
+
+#: models.py:3241
+msgid "Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory."
+msgstr ""
+
+#: models.py:3257
+msgid ""
+"Script \"{}\" is not available in your script directory. Check your "
+"configuration."
+msgstr ""
+
#: utils.py:100
msgid " (...)"
msgstr ""
diff --git a/ishtar_common/management/commands/ishtar_excute_admin_tasks.py b/ishtar_common/management/commands/ishtar_excute_admin_tasks.py
new file mode 100644
index 000000000..3fe66ad3b
--- /dev/null
+++ b/ishtar_common/management/commands/ishtar_excute_admin_tasks.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from django.core.management.base import BaseCommand, CommandError
+
+from ishtar_common import models
+
+
+class Command(BaseCommand):
+ help = "./manage.py ishtar_execute_admin_tasks\n\n"\
+ "Launch pending administration tasks."
+
+ def handle(self, *args, **options):
+ for task in models.AdministrationTask.objects.filter(state='S').all():
+ task.execute()
diff --git a/ishtar_common/migrations/0077_auto__add_administrationscript__add_administrationtask.py b/ishtar_common/migrations/0077_auto__add_administrationscript__add_administrationtask.py
new file mode 100644
index 000000000..b6f2680e6
--- /dev/null
+++ b/ishtar_common/migrations/0077_auto__add_administrationscript__add_administrationtask.py
@@ -0,0 +1,530 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'AdministrationScript'
+ db.create_table('ishtar_common_administrationscript', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('path', self.gf('django.db.models.fields.CharField')(max_length=30)),
+ ('name', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('ishtar_common', ['AdministrationScript'])
+
+ # Adding model 'AdministrationTask'
+ db.create_table('ishtar_common_administrationtask', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('script', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.AdministrationScript'])),
+ ('state', self.gf('django.db.models.fields.CharField')(default='S', max_length=2)),
+ ('creation_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('launch_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('finished_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('result', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('ishtar_common', ['AdministrationTask'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'AdministrationScript'
+ db.delete_table('ishtar_common_administrationscript')
+
+ # Deleting model 'AdministrationTask'
+ db.delete_table('ishtar_common_administrationtask')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.administrationscript': {
+ 'Meta': {'ordering': "['name']", 'object_name': 'AdministrationScript'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'path': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.administrationtask': {
+ 'Meta': {'ordering': "['script']", 'object_name': 'AdministrationTask'},
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'finished_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'launch_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'result': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'script': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AdministrationScript']"}),
+ 'state': ('django.db.models.fields.CharField', [], {'default': "'S'", 'max_length': '2'})
+ },
+ 'ishtar_common.arrondissement': {
+ 'Meta': {'object_name': 'Arrondissement'},
+ 'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.author': {
+ 'Meta': {'ordering': "('author_type__order', 'person__name')", 'object_name': 'Author'},
+ 'author_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AuthorType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'author'", 'to': "orm['ishtar_common.Person']"})
+ },
+ 'ishtar_common.authortype': {
+ 'Meta': {'ordering': "['order', 'label']", 'object_name': 'AuthorType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.canton': {
+ 'Meta': {'object_name': 'Canton'},
+ 'arrondissement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Arrondissement']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.department': {
+ 'Meta': {'ordering': "['number']", 'object_name': 'Department'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.State']", 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.documenttemplate': {
+ 'Meta': {'ordering': "['associated_object_name', 'name']", 'object_name': 'DocumentTemplate'},
+ 'associated_object_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'template': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.format': {
+ 'Meta': {'ordering': "['label']", 'object_name': 'Format'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.formatertype': {
+ 'Meta': {'ordering': "('formater_type', 'options')", 'unique_together': "(('formater_type', 'options', 'many_split'),)", 'object_name': 'FormaterType'},
+ 'formater_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'many_split': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'options': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.globalvar': {
+ 'Meta': {'ordering': "['slug']", 'object_name': 'GlobalVar'},
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.historicalorganization': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalOrganization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'organization_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.historicalperson': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalPerson'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'attached_to_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'title_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.import': {
+ 'Meta': {'object_name': 'Import'},
+ 'conservative_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
+ 'encoding': ('django.db.models.fields.CharField', [], {'default': "'utf-8'", 'max_length': '15'}),
+ 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'error_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '220'}),
+ 'imported_images': ('django.db.models.fields.files.FileField', [], {'max_length': '220', 'null': 'True', 'blank': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.ImporterType']"}),
+ 'match_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'seconds_remaining': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'skip_lines': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'state': ('django.db.models.fields.CharField', [], {'default': "'C'", 'max_length': '2'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']"})
+ },
+ 'ishtar_common.importercolumn': {
+ 'Meta': {'ordering': "('importer_type', 'col_number')", 'unique_together': "(('importer_type', 'col_number'),)", 'object_name': 'ImporterColumn'},
+ 'col_number': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'export_field_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'columns'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'regexp_pre_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'ishtar_common.importerdefault': {
+ 'Meta': {'object_name': 'ImporterDefault'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'defaults'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerdefaultvalues': {
+ 'Meta': {'object_name': 'ImporterDefaultValues'},
+ 'default_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'default_values'", 'to': "orm['ishtar_common.ImporterDefault']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerduplicatefield': {
+ 'Meta': {'object_name': 'ImporterDuplicateField'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'duplicate_fields'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+ 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'ishtar_common.importermodel': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'ImporterModel'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'klass': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'ishtar_common.importertype': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'ImporterType'},
+ 'associated_models': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['ishtar_common.ImporterModel']"}),
+ 'created_models': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.ImporterModel']"}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_template': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'unicity_keys': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.importtarget': {
+ 'Meta': {'object_name': 'ImportTarget'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'targets'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+ 'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'formater_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.FormaterType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'regexp_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.ishtarsiteprofile': {
+ 'Meta': {'ordering': "['label']", 'object_name': 'IshtarSiteProfile'},
+ 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'base_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(0, 0, 0, 0)'", 'max_length': '200'}),
+ 'base_find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{context_record__external_id}-{label}'"}),
+ 'container_external_id': ('django.db.models.fields.TextField', [], {'default': "'{responsible__external_id}-{index}'"}),
+ 'context_record': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'context_record_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(210,200,0,0.2)'", 'max_length': '200'}),
+ 'context_record_external_id': ('django.db.models.fields.TextField', [], {'default': "'{parcel__external_id}-{label}'"}),
+ 'currency': ('django.db.models.fields.CharField', [], {'default': "u'\\u20ac'", 'max_length': "'5'"}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'file_external_id': ('django.db.models.fields.TextField', [], {'default': "'{year}-{numeric_reference}'"}),
+ 'files': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'files_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(0, 32, 210, 0.1)'", 'max_length': '200'}),
+ 'find': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'find_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(210,0,0,0.15)'", 'max_length': '200'}),
+ 'find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{get_first_base_find__context_record__external_id}-{label}'"}),
+ 'find_index': ('django.db.models.fields.CharField', [], {'default': "'O'", 'max_length': '2'}),
+ 'homepage': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.TextField', [], {}),
+ 'mapping': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'mapping_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(72, 236, 0, 0.15)'", 'max_length': '200'}),
+ 'parcel_external_id': ('django.db.models.fields.TextField', [], {'default': "'{associated_file__external_id}{operation__code_patriarche}-{town__numero_insee}-{section}{parcel_number}'"}),
+ 'person_raw_name': ('django.db.models.fields.TextField', [], {'default': "'{name|upper} {surname}'"}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'warehouse': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'warehouse_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(10,20,200,0.15)'", 'max_length': '200'}),
+ 'warehouse_external_id': ('django.db.models.fields.TextField', [], {'default': "'{name|slug}'"})
+ },
+ 'ishtar_common.ishtaruser': {
+ 'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']},
+ 'advanced_shortcut_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ishtaruser'", 'unique': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
+ },
+ 'ishtar_common.itemkey': {
+ 'Meta': {'object_name': 'ItemKey'},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {})
+ },
+ 'ishtar_common.operationtype': {
+ 'Meta': {'ordering': "['-preventive', 'order', 'label']", 'object_name': 'OperationType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'preventive': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.organization': {
+ 'Meta': {'object_name': 'Organization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_organization'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'organization_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.OrganizationType']"}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.organizationtype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'OrganizationType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.person': {
+ 'Meta': {'object_name': 'Person'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}),
+ 'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
+ 'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'members'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['ishtar_common.Organization']"}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_person'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'person_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.PersonType']", 'symmetrical': 'False'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.TitleType']", 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.persontype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'PersonType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.regexp': {
+ 'Meta': {'object_name': 'Regexp'},
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'regexp': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.sourcetype': {
+ 'Meta': {'ordering': "['label']", 'object_name': 'SourceType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.spatialreferencesystem': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'SpatialReferenceSystem'},
+ 'auth_name': ('django.db.models.fields.CharField', [], {'default': "'EPSG'", 'max_length': '256'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
+ 'srid': ('django.db.models.fields.IntegerField', [], {}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.state': {
+ 'Meta': {'ordering': "['number']", 'object_name': 'State'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'})
+ },
+ 'ishtar_common.supporttype': {
+ 'Meta': {'object_name': 'SupportType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.targetkey': {
+ 'Meta': {'unique_together': "(('target', 'key', 'associated_user', 'associated_import'),)", 'object_name': 'TargetKey'},
+ 'associated_import': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}),
+ 'associated_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_set': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'key': ('django.db.models.fields.TextField', [], {}),
+ 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'keys'", 'to': "orm['ishtar_common.ImportTarget']"}),
+ 'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.titletype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'TitleType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'ishtar_common.town': {
+ 'Meta': {'ordering': "['numero_insee']", 'object_name': 'Town'},
+ 'canton': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Canton']", 'null': 'True', 'blank': 'True'}),
+ 'center': ('django.contrib.gis.db.models.fields.PointField', [], {'srid': '27572', 'null': 'True', 'blank': 'True'}),
+ 'departement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_town'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'numero_insee': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}),
+ 'surface': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['ishtar_common'] \ No newline at end of file
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 83127f2f0..0277ddefb 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -28,9 +28,11 @@ from PIL import Image
from importlib import import_module
import logging
import os
+from os.path import isfile, join
import re
from secretary import Renderer as SecretaryRenderer
import shutil
+from subprocess import Popen, PIPE
import tempfile
import time
import unicodecsv
@@ -3036,7 +3038,7 @@ post_delete.connect(post_save_cache, sender=Format)
class Source(OwnPerms, ImageModel, models.Model):
title = models.CharField(_(u"Title"), max_length=300)
- external_id = models.CharField(_(u"External ID"), max_length=12, null=True,
+ external_id = models.TextField(_(u"External ID"), max_length=300, null=True,
blank=True)
source_type = models.ForeignKey(SourceType, verbose_name=_(u"Type"))
support_type = models.ForeignKey(SupportType, verbose_name=_(u"Support"),
@@ -3196,3 +3198,123 @@ class SpatialReferenceSystem(GeneralType):
ordering = ('label',)
post_save.connect(post_save_cache, sender=SpatialReferenceSystem)
post_delete.connect(post_save_cache, sender=SpatialReferenceSystem)
+
+
+class AdministrationScript(models.Model):
+ path = models.CharField(_(u"Filename"), max_length=30)
+ name = models.TextField(_(u"Name"),
+ null=True, blank=True)
+
+ class Meta:
+ verbose_name = _(u"Administration script")
+ verbose_name_plural = _(u"Administration scripts")
+ ordering = ['name']
+
+ def __unicode__(self):
+ return unicode(self.name)
+
+
+SCRIPT_STATE = (("S", _(u"Scheduled")),
+ ("P", _(u"In progress")),
+ ("FE", _(u"Finished with errors")),
+ ("F", _(u"Finished")),
+ )
+
+SCRIPT_STATE_DCT = dict(SCRIPT_STATE)
+
+
+class AdministrationTask(models.Model):
+ script = models.ForeignKey(AdministrationScript)
+ state = models.CharField(_(u"State"), max_length=2, choices=SCRIPT_STATE,
+ default='S')
+ creation_date = models.DateTimeField(default=datetime.datetime.now)
+ launch_date = models.DateTimeField(null=True, blank=True)
+ finished_date = models.DateTimeField(null=True, blank=True)
+ result = models.TextField(_(u"Result"), null=True, blank=True)
+
+ class Meta:
+ verbose_name = _(u"Administration task")
+ verbose_name_plural = _(u"Administration tasks")
+ ordering = ['script']
+
+ def __unicode__(self):
+ state = _(u"Unknown")
+ if self.state in SCRIPT_STATE_DCT:
+ state = unicode(SCRIPT_STATE_DCT[self.state])
+ return u"{} - {} - {}".format(self.script, self.creation_date,
+ state)
+
+ def execute(self):
+ if self.state != 'S':
+ return
+ self.launch_date = datetime.datetime.now()
+
+ script_dir = settings.ISHTAR_SCRIPT_DIR
+
+ if not script_dir:
+ self.result = unicode(
+ _(u"ISHTAR_SCRIPT_DIR is not set in your "
+ u"local_settings. Contact your administrator."))
+ self.state = 'FE'
+ self.finished_date = datetime.datetime.now()
+ self.save()
+ return
+
+ if '..' in script_dir:
+ self.result = unicode(
+ _(u"Your ISHTAR_SCRIPT_DIR is containing "
+ u"dots \"..\". As it can refer to relative "
+ u"paths, it can be a security issue and this is "
+ u"not allowed. Only put a full path."))
+ self.state = 'FE'
+ self.finished_date = datetime.datetime.now()
+ self.save()
+ return
+
+ if not os.path.isdir(script_dir):
+ self.result = unicode(
+ _(u"Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory.")
+ ).format(script_dir)
+ self.state = 'FE'
+ self.finished_date = datetime.datetime.now()
+ self.save()
+ return
+
+ script_name = None
+ # only script inside the script directory can be executed
+ for name in os.listdir(script_dir):
+ if name == self.script.path:
+ if isfile(join(script_dir, name)):
+ script_name = join(script_dir, name)
+ break
+ if not script_name:
+ self.result = unicode(
+ _(u"Script \"{}\" is not available in your script directory. "
+ u"Check your configuration.")
+ ).format(self.script.path)
+ self.state = 'FE'
+ self.finished_date = datetime.datetime.now()
+ self.save()
+ return
+ self.state = 'P'
+ self.save()
+
+ self.finished_date = datetime.datetime.now()
+ try:
+ session = Popen([script_name], stdout=PIPE, stderr=PIPE)
+ stdout, stderr = session.communicate()
+ except OSError as e:
+ self.state = 'FE'
+ self.result = u"Error executing \"{}\" script: {}".format(
+ self.script.path, e)
+ self.save()
+ return
+
+ self.finished_date = datetime.datetime.now()
+ if stderr:
+ self.state = 'FE'
+ self.result = u"Error: {}".format(stderr)
+ else:
+ self.state = 'F'
+ self.result = u"{}".format(stdout)
+ self.save()
diff --git a/ishtar_common/templates/blocks/form_snippet.html b/ishtar_common/templates/blocks/form_snippet.html
index 2f841e078..5ee88e25f 100644
--- a/ishtar_common/templates/blocks/form_snippet.html
+++ b/ishtar_common/templates/blocks/form_snippet.html
@@ -10,4 +10,7 @@
</tr>
<tr class="help_text" id="{{field.auto_id}}_help">
<td colspan="3"><div>{{field.help_text}}</div></td>
- {%endif%}</tr>{% else %}{{field}}{% endif %}{% endfor %}
+ {%endif%}</tr>{% else %}{{field}}{% if field.errors %}
+ <tr class='errors'>
+ <td colspan='3'>{{field.name}} - {{ field.errors }}</td>
+ </tr>{% endif %}{{field|safe}}{% endif %}{% endfor %}
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index 63b46c40c..d89c8546c 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -192,9 +192,11 @@ class WizardTest(object):
self.wizard_name):
[current_step],
}
+
+ # reconstruct a POST request
if current_step in form_data:
d = form_data[current_step]
- if type(d) in (list, tuple): # formset
+ if type(d) in (list, tuple): # is a formset
for d_idx, item in enumerate(d):
for k in item:
data['{}-{}-{}'.format(
@@ -209,16 +211,21 @@ class WizardTest(object):
response = self.client.post(
url, data, follow=not next_form_is_checked)
except ValidationError as e:
- # on ManagementForm data is missing or has been tampered
- # error verify the wizard_name or step name
- raise ValidationError(u"Errors: {} on {}.".format(
- u" - ".join(e.messages), current_step))
+ msg = u"Errors: {} on {}. On \"ManagementForm data is " \
+ u"missing or...\" error verify the wizard_name or " \
+ u"step name".format(u" - ".join(e.messages),
+ current_step)
+ raise ValidationError(msg)
self.check_response(response, current_step)
if next_form_is_checked:
next_form = self.steps[idx + 1][0]
self.assertRedirects(
response,
- '/{}/{}'.format(self.url_name, next_form))
+ '/{}/{}'.format(self.url_name, next_form),
+ msg_prefix="Redirection to {} has failed - "
+ "Error on previous form ({})?".format(
+ next_form, current_step)
+ )
if idx == len(self.steps) - 1:
# last form
self.assertRedirects(