Skip to content

Commit

Permalink
masking search results and adding a pie chart
Browse files Browse the repository at this point in the history
  • Loading branch information
kstarkiller committed Feb 5, 2024
1 parent 069efe3 commit 9186189
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 33 deletions.
3 changes: 3 additions & 0 deletions dash/assets/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
document.getElementById('search-button').addEventListener('click', function() {
document.getElementById('search-results').classList.toggle('search-results');
});
24 changes: 23 additions & 1 deletion dash/assets/style.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&display=swap");
@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css");

* {
font-family: Oswald;
}

.checked {
color: orange;
}

body {
background-color: #202124;
}
Expand Down Expand Up @@ -96,23 +101,40 @@ li {
list-style-type:square;
}

.plot {
.categoriesCountPlot,.booksRatePlot,.categoriesRatePlot{
margin-top: 20px;
border: solid 1px #3c4043;
border-radius: 10px;
}

.categoriesCountPlot {
width: 100%;
}
.booksRatePlot {
width: 35%;
}
.categoriesRatePlot{
width: 65%;
}

.container {
display: flex;
flex-direction: column;
width: 100%;
}

.hidden {
display: none;
height: 0px;
}

.resultsContainer {
display: flex;
flex-direction: row;
height: 500px;
justify-content: space-between;
margin-bottom: 20px;
transition: height 1s;
}

.search-results {
Expand Down
188 changes: 157 additions & 31 deletions dash/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@
import pymongo
import pandas as pd
from bson.objectid import ObjectId
import sys
sys.path.append('../../')
from hidden import *
import logging

logging.basicConfig(
level=logging.DEBUG, # Set to DEBUG level for debug mode
format='%(asctime)s [%(levelname)s] - %(message)s',
handlers=[
logging.StreamHandler()
]
)


# Connect to MongoDB
client = pymongo.MongoClient("mongodb://loke:[email protected]:27017/")
client = pymongo.MongoClient("mongodb://"+MONGO_USR+":"+MONGO_PWD+"@localhost:27017/")
db = client['scraped_books']

# Initialize Dash app
Expand All @@ -27,39 +40,54 @@
]),
]),

html.Div(className='resultsContainer', children=[
html.Div(className='hidden', id='resultsContainer', children=[
html.Div(className='search-results', children=[
html.Div(id='search-output'),
]),
html.Div(id='book-details', className='book-details')
]),

html.Div(className="plot", children=[
dcc.Graph(id='category-plot')
html.Div(className="categoriesCountPlot", children=[
dcc.Graph(id='categoriescount-plot')
]),

html.Div(className="booksRatePlot", children=[
dcc.Graph(id='booksrate-plot')
])
])

@app.callback(
Output('resultsContainer', 'className'),
[Input('search-button', 'n_clicks'), Input('search-input', 'n_submit')],
)
def update_class(n_clicks, n_submit):
if n_clicks or n_submit:
return 'resultsContainer'
else:
return 'hidden'

@app.callback(
Output('search-output', 'children'),
Input('search-button', 'n_clicks'),
[Input('search-button', 'n_clicks'), Input('search-input', 'n_submit')],
[State('search-input', 'value')],
)
def update_output(n_clicks, value):
if n_clicks is None or not value:
return
results = list(db.books.find({"title": {"$regex": value, "$options": "i"}}))
results = [{**doc, '_id': str(doc['_id'])} for doc in results]
results_count = len(results)
if results_count > 0:
return html.Ul([
html.Li(html.A(
f"Title: {book['title']}, Category: {book['category']}, Price: {book['price']}",
href='#',
id={'type': 'book-item', 'index': book['_id']}
)) for book in results
])
def update_output_onClick(n_clicks, n_submit, value):
if n_clicks or n_submit :
results = list(db.books.find({"title": {"$regex": value, "$options": "i"}}))
results = [{**doc, '_id': str(doc['_id'])} for doc in results]
results_count = len(results)
if results_count > 0:
return html.Ul([
html.Li(html.A(
f"Title: {book['title']}, Category: {book['category']}, Price: {book['price']}",
href='#',
id={'type': 'book-item', 'index': book['_id']}
)) for book in results
])
else:
return "No books found"
else:
return "No books found"
return "Please enter a book title"

@app.callback(
Output('book-details', 'children'),
Expand All @@ -76,20 +104,91 @@ def display_book_details(n_clicks, ids):
book = db.books.find_one({"_id": ObjectId(book_id)})

if book:
return html.Div([
html.H3(book['title']),
# html.Img(src=f"assets/book_images/{book['image_names'][0]}"),
html.P(f"Rating: {book['rating']}"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
match book['rating']:
case 'One':
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : "),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
case 'Two':
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : "),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
case 'Three':
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : "),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star"),
html.Span(className="fa fa-star"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
case 'Four':
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : "),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
case 'Five':
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : "),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.Span(className="fa fa-star checked"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
case _:
return html.Div([
html.H3(book['title']),
html.Span(f"Rating : No rating yet for this book"),
html.P(f"Price: {book['price']}"),
html.P(f"Category: {book['category']}"),
html.P(f"Description: {book['description']}"),
html.P(f"UPC: {book['upc']}")
])
else:
return "Book details not found."

@app.callback(
Output('category-plot', 'figure'),
Output('categoriescount-plot', 'figure'),
Input('search-button', 'n_clicks')
)
def update_category_plot(n_clicks):
Expand All @@ -98,7 +197,34 @@ def update_category_plot(n_clicks):
category_counts = df['category'].value_counts().reset_index()
category_counts.columns = ['category', 'count']

fig = px.bar(category_counts, x='category', y='count', title='Number of Books by Category', color='category')
fig = px.bar(category_counts, x='category', y='count', title='Number of Books by Category', color='category',
category_orders={'category': sorted(category_counts['category'].unique())})
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
title_font_color='white',
font_color='white',
xaxis=dict(color='white'),
yaxis=dict(color='white'),
xaxis_tickangle=-45
)
fig.update_layout(legend=dict(font=dict(color='white')))
return fig

@app.callback(
Output('booksrate-plot', 'figure'),
Input('search-button', 'n_clicks')
)
def update_booksrate_plot(n_clicks):
data = list(db.books.find({}, {"_id": 0, "rating": 1}))
df = pd.DataFrame(data)
df['rating'].replace(['One', 'Two', 'Three', 'Four', 'Five'], ['1 Star', '2 Stars', '3 Stars', '4 Stars', '5 Stars'], inplace=True)
ratings_counts = df['rating'].value_counts().reset_index()
ratings_counts.columns = ['rating', 'count']

fig = px.pie(ratings_counts, values='count', names='rating',
title='Number of Books by their rating',
category_orders={'rating': ['1 Star', '2 Stars', '3 Stars', '4 Stars', '5 Stars']})
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
Expand Down
3 changes: 2 additions & 1 deletion scraping/myproject/spiders/spider.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import scrapy
import sys
sys.path.append('../../..')
from hidden import *
import os
from pymongo import MongoClient
from hidden import *


class MySpider(scrapy.Spider):
name = 'myspider'
Expand Down

0 comments on commit 9186189

Please sign in to comment.