188 lines
5.6 KiB
C#
188 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using JetBrains.Annotations;
|
|
using Portoa.Persistence;
|
|
using VideoGameQuotes.Api;
|
|
using VideoGameQuotes.Web.Models;
|
|
|
|
namespace VideoGameQuotes.Web.Services {
|
|
public interface IQuoteService {
|
|
Game GetGame(int id);
|
|
IEnumerable<Game> GetAllGames();
|
|
IEnumerable<GamingSystem> GetAllSystems();
|
|
IEnumerable<Publisher> GetAllPublishers();
|
|
IEnumerable<Category> GetAllCategories();
|
|
Quote SaveQuote(Quote quote);
|
|
Quote GetQuote(int id);
|
|
Publisher GetPublisher(int id);
|
|
GamingSystem GetSystem(int systemId);
|
|
Category GetCategory(int categoryId);
|
|
IEnumerable<Quote> GetRecentQuotes(int start, int end, out int totalCount);
|
|
[CanBeNull]
|
|
Quote GetRandomQuote();
|
|
IEnumerable<Quote> GetBestQuotes(int start, int end, out int totalCount);
|
|
Vote GetVoteOrCreateNew(Quote quote, User voter);
|
|
IEnumerable<Quote> GetBrowsableQuotes(BrowseModel model, int start, int end, out int totalCount);
|
|
Quote GetQuoteForDayOfYear(int day);
|
|
}
|
|
|
|
public class QuoteService : IQuoteService {
|
|
private readonly IRepository<Quote> quoteRepository;
|
|
private readonly IRepository<Game> gameRepository;
|
|
private readonly IRepository<GamingSystem> systemRepository;
|
|
private readonly IRepository<Publisher> publisherRepository;
|
|
private readonly IRepository<Category> categoryRepository;
|
|
private readonly IRepository<Vote> voteRepository;
|
|
private static readonly Random random = new Random();
|
|
private static readonly IDictionary<int, Quote> quoteOfTheDayMap = new Dictionary<int, Quote>();
|
|
|
|
public QuoteService(
|
|
IRepository<Quote> quoteRepository,
|
|
IRepository<Game> gameRepository,
|
|
IRepository<GamingSystem> systemRepository,
|
|
IRepository<Publisher> publisherRepository,
|
|
IRepository<Category> categoryRepository,
|
|
IRepository<Vote> voteRepository
|
|
) {
|
|
this.quoteRepository = quoteRepository;
|
|
this.categoryRepository = categoryRepository;
|
|
this.voteRepository = voteRepository;
|
|
this.gameRepository = gameRepository;
|
|
this.systemRepository = systemRepository;
|
|
this.publisherRepository = publisherRepository;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Game GetGame(int id) {
|
|
return gameRepository.FindById(id);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Game> GetAllGames() {
|
|
return gameRepository.Records;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<GamingSystem> GetAllSystems() {
|
|
return systemRepository.Records;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Publisher> GetAllPublishers() {
|
|
return publisherRepository.Records;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Category> GetAllCategories() {
|
|
return categoryRepository.Records;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Quote SaveQuote(Quote quote) {
|
|
return quoteRepository.Save(quote);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Quote GetQuote(int id) {
|
|
return quoteRepository.FindById(id);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Publisher GetPublisher(int id) {
|
|
return publisherRepository.FindById(id);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public GamingSystem GetSystem(int systemId) {
|
|
return systemRepository.FindById(systemId);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Category GetCategory(int categoryId) {
|
|
return categoryRepository.FindById(categoryId);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Quote> GetRecentQuotes(int start, int end, out int totalCount) {
|
|
totalCount = quoteRepository.Records.Count();
|
|
return quoteRepository
|
|
.Records
|
|
.OrderByDescending(quote => quote.Created)
|
|
.Skip(start - 1)
|
|
.Take(end - start + 1);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Quote GetRandomQuote() {
|
|
var length = quoteRepository.Records.Count();
|
|
if (length == 0) {
|
|
return null;
|
|
}
|
|
|
|
return GetRandomQuote(quoteRepository.Records);
|
|
}
|
|
|
|
private static Quote GetRandomQuote(IEnumerable<Quote> quotes) {
|
|
var length = quotes.Count();
|
|
if (length == 0) {
|
|
return null;
|
|
}
|
|
|
|
return quotes
|
|
.Skip(random.Next(length))
|
|
.Take(1)
|
|
.Single();
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Quote> GetBestQuotes(int start, int end, out int totalCount) {
|
|
totalCount = quoteRepository.Records.Count();
|
|
|
|
return quoteRepository.Records
|
|
.OrderByDescending(quote => quote.Score)
|
|
.ThenByDescending(quote => quote.UpVotes)
|
|
.Skip(start - 1)
|
|
.Take(end - start + 1);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public Vote GetVoteOrCreateNew(Quote quote, User voter) {
|
|
var vote = voteRepository.Records.SingleOrDefault(v => v.Quote == quote && v.Voter == voter);
|
|
return vote ?? new Vote {
|
|
Quote = quote,
|
|
Voter = voter
|
|
};
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<Quote> GetBrowsableQuotes(BrowseModel model, int start, int end, out int totalCount) {
|
|
var quotes = quoteRepository.Records;
|
|
if (model.GameIds.Any()) {
|
|
quotes = quotes.Where(quote => model.GameIds.Contains(quote.Game.Id));
|
|
}
|
|
if (model.PublisherIds.Any()) {
|
|
quotes = quotes.Where(quote => quote.Game.Publishers.Any(publisher => model.PublisherIds.Contains(publisher.Id)));
|
|
}
|
|
if (model.SystemIds.Any()) {
|
|
quotes = quotes.Where(quote => quote.Game.Systems.Any(system => model.SystemIds.Contains(system.Id)));
|
|
}
|
|
if (model.CategoryIds.Any()) {
|
|
quotes = quotes.Where(quote => quote.Categories.Any(category => model.CategoryIds.Contains(category.Id)));
|
|
}
|
|
|
|
totalCount = quotes.Count();
|
|
return quotes.Skip(start - 1).Take(end - start + 1);
|
|
}
|
|
|
|
|
|
[UnitOfWork, CanBeNull]
|
|
public Quote GetQuoteForDayOfYear(int day) {
|
|
if (!quoteOfTheDayMap.ContainsKey(day)) {
|
|
quoteOfTheDayMap[day] = GetRandomQuote(quoteRepository.Records.Where(quote => quote.Score > 0));
|
|
}
|
|
|
|
return quoteOfTheDayMap[day];
|
|
}
|
|
}
|
|
} |