{"size": 4046, "ext": "js", "max_stars_repo_path": "generate/blogpost.js", "max_stars_repo_name": "suhelhasan/website", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "generate/blogpost.js", "max_issues_repo_name": "suhelhasan/website", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "generate/blogpost.js", "max_forks_repo_name": "suhelhasan/website", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 25.7707006369, "max_line_length": 92, "alphanum_fraction": 0.6171527435}
/**
 * A NodeJS script which generates a blog post template
 * Inspired by https://github.com/kentcdodds/kentcdodds.com/blob/master/generate/blogpost.js
 */

const path = require('path');
const fs = require('fs');
const util = require('util');
const jsToYaml = require('json-to-pretty-yaml');
const mkdirp = require('mkdirp');
const fakeUa = require('fake-useragent');
const opn = require('opn');
const axios = require('axios');
const slugify = require('@sindresorhus/slugify');
const inquirer = require('inquirer');
const tinify = require('tinify');
const ora = require('ora');
require('dotenv').config({
  path: path.join(__dirname, '.env'),
});

const fromRoot = (...p) => path.join(__dirname, '..', ...p);

tinify.key = process.env.TINY_PNG_API_KEY;

const toTitleCase = function (str) {
  str = str.toLowerCase().split(' ');
  for (let i = 0; i < str.length; i++) {
    str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1);
  }
  return str.join(' ');
};

const listify = a =>
  a && a.trim().length
    ? a
        .split(',')
        .map(s => s.trim())
        .filter(Boolean)
    : null;

async function generateBlogPost() {
  const { title, categories, date, useUnsplash } = await inquirer.prompt([
    {
      type: 'input',
      name: 'title',
      message: 'Title',
    },
    {
      type: 'input',
      name: 'subTitle',
      message: 'SubTitle (default: none)',
    },
    {
      type: 'input',
      name: 'categories',
      message: 'Categories (comma separated)',
    },
    {
      type: 'input',
      name: 'date',
      message: 'Release Date (format: yyyy-mm-dd)',
    },
    {
      type: 'confirm',
      name: 'useUnsplash',
      message: 'Use cover image from Unsplash?',
    },
  ]);
  const slug = slugify(title);
  const year = new Date(date).getFullYear();
  const destination = fromRoot(`src/content/posts/${year}`, `${date}___${slug}`);
  mkdirp.sync(destination);

  let bannerCredit;
  if (useUnsplash) {
    bannerCredit = await getBannerPhoto(title, destination);
  }

  const yaml = jsToYaml.stringify(
    removeEmpty({
      title: toTitleCase(title),
      subTitle: '',
      categories: listify(categories),
      cover: 'images/cover.jpg',
      bannerCredit,
    })
  );
  fs.writeFileSync(path.join(destination, 'index.md'), `---\n${yaml}\n---\n`);

  console.log(`${destination.replace(process.cwd(), '')} is all ready for you`);
}

async function getBannerPhoto(title, destination) {
  const imagesDestination = path.join(destination, 'images');

  await opn(`https://unsplash.com/search/photos/${encodeURIComponent(title)}`, {
    wait: false,
  });

  const { unsplashPhotoId } = await inquirer.prompt([
    {
      type: 'input',
      name: 'unsplashPhotoId',
      message: `What's the Unsplash Photo ID for the banner for this post?`,
    },
  ]);
  mkdirp.sync(imagesDestination);

  const source = tinify
    .fromUrl(
      `https://unsplash.com/photos/${unsplashPhotoId}/download?force=true`
    )
    .resize({
      method: 'cover',
      width: 2070,
      height: 1500,
    });

  const spinner = ora('compressing the image with tinypng.com').start();
  await util
    .promisify(source.toFile)
    .call(source, path.join(imagesDestination, 'cover.jpg'));
  spinner.text = 'compressed the image with tinypng.com';
  spinner.stop();

  const bannerCredit = await getPhotoCredit(unsplashPhotoId);
  return bannerCredit;
}

async function getPhotoCredit(unsplashPhotoId) {
  const response = await axios({
    url: `https://unsplash.com/photos/${unsplashPhotoId}`,
    headers: { 'User-Agent': fakeUa() },
  });
  const {
    groups: { name },
  } = response.data.match(/Photo by (?<name>.*?) on Unsplash/) || {
    groups: { name: 'Unknown' },
  };
  const url = `https://unsplash.com/photos/${unsplashPhotoId}}`;
  return `Photo by <a href=${url}>${name}</a>`;
}

function removeEmpty(obj) {
  return Object.entries(obj).reduce((o, [key, value]) => {
    if (value) {
      o[key] = value;
    }
    return o;
  }, {});
}

generateBlogPost();

/* eslint no-console:0 */
