Updated the Swagger documentation for various Post endpoints to accurately reflect their return types, including arrays of Post objects and detailed schemas for specific responses.
983 lines
28 KiB
JavaScript
983 lines
28 KiB
JavaScript
var express = require('express');
|
|
var router = express.Router();
|
|
|
|
const DB = require("./../mongoDB.js");
|
|
const Post = require("./../def/post.js");
|
|
const Notifications = require("./../notifications.js");
|
|
|
|
DB.getDB.then((DB) => {
|
|
|
|
const getProfileId = (req) => {
|
|
return DB.ObjectID(req.cookies.profile_id || req.query.profile_id || req.body.profile_id);
|
|
};
|
|
|
|
const postBelongToProfile = (post, profileid) => {
|
|
if (!post) return false;
|
|
return post.profileid == profileid;
|
|
};
|
|
|
|
const generateNonOrganicPosts = async (req, profileid) => {
|
|
let posts = [];
|
|
// News Posts
|
|
const newsPosts = await DB.getNews();
|
|
posts.push(...newsPosts);
|
|
|
|
// Popular Profiles
|
|
const popularProfiles = await DB.getPopularProfiles(5);
|
|
content = "Active users to follow:\n";
|
|
popularProfiles.forEach((p) => {
|
|
content += "@p:" + p._id + "\n";
|
|
});
|
|
let popularProfilesPost = new Post({ profileid: 1, content, nonOrganicType: "PopularUsers" });
|
|
posts.push(popularProfilesPost);
|
|
|
|
// Popular Groups
|
|
const popularGroups = await DB.getPopularGroups(5);
|
|
content = "Popular groups to follow:\n";
|
|
popularGroups.forEach((p) => {
|
|
content += "@p:" + p._id + "\n";
|
|
});
|
|
let popularGroupsPost = new Post({ profileid: 1, content, nonOrganicType: "PopularGroups" });
|
|
posts.push(popularGroupsPost);
|
|
|
|
const yourFollowsInterests = await DB.getFriendsFriends(profileid);
|
|
content = "People your follow has these interests:\n";
|
|
yourFollowsInterests.forEach((p) => {
|
|
content += "@p:" + p + "\n";
|
|
});
|
|
let yourFollowsInterestsPost = new Post({ profileid: 1, content, nonOrganicType: "PopularUsers" });
|
|
posts.push(yourFollowsInterestsPost);
|
|
|
|
return posts;
|
|
};
|
|
|
|
const mergePosts = (organic, nonOrganic) => {
|
|
if (!organic || organic.length < 5) return nonOrganic;
|
|
//organic.push(...nonOrganic);
|
|
let mergedPosts = [];
|
|
while (organic.length + nonOrganic.length) {
|
|
if (organic.length == 0) {
|
|
mergedPosts.push(nonOrganic.shift());
|
|
continue;
|
|
}
|
|
if (nonOrganic.length == 0) {
|
|
mergedPosts.push(organic.shift());
|
|
continue;
|
|
}
|
|
if (nonOrganic[0].nonOrganicType == 'News') {
|
|
mergedPosts.push(nonOrganic.shift());
|
|
continue;
|
|
}
|
|
if (Math.random() < 0.2) {
|
|
mergedPosts.push(nonOrganic.shift());
|
|
} else {
|
|
mergedPosts.push(organic.shift());
|
|
}
|
|
}
|
|
return mergedPosts;
|
|
};
|
|
|
|
/**
|
|
* @swagger
|
|
* tags:
|
|
* name: Posts
|
|
* description: Post management
|
|
*/
|
|
|
|
/**
|
|
* @swagger
|
|
* components:
|
|
* schemas:
|
|
* Post:
|
|
* type: object
|
|
* properties:
|
|
* profileid:
|
|
* type: string
|
|
* description: The ID of the profile that created the post.
|
|
* content:
|
|
* type: string
|
|
* description: The content of the post.
|
|
* createdAt:
|
|
* type: string
|
|
* format: date-time
|
|
* description: The timestamp when the post was created.
|
|
* reactions:
|
|
* type: object
|
|
* description: An object containing reactions to the post, keyed by profile ID.
|
|
* comments:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* description: An array of comments on the post.
|
|
* bookmarks:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* description: An array of profile IDs that bookmarked the post.
|
|
* nonOrganicType:
|
|
* type: string
|
|
* description: Type of non-organic content (e.g., "News", "PopularUsers", "PopularGroups").
|
|
* contentHistory:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* description: A history of content edits.
|
|
* toProfile:
|
|
* type: string
|
|
* description: The ID of the profile this post is directed to (e.g., a group).
|
|
* lastUpdated:
|
|
* type: string
|
|
* format: date-time
|
|
* description: The timestamp when the post was last updated.
|
|
* tags:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* description: An array of tags associated with the post.
|
|
* chatSenderId:
|
|
* type: string
|
|
* description: The ID of the chat sender, if applicable.
|
|
*
|
|
* /post/organic:
|
|
* get:
|
|
* summary: Get the organic feed for the current user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/organic", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
let organicPosts = await DB.getFeed(profileid);
|
|
//Add non-organic posts
|
|
const nonOrganicPosts = await generateNonOrganicPosts(req, profileid);
|
|
const posts = mergePosts(organicPosts, nonOrganicPosts);
|
|
return res.json(posts);
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post:
|
|
* get:
|
|
* summary: Get the feed with promotional content
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
//Add non-organic posts
|
|
const nonOrganicPosts = await generateNonOrganicPosts(req, profileid);
|
|
let promotionalPosts = await DB.getPromotionalPosts(profileid);
|
|
const posts = mergePosts(promotionalPosts, nonOrganicPosts);
|
|
return res.json(posts);
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/tag/{tag}:
|
|
* get:
|
|
* summary: Get posts with a specific tag
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: tag
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
* 400:
|
|
* description: Tag is required
|
|
*/
|
|
router.get("/tag/:tag", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
const tag = req.query.tag || req.params.tag;
|
|
if(!tag) {
|
|
console.log("Tag query empty: ", tag);
|
|
return res.json({
|
|
status: "Tag is required",
|
|
});
|
|
}
|
|
console.log("Tag query: ", tag);
|
|
let posts = await DB.getPostsByTag('#' + tag, profileid);
|
|
return res.json(posts);
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/usr/{id}:
|
|
* get:
|
|
* summary: Get posts from a specific user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/usr/:id", async (req, res) => {
|
|
const profileId = req.params.id;
|
|
const viewerProdileId = getProfileId(req);
|
|
const profile = await DB.getProfileCache(profileId);
|
|
const posts = await DB.getPosts(profileId, viewerProdileId);
|
|
if (profile.isCourse) {
|
|
//check for subscription
|
|
//const viewerProdile = await DB.getProfileCache(viewerProdileId);
|
|
//if (!viewerProdile.subscription || viewerProdile.subscription < (new Date()-1)) {
|
|
// return res.json([posts[posts.length - 1]]);
|
|
//}
|
|
}
|
|
return res.json(posts);
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/usr/{id}/images:
|
|
* get:
|
|
* summary: Get all image posts from a user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/usr/:id/images", async (req, res) => {
|
|
const profileid = req.params.id;
|
|
const viewerProfileId = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, viewerProfileId);
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/usr/{id}/embedded:
|
|
* get:
|
|
* summary: Get all embedded posts from a user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/usr/:id/embedded", async (req, res) => {
|
|
const profileid = req.params.id;
|
|
const viewerProfileId = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, viewerProfileId, "@iframe:");
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/usr/{id}/media:
|
|
* get:
|
|
* summary: Get all media posts from a user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/usr/:id/media", async (req, res) => {
|
|
const profileid = req.params.id;
|
|
const viewerProfileId = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, viewerProfileId, "@youtube:|@vimeo:|@hls:");
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/video/{id}:
|
|
* get:
|
|
* summary: Get video details by ID
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.get("/video/:id", async (req, res) => {
|
|
videoId = req.params.id;
|
|
return res.json([]);
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post:
|
|
* post:
|
|
* summary: Create a new post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* 403:
|
|
* description: Not authorized to post to this group
|
|
*/
|
|
router.post("/", async (req, res) => {
|
|
let post = {
|
|
profileid: getProfileId(req),
|
|
...req.body
|
|
}
|
|
const isGroupPrivate = await DB.isGroupPrivate(post.toProfile);
|
|
const isGroupNewsOnly = await DB.isGroupNewsOnly(post.toProfile);
|
|
if (post.toProfile && isGroupPrivate) {
|
|
let requestProfile = getProfileId(req) + "";
|
|
let group = await DB.getProfileCache(post.toProfile);
|
|
if (!group.subscribed[requestProfile] && group._id != requestProfile) {
|
|
return res.json({
|
|
status: "You are not part of this private group",
|
|
});
|
|
}
|
|
}
|
|
if (post.toProfile && isGroupNewsOnly) {
|
|
return res.json({
|
|
status: "This is a news only group, only the admin can post",
|
|
});
|
|
}
|
|
post.toProfile = post.toProfile ? DB.ObjectID(post.toProfile) : undefined;
|
|
let postObj = new Post(post);
|
|
let dbr = await DB.newPost(postObj);
|
|
post = postObj.toObj();
|
|
post._id = dbr.insertedId;
|
|
if ((post.toProfile && post.toProfile != post.profileid) || post.nonOrganicType == 'News') {
|
|
await Notifications.youGotANewPost(post);
|
|
}
|
|
await Notifications.yourGroupMakeANewPost(post);
|
|
if(!isGroupPrivate){
|
|
await Notifications.yourSubscriptionProfileHasNewPost(post);
|
|
}
|
|
return res.json({
|
|
status: "ok",
|
|
...post
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/react:
|
|
* post:
|
|
* summary: React to a post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/react", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
let reaction = {
|
|
type: "like",
|
|
createdAt: new Date()
|
|
};
|
|
r = await DB.newReaction(postid, profileid, reaction);
|
|
Notifications.youGotANewReaction(postid, profileid, 'like');
|
|
return res.json({
|
|
status: "ok"
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/unreact:
|
|
* post:
|
|
* summary: Remove a reaction from a post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/unreact", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
r = await DB.removeReaction(postid, profileid);
|
|
return res.json({
|
|
status: "ok"
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/bookmark:
|
|
* post:
|
|
* summary: Bookmark a post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/bookmark", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
r = await DB.bookmarkPost(postid, profileid);
|
|
return res.json({
|
|
status: "ok"
|
|
});
|
|
})
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/unbookmark:
|
|
* post:
|
|
* summary: Remove a bookmark from a post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/unbookmark", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
r = await DB.unbookmarkPost(postid, profileid);
|
|
return res.json({
|
|
status: "ok"
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/comment:
|
|
* post:
|
|
* summary: Add a comment to a post
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* content:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/comment/", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
let content = req.body.content;
|
|
let comment = {
|
|
profileid: profileid,
|
|
content: content,
|
|
createdAt: new Date(),
|
|
lastUpdated: new Date(),
|
|
reactions: {}
|
|
}
|
|
Notifications.youGotANewPostComment(postid, profileid, content)
|
|
r = await DB.newComment(postid, comment);
|
|
return res.json({
|
|
status: "ok",
|
|
...comment
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/comment/react:
|
|
* post:
|
|
* summary: React to a comment
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* commentDate:
|
|
* type: string
|
|
* format: date-time
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/comment/react", async (req, res) => {
|
|
let userid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
let commentDate = new Date(req.body.commentDate);
|
|
let reaction = {
|
|
type: "like",
|
|
createdAt: new Date()
|
|
};
|
|
r = await DB.newCommentReaction(postid, commentDate, userid, reaction);
|
|
return res.json({
|
|
status: "ok"
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/comment/unreact:
|
|
* post:
|
|
* summary: Remove a reaction from a comment
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* postid:
|
|
* type: string
|
|
* commentDate:
|
|
* type: string
|
|
* format: date-time
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
*/
|
|
router.post("/comment/unreact", async (req, res) => {
|
|
let profileid = getProfileId(req);
|
|
let postid = req.body.postid;
|
|
let commentDate = new Date(req.body.commentDate);
|
|
r = await DB.removeCommentReaction(postid, commentDate, profileid);
|
|
return res.json({
|
|
status: "ok"
|
|
})
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/images:
|
|
* get:
|
|
* summary: Get all image posts for the current user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/images", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, profileid);
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/embedded:
|
|
* get:
|
|
* summary: Get all embedded posts for the current user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/embedded", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, profileid, "@iframe:");
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/media:
|
|
* get:
|
|
* summary: Get all media posts for the current user
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* posts:
|
|
* type: array
|
|
* items:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/media", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
const posts = await DB.getMediaTagPostOfUser(profileid, profileid, "@youtube:|@vimeo:|@hls:");
|
|
return res.json({
|
|
status: "ok",
|
|
posts
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/course/recent:
|
|
* get:
|
|
* summary: Get recently watched media from courses
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* status:
|
|
* type: string
|
|
* recentMedia:
|
|
* type: object
|
|
* additionalProperties:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* properties:
|
|
* watchRecord:
|
|
* type: object
|
|
* _id:
|
|
* type: string
|
|
* profileid:
|
|
* type: string
|
|
* content:
|
|
* type: string
|
|
* createdAt:
|
|
* type: string
|
|
* format: date-time
|
|
* reactions:
|
|
* type: object
|
|
* comments:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* bookmarks:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* nonOrganicType:
|
|
* type: string
|
|
* contentHistory:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* toProfile:
|
|
* type: string
|
|
* lastUpdated:
|
|
* type: string
|
|
* format: date-time
|
|
* tags:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* chatSenderId:
|
|
* type: string
|
|
* mediaProfileMap:
|
|
* type: object
|
|
* additionalProperties:
|
|
* type: object
|
|
*/
|
|
router.get("/course/recent", async (req, res) => {
|
|
const profileid = getProfileId(req);
|
|
const profile = await DB.getProfileCache(profileid);
|
|
const mediaPostsId = []
|
|
const recentMedia = {};
|
|
const mediaProfileP = []
|
|
let postPromises = [];
|
|
// Get watch information from profile data
|
|
Object.keys(profile.data).forEach(key => {
|
|
// So far we only use watch info using postid keys
|
|
if(DB.ObjectID.isValid(key)){
|
|
mediaPostsId.push(profile.data[key]);
|
|
postPromises.push(DB.getPostCached(profile.data[key].postId));
|
|
if(!recentMedia[profile.data[key].profileId]){
|
|
recentMedia[profile.data[key].profileId] = [];
|
|
mediaProfileP.push(DB.getProfileCache(profile.data[key].profileId));
|
|
}
|
|
}
|
|
});
|
|
recentMediaArray = mediaPostsId.sort((a,b)=>{
|
|
return b.ts - a.ts;
|
|
});
|
|
const postObjs = await Promise.all(postPromises);
|
|
const postObjsMap = postObjs.reduce((map, item)=>{
|
|
map[item._id] = item;
|
|
return map
|
|
}, {});
|
|
recentMediaArray.forEach(record => {
|
|
const postAndRecord = {
|
|
watchRecord: record,
|
|
... postObjsMap[record.postId]
|
|
}
|
|
recentMedia[record.profileId].push(postAndRecord);
|
|
});
|
|
// Transform profiles array to dict
|
|
let mediaProfile = await Promise.all(mediaProfileP);
|
|
let mediaProfileMap = mediaProfile.reduce((dict, item) => {
|
|
dict[item._id] = item;
|
|
return dict;
|
|
}, {});
|
|
return res.json({
|
|
status: "ok",
|
|
recentMedia,
|
|
mediaProfileMap,
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @swagger
|
|
* /post/{id}:
|
|
* get:
|
|
* summary: Get a specific post by ID
|
|
* tags: [Posts]
|
|
* security:
|
|
* - cookieAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: OK
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/Post'
|
|
*/
|
|
router.get("/:id", async (req, res) => {
|
|
const postId = req.params.id;
|
|
const post = await DB.getPost(postId);
|
|
return res.json({
|
|
status: "ok",
|
|
...post
|
|
});
|
|
});
|
|
|
|
router.delete("/:id", async (req, res) => {
|
|
const profileid = getProfileId(req) + '';
|
|
const postId = req.params.id;
|
|
const post = await DB.getPost(postId);
|
|
if (!postBelongToProfile(post, profileid))
|
|
return res.json({
|
|
status: "This post is not yours."
|
|
});
|
|
await DB.removePost(postId);
|
|
return res.json({
|
|
status: "ok"
|
|
});
|
|
});
|
|
|
|
router.post("/:id", async (req, res) => {
|
|
const profileid = getProfileId(req) + '';
|
|
const postId = req.params.id;
|
|
const post = await DB.getPost(postId);
|
|
const newContent = req.body.content;
|
|
if (!postBelongToProfile(post, profileid))
|
|
return res.json({
|
|
status: "This post is not yours."
|
|
});
|
|
await DB.updatePost(postId, newContent, post.content);
|
|
return res.json({
|
|
status: "ok"
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
module.exports = router |