mirror of
https://github.com/wassname/talk.git
synced 2026-06-28 22:04:50 +08:00
75 lines
2.2 KiB
JavaScript
75 lines
2.2 KiB
JavaScript
const DataLoader = require('dataloader');
|
|
const url = require('url');
|
|
|
|
const errors = require('../../errors');
|
|
const scraper = require('../../services/scraper');
|
|
const util = require('./util');
|
|
|
|
const AssetModel = require('../../models/asset');
|
|
const AssetsService = require('../../services/assets');
|
|
|
|
/**
|
|
* Retrieves assets by an array of ids.
|
|
* @param {Object} context the context of the request
|
|
* @param {Array} ids array of ids to lookup
|
|
*/
|
|
const genAssetsByID = (context, ids) => AssetModel.find({
|
|
id: {
|
|
$in: ids
|
|
}
|
|
}).then(util.singleJoinBy(ids, 'id'));
|
|
|
|
/**
|
|
* This endpoint find or creates an asset at the given url when it is loaded.
|
|
* @param {Object} context the context of the request
|
|
* @param {String} asset_url the url passed in from the query
|
|
* @returns {Promise} resolves to the asset
|
|
*/
|
|
const findOrCreateAssetByURL = (context, asset_url) => {
|
|
|
|
// Verify that the asset_url is parsable.
|
|
let parsed_asset_url = url.parse(asset_url);
|
|
if (!parsed_asset_url.protocol) {
|
|
return Promise.reject(errors.ErrInvalidAssetURL);
|
|
}
|
|
|
|
return AssetsService.findOrCreateByUrl(asset_url)
|
|
.then((asset) => {
|
|
|
|
// If the asset wasn't scraped before, scrape it! Otherwise just return
|
|
// the asset.
|
|
if (!asset.scraped) {
|
|
return scraper.create(asset).then(() => asset);
|
|
}
|
|
|
|
return asset;
|
|
});
|
|
};
|
|
|
|
const getAssetsForMetrics = ({loaders: {Actions, Comments}}) => {
|
|
return Actions.getByTypes({action_type: 'FLAG', item_type: 'COMMENT'})
|
|
.then((actions) => { // ALL ACTIONS :O
|
|
const ids = actions.map(({item_id}) => item_id);
|
|
|
|
return Comments.getByQuery({ids});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Creates a set of loaders based on a GraphQL context.
|
|
* @param {Object} context the context of the GraphQL request
|
|
* @return {Object} object of loaders
|
|
*/
|
|
module.exports = (context) => ({
|
|
Assets: {
|
|
|
|
// TODO: decide whether we want to move these to mutators or not, as in fact
|
|
// this operation create a new asset if one isn't found.
|
|
getByURL: (url) => findOrCreateAssetByURL(context, url),
|
|
|
|
getByID: new DataLoader((ids) => genAssetsByID(context, ids)),
|
|
getForMetrics: () => getAssetsForMetrics(context),
|
|
getAll: new util.SingletonResolver(() => AssetModel.find({}))
|
|
}
|
|
});
|