Selfie
Loading...
Searching...
No Matches
SnapshotFile.py
Go to the documentation of this file.
1import base64
2from threading import Lock
3from typing import Optional
4
5from .ArrayMap import ArrayMap
6from .Snapshot import Snapshot, SnapshotValue
7from .SnapshotReader import SnapshotReader
8from .SnapshotValueReader import SnapshotValueReader
9
10
12 HEADER_PREFIX: str = "šŸ“· "
13 END_OF_FILE: str = "[end of file]"
14
15 def __init__(self):
16 self.unix_newlines: bool = True
17 self.metadata: Optional[tuple[str, str]] = None
18 self.snapshots: ArrayMap[str, Snapshot] = ArrayMap.empty()
19 self._lock: Lock = Lock()
20 self.was_set_at_test_time: bool = False
21
22 def serialize(self, valueWriter: list[str]):
23 if self.metadata is not None:
24 self.writeEntry(
25 valueWriter,
26 f"šŸ“· {self.metadata[0]}",
27 None,
28 SnapshotValue.of(self.metadata[1]),
29 )
30
31 for entry_key, entry_value in self.snapshots.items():
32 self.writeEntry(valueWriter, entry_key, None, entry_value.subject)
33 for facet_key, facet_value in entry_value.facets.items():
34 self.writeEntry(valueWriter, entry_key, facet_key, facet_value)
35
36 self.writeEntry(valueWriter, "", "end of file", SnapshotValue.of(""))
37
38 @staticmethod
40 valueWriter: list[str], key: str, facet: Optional[str], value: SnapshotValue
41 ):
42 valueWriter.append("ā•”ā• ")
43 valueWriter.append(SnapshotValueReader.name_esc.escape(key))
44 if facet is not None:
45 valueWriter.append("[")
46 valueWriter.append(SnapshotValueReader.name_esc.escape(facet))
47 valueWriter.append("]")
48 valueWriter.append(" ā•ā•—")
49 if value.is_binary:
50 valueWriter.append(" base64 length ")
51 valueWriter.append(str(len(value.value_binary())))
52 valueWriter.append(" bytes")
53 valueWriter.append("\n")
54
55 if not key and facet == "end of file":
56 return
57
58 if value.is_binary:
59 escaped = base64.b64encode(value.value_binary()).decode("utf-8")
60 valueWriter.append(escaped.replace("\r", ""))
61 else:
62 escaped = SnapshotValueReader.body_esc.escape(value.value_string()).replace(
63 "\nā•”", "\n\ud801\udf41"
64 )
65 valueWriter.append(escaped)
66 valueWriter.append("\n")
67
68 def set_at_test_time(self, key: str, snapshot: Snapshot) -> None:
69 with self._lock:
70 self.snapshots = self.snapshots.plus_or_noop_or_replace(key, snapshot)
72
73 def remove_all_indices(self, indices: list[int]) -> None:
74 with self._lock:
75 if not indices:
76 return
77 self.snapshots = self.snapshots.minus_sorted_indices(indices)
78 self.was_set_at_test_time = True
79
80 @classmethod
81 def parse(cls, value_reader: SnapshotValueReader) -> "SnapshotFile":
82 result = cls()
83 result.unix_newlines = value_reader.unix_newlines
84 reader = SnapshotReader(value_reader)
85
86 peek_key = reader.peek_key()
87 if peek_key and peek_key.startswith(cls.HEADER_PREFIXHEADER_PREFIX):
88 metadata_name = peek_key[len(cls.HEADER_PREFIXHEADER_PREFIX) :]
89 metadata_value = value_reader.next_value().value_string()
90 result.metadata = (metadata_name, metadata_value)
91 reader.next_snapshot()
92
93 while True:
94 peek_key = reader.peek_key()
95 if peek_key is None or peek_key == cls.END_OF_FILE:
96 break
97 if peek_key.startswith(cls.HEADER_PREFIXHEADER_PREFIX):
98 continue
99 next_snapshot = reader.next_snapshot()
100 result.snapshots = result.snapshots.plus(peek_key, next_snapshot)
101
102 return result
103
104 @classmethod
105 def create_empty_with_unix_newlines(cls, unix_newlines: bool) -> "SnapshotFile":
106 result = cls()
107 result.unix_newlines = unix_newlines
108 return result
serialize(self, list[str] valueWriter)
None set_at_test_time(self, str key, Snapshot snapshot)
"SnapshotFile" parse(cls, SnapshotValueReader value_reader)
None remove_all_indices(self, list[int] indices)
writeEntry(list[str] valueWriter, str key, Optional[str] facet, SnapshotValue value)
"SnapshotFile" create_empty_with_unix_newlines(cls, bool unix_newlines)