from flask import Flask, render_template, request, jsonify import json import numpy as np import nltk from nltk.stem import PorterStemmer # استيراد مكتبات التنسرفلو للتدريب from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, Input from tensorflow.keras.optimizers import Adam import random import os # ======================================================== # 1. إعداد NLTK (تحميل ملفات اللغة) # ======================================================== nltk_data_path = os.path.join(os.getcwd(), 'nltk_data') if not os.path.exists(nltk_data_path): os.makedirs(nltk_data_path, exist_ok=True) nltk.data.path.append(nltk_data_path) print("Downloading NLTK data...") nltk.download('punkt', download_dir=nltk_data_path, quiet=True) nltk.download('wordnet', download_dir=nltk_data_path, quiet=True) nltk.download('punkt_tab', download_dir=nltk_data_path, quiet=True) nltk.download('omw-1.4', download_dir=nltk_data_path, quiet=True) print("✅ NLTK data downloaded.") # ======================================================== # 2. دالة التدريب (Train on Startup) # ======================================================== stemmer = PorterStemmer() ignore_words = ['?', '!', '.', ','] def train_model(): print("🔄 Starting training on server...") try: with open('intents.json', 'r', encoding='utf-8') as file: data = json.load(file) except Exception as e: print(f"🛑 Error reading intents.json: {e}") return None, None, None, None words = [] classes = [] documents = [] for intent in data['intents']: tag = intent['tag'] if tag not in classes: classes.append(tag) for pattern in intent['patterns']: w = nltk.word_tokenize(pattern) words.extend(w) documents.append((w, tag)) words = [stemmer.stem(w.lower()) for w in words if w not in ignore_words] words = sorted(list(set(words))) classes = sorted(list(set(classes))) training_data = [] output_empty = [0] * len(classes) for doc in documents: bag = [] pattern_words = [stemmer.stem(word.lower()) for word in doc[0]] for w in words: bag.append(1) if w in pattern_words else bag.append(0) output_row = list(output_empty) output_row[classes.index(doc[1])] = 1 training_data.append([np.array(bag), np.array(output_row)]) random.shuffle(training_data) train_x = np.array([item[0] for item in training_data]) train_y = np.array([item[1] for item in training_data]) # بناء النموذج model = Sequential() model.add(Input(shape=(len(train_x[0]),))) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(64, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(len(train_y[0]), activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.01), metrics=['accuracy']) # التدريب model.fit(train_x, train_y, epochs=200, batch_size=5, verbose=0) print("✅ Training completed successfully on server.") return model, words, classes, data # ======================================================== # 3. تشغيل التطبيق # ======================================================== app = Flask(__name__) # بدء التدريب فور التشغيل model, words, classes, intents = train_model() def clean_up_sentence(sentence): sentence_words = nltk.word_tokenize(sentence) sentence_words = [stemmer.stem(word.lower()) for word in sentence_words if word not in ignore_words] return sentence_words def bag_of_words(sentence, words): sentence_words = clean_up_sentence(sentence) bag = [0] * len(words) for s in sentence_words: for i, w in enumerate(words): if w == s: bag[i] = 1 return np.array(bag) def predict_class(sentence): if model is None: return [] bow = bag_of_words(sentence, words) res = model.predict(np.array([bow]), verbose=0)[0] ERROR_THRESHOLD = 0.25 results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD] results.sort(key=lambda x: x[1], reverse=True) return_list = [] for r in results: return_list.append({"intent": classes[r[0]], "probability": str(r[1])}) return return_list def get_response(ints, intents_json): if not ints: return "I'm sorry, I didn't understand that." tag = ints[0]['intent'] list_of_intents = intents_json['intents'] for i in list_of_intents: if i['tag'] == tag: result = random.choice(i['responses']) break else: result = "I'm sorry, I don't have a response for that." return result # --- Routes --- @app.route("/") def home(): return render_template("index.html") @app.route("/get_response", methods=["POST"]) def chatbot_response(): try: msg = request.json.get('msg') if msg: ints = predict_class(msg) res = get_response(ints, intents) return jsonify({"response": res}) else: return jsonify({"response": "Empty message"}) except Exception as e: return jsonify({"response": f"Error: {str(e)}"}) if __name__ == "__main__": # تشغيل السيرفر على المنفذ 7860 app.run(host='0.0.0.0', port=7860)