Esempio n. 1
0
        async public Task <IActionResult> Search(string query, int?page)
        {
            if (string.IsNullOrEmpty(query))
            {
                return(View());
            }

            // Add default pagination
            if (!page.HasValue)
            {
                page = 1;
            }

            var db      = new BookRecommenderContext();
            var books   = SearchEngine.SearchBook(db, query);
            var authors = SearchEngine.SearchAuthor(db, query);

            var searchModel = new SearchViewModel(query, page.Value, books.ToList(), authors.ToList(), db);

            // search the searched query if the user is signed in
            if (User.Identity.IsAuthenticated)
            {
                string userId = _userManager.GetUserAsync(HttpContext.User).Result.Id;
                var    user   = db.Users.Where(u => u.Id == userId)?.FirstOrDefault();
                if (user == null)
                {
                    return(View("Error"));
                }
                var ua = new UserActivity(user, ActivityType.KeywordSearched, query);
                await db.UsersActivities.AddAsync(ua);

                await db.SaveChangesAsync();
            }
            return(View(searchModel));
        }
Esempio n. 2
0
        public void CountSimilarity(BookRecommenderContext db)
        {
            List <BookSimilarityInformation> books = new List <BookSimilarityInformation>();

            foreach (int bookIDI in bookIDs)
            {
                Book          bookI    = db.Books.Find(bookIDI);
                List <Author> authorsI = bookI.GetAuthors(db).ToList();
                List <Genre>  genresI  = bookI.GetGenres(db).ToList();

                BookSimilarityInformation bookInfoI =
                    new BookSimilarityInformation(bookI.BookId, authorsI, genresI);

                books.Add(bookInfoI);
            }

            for (int bookIndex1 = 0; bookIndex1 < books.Count; bookIndex1++)
            {
                for (int bookIndex2 = 0; bookIndex2 < books.Count; bookIndex2++)
                {
                    if (bookIndex1 + bookIndex2 >= books.Count)
                    {
                        continue;
                    }

                    BookSimilarityInformation bookInfo1 = books[bookIndex1];
                    BookSimilarityInformation bookInfo2 = books[bookIndex2];

                    double simValue = Similarity(bookInfo1, bookInfo2);
                    this.matrix[bookIndex1, bookIndex2] = simValue;
                    this.matrix[bookIndex2, bookIndex1] = simValue;
                }
            }
        }
Esempio n. 3
0
        public void BookAuthorRelationship()
        {
            using (new TestData())
            {
                var db = new BookRecommenderContext();

                var book = GetTestBook(0, db);

                book.AddAuthor(GetTestAuthor(0, db), db);
                book.AddAuthor(GetTestAuthor(1, db), db);

                db.SaveChanges();

                var db2 = new BookRecommenderContext();

                var tb0 = GetTestBook(0, db2);
                var ta0 = GetTestAuthor(0, db2);
                var ta1 = GetTestAuthor(1, db2);


                Assert.True(tb0.GetAuthors(db2).Count() == 2);

                Assert.True(ta0.GetBooks(db2).Count() == 1);
                Assert.True(ta1.GetBooks(db2).Count() == 1);

                Assert.Contains(ta0, tb0.GetAuthors(db2));
                Assert.Contains(ta1, tb0.GetAuthors(db2));

                Assert.Contains(tb0, ta0.GetBooks(db2));
                Assert.Contains(tb0, ta1.GetBooks(db2));
            }
        }
Esempio n. 4
0
        public void BookCharacterRelationship()
        {
            using (new TestData())
            {
                var db = new BookRecommenderContext();

                var book = GetTestBook(0, db);

                book.AddCharacter(GetTestCharacter(0, db), db);
                book.AddCharacter(GetTestCharacter(1, db), db);

                db.SaveChanges();

                var db2 = new BookRecommenderContext();

                var tb0 = GetTestBook(0, db2);
                var tc0 = GetTestCharacter(0, db2);
                var tc1 = GetTestCharacter(1, db2);


                Assert.True(tb0.GetCharacters(db2).Count() == 2);
                Assert.True(tc0.GetBooks(db2).Count() == 1);
                Assert.True(tc1.GetBooks(db2).Count() == 1);

                Assert.Contains(tc0, tb0.GetCharacters(db2));
                Assert.Contains(tc1, tb0.GetCharacters(db2));

                Assert.Contains(tb0, tc0.GetBooks(db2));
                Assert.Contains(tb0, tc1.GetBooks(db2));
            }
        }
Esempio n. 5
0
        public async Task <string> TryToGetImgUrlAsync()
        {
            var pictureUrl = OriginalImage;

            if (pictureUrl == null)
            {
                // If no picture from Open Data, then try to load first picture on google search
                // First check cache:
                pictureUrl = GoogleImageCache;
                if (string.IsNullOrEmpty(pictureUrl))
                {
                    // If nothing in cache, try to load from Google
                    var imageMiner = new DataManipulation.GoogleImageMiner();
                    pictureUrl = await imageMiner.GetFirstImageUrlAsync("book " + GetNameEn());

                    // Save to cache
                    if (pictureUrl != null)
                    {
                        GoogleImageCache = pictureUrl;
                        var db = new BookRecommenderContext();
                        db.Books.Update(this);
                        await db.SaveChangesAsync();
                    }
                }
            }
            return(pictureUrl);
        }
Esempio n. 6
0
        public void BookGenreRelationship()
        {
            using (new TestData())
            {
                var db = new BookRecommenderContext();

                var book = GetTestBook(0, db);

                book.AddGenre(GetTestGenre(0, db), db);
                book.AddGenre(GetTestGenre(1, db), db);
                db.SaveChanges();

                var db2 = new BookRecommenderContext();

                var tb0 = GetTestBook(0, db2);
                var tg0 = GetTestGenre(0, db2);
                var tg1 = GetTestGenre(1, db2);


                Assert.True(tb0.GetGenres(db2).Count() == 2);
                Assert.True(tg0.GetBooks(db2).Count() == 1);
                Assert.True(tg1.GetBooks(db2).Count() == 1);

                Assert.Contains(tg0, tb0.GetGenres(db2));
                Assert.Contains(tg1, tb0.GetGenres(db2));

                Assert.Contains(tb0, tg0.GetBooks(db2));
                Assert.Contains(tb0, tg1.GetBooks(db2));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Detail of the book.
        /// </summary>
        /// <param name="id">DId of the book</param>
        /// <returns>Page with the main detail page</returns>
        async public Task <IActionResult> Detail(int id)
        {
            string userId = null;

            if (User.Identity.IsAuthenticated)
            {
                userId = (await _userManager.GetUserAsync(HttpContext.User)).Id;
            }
            var bookDetail = new BookDetail(id, userId);

            if (bookDetail.Book == null)
            {
                return(View("Error"));
            }

            if (User.Identity.IsAuthenticated)
            {
                var db   = new BookRecommenderContext();
                var user = db.Users.Where(u => u.Id == userId)?.FirstOrDefault();
                if (user == null)
                {
                    return(View("Error"));
                }
                var ua = new UserActivity(user, ActivityType.BookDetailViewed, id.ToString());
                await db.UsersActivities.AddAsync(ua);

                await db.SaveChangesAsync();
            }

            return(View(bookDetail));
        }
        private List <Tuple <int, double> > removeAlreadyRatedBooks(
            List <Tuple <int, double> > listOfBookIDsAndTheirQuantities,
            string userId, BookRecommenderContext db)
        {
            // if user signed in, remove already rated books
            if (userId == null)
            {
                return(listOfBookIDsAndTheirQuantities);
            }

            var user = db.Users.Where(u => u.Id == userId).FirstOrDefault();

            if (user == null)
            {
                return(listOfBookIDsAndTheirQuantities);
            }

            // get all ratings
            List <BookRating> userRatings = db.Ratings
                                            .Where(r => r.UserId == userId).ToList();

            // remove books which user already rated
            return(listOfBookIDsAndTheirQuantities.Where(
                       b => !userRatings.Select(r => r.BookId).Contains(b.Item1)
                       ).ToList());
        }
Esempio n. 9
0
        public BookDetail(int bookId, string userId)
        {
            var db = new BookRecommenderContext();

            Book = db.Books.Where(b => b.BookId == bookId)?.FirstOrDefault();
            if (Book != null)
            {
                Authors          = Book.GetAuthors(db);
                Genres           = Book.GetGenres(db);
                Characters       = Book.GetCharacters(db);
                Tags             = Book.GetTags(db, "en");
                RecommendedBooks = db.Books.Take(5);


                if (userId != null)
                {
                    var user = db.Users.Where(u => u.Id == userId)?.FirstOrDefault();
                    if (user != null)
                    {
                        SignedIn       = true;
                        UserBookRating = db.Ratings.Where(r => r.BookId == Book.BookId && r.UserId == userId)?.FirstOrDefault();
                    }
                }
                BookRating = Book.GetPreciseRating(db);
                Ratings    = db.Ratings.Where(r => r.BookId == Book.BookId && r.Review != null).OrderByDescending(r => r.CreatedTime);
            }
        }
Esempio n. 10
0
        public void BookTagRelationship()
        {
            using (new TestData())
            {
                var db = new BookRecommenderContext();

                var book = GetTestBook(0, db);

                book.AddTag(GetTestTag(0, db), db);
                book.AddTag(GetTestTag(1, db), db);
                db.SaveChanges();

                var db2 = new BookRecommenderContext();

                var tb0 = GetTestBook(0, db2);
                var tt0 = GetTestTag(0, db2);
                var tt1 = GetTestTag(1, db2);

                Assert.True(tb0.GetTags(db2).Count() == 2);
                Assert.True(tt0.GetBooks(db2).Count() == 1);
                Assert.True(tt1.GetBooks(db2).Count() == 1);

                Assert.Contains(tt0, tb0.GetTags(db2));
                Assert.Contains(tt1, tb0.GetTags(db2));

                Assert.Contains(tb0, tt0.GetBooks(db2));
                Assert.Contains(tb0, tt1.GetBooks(db2));
            }
        }
        /// <summary>
        /// Spreading activation recommender.
        /// If the user is logged in, we remove books already rated by him from the recommendation.
        /// </summary>
        /// <param name="bookId">Id of book on which will the recommendation be based</param>
        /// <param name="userId">Id of the signed in user</param>
        /// <param name="howMany">Depth of activation spreading</param>
        /// <returns>List of books with the highest activation value</returns>
        public List <int> Recommend(int bookId, string userId, int howMany = 6)
        {
            // initialize the activation graph
            GraphOfBooks graph = new GraphOfBooks();

            graph.AddVertex(bookId, START_ACTIVATION_VALUE);

            List <int> bookIDs = new List <int>();

            bookIDs.Add(bookId);

            // start recursive spreading activation
            RunOneLevelBFS(maxLevel, bookIDs, graph);

            graph.RemoveVertex(bookId);
            List <Tuple <int, double> > bookIDVWithActivationValues =
                graph.ExportBookIDVerticesWithActivationValues();

            BookRecommenderContext      bd = new BookRecommenderContext();
            List <Tuple <int, double> > bookIdsWithActivationValuesWithoutRated =
                removeAlreadyRatedBooks(bookIDVWithActivationValues, userId, bd);

            // sorting books according to their importance from the highest to the lowest activation value
            List <Tuple <int, double> > sortedBookIdsWithActivationValues =
                bookIdsWithActivationValuesWithoutRated.OrderBy(v => v.Item2).Reverse().ToList();

            // return sorted sublist of recommendation
            return(sortedBookIdsWithActivationValues.Select(v => v.Item1).Take(howMany).ToList());
        }
Esempio n. 12
0
        // GET: /Author/Detail
        /// <summary>
        /// Gets the main page for the autor
        /// </summary>
        /// <param name="id">Id of the author</param>
        /// <returns>Page with na author detail</returns>
        async public Task <IActionResult> Detail(int id)
        {
            var db          = new BookRecommenderContext();
            var author      = db.Authors.Where(a => a.AuthorId == id)?.FirstOrDefault();
            var authorBooks = author.GetBooks(db).OrderBy(b => b.GetNameEn());

            if (author == null)
            {
                return(View("Error"));
            }

            if (User.Identity.IsAuthenticated)
            {
                var userId = _userManager.GetUserAsync(HttpContext.User).Result.Id;
                var user   = db.Users.Where(u => u.Id == userId)?.FirstOrDefault();
                if (user == null)
                {
                    return(View("Error"));
                }
                var ua = new UserActivity(user, ActivityType.AuthorDetailViewed, id.ToString());
                await db.UsersActivities.AddAsync(ua);

                await db.SaveChangesAsync();
            }

            return(View(new AuthorDetail()
            {
                Author = author,
                Books = authorBooks,
            }));
        }
Esempio n. 13
0
 public BookHelpClass(Book book, BookRecommenderContext db)
 {
     Book        = book;
     BookAuthors = book.GetAuthors(db);
     BookGenres  = book.GetGenres(db);
     BookRating  = book.GetRating(db);
 }
Esempio n. 14
0
        static void RemoveTestEntries()
        {
            // Clean database from test entries
            var db = new BookRecommenderContext();

            foreach (var item in db.Books.Where(b => b.Uri.StartsWith(TestBook)))
            {
                db.Remove(item);
            }
            foreach (var item in db.Authors.Where(a => a.Uri.StartsWith(TestAuthor)))
            {
                db.Remove(item);
            }
            foreach (var item in db.Characters.Where(c => c.Uri.StartsWith(TestCharacter)))
            {
                db.Remove(item);
            }
            foreach (var item in db.Genres.Where(g => g.Uri.StartsWith(TestGenre)))
            {
                db.Remove(item);
            }
            foreach (var item in db.Tags.Where(t => t.Value.StartsWith(TestTag)))
            {
                db.Remove(item);
            }
            db.SaveChanges();
            System.Console.WriteLine("Test entities removed");
        }
Esempio n. 15
0
 Character GetTestCharacter(int i, BookRecommenderContext db)
 {
     if (i < 0 || i > 5)
     {
         throw new ArgumentOutOfRangeException();
     }
     return(db.Characters.Where(t => t.Uri == TestCharacter + i).First());
 }
Esempio n. 16
0
 public IEnumerable <Tag> GetTags(BookRecommenderContext db, string lang = null)
 {
     if (lang != null)
     {
         return(db.Tags.Where(bt => bt.Book == this).Where(t => t.Lang == "en"));
     }
     return(db.Tags.Where(bt => bt.Book == this));
 }
Esempio n. 17
0
 Tag GetTestTag(int i, BookRecommenderContext db)
 {
     if (i < 0 || i > 5)
     {
         throw new ArgumentOutOfRangeException();
     }
     return(db.Tags.Where(t => t.Value == TestTag + i).First());
 }
Esempio n. 18
0
 Genre GetTestGenre(int i, BookRecommenderContext db)
 {
     if (i < 0 || i > 5)
     {
         throw new ArgumentOutOfRangeException();
     }
     return(db.Genres.Where(t => t.Uri == TestGenre + i).First());
 }
Esempio n. 19
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory,
            BookRecommenderContext db,
            SpreadingRecommenderCache spreadingRecommederCache)
        {
            // add values to the appsetting singleton from appsettings.json
            AppSettingsSingleton.Database.Connection     = Configuration["Database:Connection"];
            AppSettingsSingleton.Mining.WikiPagesStorage = Configuration["Mining:WikiPagesStorage"];
            AppSettingsSingleton.Mining.Password         = Configuration["Mining:Password"];


            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsProduction())
            {
                app.UseForwardedHeaders(new ForwardedHeadersOptions
                {
                    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
                });
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            // var options = new RewriteOptions()
            //     .AddRedirectToHttps();

            app.UseStaticFiles();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            app.UseResponseCompression();

            System.Console.WriteLine("Spreading activation cache init started.");
            var sw = Stopwatch.StartNew();

            spreadingRecommederCache.Initialize(db);
            sw.Stop();
            System.Console.WriteLine($"Spreading activation cache initialized, it took: {sw.ElapsedMilliseconds}ms");
        }
Esempio n. 20
0
        Author GetTestAuthor(int i, BookRecommenderContext db)
        {
            if (i < 0 || i > 5)
            {
                throw new ArgumentOutOfRangeException();
            }
            var ret = db.Authors.Where(t => t.Uri == TestAuthor + i).First();

            return(ret);
        }
Esempio n. 21
0
        public AboutViewModel()
        {
            var db = new BookRecommenderContext();

            BooksCount   = db.Books.Count();
            AuthorsCount = db.Authors.Count();
            ReviewsCount = db.Ratings.Where(r => !string.IsNullOrEmpty(r.Review)).Count();
            RatingsCount = db.Ratings.Count();
            UsersCount   = db.Users.Count();
        }
        public MyProfileViewModel(string userId)
        {
            var db = new BookRecommenderContext();

            BookRatings = db.Ratings.Where(r => r.UserId == userId)
                          .OrderByDescending(r => r.CreatedTime)
                          .Include(x => x.Book)
                          .ToList();

            var usersActivities = db.UsersActivities
                                  .Where(a => a.UserId == userId)
                                  .OrderByDescending(a => a.CreatedTime)
                                  .ToList();

            LastSearched = usersActivities
                           .Where(a =>
                                  a.Type == UserActivity.ActivityType.KeywordSearched)
                           .Select(a => a.Value)
                           .Distinct()
                           .Take(20)
                           .ToList();

            var lastBooks = usersActivities
                            .Where(a => a.Type == UserActivity.ActivityType.BookDetailViewed)
                            .Select(a => int.Parse(a.Value))
                            .Distinct()
                            .Take(20)
                            .ToList();

            var lastAuthors = usersActivities
                              .Where(a => a.Type == UserActivity.ActivityType.AuthorDetailViewed)
                              .Select(a => int.Parse(a.Value))
                              .Distinct()
                              .Take(20)
                              .ToList();

            foreach (var bookId in lastBooks)
            {
                var book = db.Books.Where(b => b.BookId == bookId).FirstOrDefault();
                if (book != null)
                {
                    LastViewedBooks.Add(book);
                }
            }

            foreach (var authorId in lastAuthors)
            {
                var author = db.Authors.Where(b => b.AuthorId == authorId).FirstOrDefault();
                if (author != null)
                {
                    LastViewedAuthors.Add(author);
                }
            }
        }
Esempio n. 23
0
        public async Task AddAuthorAsync(Author author, BookRecommenderContext db)
        {
            var newBA = new BookAuthor()
            {
                BookId = this.BookId, AuthorId = author.AuthorId
            };

            if (!db.BooksAuthors.Where(ba => ba.AuthorId == author.AuthorId && ba.BookId == this.BookId).Any())
            {
                await db.BooksAuthors.AddAsync(newBA);
            }
        }
Esempio n. 24
0
        public int?GetPreciseRating(BookRecommenderContext db)
        {
            var ratings = GetRatings(db);
            var count   = 0;
            var sum     = ratings.Select(r => r.Rating).Sum(r => { count++; return(r); });

            if (count == 0)
            {
                return(null);
            }
            return((int)(sum * 20 / count));
        }
        public Recommendation(int bookId, string reason = null)
        {
            var db = new BookRecommenderContext();

            Book = db.Books.Where(b => b.BookId == bookId)?.FirstOrDefault();
            if (Book != null)
            {
                Authors = Book.GetAuthors(db);
                Genres  = Book.GetGenres(db);
                RecommendationReason = reason;
            }
        }
Esempio n. 26
0
        static void AddTestCharacters()
        {
            var db = new BookRecommenderContext();

            for (int i = 0; i < 5; i++)
            {
                db.Characters.Add(new Character()
                {
                    Uri = TestCharacter + i
                });
            }
            db.SaveChanges();
        }
Esempio n. 27
0
        static void AddTestBooks()
        {
            var db = new BookRecommenderContext();

            for (int i = 0; i < 5; i++)
            {
                db.Books.Add(new Book()
                {
                    Uri = TestBook + i
                });
            }
            db.SaveChanges();
        }
Esempio n. 28
0
        static void AddTestAuthors()
        {
            var db = new BookRecommenderContext();

            for (int i = 0; i < 5; i++)
            {
                db.Authors.Add(new Author()
                {
                    Uri = TestAuthor + i
                });
            }
            db.SaveChanges();
        }
Esempio n. 29
0
        static void AddTestGenres()
        {
            var db = new BookRecommenderContext();

            for (int i = 0; i < 5; i++)
            {
                db.Genres.Add(new Genre()
                {
                    Uri = TestGenre + i
                });
            }
            db.SaveChanges();
        }
Esempio n. 30
0
        static void AddTestTags()
        {
            var db = new BookRecommenderContext();

            for (int i = 0; i < 5; i++)
            {
                db.Tags.Add(new Tag()
                {
                    Value = TestTag + i
                });
            }
            db.SaveChanges();
        }