import fh from 'filehound'; import fs from 'fs-extra'; import metadataParser from 'markdown-yaml-metadata-parser'; import _ from 'lodash'; import * as DataEvent from '../../src/com/events/DataEvent'; import Navigation from './Navigation'; import Utils from './Utils'; const moment = require('moment'); const nav = new Navigation(); const utils = new Utils(); /** * Class for handling blog content pages */ export default class Book { //-------------------------- // constructor //-------------------------- constructor() {} //-------------------------- // methods //-------------------------- start() {} /** * Retrieves single page or pages * @parameter id: optional id if requesting a single Page */ getPage(id) { return new Promise((resolve, reject) => { fh.create() .paths('content/pages') .ext('md') .find() .then(files => { let pages = []; for (let index = 0; index < files.length; index++) { fs.readFile(files[index], { encoding: 'utf8' }, (err, file) => { pages.push(metadataParser(file)); }); } if (id === null || id === null || id === undefined) { setTimeout(() => { //TODO: Duct tape solution until something better created utils.organizeTags(pages); utils.organizeArchive(pages); resolve(pages); }, 100); } else { setTimeout(() => { //TODO: Duct tape solution until something better created //make check against menu to see if page should be marked as menu item //if it doesn't exist in menu change, edit page to let page = _.find(pages, list => { return list.metadata.uuid === id; }); resolve(page); }, 100); } }) .catch(err => { reject(err); }); }); } /** * Edits single page based on id and task * @parameter body: object that contains all page information * @parameter id: identifier for page being edited * @parameter task: type of task being performed - listed in DataEvents Class /src/com/events * @parameter user: object contain user information */ editPage(body, id, task, user) { return new Promise((resolve, reject) => { let self = this; let response = []; switch (task) { case DataEvent.API_PAGE_CREATE: case DataEvent.API_PAGE_WRITE: var layout = 'page'; var path = ''; fs.ensureDir( 'content/pages/' + moment(body.created).format('YYYY') + '/' + moment(body.created).format('MM') + '/' ).then(() => { if (body.menu === 'true') { body.path = moment(body.created).format('YYYY') + '/' + moment(body.created).format('MM'); nav.editMenu(DataEvent.MENU_ADD_ITEM, body, user); } else { nav.editMenu(DataEvent.MENU_DELETE_ITEM, body, user); } if (body.layout !== 'page') layout = body.layout; if (body.layout === null || body.layout === 'null') layout = 'page'; var pageWrite = '---\n' + 'id: ' + body.id + '\n' + 'uuid: ' + body.uuid + '\n' + 'title: ' + body.title + '\n' + 'feature: ' + body.feature + '\n' + 'path: ' + moment(body.created).format('YYYY') + '/' + moment(body.created).format('MM') + '\n' + 'layout: ' + layout + '\n' + 'tags: ' + body.tags + '\n' + 'author: ' + user.handle + '\n' + 'created: ' + moment(body.created).format() + '\n' + 'updated: ' + moment(Date.now()).format() + '\n' + 'deleted: ' + body.deleted + '\n' + 'menu: ' + body.menu + '\n' + 'featured: ' + body.featured + '\n' + 'published: ' + body.published + '\n' + 'slug: ' + body.slug + '\n' + '---\n' + body.content; layout === 'index' ? (path = 'content/pages/index.md') : (path = 'content/pages/' + moment(body.created).format('YYYY') + '/' + moment(body.created).format('MM') + '/' + body.slug + '.md'); fs.writeFile(path, pageWrite, err => { // throws an error, you could also catch it here if (err) { response = { type: DataEvent.PAGE_ERROR, message: err }; reject(response); } // success case, the file was saved if (task === DataEvent.API_PAGE_CREATE) { // if new file, update settings index and page count response = { type: DataEvent.PAGE_ADDED, message: 'New Page Created', id: body.uuid }; resolve(response); } else { response = { type: DataEvent.PAGE_UPDATED, message: 'Page saved. Nice Work' }; resolve(response); } }); }); break; case DataEvent.API_PAGE_DELETE: this.getPage(id) .then(page => { let body = _.mapValues(page.metadata); body.content = page.content; body.deleted = moment(Date.now()).format(); body.menu = false; self.editPage(body, body.uuid, DataEvent.API_PAGE_WRITE, user) .then(() => { let item = { title: body.title, id: body.id, slug: body.slug, uuid: body.uuid }; nav.editMenu(DataEvent.MENU_DELETE_ITEM, item); response = { type: DataEvent.PAGE_DELETED, message: 'Page deleted, sport', data: { uuid: body.uuid } }; resolve(response); }) .catch(err => { response = { type: DataEvent.PAGE_ERROR, message: err }; reject(response); }); }) .catch(err => { response = { type: DataEvent.PAGE_ERROR, message: err }; reject(response); }); break; } }); } reindexPages(req) { var response = ''; var self = this; return new Promise((resolve, reject) => { self.getPage() .then(pages => { let sorted = []; for (let i = 0; i < pages.length; i++) { let body = pages[i].metadata; body.content = pages[i].content; sorted.push(body); } //resorts pages by date created let byDate = _.sortBy(sorted, page => { return page.created; }); //reassigns id sequentially based on sorted pages for (let index = 0; index < byDate.length; index++) { byDate[index].id = index; self.editPage( byDate[index], index, DataEvent.API_PAGE_WRITE, req.session.user ); } response = { type: DataEvent.API_REINDEX_PAGES, message: 'Pages re-sorted. Easy peasy.', count: byDate.length }; resolve(response); }) .catch(err => { response = { type: DataEvent.PAGE_ERROR, message: err }; reject(response); }); }); } //-------------------------- // event handlers //-------------------------- }