First working version
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import os
|
||||
import json
|
||||
import boto3
|
||||
from typing import Optional
|
||||
from typing import Dict, Optional
|
||||
from pydantic import BaseModel
|
||||
import pydantic_core
|
||||
from redirects_base import Content, Customer, Redirects, Tag
|
||||
|
||||
s3_client = None
|
||||
@@ -55,7 +54,7 @@ def lambda_handler(event: dict, context):
|
||||
redirects = Redirects.model_validate_json(resp['Body'].read())
|
||||
else:
|
||||
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:
|
||||
print(e)
|
||||
# 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"Object: {record.s3}")
|
||||
|
||||
# splitta la chiave per capire la directory
|
||||
keys = record.s3.object.key.split('/')
|
||||
keys.reverse()
|
||||
|
||||
match record.eventName:
|
||||
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()
|
||||
if redirects.customers is None:
|
||||
redirects.customers = {cust_key: Customer(status="active")}
|
||||
if cust_key not in redirects.customers.keys():
|
||||
redirects.customers[cust_key] = Customer(status="active")
|
||||
|
||||
# Aggiunto solo un cliente
|
||||
if len(keys) == 0:
|
||||
customer = redirects.customers.get(cust_key, None)
|
||||
if len(keys) == 0 or not customer:
|
||||
redirects.customers.pop(cust_key, None)
|
||||
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()
|
||||
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
|
||||
if len(keys) == 0:
|
||||
tag = customer.tags.get(tag_key, None)
|
||||
if len(keys) == 0 or not tag:
|
||||
customer.tags.pop(tag_key, None)
|
||||
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):
|
||||
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
|
||||
if not tag.content or not isinstance(tag.content, Dict):
|
||||
return False
|
||||
tag.content.pop(keys[1], None)
|
||||
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 _:
|
||||
print("Too long keys")
|
||||
print("Unexpected")
|
||||
return False
|
||||
|
||||
print(f"Object remove: {record.s3.object.key}")
|
||||
|
||||
case "ObjectCreated:Copy":
|
||||
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))
|
||||
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
|
||||
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__":
|
||||
|
||||
@@ -1,49 +1,13 @@
|
||||
{
|
||||
"customers": {
|
||||
"customer1": {
|
||||
"customer3": {
|
||||
"status": "active",
|
||||
"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": {
|
||||
"status": "active",
|
||||
"content": {
|
||||
"type": "s3",
|
||||
"key": "file.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",
|
||||
"key": "foo.txt",
|
||||
"url": null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,52 +4,15 @@ from pydantic import BaseModel
|
||||
class Content(BaseModel):
|
||||
type: str
|
||||
key: str
|
||||
url: Optional[str | None] = None
|
||||
url: Optional[str | None]
|
||||
|
||||
class Tag(BaseModel):
|
||||
status: str
|
||||
content: Content | Dict[str, Content] | None = None
|
||||
content: Optional[Content | Dict[str, Optional[Content]]]
|
||||
|
||||
class Customer(BaseModel):
|
||||
status: str
|
||||
tags: Dict[str, Tag] | None = None
|
||||
tags: Optional[Dict[str, Optional[Tag]] ]
|
||||
|
||||
class Redirects(BaseModel):
|
||||
customers: Dict[str, 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))
|
||||
customers: Dict[str, Optional[Customer]] | None = None
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"arn": "arn:aws:s3:::standout-data"
|
||||
},
|
||||
"object": {
|
||||
"key": "customer1/tag2/file.txt",
|
||||
"key": "customer3/tag2/foo.txt",
|
||||
"size": 2844326,
|
||||
"eTag": "7039e5338840f289d0510dc9149bf0b5",
|
||||
"sequencer": "00662A206F99CD2E09"
|
||||
|
||||
Reference in New Issue
Block a user