contentmonster/classes/vessel.py

143 lines
4.8 KiB
Python
Raw Normal View History

2021-11-20 14:40:07 +00:00
from classes.connection import Connection
2021-11-22 10:14:38 +00:00
from classes.database import Database
from classes.file import File
2021-11-20 14:40:07 +00:00
from paramiko.ssh_exception import SSHException
2021-11-25 15:31:49 +00:00
from configparser import SectionProxy
from typing import Optional, Union
2021-11-22 10:14:38 +00:00
import pathlib
2021-11-25 15:31:49 +00:00
2021-11-20 14:40:07 +00:00
class Vessel:
2021-11-25 15:31:49 +00:00
"""Class describing a Vessel (= a replication destination)
"""
2021-11-20 14:40:07 +00:00
@classmethod
2021-11-25 15:31:49 +00:00
def fromConfig(cls, config: SectionProxy):
"""Create Vessel object from a Vessel section in the Config file
Args:
config (configparser.SectionProxy): Vessel section defining a
Vessel
Raises:
ValueError: Raised if section does not contain Address parameter
Returns:
classes.vessel.Vessel: Vessel object for the vessel specified in
the config section
"""
tempdir = None
2021-11-26 06:03:13 +00:00
username = None
password = None
passphrase = None
2021-11-25 15:31:49 +00:00
2021-11-22 10:14:38 +00:00
if "TempDir" in config.keys():
tempdir = config["TempDir"]
2021-11-25 15:31:49 +00:00
2021-11-26 06:03:13 +00:00
if "Username" in config.keys():
username = config["Username"]
if "Password" in config.keys():
password = config["Password"]
if "Passphrase" in config.keys():
passphrase = config["Passphrase"]
2021-11-20 14:40:07 +00:00
if "Address" in config.keys():
2021-11-26 06:03:13 +00:00
return cls(config.name.split()[1], config["Address"], username,
password, passphrase, tempdir)
2021-11-20 14:40:07 +00:00
else:
2021-11-25 15:31:49 +00:00
raise ValueError("Definition for Vessel " +
config.name.split()[1] + " does not contain Address!")
2021-11-20 14:40:07 +00:00
2021-11-26 06:03:13 +00:00
def __init__(self, name: str, address: str, username: Optional[str] = None,
password: Optional[str] = None, passphrase: Optional[str] = None,
tempdir: Optional[Union[str, pathlib.Path]] = None) -> None:
2021-11-25 15:31:49 +00:00
"""Initialize new Vessel object
Args:
name (str): Name of the Vessel
address (str): Address (IP or resolvable hostname) of the Vessel
tempdir (pathlib.Path, optional): Temporary upload location on the
Vessel, to store Chunks in
"""
2021-11-20 14:40:07 +00:00
self.name = name
self.address = address
2021-11-25 15:31:49 +00:00
self.tempdir = pathlib.Path(tempdir or "/tmp/.ContentMonster/")
2021-11-26 06:03:13 +00:00
self.username = username
self.password = password
self.passphrase = passphrase
2021-11-20 14:40:07 +00:00
self._connection = None
2021-11-25 18:03:58 +00:00
self._uploaded = self.getUploadedFromDB() # Files already uploaded
2021-11-20 14:40:07 +00:00
@property
2021-11-25 15:31:49 +00:00
def connection(self) -> Connection:
"""Get a Connection to the Vessel
Returns:
classes.connection.Connection: SSH/SFTP connection to the Vessel
"""
# If a connection exists
2021-11-20 14:40:07 +00:00
if self._connection:
try:
2021-11-25 15:31:49 +00:00
# ... check if it is up
2021-11-20 14:40:07 +00:00
self._connection._listdir()
except SSHException:
2021-11-25 15:31:49 +00:00
# ... and throw it away if it isn't
2021-11-20 14:40:07 +00:00
self._connection = None
2021-11-25 15:31:49 +00:00
# If no connection exists (anymore), set up a new one
2021-11-22 10:14:38 +00:00
self._connection = self._connection or Connection(self)
return self._connection
2021-11-25 15:31:49 +00:00
def getUploadedFromDB(self) -> list[str]:
"""Get a list of files that have previously been uploaded to the Vessel
Returns:
list: List of UUIDs of Files that have been successfully uploaded
"""
2021-11-22 10:14:38 +00:00
db = Database()
return db.getCompletionForVessel(self)
2021-11-25 15:31:49 +00:00
def currentUpload(self) -> File:
"""Get the File that is currently being uploaded to this Vessel
Returns:
classes.file.File: File object representing the file currently
being uploaded
"""
2021-11-22 10:14:38 +00:00
db = Database()
2021-11-25 15:31:49 +00:00
directory, name, _ = db.getFileByUUID(
fileuuid := self.connection.getCurrentUploadUUID())
2021-11-22 10:14:38 +00:00
return File(name, directory, fileuuid)
2021-11-20 14:40:07 +00:00
2021-11-25 15:31:49 +00:00
def clearTempDir(self) -> None:
"""Clean up the temporary directory on the Vessel
"""
self.connection.clearTempDir()
2021-11-25 18:03:58 +00:00
def pushChunk(self, chunk, path: Optional[Union[str, pathlib.Path]] = None) -> None:
"""Push the content of a Chunk object to the Vessel
Args:
chunk (classes.chunk.Chunk): Chunk object containing the data to
push to the Vessel
path (str, pathlib.Path, optional): Path at which to store the
Chunk on the Vessel. If None, use default location provided by
Vessel configuration and name provided by Chunk object. Defaults
to None.
"""
self.connection.pushChunk(chunk, path)
def compileComplete(self, remotefile) -> None:
"""Build a complete File from uploaded Chunks.
Args:
remotefile (classes.remotefile.RemoteFile): RemoteFile object
describing the uploaded File
"""
2021-11-26 06:03:13 +00:00
self.connection.compileComplete(remotefile)