openjutsu
영상에서 원클릭으로 인물 교체, ComfyUI·MiniMax H3 기반 오픈소스 로컬 힉스필드 겐주츠 대안, FLUX.3 Klein 재조명 지원
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Source code for our website that allows users to vote on the next song to be played.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A real-time voting website that lets visitors choose which Christmas song plays next at a synchronized light show. Visitors cast votes from their phones, and the results are broadcast to fppscheduler via MQTT to influence the show's playlist.
Visitor Browser
│
│ HTTP / WebSocket (Hapi NES)
▼
┌─────────────┐ MQTT ┌──────────────────┐
│ Node.js │ ◄────────────────►│ MQTT Broker │
│ Hapi Server│ └──────────────────┘
│ :7654 │ │
└─────────────┘ │ /christmas/...
▲ ┌──────┴───────┐
│ Built static files │ fppscheduler │
┌─────────────┐ │ (on FPP box)│
│ Vue 3 + │ └──────────────┘
│ Vite │
│ Frontend │
└─────────────┘
frontend/) — Vue 3 SPA built with Vite. Served as static files by a web server (e.g., nginx). Communicates with the backend via REST and a persistent WebSocket subscription.server/) — Hapi.js server. Manages vote state, pushes real-time updates to all connected clients via Hapi NES WebSockets, and relays votes/status to/from an MQTT broker.nvm use 24)/christmasserver/)Copy the example config and fill in your MQTT broker details:
cp server/greglights_config_example.json server/greglights_config.json
Edit server/greglights_config.json:
{
"username": "your-mqtt-username",
"password": "your-mqtt-password",
"port": 1883,
"host": "192.168.1.x",
"send_enabled": true
}
| Field | Description |
|---|---|
host | Hostname or IP of the MQTT broker |
port | MQTT broker port (1883 for plain, 8883 for TLS) |
username | MQTT username |
password | MQTT password |
send_enabled | Set false to disable publishing votes/queues to MQTT (dry-run mode) |
Note:
greglights_config.jsoncontains credentials — do not commit it. It is listed in.gitignore.
cd server
nvm use 24
npm install
node index.js
The server listens on port 7654 by default. Override with the port environment variable:
port=8000 node index.js
cd server
docker-compose build
docker-compose up -d
The docker-compose.yml binds the server to 127.0.0.1:7654 on the host. Front it with nginx or another reverse proxy for HTTPS.
| Method | Path | Description |
|---|---|---|
GET | /queue | Returns the full data model (songs, names, snowmen, votes remaining for session) |
GET | /model | Returns the full data model (no session info) |
GET/POST | /vote/{id} | Cast a vote for song with the given ID |
DELETE | /vote/{id} | Remove a previously cast vote for song {id} |
GET/POST | /votesnowman/{id} | Vote for a snowman display |
GET | /status | Returns server health status |
GET | /faq | Returns the shared display FAQ as rendered HTML |
GET | /ws | WebSocket endpoint (Hapi NES) — subscribe to /publicData for real-time model pushes |
GET /faqThis server owns the FAQ text for both vote-now.org and thehormanns.net, so the
two sites can never drift apart. The questions and answers live in
server/data/faqs.js; anything that can change — season dates, the song count,
the address, charity names — is written there as a {{token}} and filled in
from server/data/facts.js on each request. Answers come back as ready-to-show
HTML.
| Query | Description |
|---|---|
audience | web (thehormanns.net) or app (the vote-now info page). Omit for everything. |
site | Base URL for links into thehormanns.net. Defaults to https://thehormanns.net; thehormanns.net passes an empty string so its own links stay relative. |
curl 'http://localhost:7654/faq?audience=app'
thehormanns.net calls this at build time (which is what feeds its FAQPage
structured data) and again in the browser, so edits here reach that site without
a redeploy.
Sessions are tracked server-side via a cookie (Hapi Yar). Each session gets 8 votes, replenished by 1 every 2 minutes.
The server subscribes to these topics (all under the /christmas/ prefix):
| Topic | Purpose |
|---|---|
/christmas/nameQueue | Name queue status from fppscheduler |
/christmas/scheduler/status | Scheduler run state (on/off, short list mode, debug) |
/christmas/scheduler/name_estimate | Estimated time until next name is generated |
/christmas/scheduler/all_playlist | Full song list with durations |
/christmas/snowman/status | Available snowman displays and current selection |
/christmas/falcon/player/fpp2/playlist_details | Currently playing song from FPP |
/christmas/clock | Show clock tick |
/christmas/todayPower | Power consumption stats |
/christmas/vote/stats | Aggregated vote statistics |
/christmas/vote/setShortList | Toggle short-list mode |
/christmas/vote/debug | Toggle debug mode |
The server publishes to:
| Topic | Purpose |
|---|---|
/christmas/vote/add | Notify fppscheduler of a new song vote |
/christmas/snowmanvote/add | Notify fppscheduler of a snowman vote |
/christmas/vote/songQueue | Broadcast current song queue (every 2 s) |
/christmas/vote/snowmenQueue | Broadcast current snowman queue (every 2 s) |
/christmas/personsName | Submit a visitor's name to the name display queue |
/christmas/scheduler/requestSongs | Request full playlist from fppscheduler on startup |
/christmas is hard-coded in lib/mymqtt.js.https://vote-now.org) is hard-coded in routes/index.js but only used for a redirect on a 404.mqtt:// is active.frontend/)Vite uses .env files to inject the backend URL at build time. Two files are used:
.env.local — used automatically during npm run dev (never committed):
VITE_API_BASE_URL=http://localhost:7654
VITE_WS_URL=ws://localhost:7654/ws
.env.production — used automatically during npm run build:
VITE_API_BASE_URL=https://your-domain.com/api
VITE_WS_URL=wss://your-domain.com/ws
Update .env.production to match your production server's domain before building.
| Variable | Description |
|---|---|
VITE_API_BASE_URL | Base URL for REST API calls to the Hapi server |
VITE_WS_URL | WebSocket URL for real-time Hapi NES subscription |
cd frontend
nvm use 24
npm install
npm run dev
Starts Vite dev server at http://localhost:8080 (bound to all interfaces via host: true in vite.config.js). API requests proxy to the backend via the URL in .env.local.
npm run build
Outputs static files to frontend/dist/. Copy these to your web server's document root.
| Command | Description |
|---|---|
npm run preview | Preview the production build locally |
npm run lint | Lint and auto-fix with ESLint |
npm run format | Format source files with Prettier |
npm run test | Run unit tests with Vitest |
| Route | Component | Description |
|---|---|---|
/ | HomeView | Song voting — list of available songs with vote buttons |
/names | NameQueue | Submit your name to appear on the light show name display |
/info | InfoView | Show information and FAQ |
/stats | StatsView | Voting and power usage statistics |
/other | OtherDisplaysView | Other display elements (snowmen voting, etc.) |
| Package | Purpose |
|---|---|
| Vue 3 + Vite | UI framework and build tool |
| Pinia | State management |
| Vue Router 4 | Client-side routing |
@hapi/nes | WebSocket client for real-time server pushes |
| Axios | HTTP REST client |
| Bootstrap 5 | UI styling |
Run backend and frontend in separate terminals:
# Terminal 1 — backend
cd server && nvm use 24 && node index.js
# Terminal 2 — frontend
cd frontend && nvm use 24 && npm run dev
The frontend dev server at http://localhost:8080 connects to the backend at http://localhost:7654 as configured in frontend/.env.local.
cd frontend && npm run buildfrontend/dist/ files to your web server document root./api/ and /ws to http://127.0.0.1:7654.cd server && docker-compose up -d.