@kaydash9999/banker-plugins 0.20.1 → 0.20.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +195 -1
- package/PRIVACY.md +13 -3
- package/README.md +27 -4
- package/bin/banker.js +84 -40
- package/bin/lib/telemetry-config.mjs +31 -16
- package/codex/manifest.json +1 -1
- package/codex/transform-matrix.md +1 -1
- package/commands/setup.md +23 -0
- package/hooks/progress.mjs +143 -38
- package/hooks/register.mjs +13 -3
- package/hooks/update-checkin.mjs +15 -7
- package/hooks/update-fetch.mjs +15 -9
- package/hooks/update-notify.mjs +2 -9
- package/package.json +1 -1
- package/skills/3d-intro-build/SKILL.md +11 -5
- package/skills/3d-intro-build/references/azure-adapter.mjs +374 -81
- package/skills/3d-intro-build/references/curate.mjs +48 -14
- package/skills/3d-intro-build/references/preview-lib.mjs +51 -15
- package/skills/3d-intro-build/references/prompts.md +4 -4
- package/skills/3d-intro-build/references/serve.mjs +6 -1
- package/skills/3d-intro-build/references/verify-intro.mjs +16 -9
- package/skills/3d-intro-build/references/video-pool.mjs +250 -135
- package/skills/3d-intro-setup/SKILL.md +41 -10
- package/skills/3d-intro-setup/references/azure-adapter.mjs +374 -81
- package/skills/3d-intro-setup/references/video-pool.mjs +250 -135
- package/skills/anti-drm/SKILL.md +6 -3
- package/skills/anti-drm/scripts/anti-drm.mjs +49 -12
- package/skills/anti-drm/scripts/instruction-toggle.mjs +105 -20
- package/skills/audit-mock/SKILL.md +1 -1
- package/skills/audit-security/SKILL.md +64 -2
- package/skills/deep-research/SKILL.md +5 -0
- package/skills/docs-setup/SKILL.md +37 -7
- package/skills/lineage/SKILL.md +12 -12
- package/skills/lineage/lineage.py +399 -300
- package/skills/motion-graphic-make/SKILL.md +1 -1
- package/skills/motion-graphic-make/references/curate.mjs +48 -14
- package/skills/motion-graphic-make/references/preview-lib.mjs +51 -15
- package/skills/motion-graphic-make/references/serve.mjs +6 -1
- package/skills/motion-graphic-setup/SKILL.md +58 -13
- package/skills/obsidizer/SKILL.md +1 -1
- package/skills/obsidizer/obsidize.mjs +8 -1
- package/skills/omc-patch/SKILL.md +80 -23
- package/skills/omc-patch/scripts/omc-patch.mjs +460 -116
- package/skills/payload-mon/SKILL.md +5 -2
- package/skills/payload-mon/scripts/payload-mon.mjs +137 -30
- package/skills/payload-mon/scripts/payload-size.mjs +4 -1
- package/skills/pdf-vision-extract/SKILL.md +11 -6
- package/skills/ralph-qa/SKILL.md +125 -151
- package/skills/ralph-qa/references/gemini-seat.mjs +67 -19
- package/skills/ralph-qa/references/payload-scan.mjs +22 -7
- package/skills/ralph-qa/references/seat-payload.mjs +646 -0
- package/skills/ralph-qa/references/seat-run.mjs +956 -0
- package/skills/ralph-qa/references/seat-spawn.mjs +205 -0
- package/skills/ralph-qa/references/verifier-probe.mjs +57 -16
- package/skills/setup-harness-factory/SKILL.md +17 -1
- package/skills/setup-insane-search/SKILL.md +16 -0
- package/skills/setup-java/SKILL.md +20 -1
- package/skills/setup-lsp/SKILL.md +56 -13
- package/skills/setup-mcp/SKILL.md +73 -4
- package/skills/setup-node/SKILL.md +31 -6
- package/skills/setup-omc/SKILL.md +24 -0
- package/skills/setup-omc-hud/SKILL.md +13 -5
- package/skills/setup-omc-hud/assets/apply-hud.mjs +381 -27
- package/skills/setup-omc-hud/assets/omc-hud-custom.mjs +81 -14
- package/skills/setup-omc-hud/scripts/claude-update-last.mjs +5 -3
- package/skills/setup-playwright/SKILL.md +45 -2
- package/skills/setup-pwsh/SKILL.md +19 -0
- package/skills/setup-python/SKILL.md +45 -7
- package/skills/setup-sandbox/SKILL.md +30 -5
- package/skills/setup-stitch/SKILL.md +22 -0
- package/skills/setup-tmux/SKILL.md +24 -4
- package/skills/tone-compact/SKILL.md +2 -1
- package/skills/tone-compact/scripts/instruction-toggle.mjs +105 -20
- package/skills/ultra-chain/SKILL.md +4 -3
- package/skills/ultra-chain/references/preview-lib.mjs +51 -15
- package/skills/ultra-chain/references/serve.mjs +6 -1
- package/skills/ultra-interview/SKILL.md +1 -0
- package/skills/update-banker/SKILL.md +19 -3
- package/skills/vertical-pptx/SKILL.md +6 -3
- package/skills/vertical-pptx-setup/SKILL.md +76 -20
|
@@ -36,6 +36,44 @@ for v in 3.13 3.12 3.11 3.10 3.9; do command -v python$v >/dev/null && echo "pyt
|
|
|
36
36
|
**python 버전 주의.** `python3` 이 3.6 이나 3.7 인 배포판이 있다(RHEL8/Rocky8 계열의 기본이 3.6.8 이다).
|
|
37
37
|
python-pptx 는 그보다 높은 버전을 요구하므로 `python3` 을 그대로 쓰지 말고 위 스캔에서 고른 인터프리터를 쓴다.
|
|
38
38
|
|
|
39
|
+
### 네트워크 확인 (내려받기 전)
|
|
40
|
+
|
|
41
|
+
이 스킬이 내려받는 원천에 닿는지 먼저 본다(curl 은 10초, npm 은 15초 안). 닿지 않으면 그 원천에서 받는 단계는 하지 않고, 이미 설치된 것의 확인만 한 뒤 "오프라인이라 설치하지 않음(필요한 것: <못 깐 것>)" 으로 보고한다.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
[ "${CODEX_SANDBOX_NETWORK_DISABLED:-}" = 1 ] && echo "Codex sandbox 가 네트워크를 막음(아래 실패는 오프라인이 아님)"
|
|
45
|
+
in15() { "$@" & p=$!; ( sleep 15 && kill "$p" ) > /dev/null 2>&1 & k=$!; wait "$p" 2>/dev/null; r=$?; kill "$k" 2>/dev/null; wait "$k" 2>/dev/null; [ "$r" = 143 ] && echo "15초 안에 끝나지 않아 멈춤(패킷을 버리는 망일 수 있음)"; return "$r"; }
|
|
46
|
+
in15 sh -c 'cd ~ && exec npm ping --fetch-retries=0 --fetch-timeout=10000 --no-update-notifier' # pptxgenjs
|
|
47
|
+
# pip 이 읽는 설정 전부(PIP_CONFIG_FILE 포함)를 홈 폴더에서 읽는다. install 절이 global 절보다 앞선다
|
|
48
|
+
L=$( (cd ~ && { pip config list || pip3 config list || python3.13 -m pip config list || python3.12 -m pip config list || python3.11 -m pip config list || python3 -m pip config list; }) 2>/dev/null) || echo "pip 설정을 읽지 못함(pip 이 없거나 10 미만). 사내 미러를 쓰면 확인 주소를 그 미러로 바꿔 본다"
|
|
49
|
+
I="${PIP_INDEX_URL:-$(printf '%s\n' "$L" | sed -n "s/^install\.index-url='\(.*\)'$/\1/p")}"
|
|
50
|
+
I="${I:-$(printf '%s\n' "$L" | sed -n "s/^global\.index-url='\(.*\)'$/\1/p")}"
|
|
51
|
+
I=$(printf %s "${I:-https://pypi.org/simple}" | sed -E 's#^([A-Za-z][A-Za-z0-9+.-]*://)[^/]*@#\1#; s#/$##') # 주소의 사용자 정보는 뗌
|
|
52
|
+
printf 'url = "%s"\n' "$I/pip/" | curl --ssl-no-revoke -K - -sSI -o /dev/null --connect-timeout 5 --max-time 10 # python-pptx
|
|
53
|
+
curl --ssl-no-revoke -sSI -o /dev/null --connect-timeout 5 --max-time 10 https://download.documentfoundation.org # LibreOffice
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- `npm ping` 은 홈 폴더에서 부른다. 지금 폴더에 있는 프로젝트의 `.npmrc` 가 정한 레지스트리와 토큰을 따르지 않게 하려는 것이다.
|
|
57
|
+
- `npm ping` 은 15초 감시(`in15`) 안에서 부른다. 패킷을 버리는 망에서 npm 은 연결에 시간 제한을 두지 않아(`--fetch-timeout` 은 받는 중의 쉼만 잰다) OS 의 연결 재시도가 끝날 때까지 기다린다(Rocky 8.10 실측 130초). 15초 안에 끝나지 않으면 `15초 안에 끝나지 않아 멈춤(패킷을 버리는 망일 수 있음)` 과 종료 143 이다. `--no-update-notifier` 는 npm 이 제 판을 묻는 요청을 하나 더 내지 않게 한다.
|
|
58
|
+
- `npm ping` 이 실패하면 ping 에 답하지 않는 사내 미러일 수 있다. `(cd ~ && T=$(mktemp -d) && { npm view pptxgenjs version --fetch-retries=0 --fetch-timeout=10000 --cache "$T" --no-update-notifier; r=$?; rm -rf "$T"; exit $r; })` 도 실패해야 오프라인으로 본다. 이 스킬이 설치할 패키지(`pptxgenjs`)를 빈 캐시로 물으므로 옛 값이 나올 수 없다. ping 이 15초 감시에 걸려 멈췄으면(종료 143) 이 확인은 하지 않는다. 같은 레지스트리라 같은 시간을 또 기다린다.
|
|
59
|
+
- `npm` 이 없으면(명령 없음) 오프라인이 아니라 확인하지 못한 것이다. Node 를 먼저 갖춘다(`setup-node`).
|
|
60
|
+
- `npm ping` 은 npm 의 프록시 설정(`proxy`, `https-proxy`)을 따른다. 사내 미러만 열린 망이면 그 미러가 쓰이는지 npm 설정을 본다.
|
|
61
|
+
- `curl -sSI` 는 머리만 받는다(본문을 받지 않음). 닿지 못하면 종료 코드가 0 이 아니다(HTTP 상태와 관계없음). `curl` 은 `HTTPS_PROXY` 를 따른다. 확인 줄은 `--ssl-no-revoke` 를 준다. Windows 의 Git Bash curl 도 Schannel 이라, 폐지 목록 서버에 닿지 못하는 망에서 폐지 확인이 실패하면 종료 60 이다(Windows 박스 실측). 다른 curl 은 이 깃발을 받고 무시한다(macOS curl 8.7.1, Rocky 8.10 curl 7.61.1 실측).
|
|
62
|
+
- PyPI 는 pip 이 쓰는 색인(`PIP_INDEX_URL`, `pip config list` 의 `install.index-url` 이나 `global.index-url`, 없으면 pypi.org)의 작은 쪽(`<색인>/pip/`)을 본다.
|
|
63
|
+
- `pip config get` 은 `PIP_CONFIG_FILE` 로 준 파일을 읽지 않아(pip 25.0 실측) `pip config list` 를 읽는다.
|
|
64
|
+
- Rocky 8 의 기본 pip(9.0.3, `pip3`)은 `config` 명령이 없고 `pip` 이름은 없다(Rocky 8.10 실측). 그래서 판 붙은 python(3.13, 3.12, 3.11)의 pip 도 차례로 본다.
|
|
65
|
+
- 홈 폴더에서 읽는다. `python3 -m pip` 는 지금 폴더를 import 경로 맨 앞에 두어, 지금 폴더에 있는 남의 저장소의 `pip/` 가 실행될 수 있다.
|
|
66
|
+
- bash 블록은 주소를 명령 인자가 아니라 표준 입력의 curl 설정(`-K -`)으로 넘긴다. 명령 인자는 같은 PC 의 다른 사용자가 `ps` 로 볼 수 있어, 경로나 질의에 든 토큰도 거기 싣지 않는다. 사용자 정보(`사용자:토큰@`)는 떼고 묻는다. 닿는지만 보므로 인증은 필요 없다(401 도 닿은 것이다). Windows 에서도 뗀 주소를 쓴다.
|
|
67
|
+
- Windows PowerShell 에서는 같은 주소를 `curl.exe --ssl-no-revoke -sSI -o NUL --connect-timeout 5 --max-time 10 <주소>` 로 보고 `$LASTEXITCODE` 가 0 인지 본다(PowerShell 5.1 의 `curl` 은 `Invoke-WebRequest` 별칭이다). `curl.exe` 는 Windows 시스템 프록시를 따르지 않고 `HTTPS_PROXY` 만 따른다. `--ssl-no-revoke` 는 폐지 목록 서버에 닿지 못하는 망에서 Schannel 의 폐지 확인 실패를 오프라인으로 읽지 않게 한다. 닿는지만 보고 받은 내용은 쓰지 않으므로 이 확인에만 준다. `curl.exe` 가 없으면 `$LASTEXITCODE` 에 앞 명령의 값이 남으므로 `Get-Command curl.exe -ErrorAction SilentlyContinue` 로 먼저 보고, 없으면 확인하지 못한 것으로 적는다. `npm ping` 은 `Push-Location ~; npm ping --fetch-retries=0 --fetch-timeout=10000 --no-update-notifier; Pop-Location` 처럼 홈에서 부르고 돌아온다(돌아오지 않으면 뒤 단계가 프로젝트가 아니라 홈에서 돈다). PowerShell 에는 15초 감시를 두지 않는다(Windows 의 연결 시간 제한은 약 21초로 알려져 있다. 미실측).
|
|
68
|
+
- 사내 미러만 열린 망이면 확인 주소를 그 미러로 바꿔 본다.
|
|
69
|
+
- OS 패키지 관리자(dnf, apt, brew, winget)의 단계는 자기 설정의 미러를 쓰므로 이 확인과 관계없이 시도하고, 실패하면 그 단계를 실패로 보고한다.
|
|
70
|
+
- 패킷을 버리거나 답하지 않는 망에서 dnf 는 저장소마다 약 2분(SYN 을 버리는 망 실측 121초), apt 는 원천마다 약 4분(답하지 않는 원천 실측 247초) 기다린 뒤 실패로 끝난다. 시간 제한은 관리자 설정을 따르므로 이 스킬이 바꾸지 않는다.
|
|
71
|
+
- `apt-get update` 는 받지 못해도 종료 0 이다. 출력의 `W: Failed to fetch` 가 있으면 그 단계를 실패로 보고한다.
|
|
72
|
+
- Codex sandbox 가 네트워크를 막는 모드(기본 `workspace-write`, `read-only`)에서는 `CODEX_SANDBOX_NETWORK_DISABLED=1` 이 서고 확인이 모두 실패한다(curl 종료 7, npm `EPERM`). 블록의 첫 줄이 그렇다고 알린다. 그때는 '오프라인' 이 아니라 'sandbox 가 네트워크를 막음' 으로 보고하고, 승인을 받아 sandbox 밖에서 확인부터 다시 한다. Claude Code sandbox 안(`SANDBOX_RUNTIME=1`)에서는 허용 목록 밖 주소를 sandbox 프록시가 막는다. Windows PowerShell 에서는 `$env:CODEX_SANDBOX_NETWORK_DISABLED -eq '1'` 로 본다.
|
|
73
|
+
- 확인이 실패하면 보고에 그 명령, 종료 코드, stderr 첫 줄을 붙인다(예: `npm error code ETIMEDOUT`, `curl: (28) ...`). 원인을 '오프라인' 하나로 짐작하지 않는다.
|
|
74
|
+
- curl 의 종료 60(인증서 검증 실패)도 오프라인이 아니다. 망은 열려 있고, TLS 를 가로채는 사내 프록시의 인증서를 OS 가 믿지 않는 것이다. '인증서 문제로 설치하지 않음' 으로 보고한다.
|
|
75
|
+
- curl 은 닿는데 npm 만 인증서 오류(`UNABLE_TO_VERIFY_LEAF_SIGNATURE`, `SELF_SIGNED_CERT_IN_CHAIN`, `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`)로 실패하면 망은 열려 있고 npm 이 사내 인증서를 믿지 않는 것이다(npm 은 OS 인증서 저장소를 쓰지 않는다). '인증서 문제로 설치하지 않음' 으로 보고하고 `NODE_EXTRA_CA_CERTS=<사내 CA 파일>` 을 안내한다. Node 24 는 `NODE_OPTIONS=--use-system-ca` 도 된다.
|
|
76
|
+
|
|
39
77
|
## 1. 빌더 설치 (둘 중 하나면 충분하다)
|
|
40
78
|
|
|
41
79
|
**node 경로(권장).** `fontFace` 하나로 한글 3슬롯(`a:latin`·`a:ea`·`a:cs`)이 전부 채워져 한글 깨짐 위험이 구조적으로 낮다.
|
|
@@ -53,12 +91,12 @@ node -e "require('pptxgenjs')" && echo "pptxgenjs ok"
|
|
|
53
91
|
|
|
54
92
|
```bash
|
|
55
93
|
PY=<위 스캔에서 고른 3.9+ 인터프리터>
|
|
56
|
-
$PY -m pip install --user python-pptx
|
|
57
|
-
$PY -c "import pptx; print('python-pptx', pptx.__version__)"
|
|
94
|
+
(cd ~ && $PY -m pip install --user python-pptx) # 홈에서: -c, -m, 표준 입력 스크립트는 지금 폴더의 모듈을 먼저 불러온다
|
|
95
|
+
(cd ~ && $PY -c "import pptx; print('python-pptx', pptx.__version__)")
|
|
58
96
|
```
|
|
59
97
|
|
|
60
98
|
`fonttools` 는 필수가 아니다.
|
|
61
|
-
폭 예측 정확도를 직접 대조하고 싶을 때만 넣는다(
|
|
99
|
+
폭 예측 정확도를 직접 대조하고 싶을 때만 넣는다(`(cd ~ && $PY -m pip install --user fonttools)`).
|
|
62
100
|
|
|
63
101
|
## 2. LibreOffice 설치 — OS x 권한 분기
|
|
64
102
|
|
|
@@ -91,18 +129,19 @@ oosplash: /lib64/libc.so.6: version `GLIBC_2.33' not found
|
|
|
91
129
|
배포판 빌드는 그 배포판의 glibc 에 맞춰져 있으므로 이게 정답이다. `dnf download` 는 root 가 필요 없다.
|
|
92
130
|
|
|
93
131
|
```bash
|
|
94
|
-
SP
|
|
95
|
-
mkdir -p $
|
|
132
|
+
SP=$(mktemp -d); PREFIX=$HOME/.local/lo-distro # SP: 받은 RPM 을 둘 개인 임시 폴더(끝나면 지운다)
|
|
133
|
+
mkdir -p $PREFIX
|
|
96
134
|
dnf -q -y --disablerepo='*' --enablerepo='appstream,baseos,powertools' \
|
|
97
135
|
download --resolve --alldeps --destdir=$SP libreoffice-impress libreoffice-writer
|
|
98
136
|
cd $PREFIX
|
|
99
|
-
|
|
137
|
+
find "$SP" -name '*.rpm' -type f | while read -r r; do # 글롭 없이(zsh 는 맞는 것이 없으면 멈춤)
|
|
100
138
|
rpm2cpio "$r" | cpio -idmu --quiet 2>/dev/null
|
|
101
|
-
chmod -R u+rwX $PREFIX/usr 2>/dev/null # ★ 이 줄이 없으면 중간부터 전부 실패한다
|
|
139
|
+
chmod -R u+rwX "$PREFIX/usr" 2>/dev/null # ★ 이 줄이 없으면 중간부터 전부 실패한다
|
|
102
140
|
done
|
|
103
141
|
export LD_LIBRARY_PATH=$PREFIX/usr/lib64:$PREFIX/usr/lib64/libreoffice/program:$LD_LIBRARY_PATH
|
|
104
142
|
SOFFICE=$PREFIX/usr/lib64/libreoffice/program/soffice
|
|
105
143
|
$SOFFICE --version # 6.4.7.2 처럼 배포판 버전이 찍히면 성공이다
|
|
144
|
+
cd ~; rm -rf "$SP"
|
|
106
145
|
```
|
|
107
146
|
|
|
108
147
|
★ **`LD_LIBRARY_PATH` 를 반드시 걸어라.** 추출본은 시스템 경로에 없으므로 링커가 자기 라이브러리를 못 찾는다.
|
|
@@ -118,18 +157,31 @@ $SOFFICE --version # 6.4.7.2 처럼 배포판 버전이 찍히면 성
|
|
|
118
157
|
**glibc 2.29 이상: 업스트림 tarball 도 쓸 수 있다.** 자체 라이브러리를 번들해 배포판과 안 싸운다.
|
|
119
158
|
|
|
120
159
|
```bash
|
|
121
|
-
V=$(curl -
|
|
160
|
+
V=$(curl -fsS --connect-timeout 10 --max-time 30 https://download.documentfoundation.org/libreoffice/stable/ \
|
|
122
161
|
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+/' | sort -V | tail -1 | tr -d '/')
|
|
123
162
|
A=$(uname -m) # x86_64 또는 aarch64. 업스트림이 둘 다 제공한다
|
|
124
|
-
|
|
125
|
-
|
|
163
|
+
PREFIX=$HOME/.local/lo-upstream; T=$(mktemp -d) # T: 받은 tarball 과 푼 RPM. 끝나면 지운다
|
|
164
|
+
if [ -n "$V" ] && curl -fsSL --connect-timeout 10 --speed-limit 1000 --speed-time 30 -o "$T/lo.tar.gz" \
|
|
165
|
+
"https://download.documentfoundation.org/libreoffice/stable/$V/rpm/$A/LibreOffice_${V}_Linux_${A/x86_64/x86-64}_rpm.tar.gz" \
|
|
166
|
+
&& tar -xzf "$T/lo.tar.gz" -C "$T" && mkdir -p "$PREFIX" && cd "$PREFIX"; then
|
|
167
|
+
find "$T" -path '*/RPMS/*.rpm' -type f | while read -r r; do # 글롭 없이(zsh 는 맞는 것이 없으면 멈춤)
|
|
168
|
+
rpm2cpio "$r" | cpio -idmu --quiet 2>/dev/null
|
|
169
|
+
chmod -R u+rwX "$PREFIX" 2>/dev/null # RPM 마다(위 배포판 경로와 같은 까닭)
|
|
170
|
+
done
|
|
171
|
+
cd ~; S=$(find "$PREFIX/opt" -path '*/program/soffice' -type f 2>/dev/null | head -1)
|
|
172
|
+
[ -n "$S" ] && echo "SOFFICE=$S" || echo "soffice 를 찾지 못함(tarball 의 꼴이 바뀌었을 수 있음)"
|
|
173
|
+
else
|
|
174
|
+
cd ~; echo "받지 못했거나 풀지 못함(판: ${V:-알 수 없음})"
|
|
175
|
+
fi
|
|
176
|
+
rm -rf "$T" # 성공과 실패 모두 지운다
|
|
126
177
|
```
|
|
127
178
|
|
|
128
|
-
|
|
179
|
+
블록 하나로 받기, 풀기, 추출, 정리까지 끝낸다. 업스트림 RPM 은 `opt/libreoffice<판>/` 아래에 깔린다. 찾지 못하면 그렇다고 알린다(미실측: 내려받기 없이 꼴을 확인하지 못했다).
|
|
180
|
+
판을 알 수 없으면(목록 페이지에 닿지 못함, 페이지 모양이 바뀜) 받지 않고 그렇게 보고한다.
|
|
129
181
|
deb 계열은 `rpm/` 대신 `deb/` 를 받아 `dpkg-deb -x` 로 편다.
|
|
130
182
|
`rpm2cpio` 와 `cpio` 가 없으면 이 경로는 못 쓴다. 그때는 root 를 얻거나 시각 검증을 건너뛴다.
|
|
131
183
|
|
|
132
|
-
다운로드가 250~320MB 다. 느린 회선에서는 백그라운드로 돌린다.
|
|
184
|
+
다운로드가 250~320MB 다. 느린 회선에서는 백그라운드로 돌린다. 총 시간 제한 대신 정체 감지(`--speed-limit 1000 --speed-time 30`: 30초 동안 초당 1000바이트 미만이면 끊음)를 쓰므로 느려도 받는 중이면 끊지 않는다.
|
|
133
185
|
|
|
134
186
|
### 2-c. macOS
|
|
135
187
|
|
|
@@ -141,10 +193,13 @@ brew 가 없으면 업스트림 dmg 를 받는다. 아키텍처 이름이 `aarch
|
|
|
141
193
|
|
|
142
194
|
```bash
|
|
143
195
|
V=<위와 동일하게 조회>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
196
|
+
T=$(mktemp -d)
|
|
197
|
+
if [ -n "$V" ] && curl -fsSL --connect-timeout 10 --speed-limit 1000 --speed-time 30 -o "$T/lo.dmg" "https://download.documentfoundation.org/libreoffice/stable/$V/mac/aarch64/LibreOffice_${V}_MacOS_aarch64.dmg"; then
|
|
198
|
+
hdiutil attach "$T/lo.dmg" -nobrowse -quiet
|
|
199
|
+
cp -R "/Volumes/LibreOffice/LibreOffice.app" /Applications/ # root 또는 쓰기 권한 필요
|
|
200
|
+
hdiutil detach "/Volumes/LibreOffice" -quiet
|
|
201
|
+
fi
|
|
202
|
+
rm -rf "$T"
|
|
148
203
|
/Applications/LibreOffice.app/Contents/MacOS/soffice --version
|
|
149
204
|
```
|
|
150
205
|
|
|
@@ -171,7 +226,7 @@ $SOFFICE --headless --convert-to pdf --outdir <출력디렉터리> <입력.pptx>
|
|
|
171
226
|
**렌더 결과의 페이지 크기를 반드시 재라.** 변환이 성공했다는 것과 A4 로 나왔다는 것은 다른 말이다.
|
|
172
227
|
|
|
173
228
|
```bash
|
|
174
|
-
python -c "
|
|
229
|
+
(cd ~ && python -c "
|
|
175
230
|
import re,zlib,sys
|
|
176
231
|
d=open(sys.argv[1],'rb').read()
|
|
177
232
|
m=re.search(rb'/MediaBox\s*\[\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)', d)
|
|
@@ -179,14 +234,15 @@ if m:
|
|
|
179
234
|
w=float(m.group(3))-float(m.group(1)); h=float(m.group(4))-float(m.group(2))
|
|
180
235
|
print('MediaBox %.1f x %.1f pt = %.1f x %.1f mm' % (w,h,w*25.4/72,h*25.4/72))
|
|
181
236
|
print('A4 세로 판정:', abs(w*25.4/72-210)<1 and abs(h*25.4/72-297)<1)
|
|
182
|
-
" <출력.pdf
|
|
237
|
+
" <출력.pdf 의 절대 경로>)
|
|
183
238
|
```
|
|
184
239
|
|
|
185
240
|
A4 세로는 **210 x 297 mm = 595 x 842 pt** 다.
|
|
186
241
|
1mm 안쪽이면 통과로 본다(PDF 포인트 반올림 때문이다).
|
|
187
242
|
|
|
188
243
|
`soffice` 가 이미 떠 있으면 두 번째 호출이 조용히 아무것도 안 하고 끝날 수 있다.
|
|
189
|
-
자동화에서는 프로파일을 분리한다: `-env:UserInstallation=file
|
|
244
|
+
자동화에서는 프로파일을 분리한다: `P=$(mktemp -d)` 로 만든 개인 폴더를 `-env:UserInstallation=file://$P` 로 주고, 끝나면 `rm -rf "$P"` 로 지운다.
|
|
245
|
+
`/tmp/lo-profile-$$` 처럼 짐작할 수 있는 이름은 쓰지 않는다. 다른 사용자가 먼저 만들어 둔 프로파일(매크로 설정 포함)로 `soffice` 가 돌 수 있다.
|
|
190
246
|
|
|
191
247
|
## 4. 검증 (보고 의무)
|
|
192
248
|
|
|
@@ -195,7 +251,7 @@ A4 세로는 **210 x 297 mm = 595 x 842 pt** 다.
|
|
|
195
251
|
```bash
|
|
196
252
|
node -v # 검증기 전제
|
|
197
253
|
node -e "require('pptxgenjs')" && echo builder-node-ok
|
|
198
|
-
$PY -c "import pptx" && echo builder-python-ok # 둘 중 하나면 충분
|
|
254
|
+
(cd ~ && $PY -c "import pptx") && echo builder-python-ok # 둘 중 하나면 충분
|
|
199
255
|
$SOFFICE --version # 선택
|
|
200
256
|
```
|
|
201
257
|
|