Auto generate urls with customer ids
This commit is contained in:
@@ -1,14 +1,15 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import boto3
|
import boto3
|
||||||
from typing import Dict, Optional
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from typing import Dict, Optional
|
||||||
from redirects_base import Content, Customer, Redirects, Tag
|
from redirects_base import Content, Customer, Redirects, Tag
|
||||||
|
|
||||||
s3_client = None
|
s3_client = None
|
||||||
bucket_config = ''
|
bucket_config = ''
|
||||||
bucket_data = ''
|
bucket_data = ''
|
||||||
|
function_url = ''
|
||||||
|
|
||||||
class S3Bucket(BaseModel):
|
class S3Bucket(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
@@ -33,12 +34,13 @@ class Record(BaseModel):
|
|||||||
s3: S3Event
|
s3: S3Event
|
||||||
|
|
||||||
def lambda_handler(event: dict, context):
|
def lambda_handler(event: dict, context):
|
||||||
global s3_client, bucket_config, bucket_data
|
global s3_client, bucket_config, bucket_data, function_url
|
||||||
|
|
||||||
if s3_client is None:
|
if s3_client is None:
|
||||||
print("Init Function")
|
print("Init Function")
|
||||||
bucket_config = os.environ.get('BUCKET_CONFIG', 'standout-config')
|
bucket_config = os.environ.get('BUCKET_CONFIG', 'standout-config')
|
||||||
bucket_data = os.environ.get('BUCKET_DATA', 'standout-data')
|
bucket_data = os.environ.get('BUCKET_DATA', 'standout-data')
|
||||||
|
function_url = os.environ.get('FUNCTION_URL', 'https://api.standout.it/dev')
|
||||||
print(f'Bucket Config: {bucket_config}')
|
print(f'Bucket Config: {bucket_config}')
|
||||||
print(f' Bucket Data: {bucket_data}')
|
print(f' Bucket Data: {bucket_data}')
|
||||||
s3_client = boto3.client('s3')
|
s3_client = boto3.client('s3')
|
||||||
@@ -76,39 +78,7 @@ def lambda_handler(event: dict, context):
|
|||||||
processAdd(record=record, redirects=redirects, client=s3_client)
|
processAdd(record=record, redirects=redirects, client=s3_client)
|
||||||
|
|
||||||
case "ObjectRemoved:Delete":
|
case "ObjectRemoved:Delete":
|
||||||
keys = getObjectKeys(record=record)
|
processDelete(record=record, redirects=redirects)
|
||||||
|
|
||||||
if not redirects.customers:
|
|
||||||
return False
|
|
||||||
cust_key = keys.pop()
|
|
||||||
customer = redirects.customers.get(cust_key, None)
|
|
||||||
if len(keys) == 0 or not customer:
|
|
||||||
redirects.customers.pop(cust_key, None)
|
|
||||||
break
|
|
||||||
|
|
||||||
if not customer.tags:
|
|
||||||
return False
|
|
||||||
tag_key = keys.pop()
|
|
||||||
tag = customer.tags.get(tag_key, None)
|
|
||||||
if len(keys) == 0 or not tag:
|
|
||||||
customer.tags.pop(tag_key, None)
|
|
||||||
break
|
|
||||||
|
|
||||||
match len(keys):
|
|
||||||
case 2:
|
|
||||||
if not tag.content or not isinstance(tag.content, Dict):
|
|
||||||
return False
|
|
||||||
tag.content.pop(keys[1], None)
|
|
||||||
case 1:
|
|
||||||
if isinstance(tag.content, Dict) and keys[0] in tag.content.keys():
|
|
||||||
tag.content[keys[0]] = None
|
|
||||||
else:
|
|
||||||
tag.content = None
|
|
||||||
case _:
|
|
||||||
print("Unexpected")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print(f"Object remove: {record.s3.object.key}")
|
|
||||||
|
|
||||||
case "ObjectCreated:Copy":
|
case "ObjectCreated:Copy":
|
||||||
print(f"Object copy: {record.s3.object.key}")
|
print(f"Object copy: {record.s3.object.key}")
|
||||||
@@ -137,14 +107,17 @@ def processAdd(record: Record, redirects: Redirects, client) -> None:
|
|||||||
keys = getObjectKeys(record=record)
|
keys = getObjectKeys(record=record)
|
||||||
|
|
||||||
# crea il primo utente se necessario o selezionalo
|
# crea il primo utente se necessario o selezionalo
|
||||||
cust_key = keys.pop()
|
cust_name = keys.pop()
|
||||||
|
cust_id = searchCustomerKey(redirects=redirects, cust_name=cust_name, default=uuid4().hex)
|
||||||
|
assert(cust_id is not None) # uuid cannot return none
|
||||||
|
|
||||||
if redirects.customers is None:
|
if redirects.customers is None:
|
||||||
redirects.customers = {cust_key: Customer(status="active", tags=None)}
|
redirects.customers = {cust_id: Customer(name=cust_name, status="active", tags=None)}
|
||||||
if cust_key not in redirects.customers.keys():
|
if cust_id not in redirects.customers.keys():
|
||||||
redirects.customers[cust_key] = Customer(status="active", tags=None)
|
redirects.customers[cust_id] = Customer(name=cust_name, status="active", tags=None)
|
||||||
|
|
||||||
# Aggiunto solo un cliente
|
# Aggiunto solo un cliente
|
||||||
c = redirects.customers[cust_key]
|
c = redirects.customers[cust_id]
|
||||||
if len(keys) == 0 or not c:
|
if len(keys) == 0 or not c:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -164,24 +137,75 @@ def processAdd(record: Record, redirects: Redirects, client) -> None:
|
|||||||
file_name = keys[0]
|
file_name = keys[0]
|
||||||
if file_name == "url.txt":
|
if file_name == "url.txt":
|
||||||
with client.get_object(Bucket=bucket_data, Key=record.s3.object.key)['Body'] as url_file:
|
with client.get_object(Bucket=bucket_data, Key=record.s3.object.key)['Body'] as url_file:
|
||||||
content = Content(type='url', key=file_name, url=url_file.readline().decode().strip())
|
content = Content(type='url', key=file_name, url=url_file.readline().decode().strip(), tag_url=None)
|
||||||
else:
|
else:
|
||||||
content = Content(type='s3', key=file_name, url=None)
|
content = Content(type='s3', key=file_name, url=None, tag_url=None)
|
||||||
|
|
||||||
# Aggiungi il contenuto a una faccia o al tag a seconda della lunghezza del path
|
# Aggiungi il contenuto a una faccia o al tag a seconda della lunghezza del path
|
||||||
match len(keys):
|
match len(keys):
|
||||||
case 2:
|
case 2:
|
||||||
|
content.tag_url = generateTagUrl(cust_id, tag_key, face_id=keys[1])
|
||||||
if t.content is None or isinstance(t.content, Content):
|
if t.content is None or isinstance(t.content, Content):
|
||||||
t.content = {keys[1]: content}
|
t.content = {keys[1]: content}
|
||||||
elif isinstance(t.content, dict):
|
elif isinstance(t.content, dict):
|
||||||
t.content[keys[1]] = content
|
t.content[keys[1]] = content
|
||||||
case 1:
|
case 1:
|
||||||
|
content.tag_url = generateTagUrl(cust_id, tag_key, None)
|
||||||
t.content = content
|
t.content = content
|
||||||
case _:
|
case _:
|
||||||
print("Too long keys")
|
print("Too long keys")
|
||||||
|
|
||||||
print(f"ObjectCreated: {record.s3.object.key}")
|
print(f"ObjectCreated: {record.s3.object.key}")
|
||||||
|
|
||||||
|
def generateTagUrl(cust_id: str, tag_id: str, face_id: str | None) -> str:
|
||||||
|
return f"{function_url}/api?id={cust_id}&tag_id={tag_id}{f"&face_id={face_id}" if face_id else ""}"
|
||||||
|
|
||||||
|
def searchCustomerKey(redirects: Redirects, cust_name: str, default: str | None) -> str | None:
|
||||||
|
if redirects.customers is None:
|
||||||
|
return default
|
||||||
|
for k,v in redirects.customers.items():
|
||||||
|
if v is not None and v.name == cust_name:
|
||||||
|
return k
|
||||||
|
return default
|
||||||
|
|
||||||
|
def processDelete(record: Record, redirects: Redirects) -> None:
|
||||||
|
keys = getObjectKeys(record=record)
|
||||||
|
|
||||||
|
if not redirects.customers:
|
||||||
|
return
|
||||||
|
cust_name = keys.pop()
|
||||||
|
cust_key = searchCustomerKey(redirects=redirects, cust_name=cust_name, default=None)
|
||||||
|
if cust_key is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
customer = redirects.customers.get(cust_key, None)
|
||||||
|
if len(keys) == 0 or not customer:
|
||||||
|
redirects.customers.pop(cust_key, None)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not customer.tags:
|
||||||
|
return
|
||||||
|
tag_key = keys.pop()
|
||||||
|
tag = customer.tags.get(tag_key, None)
|
||||||
|
if len(keys) == 0 or not tag:
|
||||||
|
customer.tags.pop(tag_key, None)
|
||||||
|
return
|
||||||
|
|
||||||
|
match len(keys):
|
||||||
|
case 2:
|
||||||
|
if not tag.content or not isinstance(tag.content, Dict):
|
||||||
|
return
|
||||||
|
tag.content.pop(keys[1], None)
|
||||||
|
case 1:
|
||||||
|
if isinstance(tag.content, Dict) and keys[0] in tag.content.keys():
|
||||||
|
tag.content[keys[0]] = None
|
||||||
|
else:
|
||||||
|
tag.content = None
|
||||||
|
case _:
|
||||||
|
print("Unexpected")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Object remove: {record.s3.object.key}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
with open('/home/emanuele/dev/StandOut/lambda_config/test.json', 'r') as f:
|
with open('/home/emanuele/dev/StandOut/lambda_config/test.json', 'r') as f:
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ from pydantic import BaseModel
|
|||||||
class Content(BaseModel):
|
class Content(BaseModel):
|
||||||
type: str
|
type: str
|
||||||
key: str
|
key: str
|
||||||
url: Optional[str | None]
|
url: Optional[str]
|
||||||
|
tag_url: Optional[str]
|
||||||
|
|
||||||
class Tag(BaseModel):
|
class Tag(BaseModel):
|
||||||
status: str
|
status: str
|
||||||
@@ -12,6 +13,7 @@ class Tag(BaseModel):
|
|||||||
|
|
||||||
class Customer(BaseModel):
|
class Customer(BaseModel):
|
||||||
status: str
|
status: str
|
||||||
|
name: str
|
||||||
tags: Optional[Dict[str, Optional[Tag]] ]
|
tags: Optional[Dict[str, Optional[Tag]] ]
|
||||||
|
|
||||||
class Redirects(BaseModel):
|
class Redirects(BaseModel):
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def lambda_handler(event: dict, context):
|
|||||||
match content.type:
|
match content.type:
|
||||||
case "s3":
|
case "s3":
|
||||||
file_name = content.key.replace('+',' ') # remove slugify of filename
|
file_name = content.key.replace('+',' ') # remove slugify of filename
|
||||||
key = f'{params.id}/{params.tag_id}{'/'+params.face_id if params.face_id else ''}/{file_name}'
|
key = f'{customer['name']}/{params.tag_id}{'/'+params.face_id if params.face_id else ''}/{file_name}'
|
||||||
final_redirect = s3_client.generate_presigned_url('get_object',
|
final_redirect = s3_client.generate_presigned_url('get_object',
|
||||||
Params={'Bucket': bucket_data,
|
Params={'Bucket': bucket_data,
|
||||||
'Key': key},
|
'Key': key},
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ resource "aws_lambda_function" "lambda_standout_config" {
|
|||||||
variables = {
|
variables = {
|
||||||
BUCKET_CONFIG = aws_s3_bucket.s3_standout_config.bucket,
|
BUCKET_CONFIG = aws_s3_bucket.s3_standout_config.bucket,
|
||||||
BUCKET_DATA = aws_s3_bucket.s3_standout.bucket
|
BUCKET_DATA = aws_s3_bucket.s3_standout.bucket
|
||||||
|
FUNCTION_URL = aws_apigatewayv2_stage.api_standout_lambda_stage.invoke_url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user