Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ REFRESH_TOKEN_EXPIRY=10d

CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
CLOUDINARY_API_SECRET=
ABSTRACT_API_KEY=
90 changes: 88 additions & 2 deletions src/controllers/comment.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,107 @@ import {asyncHandler} from "../utils/asyncHandler.js"

const getVideoComments = asyncHandler(async (req, res) => {
//TODO: get all comments for a video
const {videoId} = req.params
const {page = 1, limit = 10} = req.query
const { videoId } = req.params;
const { page = 1, limit = 10 } = req.query;

if (!mongoose.Types.ObjectId.isValid(videoId))
throw new ApiError(400, "Invalid videoId");

const options = {
page: parseInt(page, 10),
limit: parseInt(limit, 10),
sort: { createdAt: -1 },
populate: { path: "owner", select: "username avatar" },
};
const result = await Comment.aggregatePaginate(
[
{ $match: { video: new mongoose.Types.ObjectId(videoId) } },
{
$addFields: {
areYouOwner: {
$eq: ["$owner", new mongoose.Types.ObjectId(req.user._id)],
},
},
},
],
options
);
res
.status(200)
.json(new ApiResponse(200, "Comments fetched successfully", result));
})

const addComment = asyncHandler(async (req, res) => {
// TODO: add a comment to a video

const content = req.body?.content;
const videoId = req.params?.videoId;
if (!content || !videoId) {
throw new ApiError(400, "Content and videoId are required");
}
const userId = req.user._id;
if (!userId) throw new ApiError(401, "Unauthorized");
if (!mongoose.Types.ObjectId.isValid(videoId))
throw new ApiError(400, "Invalid videoId");

const comment = await Comment.create({
content,
video: videoId,
owner: userId,
});

res
.status(201)
.json(new ApiResponse(201, "Comment added successfully", comment));
})

const updateComment = asyncHandler(async (req, res) => {
// TODO: update a comment
const { commentId } = req.params;
const content = req.body?.content;
// console.log('this iscontent ',content,commentId);

if (!content) throw new ApiError(400, "Content is required");
if (!mongoose.Types.ObjectId.isValid(commentId))
throw new ApiError(400, "Invalid commentId");

const userId = req.user._id;
if (!userId)
throw new ApiError(401, "Unauthorized or Token has been expired");
const comment = await Comment.findById(commentId);
if (!comment) throw new ApiError(404, "Comment not found");
const validUser = comment.validateUser(userId);
if (!validUser)
throw new ApiError(403, "You are not allowed to update this comment");
comment.content = content;
await comment.save();
res
.status(200)
.json(new ApiResponse(200, "Comment updated successfully", comment));
})

const deleteComment = asyncHandler(async (req, res) => {
// TODO: delete a comment
const { commentId } = req.params;
if (!mongoose.Types.ObjectId.isValid(commentId))
throw new ApiError(400, "Invalid commentId");
const userId = req.user._id;
if (!userId)
throw new ApiError(401, "Unauthorized or Token has been expired");

const comment = await Comment.findById(commentId);
if (!comment) throw new ApiError(404, "Comment not found");

const validUser = comment.validateUser(userId);
if (!validUser)
throw new ApiError(403, "You are not allowed to delete this comment");

const deletedComment = await Comment.findByIdAndDelete(commentId);
res
.status(200)
.json(
new ApiResponse(200, "Comment deleted successfully", deletedComment)
);
})

export {
Expand Down
91 changes: 76 additions & 15 deletions src/controllers/dashboard.controller.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,81 @@
import mongoose from "mongoose"
import {Video} from "../models/video.model.js"
import {Subscription} from "../models/subscription.model.js"
import {Like} from "../models/like.model.js"
import {ApiError} from "../utils/ApiError.js"
import {ApiResponse} from "../utils/ApiResponse.js"
import {asyncHandler} from "../utils/asyncHandler.js"
import mongoose from "mongoose";
import { ApiError } from "../utils/ApiError.js";
import { ApiResponse } from "../utils/ApiResponse.js";
import { asyncHandler } from "../utils/asyncHandler.js";
import { Video } from "../models/video.model.js";
import { Subscription } from "../models/subscription.model.js";
import { Like } from "../models/like.model.js";

const getChannelStats = asyncHandler(async (req, res) => {
// TODO: Get the channel stats like total video views, total subscribers, total videos, total likes etc.
})
// TODO: Get the channel stats like total video views, total subscribers, total videos, total likes etc.
const channelId = req.user._id;

if (!channelId) {
throw new ApiError(401, "Not a valid channel");
}

const totalVideos = await Video.countDocuments({ owner: channelId });

const viewsAgg = await Video.aggregate([
{ $match: { owner: new mongoose.Types.ObjectId(channelId) } },
{ $group: { _id: null, totalViews: { $sum: "$views" } } },
]);
const totalViews = viewsAgg.length > 0 ? viewsAgg[0].totalViews : 0;

const totalSubscribers = await Subscription.countDocuments({
channel: channelId,
});

const likesAgg = await Like.aggregate([
{
$lookup: {
from: "videos",
localField: "video",
foreignField: "_id",
as: "videoData",
},
},
{ $unwind: "$videoData" },
{ $match: { "videoData.owner": new mongoose.Types.ObjectId(channelId) } }
]);

const totalLikes = likesAgg.length > 0 ? likesAgg.length : 0;

return res.status(200).json(
new ApiResponse(
200,
{
totalVideos,
totalViews,
totalSubscribers,
totalLikes,
},
"Channel stats fetched successfully"
)
);
});


const getChannelVideos = asyncHandler(async (req, res) => {
// TODO: Get all the videos uploaded by the channel
})
// TODO: Get all the videos uploaded by the channel
const userId = req.user._id;
if (!mongoose.Types.ObjectId.isValid(userId)) {
throw new ApiError(400, "Invalid user ID");
}
const { page = 1, limit = 10 } = req.query;
const options = {
page: parseInt(page, 10),
limit: parseInt(limit, 10),
sort: { createdAt: -1 },
};
const result = await Video.aggregatePaginate(
[{ $match: { owner: new mongoose.Types.ObjectId(userId) } }],
options
);
if (!result.docs[0]) throw new ApiError(404, "No Video Found");
return res
.status(200)
.json(new ApiResponse(200, "Videos fetched successfully", result));
});

export {
getChannelStats,
getChannelVideos
}
export { getChannelStats, getChannelVideos };
17 changes: 7 additions & 10 deletions src/controllers/healthcheck.controller.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import {ApiError} from "../utils/ApiError.js"
import {ApiResponse} from "../utils/ApiResponse.js"
import {asyncHandler} from "../utils/asyncHandler.js"

import { ApiError } from "../utils/ApiError.js";
import { ApiResponse } from "../utils/ApiResponse.js";
import { asyncHandler } from "../utils/asyncHandler.js";

const healthcheck = asyncHandler(async (req, res) => {
//TODO: build a healthcheck response that simply returns the OK status as json with a message
})
//TODO: build a healthcheck response that simply returns the OK status as json with a message
return res.status(200).json(new ApiResponse("OK", null, "Server is healty"));
});

export {
healthcheck
}

export { healthcheck };
Loading