o
    WiQ                     @   s  d dl mZmZmZ d dlmZmZ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Zd dlZd dlZd dlZd dlmZmZ d dlZd d	lmZ d dlZd dlZe Zejed
gdd
gd
gd eddZej de
dddd ej de
dddd ej!"ej!#ej!$e%dZ&ej!"e&dZ'dd Z(dd Z)dd Z*G dd deZ+G dd  d eZ,e-d!d"d# Z.ej-d$ed%d&efd'd(Z/e-d)d*d+ Z0e1d,d-d. Z2e-d/d0d1 Z3e-d2d3e4fd4d5Z5e1d/d6e+fd7d8Z6e7d2d3e4d6e+fd9d:Z8e9d2d3e4fd;d<Z:e-d=d&efd>d?Z;e-d@dAdB Z<e-dCdWdDe=dEe=fdFdGZ>e-dHdIdJ Z?e-dKdLdM Z@e-dNdOdP ZAe1dNdQee, fdRdSZBe-dTdUdV ZCdS )X    )FastAPIRequestHTTPException)HTMLResponseFileResponseJSONResponseResponse)StaticFiles)CORSMiddleware)Jinja2Templates)ListN)	BaseModel	validator)datetime*T)allow_originsallow_credentialsallow_methodsallow_headers	templates)	directoryz/staticstatic)namez/assetsztemplates/assetsassetsoat_nature_datazOAT_ArcGIS_OAT_Only_data.jsonc                 C   sj   | j rg S | tdtdgd}|jD ]}||   r/|| d||  d||< q|	dS )zRClean pandas DataFrame for JSON serialization by handling NaN and infinity values.infz-infNobjectrecords)
emptyreplacefloatcolumnsisnaanyastypewherenotnato_dict)dfdf_cleancol r+   ,/var/www/OAT-AI-Tools/oat-nature-park/app.pyclean_dataframe_for_json&   s   
"
r-   c               
   C   s   zJt jtd} t j| s tjddgd}|j| dd |W S t| }|j	dd}|d 
d	t|d< ||d d	k }|jd
ddd}|W S  tya } ztddt| dd }~ww )NOAT_schools.csvURNEstablishment namer!   Findexall)howr   urn
schoolName)r/   r0     zError accessing schools data: status_codedetail)ospathjoinOAT_NATURE_DATA_DIRexistspd	DataFrameto_csvread_csvdropnafillnar$   intrename	Exceptionr   str)school_filer(   er+   r+   r,   get_schools_df4   s&   

rM   c               
      sp  dd l tjtd ddg} | D ]}|tjv rtj|= qddlm} |	j
 |jd d  D ]}t|jrA|| |  q0j ddd}|	j
 d	}|| ||  }|	j
 t fd
d|jD }|s}|| |}z|d zdd l}	dd l}
ddlm} |d W nF ty } z|d|  |d |d W Y d }~W d S d }~w ty } z|d|  |d W Y d }~W d S d }~ww ztjtd}|	|}|dt| d W n7 ty   |d |d Y W d S  ty2 } z|d|  |d W Y d }~W d S d }~ww z ddlm }m!} |d ||| |d |d W W d S  tyu } z|d|  |d W Y d }~W d S d }~w ty } z|d|  |d W Y d }~W d S d }~ww  ty } z|d|  |d W Y d }~d S d }~ww )Nr   OAT_ArcGIS_OAT_Only.logz/oat_nature_data_utils.explore_oat_arcgis_fieldsoat_nature_data_utils)loggerautf-8)modeencodingz)%(asctime)s - %(levelname)s - %(message)sc                 3   s&    | ]}t |jo|j kV  qd S N)
isinstanceFileHandlerbaseFilename).0hlog_fileloggingr+   r,   	<genexpr>y   s   $ zrun_script.<locals>.<genexpr>zScript thread started...)FeatureLayerz&Successfully imported required modulesz"Error importing required modules: zLPlease ensure all required packages are installed: pandas, geopandas, arcgisSCRIPT_FAILEDz$Unexpected error importing modules: r.   z-Successfully loaded OAT URNs from CSV. Found z	 schools.z>OAT_schools.csv file not found. Please ensure the file exists.zError loading OAT URNs: )export_all_layers_to_excellayerszStarting data export process...zSuccessfully exported dataSCRIPT_COMPLETED_SUCCESSFULLYz"Error importing export functions: zError exporting data: zError in run_script: )"r]   r<   r=   r>   r?   sysmodules/oat_nature_data_utils.explore_oat_arcgis_fieldsrP   setLevelINFOhandlersrV   rW   removeHandlerclose	FormattersetFormatter
addHandler	getLoggerr#   infopandas	geopandasarcgis.featuresr_   ImportErrorerrorrI   rD   lenFileNotFoundErrorra   rb   )modules_to_removemod_namescript_loggerhandlerfile_handlerfile_formatterroot_loggerhas_file_handlerrP   rA   gpdr_   rL   rK   oat_dfra   rb   r+   r[   r,   
run_scriptS   s   



















r   c                   @   s>   e Zd ZU eed< eed< eddd Zeddd ZdS )Schoolr6   r7   c                 C   s   |dkrt d|S )Nr   zURN must be a positive number)
ValueErrorclsvr+   r+   r,   validate_urn   s   zSchool.validate_urnc                 C   s   |  std|  S )NzSchool name cannot be empty)stripr   r   r+   r+   r,   validate_school_name   s   zSchool.validate_school_nameN)	__name__
__module____qualname__rG   __annotations__rJ   r   r   r   r+   r+   r+   r,   r      s   
 
r   c                   @   s   e Zd ZU eed< eed< dS )CarbonBaselineEntry
CarbonAreaCarbonValueKGCO2eN)r   r   r   rJ   r   r    r+   r+   r+   r,   r      s   
 r   z/favicon.icoc                      s
   t dS )Nztemplates/assets/favicon.ico)r   r+   r+   r+   r,   favicon   s   r   z/oat-nature)response_classrequestc                    s   t dd| iS )Nzoat_nature.htmlr   r   TemplateResponser   r+   r+   r,   get_oat_nature_page      r   z/api/oat-nature/datac               
      s  zt jtrMz(ttddd} t| }W d   n1 s w   Y  td t	|dW W S  t
yL } ztdt|  W Y d}~nd}~ww t jtd}t j|s`td	d
dtd tj|dd}t jtd}t|}dd | D }|t|dt t|dt t|dt t|dt d}t	|dW S  t
y } ztdt|  tddt| dd}~ww )z%Get OAT Nature data for visualizationrrR   rT   Nz%Loaded OAT nature data from JSON filecontentz0Error reading JSON file, falling back to Excel: OAT_ArcGIS_OAT_Only.xlsx  z9OAT data file not found. Please update the dataset first.r9   z<Loading OAT nature data from Excel file (JSON not available)
sheet_namer.   c                 S   s&   g | ]\}}t |d  |d dqS )r/   r0   )r6   r   )rJ   )rY   _rowr+   r+   r,   
<listcomp>   s   & z'get_oat_nature_data.<locals>.<listcomp>Site_BoundariesMapper_MicrohabitatsMapper_LinesMapper_Areas)schoolssite_boundariesmicrohabitatslinesareaszError loading OAT nature data: r8   zError loading data: )r<   r=   r@   OAT_NATURE_JSON_FILEopenjsonloadr]   rp   r   rI   warningrJ   r>   r?   r   rA   
read_excelrD   iterrowsr-   getrB   ru   )fresultrL   
excel_file
excel_datarK   school_datar   r+   r+   r,   get_oat_nature_data   sB   
 

r   z/api/oat-nature/update-datasetc               
      s  zmz)t jtd} t| ddd}|d |  W d    n1 s%w   Y  W n tyB } ztddt	| dd }~ww zt
jtd	}d
|_|  d
ddW W S  tyn } ztddt	| dd }~ww  ty } ztddt	| dd }~ww )NrN   wrR   r   zStarting update process...
r8   zError accessing log file: r9   )targetTzUpdate process startedsuccessmessagezError starting update process: Unexpected error: )r<   r=   r>   r?   r   writeflushrI   r   rJ   	threadingThreadr   daemonstart)r\   r   rL   threadr+   r+   r,   update_oat_dataset   sF   

r   z/api/oat-nature/schoolsc               
      sB   zt  } | d}|W S  ty  } ztdt|dd }~ww )Nr   r8   r9   )rM   r'   rI   r   rJ   )r(   r   rL   r+   r+   r,   get_schools"  s   
r   z/api/oat-nature/schools/{urn}r6   c              
      sb   zt  }||d | k d}|stddd|d W S  ty0 } ztdt|dd }~ww )Nr6   r   r   School not foundr9   r   r8   )rM   r'   r   rI   rJ   )r6   r(   schoolrL   r+   r+   r,   
get_school+  s   
r   r   c              
      s   z?t  }| j|d jv rtdddt| j| jdg}tj||gdd}|jdd	dd
}t	j
td}|j|dd | W S  tyT } ztdt|dd }~ww )Nr6     zSchool URN already existsr9   r6   r7   T)ignore_indexr/   r0   r1   r.   Fr2   r8   )rM   r6   valuesr   rA   rB   r7   concatrH   r<   r=   r>   r?   rC   rI   rJ   )r   r(   new_rowrK   rL   r+   r+   r,   
add_school6  s*   

r   c              
      s   z6t  }| |d jvrtddd|j|j|d | kdf< |jdddd	}tjt	d
}|j
|dd |W S  tyK } ztdt|dd }~ww )Nr6   r   r   r9   r7   r/   r0   r   r1   r.   Fr2   r8   )rM   r   r   r7   locrH   r<   r=   r>   r?   rC   rI   rJ   )r6   r   r(   rK   rL   r+   r+   r,   update_schoolS  s"   
r   c              
      s   z4t  }| |d jvrtddd||d | k }|jdddd}tjtd	}|j|d
d ddiW S  t	yI } ztdt
|dd }~ww )Nr6   r   r   r9   r/   r0   r   r1   r.   Fr2   r   zSchool deleted successfullyr8   )rM   r   r   rH   r<   r=   r>   r?   rC   rI   rJ   )r6   r(   rK   rL   r+   r+   r,   delete_schoolg  s"   

r   z/oat-nature-adminc                    s   t ddi iS )Nzoat_nature_admin.htmlr   r   r   r+   r+   r,   
admin_pagez  r   r   z/api/oat-nature/download-excelc               
      b   zt jtd} t j| stdddt| dddW S  ty0 } ztdt|dd}~ww )	z"Download the OAT ArcGIS Excel filer   r   Excel file not foundr9   zAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
media_typefilenamer8   N	r<   r=   r>   r?   r@   r   r   rI   rJ   )r   rL   r+   r+   r,   download_excel~     r   z+/api/oat-nature/download-sheet/{sheet_name}r   urnsc              
      s  ztt jtd}t j|stdddddddd	}|| }|s)td
ddtj||d}|rGdd |	dD }|rG||d 
| }ddlm} | }|j|dd | }	|  dt d d}
t|	ddd|
 didW S  ty } ztdt|dd}~ww )z?Download a specific sheet from the OAT ArcGIS Excel file as CSVr   r   r   r9   r   r   r   r   )r   r   r   r   r   zInvalid sheet namer   c                 S   s$   g | ]}|   rt|  qS r+   )r   isdigitrG   )rY   r6   r+   r+   r,   r     s   $ z"download_sheet.<locals>.<listcomp>,Urnr   )StringIOFr2   r   z%Y%m%dz.csvztext/csvzContent-Dispositionzattachment; filename="")r   r   headersr8   N)r<   r=   r>   r?   r@   r   r   rA   r   splitisinior   rC   getvaluer   nowstrftimer   rI   rJ   )r   r   r   sheet_mappingexcel_sheet_namer(   urn_listr   outputcsv_contentr   rL   r+   r+   r,   download_sheet  s@   
r   z/api/oat-nature/last-updatec               
      sv   z%t jtd} t j| sdd iW S t j| }t|d}d|iW S  t	y: } zt
dt|dd }~ww )Nr   
lastUpdatez%d/%m/%Y %H:%M:%Sr8   r9   )r<   r=   r>   r?   r@   getmtimer   fromtimestampr   rI   r   rJ   )r   last_modifiedlast_updaterL   r+   r+   r,   get_last_update  s   

r   z/api/oat-nature/logc               
      s   z6t jtd} t j| stddiddW S t| d}| }W d   n1 s,w   Y  t|dd	W S  t	y] } zt
d
t|  tdt|iddW  Y d}~S d}~ww )z+Get the contents of the OAT ArcGIS log filerN   ru   zLog file not foundr   )r   r:   r   Nz
text/plain)r   r   zError reading log file: r8   )r<   r=   r>   r?   r@   r   r   readr   rI   r]   ru   rJ   )r\   r   log_contentrL   r+   r+   r,   get_oat_nature_log  s   
 r   z/api/oat-nature/carbon-baselinec            	   
      sP  zddddddddd	} zPt jtd
}i }t|d$}t|}|D ]}|d  }t|d  }|||< q$W d    n1 sCw   Y  |rQt	|dW W S t
jd t	| dW W S  ty } zt
jdt|  t	| dW  Y d }~W S d }~ww  ty } zt
jdt|  t	ddt|idW  Y d }~S d }~ww )Ng      ?g      !@g?g      -@g@g     >@gGz?r   )zVegetable and fruit treeszGrass and wildflowerszHedges and bushesz
Wet placeszGround without plantsTreeszFlower GardensUnknownOAT_carbon_baseline.csvr   r   r   r   z-No values read from CSV, using default valuesz)Error reading CSV, using default values: r   r8   ru   )r:   r   )r<   r=   r>   r?   r   csv
DictReaderr   r    r   apprP   r   rI   ru   rJ   )	default_valuescarbon_filecarbon_valuesfilereaderr   habitatvaluerL   r+   r+   r,   get_carbon_baseline  sN   


r
  datac              
      s   z=t jtd}t|ddd!}tj|ddgd}|  | D ]	}||	  q W d   n1 s4w   Y  d	d
dW S  t
yR } ztdt|dd}~ww )z
    Update the OAT_carbon_baseline.csv file with new values.
    Expects a list of objects: {"CarbonArea": str, "CarbonValueKGCO2e": float}
    r   r    )newliner   r   )
fieldnamesNTz%Carbon baseline updated successfully.r   r8   r9   )r<   r=   r>   r?   r   r   
DictWriterwriteheaderwriterowdictrI   r   rJ   )r  r  csvfilewriterr   rL   r+   r+   r,   update_carbon_baseline  s   r  z /api/oat-nature/download-formulac               
      r   )	z)Download the formula methodology documentzFormula_for_Carbon_Storage.docxr   zFormula document not foundr9   zGapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentr   r8   Nr   )	file_pathrL   r+   r+   r,   download_formula  r   r  rU   )Dfastapir   r   r   fastapi.responsesr   r   r   r   fastapi.staticfilesr	   fastapi.middleware.corsr
   fastapi.templatingr   typingr   r<   rq   rA   r]   r   pydanticr   r   r   r   rd   r   r  add_middlewarer   mountr=   r>   dirnameabspath__file__r?   r   r-   rM   r   r   r   r   r   r   r   postr   r   rG   r   r   putr   deleter   r   r   rJ   r   r   r   r
  r  r  r+   r+   r+   r,   <module>   s    
	d

*
"


-


)