
    恕f4T                     R   d dl Z d dlmZmZmZmZ d dlmZ d dlm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZmZ d dlZd dlZd dlmZ d d	lmZ d d
lmZ ddlmZmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+  e jX                  d      Z- e.ej^                  ej`                  ejb                  ejd                  ejf                  ejh                  ejj                  ejl                  ejn                  ejp                  ejr                  ejt                  f      Z; G d de      Z<y)    N)requestflashabortResponse)expose)gettextngettextlazy_gettext)BaseModelView)create_editable_list_form)	iteritemsstring_types)get_db)ObjectId)action   )FilterConverterBaseMongoEngineFilter)get_formCustomModelConverter)DEFAULT_FORMATTERS)parse_like_term)format_error)process_ajax_referencescreate_ajax_loader)convert_subdocumentszflask-admin.mongoc                       e Zd ZdZdZ	 eZ	 eZ	  e	       Z
	 eZ	 ej                  ej                  ej                   ej"                  fZ	 dZ	 	 	 	 d fd	Z fdZ fdZd dZd Zd Zd	 Zd
 Zd Zd Zd Zd Zd!dZ d Z!d Z"d Z#	 d"dZ$d Z%d Z&d Z'd Z( e)d      d        Z* fdZ+ e,d e-d       e-d            d        Z. xZ/S )#	ModelViewz,
        MongoEngine model scaffolding.
    Nc
                 v    g | _         t        t        |   |||||||||		       | j	                         | _        y)a  
            Constructor

            :param model:
                Model class
            :param name:
                Display name
            :param category:
                Display category
            :param endpoint:
                Endpoint
            :param url:
                Custom URL
            :param menu_class_name:
                Optional class name for the menu item.
            :param menu_icon_type:
                Optional icon. Possible icon types:

                 - `flask_admin.consts.ICON_TYPE_GLYPH` - Bootstrap glyph icon
                 - `flask_admin.consts.ICON_TYPE_FONT_AWESOME` - Font Awesome icon
                 - `flask_admin.consts.ICON_TYPE_IMAGE` - Image relative to Flask static directory
                 - `flask_admin.consts.ICON_TYPE_IMAGE_URL` - Image with full URL

            :param menu_icon_value:
                Icon glyph name or URL, depending on `menu_icon_type` setting
        )menu_class_namemenu_icon_typemenu_icon_valueN)_search_fieldssuperr   __init__scaffold_pk_primary_key)selfmodelnamecategoryendpointurlstatic_folderr    r!   r"   	__class__s             c/var/www/feuerwehr-webapp/venv/lib/python3.12/site-packages/flask_admin/contrib/mongoengine/view.pyr%   zModelView.__init__   sJ    : !i'tXxm8G7E8G 	( 	I
 !,,.    c                     | j                   i | _         t        | j                         | _        t        t        |           y)z$
            Refresh cache.
        N)form_subdocumentsr   _form_subdocumentsr$   r   _refresh_cache)r(   r/   s    r0   r5   zModelView._refresh_cache
  s;    
 !!)%'D""6t7M7M"N 	i-/r1   c                 @    t         t        |          }t        ||       S )ak  
            AJAX endpoint is exposed by top-level admin view class, but
            subdocuments might have AJAX references too.

            This method will recursively go over subdocument configuration
            and will precompute AJAX references for them ensuring that
            subdocuments can also use AJAX to populate their ReferenceFields.
        )r$   r   _process_ajax_referencesr   )r(   
referencesr/   s     r0   r7   z"ModelView._process_ajax_references  s!     9dDF
&z488r1   c                 `    || j                   }t        t        |j                        d       S )z
            Inspect model and return list of model fields

            :param model:
                Model to inspect
        c                      | d   j                   S )Nr   )creation_counter)ns    r0   <lambda>z-ModelView._get_model_fields.<locals>.<lambda>-  s    ad>S>S r1   )key)r)   sortedr   _fieldsr(   r)   s     r0   _get_model_fieldszModelView._get_model_fields#  s)     =JJEi.4STTr1   c                      y)Nid r(   s    r0   r&   zModelView.scaffold_pk/  s    r1   c                     |j                   S )z
            Return the primary key value from the model instance

            :param model:
                Model instance
        pkrA   s     r0   get_pk_valuezModelView.get_pk_value3  s     xxr1   c                 J   g }| j                         D ]  \  }}t        |      }|t        j                  k(  r%t	        |j
                  t        j                        rI|t        j                  k(  r]| j                  s|t        j                  k7  s}|j                  |        |S )z+
            Scaffold list columns
        )
rB   typemongoengine	ListField
isinstancefieldEmbeddedDocumentFieldcolumn_display_pkObjectIdFieldappend)r(   columnsr<   ffield_classs        r0   scaffold_list_columnszModelView.scaffold_list_columns<  s     **, 	"DAqq'K{444qww(I(IJk???%%8Q8Q)Qq!	" r1   c                     i }| j                         D ]E  \  }}t        |      t        v s| j                  st        |      t        j
                  k7  sA|||<   G |S )zK
            Return a dictionary of sortable columns (name, field)
        )rB   rL   SORTABLE_FIELDSrR   rM   rS   )r(   rU   r<   rV   s       r0   scaffold_sortable_columnsz#ModelView.scaffold_sortable_columnsR  s[     **, 	#DAqAw/)))T!W8Q8Q-Q!"GAJ	#
 r1   c                 t   | j                   r| j                   D ]  }t        |t              r%| j                  j                  j                  |      }|t        d      t        |      }|| j                  vrt        dd|z  z         | j                  j                  |        t        | j                        S )z!
            Init search
        zInvalid search fieldz!Can only search on text columns. zFailed to setup search for "%s")column_searchable_listrO   r   r)   r@   get	ExceptionrL   allowed_search_typesr#   rT   bool)r(   p
field_types      r0   init_searchzModelView.init_search_  s     &&00 .a.

**..q1A9#$:;;!!W
 d&?&??#$G$E$I%J K K ##**1-.  D''((r1   c                 z   t        |t              r&| j                  j                  j	                  |      }n|}|t        d|z        d}t        |t              s| j                  |j                        }|s| j                  |      }t        |      j                  }| j                  j                  |||      }|S )z
            Return filter object(s) for the field

            :param name:
                Either field name or field instance
        Nz#Failed to find field for filter: %s)rO   r   r)   r@   r^   r_   get_column_namer*   rL   __name__filter_converterconvert)r(   r*   attrvisible_name	type_nameflts         r0   scaffold_filterszModelView.scaffold_filtersv  s     dL)::%%))$/DD<ADHII $-//		:L//5L J''	##++I,0,8: 
r1   c                 "    t        |t              S )z
            Validate if the provided filter is a valid MongoEngine filter

            :param filter:
                Filter object
        )rO   r   )r(   filters     r0   is_valid_filterzModelView.is_valid_filter  s     &"788r1   c           	          t        | j                  | j                  |       | j                  | j                  | j
                  | j                  | j                        }|S )z1
            Create form from the model.
        )
base_classonlyexclude
field_argsextra_fields)r   r)   model_form_converterform_base_classform_columnsform_excluded_columns	form_argsform_extra_fields)r(   
form_classs     r0   scaffold_formzModelView.scaffold_form  sV     djj"77=)-)=)=#'#4#4&*&@&@)-+/+A+AC
 r1   c                     t        | j                  | j                  |       | j                  | j                  |      }t        | j                  ||      S )ah  
            Create form for the `index_view` using only the columns from
            `self.column_editable_list`.

            :param widget:
                WTForms widget class. Defaults to `XEditableWidget`.
            :param validators:
                `form_args` dict with only validators
                {'name': {'validators': [required()]}}
        )rs   rt   rv   )r   r)   rx   ry   column_editable_listr   )r(   widget
validatorsr~   s       r0   scaffold_list_formzModelView.scaffold_list_form  sS     djj"77=)-)=)=#'#<#<)3	5
 ))=)=z)/1 	1r1   c                 2    t        | j                  |||      S N)r   r)   )r(   r*   optss      r0   _create_ajax_loaderzModelView._create_ajax_loader  s    !$**dD$??r1   c                 .    | j                   j                  S )z|
        Returns the QuerySet for this view.  By default, it returns all the
        objects for the current model.
        )r)   objectsrF   s    r0   	get_queryzModelView.get_query  s    
 zz!!!r1   c                 8   t        |      \  }}d }| j                  D ]k  }t        |      t        j                  k(  rdd l}|j                  d|z        }n|}|j                  d||i}	t        j                  di |	}
||
}g||
z  }m |j                  |      S )Nr   z.*%s.*__rE   )
r   r#   rL   rM   ReferenceFieldrecompiler*   Qrp   )r(   querysearch_termoptermcriteriarP   r   regexrm   qs              r0   _searchzModelView._search  s    
 #;/D(( 	EE{k888

8d?3$zz2.6C$$AA	 ||H%%r1   c                    | j                         }| j                  r;|D ]6  \  }	}
}| j                  |	   }|j                  ||j                  |            }8 | j                  r|r| j                  ||      }| j                  s|j                         nd}|r|j                  |rdnd|      }n=| j                         }|r+|D cg c]  \  }}|rdnd| }}} |j                  | }|| j                  }|r|j                  |      }|r|r|j                  ||z        }|r|j                         }||fS c c}}w )a  
            Get list of objects from MongoEngine

            :param page:
                Page number
            :param sort_column:
                Sort column
            :param sort_desc:
                Sort descending
            :param search:
                Search criteria
            :param filters:
                List of applied filters
            :param execute:
                Run query immediately or not
            :param page_size:
                Number of results. Defaults to ModelView's page_size. Can be
                overriden to change the page_size limit. Removing the page_size
                limit requires setting page_size to 0 or False.
        N- )r   _filtersapplyclean_search_supportedr   simple_list_pagercountorder_by_get_default_order	page_sizelimitskipall)r(   pagesort_column	sort_descsearchfiltersexecuter   r   rm   flt_namevaluerV   r   ordercoldesckeyss                     r0   get_listzModelView.get_list  sM   ,   ==(/ 7$XuMM#&qwwu~67
 !!fLL/E &*%;%; NNIS2-E{#STE++-E+02'S$ *.#2"5s; 2 2&- IKK	*EIJJti/0EIIKEe|#2s   	D>c           	          	 | j                         j                  |      j                         S # t        j                  $ r*}t        t        dt        |            d       Y d}~yd}~ww xY w)zo
            Return a single model instance by its ID

            :param id:
                Model ID
        rH   zFailed to get model. %(error)serrorr   N)r   rp   firstrM   ValidationErrorr   r   r   )r(   rD   exs      r0   get_onezModelView.get_one$  sc    	>>#**b*17799** 	': ,R 02 		s   -0 A- A((A-c           	      n   	 | j                         }|j                  |       | j                  ||d       |j                          | j	                  ||d       |S # t
        $ rP}| j                  |      s5t        t        dt        |            d       t        j                  d       Y d}~yd}~ww xY w)za
            Create model helper

            :param form:
                Form instance
        Tz"Failed to create record. %(error)sr   r   zFailed to create record.NF)r)   populate_obj_on_model_changesaveafter_model_changer_   handle_view_exceptionr   r   r   log	exceptionr(   formr)   r   s       r0   create_modelzModelView.create_model3  s    	7JJLEe$!!$t4JJL ##D%6  	--b1gB$0$46 89	s   AA 	B4$AB//B4c           	      L   	 |j                  |       | j                  ||d       |j                          | j                  ||d       y# t        $ rP}| j                  |      s5t        t        dt        |            d       t        j                  d       Y d}~yd}~ww xY w)z
            Update model helper

            :param form:
                Form instance
            :param model:
                Model instance to update
        Fz"Failed to update record. %(error)sr   r   zFailed to update record.NT)r   r   r   r   r_   r   r   r   r   r   r   r   s       r0   update_modelzModelView.update_modelL  s    	8e$!!$u5JJL ##D%7  	--b1gB$0$46 89	s   4A
 
	B#ABB#c           	      "   	 | j                  |       |j                          | j                  |       y# t        $ rP}| j	                  |      s5t        t        dt        |            d       t        j                  d       Y d}~yd}~ww xY w)zc
            Delete model helper

            :param model:
                Model instance
        z"Failed to delete record. %(error)sr   r   zFailed to delete record.NFT)
on_model_deletedeleteafter_model_deleter_   r   r   r   r   r   r   )r(   r)   r   s      r0   delete_modelzModelView.delete_modelf  s    	+  'LLN ##E*  	--b1gB$0$46 89	s   !5 	BAB		Bz
/api/file/c                    t         j                  j                  d      }t         j                  j                  d      }t         j                  j                  dd      }|r|r|st        d       t	        j
                  t        |      |      }|j                  | j                  |            }|st        d       t        |j                         |j                  d|j                  i      S )NrD   colldbdefaulti  zContent-Length)content_typeheaders)r   argsr^   r   gridfsGridFSr   object_id_converterr   readr   length)r(   rI   r   r   fsdatas         r0   api_file_viewzModelView.api_file_view~  s    \\d#||'\\dI.R#J]]6":t,vvd..r23#J		%)%6%6!14;; ?A 	Ar1   c                 N    |dk(  r| j                   syt        t        |   |      S )Nr   F)
can_deleter$   r   is_action_allowed)r(   r*   r/   s     r0   r   zModelView.is_action_allowed  s&    8DOOY7==r1   r   Deletez1Are you sure you want to delete selected records?c           	         	 d}|D cg c]  }| j                  |       }}| j                         j                  |      j                         D ]  }|| j	                  |      z  } t        t        dd||      d       y c c}w # t        $ r@}| j                  |      s%t        t        dt        |            d       Y d }~y Y d }~y d }~ww xY w)	Nr   z Record was successfully deleted.z,%(count)s records were successfully deleted.)r   successz#Failed to delete records. %(error)sr   r   )r   r   in_bulkvaluesr   r   r	   r_   r   r   str)r(   idsr   rI   all_idsobjr   s          r0   action_deletezModelView.action_delete  s    	E>ABt//3BGB~~'//8??A 0**3//0 (=I !&( *34	 C  	--b1gC3r7S  2	s(   B BA!B B 	C1CC)NNNNNNNNr   )NN)TN)0rg   
__module____qualname____doc__column_filtersr   rx   r   r   r   rh   r   column_type_formattersrM   StringFieldURLField
EmailFieldr   r`   r3   r%   r5   r7   rB   r&   rJ   rX   r[   rd   rn   rq   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
   r   __classcell__)r/   s   @r0   r   r   -   sZ    N*X 0" # '( 0 (33'00'22'668 L\ $(GKLP$/L0
9
U,).@91*@"&4 *.=~240 LA A&> H"LMOOr1   r   )=loggingflaskr   r   r   r   flask_adminr   flask_admin.babelr   r	   r
   flask_admin.modelr   flask_admin.model.formr   flask_admin._compatr   r   rM   r   mongoengine.connectionr   bson.objectidr   flask_admin.actionsr   r   r   r   r   r   r   typefmtr   toolsr   helpersr   ajaxr   r   subdocr   	getLoggerr   setr   IntField
FloatFieldBooleanFieldDateTimeFieldComplexDateTimeFieldrS   DecimalFieldr   r   	UUIDFieldr   rZ   r   rE   r1   r0   <module>r     s     1 1  = = + < 7   ) " & ; 0 ' " ! = ( g+, $$  ~	 ~	r1   