Scaryscar commited on
Commit
fa3aac3
·
verified ·
1 Parent(s): 281bbfe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +406 -0
app.py CHANGED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import random
3
+ import torch
4
+ from flask import Flask, render_template, request, jsonify, session
5
+ from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
6
+ import threading
7
+ import json
8
+ from datetime import datetime
9
+
10
+ app = Flask(__name__)
11
+ app.secret_key = os.environ.get('SESSION_SECRET', 'fortune-secret-key-2024')
12
+ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
13
+
14
+ # Game configuration
15
+ FORTUNE_TYPES = {
16
+ "love": ["romance", "relationships", "soulmate", "passion", "connection"],
17
+ "career": ["work", "job", "promotion", "business", "success"],
18
+ "health": ["wellness", "fitness", "energy", "vitality", "recovery"],
19
+ "wealth": ["money", "finance", "abundance", "prosperity", "investment"],
20
+ "general": ["future", "destiny", "path", "journey", "opportunities"]
21
+ }
22
+
23
+ TAROT_CARDS = [
24
+ "The Fool", "The Magician", "The High Priestess", "The Empress", "The Emperor",
25
+ "The Hierophant", "The Lovers", "The Chariot", "Strength", "The Hermit",
26
+ "Wheel of Fortune", "Justice", "The Hanged Man", "Death", "Temperance",
27
+ "The Devil", "The Tower", "The Star", "The Moon", "The Sun", "Judgement", "The World"
28
+ ]
29
+
30
+ ZODIAC_SIGNS = [
31
+ "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
32
+ "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"
33
+ ]
34
+
35
+ # Initialize model (loaded once at startup)
36
+ model = None
37
+ tokenizer = None
38
+ generator = None
39
+ model_lock = threading.Lock()
40
+
41
+ def load_model():
42
+ """Load the model with GPU support"""
43
+ global model, tokenizer, generator
44
+
45
+ try:
46
+ print("Loading model...")
47
+
48
+ # Using a smaller model that's good for creative text generation
49
+ model_name = "microsoft/DialoGPT-small"
50
+
51
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
52
+ model = AutoModelForCausalLM.from_pretrained(
53
+ model_name,
54
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
55
+ device_map="auto" if torch.cuda.is_available() else None
56
+ )
57
+
58
+ if torch.cuda.is_available():
59
+ model = model.cuda()
60
+ print(f"Model loaded on GPU: {torch.cuda.get_device_name(0)}")
61
+ else:
62
+ print("Model loaded on CPU")
63
+
64
+ # Create text generation pipeline
65
+ generator = pipeline(
66
+ "text-generation",
67
+ model=model,
68
+ tokenizer=tokenizer,
69
+ device=0 if torch.cuda.is_available() else -1
70
+ )
71
+
72
+ print("Model loaded successfully!")
73
+ return True
74
+
75
+ except Exception as e:
76
+ print(f"Error loading model: {str(e)}")
77
+ return False
78
+
79
+ def generate_fortune(fortune_type, user_input=""):
80
+ """Generate a fortune based on type and user input"""
81
+
82
+ # Base prompts for different fortune types
83
+ prompts = {
84
+ "love": f"Generate a romantic fortune prediction about love and relationships. {user_input}",
85
+ "career": f"Generate a professional fortune prediction about career and success. {user_input}",
86
+ "health": f"Generate a health-related fortune prediction about wellness. {user_input}",
87
+ "wealth": f"Generate a financial fortune prediction about money and prosperity. {user_input}",
88
+ "general": f"Generate a general fortune prediction about life and future. {user_input}"
89
+ }
90
+
91
+ # Select random tarot card and zodiac sign
92
+ tarot_card = random.choice(TAROT_CARDS)
93
+ zodiac_sign = random.choice(ZODIAC_SIGNS)
94
+
95
+ try:
96
+ with model_lock:
97
+ if generator:
98
+ # Generate fortune text
99
+ prompt_text = prompts.get(fortune_type, prompts["general"])
100
+ full_prompt = f"As a fortune teller, {prompt_text} Mention {tarot_card} tarot card and {zodiac_sign} zodiac sign in the reading."
101
+
102
+ generated = generator(
103
+ full_prompt,
104
+ max_length=200,
105
+ num_return_sequences=1,
106
+ temperature=0.9,
107
+ top_p=0.95,
108
+ do_sample=True,
109
+ pad_token_id=tokenizer.eos_token_id
110
+ )
111
+
112
+ fortune_text = generated[0]['generated_text']
113
+
114
+ # Extract just the generated part (remove prompt)
115
+ if fortune_text.startswith(full_prompt):
116
+ fortune_text = fortune_text[len(full_prompt):].strip()
117
+
118
+ else:
119
+ # Fallback fortunes if model fails
120
+ fallback_fortunes = [
121
+ f"The {tarot_card} card reveals new opportunities coming your way. As a {zodiac_sign}, embrace the changes ahead.",
122
+ f"{tarot_card} guides your path. Your {zodiac_sign} energy brings luck in unexpected places.",
123
+ f"Through {tarot_card}'s wisdom, your {zodiac_sign} spirit will find the answers you seek.",
124
+ f"The stars align with {tarot_card}. As a {zodiac_sign}, trust your intuition in matters of the heart.",
125
+ f"{tarot_card} whispers secrets of prosperity. Your {zodiac_sign} nature attracts abundance."
126
+ ]
127
+ fortune_text = random.choice(fallback_fortunes)
128
+
129
+ except Exception as e:
130
+ print(f"Error generating fortune: {str(e)}")
131
+ fortune_text = f"The {tarot_card} card appears in your reading. As a {zodiac_sign}, the universe has mysterious plans for you. Trust the journey."
132
+
133
+ # Create fortune object
134
+ fortune = {
135
+ "text": fortune_text,
136
+ "type": fortune_type,
137
+ "tarot_card": tarot_card,
138
+ "zodiac_sign": zodiac_sign,
139
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
140
+ "lucky_number": random.randint(1, 99),
141
+ "color": random.choice(["Red", "Blue", "Green", "Gold", "Purple", "Silver"]),
142
+ "element": random.choice(["Fire", "Water", "Earth", "Air", "Spirit"])
143
+ }
144
+
145
+ return fortune
146
+
147
+ def generate_crystal_ball_reading():
148
+ """Generate a special crystal ball reading"""
149
+ crystals = ["Amethyst", "Quartz", "Emerald", "Sapphire", "Ruby", "Diamond", "Opal"]
150
+ visions = [
151
+ "A long journey brings new friendships",
152
+ "Financial windfall appears on the horizon",
153
+ "Unexpected news changes everything",
154
+ "A secret admirer reveals themselves",
155
+ "Creative projects bring great success",
156
+ "Family matters require your attention",
157
+ "Travel plans lead to enlightenment"
158
+ ]
159
+
160
+ return {
161
+ "crystal": random.choice(crystals),
162
+ "vision": random.choice(visions),
163
+ "clarity": random.randint(1, 100),
164
+ "energy": random.choice(["High", "Medium", "Low", "Fluctuating"])
165
+ }
166
+
167
+ @app.before_first_request
168
+ def initialize():
169
+ """Initialize model before first request"""
170
+ load_model()
171
+
172
+ @app.route('/')
173
+ def index():
174
+ """Render the main page"""
175
+ return """
176
+ <!DOCTYPE html>
177
+ <html>
178
+ <head>
179
+ <title>Fortune Teller 🔮</title>
180
+ <style>
181
+ body {
182
+ background: linear-gradient(135deg, #1a0b2e 0%, #0d0630 100%);
183
+ color: #e0d6ff;
184
+ font-family: Arial, sans-serif;
185
+ margin: 0;
186
+ padding: 20px;
187
+ }
188
+ .container {
189
+ max-width: 800px;
190
+ margin: 0 auto;
191
+ text-align: center;
192
+ }
193
+ h1 {
194
+ color: #ffd700;
195
+ margin-bottom: 30px;
196
+ }
197
+ .fortune-types {
198
+ display: flex;
199
+ flex-wrap: wrap;
200
+ gap: 10px;
201
+ justify-content: center;
202
+ margin: 20px 0;
203
+ }
204
+ .fortune-type {
205
+ padding: 10px 20px;
206
+ background: #6a4c93;
207
+ border: none;
208
+ color: white;
209
+ border-radius: 5px;
210
+ cursor: pointer;
211
+ }
212
+ .fortune-type:hover {
213
+ background: #8a6cbb;
214
+ }
215
+ #question {
216
+ width: 100%;
217
+ padding: 10px;
218
+ margin: 20px 0;
219
+ background: rgba(255,255,255,0.1);
220
+ border: 1px solid #6a4c93;
221
+ color: white;
222
+ border-radius: 5px;
223
+ }
224
+ #generate {
225
+ padding: 15px 30px;
226
+ background: #ffd700;
227
+ border: none;
228
+ border-radius: 5px;
229
+ font-size: 16px;
230
+ cursor: pointer;
231
+ margin: 10px 0;
232
+ }
233
+ #result {
234
+ margin-top: 30px;
235
+ padding: 20px;
236
+ background: rgba(0,0,0,0.3);
237
+ border-radius: 10px;
238
+ text-align: left;
239
+ }
240
+ </style>
241
+ </head>
242
+ <body>
243
+ <div class="container">
244
+ <h1>🔮 Mystic Fortune Teller 🔮</h1>
245
+ <div>Select a fortune type and ask your question:</div>
246
+
247
+ <div class="fortune-types">
248
+ <button class="fortune-type" onclick="selectType('love')">💖 Love</button>
249
+ <button class="fortune-type" onclick="selectType('career')">💼 Career</button>
250
+ <button class="fortune-type" onclick="selectType('health')">🏥 Health</button>
251
+ <button class="fortune-type" onclick="selectType('wealth')">💰 Wealth</button>
252
+ <button class="fortune-type" onclick="selectType('general')">✨ General</button>
253
+ </div>
254
+
255
+ <textarea id="question" placeholder="Ask your question here... (optional)" rows="3"></textarea>
256
+ <br>
257
+ <button id="generate" onclick="generateFortune()">Generate Fortune</button>
258
+
259
+ <div id="result"></div>
260
+ <div id="loading" style="display:none;">Generating fortune... 🔮</div>
261
+ </div>
262
+
263
+ <script>
264
+ let selectedType = 'general';
265
+
266
+ function selectType(type) {
267
+ selectedType = type;
268
+ document.querySelectorAll('.fortune-type').forEach(btn => {
269
+ btn.style.background = '#6a4c93';
270
+ });
271
+ event.target.style.background = '#ff6b6b';
272
+ }
273
+
274
+ function generateFortune() {
275
+ const question = document.getElementById('question').value;
276
+ const loading = document.getElementById('loading');
277
+ const result = document.getElementById('result');
278
+
279
+ loading.style.display = 'block';
280
+ result.innerHTML = '';
281
+
282
+ fetch('/api/generate-fortune', {
283
+ method: 'POST',
284
+ headers: {
285
+ 'Content-Type': 'application/json',
286
+ },
287
+ body: JSON.stringify({
288
+ type: selectedType,
289
+ question: question
290
+ })
291
+ })
292
+ .then(response => response.json())
293
+ .then(data => {
294
+ loading.style.display = 'none';
295
+ if (data.success) {
296
+ const fortune = data.fortune;
297
+ result.innerHTML = `
298
+ <h3>Your Fortune 🔮</h3>
299
+ <p>${fortune.text}</p>
300
+ <hr>
301
+ <div>
302
+ <strong>Tarot Card:</strong> ${fortune.tarot_card}<br>
303
+ <strong>Zodiac Sign:</strong> ${fortune.zodiac_sign}<br>
304
+ <strong>Lucky Number:</strong> ${fortune.lucky_number}<br>
305
+ <strong>Lucky Color:</strong> ${fortune.color}<br>
306
+ <strong>Element:</strong> ${fortune.element}<br>
307
+ <small>${fortune.timestamp}</small>
308
+ </div>
309
+ `;
310
+ } else {
311
+ result.innerHTML = `<p style="color:red;">Error: ${data.error}</p>`;
312
+ }
313
+ })
314
+ .catch(error => {
315
+ loading.style.display = 'none';
316
+ result.innerHTML = `<p style="color:red;">Error: ${error}</p>`;
317
+ });
318
+ }
319
+ </script>
320
+ </body>
321
+ </html>
322
+ """
323
+
324
+ @app.route('/api/generate-fortune', methods=['POST'])
325
+ def api_generate_fortune():
326
+ """API endpoint to generate fortune"""
327
+ try:
328
+ data = request.get_json()
329
+ fortune_type = data.get('type', 'general')
330
+ user_question = data.get('question', '')
331
+
332
+ if fortune_type not in FORTUNE_TYPES:
333
+ fortune_type = 'general'
334
+
335
+ # Generate fortune
336
+ fortune = generate_fortune(fortune_type, user_question)
337
+
338
+ # Add crystal ball reading for special effect
339
+ if random.random() > 0.7: # 30% chance
340
+ fortune['crystal_ball'] = generate_crystal_ball_reading()
341
+
342
+ # Store in session (last 5 fortunes)
343
+ if 'fortunes' not in session:
344
+ session['fortunes'] = []
345
+
346
+ session['fortunes'] = [fortune] + session['fortunes'][:4]
347
+ session.modified = True
348
+
349
+ return jsonify({
350
+ 'success': True,
351
+ 'fortune': fortune,
352
+ 'gpu_enabled': torch.cuda.is_available()
353
+ })
354
+
355
+ except Exception as e:
356
+ return jsonify({
357
+ 'success': False,
358
+ 'error': str(e)
359
+ }), 500
360
+
361
+ @app.route('/api/history', methods=['GET'])
362
+ def api_history():
363
+ """Get fortune history"""
364
+ fortunes = session.get('fortunes', [])
365
+ return jsonify({
366
+ 'success': True,
367
+ 'fortunes': fortunes,
368
+ 'count': len(fortunes)
369
+ })
370
+
371
+ @app.route('/api/clear-history', methods=['POST'])
372
+ def api_clear_history():
373
+ """Clear fortune history"""
374
+ session['fortunes'] = []
375
+ session.modified = True
376
+ return jsonify({'success': True})
377
+
378
+ @app.route('/api/system-info', methods=['GET'])
379
+ def api_system_info():
380
+ """Get system information"""
381
+ return jsonify({
382
+ 'gpu_available': torch.cuda.is_available(),
383
+ 'gpu_name': torch.cuda.get_device_name(0) if torch.cuda.is_available() else None,
384
+ 'model_loaded': model is not None,
385
+ 'python_version': os.sys.version
386
+ })
387
+
388
+ @app.route('/health')
389
+ def health_check():
390
+ """Health check endpoint"""
391
+ return jsonify({
392
+ 'status': 'healthy',
393
+ 'model_loaded': model is not None,
394
+ 'gpu': torch.cuda.is_available()
395
+ })
396
+
397
+ if __name__ == '__main__':
398
+ # Load model at startup
399
+ load_model()
400
+
401
+ # Run the app
402
+ app.run(
403
+ host='0.0.0.0',
404
+ port=int(os.environ.get('PORT', 5000)),
405
+ debug=os.environ.get('DEBUG', 'False').lower() == 'true'
406
+ )