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)); }
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; } } }
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)); } }
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)); } }
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); }
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)); } }
/// <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()); }
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); } }
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()); }
// 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, })); }
public BookHelpClass(Book book, BookRecommenderContext db) { Book = book; BookAuthors = book.GetAuthors(db); BookGenres = book.GetGenres(db); BookRating = book.GetRating(db); }
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"); }
Character GetTestCharacter(int i, BookRecommenderContext db) { if (i < 0 || i > 5) { throw new ArgumentOutOfRangeException(); } return(db.Characters.Where(t => t.Uri == TestCharacter + i).First()); }
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)); }
Tag GetTestTag(int i, BookRecommenderContext db) { if (i < 0 || i > 5) { throw new ArgumentOutOfRangeException(); } return(db.Tags.Where(t => t.Value == TestTag + i).First()); }
Genre GetTestGenre(int i, BookRecommenderContext db) { if (i < 0 || i > 5) { throw new ArgumentOutOfRangeException(); } return(db.Genres.Where(t => t.Uri == TestGenre + i).First()); }
// 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"); }
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); }
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); } } }
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); } }
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; } }
static void AddTestCharacters() { var db = new BookRecommenderContext(); for (int i = 0; i < 5; i++) { db.Characters.Add(new Character() { Uri = TestCharacter + i }); } db.SaveChanges(); }
static void AddTestBooks() { var db = new BookRecommenderContext(); for (int i = 0; i < 5; i++) { db.Books.Add(new Book() { Uri = TestBook + i }); } db.SaveChanges(); }
static void AddTestAuthors() { var db = new BookRecommenderContext(); for (int i = 0; i < 5; i++) { db.Authors.Add(new Author() { Uri = TestAuthor + i }); } db.SaveChanges(); }
static void AddTestGenres() { var db = new BookRecommenderContext(); for (int i = 0; i < 5; i++) { db.Genres.Add(new Genre() { Uri = TestGenre + i }); } db.SaveChanges(); }
static void AddTestTags() { var db = new BookRecommenderContext(); for (int i = 0; i < 5; i++) { db.Tags.Add(new Tag() { Value = TestTag + i }); } db.SaveChanges(); }