a
    Dg2                     @   s   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	 d dl
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 d dlmZ d dlmZ d dlmZ d dlmZ d dl m!Z! G dd dZ"dd Z#G dd deZ$G dd dZ%dS )    N)OrderedDict)partial)BytesIO)label_for_field)FieldDoesNotExist)FileResponseStreamingHttpResponse)timezone)	Formatter)	force_str)
get_format)cached_property)capfirst)gettext)Buttonmultigetattrc                   @   s   e Zd ZdZdd ZdS )EchozKAn object that implements just the write method of the file-like interface.c                 C   s
   | dS )z@Write the value by returning it, instead of storing in a buffer.zUTF-8)encode)selfvalue r   Y/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/admin/views/mixins.pywrite   s    z
Echo.writeN)__name__
__module____qualname____doc__r   r   r   r   r   r      s   r   c                 C   s   t d| S )Nz, )r   joinr   r   r   r   list_to_str   s    r    c                (   @   st   e Zd ZdZddddddddddd	d	d
d
dddddddddddddddddddddddddd'Zdd Zdd ZdS )ExcelDateFormatterNdddZdddZdddd mmmZmmmZmmmmzmmm.yyZyyyyhZhHhhssz.00zAM/PMzh:mmz
h:mm AM/PMzyyyy-mm-ddThh:mm:ss.00zddd, d mmm yyyy hh:mm:ss)'r#   jDlSwzWr&   nMbEFNtyYLogGr(   HisuaAfPeIOTZcrUc                 C   s   t d}| |S )NZSHORT_DATETIME_FORMAT)r   format)r   rO   r   r   r   getx   s    zExcelDateFormatter.getc                    s8    j v r fddS tdtj d  dd S )Nc                      s
   j   S N)_formatsr   namer   r   r   <lambda>~       z0ExcelDateFormatter.__getattr__.<locals>.<lambda>'z' object has no attribute ')rR   AttributeErrortyper   )r   rT   r   rS   r   __getattr__|   s
    
zExcelDateFormatter.__getattr__)r   r   r   datarR   rP   rZ   r   r   r   r   r!   "   sV   Qr!   c                	       s  e Zd ZdZdZdZeefZg Zi Ze	j	edd ie	j
e	jfedieeeeeiiZi ZdZdZ fd	d
Z fddZdd Zdd Zdd Zdd Zd/ddZdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Z e!d'd( Z"e!d)d* Z#e$d+d, Z%e$ fd-d.Z&  Z'S )0SpreadsheetExportMixinzUA mixin for views, providing spreadsheet export functionality in csv and xlsx formatsxlsxcsvc                 C   s   t | r| S t | tj jS rQ   )r	   Zis_naiveZ
make_naivedatetimeutcr   r   r   r   rU      s    zSpreadsheetExportMixin.<lambda>Nz'wagtailadmin/shared/export_buttons.htmlzspreadsheet-exportc                    s2   t  j|g|R i | |jd| jv | _d S )Nexport)supersetupGETrP   FORMATS	is_export)r   requestargskwargs	__class__r   r   rc      s    zSpreadsheetExportMixin.setupc                    s   | j r
d S t |S rQ   )rf   rb   get_paginate_by)r   querysetrj   r   r   rl      s    z&SpreadsheetExportMixin.get_paginate_byc                 C   s   | j S )zGGets the base filename for the exported spreadsheet, without extensions)export_filenamer   r   r   r   get_filename   s    z#SpreadsheetExportMixin.get_filenamec                    s   t  fdd| jD }|S )zmReturns an OrderedDict (in the order given by list_export) of the exportable information for a model instancec                 3   s   | ]}|t  |fV  qd S rQ   r   .0fielditemr   r   	<genexpr>   s   z5SpreadsheetExportMixin.to_row_dict.<locals>.<genexpr>)r   list_export)r   ru   row_dictr   rt   r   to_row_dict   s    z"SpreadsheetExportMixin.to_row_dictc                 C   s\   | j |i }||v r|| S | j D ]&\}}t||r(||v r(||   S q(ttddS )zYReturns the preprocessing function for a given field name, field value, and export formatT)Zstrings_only)custom_field_preprocessrP   custom_value_preprocessitems
isinstancer   r   )r   rs   r   export_formatZformat_dictZvalue_classesr   r   r   get_preprocess_function   s    z.SpreadsheetExportMixin.get_preprocess_functionc                 C   s&   |  |||}|dur||S |S dS )z?Preprocesses a field value before writing it to the spreadsheetN)r   )r   rs   r   r~   Zpreprocess_functionr   r   r   preprocess_field_value   s    z-SpreadsheetExportMixin.preprocess_field_valuec                 c   sT   ddl m} | D ]:\}}||| ||| j}|rHt|tjrH||_|V  qdS )z)Generate cells to append to the worksheetr   )WriteOnlyCellN)Zopenpyxl.cellr   r|   r   FORMAT_XLSXr}   r_   Znumber_format)r   	worksheetrx   date_formatr   rs   r   cellr   r   r   generate_xlsx_row   s    z(SpreadsheetExportMixin.generate_xlsx_rowc                    s   |  fdd| D S )Nc                    s"   i | ]\}}|  || jqS r   )r   
FORMAT_CSV)rr   rs   r   ro   r   r   
<dictcomp>   s   z8SpreadsheetExportMixin.write_csv_row.<locals>.<dictcomp>)writerowr|   )r   writerrx   r   ro   r   write_csv_row   s
    
z$SpreadsheetExportMixin.write_csv_rowc              	   C   sR   | j |}|rt|S zttt||jW S  ttfyL   t| Y S 0 dS )zQGet the heading label for a given field for a spreadsheet generated from querysetN)export_headingsrP   r   r   r   modelrX   r   )r   rm   rs   Zheading_overrider   r   r   get_heading   s    z"SpreadsheetExportMixin.get_headingc                 #   sR   t jt jd}| fddjD V   D ]}||V  q4dS )zUGenerate a csv file line by line from queryset, to be used in a StreamingHTTPResponse)
fieldnamesc                    s   i | ]}|  |qS r   r   rq   rm   r   r   r   r      rV   z5SpreadsheetExportMixin.stream_csv.<locals>.<dictcomp>N)r^   
DictWriterr   rw   r   r   ry   )r   rm   r   ru   r   r   r   
stream_csv   s    z!SpreadsheetExportMixin.stream_csvc                    s~   ddl m} |ddd}|jdd}| fddjD  t  } D ] }|j|||d	 qN|	| d
S )z&Write an xlsx workbook from a querysetr   )WorkbookT)Z
write_onlyZ	iso_datesZSheet1)titlec                 3   s   | ]}  |V  qd S rQ   r   rq   r   r   r   rv      s   z4SpreadsheetExportMixin.write_xlsx.<locals>.<genexpr>)r   N)
Zopenpyxlr   Zcreate_sheetappendrw   r!   rP   r   ry   save)r   rm   outputr   Zworkbookr   r   ru   r   r   r   
write_xlsx   s    
z!SpreadsheetExportMixin.write_xlsxc                 C   s6   t  }| || |d t|dd|   ddS )z<Write an xlsx file from a queryset and return a FileResponser   TzAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetz.xlsx)Zas_attachmentcontent_typefilename)r   r   seekr   rp   )r   rm   r   r   r   r   write_xlsx_response  s    
z*SpreadsheetExportMixin.write_xlsx_responsec                 C   s,   |  |}t|dd}d|  |d< |S )Nztext/csv)r   zattachment; filename="{}.csv"zContent-Disposition)r   r   rO   rp   )r   rm   streamresponser   r   r   write_csv_response  s    
z)SpreadsheetExportMixin.write_csv_responsec                 C   s,   || j kr| |S || jkr(| |S dS )zjReturn a response with a spreadsheet representing the exported data from queryset, in the format specifiedN)r   r   r   r   )r   rm   Zspreadsheet_formatr   r   r   as_spreadsheet"  s    


z%SpreadsheetExportMixin.as_spreadsheetc                 C   s(   | j j }||d< | j jd |  S )Nra   ?)rg   rd   copypath	urlencode)r   rO   paramsr   r   r   get_export_url)  s    z%SpreadsheetExportMixin.get_export_urlc                 C   s
   |  dS )Nr]   r   ro   r   r   r   xlsx_export_url.  s    z&SpreadsheetExportMixin.xlsx_export_urlc                 C   s
   |  dS )Nr^   r   ro   r   r   r   csv_export_url2  s    z%SpreadsheetExportMixin.csv_export_urlc                 C   s
   t | jS rQ   )boolrw   ro   r   r   r   show_export_buttons6  s    z*SpreadsheetExportMixin.show_export_buttonsc                    sN   t  j }| jrJ|ttd| jddd |ttd| jddd |S )NzDownload XLSXdownloadZ   )urlZ	icon_namepriorityzDownload CSVd   )	rb   header_more_buttonsr   r   r   r   _r   r   )r   Zbuttonsrj   r   r   r   :  s&    	z*SpreadsheetExportMixin.header_more_buttons)N)(r   r   r   r   r   r   re   rw   rz   r_   datetimelistr    r{   r   Zexport_buttons_template_namern   rc   rl   rp   ry   r   r   r   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   __classcell__r   r   rj   r   r\      sL   


	


r\   )&r^   r_   collectionsr   	functoolsr   ior   Zdjango.contrib.admin.utilsr   Zdjango.core.exceptionsr   Zdjango.httpr   r   Zdjango.utilsr	   Zdjango.utils.dateformatr
   Zdjango.utils.encodingr   Zdjango.utils.formatsr   Zdjango.utils.functionalr   Zdjango.utils.textr   Zdjango.utils.translationr   r   Zwagtail.admin.widgets.buttonr   Zwagtail.coreutilsr   r   r    r!   r\   r   r   r   r   <module>   s(   b