diff options
author | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-12-05 21:33:20 +0100 |
---|---|---|
committer | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-12-05 21:33:20 +0100 |
commit | b1e3ebe5dc5a7dbfefeef79924255f1906983181 (patch) | |
tree | a323fe4c2f6c3c10b752594b54c31f3c871d5674 /Backend | |
parent | 4eab4ea8df9e3aeb7db8c86fd54a6fa9d59d11a7 (diff) | |
parent | 951b36b54b106178200cfa4fb2bbc499ca1a2de0 (diff) |
Merge branch 'develop' of http://gitlab.pmf.kg.ac.rs/BrzoDoLokacije2022/odyssey/brzodolokacije into develop
# Conflicts:
# Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt
# Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml
Diffstat (limited to 'Backend')
-rw-r--r-- | Backend/Api/Api/Controllers/LocationController.cs | 22 | ||||
-rw-r--r-- | Backend/Api/Api/Controllers/PostController.cs | 13 | ||||
-rw-r--r-- | Backend/Api/Api/Controllers/UserController.cs | 23 | ||||
-rw-r--r-- | Backend/Api/Api/Interfaces/IPostService.cs | 4 | ||||
-rw-r--r-- | Backend/Api/Api/Models/Post.cs | 9 | ||||
-rw-r--r-- | Backend/Api/Api/Models/User.cs | 15 | ||||
-rw-r--r-- | Backend/Api/Api/Services/LocationService.cs | 2 | ||||
-rw-r--r-- | Backend/Api/Api/Services/PostService.cs | 163 | ||||
-rw-r--r-- | Backend/Api/Api/Services/UserService.cs | 1 |
9 files changed, 249 insertions, 3 deletions
diff --git a/Backend/Api/Api/Controllers/LocationController.cs b/Backend/Api/Api/Controllers/LocationController.cs index ba9c9a8..ac093bb 100644 --- a/Backend/Api/Api/Controllers/LocationController.cs +++ b/Backend/Api/Api/Controllers/LocationController.cs @@ -12,9 +12,11 @@ namespace Api.Controllers public class LocationController : ControllerBase { private readonly ILocationService _locationService; - public LocationController(ILocationService locationService) + private readonly IPostService _postService; + public LocationController(ILocationService locationService, IPostService postService) { _locationService = locationService; + _postService = postService; } [HttpPost("add")] @@ -74,5 +76,23 @@ namespace Api.Controllers return Ok(ret); } } + + [HttpGet("searchradius")] + [Authorize(Roles = "User")] + public async Task<ActionResult<List<Location>>> bestPostsForLocationInRadius(double latitude, double longitude, double radius) + { + Coords coords = new Coords(); + if (latitude != null && longitude != null) + { + coords.latitude = (double)latitude; + coords.longitude = (double)longitude; + } + List<PostSend> ret = new List<PostSend>(); + ret = await _postService.BestPostForAllLocationsInRadius(coords, radius); + if (ret != null && ret.Count > 0) + return Ok(ret); + return BadRequest(); + + } } } diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 03c3f81..61a4f48 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -186,5 +186,18 @@ namespace Api.Controllers var userid = await _userService.UserIdFromJwt(); return Ok(await _postService.Recommended(userid)); } + [HttpGet("favourite/{id}")] + [Authorize(Roles = "User")] + public async Task<ActionResult<bool>> addRemoveFavourite(string id) + { + return Ok(await _postService.addRemoveFavourite(id)); + } + + [HttpGet("trending")] + [Authorize(Roles = "User")] + public async Task<ActionResult<List<Trending>>> Trending() + { + return Ok(await _postService.TrendingTags()); + } } } diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 4d7905a..97f2f8b 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -123,5 +123,28 @@ namespace Api.Controllers { return Ok(await _userService.GetMyFollowers()); } + + [HttpGet("profile/stats")] + [Authorize(Roles = "User")] + public async Task<ActionResult<UserStats>> SelfStats() + { + var id = await _userService.UserIdFromJwt(); + var tosend = await _postService.UserStats(id); + if (tosend != null) + return Ok(tosend); + return BadRequest(); + } + [HttpGet("{username}/profile/stats")] + [Authorize(Roles = "User")] + public async Task<ActionResult<UserStats>> GetStats(string username) + { + var rez = await _userService.GetUserData(username); + if (rez == null) + return BadRequest(); + var tosend = await _postService.UserStats(rez._id); + if (tosend != null) + return Ok(tosend); + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 96786bd..c854601 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -27,5 +27,9 @@ namespace Api.Interfaces Task<List<PostSend>> Get10Newest(); Task<List<PostSend>> Recommended(string userid); + Task<Boolean> addRemoveFavourite(string postId); + Task<List<Trending>> TrendingTags(); + Task<List<PostSend>> BestPostForAllLocationsInRadius(Coords coords, double radius); + Task<UserStats> UserStats(string userid); } }
\ No newline at end of file diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs index dd007ec..9c0c429 100644 --- a/Backend/Api/Api/Models/Post.cs +++ b/Backend/Api/Api/Models/Post.cs @@ -19,6 +19,7 @@ namespace Api.Models public List<Comment> comments { get; set; } public List<File> images { get; set; } public List<string>? tags { get; set; } + public List<string>? favourites { get; set; } } public class PostReceive @@ -43,6 +44,7 @@ namespace Api.Models public List<File> images { get; set; } public List<string>? tags { get; set; } public DateTime? lastViewed { get; set; } + public List<string>? favourites { get; set; } } public class Rating { @@ -113,5 +115,12 @@ namespace Api.Models { public int counter { get; set; } public string tag { get; set; } + public int? views { get; set; } + } + + public class Trending + { + public TagR tagr { get; set; } + public PostSendPage page { get; set; } } } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index 6c777e7..cf16dbe 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -72,4 +72,19 @@ namespace Api.Models } + + public class UserStats + { + public int totalViews { get; set; } + public int numberOfPosts { get; set; } + public int numberOfRatingsOnPosts { get; set; } + public double averagePostRatingOnPosts {get; set; } + public List<MonthlyViews> monthlyViews { get; set; } + } + + public class MonthlyViews + { + public int month { get; set; } + public int views { get; set; } + } } diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs index afb3b5b..55a52e7 100644 --- a/Backend/Api/Api/Services/LocationService.cs +++ b/Backend/Api/Api/Services/LocationService.cs @@ -99,5 +99,7 @@ namespace Api.Services } return tosend; } + + } } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 855b231..6d28206 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -15,6 +15,7 @@ namespace Api.Services private readonly IFileService _fileService; private readonly ILocationService _locationService; private readonly IMongoCollection<User> _users; + private readonly IMongoCollection<Location> _locations; public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext, IFileService fileService,ILocationService locationService) { var database = mongoClient.GetDatabase(settings.DatabaseName); @@ -23,6 +24,7 @@ namespace Api.Services _httpContext = httpContext; _fileService = fileService; _locationService = locationService; + _locations = database.GetCollection<Location>(settings.LocationCollectionName); } public async Task<PostSend> addPost(PostReceive post) @@ -89,6 +91,7 @@ namespace Api.Services p.createdAt = post.createdAt; p.tags = post.tags; p.ratingscount = post.ratings.Count(); + p.favourites = post.favourites; if (post.ratings.Count() > 0) { List<int> ratings = new List<int>(); @@ -346,7 +349,27 @@ namespace Api.Services var lista = new List<Post>(); var ls = new List<PostSend>(); var xd = new List<PostSend>(); - lista = await _posts.Find(x => x.locationId == locid).ToListAsync(); + if(ObjectId.TryParse(locid, out _)) + lista = await _posts.Find(x => x.locationId == locid).ToListAsync(); + else + { + lista = await _posts.Find(x => x.tags != null && x.tags.Any(y => y.ToLower().Contains(locid.ToLower()))).ToListAsync(); + if (lista.Count==0) + { + var locs = await _locations.Find(x => x.city.ToLower().Contains(locid.ToLower()) || x.name.ToLower().Contains(locid.ToLower())).ToListAsync(); + foreach(var loc in locs) + { + var posts =await _posts.Find(x => x.locationId == loc._id).ToListAsync(); + if(posts != null) + { + foreach(var p in posts) + { + lista.Add(p); + } + } + } + } + } if (lista != null) { foreach (var elem in lista) @@ -471,7 +494,7 @@ namespace Api.Services public async Task<List<PostSend>> Recommended(string userid) // momgodb bloat bleh { List<PostSend> posts = await UserHistory(userid); - //TODO-LIMIT RECOMMENDED FOR POSTS FROM THIS MONTH ONLY + //TODO-LIMIT RECOMMENDED FOR POSTS FROM THIS MONTH List<TagR> tags = new List<TagR>(); foreach (var post in posts) { @@ -530,5 +553,141 @@ namespace Api.Services taggedposts = fiveoftop5tags.Distinct().OrderByDescending(x => x.createdAt).ToList(); return taggedposts; } + public async Task<Boolean> addRemoveFavourite(string postId) + { + string userId = _httpContext.HttpContext.User.FindFirstValue("id"); + var result = false; + Post post = await _posts.Find(x => x._id == postId).FirstOrDefaultAsync(); + if (userId == null || post==null) + return result; + if (post.favourites == null) + post.favourites = new List<string>(); + if (post.favourites.Contains(userId)) + { + post.favourites.Remove(userId); + result = false; + } + else + { + post.favourites.Add(userId); + result = true; + + } + await _posts.ReplaceOneAsync(x => x._id == postId, post); + return result; + + } + + public async Task<List<Trending>> TrendingTags() + { + var all = await _posts.Find(_ => true).ToListAsync(); + var posts = new List<PostSend>(); + foreach (var elem in all) + { + if ((DateTime.Now - elem.createdAt).TotalDays < 7) + posts.Add(await postToPostSend(elem)); + } + List<TagR> tags = new List<TagR>(); + foreach (var post in posts) + { + if (post.tags != null) + { + foreach (var tagitem in post.tags) + { + if (!tags.Any(x => x.tag == tagitem)) + { + var newtag = new TagR(); + newtag.tag = tagitem; + newtag.counter = 1; + newtag.views = post.views; + tags.Add(newtag); + } + else + { + var replace = tags.Find(x => x.tag == tagitem); + tags.Remove(replace); + replace.counter += 1; + replace.views += post.views; + tags.Add(replace); + } + } + } + } + var top10tags = tags.OrderByDescending(x => x.views).Take(10).ToList(); + + var tosend = new List<Trending>(); + foreach(var trending in top10tags) + { + var novi = new Trending(); + novi.tagr = trending; + novi.page = await SearchPosts(trending.tag, 0, 1, 5); + tosend.Add(novi); + } + + return tosend; + } + + public async Task<List<PostSend>> BestPostForAllLocationsInRadius(Coords coords, double radius) + { + if (coords == null) + return null; + var lista = await _locations.Find(_ => true).ToListAsync(); + var inradius = new List<Location>(); + var tosend = new List<PostSend>(); + if (lista != null) + { + foreach (var elem in lista) + { + if (Math.Abs(elem.latitude - coords.latitude) < radius && Math.Abs(elem.longitude - coords.longitude) < radius) + inradius.Add(elem); + } + foreach (var elem in inradius) + { + var locposts = await SearchPosts(elem._id, 0, 1, 1); + var best = locposts.posts.Take(1).FirstOrDefault(); + if(best != null) + tosend.Add(best); + } + } + return tosend; + } + + public async Task<UserStats> UserStats(string userid) + { + var posts = await GetUsersPosts(userid); + var stats = new UserStats(); + double ratingsum = 0; + stats.averagePostRatingOnPosts = 0; + stats.numberOfRatingsOnPosts = 0; + stats.numberOfPosts = 0; + stats.totalViews = 0; + stats.monthlyViews = new List<MonthlyViews>(); + + + if(posts != null) + { + for(int i = 1; i <= 12; i++) + { + var novi = new MonthlyViews(); + novi.month = i; + novi.views = 0; + stats.monthlyViews.Add(novi); + } + + foreach (var post in posts) + { + var month = post.createdAt.Month; + stats.monthlyViews.FirstOrDefault(x => x.month == month).views += post.views; + stats.totalViews += post.views; + stats.numberOfRatingsOnPosts += post.ratingscount; + stats.numberOfPosts++; + ratingsum += post.ratings * post.ratingscount; + } + if(stats.numberOfRatingsOnPosts > 0) //don't forget to check div by 0 jesus + stats.averagePostRatingOnPosts = ratingsum / stats.numberOfRatingsOnPosts; + } + return stats; + } } + } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index ec67729..666dd98 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -663,6 +663,7 @@ namespace Api.Services return null; } + } } |