forked from retoor/devplacepy
- Add `agents/reports/` to `.gitignore` to prevent generated agent report files from being tracked - Implement `_TimestampStream` class and `install_timestamps()` function in `agents/agent.py` for prefixing stdout/stderr with timestamps and elapsed time - Export `install_timestamps`, `set_write_budget`, `clear_write_budget`, and `set_shell_restricted` from `agents/base.py`; add `_RUN_LOCK`, `AGENT_ICONS` dictionary, and `WRITE_BUDGET = 20` constant - Add `report_codename()` function and `CODENAME_ADJECTIVES`/`CODENAME_ANIMALS` tuples to `agents/core/__init__.py` for generating random agent report codenames - Expand `WRITE_TOOLS` tuple in `agents/core/__init__.py` to include `replace_lines`, `insert_lines`, and `delete_lines`; remove `SWARM_TOOLS` from `payloads_for` exclusion list - Update `CLAUDE.md` and `AGENTS.md` documentation with dataset column initialization rules and new agent infrastructure details - Reorder route table in `README.md` to list `/uploads` before `/messages` and document Swagger/ReDoc/OpenAPI schema endpoints
70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
|
|
import json
|
|
import shutil
|
|
import sys
|
|
import zipfile
|
|
import zlib
|
|
from pathlib import Path
|
|
|
|
FIXED_DATE = (1980, 1, 1, 0, 0, 0)
|
|
|
|
CHUNK_SIZE = 1024 * 1024
|
|
|
|
|
|
def _build(source_dir: str, output_path: str) -> dict:
|
|
bytes_in = 0
|
|
file_count = 0
|
|
dir_count = 0
|
|
source_path = Path(source_dir)
|
|
output_path_obj = Path(output_path)
|
|
with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as archive:
|
|
for root, dirs, files in Path(source_dir).walk():
|
|
dirs.sort()
|
|
for name in dirs:
|
|
dir_count += 1
|
|
arcname = str((root / name).relative_to(source_path)) + "/"
|
|
info = zipfile.ZipInfo(arcname, date_time=FIXED_DATE)
|
|
info.external_attr = (0o040755 << 16) | 0x10
|
|
archive.writestr(info, b"")
|
|
for name in sorted(files):
|
|
full = root / name
|
|
arcname = str(full.relative_to(source_path))
|
|
bytes_in += full.stat().st_size
|
|
info = zipfile.ZipInfo(arcname, date_time=FIXED_DATE)
|
|
info.compress_type = zipfile.ZIP_DEFLATED
|
|
info.external_attr = 0o644 << 16
|
|
with full.open("rb") as source, archive.open(info, "w") as target:
|
|
shutil.copyfileobj(source, target)
|
|
file_count += 1
|
|
|
|
crc = 0
|
|
with open(output_path, "rb") as handle:
|
|
for chunk in iter(lambda: handle.read(CHUNK_SIZE), b""):
|
|
crc = zlib.crc32(chunk, crc)
|
|
|
|
return {
|
|
"bytes_in": bytes_in,
|
|
"bytes_out": output_path_obj.stat().st_size,
|
|
"file_count": file_count,
|
|
"dir_count": dir_count,
|
|
"crc32": crc & 0xFFFFFFFF,
|
|
}
|
|
|
|
|
|
def main(argv: list) -> int:
|
|
if len(argv) != 3:
|
|
sys.stderr.write("usage: zip_worker <source_dir> <output_zip>\n")
|
|
return 2
|
|
source_dir, output_path = argv[1], argv[2]
|
|
if not Path(source_dir).is_dir():
|
|
sys.stderr.write(f"source directory not found: {source_dir}\n")
|
|
return 3
|
|
stats = _build(source_dir, output_path)
|
|
sys.stdout.write(json.dumps(stats))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main(sys.argv))
|