-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGimpGtpToolPreset.py
More file actions
162 lines (129 loc) · 4.25 KB
/
GimpGtpToolPreset.py
File metadata and controls
162 lines (129 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""Pure python implementation of the gimp gtp tool preset format."""
from __future__ import annotations
from io import BytesIO
import brackettree
from gimpformats import utils
class ParenFileValue:
"""A parentheses-based file format.
(possibly "scheme" language?)
"""
def __init__(self, name: str | None = None, value: str = "", children=None) -> None:
"""Parenthesis based file.
Args:
----
name (str, optional): name of the file. Defaults to None.
value (str, optional): some value, str(float) or str. Defaults to "".
children ([type], optional): children. Defaults to None.
"""
self.name = name
try:
float(value)
self.value = value
except ValueError:
self.value = '"' + value + '"'
if value in ("yes", "no"):
self.value = value
self.children = children
def __str__(self) -> str:
"""Get a textual representation of this object."""
return self.__repr__()
def __repr__(self) -> str:
"""Get a textual representation of this object."""
repr_str = f"<ParenFileValue name={self.name!r}, value={self.value!r}"
if self.children is not None:
repr_str += f", numChildren={len(self.children)}"
repr_str += ">"
return repr_str
def full_repr(self) -> str:
"""Get a textual representation of this object."""
ret = []
ret.append(f"({self.name}")
ret.append(f" {self.value}")
if self.children is None:
ret.append(")")
ret.append("\n")
if self.children is not None:
for index, child in enumerate(self.children):
ret.append(f" ({child.name}")
ret.append(" " + child.value + ")")
if index == len(self.children) - 1:
ret.append(")")
ret.append("\n")
return "".join(ret)
def parenFileDecode(data: bytearray | bytes) -> list[ParenFileValue]:
"""Decode a parentheses-based file format.
(possibly "scheme" language?)
"""
nodes = brackettree.Node(data.decode("utf-8"))
return walkTree(nodes.items)
def walkTree(items: list[brackettree.RoundNode]) -> list[ParenFileValue]:
"""Walk the tree."""
values = []
for item in items:
if isinstance(item, brackettree.RoundNode):
if len(item.items) == 1:
values.append(
ParenFileValue(
item.items[0].split(" ")[0].strip(), item.items[0].split(" ")[1].strip()
)
)
if len(item.items) == 2:
values.append(ParenFileValue(item.items[0].strip(), item.items[1].items[0].strip()))
elif len(item.items) > 2:
values.append(
ParenFileValue(
item.items[0].strip(),
item.items[1].items[0].strip(),
walkTree(item.items[2:]),
)
)
return values
def parenFileEncode(values: list[ParenFileValue]) -> str:
"""Encode a values tree to a buffer."""
ret = []
ret.append("# GIMP tool preset file\n\n")
ret.append("")
for val in values:
if val.name is not None:
ret.append(val.full_repr())
ret.append("")
ret.append("\n# end of GIMP tool preset file\n")
ret.append("")
return "".join(ret)
class GimpGtpToolPreset:
"""Pure python implementation of the gimp gtp tool preset format."""
def __init__(self, fileName: BytesIO | str | None = None) -> None:
"""Pure python implementation of the gimp gtp tool preset format."""
self.fileName = None
self.values = []
if fileName is not None:
self.load(fileName)
def load(self, fileName: BytesIO | str) -> None:
"""Load a gimp file.
:param fileName: can be a file name or a file-like object
"""
self.fileName, data = utils.fileOpen(fileName)
self.decode(data)
def decode(self, data: bytearray | bytes, index: int = 0) -> int:
"""Decode a byte buffer.
:param data: data buffer to decode
:param index: ignored
"""
self.values = parenFileDecode(data)
return index
def encode(self) -> bytes:
"""Encode to bytearray."""
return parenFileEncode(self.values).encode("utf-8")
def save(self, tofileName: str | BytesIO) -> None:
"""Save this gimp image to a file."""
utils.save(self.encode(), tofileName)
def __str__(self) -> str:
"""Get a textual representation of this object."""
return self.__repr__()
def __repr__(self) -> str:
"""Get a textual representation of this object."""
return f"<GimpGtpToolPreset numValues={len(self.values)}>"
def full_repr(self, indent: int = 0) -> str:
"""Get a textual representation of this object."""
ret = [value.full_repr() for value in self.values]
return utils.repr_indent_lines(indent, ret)