aboutsummaryrefslogtreecommitdiff
path: root/Backend
diff options
context:
space:
mode:
authorOgnjen Cirkovic <ciraboxkg@gmail.com>2022-12-06 17:25:53 +0000
committerOgnjen Cirkovic <ciraboxkg@gmail.com>2022-12-06 17:25:53 +0000
commit5a205c35d936728f76451109751e1fb5a9a75bd1 (patch)
tree2a1f7296e2186a895d730579cabc7130713f16cf /Backend
parentb76cefc486097d776e3ff374b27ce3bfb0786b56 (diff)
parentf7e16147ecb993af365c6d132f2782b73255fe2c (diff)
Merge branch 'develop' into 'master'
Merge develop->master See merge request BrzoDoLokacije2022/odyssey/brzodolokacije!10
Diffstat (limited to 'Backend')
-rw-r--r--Backend/Api/Api/Controllers/LocationController.cs22
-rw-r--r--Backend/Api/Api/Controllers/PostController.cs13
-rw-r--r--Backend/Api/Api/Controllers/UserController.cs41
-rw-r--r--Backend/Api/Api/Interfaces/IPostService.cs4
-rw-r--r--Backend/Api/Api/Interfaces/IUserService.cs4
-rw-r--r--Backend/Api/Api/Models/Post.cs9
-rw-r--r--Backend/Api/Api/Models/User.cs15
-rw-r--r--Backend/Api/Api/Services/LocationService.cs2
-rw-r--r--Backend/Api/Api/Services/PostService.cs163
-rw-r--r--Backend/Api/Api/Services/UserService.cs69
10 files changed, 338 insertions, 4 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..73d32ea 100644
--- a/Backend/Api/Api/Controllers/UserController.cs
+++ b/Backend/Api/Api/Controllers/UserController.cs
@@ -123,5 +123,46 @@ 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();
+ }
+
+ [HttpGet("{newUsername}/changeMyUsername")]
+ [Authorize(Roles = "User")]
+ public async Task<ActionResult<int>> ChangeMyProfileUsername(string newUsername)
+ {
+ return await _userService.ChangeMyProfileUsername(newUsername);
+ }
+
+
+ [HttpGet("{newName}/changeMyName")]
+ [Authorize(Roles = "User")]
+ public async Task<ActionResult<bool>> ChangeMyProfileName(string newName)
+ {
+ return Ok(await _userService.ChangeMyProfileName(newName));
+ }
+
+
+
}
}
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/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs
index 95dd46d..f4954e0 100644
--- a/Backend/Api/Api/Interfaces/IUserService.cs
+++ b/Backend/Api/Api/Interfaces/IUserService.cs
@@ -37,5 +37,9 @@ namespace Api.Interfaces
Task<List<UserSend>> GetMyFollowers();
+ Task<int> ChangeMyProfileUsername(String newUsername);
+ Task<bool> ChangeMyProfileName(String newUsername);
+
+
}
}
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..781afa8 100644
--- a/Backend/Api/Api/Services/UserService.cs
+++ b/Backend/Api/Api/Services/UserService.cs
@@ -360,6 +360,10 @@ namespace Api.Services
tosend._id= user._id;
tosend.creationDate = user.creationDate;
tosend.email="";
+ tosend.followersCount = user.followersCount;
+ tosend.followingCount = user.followingCount;
+ tosend.followers = user.followers;
+ tosend.following = user.following;
var userposts = await _posts.Find(x => x.ownerId == user._id).ToListAsync();
tosend.postcount = userposts.Count();
return tosend;
@@ -376,6 +380,10 @@ namespace Api.Services
tosend._id = user._id;
tosend.creationDate = user.creationDate;
tosend.email = user.email;
+ tosend.followersCount = user.followersCount;
+ tosend.followingCount = user.followingCount;
+ tosend.followers = user.followers;
+ tosend.following = user.following;
var userposts = await _posts.Find(x => x.ownerId == user._id).ToListAsync();
tosend.postcount = userposts.Count();
return tosend;
@@ -466,6 +474,9 @@ namespace Api.Services
follower.email = utemp.username;
follower.following = utemp.following;
follower.followers = utemp.followers;
+ follower.followersCount = utemp.followersCount;
+ follower.followingCount = utemp.followingCount;
+
follower._id = utemp._id;
followers.Add((UserSend)follower);
@@ -502,6 +513,8 @@ namespace Api.Services
follower.following = utemp.following;
follower.followers = utemp.followers;
follower._id = utemp._id;
+ follower.followersCount = utemp.followersCount;
+ follower.followingCount = utemp.followingCount;
following.Add((UserSend)follower);
}
@@ -543,6 +556,8 @@ namespace Api.Services
following.following = utemp.following;
following.followers = utemp.followers;
following._id = utemp._id;
+ following.followersCount = utemp.followersCount;
+ following.followingCount = utemp.followingCount;
myFollowings.Add((UserSend)following);
}
@@ -654,8 +669,9 @@ namespace Api.Services
follower.email = utemp.username;
follower.following = utemp.following;
follower.followers = utemp.followers;
+ follower.followersCount = utemp.followersCount;
+ follower.followingCount = utemp.followingCount;
follower._id = utemp._id;
-
myfollowers.Add((UserSend)follower);
}
return myfollowers;
@@ -663,6 +679,57 @@ namespace Api.Services
return null;
}
+
+ public async Task<int> ChangeMyProfileUsername(string newUsername)
+ {
+ string myId = null;
+
+ if (_httpContext.HttpContext.User.FindFirstValue("id") != null)
+ {
+ myId = _httpContext.HttpContext.User.FindFirstValue("id").ToString();
+ }
+ User u = await _users.Find(user => user._id == myId).FirstOrDefaultAsync();
+ if (u != null)
+ {
+
+ //da li username vec postoji?
+ if (await _users.Find(x => x.username == newUsername).FirstOrDefaultAsync() != null)
+ {
+ //vec postoji korisnik sa navedenim korisnickim imenom
+ return -1;
+ }
+ else
+ {
+ u.username = newUsername;
+ await _users.ReplaceOneAsync(x => x._id == u._id, u);
+ return 1;
+ }
+
+ }
+ return -2;
+
+ }
+
+ public async Task<bool> ChangeMyProfileName(string newName)
+ {
+ string myId = null;
+ if (_httpContext.HttpContext.User.FindFirstValue("id") != null)
+ {
+ myId = _httpContext.HttpContext.User.FindFirstValue("id").ToString();
+ }
+ User u = await _users.Find(user => user._id == myId).FirstOrDefaultAsync();
+ if (u != null)
+ {
+
+ u.name = newName;
+ await _users.ReplaceOneAsync(x => x._id == u._id, u);
+ return true;
+
+ }
+ return false;
+ }
+
+
}
}