2018-11-01 19:35:18 +01:00
|
|
|
import fs from 'fs-extra'
|
2018-09-24 01:09:50 +02:00
|
|
|
import path from 'path'
|
|
|
|
import slugify from 'slugify'
|
|
|
|
import ora from 'ora'
|
2019-10-05 00:30:38 +02:00
|
|
|
import fastExif from 'fast-exif'
|
|
|
|
import iptc from 'node-iptc'
|
2018-09-24 01:09:50 +02:00
|
|
|
|
|
|
|
const templatePath = path.join(__dirname, 'new.md')
|
2018-11-05 23:32:02 +01:00
|
|
|
const templatePathPhoto = path.join(__dirname, 'new-photo.md')
|
2018-09-24 01:09:50 +02:00
|
|
|
const template = fs.readFileSync(templatePath).toString()
|
2018-11-05 23:32:02 +01:00
|
|
|
const templatePhoto = fs.readFileSync(templatePathPhoto).toString()
|
2018-09-24 01:09:50 +02:00
|
|
|
|
2018-11-05 23:32:02 +01:00
|
|
|
const spinner = ora('Adding new post').start()
|
2018-09-24 01:09:50 +02:00
|
|
|
|
|
|
|
if (!process.argv[2]) {
|
2018-09-29 23:05:14 +02:00
|
|
|
spinner.fail('Use the format `npm run new "Title of post"`')
|
2018-09-24 01:09:50 +02:00
|
|
|
}
|
|
|
|
|
2019-10-05 00:30:38 +02:00
|
|
|
let title = process.argv[2]
|
|
|
|
const isPhoto = process.argv[2] === 'photo'
|
2018-11-05 23:32:02 +01:00
|
|
|
|
2018-09-24 01:09:50 +02:00
|
|
|
spinner.text = `Adding '${title}'.`
|
|
|
|
|
2019-10-05 00:30:38 +02:00
|
|
|
let titleSlug = slugify(title, { lower: true })
|
2018-09-29 23:05:14 +02:00
|
|
|
const postsPath = path.join('.', 'content', 'posts')
|
2018-11-05 23:32:02 +01:00
|
|
|
const photosPath = path.join('.', 'content', 'photos')
|
2018-11-06 00:28:52 +01:00
|
|
|
|
|
|
|
let date = new Date().toISOString()
|
2018-09-29 23:05:14 +02:00
|
|
|
|
2019-10-05 00:30:38 +02:00
|
|
|
async function getIptc(imagePath) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
fs.readFile(imagePath, (err, data) => {
|
|
|
|
if (err) reject(err)
|
|
|
|
const iptcData = iptc(data)
|
|
|
|
return resolve(iptcData)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getExif(imagePath) {
|
|
|
|
let exifData
|
|
|
|
try {
|
|
|
|
exifData = await fastExif.read(imagePath, true)
|
|
|
|
} catch (error) {
|
|
|
|
return null
|
2018-11-06 00:28:52 +01:00
|
|
|
}
|
|
|
|
|
2019-10-05 00:30:38 +02:00
|
|
|
let iptcData
|
|
|
|
try {
|
|
|
|
iptcData = await getIptc(imagePath)
|
|
|
|
} catch (error) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
return { ...exifData, iptc: { ...iptcData } }
|
|
|
|
}
|
|
|
|
|
|
|
|
async function createPhotoPost() {
|
|
|
|
const photo = process.argv[3]
|
2020-03-04 19:54:17 +01:00
|
|
|
try {
|
|
|
|
const exifData = await getExif(photo)
|
|
|
|
title = exifData.iptc.object_name || exifData.iptc.title
|
|
|
|
titleSlug = slugify(title, { lower: true })
|
|
|
|
date = new Date(exifData.exif.DateTimeOriginal).toISOString()
|
|
|
|
const dateShort = date.slice(0, 10)
|
|
|
|
const description = exifData.iptc.caption
|
|
|
|
const fileName = `${dateShort}-${titleSlug}`
|
|
|
|
const postPhoto = `${photosPath}/${fileName}.md`
|
|
|
|
|
|
|
|
const newContentsPhoto = templatePhoto
|
|
|
|
.split('TITLE')
|
|
|
|
.join(title)
|
|
|
|
.split('SLUG')
|
|
|
|
.join(titleSlug)
|
|
|
|
.split('DATE_LONG')
|
|
|
|
.join(date)
|
|
|
|
.split('DATE_SHORT')
|
|
|
|
.join(dateShort)
|
|
|
|
.split('DESCRIPTION')
|
|
|
|
.join(description)
|
|
|
|
|
|
|
|
// copy photo file in place
|
|
|
|
fs.copyFile(photo, `${photosPath}/${fileName}.jpg`, err => {
|
|
|
|
if (err) spinner.fail(`Error copying photo file: ${err}`)
|
|
|
|
})
|
2018-11-06 00:28:52 +01:00
|
|
|
|
2020-03-04 19:54:17 +01:00
|
|
|
// create photo post file
|
|
|
|
fs.appendFile(postPhoto, newContentsPhoto, err => {
|
|
|
|
if (err) spinner.fail(`Error creating photo post: ${err}`)
|
|
|
|
spinner.succeed(`New photo post '${title}' as '${fileName}.md' created.`)
|
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error.message)
|
|
|
|
}
|
2019-10-05 00:30:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isPhoto) {
|
|
|
|
createPhotoPost()
|
2018-11-05 23:32:02 +01:00
|
|
|
} else {
|
2018-11-06 00:28:52 +01:00
|
|
|
if (process.argv[3]) {
|
|
|
|
date = new Date(process.argv[3]).toISOString()
|
|
|
|
}
|
|
|
|
|
|
|
|
const dateShort = date.slice(0, 10)
|
|
|
|
const file = `${postsPath}/${dateShort}-${titleSlug}/index.md`
|
|
|
|
|
|
|
|
const newContents = template
|
|
|
|
.split('TITLE')
|
|
|
|
.join(title)
|
|
|
|
.split('SLUG')
|
|
|
|
.join(titleSlug)
|
|
|
|
.split('DATE')
|
|
|
|
.join(date)
|
|
|
|
|
2018-11-05 23:32:02 +01:00
|
|
|
fs.outputFile(file, newContents)
|
|
|
|
.then(() => fs.readFile(file, 'utf8'))
|
|
|
|
.then(() => spinner.succeed(`New post '${title}' created.`))
|
|
|
|
.catch(err => spinner.fail(`Error creating post: ${err}`))
|
|
|
|
}
|