Allow arbitrary database type to be passed in preparation for Academon integration
This commit is contained in:
parent
b736226140
commit
d5e560d945
5 changed files with 32 additions and 20 deletions
|
@ -5,15 +5,18 @@ from typing import Union
|
||||||
|
|
||||||
from classes.vessel import Vessel
|
from classes.vessel import Vessel
|
||||||
from classes.directory import Directory
|
from classes.directory import Directory
|
||||||
|
from classes.database import Database
|
||||||
|
|
||||||
|
|
||||||
class MonsterConfig:
|
class MonsterConfig:
|
||||||
def readFile(self, path: Union[str, Path]) -> None:
|
def readFile(self, path: Union[str, Path], dbclass: type = Database) -> None:
|
||||||
"""Read .ini file into MonsterConfig object
|
"""Read .ini file into MonsterConfig object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path (str, pathlib.Path): Location of the .ini file to read
|
path (str, pathlib.Path): Location of the .ini file to read
|
||||||
(absolute or relative to the working directory)
|
(absolute or relative to the working directory)
|
||||||
|
dbclass (type): Class to use for database connections. Defaults to
|
||||||
|
built-in Database using sqlite3.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: Raised if the passed file is not a ContentMonster .ini
|
ValueError: Raised if the passed file is not a ContentMonster .ini
|
||||||
|
@ -43,7 +46,8 @@ class MonsterConfig:
|
||||||
|
|
||||||
# Read Vessels from the config file
|
# Read Vessels from the config file
|
||||||
elif section.startswith("Vessel"):
|
elif section.startswith("Vessel"):
|
||||||
self.vessels.append(Vessel.fromConfig(parser[section]))
|
self.vessels.append(
|
||||||
|
Vessel.fromConfig(parser[section], dbclass))
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize a new (empty) MonsterConfig object
|
"""Initialize a new (empty) MonsterConfig object
|
||||||
|
|
|
@ -11,7 +11,7 @@ class File:
|
||||||
"""Object representing a file found in a local Directory
|
"""Object representing a file found in a local Directory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, directory, uuid: Optional[str] = None) -> None:
|
def __init__(self, name: str, directory, uuid: Optional[str] = None, dbclass: type = Database) -> None:
|
||||||
"""Initialize new File object
|
"""Initialize new File object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -20,12 +20,15 @@ class File:
|
||||||
is located within
|
is located within
|
||||||
uuid (str, optional): Unique identifier of this File object. Will
|
uuid (str, optional): Unique identifier of this File object. Will
|
||||||
be retrieved from database if None. Defaults to None.
|
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:
|
Raises:
|
||||||
FileNotFoundError: Raised if the specified File does not exist
|
FileNotFoundError: Raised if the specified File does not exist
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.directory = directory
|
self.directory = directory
|
||||||
|
self.dbclass = dbclass
|
||||||
|
|
||||||
if not self.exists():
|
if not self.exists():
|
||||||
raise FileNotFoundError(f"File {self.name} does not exist in {self.directory.name}!")
|
raise FileNotFoundError(f"File {self.name} does not exist in {self.directory.name}!")
|
||||||
|
@ -47,9 +50,9 @@ class File:
|
||||||
"""Return unique identifier for this File object
|
"""Return unique identifier for this File object
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: File object's UUID retrieved from Database
|
str: File object's UUID retrieved from database
|
||||||
"""
|
"""
|
||||||
db = Database()
|
db = self.dbclass()
|
||||||
return db.getFileUUID(self)
|
return db.getFileUUID(self)
|
||||||
|
|
||||||
def getFullPath(self) -> str:
|
def getFullPath(self) -> str:
|
||||||
|
|
|
@ -16,7 +16,7 @@ import os.path
|
||||||
class ShoreThread(Process):
|
class ShoreThread(Process):
|
||||||
"""Thread handling the discovery of shore-side file changes
|
"""Thread handling the discovery of shore-side file changes
|
||||||
"""
|
"""
|
||||||
def __init__(self, state: dict) -> None:
|
def __init__(self, state: dict, dbclass: type = Database) -> None:
|
||||||
"""Create a new ShoreThread object
|
"""Create a new ShoreThread object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -27,6 +27,7 @@ class ShoreThread(Process):
|
||||||
self._state = state
|
self._state = state
|
||||||
self.queue = Queue()
|
self.queue = Queue()
|
||||||
self._logger = Logger()
|
self._logger = Logger()
|
||||||
|
self._dbclass = dbclass
|
||||||
|
|
||||||
def getAllFiles(self) -> list:
|
def getAllFiles(self) -> list:
|
||||||
"""Return File objects for all files in all Directories
|
"""Return File objects for all files in all Directories
|
||||||
|
@ -107,7 +108,7 @@ class ShoreThread(Process):
|
||||||
|
|
||||||
# Remove file from database
|
# Remove file from database
|
||||||
self._logger.debug(f"Purging file {name} from database")
|
self._logger.debug(f"Purging file {name} from database")
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
db.removeFile(directory, name)
|
db.removeFile(directory, name)
|
||||||
|
|
||||||
def addFile(self, fileobj):
|
def addFile(self, fileobj):
|
||||||
|
@ -142,7 +143,7 @@ class ShoreThread(Process):
|
||||||
self._state["files"].append(f)
|
self._state["files"].append(f)
|
||||||
|
|
||||||
def checkFileCompletion(self, fileobj: File) -> bool:
|
def checkFileCompletion(self, fileobj: File) -> bool:
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
complete = db.getCompletionByFileUUID(fileobj.uuid)
|
complete = db.getCompletionByFileUUID(fileobj.uuid)
|
||||||
del(db)
|
del(db)
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,14 @@ class Vessel:
|
||||||
"""Class describing a Vessel (= a replication destination)
|
"""Class describing a Vessel (= a replication destination)
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def fromConfig(cls, config: SectionProxy):
|
def fromConfig(cls, config: SectionProxy, dbclass: type = Database):
|
||||||
"""Create Vessel object from a Vessel section in the Config file
|
"""Create Vessel object from a Vessel section in the Config file
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config (configparser.SectionProxy): Vessel section defining a
|
config (configparser.SectionProxy): Vessel section defining a
|
||||||
Vessel
|
Vessel
|
||||||
|
dbclass (type): Class to use for database connections. Defaults to
|
||||||
|
built-in Database using sqlite3.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: Raised if section does not contain Address parameter
|
ValueError: Raised if section does not contain Address parameter
|
||||||
|
@ -60,7 +62,7 @@ class Vessel:
|
||||||
|
|
||||||
if "Address" in config.keys():
|
if "Address" in config.keys():
|
||||||
return cls(config.name.split()[1], config["Address"], username,
|
return cls(config.name.split()[1], config["Address"], username,
|
||||||
password, passphrase, port, timeout, tempdir, ignoredirs)
|
password, passphrase, port, timeout, tempdir, ignoredirs, dbclass)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Definition for Vessel " +
|
raise ValueError("Definition for Vessel " +
|
||||||
config.name.split()[1] + " does not contain Address!")
|
config.name.split()[1] + " does not contain Address!")
|
||||||
|
@ -69,7 +71,7 @@ class Vessel:
|
||||||
password: Optional[str] = None, passphrase: Optional[str] = None,
|
password: Optional[str] = None, passphrase: Optional[str] = None,
|
||||||
port: Optional[int] = None, timeout: Optional[int] = None,
|
port: Optional[int] = None, timeout: Optional[int] = None,
|
||||||
tempdir: Optional[Union[str, pathlib.Path]] = None,
|
tempdir: Optional[Union[str, pathlib.Path]] = None,
|
||||||
ignoredirs: list[Optional[str]] = []) -> None:
|
ignoredirs: list[Optional[str]] = [], dbclass: type = Database) -> None:
|
||||||
"""Initialize new Vessel object
|
"""Initialize new Vessel object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -89,6 +91,7 @@ class Vessel:
|
||||||
self._connection = None
|
self._connection = None
|
||||||
self._uploaded = self.getUploadedFromDB() # Files already uploaded
|
self._uploaded = self.getUploadedFromDB() # Files already uploaded
|
||||||
self._ignoredirs = ignoredirs # Directories not replicated to this vessel
|
self._ignoredirs = ignoredirs # Directories not replicated to this vessel
|
||||||
|
self._dbclass = dbclass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connection(self) -> Connection:
|
def connection(self) -> Connection:
|
||||||
|
@ -116,7 +119,7 @@ class Vessel:
|
||||||
Returns:
|
Returns:
|
||||||
list: List of UUIDs of Files that have been successfully uploaded
|
list: List of UUIDs of Files that have been successfully uploaded
|
||||||
"""
|
"""
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
return db.getCompletionForVessel(self)
|
return db.getCompletionForVessel(self)
|
||||||
|
|
||||||
def currentUpload(self) -> Optional[tuple[str, str, str]]:
|
def currentUpload(self) -> Optional[tuple[str, str, str]]:
|
||||||
|
@ -131,7 +134,7 @@ class Vessel:
|
||||||
"""
|
"""
|
||||||
self.assertTempDirectory() # After a reboot, the tempdir may be gone
|
self.assertTempDirectory() # After a reboot, the tempdir may be gone
|
||||||
|
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
output = db.getFileByUUID(self.connection.getCurrentUploadUUID())
|
output = db.getFileByUUID(self.connection.getCurrentUploadUUID())
|
||||||
del db
|
del db
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ class VesselThread(Process):
|
||||||
"""Thread processing uploads to a single vessel
|
"""Thread processing uploads to a single vessel
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, vessel: Vessel, state: dict) -> None:
|
def __init__(self, vessel: Vessel, state: dict, dbclass: type = Database) -> None:
|
||||||
"""Initialize a new VesselThread
|
"""Initialize a new VesselThread
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -27,6 +27,7 @@ class VesselThread(Process):
|
||||||
self.vessel = vessel
|
self.vessel = vessel
|
||||||
self._state = state
|
self._state = state
|
||||||
self._logger = Logger()
|
self._logger = Logger()
|
||||||
|
self._dbclass = dbclass
|
||||||
|
|
||||||
def run(self) -> NoReturn:
|
def run(self) -> NoReturn:
|
||||||
"""Run thread and process uploads to the vessel
|
"""Run thread and process uploads to the vessel
|
||||||
|
@ -95,7 +96,7 @@ class VesselThread(Process):
|
||||||
f"Start processing file {fileobj.name} in directory {fileobj.directory.name} on vessel {self.vessel.name}")
|
f"Start processing file {fileobj.name} in directory {fileobj.directory.name} on vessel {self.vessel.name}")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
if not db.getFileByUUID(fileobj.uuid):
|
if not db.getFileByUUID(fileobj.uuid):
|
||||||
self._logger.debug(
|
self._logger.debug(
|
||||||
f"File {fileobj.name} in directory {fileobj.directory.name} does not exist anymore - deleting from {self.vessel.name}")
|
f"File {fileobj.name} in directory {fileobj.directory.name} does not exist anymore - deleting from {self.vessel.name}")
|
||||||
|
@ -111,7 +112,7 @@ class VesselThread(Process):
|
||||||
f"File {fileobj.name} uploaded to vessel {self.vessel.name} completely - finalizing")
|
f"File {fileobj.name} uploaded to vessel {self.vessel.name} completely - finalizing")
|
||||||
remotefile.finalizeUpload()
|
remotefile.finalizeUpload()
|
||||||
|
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
db.logCompletion(fileobj, self.vessel)
|
db.logCompletion(fileobj, self.vessel)
|
||||||
del(db)
|
del(db)
|
||||||
|
|
||||||
|
@ -143,7 +144,7 @@ class VesselThread(Process):
|
||||||
self.vessel.compileComplete(remotefile)
|
self.vessel.compileComplete(remotefile)
|
||||||
|
|
||||||
def checkFileCompletion(self, fileobj: File) -> None:
|
def checkFileCompletion(self, fileobj: File) -> None:
|
||||||
db = Database()
|
db = self._dbclass()
|
||||||
complete = db.getCompletionByFileUUID(fileobj.uuid)
|
complete = db.getCompletionByFileUUID(fileobj.uuid)
|
||||||
del(db)
|
del(db)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue