moonstream/moonstreamapi/moonstreamapi/admin/migrations/generate_entity_subscriptio...

856 wiersze
29 KiB
Python
Czysty Zwykły widok Historia

2023-02-14 16:43:33 +00:00
"""
Generate entity subscriptions from existing brood resources subscriptions
2023-02-14 16:43:33 +00:00
"""
import hashlib
import logging
import json
import os
import traceback
from typing import List, Optional, Dict, Any, Union, Tuple
2023-02-14 16:43:33 +00:00
import uuid
2023-04-27 12:37:17 +00:00
import time
2023-02-14 16:43:33 +00:00
2023-04-26 14:55:13 +00:00
import boto3 # type: ignore
2023-02-14 16:43:33 +00:00
from bugout.data import BugoutResources, BugoutResource
from bugout.exceptions import BugoutResponseException
2023-04-26 14:55:13 +00:00
from entity.exceptions import EntityUnexpectedResponse # type: ignore
from entity.data import EntityCollectionResponse, EntityResponse # type: ignore
2023-02-14 16:43:33 +00:00
from ...settings import (
BUGOUT_REQUEST_TIMEOUT_SECONDS,
MOONSTREAM_ADMIN_ACCESS_TOKEN,
BUGOUT_RESOURCE_TYPE_SUBSCRIPTION,
BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION,
2023-02-14 16:43:33 +00:00
MOONSTREAM_APPLICATION_ID,
BUGOUT_RESOURCE_TYPE_DASHBOARD,
2023-02-14 16:43:33 +00:00
)
from ...settings import bugout_client as bc, entity_client as ec
from ..subscription_types import CANONICAL_SUBSCRIPTION_TYPES
logger = logging.getLogger(__name__)
### create collection for user
def create_collection_for_user(user_id: uuid.UUID) -> str:
2023-02-14 16:43:33 +00:00
"""
Create collection for user if not exist
"""
try:
# try get collection
collection: EntityCollectionResponse = ec.add_collection(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, name=f"subscriptions_{user_id}"
)
collection_id = collection.collection_id
except EntityUnexpectedResponse as e:
logger.error(f"Error create collection, error: {str(e)}")
return str(collection_id)
2023-02-14 16:43:33 +00:00
def add_entity_subscription(
user_id: uuid.UUID,
subscription_type_id: str,
collection_id: str,
address: str,
color: str,
label: str,
content: Dict[str, Any],
) -> EntityResponse:
2023-02-14 16:43:33 +00:00
"""
Add subscription to collection
"""
if subscription_type_id not in CANONICAL_SUBSCRIPTION_TYPES:
raise ValueError(
f"Unknown subscription type ID: {subscription_type_id}. "
f"Known subscription type IDs: {CANONICAL_SUBSCRIPTION_TYPES.keys()}"
)
elif CANONICAL_SUBSCRIPTION_TYPES[subscription_type_id].blockchain is None:
raise ValueError(
f"Subscription type ID {subscription_type_id} is not a blockchain subscription type."
)
entity = ec.add_entity(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
collection_id=collection_id,
address=address,
blockchain=CANONICAL_SUBSCRIPTION_TYPES[subscription_type_id].blockchain,
name=label,
required_fields=[
{"type": "subscription"},
{"subscription_type_id": f"{subscription_type_id}"},
{"color": f"{color}"},
{"label": f"{label}"},
{"user_id": f"{user_id}"},
],
secondary_fields=content,
)
return entity
2023-02-14 16:43:33 +00:00
def get_abi_from_s3(s3_path: str, bucket: str):
"""
Get ABI from S3
"""
try:
s3 = boto3.resource("s3")
obj = s3.Object(bucket, s3_path)
abi = obj.get()["Body"].read().decode("utf-8")
return abi
except Exception as e:
logger.error(f"Error get ABI from S3: {str(e)}")
def revoke_collection_permissions_from_user(
user_id: uuid.UUID, collection_id: str, permissions: List[str]
):
"""
Remove all permissions from user
"""
bc.delete_journal_scopes(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
journal_id=collection_id,
holder_type="user",
holder_id=user_id,
permission_list=permissions,
)
def find_user_collection(
user_id: uuid.UUID,
create_if_not_exists: bool = False,
) -> Tuple[Optional[str], Optional[str]]:
"""
Find user collection in Brood resources
Can create new collection if not exists and create_if_not_exists = True
"""
params = {
"type": BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION,
"user_id": str(user_id),
}
2023-04-26 15:01:33 +00:00
logger.info(f"Looking for collection for user {user_id}")
try:
user_entity_resources: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, params=params
)
except BugoutResponseException as e:
logger.error(
f"Error listing subscriptions for user ({user_id}) Bugout error: {str(e)}"
)
except Exception as e:
logger.error(
f"Error listing subscriptions for user ({user_id}) error: {str(e)}"
)
if len(user_entity_resources.resources) > 0:
collection_id = user_entity_resources.resources[0].resource_data[
"collection_id"
]
2023-04-26 15:01:33 +00:00
logger.info(
f"Collection found for user {user_id}. collection_id: {collection_id}"
)
return collection_id, str(user_entity_resources.resources[0].id)
elif create_if_not_exists:
# Create collection new collection for user
2023-04-26 15:01:33 +00:00
logger.info(f"Creating new collection")
collection = create_collection_for_user(user_id)
return collection, None
return None, None
def generate_entity_subscriptions_from_brood_resources() -> None:
2023-02-14 16:43:33 +00:00
"""
Parse all existing dashboards at Brood resource
and replace key to correct one.
Schema can use for rename first level keys
"""
### Get admin user id
admin_user = bc.get_user(token=MOONSTREAM_ADMIN_ACCESS_TOKEN)
admin_user_id = admin_user.id
2023-04-26 15:01:33 +00:00
logger.info(f"admin user :{admin_user.username}")
### Get all subscription resources type = "subscription"
2023-02-14 16:43:33 +00:00
resources: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": BUGOUT_RESOURCE_TYPE_SUBSCRIPTION},
2023-02-14 16:43:33 +00:00
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
2023-04-26 15:01:33 +00:00
logger.info(f"Admin own {len(resources.resources)} subscriptions")
### initial users_subscriptions, dashboards_by_user, stages is empty
2023-02-14 16:43:33 +00:00
users_subscriptions: Dict[Union[str, uuid.UUID], Any] = {}
stages: Dict[Union[str, uuid.UUID], Any] = {}
### Restore previous stages if exists stages.json
2023-02-14 16:43:33 +00:00
if os.path.exists("stages.json"):
with open("stages.json", "r") as f:
stages = json.load(f)
2023-02-14 16:43:33 +00:00
### Subscriptions parsing and save to users_subscriptions
for resource in resources.resources:
2023-02-14 16:43:33 +00:00
resource_data = resource.resource_data
resource_data["subscription_id"] = resource.id
if "user_id" not in resource_data:
continue
user_id = resource_data["user_id"]
if user_id not in users_subscriptions:
users_subscriptions[user_id] = []
# Stages object
if user_id not in stages:
stages[user_id] = {}
users_subscriptions[user_id].append(resource_data)
2023-04-26 15:01:33 +00:00
logger.info(f"parsed users: {len(users_subscriptions)}")
### Create collections and add subscriptions
2023-02-14 16:43:33 +00:00
try:
for user_id, subscriptions in users_subscriptions.items():
user_id = str(user_id)
collection_id = None
resource_id_of_user_collection = None
2023-02-14 16:43:33 +00:00
### Collection can already exist in stages.json
2023-02-14 16:43:33 +00:00
if "collection_id" in stages[user_id]:
collection_id = stages[user_id]["collection_id"]
if "subscription_resource_id" in stages[user_id]:
resource_id_of_user_collection = stages[user_id][
"subscription_resource_id"
]
2023-02-14 16:43:33 +00:00
else:
### look for collection in brood resources
collection_id, resource_id_of_user_collection = find_user_collection(
user_id, create_if_not_exists=True
)
2023-02-14 16:43:33 +00:00
if collection_id is None:
2023-04-26 15:01:33 +00:00
logger.info(f"Collection not found or create for user {user_id}")
continue
2023-02-14 16:43:33 +00:00
stages[user_id]["collection_id"] = collection_id
2023-02-14 16:43:33 +00:00
# Create user subscription collection resource
if "subscription_resource_id" not in stages[user_id]:
if resource_id_of_user_collection is not None:
stages[user_id]["subscription_resource_id"] = str(
resource_id_of_user_collection
2023-02-14 16:43:33 +00:00
)
else:
resource_data = {
"type": BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION,
"user_id": str(user_id),
"collection_id": str(collection_id),
"version": "1.0.0",
}
### Create resource for user collection
try:
subscription_resource: BugoutResource = bc.create_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
application_id=MOONSTREAM_APPLICATION_ID,
resource_data=resource_data,
)
stages[user_id]["subscription_resource_id"] = str(
subscription_resource.id
)
except Exception as e:
logger.error(
f"Failed to create subscription brood resource: {str(e)}"
)
2023-02-14 16:43:33 +00:00
2023-04-26 14:38:32 +00:00
if "processed_subscriptions" not in stages[user_id]:
stages[user_id]["processed_subscriptions"] = {}
2023-02-14 16:43:33 +00:00
### Add subscriptions to collection
2023-02-14 16:43:33 +00:00
for subscription in subscriptions:
if (
str(subscription["subscription_id"])
2023-04-26 14:38:32 +00:00
in stages[user_id]["processed_subscriptions"]
):
2023-02-14 16:43:33 +00:00
continue
subscription_type_id = subscription["subscription_type_id"]
address = subscription["address"]
color = subscription["color"]
label = subscription["label"]
# try to get abi from S3
abi = None
if subscription.get("bucket") and subscription.get("s3_path"):
2023-02-14 16:43:33 +00:00
try:
abi_body = get_abi_from_s3(
bucket=subscription["bucket"],
s3_path=subscription["s3_path"],
2023-02-14 16:43:33 +00:00
)
# abi hash
abi_hash = hashlib.sha256(abi_body.encode("utf-8")).hexdigest()
abi = True
logger.info(
f"Got abi from S3 from path {subscription['s3_path']}"
)
2023-02-14 16:43:33 +00:00
except Exception as e:
logger.error(f"Failed to get abi from S3: {str(e)}")
abi = None
2023-04-27 13:02:21 +00:00
# Add subscription to collection
logger.info(f"Add subscription to collection: {collection_id}")
entity = add_entity_subscription(
2023-02-14 16:43:33 +00:00
user_id=user_id,
collection_id=collection_id,
subscription_type_id=subscription_type_id,
address=address,
color=color,
label=label,
content={"abi": abi_body, "abi_hash": abi_hash} if abi else {},
2023-02-14 16:43:33 +00:00
)
2023-04-26 14:38:32 +00:00
stages[user_id]["processed_subscriptions"][
str(subscription["subscription_id"])
] = {"entity_id": str(entity.entity_id), "dashboard_ids": []}
2023-02-14 16:43:33 +00:00
# Add permissions to user
if user_id != admin_user_id:
# Add permissions to user
if "permissions_granted" not in stages[user_id]:
try:
2023-04-26 14:38:32 +00:00
bc.update_journal_scopes(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
journal_id=collection_id,
holder_type="user",
holder_id=user_id,
permission_list=[
"journals.read",
"journals.update",
"journals.entries.read",
"journals.entries.create",
"journals.entries.update",
"journals.entries.delete",
],
)
2023-04-26 14:38:32 +00:00
stages[user_id]["permissions_granted"] = True
except Exception as e:
logger.error(f"Failed to add permissions to user: {str(e)}")
continue
else:
logger.warn(
f"User {user_id} == {admin_user_id} permissions not changed. Unexpected behaivior!"
)
2023-02-14 16:43:33 +00:00
except Exception as e:
traceback.print_exc()
2023-02-14 16:43:33 +00:00
logger.error(f"Failed to proccess user subscriptions: {str(e)}")
finally:
try:
with open("stages.json", "w") as f:
json.dump(stages, f)
except Exception as e:
logger.error(f"Failed to save stages: {str(e)}")
# write as text
with open("stages-json-failed.txt", "w") as f:
f.write(str(stages))
def update_dashboards_connection():
"""
Look up all dashboards and update their connection to the user subscription
"""
dashboards_by_user: Dict[Union[str, uuid.UUID], Any] = {}
stages: Dict[Union[str, uuid.UUID], Any] = {}
### Restore previous stages if exists stages.json
if os.path.exists("stages.json"):
with open("stages.json", "r") as f:
stages = json.load(f)
### Dashboards parsing and save to dashboards_by_user
dashboard_resources: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": BUGOUT_RESOURCE_TYPE_DASHBOARD},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
for dashboard in dashboard_resources.resources:
if "user_id" not in dashboard.resource_data:
continue
user_id = dashboard.resource_data["user_id"]
if user_id not in dashboards_by_user:
dashboards_by_user[user_id] = []
dashboards_by_user[user_id].append(dashboard)
try:
for user in dashboards_by_user:
2023-04-26 15:01:33 +00:00
logger.info(f"dashboards: {len(dashboards_by_user[user])}")
if user not in stages:
continue
for dashboard in dashboards_by_user[user]:
dashboard_data = dashboard.resource_data
dashboard_subscription_settings = dashboard_data.get(
"subscription_settings"
)
if dashboard_subscription_settings is None:
continue
2023-04-27 12:58:02 +00:00
if len(dashboard_subscription_settings) == 0:
continue
2023-04-26 15:01:33 +00:00
logger.info(f"dashboard {dashboard.id}")
for setting_index, subscription_setting in enumerate(
dashboard_subscription_settings
):
2023-04-26 15:01:33 +00:00
logger.info(
f"Find subscripton: {subscription_setting['subscription_id']}"
)
2023-04-27 12:58:02 +00:00
old_subscription_id = str(subscription_setting["subscription_id"])
if old_subscription_id in stages[user]["processed_subscriptions"]:
2023-04-26 15:01:33 +00:00
logger.info(
f"subscription found: {subscription_setting['subscription_id']}"
)
subscription_stages_metadata = stages[user][
2023-04-26 14:38:32 +00:00
"processed_subscriptions"
][subscription_setting["subscription_id"]]
if (
str(dashboard.id)
in subscription_stages_metadata["dashboard_ids"]
):
continue
2023-04-27 12:58:02 +00:00
# change original dashboard subscription settings
dashboard_data["subscription_settings"][setting_index][
"subscription_id"
] = subscription_stages_metadata["entity_id"]
# Update brood resource in bugout client
stages[user]["processed_subscriptions"][old_subscription_id][
"dashboard_ids"
].append(str(dashboard.id))
try:
logger.info(f"Update dashboard: {dashboard.id} for user {user}")
bc.update_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=dashboard.id,
resource_data={
"update": {
"subscription_settings": dashboard_data[
"subscription_settings"
]
}
},
)
except Exception as e:
traceback.print_exc()
logger.error(
f"**Failed to update dashboard: {str(e)} for user {user}**"
)
continue
except Exception as e:
traceback.print_exc()
logger.error(f"Failed to proccess dashboards: {str(e)}")
finally:
try:
with open("stages.json", "w") as f:
json.dump(stages, f)
except Exception as e:
logger.error(f"Failed to save stages: {str(e)}")
# write as text
with open("stages-json-failed.txt", "w") as f:
f.write(str(stages))
2023-04-13 14:49:56 +00:00
def delete_generated_entity_subscriptions_from_brood_resources():
"""
Delete all generated entity subscriptions previously created by the script
Also delete all generated entity subscriptions from the brood resources
"""
### stages file example
admin_user = bc.get_user(token=MOONSTREAM_ADMIN_ACCESS_TOKEN)
2023-04-26 15:01:33 +00:00
logger.info(f"admin user :{admin_user.username}")
2023-04-13 14:49:56 +00:00
# Get all subscriptions
### Get all subscription resources type = "subscription"
resources: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": BUGOUT_RESOURCE_TYPE_SUBSCRIPTION},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
2023-04-26 15:01:33 +00:00
logger.info(f"Admin own {len(resources.resources)} subscriptions")
2023-04-13 14:49:56 +00:00
### initial users_subscriptions, dashboards_by_user, stages is empty
users_subscriptions: Dict[Union[str, uuid.UUID], Any] = {}
stages: Dict[Union[str, uuid.UUID], Any] = {}
### Restore previous stages if exists stages.json
if os.path.exists("stages.json"):
with open("stages.json", "r") as f:
stages = json.load(f)
### Subscriptions parsing and save to users_subscriptions
for resource in resources.resources:
resource_data = resource.resource_data
resource_data["subscription_id"] = resource.id
if "user_id" not in resource_data:
continue
user_id = resource_data["user_id"]
if user_id not in users_subscriptions:
users_subscriptions[user_id] = []
users_subscriptions[user_id].append(resource_data)
2023-04-26 15:01:33 +00:00
logger.info(f"parsed users: {len(users_subscriptions)}")
2023-04-13 14:49:56 +00:00
### Create collections and add subscriptions
try:
for user_id, _ in users_subscriptions.items():
2023-04-13 14:49:56 +00:00
user_id = str(user_id)
collection_id = None
resource_id_of_user_collection = None
### Collection can already exist in stages.json
if "collection_id" in stages[user_id]:
collection_id = stages[user_id]["collection_id"]
if "subscription_resource_id" in stages[user_id]:
resource_id_of_user_collection = stages[user_id][
"subscription_resource_id"
]
2023-04-13 14:49:56 +00:00
else:
### look for collection in brood resources
collection_id, resource_id_of_user_collection = find_user_collection(
user_id, create_if_not_exists=False
2023-04-13 14:49:56 +00:00
)
if collection_id is None:
2023-04-26 15:01:33 +00:00
logger.info(f"Collection not found or create for user {user_id}")
2023-04-13 14:49:56 +00:00
continue
### Delete collection
try:
ec.delete_collection(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, collection_id=collection_id
)
2023-04-26 15:01:33 +00:00
logger.info(f"Collection deleted {collection_id}")
2023-04-13 14:49:56 +00:00
except Exception as e:
2023-04-26 15:01:33 +00:00
logger.error(f"Failed to delete collection: {str(e)}")
2023-04-13 14:49:56 +00:00
### Delete collection resource
try:
2023-04-26 15:01:33 +00:00
logger.info(f"Collection resource id {resource_id_of_user_collection}")
2023-04-13 14:49:56 +00:00
bc.delete_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource_id_of_user_collection,
)
2023-04-26 15:01:33 +00:00
logger.info(
f"Collection resource deleted {resource_id_of_user_collection}"
)
2023-04-13 14:49:56 +00:00
# clear stages
stages[user_id] = {}
except Exception as e:
2023-04-26 15:01:33 +00:00
logger.error(f"Failed to delete collection resource: {str(e)}")
2023-04-13 14:49:56 +00:00
continue
2023-04-27 12:37:17 +00:00
except Exception as e:
traceback.print_exc()
logger.error(f"Failed to proccess user subscriptions: {str(e)}")
2023-04-27 12:37:17 +00:00
def restore_dashboard_state():
### initial users_subscriptions, dashboards_by_user, stages is empty
2023-04-27 12:37:17 +00:00
dashboards_by_user: Dict[Union[str, uuid.UUID], Any] = {}
2023-04-27 12:37:17 +00:00
stages: Dict[Union[str, uuid.UUID], Any] = {}
2023-04-27 12:37:17 +00:00
### Restore previous stages if exists stages.json
2023-04-27 12:37:17 +00:00
if os.path.exists("stages.json"):
with open("stages.json", "r") as f:
stages = json.load(f)
2023-04-27 12:37:17 +00:00
### Subscriptions parsing and save to users_subscriptions
### Dashboards parsing and save to dashboards_by_user
dashboards: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": BUGOUT_RESOURCE_TYPE_DASHBOARD},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
for dashboard in dashboards.resources:
if "user_id" not in dashboard.resource_data:
continue
user_id = dashboard.resource_data["user_id"]
if user_id not in dashboards_by_user:
dashboards_by_user[user_id] = []
dashboards_by_user[user_id].append(dashboard)
### Retunr all dashboards to old state
logger.info(f"Amount of users: {len(dashboards_by_user)}")
for user_id in dashboards_by_user:
logger.info(
f"Amount of dashboards: {len(dashboards_by_user[user_id])} of user {user_id}"
)
2023-04-27 12:58:02 +00:00
user_entity_subscriptions = {
subscription["entity_id"]: key
for key, subscription in stages[user_id]["processed_subscriptions"].items()
}
2023-04-27 12:37:17 +00:00
for dashboard in dashboards_by_user[user_id]:
try:
dashboard_data = dashboard.resource_data
if "subscription_settings" not in dashboard_data:
2023-04-27 16:06:09 +00:00
logger.info("no subscription_settings")
2023-04-27 12:37:17 +00:00
continue
if len(dashboard_data["subscription_settings"]) == 0:
2023-04-27 16:06:09 +00:00
logger.info("no subscription_settings")
2023-04-27 12:37:17 +00:00
continue
dashboard_metadata = dashboard_data["subscription_settings"]
for index, settings in enumerate(dashboard_metadata):
if "subscription_id" not in settings:
2023-04-27 16:06:09 +00:00
logger.info("no subscription_id")
continue
2023-04-27 12:37:17 +00:00
subscription_id = settings["subscription_id"]
if subscription_id not in user_entity_subscriptions:
continue
logger.info(
f"Update dashboard {dashboard.id} with subscription {subscription_id} to old state"
)
2023-04-27 12:37:17 +00:00
dashboard_metadata[index][
"subscription_id"
] = user_entity_subscriptions[subscription_id]
bc.update_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=dashboard.id,
resource_data={
"update": {"subscription_settings": dashboard_metadata}
},
)
except Exception as e:
traceback.print_exc()
logger.error(f"Failed to update dashboard: {str(e)}")
continue
2023-05-01 09:32:28 +00:00
def fix_duplicates_keys_in_entity_subscription():
"""
Migration generate_entity_subscriptions_from_brood_resources
create duplicates keys "secondary_fields" subscriptions secondary_fields
"secondary_fields": {
"secondary_fields": {
...
}
}
That function will remove internal secondary_fields and flat all keys to one level upper
"""
# get all entities from subscriptions
subscriptions: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
# get collection ids from that resources
collection_id_user_id_mappig = {}
for subscription in subscriptions.resources:
if "collection_id" in subscription.resource_data:
if (
subscription.resource_data["collection_id"]
not in collection_id_user_id_mappig
):
collection_id_user_id_mappig[
subscription.resource_data["collection_id"]
] = subscription.resource_data["user_id"]
else:
raise Exception(
f"Duplicate collection_id {subscription.resource_data['collection_id']} in subscriptions"
)
# go through all collections and fix entities.
# Will creating one new entity with same data but without "type:subscription" in required_fields
for collection_id, user_id in collection_id_user_id_mappig.items():
# get collection entities
collection_entities = ec.search_entities(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
collection_id=collection_id,
required_field=[f"type:subscription"],
limit=1000,
)
2023-05-01 15:02:47 +00:00
logger.info(
f"Amount of entities in user: {user_id} collection {collection_id}: {len(collection_entities.entities)}"
)
2023-05-01 09:32:28 +00:00
for entity in collection_entities.entities:
# get entity data
2023-05-01 15:02:47 +00:00
if entity.secondary_fields is None:
2023-05-01 09:32:28 +00:00
continue
secondary_fields = entity.secondary_fields
if "secondary_fields" not in secondary_fields:
continue
secondary_fields = secondary_fields["secondary_fields"]
# get entity id
entity_id = entity.entity_id
2023-05-01 09:32:28 +00:00
# get entity type
entity_type = None
# extract required fields
for entity_required_field in entity.required_fields:
if "type" in entity_required_field:
entity_type = entity_required_field["type"]
if entity_type != "subscription":
continue
# Create new entity with same data but without "type:subscription" in required_fields
try:
new_required_fields = [
entity_field
for entity_field in entity.required_fields
if "type" not in entity_field
]
new_required_fields.append(
{"type": "copy_of_malformed_entity_20230213"}
)
2023-05-01 15:02:47 +00:00
new_required_fields.append({"entity_id": str(entity_id)})
new_entity = ec.add_entity(
2023-05-01 09:32:28 +00:00
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
collection_id=collection_id,
2023-05-01 15:02:47 +00:00
blockchain=entity.blockchain,
address=entity.address,
2023-05-01 09:32:28 +00:00
name=entity.name,
2023-05-01 15:02:47 +00:00
required_fields=new_required_fields,
secondary_fields=entity.secondary_fields,
2023-05-01 09:32:28 +00:00
)
logger.info(
2023-05-01 15:02:47 +00:00
f"Entity {new_entity.entity_id} created successfully for collection {collection_id}"
2023-05-01 09:32:28 +00:00
)
except Exception as e:
logger.error(
f"Failed to create entity {entity_id} for collection {collection_id}: {str(e)}, user_id: {user_id}"
)
continue
# Update old entity without secondary_fields duplicate
try:
ec.update_entity(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
2023-05-01 15:02:47 +00:00
collection_id=collection_id,
2023-05-01 09:32:28 +00:00
entity_id=entity_id,
2023-05-01 15:02:47 +00:00
blockchain=entity.blockchain,
address=entity.address,
2023-05-01 09:32:28 +00:00
name=entity.name,
required_fields=entity.required_fields,
secondary_fields=secondary_fields,
)
logger.info(
f"Entity {entity_id} updated successfully for collection {collection_id}"
)
except Exception as e:
logger.error(
f"Failed to update entity {entity_id} for collection {collection_id}: {str(e)}, user_id: {user_id}"
)