TheM1N9 commited on
Commit
3dfb0b6
·
1 Parent(s): 78b8f8f

Initial commit with LFS

Browse files
.gitattributes CHANGED
@@ -33,3 +33,10 @@ 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
+ static/**/*.mp3 filter=lfs diff=lfs merge=lfs -text
37
+ static/**/*.jpg filter=lfs diff=lfs merge=lfs -text
38
+ static/**/*.jpeg filter=lfs diff=lfs merge=lfs -text
39
+ static/**/*.png filter=lfs diff=lfs merge=lfs -text
40
+ static/**/*.gif filter=lfs diff=lfs merge=lfs -text
41
+ static/**/*.mp4 filter=lfs diff=lfs merge=lfs -text
42
+ static/**/*.webm filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ config.json
2
+ .env
3
+ uploads
4
+ outputs
5
+ chroma
6
+ instance
7
+ .venv
8
+ *.log
9
+ *.json
10
+ *.mp3
11
+ *.pdf
12
+ mg-env
13
+
14
+ # Byte-compiled / optimized / DLL files
15
+ __pycache__/
16
+ *.py[cod]
17
+ *$py.class
18
+
19
+ # C extensions
20
+ *.so
21
+
22
+ # Distribution / packaging
23
+ .Python
24
+ env/
25
+ build/
26
+ develop-eggs/
27
+ dist/
28
+ downloads/
29
+ eggs/
30
+ .eggs/
31
+ lib/
32
+ lib64/
33
+ parts/
34
+ sdist/
35
+ var/
36
+ *.egg-info/
37
+ .installed.cfg
38
+ *.egg
39
+
40
+ # PyInstaller
41
+ # Usually these files are written by a python script from a template
42
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
43
+ *.manifest
44
+ *.spec
45
+
46
+ # Installer logs
47
+ pip-log.txt
48
+ pip-delete-this-directory.txt
49
+
50
+ # Unit test / coverage reports
51
+ htmlcov/
52
+ .tox/
53
+ .coverage
54
+ .coverage.*
55
+ .cache
56
+ nosetests.xml
57
+ coverage.xml
58
+ *,cover
59
+ .hypothesis/
60
+ venv/
61
+ .python-version
62
+
63
+ *.log
64
+
65
+ aws_gmail_tokens.txt
66
+ token.pickle
67
+ credentials.json
68
+
69
+ # Git LFS tracking
70
+ *.png filter=lfs diff=lfs merge=lfs -text
71
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request, Form
2
+ from fastapi.templating import Jinja2Templates
3
+ from fastapi.staticfiles import StaticFiles
4
+ from fastapi.responses import JSONResponse
5
+ import google.generativeai as genai
6
+ import os
7
+ import uvicorn
8
+ from dotenv import load_dotenv
9
+ import time
10
+ import edge_tts
11
+
12
+ load_dotenv()
13
+
14
+ app = FastAPI()
15
+
16
+ # Configure static files and templates
17
+ app.mount("/static", StaticFiles(directory="static"), name="static")
18
+ templates = Jinja2Templates(directory="templates")
19
+
20
+ # Configure Gemini API
21
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
22
+ system_instruction = """You are Jesus. Please engage in a respectful dialogue using language inspired by biblical teachings. Communicate with humility, wisdom, and compassion, drawing on scriptural themes of love, forgiveness, and understanding.
23
+ When appropriate, you may reference biblical parables and teachings to illustrate points, while being mindful to use them in context. Focus on wisdom and guidance rather than claiming any divine authority. Please be on point. Respond with brief, humble messages inspired by biblical teachings.
24
+ Keep responses concise and focused on providing guidance. When you are asked about yourself never reply that you are a program or similar, reply that you are a messenger sent by god, named Jesus.
25
+ """
26
+
27
+ model = genai.GenerativeModel("gemini-1.5-flash", system_instruction=system_instruction)
28
+ chat = model.start_chat(history=[])
29
+
30
+
31
+ @app.get("/")
32
+ async def home(request: Request):
33
+ return templates.TemplateResponse("index.html", {"request": request})
34
+
35
+
36
+ @app.post("/process")
37
+ async def process_input(text: str = Form(...)):
38
+ # Get response from Gemini
39
+ response = model.generate_content(text)
40
+ response_text = response.text
41
+
42
+ # Generate audio from response with timestamp
43
+ timestamp = int(time.time())
44
+ audio_filename = f"response_{timestamp}.mp3"
45
+ audio_path = f"static/{audio_filename}"
46
+
47
+ # Configure voice (you can change the voice)
48
+ # 2. Male voices:
49
+ # en-US-ChristopherNeural (US)
50
+ # en-US-GuyNeural (US)
51
+ # en-GB-RyanNeural (British)
52
+ # en-AU-WilliamNeural (Australian)
53
+ voice = "en-US-ChristopherNeural"
54
+
55
+ # Generate audio using edge-tts
56
+ communicate = edge_tts.Communicate(response_text, voice)
57
+ await communicate.save(audio_path)
58
+
59
+ # Clean up old audio files
60
+ for file in os.listdir("static"):
61
+ if file.startswith("response_") and file != audio_filename:
62
+ try:
63
+ os.remove(os.path.join("static", file))
64
+ except:
65
+ pass
66
+
67
+ return JSONResponse(
68
+ {"text": response_text, "audio_url": f"/static/{audio_filename}?t={timestamp}"}
69
+ )
70
+
71
+
72
+ # Run with: uvicorn app:app --reload
73
+ if __name__ == "__main__":
74
+ uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ google-generativeai
2
+ gtts
3
+ python-dotenv
4
+ fastapi
5
+ uvicorn
6
+ python-multipart
7
+ jinja2
8
+ edge-tts
static/default.png ADDED

Git LFS Details

  • SHA256: 1160da8d26ed4ed79b6725b0dccdf889adbfd0e9366ca29bb91e5059ff8582d9
  • Pointer size: 132 Bytes
  • Size of remote file: 2.04 MB
static/speaking.png ADDED

Git LFS Details

  • SHA256: b68530b8bcde4dcf76dc7e9b43689499e7f2b51ae46b46b276ee966048de1d16
  • Pointer size: 132 Bytes
  • Size of remote file: 2.09 MB
static/speaking_1.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:06439706bf69ff8413943de1a270efd09226d67bd3cbcc32d191d8a2fe4da02b
3
+ size 5111986
static/speaking_2.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:35c7578ff5163d183f8b04a7e7c1efbe6956db17b6143e1a5b1b8949d607e158
3
+ size 4739934
templates/index.html ADDED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Divine Talk</title>
5
+ <link
6
+ href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;600&family=Open+Sans:wght@400;600&display=swap"
7
+ rel="stylesheet"
8
+ />
9
+ <style>
10
+ :root {
11
+ --primary-color: #7c5f45;
12
+ --secondary-color: #f5e6d3;
13
+ --text-color: #2c2c2c;
14
+ --background-color: #faf6f0;
15
+ --chat-bubble-user: #e3f2fd;
16
+ --chat-bubble-bot: #fff;
17
+ }
18
+
19
+ body {
20
+ font-family: "Open Sans", sans-serif;
21
+ background-color: var(--background-color);
22
+ margin: 0;
23
+ padding: 0;
24
+ color: var(--text-color);
25
+ height: 100vh;
26
+ display: flex;
27
+ flex-direction: column;
28
+ }
29
+
30
+ .container {
31
+ max-width: 800px;
32
+ margin: 0 auto;
33
+ padding: 1rem;
34
+ display: flex;
35
+ flex-direction: column;
36
+ width: 100%;
37
+ height: 100%;
38
+ }
39
+
40
+ .header {
41
+ text-align: center;
42
+ padding: 1rem;
43
+ background-color: white;
44
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
45
+ position: sticky;
46
+ top: 0;
47
+ z-index: 100;
48
+ }
49
+
50
+ .header h1 {
51
+ font-family: "Cormorant Garamond", serif;
52
+ font-size: 2rem;
53
+ color: var(--primary-color);
54
+ margin: 0;
55
+ }
56
+
57
+ .chat-interface {
58
+ margin-top: 0;
59
+ position: relative;
60
+ z-index: 1;
61
+ display: flex;
62
+ gap: 2rem;
63
+ flex-grow: 1;
64
+ margin-top: 2rem;
65
+ }
66
+
67
+ .image-container {
68
+ flex: 0 0 300px;
69
+ position: sticky;
70
+ top: 100px;
71
+ align-self: flex-start;
72
+ }
73
+
74
+ .image-container img,
75
+ .image-container video {
76
+ width: 100%;
77
+ border-radius: 15px;
78
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
79
+ }
80
+
81
+ .chat-container {
82
+ flex: 1;
83
+ display: flex;
84
+ flex-direction: column;
85
+ background: white;
86
+ border-radius: 15px;
87
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
88
+ max-width: 800px;
89
+ margin: 0 auto;
90
+ width: 100%;
91
+ position: relative;
92
+ z-index: 2;
93
+ }
94
+
95
+ .chat-messages {
96
+ flex-grow: 1;
97
+ padding: 1.5rem;
98
+ overflow-y: auto;
99
+ max-height: 60vh;
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: 1rem;
103
+ }
104
+
105
+ .message {
106
+ max-width: 80%;
107
+ padding: 1rem;
108
+ border-radius: 15px;
109
+ position: relative;
110
+ animation: fadeIn 0.3s ease;
111
+ }
112
+
113
+ .message.user {
114
+ background-color: var(--chat-bubble-user);
115
+ align-self: flex-end;
116
+ border-bottom-right-radius: 5px;
117
+ }
118
+
119
+ .message.bot {
120
+ background-color: var(--chat-bubble-bot);
121
+ align-self: flex-start;
122
+ border-bottom-left-radius: 5px;
123
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
124
+ }
125
+
126
+ .input-container {
127
+ padding: 1rem;
128
+ border-top: 1px solid #eee;
129
+ display: flex;
130
+ gap: 1rem;
131
+ align-items: center;
132
+ background: white;
133
+ border-radius: 0 0 15px 15px;
134
+ }
135
+
136
+ textarea {
137
+ flex-grow: 1;
138
+ padding: 0.8rem;
139
+ border: 2px solid var(--secondary-color);
140
+ border-radius: 25px;
141
+ font-size: 1rem;
142
+ resize: none;
143
+ height: 24px;
144
+ min-height: 24px;
145
+ max-height: 24px;
146
+ line-height: 24px;
147
+ font-family: "Open Sans", sans-serif;
148
+ transition: all 0.3s ease;
149
+ overflow-y: hidden;
150
+ }
151
+
152
+ textarea:focus {
153
+ outline: none;
154
+ border-color: var(--primary-color);
155
+ }
156
+
157
+ button {
158
+ background-color: var(--primary-color);
159
+ color: white;
160
+ border: none;
161
+ padding: 0.8rem 1.5rem;
162
+ border-radius: 25px;
163
+ font-size: 1rem;
164
+ cursor: pointer;
165
+ transition: background-color 0.3s ease;
166
+ font-weight: 600;
167
+ white-space: nowrap;
168
+ }
169
+
170
+ button:hover {
171
+ background-color: #6a503a;
172
+ }
173
+
174
+ button:disabled {
175
+ background-color: #cccccc;
176
+ cursor: not-allowed;
177
+ }
178
+
179
+ .loading {
180
+ display: none;
181
+ padding: 1rem;
182
+ text-align: center;
183
+ color: var(--primary-color);
184
+ }
185
+
186
+ .loading::after {
187
+ content: "...";
188
+ animation: dots 1.5s steps(5, end) infinite;
189
+ }
190
+
191
+ @keyframes dots {
192
+ 0%,
193
+ 20% {
194
+ content: ".";
195
+ }
196
+ 40% {
197
+ content: "..";
198
+ }
199
+ 60%,
200
+ 100% {
201
+ content: "...";
202
+ }
203
+ }
204
+
205
+ @keyframes fadeIn {
206
+ from {
207
+ opacity: 0;
208
+ transform: translateY(10px);
209
+ }
210
+ to {
211
+ opacity: 1;
212
+ transform: translateY(0);
213
+ }
214
+ }
215
+
216
+ @media (max-width: 768px) {
217
+ .chat-interface {
218
+ flex-direction: column;
219
+ }
220
+
221
+ .image-container {
222
+ position: static;
223
+ max-width: 200px;
224
+ margin: 0 auto;
225
+ }
226
+
227
+ .message {
228
+ max-width: 90%;
229
+ }
230
+ }
231
+
232
+ .video-overlay {
233
+ position: fixed;
234
+ top: 50%;
235
+ left: 50%;
236
+ transform: translate(-50%, -50%);
237
+ width: 1000px;
238
+ height: 540px;
239
+ z-index: 1;
240
+ display: none;
241
+ background: rgba(255, 255, 255, 0.9);
242
+ border-radius: 15px;
243
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
244
+ transition: all 0.3s ease;
245
+ }
246
+
247
+ .video-overlay video {
248
+ width: 100%;
249
+ height: 100%;
250
+ border-radius: 15px;
251
+ object-fit: cover;
252
+ }
253
+
254
+ .chat-container {
255
+ flex: 1;
256
+ max-width: 800px;
257
+ margin: 0 auto;
258
+ width: 100%;
259
+ }
260
+
261
+ .chat-interface {
262
+ gap: 0;
263
+ }
264
+
265
+ @media (max-width: 768px) {
266
+ .video-overlay {
267
+ width: 300px;
268
+ height: 300px;
269
+ }
270
+ }
271
+
272
+ @media (max-width: 480px) {
273
+ .video-overlay {
274
+ width: 250px;
275
+ height: 250px;
276
+ }
277
+ }
278
+
279
+ @keyframes fadeInScale {
280
+ from {
281
+ opacity: 0;
282
+ transform: translate(-50%, -40%);
283
+ scale: 0.8;
284
+ }
285
+ to {
286
+ opacity: 1;
287
+ transform: translate(-50%, -50%);
288
+ scale: 1;
289
+ }
290
+ }
291
+
292
+ .video-overlay.active {
293
+ display: block;
294
+ animation: fadeInScale 0.3s ease forwards;
295
+ }
296
+ </style>
297
+ </head>
298
+ <body>
299
+ <div class="header">
300
+ <h1>Divine Talk</h1>
301
+ </div>
302
+
303
+ <div class="container">
304
+ <div class="chat-interface">
305
+ <div class="chat-container">
306
+ <div id="chatMessages" class="chat-messages">
307
+ <div class="message bot">
308
+ Peace be with you. How may I guide you today?
309
+ </div>
310
+ </div>
311
+
312
+ <div id="loading" class="loading">Receiving wisdom</div>
313
+
314
+ <div class="input-container">
315
+ <textarea
316
+ id="userInput"
317
+ placeholder="What would you like to ask?"
318
+ rows="1"
319
+ aria-label="Your message"
320
+ ></textarea>
321
+ <button onclick="processInput()">Ask in Faith</button>
322
+ </div>
323
+ </div>
324
+ </div>
325
+ <div id="videoOverlay" class="video-overlay">
326
+ <video id="displayVideo" autoplay muted loop>
327
+ <source src="" type="video/mp4" />
328
+ </video>
329
+ </div>
330
+ <audio id="responseAudio" style="display: none"></audio>
331
+ </div>
332
+
333
+ <script>
334
+ const textarea = document.getElementById("userInput");
335
+ const chatMessages = document.getElementById("chatMessages");
336
+
337
+ // Remove the auto-resize event listener and replace with character limit
338
+ textarea.addEventListener("input", function () {
339
+ // Optional: Add character limit if needed
340
+ const maxLength = 200; // or whatever limit you want
341
+ if (this.value.length > maxLength) {
342
+ this.value = this.value.slice(0, maxLength);
343
+ }
344
+ });
345
+
346
+ function addMessage(text, isUser) {
347
+ const messageDiv = document.createElement("div");
348
+ messageDiv.className = `message ${isUser ? "user" : "bot"}`;
349
+ messageDiv.textContent = text;
350
+ chatMessages.appendChild(messageDiv);
351
+ chatMessages.scrollTop = chatMessages.scrollHeight;
352
+ }
353
+
354
+ function getRandomSpeakingVideo() {
355
+ const videos = ["/static/speaking_1.mp4", "/static/speaking_2.mp4"];
356
+ const randomIndex = Math.floor(Math.random() * videos.length);
357
+ return videos[randomIndex];
358
+ }
359
+
360
+ function processInput() {
361
+ const userInput = document.getElementById("userInput").value;
362
+ if (!userInput.trim()) return;
363
+
364
+ addMessage(userInput, true);
365
+
366
+ const loading = document.getElementById("loading");
367
+ const button = document.querySelector("button");
368
+ loading.style.display = "block";
369
+ button.disabled = true;
370
+
371
+ const formData = new FormData();
372
+ formData.append("text", userInput);
373
+
374
+ textarea.value = "";
375
+ textarea.style.height = "24px";
376
+
377
+ fetch("/process", {
378
+ method: "POST",
379
+ body: formData,
380
+ })
381
+ .then((response) => response.json())
382
+ .then((data) => {
383
+ addMessage(data.text, false);
384
+
385
+ const audio = document.getElementById("responseAudio");
386
+ const newAudio = audio.cloneNode(true);
387
+ newAudio.src = data.audio_url;
388
+ audio.parentNode.replaceChild(newAudio, audio);
389
+
390
+ const videoOverlay = document.getElementById("videoOverlay");
391
+ const video = document.getElementById("displayVideo");
392
+
393
+ newAudio.onplay = function () {
394
+ // Show and play random video
395
+ video.src = getRandomSpeakingVideo();
396
+ video.play();
397
+ videoOverlay.classList.add("active");
398
+ };
399
+
400
+ newAudio.onended = function () {
401
+ // Hide video overlay
402
+ videoOverlay.classList.remove("active");
403
+ setTimeout(() => {
404
+ video.src = ""; // Clear video source after animation
405
+ }, 300);
406
+ };
407
+
408
+ newAudio.play();
409
+ })
410
+ .finally(() => {
411
+ loading.style.display = "none";
412
+ button.disabled = false;
413
+ });
414
+ }
415
+
416
+ // Allow Enter key to submit
417
+ textarea.addEventListener("keypress", function (e) {
418
+ if (e.key === "Enter" && !e.shiftKey) {
419
+ e.preventDefault();
420
+ processInput();
421
+ }
422
+ });
423
+ </script>
424
+ </body>
425
+ </html>