159 lines
5.6 KiB
C#
159 lines
5.6 KiB
C#
using DysonNetwork.Shared.Proto;
|
|
using DysonNetwork.Shared.Models;
|
|
using Grpc.Core;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Text.Json;
|
|
using PollQuestionType = DysonNetwork.Shared.Proto.PollQuestionType;
|
|
|
|
namespace DysonNetwork.Sphere.Poll;
|
|
|
|
public class PollServiceGrpc(AppDatabase db, PollService ps) : Shared.Proto.PollService.PollServiceBase
|
|
{
|
|
public override async Task<Shared.Proto.Poll> GetPoll(GetPollRequest request, ServerCallContext context)
|
|
{
|
|
if (!Guid.TryParse(request.Id, out var id))
|
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "invalid poll id"));
|
|
|
|
var poll = await db.Polls
|
|
.Include(p => p.Publisher)
|
|
.Include(p => p.Questions)
|
|
.FirstOrDefaultAsync(p => p.Id == id);
|
|
|
|
if (poll == null) throw new RpcException(new Status(StatusCode.NotFound, "poll not found"));
|
|
|
|
return poll.ToProtoValue();
|
|
}
|
|
|
|
public override async Task<GetPollBatchResponse> GetPollBatch(GetPollBatchRequest request,
|
|
ServerCallContext context)
|
|
{
|
|
var ids = request.Ids
|
|
.Where(s => !string.IsNullOrWhiteSpace(s) && Guid.TryParse(s, out _))
|
|
.Select(Guid.Parse)
|
|
.ToList();
|
|
|
|
if (ids.Count == 0) return new GetPollBatchResponse();
|
|
|
|
var polls = await db.Polls
|
|
.Include(p => p.Publisher)
|
|
.Include(p => p.Questions)
|
|
.Where(p => ids.Contains(p.Id))
|
|
.ToListAsync();
|
|
|
|
var resp = new GetPollBatchResponse();
|
|
resp.Polls.AddRange(polls.Select(p => p.ToProtoValue()));
|
|
return resp;
|
|
}
|
|
|
|
public override async Task<ListPollsResponse> ListPolls(ListPollsRequest request, ServerCallContext context)
|
|
{
|
|
var query = db.Polls
|
|
.Include(p => p.Publisher)
|
|
.Include(p => p.Questions)
|
|
.AsQueryable();
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.PublisherId) && Guid.TryParse(request.PublisherId, out var pid))
|
|
query = query.Where(p => p.PublisherId == pid);
|
|
|
|
var totalSize = await query.CountAsync();
|
|
|
|
var pageSize = request.PageSize > 0 ? request.PageSize : 20;
|
|
var pageToken = request.PageToken;
|
|
var offset = string.IsNullOrEmpty(pageToken) ? 0 : int.Parse(pageToken);
|
|
|
|
IOrderedQueryable<SnPoll> orderedQuery;
|
|
|
|
if (!string.IsNullOrEmpty(request.OrderBy))
|
|
{
|
|
switch (request.OrderBy)
|
|
{
|
|
case "title":
|
|
orderedQuery = request.OrderDesc
|
|
? query.OrderByDescending(q => q.Title ?? string.Empty)
|
|
: query.OrderBy(q => q.Title ?? string.Empty);
|
|
break;
|
|
case "ended_at":
|
|
orderedQuery = request.OrderDesc
|
|
? query.OrderByDescending(q => q.EndedAt)
|
|
: query.OrderBy(q => q.EndedAt);
|
|
break;
|
|
default:
|
|
orderedQuery = request.OrderDesc
|
|
? query.OrderByDescending(q => q.CreatedAt)
|
|
: query.OrderBy(q => q.CreatedAt);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
orderedQuery = request.OrderDesc
|
|
? query.OrderByDescending(q => q.CreatedAt)
|
|
: query.OrderBy(q => q.CreatedAt);
|
|
}
|
|
|
|
var polls = await orderedQuery
|
|
.Skip(offset)
|
|
.Take(pageSize)
|
|
.ToListAsync();
|
|
|
|
var nextToken = offset + pageSize < totalSize ? (offset + pageSize).ToString() : string.Empty;
|
|
|
|
var resp = new ListPollsResponse();
|
|
resp.Polls.AddRange(polls.Select(p => p.ToProtoValue()));
|
|
resp.NextPageToken = nextToken;
|
|
resp.TotalSize = totalSize;
|
|
|
|
return resp;
|
|
}
|
|
|
|
public override async Task<PollAnswer> GetPollAnswer(GetPollAnswerRequest request, ServerCallContext context)
|
|
{
|
|
if (!Guid.TryParse(request.PollId, out var pollId))
|
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "invalid poll id"));
|
|
|
|
if (!Guid.TryParse(request.AccountId, out var accountId))
|
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "invalid account id"));
|
|
|
|
var answer = await ps.GetPollAnswer(pollId, accountId);
|
|
|
|
if (answer == null)
|
|
throw new RpcException(new Status(StatusCode.NotFound, "answer not found"));
|
|
|
|
return answer.ToProtoValue();
|
|
}
|
|
|
|
public override async Task<GetPollStatsResponse> GetPollStats(GetPollStatsRequest request, ServerCallContext context)
|
|
{
|
|
if (!Guid.TryParse(request.PollId, out var pollId))
|
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "invalid poll id"));
|
|
|
|
var stats = await ps.GetPollStats(pollId);
|
|
|
|
var resp = new GetPollStatsResponse();
|
|
foreach (var stat in stats)
|
|
{
|
|
var statsJson = JsonSerializer.Serialize(stat.Value);
|
|
resp.Stats[stat.Key.ToString()] = statsJson;
|
|
}
|
|
|
|
return resp;
|
|
}
|
|
|
|
public override async Task<GetPollQuestionStatsResponse> GetPollQuestionStats(GetPollQuestionStatsRequest request,
|
|
ServerCallContext context)
|
|
{
|
|
if (!Guid.TryParse(request.QuestionId, out var questionId))
|
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "invalid question id"));
|
|
|
|
var stats = await ps.GetPollQuestionStats(questionId);
|
|
|
|
var resp = new GetPollQuestionStatsResponse();
|
|
foreach (var stat in stats)
|
|
{
|
|
resp.Stats[stat.Key] = stat.Value;
|
|
}
|
|
|
|
return resp;
|
|
}
|
|
}
|