File size: 6,999 Bytes
7b7289a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
from flask import Flask, request, jsonify, render_template
import gensim
from gensim.models import FastText
from threading import Thread
import numpy as np
from flask_mail import Mail, Message

app = Flask(__name__)

class ModelLoader(Thread):
    def __init__(self, model_type, model_path):
        super().__init__()
        self.model_type = model_type
        self.model_path = model_path
        self.model = None

    def run(self):
        # Load the model
        if self.model_type == 'fasttext':
            self.model = gensim.models.FastText.load(self.model_path)
        elif self.model_type == 'word2vec':
            self.model = gensim.models.Word2Vec.load(self.model_path)
        else:
            raise ValueError("Unsupported model type")

# Initialize model loader threads with local paths
word2vec_loader = ModelLoader('word2vec', 'w2v_shona2.model')
fasttext_loader = ModelLoader('fasttext', 'ft_model1.model')

# Start loading models in the background
word2vec_loader.start()
fasttext_loader.start()

@app.route('/')
def home():
    return render_template('index.html')


# GETTING SIMILAR WORDS
@app.route('/get_similar_words', methods=['POST'])
def get_similar_words():
    word = request.json.get('word')
    model_type = request.json.get('model_type')
    top_n = int(request.json.get('top_n', 10))  # Default to 10 if not provided
    
    if model_type == 'word2vec':
        if word2vec_loader.model is None:
            return jsonify({'error': 'Word2Vec model is still loading'}), 503
        try:
            similar_words = word2vec_loader.model.wv.most_similar(word, topn=top_n)
            return jsonify({'similar_words': similar_words})
        except KeyError:
            return jsonify({'error': 'Word not found in Word2Vec model'}), 404
    elif model_type == 'fasttext':
        if fasttext_loader.model is None:
            return jsonify({'error': 'FastText model is still loading'}), 503
        try:
            similar_words = fasttext_loader.model.wv.most_similar(word, topn=top_n)
            return jsonify({'similar_words': similar_words})
        except KeyError:
            return jsonify({'error': 'Word not found in FastText model'}), 404
    else:
        return jsonify({'error': 'Invalid model type'}), 400



# COMPUTATIONS
@app.route('/compute', methods=['POST'])
def compute():
    data = request.json
    expression = data.get('expression')
    model_type = data.get('model')
    top_n = int(data.get('top_n', 5))

    positive = []
    negative = []

    # Parse the expression into positive and negative lists
    parts = expression.replace('-', '+-').split('+')

    for part in parts:
        part = part.strip()
        if part.startswith('-'):
            negative.append(part[1:].strip())
        elif part:
            positive.append(part)

    # Load the appropriate model and process
    if model_type == 'word2vec':
        if word2vec_loader.model is None:
            return jsonify({'error': 'Word2Vec model is still loading'}), 503
        try:
            result = word2vec_loader.model.wv.most_similar(positive=positive, negative=negative, topn=top_n)
            response = [{'word': word, 'similarity': similarity} for word, similarity in result]
        except Exception as e:
            response = {'error': str(e)}

    elif model_type == 'fasttext':
        try:
            # Check if model is loaded properly
            if fasttext_loader.model is None:
                raise ValueError("The FastText model is not loaded properly.")
            if not hasattr(fasttext_loader.model, 'wv'):
                raise TypeError("The loaded model does not have the 'wv' attribute.")
            
            if not positive:
                raise ValueError("Positive word list is empty.")
            if not isinstance(positive, list) or not isinstance(negative, list):
                raise TypeError("Positive and negative should be lists.")
            
            # Initialize result_vector with a writable copy of the first positive word vector
            result_vector = fasttext_loader.model.wv.get_vector(positive[0]).copy()  

            # Add vectors for positive words
            for word in positive[1:]:
                if word in fasttext_loader.model.wv:
                    result_vector += fasttext_loader.model.wv.get_vector(word)
                else:
                    raise KeyError(f"Word '{word}' not in vocabulary")

            # Subtract vectors for negative words
            for word in negative:
                if word in fasttext_loader.model.wv:
                    result_vector -= fasttext_loader.model.wv.get_vector(word)
                else:
                    raise KeyError(f"Word '{word}' not in vocabulary")

            # Find similar words
            result = fasttext_loader.model.wv.most_similar(positive=[result_vector], topn=top_n)
            
            # Format the results
            response = [{'word': word, 'similarity': similarity} for word, similarity in result]

        except KeyError as e:
            response = {'error': f"KeyError: {str(e)}"}
        except ValueError as e:
            response = {'error': f"ValueError: {str(e)}"}
        except TypeError as e:
            response = {'error': f"TypeError: {str(e)}"}
        except Exception as e:
            response = {'error': f"An unexpected error occurred: {str(e)}"}


        return jsonify(response)

    else:
        return jsonify({'error': 'Invalid model type'})

    return jsonify(response)








# Configure Flask-Mail
app.config['MAIL_SERVER'] = 'smtp.gmail.com'  # Replace with your mail server
app.config['MAIL_PORT'] = 587  # Typically 587 for TLS, or 465 for SSL
app.config['MAIL_USERNAME'] = '[email protected]'  # Replace with your email address
app.config['MAIL_PASSWORD'] = 'jphs dnyg buph srjf'  # Replace with your email password
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False

mail = Mail(app)

@app.route('/submit', methods=['POST'])
def submit():
    # Extract data from the form
    name = request.form.get('name')
    email = request.form.get('email')
    message = request.form.get('message')
    subscribe = 'subscribe' in request.form

    # Create and send the email
    try:
        msg = Message(
            subject='Contact Form Submission',
            sender=email,  # Replace with your email address
            recipients=[app.config['MAIL_USERNAME']],  # Replace with recipient's email address
            body=f"Name: {name}\nEmail: {email}\nMessage: {message}\nSubscribe: {subscribe}"
        )
        mail.send(msg)
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'An error occurred while sending the email: {str(e)}'
        })

    # Return a response
    return jsonify({
        'status': 'success',
        'message': 'Your message has been received and the email has been sent!'
    })



if __name__ == '__main__':
    app.run(debug=True)