6 Commits

Author SHA1 Message Date
bfcf65b6e7 Merge pull request 'dev' (#3) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/dabdatasync/pulls/3
new-tag:0.2.0
2024-03-28 03:30:02 +01:00
cclecle
5fca93e4a8 chore: rework suffix (now in compressor class only) 2024-03-28 02:16:14 +00:00
cclecle
79518946ac fix quality warning 2024-03-28 02:06:01 +00:00
cclecle
6aea5311bb feat: fully implement read for dir and files
test: implement full unitest scenario
2024-03-28 01:55:17 +00:00
f39fd9cf44 Merge pull request 'import code' (#2) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/dabdatasync/pulls/2
new-tag:0.1.0
2024-03-23 13:00:47 +01:00
cclecle
dd45b1281f rename project 2024-03-23 11:45:18 +00:00
5 changed files with 122 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>{{project_name}}</name>
<name>dabdatasync</name>
<comment></comment>
<projects>
</projects>

View File

@@ -9,6 +9,7 @@ from pathlib import Path
import os
import tarfile
from tempfile import NamedTemporaryFile, TemporaryDirectory
import shutil
from pydantic import BaseModel
from webdav3.client import Client as webdav3_Client
@@ -34,19 +35,32 @@ def urljoin(*args):
class A_DataSync_Compressor(ABC):
"""abstract compressor class"""
suffix: str
@abstractmethod
def compress(self, path_in: Path, file_out: IO):
"""compress method - virtual"""
@abstractmethod
def decompress(self, path_in: Path, path_out: Path):
"""decompress method - virtual"""
class DataSync_Compressor_targz(A_DataSync_Compressor):
"""Concrete compressor class - .tar.gz compressor"""
suffix: str = ".tar.gz"
def compress(self, path_in: Path, file_out: IO):
"""compress method - .tar.gz concrete"""
with tarfile.open(fileobj=file_out, mode="w:gz") as tar:
tar.add(path_in, arcname=os.path.basename(path_in))
def decompress(self, path_in: Path, path_out: Path):
"""decompress method - .tar.gz concrete"""
with tarfile.open(path_in, "r") as tar:
tar.extractall(path_out)
class A_DataSync_Record(BaseModel, ABC):
"""Abstract DataSync Record class"""
@@ -54,12 +68,15 @@ class A_DataSync_Record(BaseModel, ABC):
name: str
rec_type: str
value: str
suffix: str
@abstractmethod
def compress(self, compressor: A_DataSync_Compressor, file_out: IO) -> None:
"""compress the record - virtual"""
@abstractmethod
def decompress(self, compressor: A_DataSync_Compressor, path_in: Path) -> None:
"""compress the record - virtual"""
class DataSync_Record_Factory:
"""DataSync Record Factory"""
@@ -86,7 +103,6 @@ class C_DataSync_Record_FS(A_DataSync_Record):
"""Concrete DataSync Record class - FileSystem"""
rec_type: str = "fs"
suffix: str = ".tar.gz"
path: Optional[Path] = None
def model_post_init(self, __context) -> None:
@@ -98,6 +114,16 @@ class C_DataSync_Record_FS(A_DataSync_Record):
assert isinstance(self.path, Path)
compressor.compress(self.path, file_out)
def decompress(self, compressor: A_DataSync_Compressor, path_in: Path) -> None:
"""compress the record - concrete FS implementation"""
if TYPE_CHECKING:
assert isinstance(self.path, Path)
if os.path.isdir(self.path):
shutil.rmtree(self.path)
if os.path.isfile(self.path):
os.remove(self.path)
compressor.decompress(path_in, self.path.parent)
class I_DataSync(ABC):
"""Abstract DataSync class"""
@@ -165,7 +191,8 @@ class I_DataSync(ABC):
self.connect()
with TemporaryDirectory() as tmpdir:
for datasync_record in self.ar_datasync_record:
self._impl_read_data(Path(datasync_record.name + datasync_record.suffix), Path(tmpdir))
self._impl_read_data(Path(datasync_record.name + self.compressor.suffix), Path(tmpdir))
datasync_record.decompress(self.compressor, Path(tmpdir) / (datasync_record.name + self.compressor.suffix))
@abstractmethod
def _impl_read_data(self, file_in: Path, file_out: Path) -> None:
@@ -177,7 +204,7 @@ class I_DataSync(ABC):
self._impl_wipe_data()
for datasync_record in self.ar_datasync_record:
try:
with NamedTemporaryFile("wb", suffix=datasync_record.suffix, delete=False) as tmp_file:
with NamedTemporaryFile("wb", suffix=self.compressor.suffix, delete=False) as tmp_file:
datasync_record.compress(self.compressor, tmp_file)
tmp_file.seek(0)
tmp_file.close()

View File

@@ -10,6 +10,7 @@ import unittest
from os import chdir
from pathlib import Path
import pprint
import shutil
print(__name__)
print(__package__)
@@ -23,6 +24,14 @@ chdir(testdir_path.parent.resolve())
class TestDabDataSync(unittest.TestCase):
def setUp(self) -> None:
chdir(testdir_path.parent.resolve())
shutil.rmtree(testdir_path / "test_data", ignore_errors=True)
shutil.rmtree(testdir_path / "test_data2", ignore_errors=True)
shutil.copytree(testdir_path / "test_data_origin", testdir_path / "test_data")
shutil.copytree(testdir_path / "test_data_origin", testdir_path / "test_data2")
def tearDown(self) -> None:
shutil.rmtree(testdir_path / "test_data", ignore_errors=True)
shutil.rmtree(testdir_path / "test_data2", ignore_errors=True)
def test_version(self):
self.assertNotEqual(dabdatasync.__version__, "?.?.?")
@@ -32,10 +41,73 @@ class TestDabDataSync(unittest.TestCase):
datasync = dabdatasync.DataSync_Factory.get_DataSync()
self.assertIsInstance(datasync, dabdatasync.I_DataSync)
self.assertIsInstance(datasync, dabdatasync.C_DataSync_NextCloud)
pprint.pprint(datasync.ar_datasync_record)
self.assertEqual(len(datasync.ar_datasync_record), 2)
self.assertEqual(datasync.ar_datasync_record[0].name, "SOTF_map")
self.assertEqual(datasync.ar_datasync_record[1].name, "SOTF_map2")
self.assertEqual(datasync.ar_datasync_record[0].rec_type, "fs")
self.assertEqual(datasync.ar_datasync_record[1].rec_type, "fs")
self.assertEqual(datasync.ar_datasync_record[0].value, "test/test_data")
self.assertEqual(datasync.ar_datasync_record[1].value, "test/test_data2/SAVE_FILE.txt")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
datasync.write_data()
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE2")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE2")
datasync.read_data()
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "SAVED_VALUE")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE3")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE32")
datasync.write_data()
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE3")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE32")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "w", encoding="utf-8") as testfile:
testfile.write("MODIFIED_VALUE")
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE")
datasync.read_data()
with open(testdir_path / "test_data" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE3")
with open(testdir_path / "test_data2" / "SAVE_FILE.txt", "rt", encoding="utf-8") as testfile:
self.assertEqual(testfile.read(), "MODIFIED_VALUE32")
def test_load_empty(self):
dabdatasync.I_DataSync.manifest_path = testdir_path / "test_manifest_empty.json"
datasync = dabdatasync.DataSync_Factory.get_DataSync()

View File

@@ -220,6 +220,23 @@
"value": "test/test_data"
}
}
},
{
"type": "T_FSSYNC_RECORD",
"value": {
"name": {
"type": "SIMPLE_STRING",
"value": "SOTF_map2"
},
"type": {
"type": "SIMPLE_STRING",
"value": "fs"
},
"value": {
"type": "STRING",
"value": "test/test_data2/SAVE_FILE.txt"
}
}
}
]
},