src/pyams_thesaurus/zmi/thesaurus.py
changeset 87 dfe19304d980
parent 84 a3ca2f2dd419
child 90 f80eec0f148e
equal deleted inserted replaced
86:04f176e237cc 87:dfe19304d980
    35 from pyams_zmi.interfaces.menu import ISiteManagementMenu, IPropertiesMenu
    35 from pyams_zmi.interfaces.menu import ISiteManagementMenu, IPropertiesMenu
    36 from pyams_zmi.layer import IAdminLayer
    36 from pyams_zmi.layer import IAdminLayer
    37 from z3c.form.interfaces import IDataExtractedEvent, DISPLAY_MODE
    37 from z3c.form.interfaces import IDataExtractedEvent, DISPLAY_MODE
    38 
    38 
    39 # import packages
    39 # import packages
    40 from pyams_form.form import AJAXAddForm, AJAXEditForm
    40 from pyams_form.form import AJAXAddForm, ajax_config
    41 from pyams_form.schema import CloseButton
    41 from pyams_form.schema import CloseButton
    42 from pyams_pagelet.pagelet import pagelet_config
    42 from pyams_pagelet.pagelet import pagelet_config
    43 from pyams_skin.layer import IPyAMSLayer
    43 from pyams_skin.layer import IPyAMSLayer
    44 from pyams_skin.page import DefaultPageHeaderAdapter
    44 from pyams_skin.page import DefaultPageHeaderAdapter
    45 from pyams_skin.table import DefaultElementEditorAdapter
    45 from pyams_skin.table import DefaultElementEditorAdapter
   110     label_css_class = 'fa fa-fw fa-language'
   110     label_css_class = 'fa fa-fw fa-language'
   111     url = 'add-thesaurus.html'
   111     url = 'add-thesaurus.html'
   112     modal_target = True
   112     modal_target = True
   113 
   113 
   114 
   114 
   115 @pagelet_config(name='add-thesaurus.html', context=ISite, layer=IPyAMSLayer, permission=CREATE_THESAURUS_PERMISSION)
   115 @pagelet_config(name='add-thesaurus.html', context=ISite, layer=IPyAMSLayer,
       
   116                 permission=CREATE_THESAURUS_PERMISSION)
       
   117 @ajax_config(name='add-thesaurus.json', context=ISite, layer=IPyAMSLayer,
       
   118              permission=CREATE_THESAURUS_PERMISSION, base=AJAXAddForm)
   116 class ThesaurusAddForm(AdminDialogAddForm):
   119 class ThesaurusAddForm(AdminDialogAddForm):
   117     """Thesaurus add form"""
   120     """Thesaurus add form"""
   118 
   121 
   119     title = _("Utilities")
   122     title = _("Utilities")
   120     legend = _("Add new thesaurus")
   123     legend = _("Add new thesaurus")
   121     icon_css_class = 'fa fa-fw fa-language'
   124     icon_css_class = 'fa fa-fw fa-language'
   122 
   125 
   123     fields = field.Fields(IThesaurusInfo).select('name', 'title', 'subject', 'description', 'language', 'creator',
   126     fields = field.Fields(IThesaurusInfo).select('name', 'title', 'subject', 'description', 'language', 'creator',
   124                                                  'publisher', 'created')
   127                                                  'publisher', 'created')
   125     ajax_handler = 'add-thesaurus.json'
       
   126     edit_permission = None
   128     edit_permission = None
   127 
   129 
   128     def updateWidgets(self, prefix=None):
   130     def updateWidgets(self, prefix=None):
   129         super(ThesaurusAddForm, self).updateWidgets(prefix)
   131         super(ThesaurusAddForm, self).updateWidgets(prefix)
   130         if 'description' in self.widgets:
   132         if 'description' in self.widgets:
   137         manager = self.context.getSiteManager()
   139         manager = self.context.getSiteManager()
   138         manager['thesaurus::{0}'.format(object.name.lower())] = object
   140         manager['thesaurus::{0}'.format(object.name.lower())] = object
   139 
   141 
   140     def nextURL(self):
   142     def nextURL(self):
   141         return absolute_url(self.context, self.request, 'thesaurus.html')
   143         return absolute_url(self.context, self.request, 'thesaurus.html')
       
   144 
       
   145     def get_ajax_output(self, changes):
       
   146         return {
       
   147             'status': 'redirect',
       
   148             'location': absolute_url(self.context, self.request, 'admin#thesaurus.html'),
       
   149             'close_form': True
       
   150         }
   142 
   151 
   143 
   152 
   144 @subscriber(IDataExtractedEvent, form_selector=ThesaurusAddForm)
   153 @subscriber(IDataExtractedEvent, form_selector=ThesaurusAddForm)
   145 def handle_new_thesaurus_data_extraction(event):
   154 def handle_new_thesaurus_data_extraction(event):
   146     """Handle new thesaurus data extraction"""
   155     """Handle new thesaurus data extraction"""
   151     thesaurus = query_utility(IThesaurus, name=name)
   160     thesaurus = query_utility(IThesaurus, name=name)
   152     if thesaurus is not None:
   161     if thesaurus is not None:
   153         event.form.widgets.errors += (Invalid(_("A thesaurus is already registered with this name!")), )
   162         event.form.widgets.errors += (Invalid(_("A thesaurus is already registered with this name!")), )
   154 
   163 
   155 
   164 
   156 @view_config(name='add-thesaurus.json', context=ISite, request_type=IPyAMSLayer,
       
   157              permission=CREATE_THESAURUS_PERMISSION, renderer='json', xhr=True)
       
   158 class ThesaurusAJAXAddForm(AJAXAddForm, ThesaurusAddForm):
       
   159     """Thesaurus add form, AJAX view"""
       
   160 
       
   161     def get_ajax_output(self, changes):
       
   162         return {
       
   163             'status': 'redirect',
       
   164             'location': absolute_url(self.context, self.request, 'admin#thesaurus.html'),
       
   165             'close_form': True
       
   166         }
       
   167 
       
   168 
       
   169 @adapter_config(context=(IThesaurus, IAdminLayer, Interface), provides=ITableElementEditor)
   165 @adapter_config(context=(IThesaurus, IAdminLayer, Interface), provides=ITableElementEditor)
   170 class ThesaurusTableElementEditor(DefaultElementEditorAdapter):
   166 class ThesaurusTableElementEditor(DefaultElementEditorAdapter):
   171     """Thesaurus table element editor"""
   167     """Thesaurus table element editor"""
   172 
   168 
   173     view_name = 'properties.html'
   169     view_name = 'properties.html'
   208     icon_class = 'fa-edit'
   204     icon_class = 'fa-edit'
   209     url = '#properties.html'
   205     url = '#properties.html'
   210 
   206 
   211 
   207 
   212 @pagelet_config(name='properties.html', context=IThesaurus, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
   208 @pagelet_config(name='properties.html', context=IThesaurus, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
       
   209 @ajax_config(name='properties.json', context=IThesaurus, layer=IPyAMSLayer)
   213 @implementer(IWidgetForm, IInnerPage, IThesaurusView)
   210 @implementer(IWidgetForm, IInnerPage, IThesaurusView)
   214 class ThesaurusPropertiesEditForm(AdminEditForm):
   211 class ThesaurusPropertiesEditForm(AdminEditForm):
   215     """Thesaurus properties edit form"""
   212     """Thesaurus properties edit form"""
   216 
   213 
   217     @property
   214     @property
   233             self.widgets['name'].mode = DISPLAY_MODE
   230             self.widgets['name'].mode = DISPLAY_MODE
   234         if 'description' in self.widgets:
   231         if 'description' in self.widgets:
   235             self.widgets['description'].widget_css_class = 'input textarea'
   232             self.widgets['description'].widget_css_class = 'input textarea'
   236 
   233 
   237 
   234 
   238 @view_config(name='properties.json', context=IThesaurus, request_type=IPyAMSLayer,
       
   239              permission=ADMIN_THESAURUS_PERMISSION, renderer='json', xhr=True)
       
   240 class ThesaurusPropertiesAJAXEditForm(AJAXEditForm, ThesaurusPropertiesEditForm):
       
   241     """Thesaurus properties edit form, AJAX view"""
       
   242 
       
   243 
       
   244 #
   235 #
   245 # Thesaurus terms views
   236 # Thesaurus terms views
   246 #
   237 #
   247 
   238 
   248 @viewlet_config(name='terms.menu', context=IThesaurus, layer=IAdminLayer, manager=ISiteManagementMenu,
   239 @viewlet_config(name='terms.menu', context=IThesaurus, layer=IAdminLayer, manager=ISiteManagementMenu,
   272         super(ThesaurusTermsView, self).update()
   263         super(ThesaurusTermsView, self).update()
   273         self.extracts_view.update()
   264         self.extracts_view.update()
   274 
   265 
   275     @property
   266     @property
   276     def tree(self):
   267     def tree(self):
   277         return sorted([INode(node) for node in ITree(self.context).get_root_nodes()],
   268         return [INode(node) for node in ITree(self.context).get_root_nodes()]
   278                       key=lambda x: x.label)
       
   279 
   269 
   280     @property
   270     @property
   281     def search_query_params(self):
   271     def search_query_params(self):
   282         return json.dumps({'thesaurus_name': self.context.name})
   272         return json.dumps({'thesaurus_name': self.context.name})
   283 
   273 
   324         if term is None:
   314         if term is None:
   325             raise NotFound
   315             raise NotFound
   326         result = []
   316         result = []
   327         self.get_nodes(term, result)
   317         self.get_nodes(term, result)
   328         return {'term': label,
   318         return {'term': label,
   329                 'nodes': sorted(result, key=lambda x: x['label'])}
   319                 'nodes': result}
   330 
   320 
   331 
   321 
   332 @view_config(name='get-parent-nodes.json', context=IThesaurus, request_type=IPyAMSLayer,
   322 @view_config(name='get-parent-nodes.json', context=IThesaurus, request_type=IPyAMSLayer,
   333              permission=VIEW_PERMISSION, renderer='json', xhr=True)
   323              permission=VIEW_PERMISSION, renderer='json', xhr=True)
   334 class ThesaurusTermParentNodes(BaseTreeNodesView):
   324 class ThesaurusTermParentNodes(BaseTreeNodesView):
   404     add = button.Button(name='add', title=_("Import terms"))
   394     add = button.Button(name='add', title=_("Import terms"))
   405 
   395 
   406 
   396 
   407 @pagelet_config(name='import.html', context=IThesaurus, layer=IPyAMSLayer,
   397 @pagelet_config(name='import.html', context=IThesaurus, layer=IPyAMSLayer,
   408                 permission=ADMIN_THESAURUS_PERMISSION)
   398                 permission=ADMIN_THESAURUS_PERMISSION)
       
   399 @ajax_config(name='import.json', context=IThesaurus, layer=IPyAMSLayer,
       
   400              permission=ADMIN_THESAURUS_PERMISSION, base=AJAXAddForm)
   409 class ThesaurusImportForm(AdminDialogAddForm):
   401 class ThesaurusImportForm(AdminDialogAddForm):
   410     """Thesaurus import form"""
   402     """Thesaurus import form"""
   411 
   403 
   412     title = _("Thesaurus")
   404     title = _("Thesaurus")
   413     legend = _("Import thesaurus terms")
   405     legend = _("Import thesaurus terms")
   414     icon_css_class = 'fa fa-fw fa-upload'
   406     icon_css_class = 'fa fa-fw fa-upload'
   415 
   407 
   416     fields = field.Fields(IThesaurusUpdaterConfiguration).select('clear', 'conflict_suffix', 'data', 'format',
   408     fields = field.Fields(IThesaurusUpdaterConfiguration).select(
   417                                                                  'import_synonyms', 'language', 'encoding')
   409         'clear', 'conflict_suffix', 'data', 'format', 'import_synonyms', 'language', 'encoding')
   418     buttons = button.Buttons(IThesaurusFormImportButtons)
   410     buttons = button.Buttons(IThesaurusFormImportButtons)
   419 
   411 
   420     ajax_handler = 'import.json'
   412     ajax_handler = 'import.json'
   421     edit_permission = None
   413     edit_permission = None
   422 
   414 
   443 
   435 
   444     def nextURL(self):
   436     def nextURL(self):
   445         return absolute_url(self.context, self.request, 'admin#terms.html')
   437         return absolute_url(self.context, self.request, 'admin#terms.html')
   446 
   438 
   447 
   439 
   448 @view_config(name='import.json', context=IThesaurus, request_type=IPyAMSLayer,
       
   449              permission=ADMIN_THESAURUS_PERMISSION, renderer='json', xhr=True)
       
   450 class ThesaurusImportAJAXForm(AJAXAddForm, ThesaurusImportForm):
       
   451     """Thesaurus import form, AJAX view"""
       
   452 
       
   453 
       
   454 #
   440 #
   455 # Terms export views
   441 # Terms export views
   456 #
   442 #
   457 
   443 
   458 @viewlet_config(name='export.menu', context=IThesaurus, layer=IAdminLayer, manager=IThesaurusTermsMenu,
   444 @viewlet_config(name='export.menu', context=IThesaurus, layer=IAdminLayer,
   459                 permission=VIEW_SYSTEM_PERMISSION, weight=15)
   445                 manager=IThesaurusTermsMenu, permission=VIEW_SYSTEM_PERMISSION, weight=15)
   460 class ThesaurusExportMenuItem(MenuItem):
   446 class ThesaurusExportMenuItem(MenuItem):
   461     """Thesaurus export menu"""
   447     """Thesaurus export menu"""
   462 
   448 
   463     label = _("Export terms...")
   449     label = _("Export terms...")
   464     icon_class = 'fa-download'
   450     icon_class = 'fa-download'
   472 
   458 
   473     close = CloseButton(name='close', title=_("Close"))
   459     close = CloseButton(name='close', title=_("Close"))
   474     add = button.Button(name='add', title=_("Export terms"))
   460     add = button.Button(name='add', title=_("Export terms"))
   475 
   461 
   476 
   462 
   477 @pagelet_config(name='export.html', context=IThesaurus, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
   463 @pagelet_config(name='export.html', context=IThesaurus, layer=IPyAMSLayer,
       
   464                 permission=VIEW_SYSTEM_PERMISSION)
       
   465 @ajax_config(name='export.xml', context=IThesaurus, layer=IPyAMSLayer,
       
   466              permission=VIEW_SYSTEM_PERMISSION, base=AJAXAddForm)
   478 class ThesaurusExportForm(AdminDialogAddForm):
   467 class ThesaurusExportForm(AdminDialogAddForm):
   479     """Thesaurus export form"""
   468     """Thesaurus export form"""
   480 
   469 
   481     title = _("Thesaurus")
   470     title = _("Thesaurus")
   482     legend = _("Export thesaurus terms")
   471     legend = _("Export thesaurus terms")
   483     icon_css_class = 'fa fa-fw fa-download'
   472     icon_css_class = 'fa fa-fw fa-download'
   484 
   473 
   485     fields = field.Fields(IThesaurusExporterConfiguration)
   474     fields = field.Fields(IThesaurusExporterConfiguration)
   486     buttons = button.Buttons(IThesaurusFormExportButtons)
   475     buttons = button.Buttons(IThesaurusFormExportButtons)
   487 
   476 
   488     ajax_handler = 'export.xml'
       
   489     download_target = 'download_frame'
   477     download_target = 'download_frame'
   490     edit_permission = None
   478     edit_permission = None
   491 
   479 
   492     configuration = None
   480     configuration = None
   493     exporter = None
   481     exporter = None
   495     def createAndAdd(self, data):
   483     def createAndAdd(self, data):
   496         data = data.get(self, data)
   484         data = data.get(self, data)
   497         configuration = self.configuration = ThesaurusExporterConfiguration(data)
   485         configuration = self.configuration = ThesaurusExporterConfiguration(data)
   498         exporter = self.exporter = get_utility(IThesaurusExporter, name=configuration.format)
   486         exporter = self.exporter = get_utility(IThesaurusExporter, name=configuration.format)
   499         return exporter.export(self.context, configuration)
   487         return exporter.export(self.context, configuration)
   500 
       
   501 
       
   502 @view_config(name='export.xml', context=IThesaurus, request_type=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
       
   503 class ThesaurusExportAJAXForm(AJAXAddForm, ThesaurusExportForm):
       
   504     """Thesaurus export form, AJAX view"""
       
   505 
   488 
   506     def get_ajax_output(self, changes):
   489     def get_ajax_output(self, changes):
   507         changes.seek(0)
   490         changes.seek(0)
   508         headers = {'Content-Disposition': 'attachment; filename="{0}"'.format(self.configuration.filename)}
   491         headers = {'Content-Disposition': 'attachment; filename="{0}"'.format(self.configuration.filename)}
   509         response = Response(content_type=self.exporter.handler.content_type,
   492         response = Response(content_type=self.exporter.handler.content_type,