Update app.py
Browse files
app.py
CHANGED
@@ -18,6 +18,7 @@ from googleapiclient.http import MediaIoBaseDownload
|
|
18 |
import io
|
19 |
import warnings
|
20 |
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
|
|
21 |
warnings.simplefilter('ignore', InsecureRequestWarning)
|
22 |
|
23 |
# Prompt dosyasını import et
|
@@ -622,6 +623,40 @@ if root is not None:
|
|
622 |
|
623 |
print(f"Toplam {len(products)} ürün yüklendi.")
|
624 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
625 |
# Initialize enhanced features
|
626 |
initialize_enhanced_features(OPENAI_API_KEY, products)
|
627 |
|
@@ -708,39 +743,54 @@ def run_scheduler(chat_history):
|
|
708 |
schedule.run_pending()
|
709 |
time.sleep(60)
|
710 |
|
711 |
-
# NEW: Stok sorularına deterministik, tamamen veri tabanlı yanıt
|
712 |
def answer_stock_grounded(user_message):
|
713 |
"""
|
714 |
Stok sorularına tamamen veri-tabanlı, deterministik yanıt üretir.
|
715 |
Yalnızca API + XML kullanır, LLM'ye gitmez.
|
|
|
716 |
"""
|
717 |
-
# 1) Ürün adı çıkarma
|
718 |
skip_words = ['stok','stock','kaç','adet','tane','var','mı','mi','mevcut','mu','bulunuyor',
|
719 |
'hangi','mağaza','nerede','durumu','stoklarda','stokta',
|
720 |
'için','ve','ile','toplam','toplamda','fiyat','fiyatı','ne','nedir','kadar',
|
721 |
'beden','bedeni','bedenli']
|
722 |
-
|
723 |
-
if not
|
724 |
return "Hangi ürün için stok bakmamı istersiniz?"
|
725 |
|
726 |
-
# Sadece beden mi sorulmuş?
|
727 |
size_terms = {'xs','s','m','ml','l','xl','xxl','2xl','3xl','small','medium','large',
|
728 |
'44','46','48','50','52','54','56','58','60'}
|
729 |
-
is_only_size = (len(
|
730 |
-
|
|
|
|
|
|
|
|
|
731 |
|
732 |
-
#
|
733 |
stock_text = get_realtime_stock_parallel(product_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
734 |
if not stock_text:
|
735 |
return f"'{product_name}' için stok bilgisine şu an erişemedim."
|
736 |
|
737 |
-
#
|
738 |
norm_query = normalize_turkish(product_name).replace(" ", "")
|
739 |
extra_lines = []
|
740 |
added = 0
|
741 |
try:
|
742 |
for name, info, full_name in products:
|
743 |
-
if added >= 3:
|
744 |
break
|
745 |
norm_full = normalize_turkish(full_name).replace(" ", "")
|
746 |
if norm_query and norm_query in norm_full:
|
|
|
18 |
import io
|
19 |
import warnings
|
20 |
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
21 |
+
import re # NEW: yıl tespiti için
|
22 |
warnings.simplefilter('ignore', InsecureRequestWarning)
|
23 |
|
24 |
# Prompt dosyasını import et
|
|
|
623 |
|
624 |
print(f"Toplam {len(products)} ürün yüklendi.")
|
625 |
|
626 |
+
# NEW: Ürün adlarındaki yılları topla (yıl doğrulama/tolerans için)
|
627 |
+
PRODUCT_YEARS = set()
|
628 |
+
year_pat = re.compile(r'(?:19|20)\d{2}')
|
629 |
+
for _, _, full_name in products:
|
630 |
+
for y in year_pat.findall(full_name or ""):
|
631 |
+
PRODUCT_YEARS.add(y)
|
632 |
+
print(f"Yıl seti (ürün adlarından): {sorted(PRODUCT_YEARS)}")
|
633 |
+
|
634 |
+
# NEW: Yıl toleransı yardımcıları
|
635 |
+
def strip_unseen_years(q: str):
|
636 |
+
"""Sorgudan, ürünlerde hiç bulunmayan yıl(lar)ı temizle."""
|
637 |
+
if not q:
|
638 |
+
return q, []
|
639 |
+
years = re.findall(r'(?:19|20)\d{2}', q)
|
640 |
+
removed = []
|
641 |
+
new_q = q
|
642 |
+
for y in years:
|
643 |
+
if y not in PRODUCT_YEARS:
|
644 |
+
new_q = re.sub(r'\b' + re.escape(y) + r'\b', '', new_q)
|
645 |
+
removed.append(y)
|
646 |
+
new_q = ' '.join(new_q.split())
|
647 |
+
return new_q, removed
|
648 |
+
|
649 |
+
def remove_all_years(q: str):
|
650 |
+
"""Sorgudaki tüm yıl ifadelerini (19xx/20xx) sil."""
|
651 |
+
if not q:
|
652 |
+
return q
|
653 |
+
new_q = re.sub(r'\b(?:19|20)\d{2}\b', '', q)
|
654 |
+
return ' '.join(new_q.split())
|
655 |
+
|
656 |
+
def is_no_stock_text(text: str):
|
657 |
+
"""'stokta bulunmuyor' ifadesini içeriyor mu?"""
|
658 |
+
return bool(text) and ("stokta bulunmuyor" in text)
|
659 |
+
|
660 |
# Initialize enhanced features
|
661 |
initialize_enhanced_features(OPENAI_API_KEY, products)
|
662 |
|
|
|
743 |
schedule.run_pending()
|
744 |
time.sleep(60)
|
745 |
|
746 |
+
# NEW: Stok sorularına deterministik, tamamen veri tabanlı yanıt (YIL TOLERANSI ENTEGRE)
|
747 |
def answer_stock_grounded(user_message):
|
748 |
"""
|
749 |
Stok sorularına tamamen veri-tabanlı, deterministik yanıt üretir.
|
750 |
Yalnızca API + XML kullanır, LLM'ye gitmez.
|
751 |
+
YIL TOLERANSI: XML'de hiç olmayan yıl(lar)ı sorgudan otomatik çıkarır.
|
752 |
"""
|
753 |
+
# 1) Ürün adı çıkarma
|
754 |
skip_words = ['stok','stock','kaç','adet','tane','var','mı','mi','mevcut','mu','bulunuyor',
|
755 |
'hangi','mağaza','nerede','durumu','stoklarda','stokta',
|
756 |
'için','ve','ile','toplam','toplamda','fiyat','fiyatı','ne','nedir','kadar',
|
757 |
'beden','bedeni','bedenli']
|
758 |
+
tokens = [w for w in user_message.lower().split() if w not in skip_words]
|
759 |
+
if not tokens:
|
760 |
return "Hangi ürün için stok bakmamı istersiniz?"
|
761 |
|
|
|
762 |
size_terms = {'xs','s','m','ml','l','xl','xxl','2xl','3xl','small','medium','large',
|
763 |
'44','46','48','50','52','54','56','58','60'}
|
764 |
+
is_only_size = (len(tokens) == 1 and tokens[0] in size_terms)
|
765 |
+
raw_name = tokens[0] if is_only_size else ' '.join(tokens)
|
766 |
+
|
767 |
+
# 2) Sorgudan, XML'de hiç bulunmayan yıl(lar)ı çıkar
|
768 |
+
refined_name, removed_years = strip_unseen_years(raw_name)
|
769 |
+
product_name = refined_name or raw_name # emniyet
|
770 |
|
771 |
+
# 3) İlk deneme (refined query ile)
|
772 |
stock_text = get_realtime_stock_parallel(product_name)
|
773 |
+
|
774 |
+
# 4) Hâlâ "stokta yok" ve sorguda YIL vardıysa: tüm yılları silip bir kez daha dene
|
775 |
+
had_any_year = bool(re.search(r'(?:19|20)\d{2}', raw_name))
|
776 |
+
if (not stock_text or is_no_stock_text(stock_text)) and had_any_year:
|
777 |
+
name_wo_years = remove_all_years(raw_name)
|
778 |
+
if name_wo_years and name_wo_years != product_name:
|
779 |
+
retry_text = get_realtime_stock_parallel(name_wo_years)
|
780 |
+
if retry_text and not is_no_stock_text(retry_text):
|
781 |
+
stock_text = retry_text
|
782 |
+
product_name = name_wo_years # raporlamada bu adı kullan
|
783 |
+
|
784 |
if not stock_text:
|
785 |
return f"'{product_name}' için stok bilgisine şu an erişemedim."
|
786 |
|
787 |
+
# 5) XML’den (varsa) fiyat/link/resim ekle (sadece veride olanı)
|
788 |
norm_query = normalize_turkish(product_name).replace(" ", "")
|
789 |
extra_lines = []
|
790 |
added = 0
|
791 |
try:
|
792 |
for name, info, full_name in products:
|
793 |
+
if added >= 3:
|
794 |
break
|
795 |
norm_full = normalize_turkish(full_name).replace(" ", "")
|
796 |
if norm_query and norm_query in norm_full:
|