|
import gradio as gr |
|
import os |
|
import json |
|
import requests |
|
import xml.etree.ElementTree as ET |
|
from huggingface_hub import HfApi, create_repo |
|
import schedule |
|
import time |
|
import threading |
|
|
|
|
|
LOG_FILE = '/data/chat_logs.txt' if os.path.exists('/data') else 'chat_logs.txt' |
|
print(f"Dosya yolu: {os.path.abspath(LOG_FILE)}") |
|
|
|
|
|
API_URL = "https://api.openai.com/v1/chat/completions" |
|
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") |
|
if not OPENAI_API_KEY: |
|
print("Hata: OPENAI_API_KEY çevre değişkeni ayarlanmamış!") |
|
|
|
|
|
url = 'https://www.trekbisiklet.com.tr/output/8582384479' |
|
response = requests.get(url) |
|
root = ET.fromstring(response.content) |
|
|
|
products = [] |
|
for item in root.findall('item'): |
|
if item.find('isOptionOfAProduct').text == '1' and item.find('stockAmount').text > '0': |
|
name_words = item.find('rootlabel').text.lower().split() |
|
name = name_words[0] |
|
full_name = ' '.join(name_words) |
|
stockAmount = "stokta" |
|
price = item.find('priceWithTax').text |
|
item_info = (stockAmount, price) |
|
products.append((name, item_info, full_name)) |
|
|
|
|
|
hfapi = os.getenv("hfapi") |
|
if not hfapi: |
|
raise ValueError("hfapi ortam değişkeni ayarlanmamış!") |
|
|
|
create_repo("BF", token=hfapi, repo_type="space", space_sdk="gradio", exist_ok=True) |
|
|
|
def save_chat(chatbot): |
|
file_path = os.path.abspath(LOG_FILE) |
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write("\n--- Zamanlanmış Kayıt: {} ---\n".format(time.strftime("%Y-%m-%d %H:%M:%S"))) |
|
for msg in chatbot: |
|
f.write(f"{msg['role'].capitalize()}: {msg['content']}\n") |
|
print(f"Sohbet dosyaya kaydedildi: {file_path}") |
|
return True |
|
except Exception as e: |
|
print(f"Kayıt hatası: {e}") |
|
return False |
|
|
|
def upload_logs_to_hf(repo_id: str, hf_token: str, local_log_file: str = LOG_FILE): |
|
api = HfApi(token=hf_token) |
|
try: |
|
api.upload_file( |
|
path_or_fileobj=local_log_file, |
|
path_in_repo="chat_logs.txt", |
|
repo_id=repo_id, |
|
repo_type="space", |
|
commit_message="Otomatik log dosyası güncellemesi - {}".format(time.strftime("%Y-%m-%d %H:%M:%S")) |
|
) |
|
print(f"Log dosyası HF'ye yüklendi: {local_log_file}") |
|
return True |
|
except Exception as e: |
|
print(f"HF yükleme hatası: {e}") |
|
return False |
|
|
|
def run_scheduler(chatbot_ref): |
|
def scheduled_save_and_upload(): |
|
if chatbot_ref: |
|
print(f"Zamanlayıcı tetiklendi: {time.strftime('%Y-%m-DD %H:%M:%S')}") |
|
save_success = save_chat(chatbot_ref) |
|
if save_success: |
|
HF_REPO_ID = "SamiKoen/BF" |
|
upload_logs_to_hf(HF_REPO_ID, hfapi) |
|
print(f"Zamanlanmış işlem tamamlandı: {time.strftime('%H:%M:%S')}") |
|
|
|
schedule.every().day.at("11:32").do(scheduled_save_and_upload) |
|
schedule.every().day.at("15:00").do(scheduled_save_and_upload) |
|
schedule.every().day.at("21:00").do(scheduled_save_and_upload) |
|
print("Zamanlayıcı başlatıldı") |
|
|
|
while True: |
|
schedule.run_pending() |
|
print(f"Zamanlayıcı çalışıyor, bekliyor: {time.strftime('%H:%M:%S')}") |
|
time.sleep(60) |
|
|
|
def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=None, history=None): |
|
if chatbot is None: |
|
chatbot = [] |
|
if history is None: |
|
history = [] |
|
|
|
headers = { |
|
"Content-Type": "application/json", |
|
"Authorization": f"Bearer {OPENAI_API_KEY}" |
|
} |
|
print(f"System message: {system_msg}") |
|
|
|
multi_turn_message = [ |
|
{"role": "system", "content": "Bir önceki sohbeti unut. Vereceğin ürün bilgisi, bu bilginin içinde yan yana yazılmıyorsa veya arada başka bilgiler yazıyor ise, o bilgiyi vermeyeceksin çünkü o bilgi yanlıştır."} |
|
] |
|
|
|
messages = multi_turn_message.copy() |
|
input_words = [str(word).lower() for word in inputs.split()] |
|
for product_info in products: |
|
if product_info[0] in input_words: |
|
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}" |
|
print(new_msg) |
|
messages.append({"role": "system", "content": new_msg}) |
|
|
|
for data in chatbot: |
|
messages.append({"role": data["role"], "content": data["content"]}) |
|
|
|
messages.append({"role": "user", "content": inputs}) |
|
|
|
payload = { |
|
"model": "gpt-4o", |
|
"messages": messages, |
|
"temperature": 0.7, |
|
"top_p": 0.9, |
|
"n": 1, |
|
"stream": True, |
|
"presence_penalty": 0, |
|
"frequency_penalty": 0, |
|
} |
|
|
|
chat_counter += 1 |
|
history.append(inputs) |
|
|
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write(f"User: {inputs}\n") |
|
print(f"Kullanıcı mesajı dosyaya yazıldı: {inputs}") |
|
except Exception as e: |
|
print(f"Dosya yazma hatası (Kullanıcı): {e}") |
|
|
|
chatbot.append({"role": "user", "content": inputs}) |
|
response = requests.post(API_URL, headers=headers, json=payload, stream=True) |
|
|
|
if response.status_code != 200: |
|
print(f"API hatası: {response.text}") |
|
return chatbot, history, chat_counter |
|
|
|
assistant_response = "" |
|
for chunk in response.iter_lines(): |
|
if not chunk: |
|
continue |
|
chunk_str = chunk.decode('utf-8') |
|
if chunk_str.startswith("data: ") and chunk_str != "data: [DONE]": |
|
try: |
|
chunk_data = json.loads(chunk_str[6:]) |
|
delta = chunk_data['choices'][0]['delta'] |
|
if 'content' in delta and delta['content']: |
|
assistant_response += delta['content'] |
|
except json.JSONDecodeError as e: |
|
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}") |
|
elif chunk_str == "data: [DONE]": |
|
break |
|
|
|
if assistant_response: |
|
history.append(assistant_response) |
|
chatbot.append({"role": "assistant", "content": assistant_response}) |
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write(f"Bot: {assistant_response}\n") |
|
print(f"Bot yanıtı dosyaya yazıldı: {assistant_response}") |
|
except Exception as e: |
|
print(f"Dosya yazma hatası (Bot): {e}") |
|
|
|
return chatbot, history, chat_counter |
|
|
|
def reset_textbox(): |
|
return gr.update(value='') |
|
|
|
demo_css = """ |
|
#send_button { |
|
background-color: #0b93f6; |
|
border: none; |
|
color: white; |
|
font-size: 16px; |
|
border-radius: 10%; |
|
width: 100px !important; |
|
height: 37px !important; |
|
display: inline-flex; |
|
align-items: center; |
|
justify-content: center; |
|
cursor: pointer; |
|
transition: background-color 0.3s; |
|
margin: 5px; |
|
} |
|
#send_button:hover { |
|
background-color: #0077c0; |
|
} |
|
.fixed_button_container { |
|
padding: 0px; |
|
margin: 0px 0 0 0px; |
|
} |
|
#custom_row { |
|
width: 150% !important; |
|
flex-wrap: nowrap !important; |
|
} |
|
@media only screen and (max-width: 1000px) { |
|
.custom_row { |
|
flex-wrap: nowrap !important; |
|
} |
|
} |
|
#chatbot { |
|
height: 100vh; |
|
overflow-y: auto; |
|
} |
|
""" |
|
|
|
theme = gr.themes.Base( |
|
neutral_hue="blue", |
|
text_size="sm", |
|
spacing_size="sm", |
|
) |
|
|
|
with gr.Blocks(css=demo_css, theme=theme) as demo: |
|
if not os.path.exists(LOG_FILE): |
|
with open(LOG_FILE, 'w', encoding='utf-8') as f: |
|
f.write("--- Yeni Sohbet ---\n") |
|
|
|
with gr.Column(elem_id="col_container"): |
|
with gr.Accordion("", open=False, visible=False): |
|
system_msg = gr.Textbox(value="") |
|
new_msg = gr.Textbox(value="") |
|
accordion_msg = gr.HTML(value="", visible=False) |
|
|
|
chatbot = gr.Chatbot(label='Trek Asistanı', elem_id="chatbot", type="messages") |
|
|
|
with gr.Row(elem_id="custom_row"): |
|
inputs = gr.Textbox( |
|
placeholder="Buraya yazın", |
|
show_label=False, |
|
container=False, |
|
) |
|
with gr.Column(elem_classes="fixed_button_container"): |
|
send_button = gr.Button(value="Gönder", elem_id="send_button") |
|
|
|
state = gr.State([]) |
|
|
|
with gr.Accordion("", open=False, visible=False): |
|
top_p = gr.Slider(minimum=0, maximum=1.0, value=0.5, step=0.05, interactive=False, visible=False) |
|
temperature = gr.Slider(minimum=0, maximum=5.0, value=0.1, step=0.1, interactive=False, visible=False) |
|
chat_counter = gr.Number(value=0, visible=False, precision=0) |
|
|
|
chatbot_ref = [] |
|
def update_chatbot_ref(chat): |
|
chatbot_ref[:] = chat |
|
return chat |
|
|
|
inputs.submit(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]).then(update_chatbot_ref, chatbot, chatbot).then(reset_textbox, [], [inputs]) |
|
send_button.click(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]).then(update_chatbot_ref, chatbot, chatbot).then(reset_textbox, [], [inputs]) |
|
|
|
scheduler_thread = threading.Thread(target=run_scheduler, args=(chatbot_ref,), daemon=True) |
|
scheduler_thread.start() |
|
|
|
demo.launch(debug=True) |