Spaces:
Runtime error
Runtime error
Zwea Htet
commited on
Commit
β’
90653e1
1
Parent(s):
96b6b0b
added flask ui code
Browse files- app.py +80 -0
- data.py +11 -0
- model.py +25 -0
- model/customLLM.py +49 -0
- model/model.py +25 -0
- requirements.txt +17 -0
- styles/auth.css +43 -0
- styles/chat.css +166 -0
- templates/auth.html +23 -0
- templates/base.html +18 -0
- templates/chat.html +116 -0
- templates/update.html +18 -0
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 %}
|