795 lines
24 KiB
JavaScript
795 lines
24 KiB
JavaScript
// const User = require('../models/user.model');
|
|
const jwt = require('jsonwebtoken');
|
|
const authConfig = require('../configs/auth.config');
|
|
const bcrypt = require('bcryptjs');
|
|
const constant = require('../util/constant');
|
|
const Artist = require('../models/artist.model');
|
|
const Reward = require('../models/Reward.model');
|
|
const Song = require('../models/song.model');
|
|
const axios = require('axios');
|
|
const { User } = require('../models/user.model');
|
|
const { validationResult } = require('express-validator');
|
|
const nodemailer = require('nodemailer');
|
|
|
|
|
|
|
|
const sendOTPByEmail = async (email, otp) => {
|
|
try {
|
|
const transporter = nodemailer.createTransport({
|
|
service: 'gmail', // e.g., 'Gmail'
|
|
auth: {
|
|
user: 'ay2087355@gmail.com',
|
|
pass: 'mqqqnoutaukxenlh'
|
|
}
|
|
});
|
|
|
|
// Send OTP email
|
|
await transporter.sendMail({
|
|
from: 'checkdemo02@gmail.com',
|
|
to: email,
|
|
subject: 'Your OTP Code',
|
|
text: `Your OTP code is: ${otp}`
|
|
});
|
|
|
|
console.log('OTP email sent successfully');
|
|
} catch (error) {
|
|
console.error('Error sending OTP email:', error);
|
|
throw new Error('Failed to send OTP email');
|
|
}
|
|
};
|
|
|
|
const userRegister = async (req, res) => {
|
|
try {
|
|
// Check if the email already exists
|
|
const existingUser = await User.findOne({ email: req.body.email });
|
|
console.log("🚀 ~ userRegister ~ existingUser:", existingUser)
|
|
if (existingUser) {
|
|
return res.status(400).json({
|
|
error_code: 400,
|
|
message: 'Email already exists'
|
|
});
|
|
}
|
|
|
|
// Generate OTP
|
|
const otp = Math.floor(10000 + Math.random() * 90000);
|
|
|
|
// Create user object with hashed password
|
|
const user = await User.create({
|
|
email: req.body.email,
|
|
password: bcrypt.hashSync(req.body.password, 8),
|
|
registerWith: constant.registerWith.Email,
|
|
otp: otp,
|
|
userName: req.body.userName,
|
|
userType: constant.userTypes.customer
|
|
});
|
|
console.log("🚀 ~ userRegister ~ user:", user)
|
|
|
|
// Send OTP email
|
|
await sendOTPByEmail(user.email, otp);
|
|
|
|
return res.status(200).json({
|
|
error_code: 200,
|
|
message: 'Success',
|
|
user: user
|
|
});
|
|
} catch (err) {
|
|
console.error('Error in user registration:', err);
|
|
return res.status(500).json({
|
|
error_code: 500,
|
|
message: 'Failed'
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
//otp verify
|
|
|
|
const verifyOTP = async (req, res) => {
|
|
try {
|
|
const { email, otp } = req.body;
|
|
const user = await User.findOne({ email });
|
|
|
|
if (!user) {
|
|
return res.status(400).json({
|
|
error_code: 400,
|
|
message: 'User not found'
|
|
});
|
|
}
|
|
|
|
if (user.otp !== otp) {
|
|
return res.status(400).json({
|
|
error_code: 400,
|
|
message: 'Incorrect OTP'
|
|
});
|
|
}
|
|
|
|
user.otpVerified = true;
|
|
await user.save();
|
|
|
|
return res.status(200).json({
|
|
error_code: 200,
|
|
message: 'OTP verified successfully',
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error in verify OTP:', error);
|
|
return res.status(500).json({
|
|
error_code: 500,
|
|
message: 'Failed'
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
const createGoogle = async (req, res) => {
|
|
try {
|
|
// Validate request body
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({ errors: errors.array() });
|
|
}
|
|
|
|
// Fetch user data from Google API using access token
|
|
const response = await axios.get(`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${req.body.accessToken}`);
|
|
const userData = response.data;
|
|
|
|
// Check if the user with this Google ID already exists
|
|
let user = await User.findOne({ googleId: userData.id });
|
|
|
|
// If user with Google ID doesn't exist, check by email
|
|
if (!user) {
|
|
user = await User.findOne({ email: userData.email });
|
|
}
|
|
|
|
// If user exists, generate token and return response
|
|
if (user) {
|
|
const token = jwt.sign({ id: user._id, userType: user.userType }, process.env.JWT_SECRET, { expiresIn: '1h' });
|
|
return res.status(200).json({
|
|
_id: user._id,
|
|
email: user.email,
|
|
token: token,
|
|
userType: user.userType,
|
|
status: user.status,
|
|
message: 'User logged in successfully'
|
|
});
|
|
}
|
|
|
|
// If user doesn't exist, create a new user
|
|
const newUser = await User.create({
|
|
email: userData.email,
|
|
name: userData.name,
|
|
profilePic: userData.picture,
|
|
authenticationType: "GOOGLE",
|
|
googleId: userData.id,
|
|
});
|
|
|
|
// Generate token for the new user
|
|
const token = jwt.sign({ id: newUser._id, userType: newUser.userType }, process.env.JWT_SECRET, { expiresIn: '1h' });
|
|
|
|
// Send response with user data
|
|
return res.status(201).json({
|
|
_id: newUser._id,
|
|
email: newUser.email,
|
|
token: token,
|
|
userType: newUser.userType,
|
|
authenticationType: "GOOGLE",
|
|
status: newUser.status,
|
|
message: 'New user created and logged in successfully'
|
|
});
|
|
} catch (error) {
|
|
// Handle errors
|
|
console.error('Error inside createGoogle:', error);
|
|
return res.status(500).json({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
});
|
|
}
|
|
};
|
|
const update = async (req, res) => {
|
|
try {
|
|
let id = req.params.id;
|
|
let obj = {
|
|
userName: req.body.userName ? req.body.userName : undefined,
|
|
email: req.body.email ? req.body.email : undefined,
|
|
password: req.body.password ? bcrypt.hashSync(req.body.password) : undefined,
|
|
}
|
|
if (req.files.length > 0) {
|
|
obj['image'] = {
|
|
fileName: req.files[0].filename,
|
|
fileAddress: req.files[0].path
|
|
}
|
|
}
|
|
|
|
const user = await User.findById(id);
|
|
const admin = await User.findById(req.userId);
|
|
if (req.body.status) {
|
|
if (admin.userTypes == constant.userTypes.admin) {
|
|
obj.status = req.body.status ? req.body.status : undefined;
|
|
}
|
|
else {
|
|
return res.status(401).send({
|
|
error_code: 400,
|
|
message: 'status can only be updated by admin'
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
|
|
console.log(`object for updation of user is ${obj}`);
|
|
|
|
await user.updateOne(obj)
|
|
await user.save();
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: "User updated Successssssfully"
|
|
})
|
|
} catch (err) {
|
|
console.log(err);
|
|
res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Error in update controller '
|
|
})
|
|
}
|
|
}
|
|
|
|
const passUpCreate = async (req, res) => {
|
|
console.log(req.body.email);
|
|
try {
|
|
let email = req.body.email
|
|
function generateRandomNumber() {
|
|
const min = 100000; // Minimum value (inclusive)
|
|
const max = 999999; // Maximum value (inclusive)
|
|
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
const uppercaseLetter = String.fromCharCode(Math.floor(Math.random() * 26) + 65); // Uppercase letter ASCII range: 65-90
|
|
const lowercaseLetter = String.fromCharCode(Math.floor(Math.random() * 26) + 97); // Lowercase letter ASCII range: 97-122
|
|
const specialCharacter = String.fromCharCode(Math.floor(Math.random() * 15) + 33); // Special character ASCII range: 33-47
|
|
|
|
const randomString = randomNumber.toString() + uppercaseLetter + lowercaseLetter + specialCharacter;
|
|
|
|
// Shuffle the characters in the string
|
|
const shuffledString = randomString.split('').sort(() => 0.5 - Math.random()).join('');
|
|
|
|
return shuffledString;
|
|
}
|
|
|
|
// Usage example
|
|
const TempPassword = generateRandomNumber();
|
|
|
|
let obj = {
|
|
password: bcrypt.hashSync(TempPassword)
|
|
}
|
|
const user = await User.findOneAndUpdate({ email: email }, { $set: obj });
|
|
user.save();
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: `Temporary Password is ${TempPassword} for this ${email}`
|
|
})
|
|
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Error in passUpCreate'
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
const createFacebook = async (req, res) => {
|
|
try {
|
|
let user = await User.findOne({ email: req.body.email });
|
|
var flag = 0;
|
|
if (!user) {
|
|
let obj = {
|
|
email: req.body.email,
|
|
registerWith: constant.registerWith.facebook
|
|
}
|
|
user = await User.create(obj);
|
|
flag = 1
|
|
|
|
}
|
|
if (user.registerWith != constant.registerWith.facebook) {
|
|
return res.status(400).send({
|
|
error_code: 400,
|
|
message: "Can't login Through facebook"
|
|
});
|
|
}
|
|
|
|
let str = flag ? 'User Got Created' : 'User was already Created';
|
|
|
|
const token = jwt.sign({ id: user._id }, authConfig.secretKey, {
|
|
expiresIn: 600000
|
|
});
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: str,
|
|
acessToken: token
|
|
})
|
|
|
|
|
|
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Error in creating user'
|
|
})
|
|
|
|
}
|
|
}
|
|
|
|
const deleteUser = async (req, res) => {
|
|
try {
|
|
let id = req.params.id;
|
|
|
|
await User.deleteOne({ _id: id });
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: 'User Deleted succefully'
|
|
})
|
|
|
|
|
|
}
|
|
catch (err) {
|
|
console.log('Error inside delete User controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'internal server error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const getUserPlaylist = async (req, res) => {
|
|
try {
|
|
const user = await User.findById(req.userId).populate('playlist');
|
|
console.log(user);
|
|
return res.status(201).send(constant.arrayConverterName(user.playlist));
|
|
} catch (err) {
|
|
console.log('Error inside getUserPlaylist Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const favrioteSong = async (req, res) => {
|
|
try {
|
|
const user = await User.findById(req.userId).populate('favrioteSongs');
|
|
console.log(user);
|
|
for (let i = 0; i < user.favrioteSongs.length; i++) {
|
|
if (user.favrioteSongs[i]._id == req.params.id) {
|
|
await user.updateOne({
|
|
$pull: {
|
|
favrioteSongs: req.params.id
|
|
}
|
|
});
|
|
await user.save();
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: 'Song got removed from favrioteSong'
|
|
})
|
|
}
|
|
}
|
|
user.favrioteSongs.push(req.params.id);
|
|
await user.save();
|
|
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: 'Song got added to favrioteSong'
|
|
})
|
|
|
|
} catch (err) {
|
|
console.log('Error inside favrioteSong Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
const getfavrioteSongs = async (req, res) => {
|
|
try {
|
|
const user = await User.findById(req.userId).populate('favrioteSongs');
|
|
return res.status(200).send(user.favrioteSongs);
|
|
|
|
} catch (err) {
|
|
console.log('Error inside getFavrioteSong Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
const PlayedSong = async (req, res) => {
|
|
try {
|
|
|
|
let key = req.params.id;
|
|
let userId = req.userId;
|
|
const user = await User.findById(userId);
|
|
|
|
|
|
if (user.mostPlayedSongs[key]) {
|
|
const updatedObj = { $set: { ['mostPlayedSongs.' + key]: (++user.mostPlayedSongs[key]) } }
|
|
await User.findByIdAndUpdate(userId, updatedObj);
|
|
|
|
}
|
|
|
|
else {
|
|
const updatedObj = { $set: { ['mostPlayedSongs.' + key]: 1 } }
|
|
console.log('not hello')
|
|
await User.findByIdAndUpdate(userId, updatedObj)
|
|
}
|
|
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
message: 'Song is Played '
|
|
})
|
|
|
|
} catch (err) {
|
|
console.log('Error inside playedSong', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const getmostPlayedSong = async (req, res) => {
|
|
try {
|
|
const user = await User.findById(req.userId)
|
|
console.log(user.mostPlayedSongs);
|
|
|
|
// Convert the object to an array of key-value pairs
|
|
const objEntries = Object.entries(user.mostPlayedSongs);
|
|
|
|
// Sort the Array
|
|
objEntries.sort((a, b) => b[1] - a[1]);
|
|
|
|
// Convert the sorted array back to an object
|
|
const sortedObj = Object.fromEntries(objEntries);
|
|
|
|
return res.status(201).send(sortedObj);
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.log('Error inside mostPlayedSong', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const followingArtist = async (req, res) => {
|
|
try {
|
|
const artistId = req.params.id;
|
|
const userId = req.userId;
|
|
const user = await User.findById(userId);
|
|
const artist = await Artist.findById(artistId);
|
|
for (let i = 0; i < user.following.length; i++) {
|
|
if (user.following[i] == artistId) {
|
|
user.following.pull(artistId);
|
|
await user.save();
|
|
artist.followers.pull(userId);
|
|
await artist.save();
|
|
return res.status(201).send({
|
|
message: `You Unfollowed ${artist.name}`
|
|
})
|
|
}
|
|
}
|
|
user.following.push(artistId);
|
|
await user.save();
|
|
artist.followers.push(userId);
|
|
await artist.save();
|
|
return res.status(200).send({
|
|
error_code: 200,
|
|
message: `you followed ${artist.name}`
|
|
})
|
|
|
|
} catch (err) {
|
|
console.log('Error inside following Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
// Function to calculate word alignment accuracy using Levenshtein distance
|
|
|
|
|
|
// Function to calculate timing accuracy
|
|
|
|
|
|
// Function to evaluate word alignment accuracy and timing accuracy
|
|
const evaluateAccuracy = async (req, res) => {
|
|
try {
|
|
const song = await Song.findById(req.params.id);
|
|
const recognizedLyrics = req.recognizedLyrics;
|
|
const originalLyrics = song.lyricsTimeStamp;
|
|
const wordAlignmentAccuracy = constant.calculateWordAlignmentAccuracy(recognizedLyrics, originalLyrics);
|
|
const timingAccuracy = constant.calculateTimingAccuracy(recognizedLyrics, originalLyrics);
|
|
const totalAccuracy = (wordAlignmentAccuracy.toFixed(2) + timingAccuracy.toFixed(2)) / 2;
|
|
console.log(totalAccuracy);
|
|
var reward;
|
|
switch (totalAccuracy) {
|
|
case (totalAccuracy > 90):
|
|
reward = 'A+';
|
|
break;
|
|
case (totalAccuracy > 80):
|
|
reward = 'A'
|
|
break;
|
|
case (totalAccuracy > 70):
|
|
reward = 'B+'
|
|
break;
|
|
case (totalAccuracy > 60):
|
|
reward = 'B'
|
|
break;
|
|
case (totalAccuracy > 50):
|
|
reward = 'C+'
|
|
break;
|
|
case (totalAccuracy > 40):
|
|
reward = 'C'
|
|
break;
|
|
case (totalAccuracy < 40):
|
|
reward = 'F'
|
|
break;
|
|
|
|
}
|
|
|
|
const reward_score = await Reward.find({ score: reward });
|
|
const user = await User.findById(req.userId);
|
|
user.score += reward_score.reward;
|
|
await user.save();
|
|
console.log(user);
|
|
return res.status(201).send({
|
|
error_code: 200,
|
|
Score: reward
|
|
})
|
|
|
|
} catch (err) {
|
|
console.log('Error inside EvaluateAccuracy Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const ranking = async (req, res) => {
|
|
try {
|
|
const ranking = await User.find({}).sort({ score: -1 }).limit(5);
|
|
return res.status(201).send(ranking);
|
|
|
|
} catch (err) {
|
|
console.log('Error inside Ranking Controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal Server Error'
|
|
})
|
|
}
|
|
}
|
|
|
|
const changeUserStatus = async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const { status } = req.body;
|
|
|
|
// Validate the status value
|
|
if (!['activate', 'deactivate'].includes(status)) {
|
|
return res.status(400).send({
|
|
error_code: 400,
|
|
message: 'Invalid status value. Status must be either "activate" or "deactivate".'
|
|
});
|
|
}
|
|
|
|
const user = await User.findById(id);
|
|
if (!user) {
|
|
return res.status(404).send({
|
|
error_code: 404,
|
|
message: 'User not found.'
|
|
});
|
|
}
|
|
|
|
user.status = status;
|
|
await user.save();
|
|
|
|
return res.status(200).send({
|
|
error_code: 200,
|
|
message: `User status updated to ${status} successfully.`
|
|
});
|
|
} catch (err) {
|
|
console.log('Error inside changeStatus controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal server error.'
|
|
});
|
|
}
|
|
}
|
|
|
|
const usergetAllSongs =async(req,res)=>{
|
|
try {
|
|
const song = await Song.find({status: 'Active'});
|
|
return res.status(200).send(song);
|
|
|
|
|
|
}catch (err) {
|
|
console.log('Error inside changeStatus controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal server error.'
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
const newRelease = async (req, res) => {
|
|
try {
|
|
const fiveDaysAgo = new Date();
|
|
fiveDaysAgo.setDate(fiveDaysAgo.getDate() - 3);
|
|
const songs = await Song.find({
|
|
status: 'activate',
|
|
createdAt: { $gte: fiveDaysAgo }
|
|
});
|
|
|
|
return res.status(200).send({error_code:200,message:'new realese songs',song:songs});
|
|
|
|
} catch (err) {
|
|
console.log('Error inside newRelease controller', err);
|
|
return res.status(500).send({
|
|
error_code: 500,
|
|
message: 'Internal server error.'
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
const homeData = async (req, res) => {
|
|
try {
|
|
// Pipeline to aggregate songs with category name, artist names, and image URL
|
|
const pipeline = [
|
|
{
|
|
$match: { status: 'activate' }
|
|
},
|
|
{
|
|
$lookup: {
|
|
from: 'categories',
|
|
localField: 'categoryId',
|
|
foreignField: '_id',
|
|
as: 'category'
|
|
}
|
|
},
|
|
{
|
|
$lookup: {
|
|
from: 'artists',
|
|
localField: 'artistId',
|
|
foreignField: '_id',
|
|
as: 'artists'
|
|
}
|
|
},
|
|
{
|
|
$group: {
|
|
_id: { categoryId: '$categoryId', categoryName: '$category.name' },
|
|
songs: {
|
|
$push: {
|
|
_id: '$_id',
|
|
title: '$title',
|
|
artistNames: '$artists.ArtistName',
|
|
imageUrl: '$coverArtImage.imageUrl'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
_id: 0,
|
|
categoryName: '$_id.categoryName',
|
|
songs: {
|
|
$map: {
|
|
input: '$songs',
|
|
as: 'song',
|
|
in: {
|
|
_id: '$$song._id',
|
|
title: '$$song.title',
|
|
artistNames: '$$song.artistNames',
|
|
imageUrl: '$$song.imageUrl'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
];
|
|
const categoriesWithSongs = await Song.aggregate(pipeline);
|
|
return res.status(200).json({
|
|
error_code: 200,
|
|
message: 'Songs grouped by category retrieved successfully',
|
|
categories: categoriesWithSongs
|
|
});
|
|
} catch (err) {
|
|
// Log and handle errors
|
|
console.error('Error inside homeData:', err);
|
|
return res.status(500).json({ error_code: 500, message: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
const artistData = async (req, res) => {
|
|
try {
|
|
const pipeline = [
|
|
{
|
|
$lookup: {
|
|
from: 'songs',
|
|
localField: '_id',
|
|
foreignField: 'artistId',
|
|
as: 'songs'
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
_id: 1,
|
|
ArtistName: 1,
|
|
songs: {
|
|
$map: {
|
|
input: '$songs',
|
|
as: 'song',
|
|
in: {
|
|
_id: '$$song._id',
|
|
title: '$$song.title',
|
|
status: '$$song.status',
|
|
imageUrl: '$$song.coverArtImage.imageUrl'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
];
|
|
|
|
// Execute aggregation pipeline
|
|
const artistsWithSongs = await Artist.aggregate(pipeline);
|
|
|
|
// Return response
|
|
return res.status(200).json({
|
|
error_code: 200,
|
|
message: 'Artist data with songs retrieved successfully',
|
|
artists: artistsWithSongs
|
|
});
|
|
} catch (error) {
|
|
// Log and handle errors
|
|
console.error('Error inside artistData:', error);
|
|
return res.status(500).json({ error_code: 500, message: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
|
|
module.exports = {
|
|
userRegister,
|
|
verifyOTP,
|
|
createGoogle,
|
|
createFacebook,
|
|
update,
|
|
passUpCreate,
|
|
getUserPlaylist,
|
|
favrioteSong,
|
|
deleteUser,
|
|
PlayedSong,
|
|
getmostPlayedSong,
|
|
getfavrioteSongs,
|
|
followingArtist,
|
|
evaluateAccuracy,
|
|
ranking,
|
|
changeUserStatus,usergetAllSongs,
|
|
newRelease,
|
|
homeData,
|
|
artistData
|
|
}; |