feat: add psagentai agent with deployment and configuration
Initial project setup including the main agent script, configuration files, profile JSON state, systemd service unit, startup script, deployment documentation, and Python dependencies. Includes .env, venv/, and __pycache__/ which should likely be excluded via .gitignore to avoid committing secrets and artifacts.
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
#
|
||||
# THIS IS WORK IN PROGRESS
|
||||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# portable compiled font file parser
|
||||
#
|
||||
# history:
|
||||
# 1997-08-19 fl created
|
||||
# 2003-09-13 fl fixed loading of unicode fonts
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1997-2003 by Fredrik Lundh.
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
|
||||
from . import FontFile, Image
|
||||
from ._binary import i8
|
||||
from ._binary import i16be as b16
|
||||
from ._binary import i16le as l16
|
||||
from ._binary import i32be as b32
|
||||
from ._binary import i32le as l32
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
from typing import BinaryIO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# declarations
|
||||
|
||||
PCF_MAGIC = 0x70636601 # "\x01fcp"
|
||||
|
||||
PCF_PROPERTIES = 1 << 0
|
||||
PCF_ACCELERATORS = 1 << 1
|
||||
PCF_METRICS = 1 << 2
|
||||
PCF_BITMAPS = 1 << 3
|
||||
PCF_INK_METRICS = 1 << 4
|
||||
PCF_BDF_ENCODINGS = 1 << 5
|
||||
PCF_SWIDTHS = 1 << 6
|
||||
PCF_GLYPH_NAMES = 1 << 7
|
||||
PCF_BDF_ACCELERATORS = 1 << 8
|
||||
|
||||
BYTES_PER_ROW: list[Callable[[int], int]] = [
|
||||
lambda bits: ((bits + 7) >> 3),
|
||||
lambda bits: ((bits + 15) >> 3) & ~1,
|
||||
lambda bits: ((bits + 31) >> 3) & ~3,
|
||||
lambda bits: ((bits + 63) >> 3) & ~7,
|
||||
]
|
||||
|
||||
|
||||
def sz(s: bytes, o: int) -> bytes:
|
||||
return s[o : s.index(b"\0", o)]
|
||||
|
||||
|
||||
class PcfFontFile(FontFile.FontFile):
|
||||
"""Font file plugin for the X11 PCF format."""
|
||||
|
||||
name = "name"
|
||||
|
||||
def __init__(self, fp: BinaryIO, charset_encoding: str = "iso8859-1"):
|
||||
self.charset_encoding = charset_encoding
|
||||
|
||||
magic = l32(fp.read(4))
|
||||
if magic != PCF_MAGIC:
|
||||
msg = "not a PCF file"
|
||||
raise SyntaxError(msg)
|
||||
|
||||
super().__init__()
|
||||
|
||||
count = l32(fp.read(4))
|
||||
self.toc = {}
|
||||
for i in range(count):
|
||||
type = l32(fp.read(4))
|
||||
self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4))
|
||||
|
||||
self.fp = fp
|
||||
|
||||
self.info = self._load_properties()
|
||||
|
||||
metrics = self._load_metrics()
|
||||
bitmaps = self._load_bitmaps(metrics)
|
||||
encoding = self._load_encoding()
|
||||
|
||||
#
|
||||
# create glyph structure
|
||||
|
||||
for ch, ix in enumerate(encoding):
|
||||
if ix is not None:
|
||||
(
|
||||
xsize,
|
||||
ysize,
|
||||
left,
|
||||
right,
|
||||
width,
|
||||
ascent,
|
||||
descent,
|
||||
attributes,
|
||||
) = metrics[ix]
|
||||
self.glyph[ch] = (
|
||||
(width, 0),
|
||||
(left, descent - ysize, xsize + left, descent),
|
||||
(0, 0, xsize, ysize),
|
||||
bitmaps[ix],
|
||||
)
|
||||
|
||||
def _getformat(
|
||||
self, tag: int
|
||||
) -> tuple[BinaryIO, int, Callable[[bytes], int], Callable[[bytes], int]]:
|
||||
format, size, offset = self.toc[tag]
|
||||
|
||||
fp = self.fp
|
||||
fp.seek(offset)
|
||||
|
||||
format = l32(fp.read(4))
|
||||
|
||||
if format & 4:
|
||||
i16, i32 = b16, b32
|
||||
else:
|
||||
i16, i32 = l16, l32
|
||||
|
||||
return fp, format, i16, i32
|
||||
|
||||
def _load_properties(self) -> dict[bytes, bytes | int]:
|
||||
#
|
||||
# font properties
|
||||
|
||||
properties = {}
|
||||
|
||||
fp, format, i16, i32 = self._getformat(PCF_PROPERTIES)
|
||||
|
||||
nprops = i32(fp.read(4))
|
||||
|
||||
# read property description
|
||||
p = [(i32(fp.read(4)), i8(fp.read(1)), i32(fp.read(4))) for _ in range(nprops)]
|
||||
|
||||
if nprops & 3:
|
||||
fp.seek(4 - (nprops & 3), io.SEEK_CUR) # pad
|
||||
|
||||
data = fp.read(i32(fp.read(4)))
|
||||
|
||||
for k, s, v in p:
|
||||
property_value: bytes | int = sz(data, v) if s else v
|
||||
properties[sz(data, k)] = property_value
|
||||
|
||||
return properties
|
||||
|
||||
def _load_metrics(self) -> list[tuple[int, int, int, int, int, int, int, int]]:
|
||||
#
|
||||
# font metrics
|
||||
|
||||
metrics: list[tuple[int, int, int, int, int, int, int, int]] = []
|
||||
|
||||
fp, format, i16, i32 = self._getformat(PCF_METRICS)
|
||||
|
||||
append = metrics.append
|
||||
|
||||
if (format & 0xFF00) == 0x100:
|
||||
# "compressed" metrics
|
||||
for i in range(i16(fp.read(2))):
|
||||
left = i8(fp.read(1)) - 128
|
||||
right = i8(fp.read(1)) - 128
|
||||
width = i8(fp.read(1)) - 128
|
||||
ascent = i8(fp.read(1)) - 128
|
||||
descent = i8(fp.read(1)) - 128
|
||||
xsize = right - left
|
||||
ysize = ascent + descent
|
||||
append((xsize, ysize, left, right, width, ascent, descent, 0))
|
||||
|
||||
else:
|
||||
# "jumbo" metrics
|
||||
for i in range(i32(fp.read(4))):
|
||||
left = i16(fp.read(2))
|
||||
right = i16(fp.read(2))
|
||||
width = i16(fp.read(2))
|
||||
ascent = i16(fp.read(2))
|
||||
descent = i16(fp.read(2))
|
||||
attributes = i16(fp.read(2))
|
||||
xsize = right - left
|
||||
ysize = ascent + descent
|
||||
append((xsize, ysize, left, right, width, ascent, descent, attributes))
|
||||
|
||||
return metrics
|
||||
|
||||
def _load_bitmaps(
|
||||
self, metrics: list[tuple[int, int, int, int, int, int, int, int]]
|
||||
) -> list[Image.Image]:
|
||||
#
|
||||
# bitmap data
|
||||
|
||||
fp, format, i16, i32 = self._getformat(PCF_BITMAPS)
|
||||
|
||||
nbitmaps = i32(fp.read(4))
|
||||
|
||||
if nbitmaps != len(metrics):
|
||||
msg = "Wrong number of bitmaps"
|
||||
raise OSError(msg)
|
||||
|
||||
offsets = [i32(fp.read(4)) for _ in range(nbitmaps)]
|
||||
|
||||
bitmap_sizes = [i32(fp.read(4)) for _ in range(4)]
|
||||
|
||||
# byteorder = format & 4 # non-zero => MSB
|
||||
bitorder = format & 8 # non-zero => MSB
|
||||
padindex = format & 3
|
||||
|
||||
bitmapsize = bitmap_sizes[padindex]
|
||||
offsets.append(bitmapsize)
|
||||
|
||||
data = fp.read(bitmapsize)
|
||||
|
||||
pad = BYTES_PER_ROW[padindex]
|
||||
mode = "1;R"
|
||||
if bitorder:
|
||||
mode = "1"
|
||||
|
||||
bitmaps = []
|
||||
for i in range(nbitmaps):
|
||||
xsize, ysize = metrics[i][:2]
|
||||
b, e = offsets[i : i + 2]
|
||||
bitmaps.append(
|
||||
Image.frombytes("1", (xsize, ysize), data[b:e], "raw", mode, pad(xsize))
|
||||
)
|
||||
|
||||
return bitmaps
|
||||
|
||||
def _load_encoding(self) -> list[int | None]:
|
||||
fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS)
|
||||
|
||||
first_col, last_col = i16(fp.read(2)), i16(fp.read(2))
|
||||
first_row, last_row = i16(fp.read(2)), i16(fp.read(2))
|
||||
|
||||
i16(fp.read(2)) # default
|
||||
|
||||
nencoding = (last_col - first_col + 1) * (last_row - first_row + 1)
|
||||
|
||||
# map character code to bitmap index
|
||||
encoding: list[int | None] = [None] * min(256, nencoding)
|
||||
|
||||
encoding_offsets = [i16(fp.read(2)) for _ in range(nencoding)]
|
||||
|
||||
for i in range(first_col, len(encoding)):
|
||||
try:
|
||||
encoding_offset = encoding_offsets[
|
||||
ord(bytearray([i]).decode(self.charset_encoding))
|
||||
]
|
||||
if encoding_offset != 0xFFFF:
|
||||
encoding[i] = encoding_offset
|
||||
except UnicodeDecodeError: # noqa: PERF203
|
||||
# character is not supported in selected encoding
|
||||
pass
|
||||
|
||||
return encoding
|
||||
Reference in New Issue
Block a user