Skip to content

Commit

Permalink
Added Husbando Route
Browse files Browse the repository at this point in the history
  • Loading branch information
kyrea committed Feb 4, 2024
1 parent f3520ea commit dc7f2dd
Show file tree
Hide file tree
Showing 4 changed files with 445 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/controllers/v4/images/husbando.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import _ from 'lodash';
import createError from 'http-errors';
import Husbandos from '../../../models/schemas/Husbando.js';
import Stats from '../../../models/schemas/Stat.js';

/**
* Retrieves a random husbando and updates system statistics.
*
* @function
* @param {Object} req - Express request object.
* @param {Object} res - Express response object.
* @param {Function} next - Express next middleware function.
*
* @throws {Error} If there is an error during husbando retrieval or database update.
*
* @returns {Object} JSON object containing the random husbando.
* @example
* // Example usage in Express route handler
* getHusbando(req, res, next);
*/
const getHusbando = async (req, res, next) => {
try {
/**
* Extracts character name and anime parameters from the request query.
* @type {Object}
*/
const { name, anime } = req.query;

/**
* Holds the filter object based on the optional character name and anime name parameters.
* @type {Object}
*/
const filter = {};

/**
* Adds conditions to the filter object based on request parameters.
* @type {Object}
*/
if (name) {
const sanitizedName = _.escapeRegExp(name.trim());
filter['name.full'] = { $regex: new RegExp(sanitizedName, 'i') }; // Case-insensitive regex match for the English name
}

if (anime) {
const sanitizedAnime = _.escapeRegExp(anime.trim());
filter['media.nodes[0].title.userPreferred'] = { $regex: new RegExp(sanitizedAnime, 'i') }; // Case-insensitive regex match for anime name
}

/**
* Holds the result of the random husbando retrieval.
* @type {Object}
*/
const [result] = await Husbandos.aggregate([
{ $match: filter }, // Apply filter conditions (if any)
{ $sample: { size: 1 } },
{ $project: { __v: 0 } },
]);

// If no husbando is found, return a 404 error
if (!result) {
return next(createError(404, 'Could not find any matching husbando'));
}

res.status(200).json(result);

// Update system statistics for husbandos
await Stats.findOneAndUpdate({ _id: 'systemstats' }, { $inc: { husbandos: 1 } });
} catch (error) {
/**
* Update system statistics for failed requests.
* @type {Object}
*/
await Stats.findOneAndUpdate({ _id: 'systemstats' }, { $inc: { failed_requests: 1 } });
next(error);
}
};

export default getHusbando;
248 changes: 248 additions & 0 deletions src/models/schemas/Husbando.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
import mongoose from 'mongoose';

const { Schema, model } = mongoose;

/**
* Represents the schema for the Husbando model.
* @class HusbandoSchema
*/
const HusbandoSchema = new Schema({
/**
* The unique identifier for the husbando.
* @type {Number}
*/
_id: { type: Number, required: true },

/**
* The name details of the husbando.
* @type {Object}
*/
name: {
/**
* The first name of the husbando.
* @type {String}
*/
first: { type: String, required: true },

/**
* The middle name of the husbando.
* @type {String}
*/
middle: String,

/**
* The last name of the husbando.
* @type {String}
*/
last: { type: String, required: true },

/**
* The full name of the husbando.
* @type {String}
*/
full: { type: String, required: true },

/**
* The native name of the husbando.
* @type {String}
*/
native: String,

/**
* The user-preferred name of the husbando.
* @type {String}
*/
userPreferred: { type: String, required: true },

/**
* Alternative names for the husbando.
* @type {Array}
*/
alternative: [String],

/**
* Alternative spoiler names for the husbando.
* @type {Array}
*/
alternativeSpoiler: [String],
},

/**
* The image URL associated with the husbando.
* @type {Object}
*/
image: {
/**
* The URL for the large image of the husbando.
* @type {String}
*/
large: String,
medium: String,
},

/**
* The number of favorites for the husbando.
* @type {Number}
*/
favourites: { type: Number, required: true },

/**
* The URL of the AniList page for the husbando.
* @type {String}
*/
siteUrl: { type: String, required: true },

/**
* The description of the husbando.
* @type {String}
*/
description: { type: String, required: true },

/**
* The age of the husbando.
* @type {String}
*/
age: String,

/**
* The gender of the husbando.
* @type {String}
*/
gender: { type: String, required: true },

/**
* The blood type of the husbando.
* @type {String}
*/
bloodType: String,

/**
* The date of birth of the husbando.
* @type {Object}
*/
dateOfBirth: {
/**
* The year of birth for the husbando.
* @type {Number}
*/
year: Number,

/**
* The month of birth for the husbando.
* @type {Number}
*/
month: Number,

/**
* The day of birth for the husbando.
* @type {Number}
*/
day: Number,
},

/**
* The media details associated with the husbando.
* @type {Object}
*/
media: {
/**
* An array of nodes containing information about various media related to the husbando.
* @type {Array}
*/
nodes: [
{
/**
* The unique identifier for the media.
* @type {Number}
*/
id: { type: Number, required: true },

/**
* The unique identifier for the media on MyAnimeList.
* @type {Number}
*/
idMal: { type: Number, required: true },

/**
* The cover image details for the media.
* @type {Object}
*/
coverImage: {
/**
* The URL for the medium-sized cover image of the media.
* @type {String}
*/
medium: { type: String, required: true },
},

/**
* The banner image URL for the media.
* @type {String}
*/
bannerImage: String,

/**
* The title details for the media.
* @type {Object}
*/
title: {
/**
* The romaji title of the media.
* @type {String}
*/
romaji: { type: String, required: true },

/**
* The English title of the media.
* @type {String}
*/
english: { type: String, required: true },

/**
* The native title of the media.
* @type {String}
*/
native: { type: String, required: true },

/**
* The user-preferred title of the media.
* @type {String}
*/
userPreferred: { type: String, required: true },
},

/**
* Synonyms for the media.
* @type {Array}
*/
synonyms: [String],

/**
* The popularity score for the media.
* @type {Number}
*/
popularity: Number,

/**
* The type of the media.
* @type {String}
*/
type: { type: String, required: true },

/**
* The format of the media.
* @type {String}
*/
format: { type: String, required: true },
},
],
},
});

/**
* Represents the model for the Husbando.
* @class Husbando
*/
const Husbando = model('Husbando', HusbandoSchema);

export default Husbando;
Loading

0 comments on commit dc7f2dd

Please sign in to comment.