File size: 2,917 Bytes
f82850d
cb5b71d
 
 
 
f82850d
e92e659
 
cb5b71d
 
 
 
 
 
 
 
 
 
 
 
 
f82850d
cb5b71d
f82850d
cb5b71d
 
f82850d
cb5b71d
 
 
 
 
 
 
 
 
 
 
 
 
 
e92e659
f82850d
 
cb5b71d
 
f82850d
 
cb5b71d
 
 
e92e659
 
 
 
 
cb5b71d
f82850d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
    })