mcmeszi commited on
Commit
dd2c2ff
·
verified ·
1 Parent(s): e8e6c34

Upload 8 files

Browse files
Files changed (9) hide show
  1. .gitattributes +1 -0
  2. Dockerfile +8 -0
  3. README.md +1 -1
  4. env.example +1 -0
  5. etele slogan VO.wav +3 -0
  6. gitignore +2 -0
  7. package.json +14 -0
  8. server.js +60 -0
  9. theos_ex_machina.html +297 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ etele[[:space:]]slogan[[:space:]]VO.wav filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-alpine
2
+ WORKDIR /app
3
+ COPY package*.json ./
4
+ RUN npm install --production
5
+ COPY . .
6
+ EXPOSE 7860
7
+ ENV PORT=7860
8
+ CMD ["node","server.js"]
README.md CHANGED
@@ -10,4 +10,4 @@ pinned: false
10
  # Theos ex Machina – Biblia × AI elemzés
11
 
12
  1. **Open Website** → könyv + vers kiválasztása vagy 🎲 Random.
13
- 2. Kulcs: Settings → Repository secrets → `OPENAI_KEY`.
 
10
  # Theos ex Machina – Biblia × AI elemzés
11
 
12
  1. **Open Website** → könyv + vers kiválasztása vagy 🎲 Random.
13
+ 2. Kulcs: Settings → Repository secrets → `OPENAI_KEY`.
env.example ADDED
@@ -0,0 +1 @@
 
 
1
+ OPENAI_KEY=sk-YOUR-KEY-HERE
etele slogan VO.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b011e112e195f0d0271d5f36747082a335171b5e3337be8fa6b365563e5fdf76
3
+ size 345380
gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ node_modules/
2
+ .env
package.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "theos-ex-machina-space",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "main": "server.js",
6
+ "scripts": {
7
+ "start": "node server.js"
8
+ },
9
+ "dependencies": {
10
+ "dotenv": "^16.4.1",
11
+ "express": "^4.19.2",
12
+ "node-fetch": "^3.3.2"
13
+ }
14
+ }
server.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from "express";
2
+ import fetch from "node-fetch";
3
+ import dotenv from "dotenv";
4
+
5
+ dotenv.config();
6
+
7
+ const app = express();
8
+ const PORT = process.env.PORT || 7860; // HF Space default port
9
+
10
+ if (!process.env.OPENAI_KEY) {
11
+ console.error("❌ Hiányzik az OPENAI_KEY környezeti változó!");
12
+ process.exit(1);
13
+ }
14
+
15
+ app.use(express.json());
16
+ app.use(express.static("public"));
17
+
18
+ app.post("/api/analyze", async (req, res) => {
19
+ const { book, chapter, verse, translation } = req.body || {};
20
+ const ref = `${book} ${chapter}:${verse}`;
21
+
22
+ try {
23
+ // 1) Vers letöltése Bible‑API‑ról
24
+ const bibRes = await fetch(
25
+ \`https://bible-api.com/${encodeURIComponent(ref)}?translation=${translation}\`
26
+ );
27
+ if (!bibRes.ok) throw new Error("Bible‑API hiba");
28
+ const bibData = await bibRes.json();
29
+ const verseText = bibData.text.trim();
30
+
31
+ // 2) AI‑elemzés GPT‑vel
32
+ const aiRes = await fetch("https://api.openai.com/v1/chat/completions", {
33
+ method: "POST",
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ Authorization: `Bearer ${process.env.OPENAI_KEY}`,
37
+ },
38
+ body: JSON.stringify({
39
+ model: "gpt-4o-mini",
40
+ messages: [
41
+ { role: "system", content: "You are the narrator of Theos ex Machina, analysing bible verses from theological and AI‑ethical perspectives." },
42
+ { role: "user", content: \`Here is the verse: \"${verseText}\" — ${ref} (${translation.toUpperCase()}). Analyse how it resonates with the philosophical challenges and ethical dilemmas of artificial intelligence.\` }
43
+ ],
44
+ temperature: 0.8,
45
+ max_tokens: 512
46
+ })
47
+ });
48
+
49
+ if (!aiRes.ok) throw new Error("OpenAI API hiba");
50
+ const aiData = await aiRes.json();
51
+ const analysis = aiData.choices[0].message.content.trim();
52
+
53
+ res.json({ reference: \`\${ref} (\${translation.toUpperCase()})\`, verseText, analysis });
54
+ } catch (err) {
55
+ console.error(err);
56
+ res.status(500).json({ error: err.message || "Ismeretlen hiba" });
57
+ }
58
+ });
59
+
60
+ app.listen(PORT, () => console.log(\`🚀 Space‑szerver fut a \${PORT}‑as porton\`));
theos_ex_machina.html ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📂 Projektstruktúra
2
+ ```
3
+ my-theos-ex-machina/
4
+ ├── public/
5
+ │ └── index.html # Front‑end UI (statikus)
6
+ ├── server.js # Node.js + Express backend (API kulcs a szerveren)
7
+ ├── .env # OPENAI_KEY=sk‑...
8
+ └── package.json # Függőségek (express, node-fetch, dotenv)
9
+ ```
10
+
11
+ ---
12
+
13
+ ## 1️⃣ `server.js` – backend, ahol az OpenAI kulcs **biztonságban** marad
14
+ ```js
15
+ // server.js
16
+ import express from "express";
17
+ import fetch from "node-fetch";
18
+ import dotenv from "dotenv";
19
+
20
+ dotenv.config();
21
+
22
+ const app = express();
23
+ const PORT = process.env.PORT || 3000;
24
+
25
+ if (!process.env.OPENAI_KEY) {
26
+ console.error("❌ Hiányzik az OPENAI_KEY a .env fájlból!");
27
+ process.exit(1);
28
+ }
29
+
30
+ app.use(express.json());
31
+ app.use(express.static("public")); // kiszolgáljuk az index.html‑t
32
+
33
+ /**
34
+ * POST /api/analyze
35
+ * Body: { book, chapter, verse, translation }
36
+ * Visszaad: { reference, verseText, analysis }
37
+ */
38
+ app.post("/api/analyze", async (req, res) => {
39
+ const { book, chapter, verse, translation } = req.body || {};
40
+ const ref = `${book} ${chapter}:${verse}`;
41
+
42
+ try {
43
+ // 1) Vers letöltése Bible‑API‑ról
44
+ const bibRes = await fetch(
45
+ `https://bible-api.com/${encodeURIComponent(ref)}?translation=${translation}`
46
+ );
47
+ if (!bibRes.ok) throw new Error("Bible‑API hiba");
48
+ const bibData = await bibRes.json();
49
+ const verseText = bibData.text.trim();
50
+
51
+ // 2) AI‑elemzés OpenAI‑val
52
+ const aiRes = await fetch("https://api.openai.com/v1/chat/completions", {
53
+ method: "POST",
54
+ headers: {
55
+ "Content-Type": "application/json",
56
+ Authorization: `Bearer ${process.env.OPENAI_KEY}`,
57
+ },
58
+ body: JSON.stringify({
59
+ model: "gpt-4o-mini",
60
+ messages: [
61
+ {
62
+ role: "system",
63
+ content:
64
+ "You are the narrator of Theos ex Machina, analysing bible verses from both theological and AI‑ethical perspectives.",
65
+ },
66
+ {
67
+ role: "user",
68
+ content: `Here is the verse: "${verseText}" — ${ref} (${translation.toUpperCase()}). Analyse how it resonates with the philosophical challenges and ethical dilemmas of artificial intelligence.`,
69
+ },
70
+ ],
71
+ temperature: 0.8,
72
+ max_tokens: 512,
73
+ }),
74
+ });
75
+
76
+ if (!aiRes.ok) throw new Error("OpenAI API hiba");
77
+ const aiData = await aiRes.json();
78
+ const analysis = aiData.choices[0].message.content.trim();
79
+
80
+ res.json({ reference: `${ref} (${translation.toUpperCase()})`, verseText, analysis });
81
+ } catch (err) {
82
+ console.error(err);
83
+ res.status(500).json({ error: err.message || "Ismeretlen hiba" });
84
+ }
85
+ });
86
+
87
+ app.listen(PORT, () => console.log(`🚀 Szerver fut http://localhost:${PORT}`));
88
+ ```
89
+
90
+ > **Biztonság:** az API‑kulcs a szerveren (`.env`) marad, a front‑end nem látja.
91
+
92
+ ---
93
+
94
+ ## 2️⃣ `public/index.html` – felhasználói felület dinamikus vers‑választással és 🎲 Random gombbal
95
+ ```html
96
+ <!DOCTYPE html>
97
+ <html lang="hu">
98
+ <head>
99
+ <meta charset="UTF-8" />
100
+ <title>Theos ex Machina</title>
101
+ <style>
102
+ body{font-family:Arial,Helvetica,sans-serif;max-width:760px;margin:40px auto;padding:0 1rem;line-height:1.5;}
103
+ h1{font-size:1.9rem;margin-bottom:0.4rem;}
104
+ label{display:block;margin-top:1rem;font-weight:600;}
105
+ select,input,button{font-size:1rem;padding:0.4rem 0.6rem;width:100%;box-sizing:border-box;border:1px solid #bbb;border-radius:4px;}
106
+ button{margin-top:1.2rem;background:#00684a;color:#fff;border:none;cursor:pointer;transition:background 0.2s;}
107
+ button:hover:not(:disabled){background:#004f38;}
108
+ button:disabled{opacity:0.6;cursor:not-allowed;}
109
+ #result{margin-top:2rem;border-top:1px solid #ccc;padding-top:1.5rem;display:none;}
110
+ pre{white-space:pre-wrap;background:#f7f7f7;padding:1rem;border-radius:4px;}
111
+ .row{display:flex;gap:0.5rem;}
112
+ .row>*{flex:1;}
113
+ </style>
114
+ </head>
115
+ <body>
116
+ <h1>Theos ex Machina</h1>
117
+ <p>Válassz könyvet, fejezetet és verset, vagy használd a <strong>Random</strong> gombot! A kulcs a szerveren van, így biztonságban vagy.</p>
118
+
119
+ <label>Könyv (angol/magyar):
120
+ <input type="text" id="book" placeholder="Jonah / Jónás" />
121
+ </label>
122
+
123
+ <div class="row">
124
+ <label>Fejezet:
125
+ <select id="chapter"></select>
126
+ </label>
127
+
128
+ <label>Vers:
129
+ <select id="verse"></select>
130
+ </label>
131
+ </div>
132
+
133
+ <label>Fordítás kód (pl. kjv, niv, hun‑carl‑gaspar):
134
+ <input type="text" id="translation" value="kjv" />
135
+ </label>
136
+
137
+ <button id="randomBtn">🎲 Random vers</button>
138
+ <button id="generateBtn">📖 Elemzés létrehozása</button>
139
+
140
+ <div id="result">
141
+ <h2>Vers</h2>
142
+ <pre id="verseText"></pre>
143
+ <h2>AI elemzés</h2>
144
+ <pre id="analysis"></pre>
145
+ </div>
146
+
147
+ <script>
148
+ // 1️⃣ Fejezetek+versek lekérése a Bible‑API‑ról, hogy mindig érvényes értékek legyenek
149
+ async function fetchChapterVerseCounts(book, translation){
150
+ const chapters = [];
151
+ for(let ch=1; ch<=150; ch++){ // max. 150 fejezet biztos elég
152
+ const resp = await fetch(`https://bible-api.com/${encodeURIComponent(book)}+${ch}:1?translation=${translation}`);
153
+ if(!resp.ok) break;
154
+ const data = await resp.json();
155
+ const versesInChapter = data.verses[data.verses.length-1].verse;
156
+ chapters.push(versesInChapter);
157
+ }
158
+ if(!chapters.length) throw new Error('📕 Nem találtam könyvet ilyen néven.');
159
+ return chapters; // [verseskárták száma fejezetenként]
160
+ }
161
+
162
+ function fillSelect(sel, count){
163
+ sel.innerHTML="";
164
+ for(let i=1;i<=count;i++){
165
+ const opt=document.createElement('option');
166
+ opt.value=i; opt.textContent=i; sel.appendChild(opt);
167
+ }
168
+ }
169
+
170
+ async function refreshChapterSelect(){
171
+ const book=document.getElementById('book').value.trim();
172
+ const translation=document.getElementById('translation').value.trim();
173
+ if(!book) return;
174
+ try{
175
+ document.getElementById('generateBtn').disabled=true;
176
+ document.getElementById('randomBtn').disabled=true;
177
+ const chapters=await fetchChapterVerseCounts(book,translation);
178
+ window.chapterVerseMap=chapters; // globális tárolás
179
+ fillSelect(document.getElementById('chapter'), chapters.length);
180
+ fillSelect(document.getElementById('verse'), chapters[0]);
181
+ document.getElementById('generateBtn').disabled=false;
182
+ document.getElementById('randomBtn').disabled=false;
183
+ }catch(err){
184
+ alert(err.message);
185
+ }
186
+ }
187
+
188
+ document.getElementById('book').addEventListener('change', refreshChapterSelect);
189
+ document.getElementById('translation').addEventListener('change', refreshChapterSelect);
190
+
191
+ document.getElementById('chapter').addEventListener('change', ()=>{
192
+ const chSel=document.getElementById('chapter');
193
+ const maxVerses=window.chapterVerseMap[chSel.value-1]||1;
194
+ fillSelect(document.getElementById('verse'), maxVerses);
195
+ });
196
+
197
+ // 2️⃣ Random gomb – válasszon véletlenszerűen érvényes fejezetet+verset
198
+ function pickRandomVerse(){
199
+ const chSel=document.getElementById('chapter');
200
+ const verseSel=document.getElementById('verse');
201
+ const randChIdx=Math.floor(Math.random()*window.chapterVerseMap.length);
202
+ chSel.value=randChIdx+1;
203
+ const maxV=window.chapterVerseMap[randChIdx];
204
+ fillSelect(verseSel, maxV);
205
+ verseSel.value=Math.floor(Math.random()*maxV)+1;
206
+ }
207
+
208
+ document.getElementById('randomBtn').addEventListener('click', pickRandomVerse);
209
+
210
+ // 3️⃣ Elemzés létrehozása a backenden keresztül
211
+ async function generate(){
212
+ const payload={
213
+ book:document.getElementById('book').value.trim(),
214
+ chapter:document.getElementById('chapter').value,
215
+ verse:document.getElementById('verse').value,
216
+ translation:document.getElementById('translation').value.trim()
217
+ };
218
+ if(!payload.book) return alert('📕 Írj be egy könyvet!');
219
+
220
+ document.getElementById('generateBtn').disabled=true;
221
+ document.getElementById('generateBtn').textContent='⏳ Feldolgozás…';
222
+
223
+ try{
224
+ const res=await fetch('/api/analyze',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
225
+ if(!res.ok){const e=await res.json();throw new Error(e.error||'Ismeretlen hiba');}
226
+ const data=await res.json();
227
+ document.getElementById('verseText').textContent=`${data.verseText}`;
228
+ document.getElementById('analysis').textContent=data.analysis;
229
+ document.getElementById('result').style.display='block';
230
+ }catch(err){
231
+ alert(err.message);
232
+ }finally{
233
+ document.getElementById('generateBtn').disabled=false;
234
+ document.getElementById('generateBtn').textContent='📖 Elemzés létrehozása';
235
+ }
236
+ }
237
+
238
+ document.getElementById('generateBtn').addEventListener('click', generate);
239
+
240
+ // Induláskor próbáljuk meg automatikusan betölteni a könyv fejezeteit, ha van
241
+ refreshChapterSelect();
242
+ </script>
243
+ </body>
244
+ </html>
245
+ ```
246
+
247
+ ---
248
+
249
+ ## 3️⃣ `package.json`
250
+ ```json
251
+ {
252
+ "name": "theos-ex-machina",
253
+ "type": "module",
254
+ "version": "1.0.0",
255
+ "main": "server.js",
256
+ "scripts": {
257
+ "start": "node server.js"
258
+ },
259
+ "dependencies": {
260
+ "dotenv": "^16.4.1",
261
+ "express": "^4.19.2",
262
+ "node-fetch": "^3.3.2"
263
+ }
264
+ }
265
+ ```
266
+
267
+ ---
268
+
269
+ ## 4️⃣ `.env`
270
+ ```
271
+ OPENAI_KEY=sk-PASTE_YOUR_KEY_HERE
272
+ ```
273
+
274
+ > **Ne committelj `.env`‑et!** A kulcs privát marad.
275
+
276
+ ---
277
+
278
+ ### 💾 Telepítés & futtatás
279
+ ```bash
280
+ # 1. Fájlok elhelyezése (lásd struktúra)
281
+ # 2. Telepítés
282
+ npm install
283
+ # 3. .env‑be beilleszted a kulcsot
284
+ # 4. Start
285
+ npm start
286
+ # 5. Böngészőben: http://localhost:3000
287
+ ```
288
+
289
+ ---
290
+
291
+ ### 🚀 Mit kaptál most?
292
+ - **Backend** védi az OpenAI kulcsot.
293
+ - **Front‑end** csak a saját szerveredhez beszél, és mindig valós fejezet/vers számok jelennek meg.
294
+ - **Random vers** egyetlen kattintás.
295
+ - Mindössze **1 Bible‑API + 1 OpenAI** hívással működik.
296
+
297
+ Ha szeretnéd tovább bővíteni (például egész könyv elemzés, PDF export, több nyelvű UI), csak szólj! 😉