Skip to content

Commit

Permalink
Atached recomendation algorithm to controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
bilimig committed Jun 23, 2024
1 parent 76a93f1 commit c749b18
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 60 deletions.
76 changes: 46 additions & 30 deletions Server/ReasnAPI/ReasnAPI/Controllers/MeController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.Tracing;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -12,19 +13,14 @@ namespace ReasnAPI.Controllers;
[ApiController]
[Authorize]
[Route("[controller]")]
public class MeController(UserService userService, EventService eventService, ParticipantService participantService, ImageService imageService) : ControllerBase
public class MeController(UserService userService, EventService eventService, ParticipantService participantService, ImageService imageService, RecomendationService recomendationService) : ControllerBase
{
private readonly UserService _userService = userService;
private readonly EventService _eventService = eventService;
private readonly ParticipantService _participantService = participantService;
private readonly ImageService _imageService = imageService;

[HttpGet]
[ProducesResponseType<UserDto>(StatusCodes.Status200OK)]
public IActionResult GetCurrentUser()
{
var username = _userService.GetCurrentUser().Username;
var user = _userService.GetUserByUsername(username);
var username = userService.GetCurrentUser().Username;
var user = userService.GetUserByUsername(username);

return Ok(user);
}
Expand All @@ -37,15 +33,15 @@ public IActionResult UpdateCurrentUser(
{
validator.ValidateAndThrow(userDto);

var user = _userService.GetCurrentUser();
var user = userService.GetCurrentUser();

// Users cant change their role in this endpoint
if (user.Role != userDto.Role)
{
return Forbid();
}

var updatedUser = _userService.UpdateUser(user.Username, userDto);
var updatedUser = userService.UpdateUser(user.Username, userDto);

return Ok(updatedUser);
}
Expand All @@ -55,8 +51,8 @@ public IActionResult UpdateCurrentUser(
[ProducesResponseType<ImageDto>(StatusCodes.Status200OK)]
public IActionResult GetCurrentUserImage()
{
var user = _userService.GetCurrentUser();
var image = _imageService.GetImageByUserId(user.Id);
var user = userService.GetCurrentUser();
var image = imageService.GetImageByUserId(user.Id);

if (image is null)
{
Expand All @@ -71,7 +67,7 @@ public IActionResult GetCurrentUserImage()
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> AddCurrentUserImage([FromForm] List<IFormFile> images)
{
var userId = _userService.GetCurrentUser().Id;
var userId = userService.GetCurrentUser().Id;

foreach (var image in images.Where(image => image.Length > 0))
{
Expand All @@ -86,7 +82,7 @@ public async Task<IActionResult> AddCurrentUserImage([FromForm] List<IFormFile>
ImageData = fileBytes
};

_imageService.CreateImages([imageDto]);
imageService.CreateImages([imageDto]);
}

return Ok();
Expand All @@ -97,7 +93,7 @@ public async Task<IActionResult> AddCurrentUserImage([FromForm] List<IFormFile>
[ProducesResponseType<ImageDto>(StatusCodes.Status200OK)]
public async Task<IActionResult> UpdateCurrentUserImage([FromForm] List<IFormFile> images)
{
var userId = _userService.GetCurrentUser().Id;
var userId = userService.GetCurrentUser().Id;

foreach (var image in images.Where(image => image.Length > 0))
{
Expand All @@ -112,7 +108,7 @@ public async Task<IActionResult> UpdateCurrentUserImage([FromForm] List<IFormFil
ImageData = fileBytes
};

_imageService.UpdateImageForUser(userId, imageDto);
imageService.UpdateImageForUser(userId, imageDto);
}

return Ok();
Expand All @@ -123,8 +119,8 @@ public async Task<IActionResult> UpdateCurrentUserImage([FromForm] List<IFormFil
[ProducesResponseType(StatusCodes.Status204NoContent)]
public IActionResult DeleteCurrentUserImage()
{
var userId = _userService.GetCurrentUser().Id;
_imageService.DeleteImageByObjectIdAndType(userId, ObjectType.User);
var userId = userService.GetCurrentUser().Id;
imageService.DeleteImageByObjectIdAndType(userId, ObjectType.User);

return NoContent();
}
Expand All @@ -134,12 +130,12 @@ public IActionResult DeleteCurrentUserImage()
[ProducesResponseType<IEnumerable<EventResponse>>(StatusCodes.Status200OK)]
public IActionResult GetCurrentUserEvents()
{
var user = _userService.GetCurrentUser();
var events = _eventService.GetUserEvents(user.Username);
var user = userService.GetCurrentUser();
var events = eventService.GetUserEvents(user.Username);

if (user.Role == UserRole.Organizer)
{
var organizerEvents = _eventService.GetEventsByFilter(e => e.OrganizerId == user.Id);
var organizerEvents = eventService.GetEventsByFilter(e => e.OrganizerId == user.Id);
events = events.Concat(organizerEvents);
}

Expand All @@ -151,9 +147,9 @@ public IActionResult GetCurrentUserEvents()
[ProducesResponseType<ParticipantDto>(StatusCodes.Status201Created)]
public IActionResult EnrollCurrentUserInEvent([FromRoute] string slug)
{
var user = _userService.GetCurrentUser();
var user = userService.GetCurrentUser();

var participant = _participantService.CreateOrUpdateParticipant(new ParticipantDto { EventSlug = slug, Username = user.Username, Status = ParticipantStatus.Interested });
var participant = participantService.CreateOrUpdateParticipant(new ParticipantDto { EventSlug = slug, Username = user.Username, Status = ParticipantStatus.Interested });

var location = Url.Action(
action: nameof(GetCurrentUserEvents),
Expand All @@ -167,8 +163,8 @@ public IActionResult EnrollCurrentUserInEvent([FromRoute] string slug)
[ProducesResponseType<ParticipantDto>(StatusCodes.Status200OK)]
public IActionResult ConfirmCurrentUserEventAttendance([FromRoute] string slug)
{
var user = _userService.GetCurrentUser();
var participant = _participantService.CreateOrUpdateParticipant(new ParticipantDto { EventSlug = slug, Username = user.Username, Status = ParticipantStatus.Participating });
var user = userService.GetCurrentUser();
var participant = participantService.CreateOrUpdateParticipant(new ParticipantDto { EventSlug = slug, Username = user.Username, Status = ParticipantStatus.Participating });

return Ok(participant);
}
Expand All @@ -178,16 +174,36 @@ public IActionResult ConfirmCurrentUserEventAttendance([FromRoute] string slug)
[ProducesResponseType(StatusCodes.Status204NoContent)]
public IActionResult CancelCurrentUserEventAttendance([FromRoute] string slug)
{
var userId = _userService.GetCurrentUser().Id;
_participantService.DeleteParticipant(userId, slug);
var userId = userService.GetCurrentUser().Id;
participantService.DeleteParticipant(userId, slug);

return NoContent();
}

[HttpGet]
[Route("events/recommendations")]
public IActionResult GetCurrentUserEventRecommendations()
{
throw new NotImplementedException();
[ProducesResponseType<List<EventSugestion>>(StatusCodes.Status200OK)]
public async Task<IActionResult> GetCurrentUserEventRecommendations(
[FromQuery] int offset = 0,
[FromQuery] int limit = 10)
{

var currentUser = userService.GetCurrentUser();
var username = currentUser.Username;
var currentUserInterest = userService.GetUserByUsername(username).Interests;
if (currentUserInterest == null || currentUserInterest.Count == 0)
{
return Ok(new List<EventSugestion>());
}

var request = new RecomendationPageRequest
{
Limit = limit,
Offset = offset
};

var events = await recomendationService.GetEventsByInterest(currentUserInterest, username, request);

return Ok(events);
}
}
12 changes: 0 additions & 12 deletions Server/ReasnAPI/ReasnAPI/Controllers/UsersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,6 @@ public IActionResult GetUserByUsername([FromRoute] string username)
return Ok(user);
}

[HttpGet]
[Route("{username}/recomendetevents")]
public async Task<IActionResult> GetRecomendetEvents(string username)
{
var currentUser = _userService.GetUserByUsername(username);
var interests = currentUser.Interests;

var events = await _recomendationService.GetEventsByInterest(interests, username);

return Ok(events);
}

[HttpPut]
[Authorize]
[Route("{username}")]
Expand Down
12 changes: 12 additions & 0 deletions Server/ReasnAPI/ReasnAPI/Mappers/EventMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,17 @@ public static EventDto ToDto(this EventCreateRequest eventCreateRequest, int org
};
}

public static EventSugestion ToSugestion(this EventDto eventDto, Participants participants, List<string> images)
{
return new EventSugestion()
{
Name = eventDto.Name,
Slug = eventDto.Slug,
Description = eventDto.Description,
Participants = participants,
Images = images
};
}

}
}
12 changes: 12 additions & 0 deletions Server/ReasnAPI/ReasnAPI/Models/API/EventSugestion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace ReasnAPI.Models.API
{
public class EventSugestion
{
public string Name { get; set; } = null!;
public string Slug { get; set; } = null!;
public string Description { get; set; } = null!;
public List<String>? Images { get; set; }
public Participants? Participants { get; set; }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ReasnAPI.Models.API
{
public class RecomendationPageRequest
{
public int Offset { get; set; }
public int Limit { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ReasnAPI.Models.API
{
public class RecomendationPageResponse<T>
{
public List<T>? Items { get; set; }
public int Offset { get; set; }
public int Limit { get; set; }
}
}
34 changes: 16 additions & 18 deletions Server/ReasnAPI/ReasnAPI/Services/RecomendationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
using ReasnAPI.Mappers;
using ReasnAPI.Models.Recomendation;
using Npgsql;
using ReasnAPI.Models.API;
using ReasnAPI.Models.Enums;

namespace ReasnAPI.Services
{
public class RecomendationService(ReasnContext context,EventService eventService, IConfiguration configuration)
public class RecomendationService(ReasnContext context,EventService eventService, ImageService imageService, IConfiguration configuration)

Check warning on line 18 in Server/ReasnAPI/ReasnAPI/Services/RecomendationService.cs

View workflow job for this annotation

GitHub Actions / dotnet-tests (ubuntu-latest)

Parameter 'imageService' is unread.

Check warning on line 18 in Server/ReasnAPI/ReasnAPI/Services/RecomendationService.cs

View workflow job for this annotation

GitHub Actions / dotnet-tests (macos-latest)

Parameter 'imageService' is unread.
{
private readonly string? _connectionString = configuration.GetConnectionString("DefaultValue");

public async Task<List<EventDto>> GetEventsByInterest(List<UserInterestDto> interestsDto, string username)
public async Task<List<EventSugestion>> GetEventsByInterest(List<UserInterestDto> interestsDto, string username, RecomendationPageRequest pageRequest)
{
var interests = interestsDto.Select(i => i.Interest.Name).ToList();
var interestsLevels = interestsDto.Select(i => i.Level).ToList();
Expand Down Expand Up @@ -50,7 +52,7 @@ public async Task<List<EventDto>> GetEventsByInterest(List<UserInterestDto> inte
var events = await context.Events
.Include(e => e.Tags)
.Include(e => e.Parameters)
.Where(e => e.Tags.Any(t => tagNames.Contains(t.Name)) && !userEventSlugs.Contains(e.Slug))
.Where(e => !userEventSlugs.Contains(e.Slug) && (e.Status == EventStatus.Approved || e.Status == EventStatus.Ongoing))
.Select(e => new
{
Event = e,
Expand All @@ -59,27 +61,23 @@ public async Task<List<EventDto>> GetEventsByInterest(List<UserInterestDto> inte
})
.OrderByDescending(e => e.TotalTagValue)
.Select(e => e.Event)
.Skip((pageRequest.Offset))
.Take(pageRequest.Limit)
.ToListAsync();


var eventDtos = events.Select(e => e.ToDto()).ToList();

if (eventDtos.Count < 10)

var eventSugestions = new List<EventSugestion>();
foreach (var eventDto in eventDtos)
{
int additionalEventsNeeded = 10 - eventDtos.Count;
var randomEvents = await context.Events
.Include(e => e.Tags)
.Include(e => e.Parameters)
.Where(e => !events.Contains(e))
.OrderBy(r => r.StartAt)
.Take(additionalEventsNeeded)
.ToListAsync();

eventDtos.AddRange(randomEvents.Select(e => e.ToDto()));

var participating = eventService.GetEventParticipantsCountBySlugAndStatus(eventDto.Slug, ParticipantStatus.Participating);
var interested = eventService.GetEventParticipantsCountBySlugAndStatus(eventDto.Slug, ParticipantStatus.Interested);
var participants = new Participants(participating, interested);
var images = eventService.GetEventImages(eventDto.Slug);
eventSugestions.Add(eventDto.ToSugestion(participants, images));
}

return eventDtos;
return eventSugestions;
}
catch (Exception ex)
{
Expand Down

0 comments on commit c749b18

Please sign in to comment.