Spaces:
Running
Running
import dataclasses | |
import enum | |
import streamlit as st | |
from core.files import FILE_OBJECT | |
from core.files import name_to_code | |
from core.path import get_resource_path | |
from core.state import FileObject | |
from core.state import FileSet | |
from core.state import Metadata | |
Resource = FileObject | FileSet | |
class ResourceEvent(enum.Enum): | |
"""Event that triggers a resource change.""" | |
NAME = "NAME" | |
DESCRIPTION = "DESCRIPTION" | |
ENCODING_FORMAT = "ENCODING_FORMAT" | |
INCLUDES = "INCLUDES" | |
SHA256 = "SHA256" | |
CONTAINED_IN = "CONTAINED_IN" | |
CONTENT_SIZE = "CONTENT_SIZE" | |
CONTENT_URL = "CONTENT_URL" | |
TYPE = "TYPE" | |
def handle_resource_change(event: ResourceEvent, resource: Resource, key: str): | |
value = st.session_state[key] | |
if event == ResourceEvent.NAME: | |
old_name = resource.name | |
new_name = value | |
if old_name != new_name: | |
metadata: Metadata = st.session_state[Metadata] | |
metadata.rename_distribution(old_name=old_name, new_name=new_name) | |
resource.name = value | |
elif event == ResourceEvent.DESCRIPTION: | |
resource.description = value | |
elif event == ResourceEvent.ENCODING_FORMAT: | |
resource.encoding_format = name_to_code(value) | |
elif event == ResourceEvent.INCLUDES: | |
resource.includes = value | |
elif event == ResourceEvent.SHA256: | |
resource.sha256 = value | |
elif event == ResourceEvent.CONTAINED_IN: | |
resource.contained_in = value | |
elif event == ResourceEvent.CONTENT_SIZE: | |
resource.content_size = value | |
elif event == ResourceEvent.CONTENT_URL: | |
if resource.content_url and value: | |
old_path = get_resource_path(resource.content_url) | |
new_path = get_resource_path(value) | |
if old_path.exists() and not new_path.exists(): | |
old_path.rename(new_path) | |
resource.content_url = value | |
elif event == ResourceEvent.TYPE: | |
metadata: Metadata = st.session_state[Metadata] | |
index = metadata.distribution.index(resource) | |
# Changing type by trying to retain as many attributes as possible. | |
if value == FILE_OBJECT: | |
file_object = _create_instance1_from_instance2(resource, FileObject) | |
metadata.distribution[index] = file_object | |
else: | |
file_set = _create_instance1_from_instance2(resource, FileSet) | |
metadata.distribution[index] = file_set | |
def _create_instance1_from_instance2(instance1: Resource, instance2: type): | |
"""Creates instance2 by retaining as many common attributes as possible.""" | |
attributes1 = set((field.name for field in dataclasses.fields(instance1))) | |
attributes2 = set((field.name for field in dataclasses.fields(instance2))) | |
common_attributes = attributes2.intersection(attributes1) | |
return instance2(**{ | |
attribute: getattr(instance1, attribute) for attribute in common_attributes | |
}) | |