split filepointer in to text and binary variants
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
from grung.types import (
|
||||
BackReference,
|
||||
BinaryFilePointer,
|
||||
Collection,
|
||||
DateTime,
|
||||
Dict,
|
||||
Field,
|
||||
FilePointer,
|
||||
Integer,
|
||||
List,
|
||||
Password,
|
||||
Record,
|
||||
RecordDict,
|
||||
TextFilePointer,
|
||||
Timestamp,
|
||||
)
|
||||
|
||||
@@ -50,7 +51,8 @@ class Album(Record):
|
||||
Dict("credits"),
|
||||
List("tracks"),
|
||||
BackReference("artist", Artist),
|
||||
FilePointer("cover", extension=".jpg"),
|
||||
BinaryFilePointer("cover", extension=".jpg"),
|
||||
TextFilePointer("review"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
+36
-7
@@ -283,14 +283,14 @@ class BackReference(Pointer):
|
||||
|
||||
|
||||
@dataclass
|
||||
class FilePointer(Field):
|
||||
class BinaryFilePointer(Field):
|
||||
"""
|
||||
Write the contents of this field to disk and store the path in the db.
|
||||
"""
|
||||
|
||||
name: str
|
||||
value_type: type = bytes
|
||||
extension: str = ".txt"
|
||||
extension: str = ".blob"
|
||||
|
||||
def relpath(self, record):
|
||||
return Path(record._metadata.table) / record[record._metadata.primary_key] / f"{self.name}{self.extension}"
|
||||
@@ -298,16 +298,45 @@ class FilePointer(Field):
|
||||
def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type:
|
||||
if not value:
|
||||
return None
|
||||
return (db.path / str(value)).read_bytes()
|
||||
_, relpath = value.split("::")
|
||||
return self.value_type((db.path / relpath).read_bytes())
|
||||
|
||||
def prepare(self, data: value_type):
|
||||
if not data:
|
||||
return
|
||||
if not isinstance(data, self.value_type):
|
||||
return data.encode()
|
||||
return data
|
||||
|
||||
def before_insert(self, value: value_type, db: TinyDB, record: Record) -> None:
|
||||
if not value:
|
||||
return
|
||||
relpath = self.relpath(record)
|
||||
path = db.path / relpath
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(
|
||||
record[self.name] if isinstance(record[self.name], FilePointer.value_type) else record[self.name].encode()
|
||||
)
|
||||
record[self.name] = str(relpath)
|
||||
path.write_bytes(self.prepare(value))
|
||||
record[self.name] = f"File::{self.relpath(record)}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class TextFilePointer(BinaryFilePointer):
|
||||
"""
|
||||
Write the contents of this field to disk and store the path in the db.
|
||||
"""
|
||||
|
||||
name: str
|
||||
value_type: type = str
|
||||
extension: str = ".txt"
|
||||
|
||||
def prepare(self, data: value_type):
|
||||
if data:
|
||||
return str(data).encode()
|
||||
|
||||
def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type:
|
||||
if not value:
|
||||
return None
|
||||
_, relpath = value.split("::")
|
||||
return (db.path / relpath).read_text()
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user