diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/admin.py | 8 | ||||
| -rw-r--r-- | ishtar_common/context_processors.py | 14 | ||||
| -rw-r--r-- | ishtar_common/fixtures/groups_person_types-SRA-fr.json | 22 | ||||
| -rw-r--r-- | ishtar_common/locale/django.pot | 525 | ||||
| -rw-r--r-- | ishtar_common/management/commands/update_specific_importers.py | 7 | ||||
| -rw-r--r-- | ishtar_common/menu_base.py | 31 | ||||
| -rw-r--r-- | ishtar_common/migrations/0048_auto__add_ishtarsiteprofile.py | 374 | ||||
| -rw-r--r-- | ishtar_common/models.py | 174 | ||||
| -rw-r--r-- | ishtar_common/static/media/style.css | 2 | ||||
| -rw-r--r-- | ishtar_common/templates/blocks/comma_list.html | 1 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/window_tables/static_documents.html | 11 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html | 2 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/sheet_person.html | 6 | ||||
| -rw-r--r-- | ishtar_common/templates/sheet_ope.html | 6 | ||||
| -rw-r--r-- | ishtar_common/templatetags/window_tables.py | 54 | ||||
| -rw-r--r-- | ishtar_common/tests.py | 156 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 3 | ||||
| -rw-r--r-- | ishtar_common/views.py | 39 | ||||
| -rw-r--r-- | ishtar_common/widgets.py | 18 | 
19 files changed, 1051 insertions, 402 deletions
| diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index f8cc34208..b7ad530b7 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -93,6 +93,14 @@ admin.site.unregister(Group)  admin.site.register(Group, MyGroupAdmin) +class IshtarSiteProfileAdmin(admin.ModelAdmin): +    list_display = ('label', 'slug', 'active', 'files', 'context_record', +                    'find', 'warehouse') +    model = models.IshtarSiteProfile + +admin.site.register(models.IshtarSiteProfile, IshtarSiteProfileAdmin) + +  class DepartmentAdmin(admin.ModelAdmin):      list_display = ('number', 'label',)      model = models.Department diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py index ce303c344..03ba9bc36 100644 --- a/ishtar_common/context_processors.py +++ b/ishtar_common/context_processors.py @@ -25,18 +25,20 @@ from ishtar_common.utils import shortify  from menus import Menu +from ishtar_common.models import get_current_profile  from archaeological_operations.models import Operation +from archaeological_files.models import File +from archaeological_context_records.models import ContextRecord +from archaeological_finds.models import Find +profile = get_current_profile()  CURRENT_ITEMS = [] -if 'archaeological_files' in settings.INSTALLED_APPS: -    from archaeological_files.models import File +if profile.files:      CURRENT_ITEMS.append((_(u"Archaeological file"), File))  CURRENT_ITEMS.append((_(u"Operation"), Operation)) -if 'archaeological_context_records' in settings.INSTALLED_APPS: -    from archaeological_context_records.models import ContextRecord +if profile.context_record:      CURRENT_ITEMS.append((_(u"Context record"), ContextRecord)) -if 'archaeological_finds' in settings.INSTALLED_APPS: -    from archaeological_finds.models import Find +if profile.find:      CURRENT_ITEMS.append((_(u"Find"), Find)) diff --git a/ishtar_common/fixtures/groups_person_types-SRA-fr.json b/ishtar_common/fixtures/groups_person_types-SRA-fr.json index 6a3044cdd..92fabaccd 100644 --- a/ishtar_common/fixtures/groups_person_types-SRA-fr.json +++ b/ishtar_common/fixtures/groups_person_types-SRA-fr.json @@ -112,7 +112,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_contextrecord", -            "name": "Can view all Context Record", +            "name": "Can view all Context Records",              "content_type": 50          }      }, @@ -382,7 +382,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_file", -            "name": "Can view all Archaelogical file", +            "name": "Can view all Archaelogical files",              "content_type": 29          }      }, @@ -589,7 +589,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_basefind", -            "name": "Can view all Base find", +            "name": "Can view all Base finds",              "content_type": 58          }      }, @@ -688,7 +688,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_find", -            "name": "Can view all Find", +            "name": "Can view all Finds",              "content_type": 60          }      }, @@ -931,7 +931,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_treatment", -            "name": "Can view all Treatment", +            "name": "Can view all Treatments",              "content_type": 64          }      }, @@ -1075,7 +1075,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_administrativeact", -            "name": "Can view all Administrative act", +            "name": "Can view all Administrative acts",              "content_type": 40          }      }, @@ -1147,7 +1147,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_archaeologicalsite", -            "name": "Can view all Archaeological site", +            "name": "Can view all Archaeological sites",              "content_type": 69          }      }, @@ -1282,7 +1282,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_operation", -            "name": "Can view all Operation", +            "name": "Can view all Operations",              "content_type": 35          }      }, @@ -1381,7 +1381,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_operationsource", -            "name": "Can view all Operation source", +            "name": "Can view all Operation sources",              "content_type": 37          }      }, @@ -1624,7 +1624,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_warehouse", -            "name": "Can view all Warehouse", +            "name": "Can view all Warehouses",              "content_type": 53          }      }, @@ -2038,7 +2038,7 @@          "model": "auth.permission",          "fields": {              "codename": "view_organization", -            "name": "Can view all Organization", +            "name": "Can view all Organizations",              "content_type": 15          }      }, diff --git a/ishtar_common/locale/django.pot b/ishtar_common/locale/django.pot index bb230179f..6f2d58879 100644 --- a/ishtar_common/locale/django.pot +++ b/ishtar_common/locale/django.pot @@ -3,6 +3,7 @@  # This file is distributed under the same license as the Ishtar package.  # Étienne Loks <etienne.loks at peacefrogs net>, 2010-2015.  # Étienne Loks <etienne.loks@iggdrasil.net>, 2015. #zanata +# Valérie-Emma Leroux <emma@iggdrasil.net>, 2016. #zanata  # Étienne Loks <etienne.loks@iggdrasil.net>, 2016. #zanata  msgid ""  msgstr "" @@ -19,19 +20,19 @@ msgstr ""  msgid "Related item"  msgstr "" -#: context_processors.py:33 +#: context_processors.py:37  msgid "Archaeological file"  msgstr "" -#: context_processors.py:34 models.py:1178 +#: context_processors.py:38 models.py:1251  msgid "Operation"  msgstr "" -#: context_processors.py:37 +#: context_processors.py:40  msgid "Context record"  msgstr "" -#: context_processors.py:40 +#: context_processors.py:42  msgid "Find"  msgstr "" @@ -170,12 +171,12 @@ msgstr ""  msgid "Add a new item"  msgstr "" -#: forms.py:171 models.py:993 +#: forms.py:171 models.py:1058  msgid "Template"  msgstr ""  #: forms_common.py:39 forms_common.py:57 forms_common.py:169 -#: forms_common.py:269 forms_common.py:274 models.py:1059 models.py:2274 +#: forms_common.py:269 forms_common.py:274 models.py:1124 models.py:2340  #: templates/blocks/JQueryAdvancedTown.html:19  #: templates/ishtar/sheet_organization.html:17  msgid "Town" @@ -191,64 +192,64 @@ msgid ""  "french town Saint-Denis in the Seine-Saint-Denis department.</p>"  msgstr "" -#: forms_common.py:66 forms_common.py:648 ishtar_menu.py:42 models.py:1973 -#: models.py:2102 models.py:2156 templates/ishtar/sheet_person.html:6 +#: forms_common.py:66 forms_common.py:648 ishtar_menu.py:42 models.py:2039 +#: models.py:2168 models.py:2222 templates/ishtar/sheet_person.html:6  msgid "Person"  msgstr "" -#: forms_common.py:157 forms_common.py:231 ishtar_menu.py:66 models.py:1895 +#: forms_common.py:157 forms_common.py:231 ishtar_menu.py:66 models.py:1961  #: templates/ishtar/sheet_organization.html:6  msgid "Organization"  msgstr ""  #: forms_common.py:160 forms_common.py:196 forms_common.py:226 -#: forms_common.py:259 models.py:992 models.py:1228 models.py:1445 -#: models.py:1889 models.py:1963 models.py:2260 +#: forms_common.py:259 models.py:775 models.py:1057 models.py:1293 +#: models.py:1511 models.py:1955 models.py:2029 models.py:2326  #: templates/ishtar/sheet_organization.html:12  #: templates/ishtar/sheet_organization.html:25  msgid "Name"  msgstr "" -#: forms_common.py:161 models.py:1173 models.py:1576 +#: forms_common.py:161 models.py:1238 models.py:1642  msgid "Organization type"  msgstr "" -#: forms_common.py:163 forms_common.py:263 models.py:1054 +#: forms_common.py:163 forms_common.py:263 models.py:1119  #: templates/ishtar/sheet_organization.html:14  msgid "Address"  msgstr "" -#: forms_common.py:165 forms_common.py:265 models.py:1055 +#: forms_common.py:165 forms_common.py:265 models.py:1120  #: templates/ishtar/sheet_organization.html:15  msgid "Address complement"  msgstr "" -#: forms_common.py:167 forms_common.py:267 models.py:1057 +#: forms_common.py:167 forms_common.py:267 models.py:1122  #: templates/ishtar/sheet_organization.html:16  msgid "Postal code"  msgstr "" -#: forms_common.py:170 forms_common.py:270 models.py:1060 +#: forms_common.py:170 forms_common.py:270 models.py:1125  msgid "Country"  msgstr ""  #: forms_common.py:172 forms_common.py:228 forms_common.py:272 -#: forms_common.py:376 models.py:1066 +#: forms_common.py:376 models.py:1131  msgid "Email"  msgstr "" -#: forms_common.py:173 forms_common.py:273 models.py:1062 +#: forms_common.py:173 forms_common.py:273 models.py:1127  #: templates/ishtar/sheet_organization.html:18  msgid "Phone"  msgstr "" -#: forms_common.py:174 models.py:1063 +#: forms_common.py:174 models.py:1128  #: templates/ishtar/sheet_organization.html:19  msgid "Mobile phone"  msgstr "" -#: forms_common.py:197 forms_common.py:229 models.py:1600 models.py:1891 -#: models.py:2197 templates/sheet_ope.html:85 templates/sheet_ope.html.py:105 +#: forms_common.py:197 forms_common.py:229 models.py:1666 models.py:1957 +#: models.py:2263 templates/sheet_ope.html:85 templates/sheet_ope.html.py:105  #: templates/sheet_ope.html:126 templates/ishtar/import_list.html:13  #: templates/ishtar/sheet_organization.html:27  #: templates/ishtar/sheet_person.html:56 @@ -256,16 +257,16 @@ msgstr ""  msgid "Type"  msgstr "" -#: forms_common.py:206 views.py:109 +#: forms_common.py:206 views.py:114  msgid "Organization search"  msgstr "" -#: forms_common.py:227 forms_common.py:257 models.py:1961 +#: forms_common.py:227 forms_common.py:257 models.py:2027  #: templates/ishtar/sheet_organization.html:26  msgid "Surname"  msgstr "" -#: forms_common.py:243 views.py:83 +#: forms_common.py:243 views.py:88  msgid "Person search"  msgstr "" @@ -273,14 +274,14 @@ msgstr ""  msgid "Identity"  msgstr "" -#: forms_common.py:256 forms_common.py:574 forms_common.py:615 models.py:1959 -#: models.py:2194 templates/sheet_ope.html:104 +#: forms_common.py:256 forms_common.py:574 forms_common.py:615 models.py:2025 +#: models.py:2260 templates/sheet_ope.html:104  #: templates/ishtar/sheet_person.html:55  #: templates/ishtar/blocks/window_tables/documents.html:5  msgid "Title"  msgstr "" -#: forms_common.py:261 models.py:1965 +#: forms_common.py:261 models.py:2031  msgid "Raw name"  msgstr "" @@ -288,7 +289,7 @@ msgstr ""  msgid "Current organization"  msgstr "" -#: forms_common.py:325 forms_common.py:355 forms_common.py:359 models.py:1943 +#: forms_common.py:325 forms_common.py:355 forms_common.py:359 models.py:2009  msgid "Person type"  msgstr "" @@ -296,7 +297,7 @@ msgstr ""  msgid "Account"  msgstr "" -#: forms_common.py:379 wizards.py:1146 +#: forms_common.py:379 wizards.py:1154  msgid "New password"  msgstr "" @@ -320,7 +321,7 @@ msgstr ""  msgid "Send the new password by email?"  msgstr "" -#: forms_common.py:430 forms_common.py:443 models.py:2275 +#: forms_common.py:430 forms_common.py:443 models.py:2341  msgid "Towns"  msgstr "" @@ -336,7 +337,7 @@ msgstr ""  msgid "Documentation informations"  msgstr "" -#: forms_common.py:576 forms_common.py:616 models.py:1577 models.py:2177 +#: forms_common.py:576 forms_common.py:616 models.py:1643 models.py:2243  msgid "Source type"  msgstr "" @@ -348,41 +349,41 @@ msgstr ""  msgid "Internal reference"  msgstr "" -#: forms_common.py:584 models.py:2208 +#: forms_common.py:584 models.py:2274  msgid "Numerical ressource (web address)"  msgstr "" -#: forms_common.py:585 models.py:2210 +#: forms_common.py:585 models.py:2276  msgid "Receipt date"  msgstr "" -#: forms_common.py:587 models.py:1727 models.py:2212 +#: forms_common.py:587 models.py:1793 models.py:2278  msgid "Creation date"  msgstr "" -#: forms_common.py:590 models.py:2215 +#: forms_common.py:590 models.py:2281  msgid "Receipt date in documentation"  msgstr "" -#: forms_common.py:592 forms_common.py:620 models.py:260 models.py:1472 -#: models.py:2222 +#: forms_common.py:592 forms_common.py:620 models.py:277 models.py:1538 +#: models.py:2288  msgid "Comment"  msgstr "" -#: forms_common.py:594 forms_common.py:619 models.py:1232 models.py:1404 -#: models.py:1446 models.py:2221 templates/sheet_ope.html:128 +#: forms_common.py:594 forms_common.py:619 models.py:777 models.py:1297 +#: models.py:1470 models.py:1512 models.py:2287 templates/sheet_ope.html:128  msgid "Description"  msgstr "" -#: forms_common.py:597 models.py:2223 +#: forms_common.py:597 models.py:2289  msgid "Additional information"  msgstr "" -#: forms_common.py:599 forms_common.py:623 models.py:2225 +#: forms_common.py:599 forms_common.py:623 models.py:2291  msgid "Has a duplicate"  msgstr "" -#: forms_common.py:612 forms_common.py:641 forms_common.py:674 models.py:2161 +#: forms_common.py:612 forms_common.py:641 forms_common.py:674 models.py:2227  #: templates/ishtar/wizard/wizard_person_deletion.html:124  msgid "Author"  msgstr "" @@ -395,7 +396,7 @@ msgstr ""  msgid "Would you like to delete this documentation?"  msgstr "" -#: forms_common.py:649 models.py:1578 models.py:2151 models.py:2158 +#: forms_common.py:649 models.py:1644 models.py:2217 models.py:2224  msgid "Author type"  msgstr "" @@ -407,7 +408,7 @@ msgstr ""  msgid "There are identical authors."  msgstr "" -#: forms_common.py:685 models.py:2162 models.py:2204 +#: forms_common.py:685 models.py:2228 models.py:2270  #: templates/sheet_ope.html:106  #: templates/ishtar/blocks/window_tables/documents.html:7  msgid "Authors" @@ -417,11 +418,11 @@ msgstr ""  msgid "Administration"  msgstr "" -#: ishtar_menu.py:31 views.py:135 +#: ishtar_menu.py:31 views.py:140  msgid "Account management"  msgstr "" -#: ishtar_menu.py:34 models.py:776 views.py:1116 +#: ishtar_menu.py:34 models.py:853 views.py:1115  msgid "Global variables"  msgstr "" @@ -445,19 +446,19 @@ msgstr ""  msgid "Merge"  msgstr "" -#: ishtar_menu.py:61 ishtar_menu.py:88 models.py:1764 widgets.py:110 +#: ishtar_menu.py:61 ishtar_menu.py:88 models.py:1830 widgets.py:110  msgid "Delete"  msgstr "" -#: ishtar_menu.py:96 models.py:1738 +#: ishtar_menu.py:96 models.py:1804  msgid "Imports"  msgstr "" -#: ishtar_menu.py:99 views.py:1124 +#: ishtar_menu.py:99 views.py:1123  msgid "New import"  msgstr "" -#: ishtar_menu.py:103 views.py:1138 +#: ishtar_menu.py:103 views.py:1137  msgid "Current imports"  msgstr "" @@ -470,690 +471,726 @@ msgid "Not a valid item."  msgstr ""  #: models.py:191 -msgid "An item selected is not a valid item." +msgid "A selected item is not a valid item."  msgstr ""  #: models.py:202 -msgid "This item already exist." +msgid "This item already exists."  msgstr "" -#: models.py:256 models.py:1027 models.py:1039 +#: models.py:273 models.py:1092 models.py:1104  msgid "Label"  msgstr "" -#: models.py:258 +#: models.py:275  msgid "Textual ID"  msgstr "" -#: models.py:261 models.py:996 +#: models.py:278 models.py:1061  msgid "Available"  msgstr "" -#: models.py:474 models.py:1518 +#: models.py:479 models.py:1584  msgid "Key"  msgstr "" -#: models.py:480 -msgid "Key specific to an import" +#: models.py:485 +msgid "Specific key to an import"  msgstr "" -#: models.py:551 +#: models.py:556  msgid "Last editor"  msgstr "" -#: models.py:554 +#: models.py:559  msgid "Creator"  msgstr "" -#: models.py:687 models.py:2286 +#: models.py:692 models.py:2352  msgid "Order"  msgstr "" -#: models.py:688 +#: models.py:693  msgid "Symmetrical"  msgstr "" -#: models.py:701 +#: models.py:706  msgid "Cannot have symmetrical and an inverse_relation"  msgstr "" -#: models.py:769 +#: models.py:776 models.py:1295 +msgid "Slug" +msgstr "" + +#: models.py:778 +msgid "Files module" +msgstr "" + +#: models.py:779 +msgid "Context records module" +msgstr "" + +#: models.py:781 +msgid "Finds module" +msgstr "" + +#: models.py:782 +msgid "Need context records module" +msgstr "" + +#: models.py:784 +msgid "Warehouses module" +msgstr "" + +#: models.py:785 +msgid "Need finds module" +msgstr "" + +#: models.py:786 +msgid "Current active" +msgstr "" + +#: models.py:789 +msgid "Ishtar site profile" +msgstr "" + +#: models.py:790 +msgid "Ishtar site profiles" +msgstr "" + +#: models.py:846  msgid "Variable name"  msgstr "" -#: models.py:770 +#: models.py:847  msgid "Description of the variable"  msgstr "" -#: models.py:772 models.py:1519 +#: models.py:849 models.py:1585  msgid "Value"  msgstr "" -#: models.py:775 +#: models.py:852  msgid "Global variable"  msgstr "" -#: models.py:897 models.py:927 +#: models.py:962 models.py:992  msgid "Total"  msgstr "" -#: models.py:904 models.py:1028 models.py:1040 +#: models.py:969 models.py:1093 models.py:1105  #: templates/ishtar/dashboards/dashboard_main_detail.html:135  #: templates/ishtar/dashboards/dashboard_main_detail_users.html:26  msgid "Number"  msgstr "" -#: models.py:991 +#: models.py:1056  msgid "Administrative Act"  msgstr "" -#: models.py:995 +#: models.py:1060  msgid "Associated object"  msgstr "" -#: models.py:999 +#: models.py:1064  msgid "Document template"  msgstr "" -#: models.py:1000 +#: models.py:1065  msgid "Document templates"  msgstr "" -#: models.py:1031 models.py:1041 models.py:1722 +#: models.py:1096 models.py:1106 models.py:1788  msgid "State"  msgstr "" -#: models.py:1045 templates/blocks/JQueryAdvancedTown.html:12 +#: models.py:1110 templates/blocks/JQueryAdvancedTown.html:12  msgid "Department"  msgstr "" -#: models.py:1046 +#: models.py:1111  msgid "Departments"  msgstr "" -#: models.py:1100 +#: models.py:1165  msgid "Tel: "  msgstr "" -#: models.py:1104 +#: models.py:1169  msgid "Mobile: "  msgstr "" -#: models.py:1108 +#: models.py:1173  msgid "Email: "  msgstr "" -#: models.py:1113 +#: models.py:1178  msgid "Merge key"  msgstr "" -#: models.py:1174 +#: models.py:1239  msgid "Organization types"  msgstr "" -#: models.py:1180 +#: models.py:1253  msgid "Archaeological site"  msgstr "" -#: models.py:1181 +#: models.py:1254  msgid "Parcels"  msgstr "" -#: models.py:1183 +#: models.py:1256  msgid "Operation source"  msgstr "" -#: models.py:1189 views.py:931 views.py:988 +#: models.py:1259 views.py:940 views.py:991  msgid "Archaeological files"  msgstr "" -#: models.py:1196 views.py:934 views.py:998 +#: models.py:1261 views.py:943 views.py:999  msgid "Context records"  msgstr "" -#: models.py:1199 views.py:936 views.py:1003 +#: models.py:1263 views.py:945 views.py:1002  msgid "Finds"  msgstr "" -#: models.py:1230 -msgid "Slug" -msgstr "" - -#: models.py:1234 templates/ishtar/dashboards/dashboard_main.html:26 +#: models.py:1299 templates/ishtar/dashboards/dashboard_main.html:26  msgid "Users"  msgstr "" -#: models.py:1236 +#: models.py:1301  msgid "Associated model"  msgstr "" -#: models.py:1238 +#: models.py:1304  msgid "Is template"  msgstr "" -#: models.py:1239 +#: models.py:1305  msgid "Unicity keys (separator \";\")"  msgstr "" -#: models.py:1243 +#: models.py:1309  msgid "Importer - Type"  msgstr "" -#: models.py:1244 +#: models.py:1310  msgid "Importer - Types"  msgstr "" -#: models.py:1334 +#: models.py:1400  msgid "Importer - Default"  msgstr "" -#: models.py:1335 +#: models.py:1401  msgid "Importer - Defaults"  msgstr "" -#: models.py:1370 +#: models.py:1436  msgid "Importer - Default value"  msgstr "" -#: models.py:1371 +#: models.py:1437  msgid "Importer - Default values"  msgstr "" -#: models.py:1403 +#: models.py:1469  msgid "Column number"  msgstr "" -#: models.py:1406 +#: models.py:1472  msgid "Required"  msgstr "" -#: models.py:1409 +#: models.py:1475  msgid "Importer - Column"  msgstr "" -#: models.py:1410 +#: models.py:1476  msgid "Importer - Columns"  msgstr "" -#: models.py:1430 +#: models.py:1496  msgid "Field name"  msgstr "" -#: models.py:1432 models.py:1466 -msgid "Force creation of new item" +#: models.py:1498 models.py:1532 +msgid "Force creation of new items"  msgstr "" -#: models.py:1434 models.py:1468 +#: models.py:1500 models.py:1534  msgid "Concatenate with existing"  msgstr "" -#: models.py:1436 models.py:1470 +#: models.py:1502 models.py:1536  msgid "Concatenate character"  msgstr "" -#: models.py:1440 +#: models.py:1506  msgid "Importer - Duplicate field"  msgstr "" -#: models.py:1441 +#: models.py:1507  msgid "Importer - Duplicate fields"  msgstr "" -#: models.py:1448 +#: models.py:1514  msgid "Regular expression"  msgstr "" -#: models.py:1451 +#: models.py:1517  msgid "Importer - Regular expression"  msgstr "" -#: models.py:1452 +#: models.py:1518  msgid "Importer - Regular expressions"  msgstr "" -#: models.py:1475 +#: models.py:1541  msgid "Importer - Target"  msgstr "" -#: models.py:1476 +#: models.py:1542  msgid "Importer - Targets"  msgstr "" -#: models.py:1500 views.py:306 +#: models.py:1566 views.py:311  msgid "True"  msgstr "" -#: models.py:1501 views.py:308 +#: models.py:1567 views.py:313  msgid "False"  msgstr "" -#: models.py:1520 +#: models.py:1586  msgid "Is set"  msgstr "" -#: models.py:1527 +#: models.py:1593  msgid "Importer - Target key"  msgstr "" -#: models.py:1528 +#: models.py:1594  msgid "Importer - Targets keys"  msgstr "" -#: models.py:1579 models.py:2189 models.py:2200 +#: models.py:1645 models.py:2255 models.py:2266  msgid "Format"  msgstr "" -#: models.py:1580 models.py:2290 +#: models.py:1646 models.py:2356  msgid "Operation type"  msgstr "" -#: models.py:1581 +#: models.py:1647  msgid "Period"  msgstr "" -#: models.py:1582 +#: models.py:1648  msgid "Unit"  msgstr "" -#: models.py:1583 +#: models.py:1649  msgid "Material"  msgstr "" -#: models.py:1585 +#: models.py:1651  msgid "Conservatory state"  msgstr "" -#: models.py:1586 +#: models.py:1652  msgid "Preservation type"  msgstr "" -#: models.py:1587 +#: models.py:1653  msgid "Object type"  msgstr "" -#: models.py:1589 +#: models.py:1655  msgid "Identification type"  msgstr "" -#: models.py:1590 models.py:2183 +#: models.py:1656 models.py:2249  msgid "Support type"  msgstr "" -#: models.py:1596 +#: models.py:1662  msgid "Integer"  msgstr "" -#: models.py:1597 +#: models.py:1663  msgid "Float"  msgstr "" -#: models.py:1598 +#: models.py:1664  msgid "String"  msgstr "" -#: models.py:1599 templates/sheet_ope.html:86 +#: models.py:1665 templates/sheet_ope.html:86  msgid "Date"  msgstr "" -#: models.py:1601 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83 +#: models.py:1667 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83  #: templates/ishtar/sheet_person.html:54  #: templates/ishtar/dashboards/dashboard_main_detail.html:120  msgid "Year"  msgstr "" -#: models.py:1602 +#: models.py:1668  msgid "String to boolean"  msgstr "" -#: models.py:1603 +#: models.py:1669  msgctxt "filesystem"  msgid "File"  msgstr "" -#: models.py:1604 +#: models.py:1670  msgid "Unknow type"  msgstr "" -#: models.py:1620 +#: models.py:1686  msgid "4 digit year. e.g.: \"2015\""  msgstr "" -#: models.py:1621 +#: models.py:1687  msgid "4 digit year/month/day. e.g.: \"2015/02/04\""  msgstr "" -#: models.py:1622 +#: models.py:1688  msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""  msgstr "" -#: models.py:1632 +#: models.py:1698  msgid "Options"  msgstr "" -#: models.py:1634 +#: models.py:1700  msgid "Split character(s)"  msgstr "" -#: models.py:1638 +#: models.py:1704  msgid "Importer - Formater type"  msgstr "" -#: models.py:1639 +#: models.py:1705  msgid "Importer - Formater types"  msgstr "" -#: models.py:1686 templates/ishtar/dashboards/dashboard_main_detail.html:61 +#: models.py:1752 templates/ishtar/dashboards/dashboard_main_detail.html:61  msgid "Created"  msgstr "" -#: models.py:1687 +#: models.py:1753  msgid "Analyse in progress"  msgstr "" -#: models.py:1688 +#: models.py:1754  msgid "Analysed"  msgstr "" -#: models.py:1689 +#: models.py:1755  msgid "Import pending"  msgstr "" -#: models.py:1690 +#: models.py:1756  msgid "Import in progress"  msgstr "" -#: models.py:1691 +#: models.py:1757  msgid "Finished with errors"  msgstr "" -#: models.py:1692 +#: models.py:1758  msgid "Finished"  msgstr "" -#: models.py:1693 +#: models.py:1759  msgid "Archived"  msgstr "" -#: models.py:1705 +#: models.py:1771  msgid "Imported file"  msgstr "" -#: models.py:1708 +#: models.py:1774  msgid "Associated images (zip file)"  msgstr "" -#: models.py:1710 +#: models.py:1776  msgid "Encoding"  msgstr "" -#: models.py:1712 +#: models.py:1778  msgid "Skip lines"  msgstr "" -#: models.py:1713 templates/ishtar/import_list.html:47 +#: models.py:1779 templates/ishtar/import_list.html:47  msgid "Error file"  msgstr "" -#: models.py:1716 +#: models.py:1782  msgid "Result file"  msgstr "" -#: models.py:1719 templates/ishtar/import_list.html:53 +#: models.py:1785 templates/ishtar/import_list.html:53  msgid "Match file"  msgstr "" -#: models.py:1725 +#: models.py:1791  msgid "Conservative import"  msgstr "" -#: models.py:1730 +#: models.py:1796  msgid "End date"  msgstr "" -#: models.py:1732 -msgid "Seconds remaining" +#: models.py:1798 +msgid "Remaining seconds"  msgstr "" -#: models.py:1737 +#: models.py:1803  msgid "Import"  msgstr "" -#: models.py:1754 +#: models.py:1820  msgid "Analyse"  msgstr "" -#: models.py:1756 models.py:1759 +#: models.py:1822 models.py:1825  msgid "Re-analyse"  msgstr "" -#: models.py:1757 +#: models.py:1823  msgid "Launch import"  msgstr "" -#: models.py:1760 +#: models.py:1826  msgid "Re-import"  msgstr "" -#: models.py:1761 +#: models.py:1827  msgid "Archive"  msgstr "" -#: models.py:1763 +#: models.py:1829  msgid "Unarchive"  msgstr "" -#: models.py:1896 +#: models.py:1962  msgid "Organizations"  msgstr "" -#: models.py:1898 -msgid "Can view all Organization" +#: models.py:1964 +msgid "Can view all Organizations"  msgstr "" -#: models.py:1899 +#: models.py:1965  msgid "Can view own Organization"  msgstr "" -#: models.py:1900 +#: models.py:1966  msgid "Can add own Organization"  msgstr "" -#: models.py:1902 +#: models.py:1968  msgid "Can change own Organization"  msgstr "" -#: models.py:1904 +#: models.py:1970  msgid "Can delete own Organization"  msgstr "" -#: models.py:1939 +#: models.py:2005  msgid "Groups"  msgstr "" -#: models.py:1944 +#: models.py:2010  msgid "Person types"  msgstr "" -#: models.py:1951 +#: models.py:2017  msgid "Mr"  msgstr "" -#: models.py:1952 +#: models.py:2018  msgid "Miss"  msgstr "" -#: models.py:1953 -msgid "Mr and Miss" +#: models.py:2019 +msgid "Mr and Mrs"  msgstr "" -#: models.py:1954 +#: models.py:2020  msgid "Mrs"  msgstr "" -#: models.py:1955 +#: models.py:2021  msgid "Doctor"  msgstr "" -#: models.py:1967 models.py:2014 +#: models.py:2033 models.py:2080  msgid "Types"  msgstr "" -#: models.py:1970 +#: models.py:2036  msgid "Is attached to"  msgstr "" -#: models.py:1974 +#: models.py:2040  msgid "Persons"  msgstr "" -#: models.py:1976 -msgid "Can view all Person" +#: models.py:2042 +msgid "Can view all Persons"  msgstr "" -#: models.py:1977 +#: models.py:2043  msgid "Can view own Person"  msgstr "" -#: models.py:1978 +#: models.py:2044  msgid "Can add own Person"  msgstr "" -#: models.py:1979 +#: models.py:2045  msgid "Can change own Person"  msgstr "" -#: models.py:1980 +#: models.py:2046  msgid "Can delete own Person"  msgstr "" -#: models.py:2106 +#: models.py:2172  msgid "Ishtar user"  msgstr "" -#: models.py:2107 +#: models.py:2173  msgid "Ishtar users"  msgstr "" -#: models.py:2152 +#: models.py:2218  msgid "Author types"  msgstr "" -#: models.py:2178 +#: models.py:2244  msgid "Source types"  msgstr "" -#: models.py:2184 +#: models.py:2250  msgid "Support types"  msgstr "" -#: models.py:2190 +#: models.py:2256  msgid "Formats"  msgstr "" -#: models.py:2195 +#: models.py:2261  msgid "External ID"  msgstr "" -#: models.py:2198 +#: models.py:2264  msgid "Support"  msgstr "" -#: models.py:2202 +#: models.py:2268  msgid "Scale"  msgstr "" -#: models.py:2216 +#: models.py:2282  msgid "Item number"  msgstr "" -#: models.py:2217 +#: models.py:2283  msgid "Ref."  msgstr "" -#: models.py:2220 +#: models.py:2286  msgid "Internal ref."  msgstr "" -#: models.py:2261 +#: models.py:2327  msgid "Surface (m2)"  msgstr "" -#: models.py:2262 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107 +#: models.py:2328 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107  msgid "Localisation"  msgstr "" -#: models.py:2287 +#: models.py:2353  msgid "Is preventive"  msgstr "" -#: models.py:2291 +#: models.py:2357  msgid "Operation types"  msgstr "" -#: models.py:2317 +#: models.py:2383  msgid "Preventive"  msgstr "" -#: models.py:2318 +#: models.py:2384  msgid "Research"  msgstr "" -#: utils.py:50 +#: utils.py:51  msgid " (...)"  msgstr "" -#: views.py:90 +#: views.py:95  msgid "New person"  msgstr "" -#: views.py:98 +#: views.py:103  msgid "Person modification"  msgstr "" -#: views.py:104 +#: views.py:109  msgid "Person deletion"  msgstr "" -#: views.py:115 +#: views.py:120  msgid "New organization"  msgstr "" -#: views.py:122 +#: views.py:127  msgid "Organization modification"  msgstr "" -#: views.py:128 +#: views.py:133  msgid "Organization deletion"  msgstr "" -#: views.py:632 templates/base.html:80 +#: views.py:637 templates/base.html:80  #: templates/ishtar/sheet_organization.html:35  #: templatetags/link_to_window.py:16  msgid "Details"  msgstr "" -#: views.py:860 views.py:914 +#: views.py:868 views.py:922  msgid "Operation not permitted."  msgstr "" -#: views.py:862 +#: views.py:870  #, python-format  msgid "New %s"  msgstr "" -#: views.py:932 views.py:992 +#: views.py:941 views.py:995  msgid "Operations"  msgstr "" -#: views.py:1185 templates/ishtar/import_list.html:43 +#: views.py:1184 templates/ishtar/import_list.html:43  msgid "Link unmatched items"  msgstr "" -#: views.py:1200 +#: views.py:1199  msgid "Delete import"  msgstr "" -#: views.py:1259 views.py:1275 +#: views.py:1258 views.py:1274  msgid "Corporation manager"  msgstr "" @@ -1161,27 +1198,27 @@ msgstr ""  msgid "Search..."  msgstr "" -#: widgets.py:596 templatetags/window_tables.py:72 +#: widgets.py:602 templatetags/window_tables.py:80  msgid "No results"  msgstr "" -#: widgets.py:597 templatetags/window_tables.py:73 +#: widgets.py:603 templatetags/window_tables.py:81  msgid "Loading..."  msgstr "" -#: widgets.py:598 +#: widgets.py:604  msgid "Remove"  msgstr "" -#: wizards.py:317 templates/ishtar/import_delete.html:20 +#: wizards.py:318 templates/ishtar/import_delete.html:20  msgid "Yes"  msgstr "" -#: wizards.py:319 +#: wizards.py:320  msgid "No"  msgstr "" -#: wizards.py:1203 +#: wizards.py:1211  #, python-format  msgid "[%(app_name)s] Account creation/modification"  msgstr "" @@ -1465,7 +1502,7 @@ msgid "No document associated to this operation"  msgstr ""  #: templates/sheet_ope.html:121 templates/sheet_ope.html.py:123 -msgid "Recording Units" +msgid "Context Records"  msgstr ""  #: templates/sheet_ope.html:125 @@ -1477,7 +1514,7 @@ msgid "Chronology"  msgstr ""  #: templates/sheet_ope.html:142 -msgid "No recording unit associated to this operation" +msgid "No context record associated to this operation"  msgstr ""  #: templates/window.html:38 templates/blocks/JQueryJqGrid.html:25 @@ -1522,6 +1559,18 @@ msgstr ""  msgid "An error as occured during search. Check your query fields."  msgstr "" +#: templates/blocks/comma_list.html:1 +msgid "and" +msgstr "" + +#: templates/blocks/comma_list.html:1 +msgid ", " +msgstr "" + +#: templates/blocks/comma_list.html:1 +msgid "." +msgstr "" +  #: templates/blocks/form_flex_snippet.html:10  #: templates/blocks/form_snippet.html:9  msgid "Help" @@ -1776,7 +1825,7 @@ msgid "Modified"  msgstr ""  #: templates/ishtar/dashboards/dashboard_main_detail.html:108 -msgid "No data for theses criteria." +msgid "No data for these criteria."  msgstr ""  #: templates/ishtar/dashboards/dashboard_main_detail.html:126 diff --git a/ishtar_common/management/commands/update_specific_importers.py b/ishtar_common/management/commands/update_specific_importers.py index c5445eb0b..9a13e3f3e 100644 --- a/ishtar_common/management/commands/update_specific_importers.py +++ b/ishtar_common/management/commands/update_specific_importers.py @@ -4,14 +4,11 @@  from optparse import make_option  from django.core.management.base import BaseCommand -from django.conf import settings  IMPORTERS = [] - -if 'archaeological_files' in settings.INSTALLED_APPS: -    from archaeological_files.data_importer import FileImporterSraPdL -    IMPORTERS.append(FileImporterSraPdL) +from archaeological_files.data_importer import FileImporterSraPdL +IMPORTERS.append(FileImporterSraPdL)  class Command(BaseCommand): diff --git a/ishtar_common/menu_base.py b/ishtar_common/menu_base.py index ab0a43d41..eb08d8c78 100644 --- a/ishtar_common/menu_base.py +++ b/ishtar_common/menu_base.py @@ -17,16 +17,28 @@  # See the file COPYING for details. +from ishtar_common.models import get_current_profile +  class SectionItem: -    def __init__(self, idx, label, childs=[]): +    def __init__(self, idx, label, childs=[], profile_restriction=None):          self.idx = idx          self.label = label          self.childs = childs          self.available = False          self.items = {} +        self.profile_restriction = profile_restriction + +    def check_profile_restriction(self): +        if self.profile_restriction: +            profile = get_current_profile() +            if not getattr(profile, self.profile_restriction): +                return False +        return True      def can_be_available(self, user, session=None): +        if not self.check_profile_restriction(): +            return False          for child in self.childs:              if child.can_be_available(user, session=session):                  return True @@ -50,14 +62,27 @@ class SectionItem:  class MenuItem: -    def __init__(self, idx, label, model=None, access_controls=[]): +    def __init__(self, idx, label, model=None, access_controls=[], +                 profile_restriction=None):          self.idx = idx          self.label = label          self.model = model          self.access_controls = access_controls          self.available = False +        self.profile_restriction = profile_restriction +        if not self.check_profile_restriction(): +            return False + +    def check_profile_restriction(self): +        if self.profile_restriction: +            profile = get_current_profile() +            if not getattr(profile, self.profile_restriction): +                return False +        return True      def can_be_available(self, user, session=None): +        if not self.check_profile_restriction(): +            return False          if not self.access_controls:              return True          prefix = (self.model._meta.app_label + '.') if self.model else '' @@ -75,6 +100,8 @@ class MenuItem:          return False      def is_available(self, user, obj=None, session=None): +        if not self.check_profile_restriction(): +            return False          if not self.access_controls:              return True          prefix = (self.model._meta.app_label + '.') if self.model else '' diff --git a/ishtar_common/migrations/0048_auto__add_ishtarsiteprofile.py b/ishtar_common/migrations/0048_auto__add_ishtarsiteprofile.py new file mode 100644 index 000000000..5a2c21bf1 --- /dev/null +++ b/ishtar_common/migrations/0048_auto__add_ishtarsiteprofile.py @@ -0,0 +1,374 @@ +# -*- 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 'IshtarSiteProfile' +        db.create_table('ishtar_common_ishtarsiteprofile', ( +            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), +            ('label', self.gf('django.db.models.fields.TextField')()), +            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)), +            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), +            ('files', self.gf('django.db.models.fields.BooleanField')(default=False)), +            ('context_record', self.gf('django.db.models.fields.BooleanField')(default=False)), +            ('find', self.gf('django.db.models.fields.BooleanField')(default=False)), +            ('warehouse', self.gf('django.db.models.fields.BooleanField')(default=False)), +            ('active', self.gf('django.db.models.fields.BooleanField')(default=False)), +        )) +        db.send_create_signal('ishtar_common', ['IshtarSiteProfile']) + + +    def backwards(self, orm): +        # Deleting model 'IshtarSiteProfile' +        db.delete_table('ishtar_common_ishtarsiteprofile') + + +    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.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': {'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': {'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'}), +            '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': {'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'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'exclude_from_merge': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', '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': '300'}), +            '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'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', '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': '100', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), +            'imported_images': ('django.db.models.fields.files.FileField', [], {'max_length': '100', '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': '100', 'null': 'True', 'blank': 'True'}), +            'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', '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'}), +            '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']"}), +            '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.importertype': { +            'Meta': {'object_name': 'ImporterType'}, +            'associated_models': ('django.db.models.fields.CharField', [], {'max_length': '200'}), +            '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'}), +            'context_record': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'files': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'find': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.TextField', [], {}), +            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), +            'warehouse': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) +        }, +        'ishtar_common.ishtaruser': { +            'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']}, +            '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'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'exclude_from_merge': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', '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': '300'}), +            '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'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', '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'}), +            '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']"}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'exclude_from_merge': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', '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'}), +            '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'}), +            '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'}), +            'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), +            'title': ('django.db.models.fields.CharField', [], {'max_length': '100', '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': {'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.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.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'}), +            '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 d7e63856b..2a12edc02 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -42,7 +42,7 @@ from django.core.urlresolvers import reverse, NoReverseMatch  from django.db.utils import DatabaseError  from django.db.models import Q, Max, Count  from django.db.models.base import ModelBase -from django.db.models.signals import post_save, pre_delete +from django.db.models.signals import post_save, pre_delete, post_delete  from django.utils.translation import ugettext_lazy as _, ugettext, \      pgettext_lazy @@ -188,7 +188,7 @@ def valid_ids(cls):                  cls.objects.get(pk=v)              except ObjectDoesNotExist:                  raise ValidationError( -                    _(u"An item selected is not a valid item.")) +                    _(u"A selected item is not a valid item."))      return func @@ -199,7 +199,7 @@ def is_unique(cls, field):          try:              assert cls.objects.filter(**query).count() == 0          except AssertionError: -            raise ValidationError(_(u"This item already exist.")) +            raise ValidationError(_(u"This item already exists."))      return func @@ -249,7 +249,24 @@ class OwnPerms:          return cls.objects.filter(query).order_by(*cls._meta.ordering) -class GeneralType(models.Model): +class Cached(object): +    slug_field = 'txt_idx' + +    @classmethod +    def get_cache(cls, slug): +        cache_key, value = get_cache(cls, slug) +        if value: +            return value +        try: +            k = {cls.slug_field: slug} +            obj = cls.objects.get(**k) +            cache.set(cache_key, obj, settings.CACHE_TIMEOUT) +            return obj +        except cls.DoesNotExist: +            return None + + +class GeneralType(models.Model, Cached):      """      Abstract class for "types"      """ @@ -457,18 +474,6 @@ class GeneralType(models.Model):          for item in cls.objects.all():              item.generate_key() -    @classmethod -    def get_cache(cls, slug): -        cache_key, value = get_cache(cls, slug) -        if value: -            return value -        try: -            obj = cls.objects.get(txt_idx=slug) -            cache.set(cache_key, obj, settings.CACHE_TIMEOUT) -            return obj -        except cls.DoesNotExist: -            return None -  class ItemKey(models.Model):      key = models.CharField(_(u"Key"), max_length=100) @@ -477,7 +482,7 @@ class ItemKey(models.Model):      content_object = generic.GenericForeignKey('content_type', 'object_id')      importer = models.ForeignKey(          'Import', null=True, blank=True, -        help_text=_(u"Key specific to an import")) +        help_text=_(u"Specific key to an import"))      def __unicode__(self):          return self.key @@ -765,7 +770,79 @@ class LightHistorizedItem(BaseHistorizedItem):          return True -class GlobalVar(models.Model): +class IshtarSiteProfile(models.Model, Cached): +    slug_field = 'slug' +    label = models.TextField(_(u"Name")) +    slug = models.SlugField(_(u"Slug"), unique=True) +    description = models.TextField(_(u"Description"), null=True, blank=True) +    files = models.BooleanField(_(u"Files module"), default=False) +    context_record = models.BooleanField(_(u"Context records module"), +                                         default=False) +    find = models.BooleanField(_(u"Finds module"), default=False, +                               help_text=_(u"Need context records module")) +    warehouse = models.BooleanField( +        _(u"Warehouses module"), default=False, +        help_text=_(u"Need finds module")) +    active = models.BooleanField(_(u"Current active"), default=False) + +    class Meta: +        verbose_name = _(u"Ishtar site profile") +        verbose_name_plural = _(u"Ishtar site profiles") +        ordering = ['label'] + +    def __unicode__(self): +        return unicode(self.label) + +    def save(self, *args, **kwargs): +        raw = False +        if 'raw' in kwargs: +            raw = kwargs.pop('raw') +        super(IshtarSiteProfile, self).save(*args, **kwargs) +        obj = self +        if raw: +            return obj +        q = self.__class__.objects.filter(active=True).exclude(slug=self.slug) +        if obj.active and q.count(): +            for profile in q.all(): +                profile.active = False +                profile.save(raw=True) +        changed = False +        if not obj.active and not q.count(): +            obj.active = True +            changed = True +        if obj.warehouse and not obj.find: +            obj.find = True +            changed = True +        if obj.find and not obj.context_record: +            obj.context_record = True +            changed = True +        if changed: +            obj = obj.save(raw=True) +        return obj + + +def get_current_profile(force=False): +    cache_key, value = get_cache(IshtarSiteProfile, ['is-current-profile']) +    if value and not force: +        return value +    q = IshtarSiteProfile.objects.filter(active=True) +    if not q.count(): +        obj = IshtarSiteProfile.objects.create( +            label="Default profile", slug='default', active=True) +    else: +        obj = q.all()[0] +    cache.set(cache_key, obj, settings.CACHE_TIMEOUT) +    return obj + + +def cached_site_changed(sender, **kwargs): +    get_current_profile(force=True) + +post_save.connect(cached_site_changed, sender=IshtarSiteProfile) +post_delete.connect(cached_site_changed, sender=IshtarSiteProfile) + + +class GlobalVar(models.Model, Cached):      slug = models.SlugField(_(u"Variable name"), unique=True)      description = models.TextField(_(u"Description of the variable"),                                     null=True, blank=True) @@ -779,18 +856,6 @@ class GlobalVar(models.Model):      def __unicode__(self):          return unicode(self.slug) -    @classmethod -    def get_cache(cls, slug): -        cache_key, value = get_cache(cls, slug) -        if value: -            return value -        try: -            obj = cls.objects.get(slug=slug) -            cache.set(cache_key, obj.value, settings.CACHE_TIMEOUT) -            return obj.value -        except cls.DoesNotExist: -            return None -  def cached_globalvar_changed(sender, **kwargs):      if not kwargs['instance']: @@ -1174,29 +1239,29 @@ class OrganizationType(GeneralType):          verbose_name_plural = _(u"Organization types")          ordering = ('label',) -MODELS = [ -    ('archaeological_operations.models.Operation', _(u"Operation")), -    ('archaeological_operations.models.ArchaeologicalSite', -     _(u"Archaeological site")), -    ('archaeological_operations.models.Parcel', _(u"Parcels")), -    ('archaeological_operations.models.OperationSource', -     _(u"Operation source")), -] -  IMPORTER_CLASSES = {} -if 'archaeological_files' in settings.INSTALLED_APPS: -    MODELS = [('archaeological_files.models.File', _(u"Archaeological files"))]\ -        + MODELS -    IMPORTER_CLASSES.update({ -        'sra-pdl-files': -        'archaeological_files.data_importer.FileImporterSraPdL'}) -if 'archaeological_context_records' in settings.INSTALLED_APPS: +IMPORTER_CLASSES.update({ +    'sra-pdl-files': +    'archaeological_files.data_importer.FileImporterSraPdL'}) + + +def get_importer_models(): +    MODELS = [ +        ('archaeological_operations.models.Operation', _(u"Operation")), +        ('archaeological_operations.models.ArchaeologicalSite', +         _(u"Archaeological site")), +        ('archaeological_operations.models.Parcel', _(u"Parcels")), +        ('archaeological_operations.models.OperationSource', +         _(u"Operation source")), +    ] +    MODELS = [('archaeological_files.models.File', +              _(u"Archaeological files"))] + MODELS      MODELS = [('archaeological_context_records.models.ContextRecord',                _(u"Context records")), ] + MODELS -if 'archaeological_finds' in settings.INSTALLED_APPS:      MODELS = [('archaeological_finds.models.BaseFind',                _(u"Finds")), ] + MODELS +    return MODELS  def get_model_fields(model): @@ -1234,7 +1299,8 @@ class ImporterType(models.Model):      users = models.ManyToManyField('IshtarUser', verbose_name=_(u"Users"),                                     blank=True, null=True)      associated_models = models.CharField(_(u"Associated model"), -                                         max_length=200, choices=MODELS) +                                         max_length=200, +                                         choices=get_importer_models())      is_template = models.BooleanField(_(u"Is template"), default=False)      unicity_keys = models.CharField(_(u"Unicity keys (separator \";\")"),                                      blank=True, null=True, max_length=500) @@ -1429,7 +1495,7 @@ class ImporterDuplicateField(models.Model):      column = models.ForeignKey(ImporterColumn, related_name='duplicate_fields')      field_name = models.CharField(_(u"Field name"), blank=True, null=True,                                    max_length=200) -    force_new = models.BooleanField(_(u"Force creation of new item"), +    force_new = models.BooleanField(_(u"Force creation of new items"),                                      default=False)      concat = models.BooleanField(_(u"Concatenate with existing"),                                   default=False) @@ -1463,7 +1529,7 @@ class ImportTarget(models.Model):      target = models.CharField(u"Target", max_length=500)      regexp_filter = models.ForeignKey("Regexp", blank=True, null=True)      formater_type = models.ForeignKey("FormaterType") -    force_new = models.BooleanField(_(u"Force creation of new item"), +    force_new = models.BooleanField(_(u"Force creation of new items"),                                      default=False)      concat = models.BooleanField(_(u"Concatenate with existing"),                                   default=False) @@ -1729,7 +1795,7 @@ class Import(models.Model):                                           null=True)      end_date = models.DateTimeField(_(u"End date"), blank=True,                                      null=True, editable=False) -    seconds_remaining = models.IntegerField(_(u"Seconds remaining"), +    seconds_remaining = models.IntegerField(_(u"Remaining seconds"),                                              blank=True, null=True,                                              editable=False) @@ -1895,7 +1961,7 @@ class Organization(Address, Merge, OwnPerms, ValueGetter):          verbose_name = _(u"Organization")          verbose_name_plural = _(u"Organizations")          permissions = ( -            ("view_organization", ugettext(u"Can view all Organization")), +            ("view_organization", ugettext(u"Can view all Organizations")),              ("view_own_organization", ugettext(u"Can view own Organization")),              ("add_own_organization", ugettext(u"Can add own Organization")),              ("change_own_organization", @@ -1950,7 +2016,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter):      TYPE = (          ('Mr', _(u'Mr')),          ('Ms', _(u'Miss')), -        ('Mr and Miss', _(u'Mr and Miss')), +        ('Mr and Miss', _(u'Mr and Mrs')),          ('Md', _(u'Mrs')),          ('Dr', _(u'Doctor')),      ) @@ -1973,7 +2039,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter):          verbose_name = _(u"Person")          verbose_name_plural = _(u"Persons")          permissions = ( -            ("view_person", ugettext(u"Can view all Person")), +            ("view_person", ugettext(u"Can view all Persons")),              ("view_own_person", ugettext(u"Can view own Person")),              ("add_own_person", ugettext(u"Can add own Person")),              ("change_own_person", ugettext(u"Can change own Person")), diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css index a4c62739b..2a0079706 100644 --- a/ishtar_common/static/media/style.css +++ b/ishtar_common/static/media/style.css @@ -371,7 +371,7 @@ div#main_menu > ul > li{      -webkit-border-radius:0;  } -#section-file_management, #section-administration, +#section-file_management,  #section-administrativact_management{      background-color:#ddffdd;  } diff --git a/ishtar_common/templates/blocks/comma_list.html b/ishtar_common/templates/blocks/comma_list.html new file mode 100644 index 000000000..12fcd2b41 --- /dev/null +++ b/ishtar_common/templates/blocks/comma_list.html @@ -0,0 +1 @@ +{% load i18n %}{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} {% trans "and" %} {% else %}{% trans ", "%}{% endifequal %}{% else %}{% trans "." %}{% endif %} diff --git a/ishtar_common/templates/ishtar/blocks/window_tables/static_documents.html b/ishtar_common/templates/ishtar/blocks/window_tables/static_documents.html new file mode 100644 index 000000000..d6686b553 --- /dev/null +++ b/ishtar_common/templates/ishtar/blocks/window_tables/static_documents.html @@ -0,0 +1,11 @@ +{% load i18n %} + +<table class='simple'> +  <caption>{{caption}}</caption> +  <tr>{% for col in col_names %} +    <th>{% trans col %}</th>{% endfor %} +  </tr>{% for item in data %} +  <tr>{% for value in item %} +    <td>{{value}}</td>{%endfor%} +  </tr>{% endfor %} +</table> diff --git a/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html b/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html index 87ce5c528..d7ea16d90 100644 --- a/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html +++ b/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html @@ -105,7 +105,7 @@ if (typeof values_1_{{unique_id}} === 'undefined'      || values_1_{{unique_id}}.length == 0){  $('#chart_img_{{unique_id}}').hide(); -$('#chart_{{unique_id}}').html("<p class='alert'>{% trans 'No data for theses criteria.' %}</p>"); +$('#chart_{{unique_id}}').html("<p class='alert'>{% trans 'No data for these criteria.' %}</p>");  } else {  var showmarker = false; diff --git a/ishtar_common/templates/ishtar/sheet_person.html b/ishtar_common/templates/ishtar/sheet_person.html index 2dfc4bbea..796fe2c4a 100644 --- a/ishtar_common/templates/ishtar/sheet_person.html +++ b/ishtar_common/templates/ishtar/sheet_person.html @@ -35,17 +35,17 @@  {% trans "Associated operations as scientist" as ao %}  {% if item.operation_scientist_responsability.count %} -{% dynamic_table_document ao 'operations' 'scientist' item.pk %} +{% dynamic_table_document ao 'operations' 'scientist' item.pk '' output %}  {% endif %}  {% trans "Associated operations as responsible" as ao %}  {% if item.operation_responsability.count %} -{% dynamic_table_document ao 'operations' 'in_charge' item.pk %} +{% dynamic_table_document ao 'operations' 'in_charge' item.pk '' output %}  {% endif %}  {% trans "Associated archaelogical files" as af %}  {% if item.file_responsability.count %} -{% dynamic_table_document af 'files' 'in_charge' item.pk %} +{% dynamic_table_document af 'files' 'in_charge' item.pk '' output %}  {% endif %}  <table> diff --git a/ishtar_common/templates/sheet_ope.html b/ishtar_common/templates/sheet_ope.html index dbe3297b3..28390af45 100644 --- a/ishtar_common/templates/sheet_ope.html +++ b/ishtar_common/templates/sheet_ope.html @@ -118,9 +118,9 @@    {% endfor %}  </table> -<h3>{% trans "Recording Units"%}</h3> +<h3>{% trans "Context Records"%}</h3>  <table> -  <caption>{%trans "Recording Units"%}</caption> +  <caption>{%trans "Context Records"%}</caption>    <tr>      <th>{% trans "ID" %}</th>      <th>{% trans "Type" %}</th> @@ -139,7 +139,7 @@      <td class='link'><a href="#{#{%url show-record_unit record_unit.pk%}#}">{% trans "Details" %}</a></td>    </tr>    {% empty %} -  <tr><td colspan="6" class='no_items'>{% trans "No recording unit associated to this operation" %}</td></tr> +  <tr><td colspan="6" class='no_items'>{% trans "No context record associated to this operation" %}</td></tr>    {% endfor %}  </table> diff --git a/ishtar_common/templatetags/window_tables.py b/ishtar_common/templatetags/window_tables.py index a1aa735a7..687b2cf49 100644 --- a/ishtar_common/templatetags/window_tables.py +++ b/ishtar_common/templatetags/window_tables.py @@ -1,8 +1,11 @@ +import json  import time  from django import template  from django.conf import settings +from django.core.urlresolvers import resolve  from django.template.defaultfilters import slugify +from django.template.loader import get_template  from django.utils.translation import ugettext_lazy as _  from ishtar_common.forms import reverse_lazy @@ -52,16 +55,21 @@ except:      pass -@register.inclusion_tag('ishtar/blocks/window_tables/dynamic_documents.html') -def dynamic_table_document(caption, associated_model, key, value, -                           table_cols='TABLE_COLS'): +@register.simple_tag(takes_context=True) +def dynamic_table_document(context, caption, associated_model, key, value, +                           table_cols='TABLE_COLS', output='html'): +    if not table_cols: +        table_cols = 'TABLE_COLS'      model, url, url_full = ASSOCIATED_MODELS[associated_model]      grid = JQueryJqGrid(None, None, model, table_cols=table_cols)      source = unicode(reverse_lazy(url))      source_full = unicode(reverse_lazy(url_full)) if url_full else ''      source_attrs = '?{}={}'.format(key, value) -    col_names, extra_cols = grid.get_cols() -    return {'caption': caption, +    if output == 'html': +        col_names, extra_cols = grid.get_cols() +        t = get_template('ishtar/blocks/window_tables/dynamic_documents.html') +        context = template.Context({ +            'caption': caption,              'name': slugify(caption) + '{}'.format(int(time.time())),              'source': source + source_attrs,              'source_full': source_full, @@ -72,4 +80,38 @@ def dynamic_table_document(caption, associated_model, key, value,              'no_result': unicode(_("No results")),              'loading': unicode(_("Loading...")),              'encoding': settings.ENCODING or 'utf-8', -            } +        }) +        return t.render(context) +    else: +        col_names, extra_cols = grid.get_cols(python=True) +        view, args, kwargs = resolve(source) +        request = context['request'] +        if source_attrs and source_attrs.startswith('?'): +            source_attrs = source_attrs[1:] +            dct = {} +            for attr in source_attrs.split('&'): +                if '=' in attr: +                    key, val = attr.split('=') +                    dct[key] = val +            request.GET = dct +        kwargs['request'] = request +        page = view(*args, **kwargs) +        data = [] +        if page.content: +            res = json.loads(page.content) +            if "rows" in res: +                for r in res["rows"]: +                    d = [] +                    for col in extra_cols: +                        if col in r: +                            d.append(r[col]) +                        else: +                            d.append('') +                    data.append(d) +        t = get_template('ishtar/blocks/window_tables/static_documents.html') +        context = template.Context({ +            'caption': caption, +            'col_names': col_names, +            'data': data +        }) +        return t.render(context) diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 621b05242..82ab009e0 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -17,18 +17,22 @@  # See the file COPYING for details. -import tempfile, datetime -from zipfile import ZipFile, ZIP_DEFLATED -  from django.conf import settings  from django.contrib.auth.models import User  from django.contrib.contenttypes.models import ContentType +from django.core.cache import cache +from django.core.urlresolvers import reverse  from django.template.defaultfilters import slugify  from django.test import TestCase +from django.test.client import Client  from ishtar_common import models  """ +from django.conf import settings +import tempfile, datetime +from zipfile import ZipFile, ZIP_DEFLATED +  from oook_replace.oook_replace import oook_replace  class OOOGenerationTest(TestCase): @@ -53,34 +57,36 @@ class OOOGenerationTest(TestCase):  class MergeTest(TestCase):      def setUp(self):          self.user, created = User.objects.get_or_create(username='username') -        self.organisation_types = models.OrganizationType.create_default_for_test() +        self.organisation_types = \ +            models.OrganizationType.create_default_for_test()          self.person_types = [models.PersonType.objects.create(label='Admin'),                               models.PersonType.objects.create(label='User')]          self.author_types = [models.AuthorType.objects.create(label='1'), -                             models.AuthorType.objects.create(label='2'),] +                             models.AuthorType.objects.create(label='2')]          self.company_1 = models.Organization.objects.create( -                    history_modifier=self.user, name='Franquin Comp.', -                    organization_type=self.organisation_types[0]) -        self.person_1 = models.Person.objects.create(name='Boule', -                surname=' ', -                history_modifier=self.user, attached_to=self.company_1) +            history_modifier=self.user, name='Franquin Comp.', +            organization_type=self.organisation_types[0]) +        self.person_1 = models.Person.objects.create( +            name='Boule', surname=' ', history_modifier=self.user, +            attached_to=self.company_1)          self.person_1.person_types.add(self.person_types[0]) -        self.author_1_pk = models.Author.objects.create(person=self.person_1, -                                            author_type=self.author_types[0]).pk +        self.author_1_pk = models.Author.objects.create( +            person=self.person_1, author_type=self.author_types[0]).pk          self.company_2 = models.Organization.objects.create( -                    history_modifier=self.user, name='Goscinny Corp.', -                    organization_type=self.organisation_types[1]) -        self.person_2 = models.Person.objects.create(name='Bill', -                history_modifier=self.user, surname='Peyo', title='Mr', -                attached_to=self.company_2) +            history_modifier=self.user, name='Goscinny Corp.', +            organization_type=self.organisation_types[1]) +        self.person_2 = models.Person.objects.create( +            name='Bill', history_modifier=self.user, surname='Peyo', +            title='Mr', attached_to=self.company_2)          self.person_2.person_types.add(self.person_types[1]) -        self.author_2_pk = models.Author.objects.create(person=self.person_2, -                                            author_type=self.author_types[1]).pk -        self.person_3 = models.Person.objects.create(name='George', -                history_modifier=self.user, attached_to=self.company_1) +        self.author_2_pk = models.Author.objects.create( +            person=self.person_2, author_type=self.author_types[1]).pk +        self.person_3 = models.Person.objects.create( +            name='George', history_modifier=self.user, +            attached_to=self.company_1)      def testPersonMerge(self):          self.person_1.merge(self.person_2) @@ -93,9 +99,11 @@ class MergeTest(TestCase):          # preserve existing foreign key          self.assertEqual(self.person_1.attached_to, self.company_1)          # preserve existing many to many -        self.assertTrue(self.person_types[0] in self.person_1.person_types.all()) +        self.assertTrue(self.person_types[0] +                        in self.person_1.person_types.all())          # add new many to many -        self.assertTrue(self.person_types[1] in self.person_1.person_types.all()) +        self.assertTrue(self.person_types[1] +                        in self.person_1.person_types.all())          # update reverse foreign key association and dont break the existing          self.assertEqual(models.Author.objects.get(pk=self.author_1_pk).person,                           self.person_1) @@ -104,32 +112,37 @@ class MergeTest(TestCase):          self.person_3.merge(self.person_1)          # manage well empty many to many fields -        self.assertTrue(self.person_types[1] in self.person_3.person_types.all()) +        self.assertTrue(self.person_types[1] +                        in self.person_3.person_types.all()) +  class ImportKeyTest(TestCase):      def testKeys(self): -        content_type = ContentType.objects.get_for_model(models.OrganizationType) +        content_type = ContentType.objects.get_for_model( +            models.OrganizationType)          # creation          label = u"Ploufé"          ot = models.OrganizationType.objects.create(label=label) -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot.pk, -                                    key=slugify(label), -                                    content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot.pk, key=slugify(label), +                         content_type=content_type).count(), 1)          label_2 = u"Plif"          ot_2 = models.OrganizationType.objects.create(label=label_2) -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, -                                    key=slugify(label_2), -                                    content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot_2.pk, key=slugify(label_2), +                         content_type=content_type).count(), 1)          # replace key          ot_2.add_key(slugify(label), force=True)          # one key point to only one item -        self.assertEqual(models.ItemKey.objects.filter(key=slugify(label), -                                    content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         key=slugify(label), +                         content_type=content_type).count(), 1)          # this key point to the right item -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, -                key=slugify(label), content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot_2.pk, key=slugify(label), +                         content_type=content_type).count(), 1)          # modification          label_3 = "Yop" @@ -137,14 +150,67 @@ class ImportKeyTest(TestCase):          ot_2.txt_idx = slugify(label_3)          ot_2.save()          # old label not referenced anymore -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, -                key=slugify(label_2), content_type=content_type).count(), 0) -        # forced key association is always here -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, -                key=slugify(label), content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot_2.pk, key=slugify(label_2), +                         content_type=content_type).count(), 0) +        # # forced key association is always here          # new key is here -        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, -                key=slugify(label_3), content_type=content_type).count(), 1) - - - +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot_2.pk, key=slugify(label), +                         content_type=content_type).count(), 1) +        self.assertEqual(models.ItemKey.objects.filter( +                         object_id=ot_2.pk, key=slugify(label_3), +                         content_type=content_type).count(), 1) + + +class IshtarSiteProfileTest(TestCase): +    def testRelevance(self): +        cache.set('default-ishtarsiteprofile-is-current-profile', None, +                  settings.CACHE_TIMEOUT) +        profile = models.get_current_profile() +        default_slug = profile.slug +        profile2 = models.IshtarSiteProfile.objects.create( +            label="Test profile 2", slug='test-profile-2') +        profile2.save() +        # when no profile is the current, activate by default the first created +        self.assertTrue(profile.active and not profile2.active) +        profile2.active = True +        profile2 = profile2.save() +        # only one profile active at a time +        profile = models.IshtarSiteProfile.objects.get(slug=default_slug) +        self.assertTrue(profile2.active and not profile.active) +        # activate find active automatically context records +        self.assertFalse(profile.context_record) +        profile.find = True +        profile = profile.save() +        self.assertTrue(profile.context_record) +        # activate warehouse active automatically context records and finds +        self.assertFalse(profile2.context_record or profile2.find) +        profile2.warehouse = True +        profile2 = profile2.save() +        self.assertTrue(profile2.context_record and profile2.find) + +    def testDefaultProfile(self): +        cache.set('default-ishtarsiteprofile-is-current-profile', None, +                  settings.CACHE_TIMEOUT) +        self.assertFalse(models.IshtarSiteProfile.objects.count()) +        profile = models.get_current_profile() +        self.assertTrue(profile) +        self.assertTrue(models.IshtarSiteProfile.objects.count()) + +    def testMenuFiltering(self): +        cache.set('default-ishtarsiteprofile-is-current-profile', None, +                  settings.CACHE_TIMEOUT) +        username = 'username4277' +        password = 'dcbqj756456!@%' +        User.objects.create_superuser(username, "nomail@nomail.com", +                                      password) +        c = Client() +        c.login(username=username, password=password) +        response = c.get(reverse('start')) +        self.assertFalse("section-file_management" in response.content) +        profile = models.get_current_profile() +        profile.files = True +        profile.save() +        response = c.get(reverse('start')) +        self.assertTrue("section-file_management" in response.content) diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 65bd1ee15..25ae6ddf5 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -17,13 +17,14 @@  # See the file COPYING for details. +from django.conf import settings  from django.core.cache import cache  from django.utils.translation import ugettext  from django.template.defaultfilters import slugify  def get_cache(cls, extra_args=[]): -    cache_key = cls.__name__ +    cache_key = u"{}-{}".format(settings.PROJECT_SLUG, cls.__name__)      for arg in extra_args:          if not arg:              cache_key += '-0' diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 6f95e070a..5ea53374d 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -51,7 +51,12 @@ from xhtml2odt import xhtml2odt  from menus import menu +from archaeological_files.models import File +from archaeological_context_records.models import ContextRecord +from archaeological_finds.models import Find +  from archaeological_operations.forms import DashboardForm as DashboardFormOpe +from archaeological_files.forms import DashboardForm as DashboardFormFile  from ishtar_common.forms import FinalForm, FinalDeleteForm  from ishtar_common import forms_common as forms @@ -724,6 +729,7 @@ def show_item(model, name, extra_dct=None):              dct.update(extra_dct(request, item))          context_instance = RequestContext(request)          context_instance.update(dct) +        context_instance['output'] = 'html'          filename = ""          if hasattr(item, 'history_object'):              filename = item.history_object.associated_filename @@ -731,6 +737,7 @@ def show_item(model, name, extra_dct=None):              filename = item.associated_filename          if doc_type == "odt" and settings.ODT_TEMPLATE:              tpl = loader.get_template('ishtar/sheet_%s.html' % name) +            context_instance['output'] = 'ODT'              content = tpl.render(context_instance)              try:                  tidy_options = {'output-xhtml': 1, 'indent': 1, @@ -770,6 +777,7 @@ def show_item(model, name, extra_dct=None):              return response          elif doc_type == 'pdf':              tpl = loader.get_template('ishtar/sheet_%s_pdf.html' % name) +            context_instance['output'] = 'PDF'              content = tpl.render(context_instance)              result = StringIO.StringIO()              html = content.encode('utf-8') @@ -927,22 +935,20 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs):      Main dashboard      """      app_list = [] -    if 'archaeological_files' in settings.INSTALLED_APPS: +    profile = models.get_current_profile() +    if profile.files:          app_list.append((_(u"Archaeological files"), 'files'))      app_list.append((_(u"Operations"), 'operations')) -    if 'archaeological_context_records' in settings.INSTALLED_APPS: +    if profile.context_record:          app_list.append((_(u"Context records"), 'contextrecords')) -    if 'archaeological_finds' in settings.INSTALLED_APPS: +    if profile.find:          app_list.append((_(u"Finds"), 'finds'))      dct = {'app_list': app_list}      return render_to_response('ishtar/dashboards/dashboard_main.html', dct,                                context_instance=RequestContext(request))  DASHBOARD_FORMS = {} -if 'archaeological_files' in settings.INSTALLED_APPS: -    from archaeological_files.forms import DashboardForm as DashboardFormFile -    DASHBOARD_FORMS['files'] = DashboardFormFile - +DASHBOARD_FORMS['files'] = DashboardFormFile  DASHBOARD_FORMS['operations'] = DashboardFormOpe @@ -957,8 +963,8 @@ def dashboard_main_detail(request, item_name):              dct, context_instance=RequestContext(request))      form = None      slicing, date_source, fltr, show_detail = 'year', None, {}, False -    if (item_name == 'files' and -        'archaeological_files' in settings.INSTALLED_APPS) \ +    profile = models.get_current_profile() +    if (item_name == 'files' and profile.files) \              or item_name == 'operations':          slicing = 'month'      if item_name in DASHBOARD_FORMS: @@ -974,32 +980,25 @@ def dashboard_main_detail(request, item_name):          else:              form = DASHBOARD_FORMS[item_name]()      lbl, dashboard = None, None -    if (item_name == 'files' and -        'archaeological_files' in settings.INSTALLED_APPS) \ +    if (item_name == 'files' and profile.files) \              or item_name == 'operations':          dashboard_kwargs = {'slice': slicing, 'fltr': fltr,                              'show_detail': show_detail}          # date_source is only relevant when the form has set one          if date_source:              dashboard_kwargs['date_source'] = date_source -    if item_name == 'files' and \ -            'archaeological_files' in settings.INSTALLED_APPS: -        from archaeological_files.models import File +    if item_name == 'files' and profile.files:          lbl, dashboard = (_(u"Archaeological files"),                            models.Dashboard(File, **dashboard_kwargs))      if item_name == 'operations':          from archaeological_operations.models import Operation          lbl, dashboard = (_(u"Operations"),                            models.Dashboard(Operation, **dashboard_kwargs)) -    if item_name == 'contextrecords' and \ -            'archaeological_context_records' in settings.INSTALLED_APPS: -        from archaeological_context_records.models import ContextRecord +    if item_name == 'contextrecords' and profile.context_record:          lbl, dashboard = (              _(u"Context records"),              models.Dashboard(ContextRecord, slice=slicing, fltr=fltr)) -    if item_name == 'finds' and \ -            'archaeological_finds' in settings.INSTALLED_APPS: -        from archaeological_finds.models import Find +    if item_name == 'finds' and profile.find:          lbl, dashboard = (_(u"Finds"), models.Dashboard(Find,                                                          slice=slicing,                                                          fltr=fltr)) diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 688648e10..57aa8cf69 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -524,7 +524,7 @@ class JQueryJqGrid(forms.RadioSelect):          self.new, self.new_message = new, new_message          self.source_full = source_full -    def get_cols(self): +    def get_cols(self, python=False):          jq_col_names, extra_cols = [], []          col_labels = {}          if hasattr(self.associated_model, self.table_cols + '_LBL'): @@ -557,13 +557,19 @@ class JQueryJqGrid(forms.RadioSelect):                  field_name += f_name                  field_verbose_names.append(unicode(field_verbose_name))              if field_name in col_labels: -                jq_col_names.append(u'"%s"' % unicode(col_labels[field_name])) +                jq_col_names.append(unicode(col_labels[field_name]))              else: -                jq_col_names.append(u'"%s"' % settings.JOINT.join( +                jq_col_names.append(settings.JOINT.join(                      [f for f in field_verbose_names if f])) -            extra_cols.append(self.COL_TPL % {'idx': field_name}) -        jq_col_names = jq_col_names and ", ".join(jq_col_names) or "" -        extra_cols = extra_cols and ", ".join(extra_cols) or "" +            if not python: +                jq_col_names[-1] = u'"%s"' % jq_col_names[-1] +            if python: +                extra_cols.append(field_name) +            else: +                extra_cols.append(self.COL_TPL % {'idx': field_name}) +        if not python: +            jq_col_names = jq_col_names and ", ".join(jq_col_names) or "" +            extra_cols = extra_cols and ", ".join(extra_cols) or ""          return jq_col_names, extra_cols      def render(self, name, value=None, attrs=None): | 
