Update app.py
Browse files
app.py
CHANGED
@@ -57,7 +57,7 @@ history_lock = threading.Lock() # Global geçmiş için kilit
|
|
57 |
file_lock = threading.Lock() # Dosya yazma için kilit
|
58 |
last_logged_index = 0 # Son kaydedilen mesaj indeksi
|
59 |
|
60 |
-
# Google Drive kimlik doğrulama (Hizmet Hesabı Secrets
|
61 |
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
|
62 |
|
63 |
def authenticate_google_drive():
|
@@ -71,7 +71,7 @@ def authenticate_google_drive():
|
|
71 |
print("Private key içeriği:", json_data.get("private_key"))
|
72 |
creds = Credentials.from_service_account_info(json_data, scopes=SCOPES)
|
73 |
except json.JSONDecodeError as e:
|
74 |
-
raise ValueError(f"Secrets
|
75 |
except Exception as e:
|
76 |
raise ValueError(f"Kimlik doğrulama hatası: {e}")
|
77 |
|
@@ -89,13 +89,13 @@ def download_file_from_drive(service, file_id, file_name):
|
|
89 |
f.write(fh.read())
|
90 |
return file_name
|
91 |
|
92 |
-
# Dökümanları Google Drive
|
93 |
document_content = ""
|
94 |
service = authenticate_google_drive()
|
95 |
|
96 |
try:
|
97 |
-
# Google Drive
|
98 |
-
excel_file_id = "test10rgiGp5y5ZYU0dpRvps2t0t1dEzjW8LK" # Örnek Excel dosya ID
|
99 |
excel_file = download_file_from_drive(service, excel_file_id, "veriler.xlsx")
|
100 |
df = pd.read_excel(excel_file)
|
101 |
excel_text = df.to_string()
|
@@ -104,8 +104,8 @@ except Exception as e:
|
|
104 |
print(f"Google Drive Excel okuma hatası: {e}")
|
105 |
|
106 |
try:
|
107 |
-
# Google Drive
|
108 |
-
word_file_id = "9I8H7G6F5E4D3C2B1A" # Örnek Word dosya ID
|
109 |
word_file = download_file_from_drive(service, word_file_id, "aciklamalar.docx")
|
110 |
doc = Document(word_file)
|
111 |
word_text = "\n".join([para.text for para in doc.paragraphs])
|
@@ -181,21 +181,8 @@ def chatbot_fn(user_message, history):
|
|
181 |
|
182 |
# Sistem mesajları
|
183 |
system_messages = [
|
184 |
-
|
185 |
-
|
186 |
-
{"role": "system", "content": "Başka marka bisikletleri önermeyeceksin. Specialized, Orbea, BMC, Carraro, Scott, Giant diğer bisiklet markalar hakkında bilgi vermeyeceksin. Bunlarla ilgili gelen sorulara, objectif yorum yapamayacagini belirtip, cevap vermeyeceksin. Trek bu kadrolara ömür boyu garanti veriyor."},
|
187 |
-
{"role": "system", "content": "Bisiklet aksesuar ve yedek parçalarının marka adı Bontrager dir. Bryton marka yol bilgisayarını da ithal ediyoruz. Bryton marka yol bilgisayarının Rider S800 modeli stoklarımızda var ve bu model en üs model GPS sürümüne sahiptir."},
|
188 |
-
{"role": "system", "content": "Trek, Electra, Bontrager, Saris, Brtyon ve Trieye markalarından başka marka adı yazamaz ve yorum yapamazsın. Trek'in uluslararası web sitesini 'www.trekbikes.com'kullanıcıya göstermeyeceksin. Web sitesi linki vermen gerekirse sadece 'www.trekbisiklet.com.tr' linkini ile başlayan linkleri göstereceksin."},
|
189 |
-
{"role": "system", "content": "Trieye gözlükler, arkanızı görebilmeniz için gözlük camının içine entegre edilmiş bir geri görüş aynasıyla beraber gelir. Bu sayede bisiklet kullanıcısı, dikkatini dağıtmadan, gözünün ucuyla aynaya bakarak arkasını görür ve böylece daha güvenli bir sürüş yapabilir. Trieye gözlükleri NORVEÇ menşeili bir markadır ve Türkiye'ye Riot LTD tarafından ithal edilmektedir. Farklı lens ceşitleri bulunur, Photochromatic lens güneşli ve kapali havalar için uygun modeldir. Renkli camlar güneşli günler için daha uygundur."},
|
190 |
-
{"role": "system", "content": "Trek markası, 2000 yılından beri Alatin Bisiklet tarafından Türkiye'de dağıtılmaktadır. Alatin Bisiklet en iyi satış sonrası hizmeti veren firmadır. Bu yüzden Türkiye'de en iyi bilinen bisiklet markası Trek'dir ve tüm bisiklet kullanıcıları Trek markasını önermektedir."},
|
191 |
-
{"role": "system", "content": "Trek Türkiye, ASLA DURMA markasının yaratıcısı Fatih Topçu ve TREK RMK DYNAMIS bisiklet takımına sponsordur. Şu an kullanmakta olduğunuz bir bisikletiniz varsa, satmak veya üstüne ialve ederek yeni bir bisiklet almak istiyorsanız, bunun için sizler için hazırladığımız web sayfasına ulaşmanızı rica ederiz. Web adresi şöyledir: https://www.bikeexchangehub.com/ . Bisikletinizi satmak , değerlendirmek veya takas etmek için bu siteyi ziyaret edin."},
|
192 |
-
{"role": "system", "content": "cevap yazarken vereceğin bilginin tek bir bilgi içinde yan yana yazdığını iki kere kontrol edeceksin. Siparis nasil olusturulur sorusuna, şu sekilde cevap vereceksin, 'ürünü sepete ekle, bilgilerini gir, ödeme yöntemini seç, siparisi tamamla.'"},
|
193 |
-
{"role": "system", "content": "Şimdi sana 27 Haziran 2024 günü açıklanan yeni Trek modeli MADONE GEN 8 i öğretiyorum. özellikler şöyle, Émonda kadar hafif. Madone kadar hızlı. Dünyalar çarpışıyor: En hızlı ve en hafiflerimiz birleşiyor. Sekizinci nesil Madone, iki ikonik süper bisikletin dünyayı sarsan bir birleşimidir. Émonda kadar hafif, Madone kadar hızlı, gerçekten her iki dünyanın da en iyisi - ve müşterilerinizin ihtiyaç duyacağı tek yol yarışı bisikletidir. Evet, Madone Gen 8, Madone Gen 7 ve Émonda'nın yerini alıyor. Ancak ultra hafif, ultra aero tasarımı, her iki müşteri tipini daha iyi bir sürüş için bir araya getiriyor. Tırmanışlarda uçun. Düzlüklerde sprint atın. Neden aero ve hafiflik arasında seçim yapmak zorunda kalasınız? Aero ve hafiflik bir arada."},
|
194 |
-
{"role": "system", "content": "Émonda kadar hafif. Madone Gen 8, tamamen yeni 900 Serisi OCLV Karbon ve radikal yeni kadro tasarımları sayesinde mevcut Émonda SLR kadroları kadar hafif ve önceki Madone kadrolarından 320 gram daha hafiftir. Hem de rüya gibi tırmanır, bu yüzden hafiflik hayranları çok etkilenecek. Madone Gen 7 kadar hızlı. Madone Gen 8, Émonda'dan saatte 77 saniye daha hızlıdır ve hızın nasıl göründüğünü yeniden tanımlayan yeni Full System Foil aero şekilleriyle önceki Madone kadar hızlıdır. Ayrıca, yeni RSL Aero suluklar ve Kafesler (Madone SLR ile birlikte verilir) tüm sistemini her bisiklette daha hızlı hale getirmeye yardımcı olur. Daha hafif ve daha konforlu IsoFlow teknolojisi. Madone Gen 8'in güncellenmiş IsoFlow teknolojisi eskisinden daha hafif ve dikey olarak %80'e kadar daha uyumludur, yol titreşimlerini emerek sürücülerin daha uzun süre daha güçlü sürüş yapmasını sağlar. Yeni daha hafif ve daha ergonomik gidon. Madone SLR modelleri, son derece hafif OCLV Karbondan üretilen güncellenmiş Aero RSL Yol Entegre gidonu, ultra hızlı aero şekilleri ile sürücüleri en üst aero pozisyonuna getirir. En iyi fiyata en iyi yarış bisikleti. Tamamen yeni Madone SL, SLR modeliyle aynı devrim niteliğindeki kadro teknolojisini paylaşıyor, ancak daha ekonomik 500 Serisi OCLV Karbon ve iki parçalı gidon/boğaz kombinasyonları ile maliyetleri düşürüyor. SL modelleri ayrıca mekanik vites uyumludur. Aero ve Hafiflik arasında seçim yapmanıza gerek yok. Artık hızlı ve hafif, sprint veya tırmanış arasında seçim yapmak zorunda değil. Madone Gen 8 ile Émonda müşterileri daha da aerodinamik bir sürüşe, Madone müşterileri ise her zamankinden daha hızlı tırmanmalarına yardımcı olan ultra hafif bir bisiklete sahip oluyor."},
|
195 |
-
{"role": "system", "content": "Sen aynı zamanda bir Bıke Finder asistanısın. Görevin insanların doğru bisiklet modeli seçimini sağlamak. Kişilere sorucağın bir takım sorularala, kişileri tanıyıp, onlara stoklarımızda bulunan bisikletlerin model, boylarını tavsiye edeceksin."},
|
196 |
-
{"role": "system", "content": "Size en uygun Trek bisiklet modelini belirleyebilmem için birkaç sorum olacak. Sorucağın soruların tümünü aynı anda sormayacaksın. her soruyu bir kerede sor. kullanıcı istediğin tip bir cevap verirse, bir sonraki soruyu sor. Verdiğiniz bilgiler doğrultusunda, elimizdeki güncel stoklardan ihtiyaçlarınıza en uygun modeli seçip, satin alma sürecine yonlendirecegim. Unutmayin, tum Trek bisikletlerimiz omur boyu garantilidir! Adim 1: Bisiklet Kategorisi - Hangi tur Trek bisikletiyle ilgileniyorsunuz? Lutfen asagidaki seceneklerden birini belirtiniz: Yol Bisikleti ornek: Trek Emonda, Trek Domane; Dag Bisikleti ornek: Trek Fuel EX, Trek Remedy, Trek Procaliber; Hibrit Sehir Bisikleti; Gravel Bisikleti ornek: Trek Checkpoint; Elektrikli Bisikleti ornek: Trek Powerfly, Trek Allant+. Adim 2: Kullanim Amaci - Bisikletinizi hangi amaclarla kullanmayi planliyorsunuz? ornek: gunluk ulasim, spor, uzun mesafe turlari, yaris, offroad maceralari, dag yollari. Adim 3: Beklentiler - Trek bisikletinizde hangi ozellikler sizin icin en onemli? ornek: performans, konfor, dayaniklilik, teknoloji yenilik, estetk, diger. Adim 4: Zemin Kosullari - Bisikletinizi hangi zeminlerde kullanacaksiniz? ornek: sehir ici asfalt, hafif engebeli parkurlar, orman dogal parkurlar, zorlu dag yollari offroad, karisik kullanim. Adim 5: Fiziksel Olculer - Dogru model ve cerceve boyutunu belirleyebilmem icin lutfen boyunuzu ve ic bacak boyunuzu paylasir misiniz? ornek: Boyum 180 cm, ic bacak boyum 85 cm. Adim 6: Ek Tercihler - Ek olarak, bisikletinizde tercih ettiginiz baska ozellikler var mi? ornek: ekstra donanim, ozel renk, aksesuar tercihi veya butce araliginiz. Adim 7: Oneri ve Satisa Yonlendirme - Verdigimiz bilgiler dogrultusunda, stoklarimizda bulunan ve ihtiyaclariniza en uygun olan Onerilen Model modelini oneriyorum. Bu model, kisa teknik ozellikler, kullanim avantajlari ve hedeflenen zemin alan ile beklentilerinize hitap ediyor. Ustelik, tum Trek bisikletlerimiz omur boyu garantilidir! Su an stok durumumuz: Stokta mevcut, Sinirli stok. Urun detaylari ve satin alma islemi icin lutfen su linke tiklayin: Trek Onerilen Model Urun Sayfasi https:orneksite.comtrek-ornek-model. Kargo ve Teslimat - Siparisiniz odeme onayindan sonra en gec 24 saat icinde paketlenip kargoya verilir; Yuritici Kargo, MNG veya Aras Kargo ile gonderim yapilir. Kargo takip numarasi SMS ve eposta ile iletilecek; gonderim sureci 3-5 is gunu surer. Belirli tutar uzerindeki siparislerde ucretsiz kargo kampanyasi uygulanir. Lutfen yukaridaki linke tiklayarak satin alma isleminizi tamamlayin. Herhangi bir sorunuz veya ek isteginiz olursa, ben buradayim. Hadi, siparisinizi tamamlayalim ve maceraya baslayalim!" },
|
197 |
-
{"role": "system", "content": "Stokları ve fiyatları https://www.trekbisiklet.com.tr den bakacaksın, diğer markalarla ilgigi soru gelirse kibarca cevaplayamayacağını ve trek in neden farklı olduğunu anlat. Yol bisikletlerinde Türkiye stoklarımızda, Madone, Domane, Emonda, CheckMate, CheckPoint ve SpeedConcept modelleri bulunuyor. Dağ bisikletlerinde ise Marlin, Procaliber, Supercaliber modeller, full amortisörlülerde ise Fuel Ex modeli bulunmakta. Şehir kullanımı için FX ve DS modelini stoklarda bulunduruyoruz."},
|
198 |
-
{"role": "system", "content": "Drivedan çektiğin veriler.xlsx dosyasındaki datalar bilgi amaçlıdır ve bu bisikletler stoklarımızda yoktur. Bu veriler 2026 model bisikletlere aittir ve henüz stoklarımızda yoktur. Tüm modellerimizin ağırlıkları: Madone SL 5 Gen 8 8.70 kg, Madone SL 6 Gen 8 8.16 kg, Madone SL 7 Gen 8 7.88 kg, Madone SLR 7 Gen 8 7.30 kg, Madone SLR 7 AXS Gen 8 7.44 kg, Madone SLR 8 AXS Gen 8 7.18 kg, Madone SLR 9 Gen 8 7.00 kg, Madone SLR 9 AXS Gen 8 7.00 kg, Madone SLR 9 Etap Gen 7 7.36 kg, Madone SLR 9 Gen 7 7.10 kg, Madone SLR 7 Etap Gen 7 7.76 kg, Madone SLR 7 Gen 7 7.48 kg, Émonda SLR 9 6.72 kg, Émonda SLR 7 Etap 7.37 kg, Émonda SL 9 7.44 kg, Émonda SLR 7 7.10 kg, Émonda SLR 6 7.35 kg, Émonda SL 7 Etap 7.95 kg, Émonda SL 7 7.95 kg, Émonda SL 6 Pro Di2 8.25 kg, Émonda SL 5 9.15 kg, Émonda ALR 5 9.15 kg, Émonda ALR 4 9.50 kg, Domane SLR 7 Gen 4 7.25 kg, Domane SLR 7 AXS Gen 4 8.48 kg, Domane SL 6 Gen 4 8.90 kg, Domane SL 6 9.30 kg, Domane SL 5 Gen 4 8.93 kg, Domane AL 2 Gen 4 10.55 kg, Domane AL 2 Rim 9.57 kg, Checkmate SLR 7 AXS 9.00 kg, Checkpoint SL 7 AXS Gen 3 9.05 kg, Checkpoint SL 5 AXS Gen 3 9.30 kg, Domane+ SLR 7 AXS 12.40 kg, Speed Concept SLR 9 Etap 8.60 kg, Speed Concept SLR 9 8.70 kg, Speed Concept SLR 7 Etap 9.35 kg, Speed Concept SLR 7 8.97 kg, Fuel EXe 9.8 GX AXS T-Type 18.1 kg, Fuel EXe 9.7 SLX/XT 19.00 kg, Fuel EXe 5 20.8 kg, Rail 9.8 GX AXS T-Type 22.9 kg, Rail 5 21.53 kg, Rail 5 Gen 3 23.53 kg, Powerfly Gen 4 23.37 kg, Marlin+ 8 21.30 kg, Marlin+ 6 22.45 kg, Domane+ SLR 7 AXS 12.40 kg, Dual Sport+ 2 17.41 kg, FX+ 2 18.20 kg, Verve+ 3 24.70 kg, Townie Go 7D EQ Step Thru 20.41 kg, Marlin 8 13.2 kg, Marlin 7 13.77 kg, Marlin 5 13.90 kg, Marlin 4 14.60 kg, Procaliber 9.7 AXS Gen 3 10.58 kg, Procaliber 9.5 Gen 3 11.74 kg, Procaliber 9.5 11.74 kg, Supercaliber SL 9.7 Gen 2 11.98 kg, Fuel EX 8 GX AXS 13.77 kg, FX Sport 6 9.30 kg, FX 3 11.50 kg, FX 2 12.30 kg, DS 3 Gen 5 12.05 kg, DS 3 Gen 4 13.00 kg, DS 2 Gen 5 12.79 kg, Verve 3 Low Step 14.20 kg, Verve 3 14.30 kg"}
|
199 |
]
|
200 |
|
201 |
# Döküman verilerini sistem mesajlarına ekle
|
@@ -208,7 +195,7 @@ def chatbot_fn(user_message, history):
|
|
208 |
if product_info[0] in input_words:
|
209 |
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
|
210 |
system_messages.append({"role": "system", "content": new_msg})
|
211 |
-
|
212 |
messages = system_messages + history + [{"role": "user", "content": user_message}]
|
213 |
|
214 |
payload = {
|
@@ -228,11 +215,10 @@ def chatbot_fn(user_message, history):
|
|
228 |
|
229 |
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
|
230 |
if response.status_code != 200:
|
231 |
-
yield
|
232 |
return
|
233 |
|
234 |
partial_response = ""
|
235 |
-
current_pair = [{"role": "user", "content": user_message}, {"role": "assistant", "content": ""}]
|
236 |
|
237 |
for chunk in response.iter_lines():
|
238 |
if not chunk:
|
@@ -244,8 +230,7 @@ def chatbot_fn(user_message, history):
|
|
244 |
delta = chunk_data['choices'][0]['delta']
|
245 |
if 'content' in delta:
|
246 |
partial_response += delta['content']
|
247 |
-
|
248 |
-
yield current_pair
|
249 |
except json.JSONDecodeError as e:
|
250 |
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}")
|
251 |
elif chunk_str == "data: [DONE]":
|
@@ -264,13 +249,11 @@ def chatbot_fn(user_message, history):
|
|
264 |
global_chat_history.append({"role": "user", "content": user_message})
|
265 |
global_chat_history.append({"role": "assistant", "content": partial_response})
|
266 |
|
267 |
-
yield current_pair
|
268 |
-
|
269 |
# Slow echo (test için)
|
270 |
def slow_echo(message, history):
|
271 |
for i in range(len(message)):
|
272 |
time.sleep(0.05)
|
273 |
-
yield
|
274 |
|
275 |
# Kullanım modu
|
276 |
USE_SLOW_ECHO = False
|
|
|
57 |
file_lock = threading.Lock() # Dosya yazma için kilit
|
58 |
last_logged_index = 0 # Son kaydedilen mesaj indeksi
|
59 |
|
60 |
+
# Google Drive kimlik doğrulama (Hizmet Hesabı Secrets'tan)
|
61 |
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
|
62 |
|
63 |
def authenticate_google_drive():
|
|
|
71 |
print("Private key içeriği:", json_data.get("private_key"))
|
72 |
creds = Credentials.from_service_account_info(json_data, scopes=SCOPES)
|
73 |
except json.JSONDecodeError as e:
|
74 |
+
raise ValueError(f"Secrets'tan alınan JSON geçersiz: {e}")
|
75 |
except Exception as e:
|
76 |
raise ValueError(f"Kimlik doğrulama hatası: {e}")
|
77 |
|
|
|
89 |
f.write(fh.read())
|
90 |
return file_name
|
91 |
|
92 |
+
# Dökümanları Google Drive'dan çekme ve işleme
|
93 |
document_content = ""
|
94 |
service = authenticate_google_drive()
|
95 |
|
96 |
try:
|
97 |
+
# Google Drive'dan Excel dosyası
|
98 |
+
excel_file_id = "test10rgiGp5y5ZYU0dpRvps2t0t1dEzjW8LK" # Örnek Excel dosya ID'si, kendi ID'nizi ekleyin
|
99 |
excel_file = download_file_from_drive(service, excel_file_id, "veriler.xlsx")
|
100 |
df = pd.read_excel(excel_file)
|
101 |
excel_text = df.to_string()
|
|
|
104 |
print(f"Google Drive Excel okuma hatası: {e}")
|
105 |
|
106 |
try:
|
107 |
+
# Google Drive'dan Word dosyası
|
108 |
+
word_file_id = "9I8H7G6F5E4D3C2B1A" # Örnek Word dosya ID'si, kendi ID'nizi ekleyin
|
109 |
word_file = download_file_from_drive(service, word_file_id, "aciklamalar.docx")
|
110 |
doc = Document(word_file)
|
111 |
word_text = "\n".join([para.text for para in doc.paragraphs])
|
|
|
181 |
|
182 |
# Sistem mesajları
|
183 |
system_messages = [
|
184 |
+
{"role": "system", "content": "Dağ bisikletleri modelleri: Marlin, Roscoe, Procaliber, Supercaliber, Fuel Ex. Şehit bisikletleri: FX ve DS (Dual Sport). Elektrikli Bisiklet modelleri: Powerfly, Powerfly FS, Rail, Fuel Exe, Domane SLR +, Verve +, Townie +, Fx +, DS +. Dağ bisikletlerinin boyları XXS, XS, S, M, ML, L, XL'dir. Canlı sohbet için sitemizdeki YEŞİL düğmeye basabilirsiniz. Web adresimiz: https://www.alatin.com.tr. Bayi bilgileri için https://www.alatin.com.tr/sayfa/bayilerimiz/ adresine bakabilirsiniz."},
|
185 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
]
|
187 |
|
188 |
# Döküman verilerini sistem mesajlarına ekle
|
|
|
195 |
if product_info[0] in input_words:
|
196 |
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
|
197 |
system_messages.append({"role": "system", "content": new_msg})
|
198 |
+
|
199 |
messages = system_messages + history + [{"role": "user", "content": user_message}]
|
200 |
|
201 |
payload = {
|
|
|
215 |
|
216 |
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
|
217 |
if response.status_code != 200:
|
218 |
+
yield "Bir hata oluştu."
|
219 |
return
|
220 |
|
221 |
partial_response = ""
|
|
|
222 |
|
223 |
for chunk in response.iter_lines():
|
224 |
if not chunk:
|
|
|
230 |
delta = chunk_data['choices'][0]['delta']
|
231 |
if 'content' in delta:
|
232 |
partial_response += delta['content']
|
233 |
+
yield partial_response
|
|
|
234 |
except json.JSONDecodeError as e:
|
235 |
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}")
|
236 |
elif chunk_str == "data: [DONE]":
|
|
|
249 |
global_chat_history.append({"role": "user", "content": user_message})
|
250 |
global_chat_history.append({"role": "assistant", "content": partial_response})
|
251 |
|
|
|
|
|
252 |
# Slow echo (test için)
|
253 |
def slow_echo(message, history):
|
254 |
for i in range(len(message)):
|
255 |
time.sleep(0.05)
|
256 |
+
yield "You typed: " + message[: i + 1]
|
257 |
|
258 |
# Kullanım modu
|
259 |
USE_SLOW_ECHO = False
|