Live (In a Volcano) community card game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

183 lines
4.5 KiB

// post.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const striptags = require('striptags');
const slug = require('slug');
const { SiteService } = require('../../lib/site-lib');
const mongoose = require('mongoose');
const ObjectId = mongoose.Types.ObjectId;
const Post = mongoose.model('Post');
class PostService extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
this.populatePost = [
{
path: 'author',
select: '_id username username_lc displayName bio picture',
},
{
path: 'image',
},
];
}
async create (author, postDefinition) {
const NOW = new Date();
const post = new Post();
post.created = NOW;
post.author = author._id;
post.title = striptags(postDefinition.title.trim());
post.slug = this.createPostSlug(post._id, post.title);
post.summary = striptags(postDefinition.summary.trim());
post.content = postDefinition.content.trim();
post.status = postDefinition.status || 'draft';
post.flags = {
enableComments: postDefinition.enableComments === 'on',
isFeatured: postDefinition.isFeatured === 'on',
};
await post.save();
return post.toObject();
}
async update (post, postDefinition) {
const NOW = new Date();
const updateOp = {
$set: {
updated: NOW,
},
};
if (postDefinition.title) {
updateOp.$set.title = striptags(postDefinition.title.trim());
updateOp.$set.slug = this.createPostSlug(post._id, updateOp.$set.title);
}
if (postDefinition.slug) {
let postSlug = striptags(slug(postDefinition.slug.trim())).split('-');
while (ObjectId.isValid(postSlug[postSlug.length - 1])) {
postSlug.pop();
}
postSlug = postSlug.splice(0, 4);
postSlug.push(post._id.toString());
updateOp.$set.slug = `${postSlug.join('-')}`;
}
if (postDefinition.summary) {
updateOp.$set.summary = striptags(postDefinition.summary.trim());
}
if (postDefinition.content) {
updateOp.$set.content = postDefinition.content.trim();
}
if (postDefinition.status) {
updateOp.$set.status = striptags(postDefinition.status.trim());
}
updateOp.$set['flags.enableComments'] = postDefinition.enableComments === 'on';
updateOp.$set['flags.isFeatured'] = postDefinition.isFeatured === 'on';
await Post.updateOne(
{ _id: post._id },
updateOp,
{ upsert: true },
);
}
async updateImage (user, post, file) {
const { image: imageService } = this.dtp.services;
const images = [
{
width: 960,
height: 540,
format: 'jpeg',
formatParameters: {
quality: 80,
},
},
];
await imageService.processImageFile(user, file, images);
await Post.updateOne(
{ _id: post._id },
{
$set: {
image: images[0].image._id,
},
},
);
}
async getPosts (pagination, status = ['published']) {
if (!Array.isArray(status)) {
status = [status];
}
const posts = await Post
.find({ status: { $in: status }, 'flags.isFeatured': false })
.sort({ created: -1 })
.skip(pagination.skip)
.limit(pagination.cpp)
.lean();
return posts;
}
async getFeaturedPosts (maxCount = 3) {
const posts = await Post
.find({ status: 'published', 'flags.isFeatured': true })
.sort({ created: -1 })
.limit(maxCount)
.lean();
return posts;
}
async getAllPosts (pagination) {
const posts = await Post
.find()
.sort({ created: -1 })
.skip(pagination.skip)
.limit(pagination.cpp)
.lean();
return posts;
}
async getById (postId) {
const post = await Post
.findById(postId)
.select('+content')
.populate(this.populatePost)
.lean();
return post;
}
async getBySlug (postSlug) {
const slugParts = postSlug.split('-');
const postId = slugParts[slugParts.length - 1];
return this.getById(postId);
}
async deletePost (post) {
this.log.info('deleting post', { postId: post._id });
await Post.deleteOne({ _id: post._id });
}
createPostSlug (postId, postTitle) {
if ((typeof postTitle !== 'string') || (postTitle.length < 1)) {
throw new Error('Invalid input for making a post slug');
}
const postSlug = slug(postTitle.trim().toLowerCase()).split('-').slice(0, 4).join('-');
return `${postSlug}-${postId}`;
}
}
module.exports = {
slug: 'post',
name: 'post',
create: (dtp) => { return new PostService(dtp); },
};