media-grab
Version:
Grab random media from the internet
168 lines (167 loc) • 8.45 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RedditGrabber = void 0;
// Imports
const magicStrings_js_1 = __importDefault(require("./magicStrings.js"));
const helpers = __importStar(require("./helpers.js"));
const index_js_1 = __importDefault(require("./reddit/index.js"));
/**
* The possible states of the tool.
* @private
*/
// Export a class called RedditGrabber
/**
* The super tool class. Holds a state and implements the execute command.
*/
class RedditGrabber {
/**
* The possible states of the tool.
* @return {{great: string, cool: string, awesome: string, swag: string}}
*/
// The constructor should set the username, password, appId, appSecret, and userAgent
constructor(options) {
// Ensure that options is an object with properties username, password, appId, appSecret else throw an error
if (typeof options === 'object' &&
(options === null || options === void 0 ? void 0 : options.username) &&
(options === null || options === void 0 ? void 0 : options.password) &&
(options === null || options === void 0 ? void 0 : options.appId) &&
(options === null || options === void 0 ? void 0 : options.appSecret)) {
this.username = options.username;
this.password = options.password;
this.appId = options.appId;
this.appSecret = options.appSecret;
this.userAgent = options.userAgent;
}
else {
throw new Error('Invalid options');
}
// Optional
this.userAgent = options === null || options === void 0 ? void 0 : options.userAgent;
this.subreddits = (options === null || options === void 0 ? void 0 : options.subreddits) || ['funny'];
this.alwaysTypes = ['hot'];
this.randomTypes = ['top'];
this.times = ['t=year', 't=month'];
this.mediaSources = ['redgifs', 'imgur', 'gfycat', 'v.redd.it', 'i.redd.it'];
this.reddit = new index_js_1.default({
username: this.username,
password: this.password,
appId: this.appId,
appSecret: this.appSecret,
userAgent: this.userAgent || 'Bot',
});
}
// Function that gets username
/**
* Validates a state. To be valid, the value needs to be part of the {tool.states}.
* Throws an Error if invalid. Returns void / undefined if passed.
* @param value The state candidate to be validated.
* @throws if state is not a valid state
*/
getSubreddits() {
return this.subreddits;
}
// Function that sets username
/**
* Validates and sets a new state value if given and returns the updated value. If no defined value is given it just returns the
* current state value.
* @param value {String|undefined} optional state to be set.
* @return {String} the current state value
*/
setSubreddits(subreddits) {
// Make sure subreddits is an array of strings
if (subreddits.every((e) => typeof e === 'string')) {
this.subreddits = subreddits;
}
else {
throw new Error('Subreddits must be an array of strings');
}
}
// Main grabbit function
grabbit() {
return __awaiter(this, void 0, void 0, function* () {
let redditSlugs = [];
for (const subreddit of this.subreddits) {
redditSlugs = redditSlugs.concat(helpers.getRedditSlug(subreddit, this.alwaysTypes[0], this.times[0]) // TODO make types/times configurable in the future
);
}
// Throw an error if there are no reddit slugs
if (redditSlugs.length === 0) {
throw new Error('No reddit slugs due to lack of subreddits');
}
const allDemUrls = yield Promise.all(redditSlugs.map((url) => __awaiter(this, void 0, void 0, function* () {
var _a;
const res = yield this.reddit.get(url);
const after = res.data.after;
const data = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.children.map((e) => {
var _a, _b, _c, _d, _e, _f, _g;
if ((_c = (_b = (_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.media) === null || _b === void 0 ? void 0 : _b.reddit_video) === null || _c === void 0 ? void 0 : _c.fallback_url) {
return (_f = (_e = (_d = e === null || e === void 0 ? void 0 : e.data) === null || _d === void 0 ? void 0 : _d.media) === null || _e === void 0 ? void 0 : _e.reddit_video) === null || _f === void 0 ? void 0 : _f.fallback_url;
}
else {
return (_g = e === null || e === void 0 ? void 0 : e.data) === null || _g === void 0 ? void 0 : _g.url_overridden_by_dest;
}
}).filter((e) => typeof e === 'string').filter((e) => {
return this.mediaSources.some((source) => e.includes(source));
});
return { data, after };
})));
// Filter out any string that doesnt contain any value form an array of strings
const flattened = allDemUrls.map((e) => e.data).flat();
// Get a random one
let theChosenOne = helpers.getRandomIndex(flattened);
// Check if the chosen one is a valid url else get another one (5 tries)
let start = 0;
while (!helpers.isValidURL(theChosenOne) && start < 5) {
theChosenOne = helpers.getRandomIndex(flattened);
start++;
}
// Final check and package response data
const baseRespData = {
url: theChosenOne,
subreddits: this.subreddits,
};
if (helpers.isValidURL(theChosenOne)) {
return helpers.createResponse(true, Object.assign(Object.assign({}, baseRespData), { message: magicStrings_js_1.default.SUCCESS_MESSAGE }));
}
else {
return helpers.createResponse(false, Object.assign(Object.assign({}, baseRespData), { message: magicStrings_js_1.default.ERROR_MESSAGE }));
}
});
}
}
exports.RedditGrabber = RedditGrabber;