|  | @@ -1,41 +1,82 @@
 | 
	
		
			
				|  |  | -import base64
 | 
	
		
			
				|  |  | -import pathlib
 | 
	
		
			
				|  |  | -import asyncio
 | 
	
		
			
				|  |  | +import tortoise.transactions
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +from .container_blob import encoded 
 | 
	
		
			
				|  |  |  from .attachment import attachment
 | 
	
		
			
				|  |  |  from .attachment import attachment_proxy
 | 
	
		
			
				|  |  | -from .attachment_file import attachment_file
 | 
	
		
			
				|  |  | -from .exceptions import resources_directory_not_exists
 | 
	
		
			
				|  |  | +from .attachments_directory import attachments_directory
 | 
	
		
			
				|  |  | +from .exceptions import id_is_invalid
 | 
	
		
			
				|  |  | +from .exceptions import not_found
 | 
	
		
			
				|  |  | +from .validators import validators
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class attachments_manager:
 | 
	
		
			
				|  |  | -    def __init__(
 | 
	
		
			
				|  |  | +    def __init__(self, directory: attachments_directory) -> None:
 | 
	
		
			
				|  |  | +        self.__directory = directory
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def directory(self) -> attachments_directory:
 | 
	
		
			
				|  |  | +        return self.__directory
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async def get_all(self) -> tuple:
 | 
	
		
			
				|  |  | +        items = await attachment.all()
 | 
	
		
			
				|  |  | +        return tuple(items)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async def upload(
 | 
	
		
			
				|  |  |          self, 
 | 
	
		
			
				|  |  | -        resources: pathlib.Path, 
 | 
	
		
			
				|  |  | -        init_directory: bool = False
 | 
	
		
			
				|  |  | -    ) -> None:
 | 
	
		
			
				|  |  | -        if init_directory:
 | 
	
		
			
				|  |  | -            resources.mkdir()
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -        if not resources.is_dir() or not resources.exists():
 | 
	
		
			
				|  |  | -            raise resources_directory_not_exists(resources)
 | 
	
		
			
				|  |  | +        content: str, 
 | 
	
		
			
				|  |  | +        extension: str, 
 | 
	
		
			
				|  |  | +        name: str, 
 | 
	
		
			
				|  |  | +        description: str
 | 
	
		
			
				|  |  | +    ) -> int:
 | 
	
		
			
				|  |  | +        decoded = await encoded(content).decode()
 | 
	
		
			
				|  |  | +        decoded = decoded.result()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        self.__resources = resources
 | 
	
		
			
				|  |  | +        proxy = await self.directory.store(decoded, extension)
 | 
	
		
			
				|  |  | +        proxy.set_name(name)
 | 
	
		
			
				|  |  | +        proxy.set_description(description)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    @property
 | 
	
		
			
				|  |  | -    def resources(self) -> pathlib.Path:
 | 
	
		
			
				|  |  | -        return self.__resources
 | 
	
		
			
				|  |  | +        created = proxy.result()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        async with tortoise.transactions.in_transaction():
 | 
	
		
			
				|  |  | +            await created.save()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return created.get_identifier()   
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async def edit(
 | 
	
		
			
				|  |  | +        self, 
 | 
	
		
			
				|  |  | +        id: int,
 | 
	
		
			
				|  |  | +        name: str,
 | 
	
		
			
				|  |  | +        description: str
 | 
	
		
			
				|  |  | +    ) -> int:
 | 
	
		
			
				|  |  | +        async with tortoise.transactions.in_transaction():
 | 
	
		
			
				|  |  | +            target = await self.require_by_id(id)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +            proxy = attachment_proxy(target)
 | 
	
		
			
				|  |  | +            proxy.set_name(name)
 | 
	
		
			
				|  |  | +            proxy.set_description(description)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            result = proxy.result()
 | 
	
		
			
				|  |  | +            await result.save()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            return result.get_identifier()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async def remove(self, id: int) -> None:
 | 
	
		
			
				|  |  | +        target = await self.require_by_id(id)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        items = await target.get_related("item", "attachments")
 | 
	
		
			
				|  |  | +       
 | 
	
		
			
				|  |  | +        await target.delete()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async def get_by_id(self, id: int) -> attachment | None:
 | 
	
		
			
				|  |  | +        if validators.id(id) is False:
 | 
	
		
			
				|  |  | +            raise id_is_invalid(id)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    async def __decode(self, content: str) -> bytes:
 | 
	
		
			
				|  |  | -        return await asyncio.to_thread(
 | 
	
		
			
				|  |  | -            base64.b64decode,
 | 
	
		
			
				|  |  | -            content.encode("ascii")
 | 
	
		
			
				|  |  | -        )   
 | 
	
		
			
				|  |  | +        async with tortoise.transactions.in_transaction():
 | 
	
		
			
				|  |  | +            return await attachment.filter(id = id).first()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    async def upload(self, content: str, extension: str) -> attachment_file:
 | 
	
		
			
				|  |  | -        decoded = await self.__decode(content)
 | 
	
		
			
				|  |  | -        file_handler = attachment_file.create(self.resources, extension)
 | 
	
		
			
				|  |  | +    async def require_by_id(self, id: int) -> attachment:
 | 
	
		
			
				|  |  | +        result = await self.get_by_id(id)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        return await file_handler.store(decoded)
 | 
	
		
			
				|  |  | +        if result is None:
 | 
	
		
			
				|  |  | +            raise not_found("attachment", id = id)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    def restore(self, file: attachment) -> attachment_file:
 | 
	
		
			
				|  |  | -        return attachment_file(file.resources_path, self.resources) 
 | 
	
		
			
				|  |  | +        return result
 |