Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZIP fastAPI shell #165

Merged
merged 6 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions WMS/Util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#Import Pillow library for working with images
from PIL import Image
import os
import shutil


def split_image(image_path, output_folder, tile_size):
Expand All @@ -19,7 +21,7 @@ def split_image(image_path, output_folder, tile_size):
print("done");

#Checks if the file is of the correct type, otherwise raises an error
if(image_path.split(".")[2] not in acceptedFileTypes):
if(image_path.split(".")[1] not in acceptedFileTypes):
return "Filetype not supported"


Expand All @@ -46,8 +48,65 @@ def split_image(image_path, output_folder, tile_size):
tile = image.crop((left_top, left_bottom, right_top, right_bottom))

#Save the tile to the output folder
tile.save(f"{output_folder}/tile_{i}_{j}.jpeg")
tile.save(f"{output_folder}/tile_{i}_{i}.png")

#Return the amount of tiles created to be used for testing purposes
#Return the amount of tiles created
return horizontal_tiles + vertical_tiles


def split_files(image_path, output_folder, tiles, training_fraction, validation_fraction):
'''
Splits a set of tiles and sorts them according to machine learning specifications

Args:
image_path (str): The path to where the images are stored
output_folder (str): The path to the output folder
tiles (int): The amount of tiles that need to be handled
training_fraction (int): The amount of tiles that will be used for training
validation (int): The amount of tiles that will be used for validation

'''



try:
#Generate output folder
os.mkdir("WMS/" + output_folder + "/")

#Generate subfolders based on the standard
folders = ["train", "val", "/train/images", "/train/masks", "/val/images", "/val/masks"]
for folder in folders:
path = os.path.join("WMS/" + output_folder + "/" + folder)
os.mkdir(path)
except:
print("Something went wrong with generating the folders...")


#Calculate the amount of files for each fraction
training_files = int(training_fraction)/100 * int(tiles)
validation_files = int(validation_fraction)/100 * int(tiles)

#Copy the files into the right places
for i in range(0, tiles - 1):
if(i > 0 and i < training_files):
try:
shutil.copy2(image_path + f"/orto/tile_{i}_{i}.png", "WMS/" + output_folder + "/train/images")
shutil.copy2(image_path + f"/fasit/tile_{i}_{i}.png", "WMS/" + output_folder + "/train/masks")
except:
print("Something went wrong with copying...")
else:
try:
shutil.copy2(image_path + f"/orto/tile_{i}_{i}.png", "WMS/" + output_folder + "/val/images")
shutil.copy2(image_path + f"/fasit/tile_{i}_{i}.png", "WMS/" + output_folder + "/val/masks")
except:
print("Something went wrong with copying...")

#Delete the files, we dont need them anymore
for i in range(0, tiles):
try:
os.remove(image_path + f"/orto/tile_{i}_{i}.png")
os.remove(image_path + f"/fasit/tile_{i}_{i}.png")
except:
print("Couldn't delete")


Binary file added WMS/__pycache__/__init__.cpython-311.pyc
Binary file not shown.
Binary file added WMS/email/train/images/tile_1_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_2_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_3_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_4_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_5_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_6_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_7_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/images/tile_8_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_1_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_2_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_3_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_4_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_5_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_6_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_7_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/train/masks/tile_8_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/val/images/tile_0_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/email/val/masks/tile_0_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/ortofoto_images/output_20240217013013.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed WMS/rawphotos/eksempel.png
Binary file not shown.
Binary file added WMS/rawphotos/fasit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WMS/rawphotos/orto.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed WMS/readyforemail/tile_0_0.jpeg
Binary file not shown.
Binary file removed WMS/readyforemail/tile_0_1.jpeg
Binary file not shown.
Binary file removed WMS/readyforemail/tile_0_2.jpeg
Binary file not shown.
Binary file removed WMS/readyforemail/tile_1_0.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_1_1.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_1_2.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_2_0.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_2_1.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_2_2.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_3_0.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_3_1.jpeg
Diff not rendered.
Binary file removed WMS/readyforemail/tile_3_2.jpeg
Diff not rendered.
2 changes: 1 addition & 1 deletion WMS/resources/config.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Config": {"data_parameters": ["60", "40", "5"], "layers": ["Bygning", "Veg", "Bru"], "colors": ["#000000", "#ffff00", "#00ff00"]}}
{"Config": {"data_parameters": ["90", "10", "10"], "layers": ["Bygning", "Veg", "Bru"], "colors": ["#000000", "#ffff00", "#00ff00"]}}
2 changes: 1 addition & 1 deletion WMS/resources/coordinates.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Coordinates": [[588751.5420105711, 6642899.275265058], [588749.8344259012, 6642970.498298281], [589238.8910459754, 6642982.255880976], [589240.6080427505, 6642911.032997987], [588751.5420105711, 6642899.275265058]]}
{"Coordinates": [[586077.6407936335, 6646104.917552568], [586025.9038943398, 6648327.088944961], [588710.10992247, 6648390.564976909], [588763.4615420719, 6646168.418973851], [586077.6407936335, 6646104.917552568]]}
Binary file modified __pycache__/deleteFolder.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/main.cpython-311.pyc
Binary file not shown.
8 changes: 6 additions & 2 deletions frontend/pages/setConstraints.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,13 @@ <h2 class="modal-title">Confirm order</h2>
<div class="modal-footer d-flex">
<button type="button" class="btn btn-primary btn-lg col-auto ms-3 bg-danger border-0"
data-dismiss="modal">Cancel</button>
<!--
KNAPPEN FRA NGIS
<button type="button" class="btn btn-primary btn-lg col me-3 ms-3 "
onclick="confirmTraining(), loadingModal();" data-dismiss="modal">Confirm</button>
</div>
onclick="confirmTraining(), loadingModal();" data-dismiss="modal">Confirm</button> -->
<button type="button" class="btn btn-primary btn-lg col me-3 ms-3 "
onclick="generatePhotos(), loadingModal();" data-dismiss="modal">Confirm</button>
</div>
</div>
</div>
</div>
Expand Down
11 changes: 11 additions & 0 deletions frontend/scripts/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ function confirmTraining() {
.catch(error => console.error(error));
}

// Initiate a download process and redirect to next page
function generatePhotos() {
fetch('/generatePhotos', {
method: 'POST'
})
.then(() => {
window.location.href = '/order.html';
})
.catch(error => console.error(error));
}

// Display the loading modal
function loadingModal() {
$('.modal').modal('show');
Expand Down
97 changes: 95 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import smtplib
import ssl
import zipfile
from zipfile import ZipFile
import base64
import sendgrid
import asyncio
Expand All @@ -23,6 +24,7 @@
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from deleteFolder import delete_all_folders
from WMS import util

# Class for the FastAPI. Will contain all our methods for updating values and starting scripts

Expand All @@ -35,8 +37,6 @@ class ConfigInput(BaseModel):
layers: list
colors: list



# Import and create instance of the FastAPI framework
app = FastAPI()

Expand Down Expand Up @@ -308,3 +308,96 @@ async def update_wms_config_file(configInput: ConfigInput):
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to write config to json file: {str(e)}")
return {"Message": "Config was updated successfully"}


@app.post("/generatePhotos")
async def generatePhotos():

#Read config from the file
file = open(CONFIG_FILE)
data = json.load(file)
config = data["Config"];


#Her må de forskjellige WMSene plugges inn
#generate_wms_picture(coordinates[0], coordinates[1], coordinates[2], coordinates[3])
#generate_wms_photo(coordinates, config)

#Også må de riktige urlene plugges inn som image_path

util.split_image("WMS/rawphotos/fasit.png", "WMS/tiles/fasit", 100)
tiles = util.split_image("WMS/rawphotos/orto.png", "WMS/tiles/orto", 100)
util.split_files("WMS/tiles", "email", tiles, config["data_parameters"][0], config["data_parameters"][1])

# Her begynner fil zipping og epost sending for WMS/Fasit

# Finner path til .env filen som ligger i ngisopenapi mappen
current_script_directory = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.abspath(os.path.join(current_script_directory, '..', 'ngisopenapi'))
env_file_path = os.path.join(project_root, '.env')

# Laster .env fra riktig path
load_dotenv(env_file_path)


def send_email_with_attachment(to_emails, subject, content, attachment_path):
"""Define email sending through SendGrid"""

if not os.path.exists(attachment_path):
raise FileNotFoundError(f"Attachment '{attachment_path}' not found.")

message = Mail(
from_email='[email protected]', # Sender epost api
to_emails=to_emails, # Til epost som blir lagt inn, tror den er definert som "email" i koden.
subject=subject,
html_content=content
)

with open(attachment_path, 'rb') as f:
data = f.read()
encoded_file = base64.b64encode(data).decode()

attachedFile = Attachment(
FileContent(encoded_file),
FileName(os.path.basename(attachment_path)),
FileType('application/zip'),
Disposition('attachment')
)
message.attachment = attachedFile

try:
sg = SendGridAPIClient(os.getenv('SENDGRID_API_KEY')) # Henter API nøkkel
response = sg.send(message)
# Prints response below
print(f"Email sent. Status code: {response.status_code}")
except Exception as e:
print(f"An error occurred: {e}")

def zip_files(directory_path: str = 'WMS/email/', zip_name: str = 'attachments.zip'):
"""Zip all files in the specified directory and save them to a zip file."""
with ZipFile(zip_name, 'w') as zipf:
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, arcname=os.path.relpath(file_path, directory_path))

@app.post("/send-email/")
async def send_zipped_files_email():
"""Zip and send email to endpoint"""
zip_files() # Zipper alle filer i WMS/email/

send_email_with_attachment(
to_emails=["[email protected]"],
subject="Here are your zipped files",
content="<strong>Zip file holding the requested data.</strong>",
attachment_path="attachments.zip"
)

# Sletter zip etter sending
os.remove("attachments.zip")

return {"message": "Email sent successfully with zipped files."}

if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
7 changes: 2 additions & 5 deletions test_main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from fastapi.testclient import TestClient
from main import app
from unittest.mock import patch


#Import test client
Expand Down Expand Up @@ -28,8 +29,4 @@ def test_update_wms_config_file():

#Check that the responses are okay
assert response.status_code == 200
assert response.json() == {"Message": "Config was updated successfully"}




assert response.json() == {"Message": "Config was updated successfully"}