contentmonster/src/contentmonster/classes/file.py
Kumi e82ccb2701
feat: Enhance stability and configurability
- Extended copyright to reflect the current year.
- Incremented project version to indicate new features and fixes.
- Added a new script entry for easier execution, increasing utility and accessibility.
- Updated project URLs for better alignment with current infrastructure.
- Refactored settings path for simplicity and consistency across deployments.
- Improved code readability and maintenance across several modules by cleaning up redundant code, adding missing type annotations, and ensuring consistent code formatting.
- Enhanced logging capabilities and error handling to improve diagnostics and troubleshooting, supporting more robust error recovery mechanisms.
- Implemented more graceful handling of termination signals to ensure clean shutdown and resource cleanup, enhancing the robustness of the application in production environments.
- Introduced command-line argument parsing for configuration file path customization, improving flexibility in different runtime environments.

These changes collectively improve the project's maintainability, reliability, and user experience, laying a stronger foundation for future development.
2024-04-22 16:39:33 +02:00

104 lines
3.3 KiB
Python

from .chunk import Chunk
from .database import Database
from typing import Optional
import hashlib
import os.path
class File:
"""Object representing a file found in a local Directory"""
def __init__(
self, name: str, directory, uuid: Optional[str] = None, dbclass: type = Database
) -> None:
"""Initialize new File object
Args:
name (str): Filename (basename without path) of the File to create
directory (classes.directory.Directory): Directory object the File
is located within
uuid (str, optional): Unique identifier of this File object. Will
be retrieved from database if None. Defaults to None.
dbclass (type): Class to use for database connections. Defaults to
built-in Database using sqlite3.
Raises:
FileNotFoundError: Raised if the specified File does not exist
"""
self.name = name
self.directory = directory
self.dbclass = dbclass
if not self.exists():
raise FileNotFoundError(
f"File {self.name} does not exist in {self.directory.name}!"
)
self.uuid = uuid or self.getUUID()
def exists(self) -> bool:
"""Check if the File exists on the local file system
Returns:
bool: True if the File exists, else False
"""
return os.path.isfile(self.directory.location / self.name)
def moveCompleted(self) -> None:
self.getFullPath().rename(self.directory.completeddir / self.name)
def getUUID(self) -> str:
"""Return unique identifier for this File object
Returns:
str: File object's UUID retrieved from database
"""
db = self.dbclass()
return db.getFileUUID(self)
def getFullPath(self) -> str:
"""Get the full path of the File
Returns:
str: Full path of the File on the local file system
"""
return self.directory.location / self.name
def getHash(self) -> str:
"""Get hash for this File
Returns:
str: SHA256 for the full content of this File
"""
return self.getChunk(-1).getHash()
def getChunk(self, count: int, size: Optional[int] = None) -> Chunk:
"""Get a Chunk of this File
Args:
count (int): Position of the Chunk in a list of equally large
Chunks (first index: 0). -1 represents a Chunk containing the
complete file.
size (int, optional): Size of the Chunk to create in Bytes. Must
be set if count is not -1. Defaults to None.
Returns:
classes.chunk.Chunk: Chunk object containing File content from
(count * size) bytes to ((count + 1) * size - 1) bytes
Raises:
ValueError: Raised if size is not set for a count that is not -1
"""
if count != -1 and not size:
raise ValueError(
"A Chunk size needs to be passed to getChunk() if not using the complete file (-1)!"
)
with open(self.getFullPath(), "rb") as binary:
binary.seek((count * size) if count > 0 else 0)
data = binary.read(size if count >= 0 else None)
return Chunk(self, count, data)