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"
@@ -71,78 +70,117 @@ 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)
# crea il primo utente se necessario o selezionalo if not redirects.customers:
return False
cust_key = keys.pop() cust_key = keys.pop()
if redirects.customers is None: customer = redirects.customers.get(cust_key, None)
redirects.customers = {cust_key: Customer(status="active")} if len(keys) == 0 or not customer:
if cust_key not in redirects.customers.keys(): redirects.customers.pop(cust_key, None)
redirects.customers[cust_key] = Customer(status="active")
# Aggiunto solo un cliente
if len(keys) == 0:
break break
c = redirects.customers[cust_key]
# crea un tag per l'utente, con contenuto nullo o selezionalo if not customer.tags:
return False
tag_key = keys.pop() tag_key = keys.pop()
if c.tags is None: tag = customer.tags.get(tag_key, None)
c.tags = {tag_key: Tag(status="active", content=None)} if len(keys) == 0 or not tag:
if tag_key not in c.tags.keys(): customer.tags.pop(tag_key, None)
c.tags[tag_key] = Tag(status="active", content=None)
# Aggiunta anche una chiave
if len(keys) == 0:
break break
t = c.tags[tag_key]
# Crea un contenuto per il tag a seconda della lunghezza della chiave
file_name = keys[0]
if file_name == "url.txt":
with s3_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())
else:
content = Content(type='s3', key=file_name, url=None)
# 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:
if t.content is None or isinstance(t.content, Content): if not tag.content or not isinstance(tag.content, Dict):
t.content = {keys[1]: content} return False
elif isinstance(t.content, dict): tag.content.pop(keys[1], None)
t.content[keys[1]] = content
case 1: case 1:
t.content = content if isinstance(tag.content, Dict) and keys[0] in tag.content.keys():
tag.content[keys[0]] = None
else:
tag.content = None
case _: case _:
print("Too long keys") 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}")
case "s3:ObjectRemoved:Delete":
print(f"Object remove: {record.s3.object.key}")
case _: case _:
print("Unknown action") print("Unknown action")
if context is not None: if context is not None:
resp = s3_client.put_object(Bucket=bucket_config, resp = s3_client.put_object(Bucket=bucket_config,
Key='redirects.json', Key='redirects.json',
Body=redirects.model_dump_json(indent=2)) Body=redirects.model_dump_json(indent=2))
print(f"New redirects version: {resp['ETag']}") print(f"New redirects version: {resp['ETag']}")
else: else:
with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'w') as f: with open('/home/emanuele/dev/StandOut/lambda_config/redirects.json', 'w') as f:
f.write(redirects.model_dump_json(indent=2)) f.write(redirects.model_dump_json(indent=2))
return True 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
cust_key = keys.pop()
if redirects.customers is None:
redirects.customers = {cust_key: Customer(status="active", tags=None)}
if cust_key not in redirects.customers.keys():
redirects.customers[cust_key] = Customer(status="active", tags=None)
# Aggiunto solo un cliente
c = redirects.customers[cust_key]
if len(keys) == 0 or not c:
return
# crea un tag per l'utente, con contenuto nullo o selezionalo
tag_key = keys.pop()
if c.tags is None:
c.tags = {tag_key: Tag(status="active", content=None)}
if tag_key not in c.tags.keys():
c.tags[tag_key] = Tag(status="active", content=None)
# Aggiunta anche una chiave
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
file_name = keys[0]
if file_name == "url.txt":
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())
else:
content = Content(type='s3', key=file_name, url=None)
# Aggiungi il contenuto a una faccia o al tag a seconda della lunghezza del path
match len(keys):
case 2:
if t.content is None or isinstance(t.content, Content):
t.content = {keys[1]: content}
elif isinstance(t.content, dict):
t.content[keys[1]] = content
case 1:
t.content = content
case _:
print("Too long keys")
print(f"ObjectCreated: {record.s3.object.key}")
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"