Zwea Htet commited on
Commit
90653e1
β€’
1 Parent(s): 96b6b0b

added flask ui code

Browse files
app.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import os
2
+ # from datetime import datetime
3
+
4
+ # from flask import Flask, redirect, render_template, request, url_for
5
+ # from model import initialize_index
6
+
7
+ # app = Flask(__name__)
8
+ # index = None
9
+
10
+ # @app.route("/")
11
+ # def home():
12
+ # return render_template('chat.html')
13
+
14
+ # @app.route("/get")
15
+ # def get_bot_response():
16
+ # query_text = request.args.get("msg", None)
17
+ # if query_text is None:
18
+ # return "Invalid input"
19
+ # response = index.query(query_text)
20
+ # return str(response), 200
21
+
22
+ # if __name__ == "__main__":
23
+ # index = initialize_index("index.json")
24
+ # app.run(debug=True)
25
+ import os
26
+ from datetime import datetime
27
+
28
+ import openai
29
+ from flask import Flask, redirect, render_template, request, session, url_for
30
+ from model import initialize_index
31
+
32
+ app = Flask(__name__)
33
+ app.secret_key = os.environ.get('SECRET_KEY', 'my-secret-key')
34
+ index = None
35
+
36
+ # Set up OpenAI authentication
37
+ # openai.api_key = os.environ.get('OPENAI_API_KEY')
38
+
39
+ @app.route("/")
40
+ def home():
41
+ if 'access_token' not in session:
42
+ return render_template('auth.html')
43
+ global index
44
+ try:
45
+ index = initialize_index("index.json")
46
+ except:
47
+ return render_template("auth.html", error="Invalid Token Key")
48
+ return render_template('chat.html')
49
+
50
+
51
+ @app.route("/login", methods=["GET", "POST"])
52
+ def login():
53
+ if request.method == "POST":
54
+ username = request.form.get("username")
55
+ access_token = request.form.get("access_token")
56
+ openai.api_key = access_token
57
+ session['access_token'] = access_token
58
+ return redirect(url_for('home'))
59
+ return render_template('auth.html')
60
+
61
+ @app.route("/logout")
62
+ def logout():
63
+ session.pop('access_token', None)
64
+ return redirect(url_for('home'))
65
+
66
+ @app.route("/chat")
67
+ def chat():
68
+ query_text = request.args.get("msg", None)
69
+ if query_text is None:
70
+ return "Invalid input"
71
+
72
+ if 'access_token' not in session:
73
+ return redirect(url_for('login'))
74
+
75
+ response = index.query(query_text)
76
+ return str(response), 200
77
+
78
+
79
+ if __name__ == "__main__":
80
+ app.run(debug=True)
data.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import numpy as np
3
+ import pandas as pd
4
+
5
+ df = pd.read_json(r"../../Dataset/regItems.json")
6
+ df = df.replace(to_replace="", value=np.nan).dropna(axis=0) # remove null values
7
+ df['paragraphText'] = df['paragraphText'].str.replace("OLD SECTION.*", "", regex=True) # remove any dirty words
8
+ df['paragraphText'] = df['paragraphText'].str.replace("[a-zA-z]\d\w+", ". ", regex=True)
9
+ df['paragraphText'] = df['paragraphText'].str.lower()
10
+
11
+ data = df['paragraphText'].tolist()
model.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import openai
4
+ from customLLM import CustomLLM, prompt_helper
5
+ from data import data
6
+ from dotenv import load_dotenv
7
+ from llama_index import (Document, GPTSimpleVectorIndex, LLMPredictor,
8
+ ServiceContext)
9
+
10
+ load_dotenv()
11
+
12
+ # openai.api_key = os.getenv("OPENAI_API_KEY")
13
+
14
+ #define our llm
15
+ llm_predictor = LLMPredictor(llm=CustomLLM())
16
+ service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper)
17
+
18
+ def initialize_index(index_name):
19
+ if os.path.exists(index_name):
20
+ return GPTSimpleVectorIndex.load_from_disk(index_name)
21
+ else:
22
+ documents = [Document(d) for d in data]
23
+ index = GPTSimpleVectorIndex.from_documents(documents, service_context=service_context)
24
+ index.save_to_disk(index_name)
25
+ return index
model/customLLM.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, List, Mapping, Optional
2
+
3
+ from langchain.llms.base import LLM
4
+ from llama_index import (Document, GPTSimpleVectorIndex, LLMPredictor,
5
+ PromptHelper, ServiceContext, SimpleDirectoryReader)
6
+ from transformers import (AutoModelForCausalLM, AutoTokenizer, GPT2LMHeadModel,
7
+ GPT2Tokenizer, pipeline)
8
+
9
+ # define prompt helper
10
+ # set maximum input size
11
+ max_input_size = 2048
12
+ # set number of output tokens
13
+ num_output = 525
14
+ # set maximum chunk overlap
15
+ max_chunk_overlap = 20
16
+ prompt_helper = PromptHelper(max_input_size, num_output, max_chunk_overlap)
17
+
18
+ model_name = "bigscience/bloom-560m" # "bigscience/bloomz"
19
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
20
+ model = AutoModelForCausalLM.from_pretrained(model_name, config='T5Config')
21
+
22
+ class CustomLLM(LLM):
23
+ # 3. Create the pipeline for question answering
24
+ pipeline = pipeline(
25
+ model=model,
26
+ tokenizer=tokenizer,
27
+ task="text-generation",
28
+ # device=0, # GPU device number
29
+ max_length=512,
30
+ do_sample=True,
31
+ top_p=0.95,
32
+ top_k=50,
33
+ temperature=0.7
34
+ )
35
+
36
+ def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
37
+ prompt_length = len(prompt)
38
+ response = self.pipeline(prompt, max_new_tokens=num_output)[0]["generated_text"]
39
+
40
+ # only return newly generated tokens
41
+ return response[prompt_length:]
42
+
43
+ @property
44
+ def _identifying_params(self) -> Mapping[str, Any]:
45
+ return {"name_of_model": self.model_name}
46
+
47
+ @property
48
+ def _llm_type(self) -> str:
49
+ return "custom"
model/model.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import openai
4
+ from customLLM import CustomLLM, prompt_helper
5
+ from data import data
6
+ from dotenv import load_dotenv
7
+ from llama_index import (Document, GPTSimpleVectorIndex, LLMPredictor,
8
+ ServiceContext)
9
+
10
+ load_dotenv()
11
+
12
+ # openai.api_key = os.getenv("OPENAI_API_KEY")
13
+
14
+ #define our llm
15
+ llm_predictor = LLMPredictor(llm=CustomLLM())
16
+ service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper)
17
+
18
+ def initialize_index(index_name):
19
+ if os.path.exists(index_name):
20
+ return GPTSimpleVectorIndex.load_from_disk(index_name)
21
+ else:
22
+ documents = [Document(d) for d in data]
23
+ index = GPTSimpleVectorIndex.from_documents(documents, service_context=service_context)
24
+ index.save_to_disk(index_name)
25
+ return index
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Click
2
+ Flask
3
+ Flask-SQLAlchemy
4
+ gunicorn
5
+ itsdangerous
6
+ Jinja2
7
+ MarkupSafe
8
+ SQLAlchemy
9
+ Werkzeug
10
+ llama_index
11
+ torch
12
+ transformers
13
+ panda
14
+ numpy
15
+ langchain
16
+ python-dotenv
17
+ flask-login
styles/auth.css ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Center the text input fields */
2
+ input[type=text],
3
+ input[type=password] {
4
+ width: 100%;
5
+ padding: 12px 20px;
6
+ margin: 8px 0;
7
+ display: inline-block;
8
+ border: 1px solid #ccc;
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ /* Add a gradient background */
13
+ body {
14
+ background: linear-gradient(to bottom right, #1a237e, #3949ab);
15
+ }
16
+
17
+ /* Center the login box */
18
+ .login-box {
19
+ margin: auto;
20
+ width: 300px;
21
+ background-color: white;
22
+ padding: 20px;
23
+ border-radius: 5px;
24
+ /* text-align: center; */
25
+ box-shadow: 0px 0px 10px #888;
26
+ }
27
+
28
+ /* Style the login button */
29
+ .login-button {
30
+ background-color: #4caf50;
31
+ color: white;
32
+ padding: 14px 20px;
33
+ margin: 8px 0;
34
+ border: none;
35
+ border-radius: 5px;
36
+ cursor: pointer;
37
+ width: 100%;
38
+ }
39
+
40
+ /* Style error messages */
41
+ .error-message {
42
+ color: red;
43
+ }
styles/chat.css ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --body-bg: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
3
+ --msger-bg: #fff;
4
+ --border: 2px solid #ddd;
5
+ --left-msg-bg: #ececec;
6
+ --right-msg-bg: #579ffb;
7
+ }
8
+
9
+ html {
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ *,
14
+ *:before,
15
+ *:after {
16
+ margin: 0;
17
+ padding: 0;
18
+ box-sizing: inherit;
19
+ }
20
+
21
+ body {
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ height: 100vh;
26
+ background-image: var(--body-bg);
27
+ font-family: Helvetica, sans-serif;
28
+ }
29
+
30
+ .msger {
31
+ display: flex;
32
+ flex-flow: column wrap;
33
+ justify-content: space-between;
34
+ width: 100%;
35
+ max-width: 867px;
36
+ margin: 25px 10px;
37
+ height: calc(100% - 50px);
38
+ border: var(--border);
39
+ border-radius: 5px;
40
+ background: var(--msger-bg);
41
+ box-shadow: 0 15px 15px -5px rgba(0, 0, 0, 0.2);
42
+ }
43
+
44
+ .msger-header {
45
+ /* display: flex; */
46
+ font-size: medium;
47
+ justify-content: space-between;
48
+ padding: 10px;
49
+ text-align: center;
50
+ border-bottom: var(--border);
51
+ background: #eee;
52
+ color: #666;
53
+ }
54
+
55
+ .msger-chat {
56
+ flex: 1;
57
+ overflow-y: auto;
58
+ padding: 10px;
59
+ }
60
+
61
+ .msger-chat::-webkit-scrollbar {
62
+ width: 6px;
63
+ }
64
+
65
+ .msger-chat::-webkit-scrollbar-track {
66
+ background: #ddd;
67
+ }
68
+
69
+ .msger-chat::-webkit-scrollbar-thumb {
70
+ background: #bdbdbd;
71
+ }
72
+
73
+ .msg {
74
+ display: flex;
75
+ align-items: flex-end;
76
+ margin-bottom: 10px;
77
+ }
78
+
79
+ .msg-img {
80
+ width: 50px;
81
+ height: 50px;
82
+ margin-right: 10px;
83
+ background: #ddd;
84
+ background-repeat: no-repeat;
85
+ background-position: center;
86
+ background-size: cover;
87
+ border-radius: 50%;
88
+ }
89
+
90
+ .msg-bubble {
91
+ max-width: 450px;
92
+ padding: 15px;
93
+ border-radius: 15px;
94
+ background: var(--left-msg-bg);
95
+ }
96
+
97
+ .msg-info {
98
+ display: flex;
99
+ justify-content: space-between;
100
+ align-items: center;
101
+ margin-bottom: 10px;
102
+ }
103
+
104
+ .msg-info-name {
105
+ margin-right: 10px;
106
+ font-weight: bold;
107
+ }
108
+
109
+ .msg-info-time {
110
+ font-size: 0.85em;
111
+ }
112
+
113
+ .left-msg .msg-bubble {
114
+ border-bottom-left-radius: 0;
115
+ }
116
+
117
+ .right-msg {
118
+ flex-direction: row-reverse;
119
+ }
120
+
121
+ .right-msg .msg-bubble {
122
+ background: var(--right-msg-bg);
123
+ color: #fff;
124
+ border-bottom-right-radius: 0;
125
+ }
126
+
127
+ .right-msg .msg-img {
128
+ margin: 0 0 0 10px;
129
+ }
130
+
131
+ .msger-inputarea {
132
+ display: flex;
133
+ padding: 10px;
134
+ border-top: var(--border);
135
+ background: #eee;
136
+ }
137
+
138
+ .msger-inputarea * {
139
+ padding: 10px;
140
+ border: none;
141
+ border-radius: 3px;
142
+ font-size: 1em;
143
+ }
144
+
145
+ .msger-input {
146
+ flex: 1;
147
+ background: #ddd;
148
+ }
149
+
150
+ .msger-send-btn {
151
+ margin-left: 10px;
152
+ background: rgb(0, 196, 65);
153
+ color: #fff;
154
+ font-weight: bold;
155
+ cursor: pointer;
156
+ transition: background 0.23s;
157
+ }
158
+
159
+ .msger-send-btn:hover {
160
+ background: rgb(0, 180, 50);
161
+ }
162
+
163
+ .msger-chat {
164
+ background-color: #fcfcfe;
165
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260' viewBox='0 0 260 260'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23dddddd' fill-opacity='0.4'%3E%3Cpath d='M24.37 16c.2.65.39 1.32.54 2H21.17l1.17 2.34.45.9-.24.11V28a5 5 0 0 1-2.23 8.94l-.02.06a8 8 0 0 1-7.75 6h-20a8 8 0 0 1-7.74-6l-.02-.06A5 5 0 0 1-17.45 28v-6.76l-.79-1.58-.44-.9.9-.44.63-.32H-20a23.01 23.01 0 0 1 44.37-2zm-36.82 2a1 1 0 0 0-.44.1l-3.1 1.56.89 1.79 1.31-.66a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .86.02l2.88-1.27a3 3 0 0 1 2.43 0l2.88 1.27a1 1 0 0 0 .85-.02l3.1-1.55-.89-1.79-1.42.71a3 3 0 0 1-2.56.06l-2.77-1.23a1 1 0 0 0-.4-.09h-.01a1 1 0 0 0-.4.09l-2.78 1.23a3 3 0 0 1-2.56-.06l-2.3-1.15a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1L.9 19.22a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01zm0-2h-4.9a21.01 21.01 0 0 1 39.61 0h-2.09l-.06-.13-.26.13h-32.31zm30.35 7.68l1.36-.68h1.3v2h-36v-1.15l.34-.17 1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0L2.26 23h2.59l1.36.68a3 3 0 0 0 2.56.06l1.67-.74h3.23l1.67.74a3 3 0 0 0 2.56-.06zM-13.82 27l16.37 4.91L18.93 27h-32.75zm-.63 2h.34l16.66 5 16.67-5h.33a3 3 0 1 1 0 6h-34a3 3 0 1 1 0-6zm1.35 8a6 6 0 0 0 5.65 4h20a6 6 0 0 0 5.66-4H-13.1z'/%3E%3Cpath id='path6_fill-copy' d='M284.37 16c.2.65.39 1.32.54 2H281.17l1.17 2.34.45.9-.24.11V28a5 5 0 0 1-2.23 8.94l-.02.06a8 8 0 0 1-7.75 6h-20a8 8 0 0 1-7.74-6l-.02-.06a5 5 0 0 1-2.24-8.94v-6.76l-.79-1.58-.44-.9.9-.44.63-.32H240a23.01 23.01 0 0 1 44.37-2zm-36.82 2a1 1 0 0 0-.44.1l-3.1 1.56.89 1.79 1.31-.66a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .86.02l2.88-1.27a3 3 0 0 1 2.43 0l2.88 1.27a1 1 0 0 0 .85-.02l3.1-1.55-.89-1.79-1.42.71a3 3 0 0 1-2.56.06l-2.77-1.23a1 1 0 0 0-.4-.09h-.01a1 1 0 0 0-.4.09l-2.78 1.23a3 3 0 0 1-2.56-.06l-2.3-1.15a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01zm0-2h-4.9a21.01 21.01 0 0 1 39.61 0h-2.09l-.06-.13-.26.13h-32.31zm30.35 7.68l1.36-.68h1.3v2h-36v-1.15l.34-.17 1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.56.06l1.67-.74h3.23l1.67.74a3 3 0 0 0 2.56-.06zM246.18 27l16.37 4.91L278.93 27h-32.75zm-.63 2h.34l16.66 5 16.67-5h.33a3 3 0 1 1 0 6h-34a3 3 0 1 1 0-6zm1.35 8a6 6 0 0 0 5.65 4h20a6 6 0 0 0 5.66-4H246.9z'/%3E%3Cpath d='M159.5 21.02A9 9 0 0 0 151 15h-42a9 9 0 0 0-8.5 6.02 6 6 0 0 0 .02 11.96A8.99 8.99 0 0 0 109 45h42a9 9 0 0 0 8.48-12.02 6 6 0 0 0 .02-11.96zM151 17h-42a7 7 0 0 0-6.33 4h54.66a7 7 0 0 0-6.33-4zm-9.34 26a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-4.34a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-4.34a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-7a7 7 0 1 1 0-14h42a7 7 0 1 1 0 14h-9.34zM109 27a9 9 0 0 0-7.48 4H101a4 4 0 1 1 0-8h58a4 4 0 0 1 0 8h-.52a9 9 0 0 0-7.48-4h-42z'/%3E%3Cpath d='M39 115a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm6-8a6 6 0 1 1-12 0 6 6 0 0 1 12 0zm-3-29v-2h8v-6H40a4 4 0 0 0-4 4v10H22l-1.33 4-.67 2h2.19L26 130h26l3.81-40H58l-.67-2L56 84H42v-6zm-4-4v10h2V74h8v-2h-8a2 2 0 0 0-2 2zm2 12h14.56l.67 2H22.77l.67-2H40zm13.8 4H24.2l3.62 38h22.36l3.62-38z'/%3E%3Cpath d='M129 92h-6v4h-6v4h-6v14h-3l.24 2 3.76 32h36l3.76-32 .24-2h-3v-14h-6v-4h-6v-4h-8zm18 22v-12h-4v4h3v8h1zm-3 0v-6h-4v6h4zm-6 6v-16h-4v19.17c1.6-.7 2.97-1.8 4-3.17zm-6 3.8V100h-4v23.8a10.04 10.04 0 0 0 4 0zm-6-.63V104h-4v16a10.04 10.04 0 0 0 4 3.17zm-6-9.17v-6h-4v6h4zm-6 0v-8h3v-4h-4v12h1zm27-12v-4h-4v4h3v4h1v-4zm-6 0v-8h-4v4h3v4h1zm-6-4v-4h-4v8h1v-4h3zm-6 4v-4h-4v8h1v-4h3zm7 24a12 12 0 0 0 11.83-10h7.92l-3.53 30h-32.44l-3.53-30h7.92A12 12 0 0 0 130 126z'/%3E%3Cpath d='M212 86v2h-4v-2h4zm4 0h-2v2h2v-2zm-20 0v.1a5 5 0 0 0-.56 9.65l.06.25 1.12 4.48a2 2 0 0 0 1.94 1.52h.01l7.02 24.55a2 2 0 0 0 1.92 1.45h4.98a2 2 0 0 0 1.92-1.45l7.02-24.55a2 2 0 0 0 1.95-1.52L224.5 96l.06-.25a5 5 0 0 0-.56-9.65V86a14 14 0 0 0-28 0zm4 0h6v2h-9a3 3 0 1 0 0 6H223a3 3 0 1 0 0-6H220v-2h2a12 12 0 1 0-24 0h2zm-1.44 14l-1-4h24.88l-1 4h-22.88zm8.95 26l-6.86-24h18.7l-6.86 24h-4.98zM150 242a22 22 0 1 0 0-44 22 22 0 0 0 0 44zm24-22a24 24 0 1 1-48 0 24 24 0 0 1 48 0zm-28.38 17.73l2.04-.87a6 6 0 0 1 4.68 0l2.04.87a2 2 0 0 0 2.5-.82l1.14-1.9a6 6 0 0 1 3.79-2.75l2.15-.5a2 2 0 0 0 1.54-2.12l-.19-2.2a6 6 0 0 1 1.45-4.46l1.45-1.67a2 2 0 0 0 0-2.62l-1.45-1.67a6 6 0 0 1-1.45-4.46l.2-2.2a2 2 0 0 0-1.55-2.13l-2.15-.5a6 6 0 0 1-3.8-2.75l-1.13-1.9a2 2 0 0 0-2.5-.8l-2.04.86a6 6 0 0 1-4.68 0l-2.04-.87a2 2 0 0 0-2.5.82l-1.14 1.9a6 6 0 0 1-3.79 2.75l-2.15.5a2 2 0 0 0-1.54 2.12l.19 2.2a6 6 0 0 1-1.45 4.46l-1.45 1.67a2 2 0 0 0 0 2.62l1.45 1.67a6 6 0 0 1 1.45 4.46l-.2 2.2a2 2 0 0 0 1.55 2.13l2.15.5a6 6 0 0 1 3.8 2.75l1.13 1.9a2 2 0 0 0 2.5.8zm2.82.97a4 4 0 0 1 3.12 0l2.04.87a4 4 0 0 0 4.99-1.62l1.14-1.9a4 4 0 0 1 2.53-1.84l2.15-.5a4 4 0 0 0 3.09-4.24l-.2-2.2a4 4 0 0 1 .97-2.98l1.45-1.67a4 4 0 0 0 0-5.24l-1.45-1.67a4 4 0 0 1-.97-2.97l.2-2.2a4 4 0 0 0-3.09-4.25l-2.15-.5a4 4 0 0 1-2.53-1.84l-1.14-1.9a4 4 0 0 0-5-1.62l-2.03.87a4 4 0 0 1-3.12 0l-2.04-.87a4 4 0 0 0-4.99 1.62l-1.14 1.9a4 4 0 0 1-2.53 1.84l-2.15.5a4 4 0 0 0-3.09 4.24l.2 2.2a4 4 0 0 1-.97 2.98l-1.45 1.67a4 4 0 0 0 0 5.24l1.45 1.67a4 4 0 0 1 .97 2.97l-.2 2.2a4 4 0 0 0 3.09 4.25l2.15.5a4 4 0 0 1 2.53 1.84l1.14 1.9a4 4 0 0 0 5 1.62l2.03-.87zM152 207a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm6 2a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-11 1a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-6 0a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm3-5a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-8 8a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm3 6a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm0 6a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm4 7a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5-2a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5 4a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm4-6a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm6-4a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-4-3a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm4-3a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-5-4a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm-24 6a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm16 5a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm7-5a7 7 0 1 1-14 0 7 7 0 0 1 14 0zm86-29a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm19 9a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm-14 5a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm-25 1a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm5 4a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm9 0a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm15 1a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm12-2a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm-11-14a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm-19 0a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm6 5a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm-25 15c0-.47.01-.94.03-1.4a5 5 0 0 1-1.7-8 3.99 3.99 0 0 1 1.88-5.18 5 5 0 0 1 3.4-6.22 3 3 0 0 1 1.46-1.05 5 5 0 0 1 7.76-3.27A30.86 30.86 0 0 1 246 184c6.79 0 13.06 2.18 18.17 5.88a5 5 0 0 1 7.76 3.27 3 3 0 0 1 1.47 1.05 5 5 0 0 1 3.4 6.22 4 4 0 0 1 1.87 5.18 4.98 4.98 0 0 1-1.7 8c.02.46.03.93.03 1.4v1h-62v-1zm.83-7.17a30.9 30.9 0 0 0-.62 3.57 3 3 0 0 1-.61-4.2c.37.28.78.49 1.23.63zm1.49-4.61c-.36.87-.68 1.76-.96 2.68a2 2 0 0 1-.21-3.71c.33.4.73.75 1.17 1.03zm2.32-4.54c-.54.86-1.03 1.76-1.49 2.68a3 3 0 0 1-.07-4.67 3 3 0 0 0 1.56 1.99zm1.14-1.7c.35-.5.72-.98 1.1-1.46a1 1 0 1 0-1.1 1.45zm5.34-5.77c-1.03.86-2 1.79-2.9 2.77a3 3 0 0 0-1.11-.77 3 3 0 0 1 4-2zm42.66 2.77c-.9-.98-1.87-1.9-2.9-2.77a3 3 0 0 1 4.01 2 3 3 0 0 0-1.1.77zm1.34 1.54c.38.48.75.96 1.1 1.45a1 1 0 1 0-1.1-1.45zm3.73 5.84c-.46-.92-.95-1.82-1.5-2.68a3 3 0 0 0 1.57-1.99 3 3 0 0 1-.07 4.67zm1.8 4.53c-.29-.9-.6-1.8-.97-2.67.44-.28.84-.63 1.17-1.03a2 2 0 0 1-.2 3.7zm1.14 5.51c-.14-1.21-.35-2.4-.62-3.57.45-.14.86-.35 1.23-.63a2.99 2.99 0 0 1-.6 4.2zM275 214a29 29 0 0 0-57.97 0h57.96zM72.33 198.12c-.21-.32-.34-.7-.34-1.12v-12h-2v12a4.01 4.01 0 0 0 7.09 2.54c.57-.69.91-1.57.91-2.54v-12h-2v12a1.99 1.99 0 0 1-2 2 2 2 0 0 1-1.66-.88zM75 176c.38 0 .74-.04 1.1-.12a4 4 0 0 0 6.19 2.4A13.94 13.94 0 0 1 84 185v24a6 6 0 0 1-6 6h-3v9a5 5 0 1 1-10 0v-9h-3a6 6 0 0 1-6-6v-24a14 14 0 0 1 14-14 5 5 0 0 0 5 5zm-17 15v12a1.99 1.99 0 0 0 1.22 1.84 2 2 0 0 0 2.44-.72c.21-.32.34-.7.34-1.12v-12h2v12a3.98 3.98 0 0 1-5.35 3.77 3.98 3.98 0 0 1-.65-.3V209a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4v-24c.01-1.53-.23-2.88-.72-4.17-.43.1-.87.16-1.28.17a6 6 0 0 1-5.2-3 7 7 0 0 1-6.47-4.88A12 12 0 0 0 58 185v6zm9 24v9a3 3 0 1 0 6 0v-9h-6z'/%3E%3Cpath d='M-17 191a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm19 9a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1zm-14 5a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm-25 1a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm5 4a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm9 0a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm15 1a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm12-2a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2H4zm-11-14a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm-19 0a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2h-2zm6 5a1 1 0 0 1 1-1h2a1 1 0 0 1 0 2h-2a1 1 0 0 1-1-1zm-25 15c0-.47.01-.94.03-1.4a5 5 0 0 1-1.7-8 3.99 3.99 0 0 1 1.88-5.18 5 5 0 0 1 3.4-6.22 3 3 0 0 1 1.46-1.05 5 5 0 0 1 7.76-3.27A30.86 30.86 0 0 1-14 184c6.79 0 13.06 2.18 18.17 5.88a5 5 0 0 1 7.76 3.27 3 3 0 0 1 1.47 1.05 5 5 0 0 1 3.4 6.22 4 4 0 0 1 1.87 5.18 4.98 4.98 0 0 1-1.7 8c.02.46.03.93.03 1.4v1h-62v-1zm.83-7.17a30.9 30.9 0 0 0-.62 3.57 3 3 0 0 1-.61-4.2c.37.28.78.49 1.23.63zm1.49-4.61c-.36.87-.68 1.76-.96 2.68a2 2 0 0 1-.21-3.71c.33.4.73.75 1.17 1.03zm2.32-4.54c-.54.86-1.03 1.76-1.49 2.68a3 3 0 0 1-.07-4.67 3 3 0 0 0 1.56 1.99zm1.14-1.7c.35-.5.72-.98 1.1-1.46a1 1 0 1 0-1.1 1.45zm5.34-5.77c-1.03.86-2 1.79-2.9 2.77a3 3 0 0 0-1.11-.77 3 3 0 0 1 4-2zm42.66 2.77c-.9-.98-1.87-1.9-2.9-2.77a3 3 0 0 1 4.01 2 3 3 0 0 0-1.1.77zm1.34 1.54c.38.48.75.96 1.1 1.45a1 1 0 1 0-1.1-1.45zm3.73 5.84c-.46-.92-.95-1.82-1.5-2.68a3 3 0 0 0 1.57-1.99 3 3 0 0 1-.07 4.67zm1.8 4.53c-.29-.9-.6-1.8-.97-2.67.44-.28.84-.63 1.17-1.03a2 2 0 0 1-.2 3.7zm1.14 5.51c-.14-1.21-.35-2.4-.62-3.57.45-.14.86-.35 1.23-.63a2.99 2.99 0 0 1-.6 4.2zM15 214a29 29 0 0 0-57.97 0h57.96z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
166
+ }
templates/auth.html ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends 'base.html' %}
2
+
3
+ {% block title %}Login{% endblock %}
4
+
5
+ {% block content %}
6
+ <div class="login-box">
7
+ <h2 style="text-align: center">Login</h2>
8
+ {% if error %}
9
+ <p class="error-message">{{ error }}</p>
10
+ {% endif %}
11
+
12
+ <form action="{{ url_for('login') }}" method="post">
13
+ <label for="username">Username</label>
14
+ <input type="text" id="username" name="username" placeholder="Enter username" required>
15
+
16
+ <label for="accessToken">Access Token</label>
17
+ <input type="password" id="access_token" name="access_token" placeholder="Enter Token Key" required>
18
+
19
+ <button type="submit" class="login-button">Login</button>
20
+ </form>
21
+ </div>
22
+
23
+ {% endblock %}
templates/base.html ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
+ <title>{% block title %}{% endblock %}</title>
9
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat.css') }}">
10
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/auth.css') }}">
11
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
12
+ </head>
13
+
14
+ <body>
15
+ {% block content %}{% endblock %}
16
+ </body>
17
+
18
+ </html>
templates/chat.html ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends 'base.html' %}
2
+
3
+ {% block title %}CA Waterboard Chatbot{% endblock %}
4
+
5
+ {% block content %}
6
+ <!-- partial:index.partial.html -->
7
+ <section class="msger">
8
+ <header class="msger-header">
9
+ <div class="msger-header-title">
10
+ <i class="fas fa-bug"></i> Chatbot <i class="fas fa-bug"></i>
11
+ </div>
12
+
13
+ {% if session.logged_in %}
14
+ <a href="{{ url_for('logout') }}" class="msger-logout-btn">Logout</a>
15
+ {% endif %}
16
+ </header>
17
+
18
+ <main class="msger-chat">
19
+ <div class="msg left-msg">
20
+ <div class="msg-img" style="background-image: url(https://image.flaticon.com/icons/svg/327/327779.svg)">
21
+ </div>
22
+
23
+ <div class="msg-bubble">
24
+ <div class="msg-info">
25
+ <div class="msg-info-name">Chatbot</div>
26
+ <div class="msg-info-time">12:45</div>
27
+ </div>
28
+
29
+ <div class="msg-text">
30
+ Hi, welcome to ChatBot! Go ahead and send me a message. πŸ˜„
31
+ </div>
32
+ </div>
33
+ </div>
34
+
35
+ </main>
36
+
37
+ <form class="msger-inputarea" action="/" method="POST">
38
+ <input type="text" class="msger-input" id="textInput" placeholder="Enter your message...">
39
+ <button type="submit" class="msger-send-btn">Send</button>
40
+ </form>
41
+ </section>
42
+ <!-- partial -->
43
+ <script src='https://use.fontawesome.com/releases/v5.0.13/js/all.js'></script>
44
+ <script>
45
+
46
+ const msgerForm = get(".msger-inputarea");
47
+ const msgerInput = get(".msger-input");
48
+ const msgerChat = get(".msger-chat");
49
+
50
+
51
+ // Icons made by Freepik from www.flaticon.com
52
+ const BOT_IMG = "https://image.flaticon.com/icons/svg/327/327779.svg";
53
+ const PERSON_IMG = "https://image.flaticon.com/icons/svg/145/145867.svg";
54
+ const BOT_NAME = " ChatBot";
55
+ const PERSON_NAME = "You";
56
+
57
+ msgerForm.addEventListener("submit", event => {
58
+ event.preventDefault();
59
+
60
+ const msgText = msgerInput.value;
61
+ if (!msgText) return;
62
+
63
+ appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
64
+ msgerInput.value = "";
65
+ botResponse(msgText);
66
+ });
67
+
68
+ function appendMessage(name, img, side, text) {
69
+ // Simple solution for small apps
70
+ const msgHTML = `
71
+ <div class="msg ${side}-msg">
72
+ <div class="msg-img" style="background-image: url(${img})"></div>
73
+
74
+ <div class="msg-bubble">
75
+ <div class="msg-info">
76
+ <div class="msg-info-name">${name}</div>
77
+ <div class="msg-info-time">${formatDate(new Date())}</div>
78
+ </div>
79
+
80
+ <div class="msg-text">${text}</div>
81
+ </div>
82
+ </div>
83
+ `;
84
+
85
+ msgerChat.insertAdjacentHTML("beforeend", msgHTML);
86
+ msgerChat.scrollTop += 500;
87
+ }
88
+
89
+ function botResponse(rawText) {
90
+
91
+ // Bot Response
92
+ $.get("/chat", { msg: rawText }).done(function (data) {
93
+ console.log(rawText);
94
+ console.log(data);
95
+ const msgText = data;
96
+ appendMessage(BOT_NAME, BOT_IMG, "left", msgText);
97
+
98
+ });
99
+
100
+ }
101
+
102
+
103
+ // Utils
104
+ function get(selector, root = document) {
105
+ return root.querySelector(selector);
106
+ }
107
+
108
+ function formatDate(date) {
109
+ const h = "0" + date.getHours();
110
+ const m = "0" + date.getMinutes();
111
+
112
+ return `${h.slice(-2)}:${m.slice(-2)}`;
113
+ }
114
+ </script>
115
+
116
+ {% endblock %}
templates/update.html ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends 'base.html' %}
2
+
3
+ {% block head %}
4
+ <title>Task Master</title>
5
+ {% endblock %}
6
+
7
+ {% block body %}
8
+ <div class="content">
9
+ <h1 style="text-align: center">Update Task</h1>
10
+
11
+ <div class="form">
12
+ <form action="/update/{{task.id}}" method="POST">
13
+ <input type="text" name="content" id="content" value="{{task.content}}">
14
+ <input type="submit" value="Update">
15
+ </form>
16
+ </div>
17
+ </div>
18
+ {% endblock %}