| box::use( |
| utils[head, read.csv2], |
| shiny[div, moduleServer, downloadLink, downloadHandler, sliderInput, tagList, req, reactiveVal, actionButton, fileInput, observeEvent, h1, h3, p, NS, selectizeInput, HTML, tags], |
| bslib[page_fillable, page_sidebar, nav_panel, page_navbar, layout_columns, card, card_header, card_body, layout_column_wrap, value_box, input_dark_mode, nav_item], |
| shinyWidgets[pickerInput], |
| waiter[useWaiter, autoWaiter, waiter_show, spin_fading_circles, waiter_hide, waiterShowOnLoad, waiter_on_busy], |
| spacyr[spacy_install], |
| data.table[fread, fwrite], |
| ) |
|
|
| box::use( |
| view / mod_search_books, |
| view / mod_recommend_books, |
| view / mod_data_analysis |
| ) |
|
|
|
|
| |
| ui <- function(id) { |
| ns <- NS(id) |
| page_navbar( |
| title = "Book Recommender", |
| sidebar = my_sidebar(ns), |
| fillable = FALSE, |
| nav_panel( |
| useWaiter(), |
| waiter_on_busy(html = tagList(div(class = "main-waiter", h3("Give me a second to read all those books..."), spin_fading_circles()))), |
| |
| title = "Recommendations", |
| tags$main( |
| class = "main-container", |
| tags$section( |
| h1("Discover books you will love!", class = "align-text-center"), |
| div(class = "text-main align-text-center", p(" Enter books you like and the site will analyse the contents of the books to provide book recommendations and suggestions for what to read next.")), |
| mod_search_books$ui(ns("search_books")), |
| mod_recommend_books$ui(ns("recommend_books")) |
| ) |
| ) |
| ), |
| nav_panel( |
| "Data analysis", |
| mod_data_analysis$ui(ns("data_analysis")) |
| ), |
| |
| |
| |
| ) |
| } |
|
|
| |
| server <- function(id) { |
| moduleServer(id, function(input, output, session) { |
| gargoyle::init("start_recommend_event") |
|
|
| |
|
|
| data <- load_data("data/dataset_goodreads_filtered.csv") |
| item_item_df <- fread("data/item_to_item_similarity_dataframe_full.csv") |
| user_ratings_tab <- readRDS("data/ratings_filtered.rds") |
| corp_dfm <- readRDS("data/ref_corp_tfidf_new.rds") |
| SVD_model <- readRDS("data/svdf.rds") |
| |
|
|
| selected_books_ids <- mod_search_books$server("search_books", data$title, data$image_url, data$book_id) |
| mod_data_analysis$server("data_analysis") |
|
|
| output$downloadData <- downloadHandler( |
| filename = function() { |
| "system_recommendations_log.csv" |
| }, |
| content = function(file) { |
| data <- fread("system_recommendations_log.csv") |
| fwrite(data, file) |
| } |
| ) |
| |
| observeEvent(input$method, { |
| mod_recommend_books$server( |
| "recommend_books", |
| user_ratings_tab, |
| SVD_model, |
| corp_dfm, |
| item_item_df, |
| selected_books_ids, |
| data, |
| input$how_many_recommends_slider, |
| input$simil_metrics, |
| input$method |
| ) |
| }) |
|
|
| observeEvent(input$how_many_recommends_slider, { |
| mod_recommend_books$server( |
| "recommend_books", |
| user_ratings_tab, |
| SVD_model, |
| corp_dfm, |
| item_item_df, |
| selected_books_ids, |
| data, |
| input$how_many_recommends_slider, |
| input$simil_metrics, |
| input$method |
| ) |
| gargoyle::trigger("start_recommend_event") |
| }) |
| }) |
| } |
|
|
|
|
| load_data <- function(path) { |
| data <- data.table::fread(path) |
| data[, genres := strsplit(genre, split = ",")] |
| data[, average_rating := as.numeric(average_rating)] |
| data$genre <- NULL |
| data$similar_books <- NULL |
| return(data) |
| } |
|
|
|
|
| my_sidebar <- function(ns) { |
| tagList( |
| sliderInput(ns("how_many_recommends_slider"), "Number of books to recommend", 1, 100, 10, step = 1), |
| pickerInput( |
| inputId = ns("method"), |
| label = "recommendation method", |
| selected = "ALL", |
| choices = c("SVD", "TFIDF", "item-item", "ALL") |
| ), |
| downloadLink(ns("downloadData"), "Download logs") |
| ) |
| } |
|
|