First working version

This commit is contained in:
2024-05-01 15:22:18 +02:00
parent a9be8054fd
commit 5a854279b1
4 changed files with 98 additions and 133 deletions

View File

@@ -1,9 +1,8 @@
import os import os
import json import json
import boto3 import boto3
from typing import Optional from typing import Dict, Optional
from pydantic import BaseModel from pydantic import BaseModel
import pydantic_core
from redirects_base import Content, Customer, Redirects, Tag from redirects_base import Content, Customer, Redirects, Tag
s3_client = None s3_client = None
@@ -55,7 +54,7 @@ def lambda_handler(event: dict, context):
redirects = Redirects.model_validate_json(resp['Body'].read()) redirects = Redirects.model_validate_json(resp['Body'].read())
else: else:
with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'r') as f: with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'r') as f:
redirects = Redirects.model_validate_json(f.read()) redirects = Redirects.model_validate_json(f.read(), strict=False)
except s3_client.exceptions.NoSuchKey as e: except s3_client.exceptions.NoSuchKey as e:
print(e) print(e)
# Oppure pagina "siamo spiacenti ma il contenuto non e' disponibile" # Oppure pagina "siamo spiacenti ma il contenuto non e' disponibile"
@@ -72,25 +71,82 @@ def lambda_handler(event: dict, context):
print(f"Action: {record.eventName}") print(f"Action: {record.eventName}")
print(f"Object: {record.s3}") print(f"Object: {record.s3}")
# splitta la chiave per capire la directory
keys = record.s3.object.key.split('/')
keys.reverse()
match record.eventName: match record.eventName:
case "ObjectCreated:Put" | "ObjectCreated:CompleteMultipartUpload": case "ObjectCreated:Put" | "ObjectCreated:CompleteMultipartUpload":
print(f"ObjectCreated: {record.s3.object.key}") processAdd(record=record, redirects=redirects, client=s3_client)
case "ObjectRemoved:Delete":
keys = getObjectKeys(record=record)
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":
print(f"Object copy: {record.s3.object.key}")
case _:
print("Unknown action")
if context is not None:
resp = s3_client.put_object(Bucket=bucket_config,
Key='redirects.json',
Body=redirects.model_dump_json(indent=2))
print(f"New redirects version: {resp['ETag']}")
else:
with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'w') as f:
f.write(redirects.model_dump_json(indent=2))
return True
def getObjectKeys(record: Record) -> list[str]:
keys = [v for v in record.s3.object.key.split('/') if v != '']
keys.reverse()
return keys
def processAdd(record: Record, redirects: Redirects, client) -> None:
# splitta la chiave per capire la directory
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_key = keys.pop()
if redirects.customers is None: if redirects.customers is None:
redirects.customers = {cust_key: Customer(status="active")} redirects.customers = {cust_key: Customer(status="active", tags=None)}
if cust_key not in redirects.customers.keys(): if cust_key not in redirects.customers.keys():
redirects.customers[cust_key] = Customer(status="active") redirects.customers[cust_key] = Customer(status="active", tags=None)
# Aggiunto solo un cliente # Aggiunto solo un cliente
if len(keys) == 0:
break
c = redirects.customers[cust_key] c = redirects.customers[cust_key]
if len(keys) == 0 or not c:
return
# crea un tag per l'utente, con contenuto nullo o selezionalo # crea un tag per l'utente, con contenuto nullo o selezionalo
tag_key = keys.pop() tag_key = keys.pop()
@@ -100,14 +156,14 @@ def lambda_handler(event: dict, context):
c.tags[tag_key] = Tag(status="active", content=None) c.tags[tag_key] = Tag(status="active", content=None)
# Aggiunta anche una chiave # Aggiunta anche una chiave
if len(keys) == 0:
break
t = c.tags[tag_key] t = c.tags[tag_key]
if len(keys) == 0 or not t:
return
# Crea un contenuto per il tag a seconda della lunghezza della chiave # Crea un contenuto per il tag a seconda della lunghezza della chiave
file_name = keys[0] file_name = keys[0]
if file_name == "url.txt": if file_name == "url.txt":
with s3_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())
else: else:
content = Content(type='s3', key=file_name, url=None) content = Content(type='s3', key=file_name, url=None)
@@ -124,25 +180,7 @@ def lambda_handler(event: dict, context):
case _: case _:
print("Too long keys") print("Too long keys")
case "ObjectCreated:Copy": print(f"ObjectCreated: {record.s3.object.key}")
print(f"Object copy: {record.s3.object.key}")
case "s3:ObjectRemoved:Delete":
print(f"Object remove: {record.s3.object.key}")
case _:
print("Unknown action")
if context is not None:
resp = s3_client.put_object(Bucket=bucket_config,
Key='redirects.json',
Body=redirects.model_dump_json(indent=2))
print(f"New redirects version: {resp['ETag']}")
else:
with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'w') as f:
f.write(redirects.model_dump_json(indent=2))
return True
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -1,49 +1,13 @@
{ {
"customers": { "customers": {
"customer1": { "customer3": {
"status": "active", "status": "active",
"tags": { "tags": {
"tag1": {
"status": "active",
"content": {
"type": "url",
"key": "url.txt",
"url": "https://grafana.etss.it/d/LbON5PkGz/power?orgId=1&from=now-12h&to=now&refresh=30s"
}
},
"tag2": { "tag2": {
"status": "active", "status": "active",
"content": { "content": {
"type": "s3", "type": "s3",
"key": "file.txt", "key": "foo.txt",
"url": null
}
}
}
},
"customer2": {
"status": "active",
"tags": {
"tag1": {
"status": "active",
"content": {
"face1": {
"type": "s3",
"key": "file.txt",
"url": null
}
}
}
}
},
"customer3": {
"status": "active",
"tags": {
"tag1": {
"status": "active",
"content": {
"type": "s3",
"key": "VID20240116160134.mp4",
"url": null "url": null
} }
} }

View File

@@ -4,52 +4,15 @@ from pydantic import BaseModel
class Content(BaseModel): class Content(BaseModel):
type: str type: str
key: str key: str
url: Optional[str | None] = None url: Optional[str | None]
class Tag(BaseModel): class Tag(BaseModel):
status: str status: str
content: Content | Dict[str, Content] | None = None content: Optional[Content | Dict[str, Optional[Content]]]
class Customer(BaseModel): class Customer(BaseModel):
status: str status: str
tags: Dict[str, Tag] | None = None tags: Optional[Dict[str, Optional[Tag]] ]
class Redirects(BaseModel): class Redirects(BaseModel):
customers: Dict[str, Customer] | None = None customers: Dict[str, Optional[Customer]] | None = None
if __name__ == "__main__":
r = Redirects (
customers = {
"cust1": Customer(
status="active",
tags= {
"tag1" : Tag (
status="active",
content= Content(
type="s3",
key="foo",
url=None
)
),
"tag2" : Tag(
status="active",
content = {
"face1" : Content(
type="s3",
key="contentface1",
url = "foo"
),
"face2": Content(
type="s3",
key="contentface2",
url = "bar"
),
}
)
}
)
}
)
r.customers['cust2'] = Customer(status="inactive", tags=None)
print(r.model_dump_json(indent=2))

View File

@@ -27,7 +27,7 @@
"arn": "arn:aws:s3:::standout-data" "arn": "arn:aws:s3:::standout-data"
}, },
"object": { "object": {
"key": "customer1/tag2/file.txt", "key": "customer3/tag2/foo.txt",
"size": 2844326, "size": 2844326,
"eTag": "7039e5338840f289d0510dc9149bf0b5", "eTag": "7039e5338840f289d0510dc9149bf0b5",
"sequencer": "00662A206F99CD2E09" "sequencer": "00662A206F99CD2E09"