69 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""transfer common classes"""
 | 
						|
from dataclasses import asdict, dataclass, field, is_dataclass
 | 
						|
from json.encoder import JSONEncoder
 | 
						|
from typing import Any, Dict, List
 | 
						|
from uuid import UUID
 | 
						|
 | 
						|
from passbook.lib.models import SerializerModel
 | 
						|
from passbook.lib.sentry import SentryIgnoredException
 | 
						|
 | 
						|
 | 
						|
def get_attrs(obj: SerializerModel) -> Dict[str, Any]:
 | 
						|
    """Get object's attributes via their serializer, and covert it to a normal dict"""
 | 
						|
    data = dict(obj.serializer(obj).data)
 | 
						|
    to_remove = ("policies", "stages", "pk")
 | 
						|
    for to_remove_name in to_remove:
 | 
						|
        if to_remove_name in data:
 | 
						|
            data.pop(to_remove_name)
 | 
						|
    return data
 | 
						|
 | 
						|
 | 
						|
@dataclass
 | 
						|
class FlowBundleEntry:
 | 
						|
    """Single entry of a bundle"""
 | 
						|
 | 
						|
    identifiers: Dict[str, Any]
 | 
						|
    model: str
 | 
						|
    attrs: Dict[str, Any]
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def from_model(
 | 
						|
        model: SerializerModel, *extra_identifier_names: str
 | 
						|
    ) -> "FlowBundleEntry":
 | 
						|
        """Convert a SerializerModel instance to a Bundle Entry"""
 | 
						|
        identifiers = {
 | 
						|
            "pk": model.pk,
 | 
						|
        }
 | 
						|
        all_attrs = get_attrs(model)
 | 
						|
 | 
						|
        for extra_identifier_name in extra_identifier_names:
 | 
						|
            identifiers[extra_identifier_name] = all_attrs.pop(extra_identifier_name)
 | 
						|
        return FlowBundleEntry(
 | 
						|
            identifiers=identifiers,
 | 
						|
            model=f"{model._meta.app_label}.{model._meta.model_name}",
 | 
						|
            attrs=all_attrs,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
@dataclass
 | 
						|
class FlowBundle:
 | 
						|
    """Dataclass used for a full export"""
 | 
						|
 | 
						|
    version: int = field(default=1)
 | 
						|
    entries: List[FlowBundleEntry] = field(default_factory=list)
 | 
						|
 | 
						|
 | 
						|
class DataclassEncoder(JSONEncoder):
 | 
						|
    """Convert FlowBundleEntry to json"""
 | 
						|
 | 
						|
    def default(self, o):
 | 
						|
        if is_dataclass(o):
 | 
						|
            return asdict(o)
 | 
						|
        if isinstance(o, UUID):
 | 
						|
            return str(o)
 | 
						|
        return super().default(o)
 | 
						|
 | 
						|
 | 
						|
class EntryInvalidError(SentryIgnoredException):
 | 
						|
    """Error raised when an entry is invalid"""
 |