SamiKoen commited on
Commit
109e05b
·
verified ·
1 Parent(s): 4a71b5a

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +78 -13
  2. enhanced_features.py +305 -0
  3. requirements.txt +1 -1
app.py CHANGED
@@ -22,6 +22,12 @@ warnings.simplefilter('ignore', InsecureRequestWarning)
22
  # Prompt dosyasını import et
23
  from prompts import get_prompt_content_only
24
 
 
 
 
 
 
 
25
  # Gradio uyarılarını bastır
26
  warnings.filterwarnings("ignore", category=UserWarning, module="gradio.components.chatbot")
27
 
@@ -181,6 +187,9 @@ print(f"Toplam {len(products)} ürün yüklendi")
181
  if products:
182
  print(f"İlk ürün örneği: {products[0]}")
183
 
 
 
 
184
  # Hugging Face token
185
  hfapi = os.getenv("hfapi")
186
  if not hfapi:
@@ -303,10 +312,32 @@ def run_scheduler(chat_history_ref):
303
  time.sleep(60)
304
 
305
  @spaces.GPU(duration=1200)
306
- def chatbot_fn(user_message, history):
307
  if history is None:
308
  history = []
309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  # Log: Kullanıcı mesajını ekle
311
  try:
312
  with file_lock:
@@ -554,18 +585,52 @@ document.addEventListener('DOMContentLoaded', function() {
554
  """
555
 
556
 
557
- # Demo arayüzüne CSS'i ekleyin
558
- demo = gr.ChatInterface(
559
- fn=chat_fn,
560
- title="Trek Asistanı",
561
- theme="soft",
562
- type="messages",
563
- flagging_mode="manual",
564
- flagging_options=["Doğru", "Yanlış", "Emin değilim", "Diğer"],
565
- save_history=True,
566
- autoscroll=True,
567
- css=custom_css
568
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
 
570
  if __name__ == "__main__":
571
  demo.launch(debug=True)
 
22
  # Prompt dosyasını import et
23
  from prompts import get_prompt_content_only
24
 
25
+ # Enhanced features import et
26
+ from enhanced_features import (
27
+ initialize_enhanced_features, process_image_message,
28
+ handle_comparison_request, get_user_recommendations, profile_manager
29
+ )
30
+
31
  # Gradio uyarılarını bastır
32
  warnings.filterwarnings("ignore", category=UserWarning, module="gradio.components.chatbot")
33
 
 
187
  if products:
188
  print(f"İlk ürün örneği: {products[0]}")
189
 
190
+ # Enhanced features'ları başlat
191
+ initialize_enhanced_features(OPENAI_API_KEY, products)
192
+
193
  # Hugging Face token
194
  hfapi = os.getenv("hfapi")
195
  if not hfapi:
 
312
  time.sleep(60)
313
 
314
  @spaces.GPU(duration=1200)
315
+ def chatbot_fn(user_message, history, image=None):
316
  if history is None:
317
  history = []
318
 
319
+ # Enhanced features - Görsel işleme
320
+ if image is not None:
321
+ user_message = process_image_message(image, user_message)
322
+
323
+ # Enhanced features - Karşılaştırma kontrolü
324
+ comparison_result = handle_comparison_request(user_message)
325
+ if comparison_result:
326
+ yield comparison_result
327
+ return
328
+
329
+ # Enhanced features - Kişisel öneriler
330
+ user_id = "default_user" # Gerçek uygulamada session ID kullanılır
331
+ recommendation_result = get_user_recommendations(user_id, user_message)
332
+ if recommendation_result:
333
+ # Kullanıcı etkileşimini kaydet
334
+ profile_manager.add_interaction(user_id, "recommendation_request", {
335
+ "message": user_message,
336
+ "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
337
+ })
338
+ yield recommendation_result
339
+ return
340
+
341
  # Log: Kullanıcı mesajını ekle
342
  try:
343
  with file_lock:
 
585
  """
586
 
587
 
588
+ # Enhanced chatbot fonksiyonu image destekli
589
+ def enhanced_chatbot_fn(message, history, image):
590
+ return chatbot_fn(message, history, image)
591
+
592
+ # Demo arayüzü - Özel layout ile image upload destekli
593
+ with gr.Blocks(css=custom_css, theme="soft", title="Trek Asistanı") as demo:
594
+ gr.Markdown("# 🚲 Trek Asistanı AI")
595
+ gr.Markdown("**Yeni özellikler:** Bisiklet fotoğrafı yükleyebilir, ürün karşılaştırması yapabilir ve kişisel öneriler alabilirsiniz!")
596
+
597
+ with gr.Row():
598
+ with gr.Column(scale=4):
599
+ chatbot = gr.Chatbot(height=500)
600
+
601
+ with gr.Column(scale=1):
602
+ gr.Markdown("### 🖼️ Bisiklet Fotoğrafı")
603
+ image_input = gr.Image(type="filepath", height=200)
604
+ gr.Markdown("### 🔍 Özel Komutlar")
605
+ gr.Markdown("""
606
+ • **Karşılaştırma:** "Émonda ve Madone karşılaştır"
607
+ • **Bütçe:** "50-100K TL bütçem var"
608
+ • **Görsel:** Bisiklet fotoğrafı yükle
609
+ """)
610
+
611
+ with gr.Row():
612
+ msg = gr.Textbox(
613
+ placeholder="Sorunuzu yazın veya fotoğraf yükleyip analiz isteyin...",
614
+ show_label=False,
615
+ scale=4
616
+ )
617
+ submit_btn = gr.Button("Gönder", scale=1)
618
+
619
+ def respond(message, chat_history, image):
620
+ # Enhanced chatbot fonksiyonunu çağır
621
+ response_generator = chatbot_fn(message, chat_history, image)
622
+
623
+ # Generator'dan son cevabı al
624
+ response = ""
625
+ for partial in response_generator:
626
+ response = partial
627
+
628
+ # Chat history güncelle
629
+ chat_history.append((message, response))
630
+ return "", chat_history, None
631
+
632
+ submit_btn.click(respond, [msg, chatbot, image_input], [msg, chatbot, image_input])
633
+ msg.submit(respond, [msg, chatbot, image_input], [msg, chatbot, image_input])
634
 
635
  if __name__ == "__main__":
636
  demo.launch(debug=True)
enhanced_features.py ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Trek Chatbot Enhanced Features
4
+ 1. Görsel AI Entegrasyonu
5
+ 2. Kişiselleştirilmiş Öneri Motoru
6
+ 3. Gelişmiş Ürün Karşılaştırma
7
+ """
8
+
9
+ import os
10
+ import json
11
+ import base64
12
+ import requests
13
+ from datetime import datetime
14
+ import pandas as pd
15
+
16
+ # Kullanıcı profili dosyası
17
+ USER_PROFILES_FILE = "user_profiles.json"
18
+
19
+ class UserProfileManager:
20
+ """Kullanıcı profili yönetimi"""
21
+
22
+ def __init__(self):
23
+ self.profiles = self.load_profiles()
24
+
25
+ def load_profiles(self):
26
+ """Kullanıcı profillerini yükle"""
27
+ if os.path.exists(USER_PROFILES_FILE):
28
+ with open(USER_PROFILES_FILE, 'r', encoding='utf-8') as f:
29
+ return json.load(f)
30
+ return {}
31
+
32
+ def save_profiles(self):
33
+ """Kullanıcı profillerini kaydet"""
34
+ with open(USER_PROFILES_FILE, 'w', encoding='utf-8') as f:
35
+ json.dump(self.profiles, f, ensure_ascii=False, indent=2)
36
+
37
+ def get_or_create_profile(self, user_id="default_user"):
38
+ """Kullanıcı profili al veya oluştur"""
39
+ if user_id not in self.profiles:
40
+ self.profiles[user_id] = {
41
+ "created_at": datetime.now().isoformat(),
42
+ "preferences": {
43
+ "budget_range": None,
44
+ "bike_category": None,
45
+ "size": None,
46
+ "usage_purpose": None
47
+ },
48
+ "interaction_history": [],
49
+ "favorite_products": [],
50
+ "viewed_products": []
51
+ }
52
+ return self.profiles[user_id]
53
+
54
+ def update_user_preference(self, user_id, key, value):
55
+ """Kullanıcı tercihini güncelle"""
56
+ profile = self.get_or_create_profile(user_id)
57
+ profile["preferences"][key] = value
58
+ self.save_profiles()
59
+
60
+ def add_interaction(self, user_id, interaction_type, data):
61
+ """Kullanıcı etkileşimi ekle"""
62
+ profile = self.get_or_create_profile(user_id)
63
+ interaction = {
64
+ "timestamp": datetime.now().isoformat(),
65
+ "type": interaction_type,
66
+ "data": data
67
+ }
68
+ profile["interaction_history"].append(interaction)
69
+ # Son 50 etkileşimi tut
70
+ profile["interaction_history"] = profile["interaction_history"][-50:]
71
+ self.save_profiles()
72
+
73
+ class VisualAI:
74
+ """Görsel AI işlemleri"""
75
+
76
+ def __init__(self, openai_api_key):
77
+ self.api_key = openai_api_key
78
+
79
+ def analyze_bike_image(self, image_path):
80
+ """Bisiklet görselini analiz et"""
81
+ if not self.api_key:
82
+ return "Görsel analiz için OpenAI API key gerekli."
83
+
84
+ try:
85
+ # Görseli base64'e çevir
86
+ with open(image_path, "rb") as image_file:
87
+ base64_image = base64.b64encode(image_file.read()).decode('utf-8')
88
+
89
+ headers = {
90
+ "Content-Type": "application/json",
91
+ "Authorization": f"Bearer {self.api_key}"
92
+ }
93
+
94
+ payload = {
95
+ "model": "gpt-4-vision-preview",
96
+ "messages": [
97
+ {
98
+ "role": "user",
99
+ "content": [
100
+ {
101
+ "type": "text",
102
+ "text": "Bu bisiklet görselini analiz et. Hangi tip bisiklet? Marka, model tahmininde bulun. Trek bisikletleri hakkında uzmanısın."
103
+ },
104
+ {
105
+ "type": "image_url",
106
+ "image_url": {
107
+ "url": f"data:image/jpeg;base64,{base64_image}"
108
+ }
109
+ }
110
+ ]
111
+ }
112
+ ],
113
+ "max_tokens": 300
114
+ }
115
+
116
+ response = requests.post("https://api.openai.com/v1/chat/completions",
117
+ headers=headers, json=payload)
118
+
119
+ if response.status_code == 200:
120
+ result = response.json()
121
+ return result["choices"][0]["message"]["content"]
122
+ else:
123
+ return f"Görsel analiz hatası: {response.status_code}"
124
+
125
+ except Exception as e:
126
+ return f"Görsel analiz hatası: {str(e)}"
127
+
128
+ class ProductComparison:
129
+ """Ürün karşılaştırma sistemi"""
130
+
131
+ def __init__(self, products_data):
132
+ self.products = products_data
133
+
134
+ def find_products_by_name(self, product_names):
135
+ """İsimlere göre ürünleri bul"""
136
+ found_products = []
137
+ for name in product_names:
138
+ for product in self.products:
139
+ if name.lower() in product[2].lower(): # product[2] = full_name
140
+ found_products.append(product)
141
+ break
142
+ return found_products
143
+
144
+ def create_comparison_table(self, product_names):
145
+ """Karşılaştırma tablosu oluştur"""
146
+ products = self.find_products_by_name(product_names)
147
+
148
+ if len(products) < 2:
149
+ return "Karşılaştırma için en az 2 ürün gerekli."
150
+
151
+ # Tablo verilerini hazırla
152
+ comparison_data = []
153
+ for product in products:
154
+ name, item_info, full_name = product
155
+
156
+ # Ürün bilgilerini parse et
157
+ stock_status = item_info[0] if len(item_info) > 0 else "Bilgi yok"
158
+ price = item_info[1] if len(item_info) > 1 and item_info[1] else "Fiyat yok"
159
+ product_link = item_info[2] if len(item_info) > 2 else ""
160
+
161
+ comparison_data.append({
162
+ "Ürün": full_name,
163
+ "Stok": stock_status,
164
+ "Fiyat": f"{price} TL" if price != "Fiyat yok" else price,
165
+ "Link": product_link
166
+ })
167
+
168
+ # DataFrame oluştur
169
+ df = pd.DataFrame(comparison_data)
170
+
171
+ # Markdown tablosu olarak döndür
172
+ return df.to_markdown(index=False)
173
+
174
+ def get_similar_products(self, product_name, category_filter=None):
175
+ """Benzer ürünleri bul"""
176
+ similar_products = []
177
+ base_name = product_name.lower().split()[0] # İlk kelimeyi al
178
+
179
+ for product in self.products:
180
+ product_full_name = product[2].lower()
181
+ if base_name in product_full_name and product_name.lower() != product_full_name:
182
+ if category_filter:
183
+ if category_filter.lower() in product_full_name:
184
+ similar_products.append(product)
185
+ else:
186
+ similar_products.append(product)
187
+
188
+ return similar_products[:5] # İlk 5 benzer ürün
189
+
190
+ class PersonalizedRecommendations:
191
+ """Kişiselleştirilmiş öneriler"""
192
+
193
+ def __init__(self, profile_manager, products_data):
194
+ self.profile_manager = profile_manager
195
+ self.products = products_data
196
+
197
+ def get_budget_recommendations(self, user_id, budget_min, budget_max):
198
+ """Bütçeye uygun öneriler"""
199
+ suitable_products = []
200
+
201
+ for product in self.products:
202
+ if product[1][0] == "stokta" and product[1][1]: # Stokta ve fiyatı var
203
+ try:
204
+ price = float(product[1][1])
205
+ if budget_min <= price <= budget_max:
206
+ suitable_products.append(product)
207
+ except (ValueError, TypeError):
208
+ continue
209
+
210
+ # Kullanıcı tercihlerini kaydet
211
+ self.profile_manager.update_user_preference(user_id, "budget_range", [budget_min, budget_max])
212
+
213
+ return suitable_products[:5] # İlk 5 öneri
214
+
215
+ def get_personalized_suggestions(self, user_id):
216
+ """Geçmiş davranışlara göre öneriler"""
217
+ profile = self.profile_manager.get_or_create_profile(user_id)
218
+ preferences = profile["preferences"]
219
+
220
+ suggestions = []
221
+
222
+ # Bütçe tercihi varsa ona göre filtrele
223
+ if preferences.get("budget_range"):
224
+ budget_min, budget_max = preferences["budget_range"]
225
+ suggestions.extend(self.get_budget_recommendations(user_id, budget_min, budget_max))
226
+
227
+ # Kategori tercihi varsa ona göre filtrele
228
+ if preferences.get("bike_category"):
229
+ category = preferences["bike_category"]
230
+ for product in self.products:
231
+ if category.lower() in product[2].lower() and product[1][0] == "stokta":
232
+ suggestions.append(product)
233
+
234
+ return list(set(suggestions))[:3] # Duplicate'ları kaldır ve ilk 3'ü al
235
+
236
+ # Global instance'lar
237
+ profile_manager = UserProfileManager()
238
+ visual_ai = None # OpenAI key ile başlatılacak
239
+ product_comparison = None # Products data ile başlatılacak
240
+ personalized_recommendations = None # Profile manager ve products ile başlatılacak
241
+
242
+ def initialize_enhanced_features(openai_api_key, products_data):
243
+ """Enhanced özellikleri başlat"""
244
+ global visual_ai, product_comparison, personalized_recommendations
245
+
246
+ visual_ai = VisualAI(openai_api_key)
247
+ product_comparison = ProductComparison(products_data)
248
+ personalized_recommendations = PersonalizedRecommendations(profile_manager, products_data)
249
+
250
+ def process_image_message(image_path, user_message):
251
+ """Görsel mesajını işle"""
252
+ if visual_ai and image_path:
253
+ image_analysis = visual_ai.analyze_bike_image(image_path)
254
+ return f"Görsel Analiz: {image_analysis}\n\nSoru: {user_message}"
255
+ return user_message
256
+
257
+ def handle_comparison_request(user_message):
258
+ """Karşılaştırma talebini işle"""
259
+ if "karşılaştır" in user_message.lower() or "compare" in user_message.lower():
260
+ # Ürün isimlerini çıkarmaya çalış
261
+ words = user_message.lower().split()
262
+ potential_products = []
263
+
264
+ # Bilinen model isimlerini ara
265
+ known_models = ["émonda", "madone", "domane", "marlin", "fuel", "powerfly", "fx"]
266
+ for word in words:
267
+ for model in known_models:
268
+ if model in word:
269
+ potential_products.append(model)
270
+
271
+ if len(potential_products) >= 2:
272
+ comparison_table = product_comparison.create_comparison_table(potential_products)
273
+ return f"Ürün Karşılaştırması:\n\n{comparison_table}"
274
+
275
+ return None
276
+
277
+ def get_user_recommendations(user_id, user_message):
278
+ """Kullanıcıya özel öneriler al"""
279
+ # Bütçe sorgusu varsa
280
+ if "bütçe" in user_message.lower() or "budget" in user_message.lower():
281
+ # Rakamları çıkarmaya çalış
282
+ import re
283
+ numbers = re.findall(r'\d+', user_message)
284
+ if len(numbers) >= 2:
285
+ budget_min = int(numbers[0]) * 1000 # K TL formatı için
286
+ budget_max = int(numbers[1]) * 1000
287
+ recommendations = personalized_recommendations.get_budget_recommendations(
288
+ user_id, budget_min, budget_max
289
+ )
290
+
291
+ if recommendations:
292
+ rec_text = "Bütçenize uygun öneriler:\n\n"
293
+ for product in recommendations[:3]:
294
+ rec_text += f"• {product[2]} - {product[1][1]} TL\n"
295
+ return rec_text
296
+
297
+ # Genel kişisel öneriler
298
+ suggestions = personalized_recommendations.get_personalized_suggestions(user_id)
299
+ if suggestions:
300
+ sug_text = "Size özel önerilerimiz:\n\n"
301
+ for product in suggestions:
302
+ sug_text += f"• {product[2]} - {product[1][1]} TL\n"
303
+ return sug_text
304
+
305
+ return None
requirements.txt CHANGED
@@ -4,10 +4,10 @@ requests
4
  pandas
5
  python-docx
6
  huggingface_hub
7
- schedule
8
  openpyxl
9
  spaces
10
  google-auth
11
  google-auth-oauthlib
12
  google-auth-httplib2
13
  google-api-python-client
 
 
4
  pandas
5
  python-docx
6
  huggingface_hub
 
7
  openpyxl
8
  spaces
9
  google-auth
10
  google-auth-oauthlib
11
  google-auth-httplib2
12
  google-api-python-client
13
+ tabulate