ai/at
1
0

Compare commits

...

4 Commits

Author SHA1 Message Date
ded3110fce update scpt 2025-06-01 01:06:24 +09:00
6f4712e461 add lex 2025-05-27 01:21:35 +09:00
bd3299154c add item 2025-05-12 02:33:03 +09:00
8b97cbfd9b add ozone 2025-05-06 18:53:56 +09:00
51 changed files with 798 additions and 91 deletions

38
.github/workflows/generate-record.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Generate Record JSON
on:
workflow_dispatch: # 手動トリガー
push:
paths:
- scpt/generate_record.py # スクリプトに変更があったとき
schedule:
- cron: '0 3 * * *' # 毎日03:00 UTCに自動生成任意
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Dependencies
run: |
pip install -r requirements.txt || true # 必要なら
- name: Run Record Generator Script
run: |
python scpt/generate_record.py
- name: Commit and Push Generated JSON
run: |
git config --global user.name "GitHub Actions Bot"
git config --global user.email "actions@github.com"
git add record.json
git commit -m "🧬 Auto-generate record.json" || echo "No changes to commit"
git push origin main

View File

@ -67,41 +67,6 @@ services:
database:
condition: service_healthy
# ozone:
# ports:
# - 2585:3000
# build:
# context: ./repos/atproto/
# dockerfile: services/ozone/Dockerfile
# restart: always
# command: node --enable-source-maps api.js
# volumes:
# - ./data/ozone/:/data/
# - ./repos/ozone.js:/app/services/ozone/api.js:ro
# env_file:
# - ./envs/ozone
# healthcheck:
# test: "wget -q --spider http://localhost:3000/xrpc/_health"
# interval: 5s
# retries: 20
# depends_on:
# database:
# condition: service_healthy
#
# ozone-daemon:
# build:
# context: ./repos/atproto/
# dockerfile: services/ozone/Dockerfile
# restart: always
# command: node --enable-source-maps daemon.js
# env_file:
# - ./envs/ozone
# depends_on:
# ozone:
# condition: service_healthy
# database:
# condition: service_healthy
social-app:
ports:
- 8100:8100
@ -131,3 +96,53 @@ services:
condition: service_healthy
redis:
condition: service_healthy
jetstream:
build:
context: ./repos/jetstream/
dockerfile: Dockerfile
ports:
- 6008:6008
volumes:
- ./data/jetstream:/data
restart: always
env_file:
- ./envs/jetstream
ozone-web:
build:
context: ./repos/ozone/
ports:
- 2586:3000
restart: always
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
depends_on:
database:
condition: service_healthy
ozone:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
ports:
- 2585:3000
restart: always
command: node --enable-source-maps api.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
ozone-daemon:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
restart: always
command: node --enable-source-maps daemon.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone

5
envs/jetstream Normal file
View File

@ -0,0 +1,5 @@
JETSTREAM_WS_URL=wss://bgs.${host}/xrpc/com.atproto.sync.subscribeRepos
JETSTREAM_DATA_DIR=/data
JETSTREAM_LISTEN_ADDR=:6008
JETSTREAM_METRICS_LISTEN_ADDR=:6009
JETSTREAM_LIVENESS_TTL=96h

View File

@ -19,3 +19,9 @@ OZONE_DB_MIGRATE=1
OZONE_ADMIN_PASSWORD
OZONE_SIGNING_KEY_HEX
OZONE_BLOB_DIVERT_ADMIN_PASSWORD
OZONE_VERIFIER_URL
OZONE_VERIFIER_DID
OZONE_VERIFIER_PASSWORD
OZONE_VERIFIER_ISSUERS_TO_INDEX
OZONE_VERIFIER_JETSTREAM_URL

View File

@ -1,7 +1,7 @@
#!/bin/zsh
# ./install.zsh $HOST
repos_v='{}'
function at-repos-env() {
host=$1
if [ -z "$1" ];then
@ -15,6 +15,8 @@ function at-repos-env() {
https://github.com/bluesky-social/atproto
https://github.com/bluesky-social/social-app
https://github.com/bluesky-social/feed-generator
https://github.com/bluesky-social/ozone
https://github.com/bluesky-social/jetstream
)
d=${0:a:h}
dh=${0:a:h:h}
@ -55,6 +57,7 @@ function at-repos-clone() {
echo $repo
if [ ! -d $d/repos/${repo##*/} ];then
git clone $repo
fi
done
if [ ! -f $d/repos/feed-generator/Dockerfile ] && [ -f $d/docker/feed/Dockerfile ];then
@ -74,6 +77,12 @@ function at-repos-pull() {
at-repos-clone
fi
fi
rv=$(echo "$repos_v" | jq -r ".[\"${repo##*/}\"]")
if [ "$rv" != "null" ];then
cd $d/repos/${repo##*/}
git reset --hard $rv
cd ..
fi
done
cd $d
}
@ -91,12 +100,12 @@ function at-repos-social-app-icon-origin() {
}
function at-repos-social-app-write() {
did_admin=did:plc:z72i7hdynmk6r22z27h6tvur
did_admin=did:plc:6qyecktefllvenje24fcxnie
dt=$d/repos/social-app/src
cd $dt
grep -R bsky.social .|cut -d : -f 1|sort -u|xargs sed -i "s/bsky.social/${host}/g"
grep -R bsky.app .|cut -d : -f 1|sort -u|xargs sed -i "s/bsky.app/web.${host}/g"
grep -R syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/syu.is/${host}/g"
grep -R web.syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/web.syu.is/web.${host}/g"
f=$dt/lib/constants.ts
sed -i "s/public.api.web/bsky/g" $f
f=$dt/view/icons/Logotype.tsx
@ -105,11 +114,11 @@ function at-repos-social-app-write() {
f=$dt/view/com/util/UserAvatar.tsx
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/view/com/util/UserAvatar.tsx -o $f
sed -i "s#/img/avatar/plain/#https://cdn.bsky.app/img/avatar/plain/#g" $f
sed -i "s#/img/avatar/plain/#https://cdn.web.syu.is/img/avatar/plain/#g" $f
sed -i "s#/img/avatar_thumbnail/plain/#https://bsky.${host}/img/avatar/plain/#g" $f
sed -i "s#source={{uri: avatar}}#source={{ uri: hackModifyThumbnailPath(avatar, 1 > 0), }}#g" $f
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/lib/strings/url-helpers.ts -o $dt/lib/strings/url-helpers.ts
sed -i "s#https://go.bsky.app/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts
sed -i "s#https://go.web.syu.is/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts
grep -R $did_admin .|cut -d : -f 1|sort -u|xargs sed -i "s/${did_admin}/${did}/g"
}
@ -122,7 +131,7 @@ function at-repos-bsky-patch() {
if [ ! -f ${p_} ];then
# https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff
echo download patch: https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff
curl -sLO https://raw.githubusercontent.com/itaru2622/bluesky-selfhost-env/refs/heads/master/patching/105-atproto-services-for-docker.diff
curl -sL https://raw.githubusercontent.com/itaru2622/bluesky-selfhost-env/refs/heads/master/patching/105-atproto-services-for-docker.diff -o ${p_}
else
echo local patch
fi
@ -144,6 +153,28 @@ function at-repos-social-app-patch() {
popd
}
function at-repos-ozone-patch() {
#DOMAIN=syu.is
cd $d/repos
d_=$d/repos/ozone
rm -rf ${d_}
p_=$d/patching/120-ozone-runtimeEnvVars.diff
git clone https://github.com/bluesky-social/ozone
cd ${d_}
pushd ${d_}
echo "applying patch: under ${d_} for ${p_}"
patch -p1 < ${p_}
popd
p_=$d/patching/122-ozone-enable-daemon.diff
echo "applying patch: under ${d_} for ${p_}"
pushd ${d_}
patch -p1 < ${p_}
popd
#cp -rf $d/repos/atproto/service/ozone/* $d/ozone/service/
}
function at-repos-docker() {
cd $d
docker compose build && docker compose up -d
@ -157,11 +188,14 @@ at-repos-social-app-icon-origin
at-repos-social-app-write
at-repos-bsky-patch
at-repos-social-app-patch
at-repos-ozone-patch
echo "[y]docker compose build && up"
read key
case $key in
[yY])
at-repos-docker
;;
esac
#echo "[y]docker compose build && up"
#read key
#case $key in
# [yY])
# at-repos-docker
# ;;
#esac

BIN
item/card/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
item/card/0.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
item/card/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

BIN
item/card/1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
item/card/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 KiB

BIN
item/card/10.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
item/card/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

BIN
item/card/11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
item/card/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

BIN
item/card/12.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
item/card/13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

BIN
item/card/13.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
item/card/135.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
item/card/135.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
item/card/136.mp4 Normal file

Binary file not shown.

BIN
item/card/136.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
item/card/136.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

BIN
item/card/14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

BIN
item/card/14.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
item/card/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
item/card/2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
item/card/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 KiB

BIN
item/card/3.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
item/card/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 KiB

BIN
item/card/4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
item/card/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

BIN
item/card/5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
item/card/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 KiB

BIN
item/card/6.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
item/card/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 KiB

BIN
item/card/7.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
item/card/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

BIN
item/card/8.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
item/card/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 KiB

BIN
item/card/9.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

38
item/card/readme.md Normal file
View File

@ -0,0 +1,38 @@
# card
カードの仕様を決定します。
基本的に`3:4``1620x2160`で生成していましたが、`4:5``1080x1350`で生成することにしました。これはwindows動画編集が4:5にしか対応していないからです。`.mov`から動画編集で`.mp4`に変換し、それを`.webp`にします。
comfyuiの動画生成はカードの大きさではなかなか思うような動画が作れませんでした。やはり`1920x1080(1080p)`からの生成が最適でした。
- [16:9] 1920x1080 (1080p)
- [16:9] 1280×720 (720p)
- [16:9] 854x480 (480p)
- [4:3] 2160x1620
- [4:3] 1440x1080
- [4:3] 1024×768
- [4:3] 640×480
- [4:5] 2025x1620
- [4:5] 1536x2048
- [4:5] 1080x1350
```bash
$ magick convert -resize 480x -quality 100 4.png 4.webp
$ magick convert -quality 100 1.png 1.webp
$ magick convert -size 1620x2160 xc:white 1080p.png
$ magick convert -resize 1080x -quality 100 1.png 1.webp
```
```sh
$ ffmpeg -i 4.mp4 -vf "fps=15,setpts=PTS/4" -c:v libwebp -loop 1 -quality 100 4.webp
```
## list
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/1.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/2.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/3.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/4.webp" width="200px">

153
lex/ai.syui.system.json Normal file
View File

@ -0,0 +1,153 @@
{
"lexicon": 1,
"id": "ai.syui.system",
"revision": 1,
"description": "Syui's system definitions for game logic and metaphysics",
"defs": {
"main": {
"type": "record",
"record": {
"key": "self",
"recordType": "document",
"schema": {
"type": "object",
"required": ["card", "system"],
"properties": {
"card": {
"type": "array",
"items": { "$ref": "#card" }
},
"system": {
"type": "array",
"items": { "$ref": "#system" }
},
"weapon": {
"type": "array",
"items": { "$ref": "#weapon" }
},
"ability": {
"type": "array",
"items": { "$ref": "#ability" }
},
"character": {
"type": "array",
"items": { "$ref": "#character" }
}
}
}
}
},
"card": {
"type": "object",
"required": ["id", "img", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
}
},
"system": {
"type": "object",
"required": ["id", "enum", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"enum": {
"type": "array",
"items": { "type": "string" }
},
"name": { "type": "string" },
"alias": {
"type": "array",
"items": { "type": "string" }
},
"lang": {
"type": "object",
"properties": {
"ja": { "type": "string" }
}
},
"description": { "type": "string" }
}
},
"weapon": {
"type": "object",
"required": ["id", "img", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
}
},
"ability": {
"type": "object",
"required": ["id", "name", "color"],
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": { "type": "string" }
}
},
"color": { "type": "string" },
"group": {
"type": "array",
"items": { "type": "string" }
},
"duration": { "type": "integer" },
"multiplier": {
"type": "object",
"additionalProperties": { "type": "number" }
}
}
},
"character": {
"type": "object",
"required": ["id", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" },
"description": { "type": "string" }
}
}
}
},
"text": { "type": "string" }
}
}
}
}

View File

@ -0,0 +1,119 @@
diff --git a/app/layout.tsx b/app/layout.tsx
index bfc3470..9350629 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -5,6 +5,7 @@ import 'yet-another-react-lightbox/styles.css'
import 'yet-another-react-lightbox/plugins/thumbnails.css'
import 'yet-another-react-lightbox/plugins/captions.css'
import { ToastContainer } from 'react-toastify'
+import { PublicEnvScript } from 'next-runtime-env';
import { Shell } from '@/shell/Shell'
import { CommandPaletteRoot } from '@/shell/CommandPalette/Root'
@@ -36,6 +37,7 @@ export default function RootLayout({
isDarkModeEnabled() ? 'dark' : ''
}`}
>
+ <head>
<title>Ozone</title>
<link
rel="icon"
@@ -43,6 +45,8 @@ export default function RootLayout({
sizes="any"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
+ <PublicEnvScript />
+ </head>
<body className="h-full overflow-hidden">
<ToastContainer
position="bottom-right"
diff --git a/environment.d.ts b/environment.d.ts
index 7a47cc2..33ab29f 100644
--- a/environment.d.ts
+++ b/environment.d.ts
@@ -9,6 +9,8 @@ declare global {
NEXT_PUBLIC_OZONE_SERVICE_DID?: string // e.g. did:plc:xxx#atproto_labeler
NEXT_PUBLIC_OZONE_PUBLIC_URL?: string // e.g. https://ozone.example.com (falls back to window.location.origin)
NEXT_PUBLIC_SOCIAL_APP_URL?: string // e.g. https://bsky.app
+ NEXT_PUBLIC_SOCIAL_APP_DOMAIN?: string // e.g. bsky.app
+ NEXT_PUBLIC_HANDLE_RESOLVER_URL?: string // e.g. https://api.bsky.app
}
}
}
diff --git a/lib/constants.ts b/lib/constants.ts
index fe7c0e8..c286ac6 100644
--- a/lib/constants.ts
+++ b/lib/constants.ts
@@ -1,29 +1,32 @@
+import { env } from 'next-runtime-env';
+
export const OAUTH_SCOPE = 'atproto transition:generic'
export const OZONE_SERVICE_DID =
- process.env.NEXT_PUBLIC_OZONE_SERVICE_DID || undefined
+ env('NEXT_PUBLIC_OZONE_SERVICE_DID') || undefined
export const OZONE_PUBLIC_URL =
- process.env.NEXT_PUBLIC_OZONE_PUBLIC_URL || undefined
+ env('NEXT_PUBLIC_OZONE_PUBLIC_URL') || undefined
export const PLC_DIRECTORY_URL =
- process.env.NEXT_PUBLIC_PLC_DIRECTORY_URL ||
+ env('NEXT_PUBLIC_PLC_DIRECTORY_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2582'
: 'https://plc.directory')
-export const QUEUE_CONFIG = process.env.NEXT_PUBLIC_QUEUE_CONFIG || '{}'
+export const QUEUE_CONFIG = env('NEXT_PUBLIC_QUEUE_CONFIG') || '{}'
-export const QUEUE_SEED = process.env.NEXT_PUBLIC_QUEUE_SEED || ''
+export const QUEUE_SEED = env('NEXT_PUBLIC_QUEUE_SEED') || ''
+export const SOCIAL_APP_DOMAIN = env('NEXT_PUBLIC_SOCIAL_APP_DOMAIN') || 'bsky.app'
export const SOCIAL_APP_URL =
- process.env.NEXT_PUBLIC_SOCIAL_APP_URL ||
+ env('NEXT_PUBLIC_SOCIAL_APP_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
- : 'https://bsky.app')
+ : `https://${SOCIAL_APP_DOMAIN}`)
export const HANDLE_RESOLVER_URL =
- process.env.NEXT_PUBLIC_HANDLE_RESOLVER_URL ||
+ env('NEXT_PUBLIC_HANDLE_RESOLVER_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
: 'https://api.bsky.app')
diff --git a/lib/util.ts b/lib/util.ts
index 0aa4460..ecec7d1 100644
--- a/lib/util.ts
+++ b/lib/util.ts
@@ -1,5 +1,5 @@
import { CollectionId } from '@/reports/helpers/subject'
-import { SOCIAL_APP_URL } from './constants'
+import { SOCIAL_APP_URL, SOCIAL_APP_DOMAIN } from './constants'
import { AtUri } from '@atproto/api'
export function classNames(...classes: (string | undefined)[]) {
@@ -57,7 +57,7 @@ export function takesKeyboardEvt(el?: EventTarget | null) {
)
}
-const blueSkyUrlMatcher = new RegExp('(https?://)?.*bsky.app')
+const blueSkyUrlMatcher = new RegExp('(https?://)?.*'+ `${SOCIAL_APP_DOMAIN}`)
export const isBlueSkyAppUrl = (url: string) => blueSkyUrlMatcher.test(url)
diff --git a/package.json b/package.json
index 8919841..750dce9 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"kbar": "^0.1.0-beta.45",
"lande": "^1.0.10",
"next": "15.2.4",
+ "next-runtime-env": "^3.2.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-dropzone": "^14.3.5",

View File

@ -0,0 +1,82 @@
diff --git a/service/index.js b/service/index.js
index 943c281..7721cd9 100644
--- a/service/index.js
+++ b/service/index.js
@@ -1,5 +1,7 @@
const next = require('next')
-const {
+const ozone = require('@atproto/ozone')
+/*
+{
readEnv,
httpLogger,
envToCfg,
@@ -7,6 +9,7 @@ const {
OzoneService,
Database,
} = require('@atproto/ozone')
+*/
const pkg = require('@atproto/ozone/package.json')
async function main() {
@@ -16,37 +19,48 @@ async function main() {
const frontendHandler = frontend.getRequestHandler()
await frontend.prepare()
// backend
- const env = readEnv()
+ const env = ozone.readEnv()
env.version ??= pkg.version
- const config = envToCfg(env)
- const secrets = envToSecrets(env)
+ const config = ozone.envToCfg(env)
+ const secrets = ozone.envToSecrets(env)
const migrate = process.env.OZONE_DB_MIGRATE === '1'
if (migrate) {
- const db = new Database({
+ const db = new ozone.Database({
url: config.db.postgresUrl,
schema: config.db.postgresSchema,
})
await db.migrateToLatestOrThrow()
await db.close()
}
- const ozone = await OzoneService.create(config, secrets)
+ const server = await ozone.OzoneService.create(config, secrets)
// setup handlers
- ozone.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
+ server.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
return res.json({
- did: ozone.ctx.cfg.service.did,
- url: ozone.ctx.cfg.service.publicUrl,
- publicKey: ozone.ctx.signingKey.did(),
+ did: server.ctx.cfg.service.did,
+ url: server.ctx.cfg.service.publicUrl,
+ publicKey: server.ctx.signingKey.did(),
})
})
// Note: We must use `use()` here. This should be the last middleware.
- ozone.app.use((req, res) => {
+ server.app.use((req, res) => {
void frontendHandler(req, res, undefined)
})
// run
- const httpServer = await ozone.start()
+ const httpServer = await server.start()
+ // starts: involve ops from atproto/packages/dev-env/src/ozone.ts >>>
+ ozone.httpLogger.info('starts ozone daemon')
+ const daemon = await ozone.OzoneDaemon.create(config, secrets)
+ await daemon.start()
+ //if (process.env.OZONE_ENABLE_EVENT_REVERSER != 'true') // atproto/services/ozone/daemon.js doesn't stop eventReverser
+ //{
+ // ozone.httpLogger.info('disable ozone daemon eventReverser')
+ // await daemon.ctx.eventReverser.destroy()
+ //}
+ // ends: involve ops from atproto/packages/dev-env/src/ozone.ts <<<
+
/** @type {import('net').AddressInfo} */
const addr = httpServer.address()
- httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
+ ozone.httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
}
main().catch(console.error)

View File

@ -4,6 +4,7 @@ d=${0:a:h}
source $d/src/tag.zsh
source $d/src/func.zsh
source $d/src/ue.zsh
source $d/src/ai/syui/game/character.zsh
source $d/src/is/syu/main.zsh
@ -61,7 +62,13 @@ case $1 in
verify-icon
;;
self-col)
self-col
self-col $2
;;
ue-system)
ue-system
;;
ue-user)
ue-user $2
;;
*)
echo "${help[@]}"

10
scpt/generate_record.py Normal file
View File

@ -0,0 +1,10 @@
import json
record = {
"$type": "app.bsky.feed.post",
"text": "テスト投稿 from script",
"createdAt": "2025-05-26T12:00:00Z"
}
with open("record.json", "w", encoding="utf-8") as f:
json.dump(record, f, ensure_ascii=False, indent=2)

View File

@ -1,33 +1,3 @@
character=(
ai
manny
quinn
chinese
kirin
leviathan
phoenix
wyvern
cerberus
dragon
kitsune
pegasus
)
img=(
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreidlealfybajqzwv5eoz4jshnsijc2vnktlhpw4ph47krwj6aigqby
bafkreiegpqedlrfa4ljhssdnkrr5hyd5huy2xhh2zszj5wq2wuuzejggmq
bafkreig6vszkx3c4dcortjwfsz6sa6zwqgj7zpxj4lxfrrkwql4xhiu5ou
bafkreich7fsumke2yvumvixkruonzrcevk3f6g2cntzfwdn4n2c2vox5dm
bafkreiacjvagsekhiiljz3j237b6klrt6pkptxljt7kltprgg5276gv25q
bafkreihpni4lp55jysalcntulzal5rbhidtbseanlucpyucagzxmv6xj24
bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
bafkreidy74aieb6ie646xhosginox5zbnbnrtd76cnt4pbn73hrxgfnple
bafkreifnbfj27fr6nv7qeqqmwdibf7qrw4lauvzoknw5hexbifmwqt6kmq
)
function download_character_icon(){
t=(
@ -219,8 +189,8 @@ delete_game_user() {
function create_game_user() {
col=ai.syui.game
rkey=$1
did=$did
handle=$handle
handle_yui=$handle
did_yui=$did
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
@ -249,6 +219,8 @@ function create_game_user() {
if [ "$rkey" = "self" ];then
cname=manny
unset did handle gender
pds=bsky.social
plc=plc.directory
fi
imguri=https://cdn.bsky.app/img/feed_thumbnail/plain/$did_yui/${cid}@jpeg
season=1
@ -286,8 +258,8 @@ function create_game_user() {
v1_json="
{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
@ -313,8 +285,8 @@ json_item="
json="
{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
@ -345,7 +317,7 @@ if echo $json|jq . ;then
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
#echo $t|jq .
echo $t|jq .
#f=~/ai/ue/json/v${version}_${rkey}.json
#if [ -f $f ];then
# get_game_user $rkey >! $f

View File

@ -10,6 +10,10 @@ function at-env() {
did=$did_yui
created=2025-04-21T00:00:00.323Z
docs_uri=https://docs.bsky.app/docs/api
at_uri=at://$handle/ai.syui.game/ai
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
d=${0:a:h}
f=~/.config/ai/token.json
if [ -f $f ];then
@ -23,10 +27,6 @@ function at-env() {
plc=plc.syu.is
pds=$host
fi
at_uri=at://$handle/ai.syui.game/ai
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
}
function at-unset() {

View File

@ -1,6 +1,11 @@
#!/bin/zsh
function self-col(){
if [ -n "$1" ];then
t=`curl -sL "$pds/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=$1"`
echo $t|jq .
exit
fi
col=(
ai.syui.game
ai.syui.system

View File

@ -38,3 +38,33 @@ github=(
)
tag=( at bsky bsync pds bgs plc ozone feed jetstream social-app oauth )
#pds_list=(bsky.social syu.is boobee.blue socl.is )
character=(
ai
manny
quinn
chinese
kirin
leviathan
phoenix
wyvern
cerberus
dragon
kitsune
pegasus
)
character_img=(
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreidlealfybajqzwv5eoz4jshnsijc2vnktlhpw4ph47krwj6aigqby
bafkreiegpqedlrfa4ljhssdnkrr5hyd5huy2xhh2zszj5wq2wuuzejggmq
bafkreig6vszkx3c4dcortjwfsz6sa6zwqgj7zpxj4lxfrrkwql4xhiu5ou
bafkreich7fsumke2yvumvixkruonzrcevk3f6g2cntzfwdn4n2c2vox5dm
bafkreiacjvagsekhiiljz3j237b6klrt6pkptxljt7kltprgg5276gv25q
bafkreihpni4lp55jysalcntulzal5rbhidtbseanlucpyucagzxmv6xj24
bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
bafkreidy74aieb6ie646xhosginox5zbnbnrtd76cnt4pbn73hrxgfnple
bafkreifnbfj27fr6nv7qeqqmwdibf7qrw4lauvzoknw5hexbifmwqt6kmq
)

193
scpt/src/ue.zsh Executable file
View File

@ -0,0 +1,193 @@
case $OSTYPE in
darwin*)
day=`gdate --iso-8601=seconds`
;;
*)
day=`date --iso-8601=seconds`
;;
esac
function get_game_user() {
rkey=$did.$pds
pds=bsky.social
if [ "$1" = "syui" ] || [ "$1" = "ai" ];then
rkey=$1
fi
req=com.atproto.repo.getRecord
url="https://$pds/xrpc/$req?rkey=$rkey&repo=$did_yui&collection=ai.syui.game"
curl -sL $url|jq .
}
function delete_game_user() {
rkey=$2
if [ -z "$1" ];then
col=ai.syui.game
else
col=$1
fi
req=com.atproto.repo.DeleteRecord
url=https://$pds/xrpc/$req
repo=$did
#repo=did:plc:6qyecktefllvenje24fcxnie
json="{\"collection\":\"$col\", \"rkey\":\"$rkey\", \"repo\":\"$repo\"}"
echo $json
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url
}
function ue-user() {
col=ai.syui.game
rkey=$1
handle_yui=$handle
did_yui=$did
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=4
#rkey=syui
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
cname=dragon
if [ "$rkey" = "ai" ];then
cname=$rkey
gender=none
fi
if [ "$rkey" = "syui" ];then
cname=chinese
did=$did_syui
handle=syui.ai
gender=male
fi
if [ "$rkey" = "self" ];then
cname=manny
unset did handle gender
pds=bsky.social
plc=plc.directory
fi
season=1
group=test
lv=1
hp=1
exp=0
rare=0
mode=0
attack=0
attack_post=0
critical=0
critical_d=0
card=0
weapon=0
coin=0
count=0
case $cname in
ai)
group=origin
season=0
mode=2
;;
manny|quinn)
group=test
;;
*)
group=fantasy
;;
esac
json_item="
\"coin\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"card\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"weapon\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}]
"
json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"version\": $version,
\"did\": \"$did\",
\"handle\": \"$handle\",
\"plc\": \"$plc\",
\"pds\": \"$pds\",
\"player\": {
\"limit\": false,
\"login\": false,
\"ten\": 0,
\"gender\": \"$gender\"
},
\"character\": {
$json
},
\"item\": {
$json_item
},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
#f=~/ai/ue/json/v${version}_${rkey}.json
#if [ -f $f ];then
# get_game_user $rkey >! $f
#fi
fi
fi
}
function ue-system() {
col=ai.syui.system
rkey=self
did=$did
handle=$handle
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=1
#rkey=syui
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
imgurl=https://git.syui.ai/ai/ai/raw/branch/main/img/item/card
json_card=" \"id\": $id, \"name\": \"$name\", \"img\": \"${imgurl}/${id}.webp\""
json_card=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/card.json|jq ".[]"`
json_weapon=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/weapon.json|jq ".[]"`
json_system=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/system.json|jq ".[]"`
json_character=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/character.json|jq ".[]"`
json_ability=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/ability.json|jq ".[]"`
json="
{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"card\": ${json_card},
\"weapon\": ${json_weapon},
\"system\": ${json_system},
\"character\": ${json_character},
\"ability\": ${json_ability},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
fi
fi
}