Skip to content

Commit

Permalink
fix: New download function with improved chatbot interface and implem…
Browse files Browse the repository at this point in the history
…entation of videos and lifestyle recommendation implemented fixed the #5
  • Loading branch information
PrathameshDhande22 committed Apr 27, 2024
1 parent 1c6bdfa commit 002d64f
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 86 deletions.
5 changes: 1 addition & 4 deletions bot/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ async def chatsocket(websocket: WebSocket) -> Reply:
chat: ChatResponse = await chatWithUser(received, session,websocket)
if isinstance(chat.get("response"), list):
for resps in chat.get("response"):
if isinstance(resps, bytes):
await websocket.send_bytes(resps)
else:
await websocket.send_json({"name": "bot", "message": resps})
await websocket.send_json({"name": "bot", "message": resps})
time.sleep(1.1)
else:
await websocket.send_json(
Expand Down
19 changes: 11 additions & 8 deletions bot/chatModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,21 @@ def askQuestion(msg: Reply, session: Session) -> dict | str:
recommend = True
return [
msg,
{"share": "Prakriti", "dosha": prakriti.prakriti.title()},
f"The input you provided is <b>{already_known.title()}</b> and our model predicted as <b>{prakriti.prakriti.title()}</b> is different.",
"It seems that there may be one or more incorrect answers to the questions you provided. Please review and verify your responses.",
{
"question": "Want Diet Recommendation based on Your Prakriti?",
"question": "Want Diet & LifeStyle Recommendation based on Your Prakriti?",
"options": {0: "yes", 1: "no"},
},
]
clearAll(exclude=True)
recommend = True
return [
msg,
{"share": "Prakriti", "dosha": prakriti.prakriti.title()},
{
"question": "Want Diet Recommendation based on Your Prakriti?",
"question": "Want Diet & LifeStyle Recommendation based on Your Prakriti?",
"options": {0: "yes", 1: "no"},
},
]
Expand All @@ -201,8 +203,8 @@ def handleWrongAnswer(response: str | dict | list) -> ChatResponse:
}


async def sendPDFBytes(toConsume: str, toAvoid: str, websocket: WebSocket, doshas: str) -> None:
pdfbytes = createPDF(toConsume, toAvoid, doshas)
async def sendPDFBytes(toConsume: str, toAvoid: str, websocket: WebSocket, doshas: str, lifestyle: str) -> None:
pdfbytes = createPDF(toConsume, toAvoid, doshas, lifestyle)
await websocket.send_json({"name": "bot", "message": "Your PDF has been Created."})
await websocket.send_bytes(pdfbytes)

Expand Down Expand Up @@ -231,7 +233,7 @@ async def chatWithUser(msg: Reply, session: Session, websocket: WebSocket) -> Ch
confirm = True
return {
"response": {
"question": "Do you already know your Prakriti? If yes, could you please share it with me?",
"question": "Do you already know your Prakriti? If Yes, could you please share it with me?",
"options": {0: "yes", 1: "no"},
}
}
Expand Down Expand Up @@ -325,7 +327,7 @@ async def chatWithUser(msg: Reply, session: Session, websocket: WebSocket) -> Ch
[
"Please give Proper Input Either Yes or No",
{
"question": "Do you already know your Prakriti? If yes, could you please share it with me?",
"question": "Do you already know your Prakriti? If Yes, could you please share it with me?",
"options": {0: "yes", 1: "no"},
},
]
Expand All @@ -334,12 +336,13 @@ async def chatWithUser(msg: Reply, session: Session, websocket: WebSocket) -> Ch
elif recommend:
if str(msg.get("message")).lower().strip() == "yes":
diet = recommend_Diet(prakriti.prakriti)
lifestyle = diet.pop(2)
Thread(target=runAsynioFunc, args=(sendPDFBytes(
diet[0][20:], diet[1][18:], websocket, prakriti.prakriti),)).start()
diet[0][20:], diet[1][18:], websocket, prakriti.prakriti, lifestyle),)).start()
diet.append(
"Thank You For predicting Prakriti with <b>AYURBOT</b>")
diet.append(
"Your diet plan in PDF format will be available shortly. Please Wait for Some time.")
"Your personalized advice on lifestyle, diet, and related videos for your Prakriti will be ready to download in PDF format soon. Please be patient while it processes.")
clearAll()
return {"response": diet}
else:
Expand Down
102 changes: 37 additions & 65 deletions bot/utils.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,51 @@
import os
import nltk
from nltk.tokenize import sent_tokenize
from weasyprint import HTML
import logging
import pandas as pd
from logger import logger
from diet import recommend_Diet
from weasyprint import HTML, CSS
from nltk.tokenize import sent_tokenize
from typing import Literal
import os

df = pd.read_csv(os.path.join("dataset", "videos.csv"))
# nltk.download("punkt")

logging.getLogger("weasyprint").setLevel(logging.WARNING)
logging.getLogger("fontTools").setLevel(logging.WARNING)

def createHTMLListString(text: str) -> str:
"""Converts the paragraph into a Unorderedlist HTML Tag.
Args:
text (str): Paragraph to be converted into a unorderedlist.
Returns:
str: Paragraph converted into a unorderedlist.
"""
def createHTMLListString(text: str, listTag: Literal["<ul>", "<ol>"], closingTag: Literal["</ul>", "</ol>"]) -> str:
text: list[str] = sent_tokenize(text)
text.insert(0, "<ul>")
text.insert(len(text), "</ul>")
text.insert(0, listTag)
text.insert(len(text), closingTag)
for i in range(1, len(text)-1):
text[i] = f"<li>{text[i]}</li>"
text = "".join(text)
return text


def createPDF(consume: str, avoid: str, dosha: str) -> bytes:
html_content = f"""
<html>
<head>
<title>Your Prakriti - AyurInsights</title>
</head>
<body>
<header>
<div>
<center>
<img src="https://ucarecdn.com/56c57686-f88c-471d-8b0e-f7b6b70ee7a4/-/preview/300x189/" alt="Logo">
</center>
</div>
</header>
<div>
<h2 style="text-align: center;">Your Prakriti is : {dosha}</h2>
<div class="table-result">
<div style="font-size: 20px;font-weight: bold;text-align: center;text-decoration-line: underline;">Diet
Recommendation</div>
<div>
<h3>To Consume: </h6>
<div style="text-align: justify;">
{createHTMLListString(consume)}
</div>
</div>
<div>
<h3>To Avoid: </h3>
<div style="text-align: justify;">
{createHTMLListString(avoid)}
</div>
</div>
</div>
</div>
<footer style="padding-top: 17px;">
<div style="padding:14px 0px; color:gray; text-align: center;">
<b>Disclaimer : </b>The dietary recommendations provided above have been curated and tested by Ayurvedic
experts.
</div>
<div style="padding: 8px;border: 2px solid black ;">
<b>Note:</b> This document has been automatically generated by <a
href="http://localhost:5173">AyurInsights</a>. You can also discover your prakriti by visiting and
answering a set of questions.
</div>
<div style="text-align: center;padding-top: 18px;font-weight: bold;font-size:18px">
Thank You 🙏🙏 For Using our Website and Our Services.
</div>
</footer>
</body>
</html>"""
pdf = HTML(string=html_content).write_pdf()
def createHTMLVideoElement(videos: dict[str, str]) -> str:
htmlstr = list()
for vids in videos:
htmlstr.append("<div style='margin-top:9px;'>")
htmlstr.append(f"<span>{vids} ➡️ </span>")
htmlstr.append(f"<a href='{videos[vids]}'>{videos[vids]}</a>")
htmlstr.append("</div>")
videosString = "".join(htmlstr)
return videosString


def recommentVideos(dosha: str) -> dict[str, str]:
vids = df.loc[df["Doshas"] == dosha].drop("Doshas", axis=1).to_dict()
return dict(zip(list(vids["Title"].values()), list(vids["Video"].values())))


def createPDF(consume: str, avoid: str, dosha: str, lifeStyle: str) -> bytes:
with open(os.path.join("doc.html"), "r", encoding="utf8") as f:
html_content = str(f.read())
videos = recommentVideos(dosha)
html_content = html_content.format(
dosha, createHTMLListString(consume, "<ul>", "</ul>"), createHTMLListString(avoid, "<ul>", "</ul>"), createHTMLListString(lifeStyle, "<ol>", "</ol>"), createHTMLVideoElement(videos=videos))
pdf = HTML(string=html_content).write_pdf(stylesheets=[
CSS(string="@page {size: A4; margin: 18mm 15mm 25mm 15mm;}")])
logger.info("Created PDF File")
return pdf
4 changes: 0 additions & 4 deletions frontend/src/Components/About.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@ function About() {
"Welcome to AyurInsights, your gateway to the harmonious fusion of ancient Ayurvedic wisdom and modern technology. At AyurInsights, we're dedicated to empowering individuals with profound insights into their well-being, health, and constitution. Our journey began with a simple yet powerful question: how can we blend the timeless principles of Ayurveda with the precision of modern machine learning to enhance lives?"
}
</p>

<h4 className="about-text-title">Your Solutions</h4>

<SolutionStep
title="Click On Chat Bot"
description="Locate the Chat with our Ayurvedic Expert button on the homepage and click it."
/>

<SolutionStep
title="Start the Conversation"
description="Once the chat interface opens, initiate a conversation with our AI-powered chatbot by responding to its greetings."
/>

<SolutionStep
title="Answer Questions"
description="The chatbot will ask you a series of questions related to your health, lifestyle, and preferences. Provide honest and detailed responses."
Expand Down
17 changes: 13 additions & 4 deletions frontend/src/Components/Chatbot.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,21 @@ const Chatbot = ({ open, set }) => {
[websckt]
);

const handleMaximizeandMinimize = () => {
setFullSize(!fullsize);
if (!fullsize) {
if (typeof window != "undefined" && window.document) {
document.body.style.overflow = "hidden";
}
} else {
document.body.style.overflow = "unset";
}
};

return (
<div className="relative h-full flex justify-center flex-col">
<div
className={`z-30 self-center rounded-lg border-4 border-sky-400 pb-5 bg-white animate__animated animate__fadeIn ${
className={`z-30 self-center rounded-lg border-4 border-sky-400 pb-5 bg-white animate__animated animate__fadeIn shadow-[-10px_-10px_30px_4px_rgba(0,0,0,0.1),_10px_10px_30px_4px_rgba(45,78,255,0.15)] ${
fullsize
? "w-full h-screen top-0 fixed"
: "w-[90%] sm:w-[400px] fixed sm:top-[15%] top-3 sm:right-7 h-[95%] md:h-fit"
Expand All @@ -105,9 +116,7 @@ const Chatbot = ({ open, set }) => {
<button
type="button"
className="hover:bg-sky-400"
onClick={() => {
setFullSize(!fullsize);
}}
onClick={handleMaximizeandMinimize}
>
{!fullsize ? (
<FiMaximize2 size={20} />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/Components/DownloadButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const DownloadButton = ({ blob }) => {

return (
<div className="flex flex-row flex-wrap items-center gap-1">
<span>Download Your Diet Plan in PDF Format : </span>
<span>Download Your Recommendation in PDF Format : </span>
<button
type="button"
onClick={handleClick}
Expand Down

0 comments on commit 002d64f

Please sign in to comment.