Convert Markdown Files into Quiver Notes

'use strict';

const fs = require('fs');
const Bluebird = require('bluebird');
const path = require('path');
const readDir = Bluebird.promisify(fs.readdir);
const readFile = Bluebird.promisify(fs.readFile);
const mkdir = Bluebird.promisify(fs.mkdir);
const stat = Bluebird.promisify(fs.stat);
const moment = require('moment');
const writeFile = Bluebird.promisify(fs.writeFile);
const rimraf = Bluebird.promisify(require('rimraf'));
const uuid = require('node-uuid')

readDir(process.cwd())
    .filter(filename => filename.indexOf('.md') !== -1)
    .map(generateQuiverNote);

function generateQuiverNote(filename) {
    const filepath = path.join(process.cwd(), filename);
    const fileuuid = uuid.v4().toUpperCase();
    const dirpath = path.join(process.cwd(), fileuuid + '.qvnote');

    return createNoteDir()
        .then(() => Bluebird.join(createNoteMeta(), createNoteContent()));

    function createNoteDir() {
        return rimraf(dirpath).then(() => mkdir(dirpath));
    }

    function createNoteMeta() {
        return stat(filepath).then(function(stats, data) {
            let meta = {};

            meta.created_at = moment(stats.birthtime).unix();
            meta.tags = [];
            meta.title = filename.slice(0, -3);
            meta.updated_at = moment(stats.mtime).unix();
            meta.uuid = fileuuid;

            return writeFile(path.join(dirpath, 'meta.json'), JSON.stringify(meta, null, 2));
        });
    }

    function createNoteContent() {
        return readFile(filepath).then(function(data) {
            let content = {};

            content.title = filename;
            content.cells = [{
                type: 'markdown',
                data: data.toString()
            }];

            return writeFile(path.join(dirpath, 'content.json'), JSON.stringify(content, null, 2));
        });
    }
}
{"name":"markdown-to-quiver","version":"1.0.0","description":"Convert your markdown files into Quiver notes.","main":"sort.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"author":"James DiGioia <jamesorodig@gmail.com> (jamesdigioia.com)","license":"ISC","dependencies":{"bluebird":"^3.1.1","moment":"^2.10.6","node-uuid":"^1.4.7","rimraf":"^2.4.4"}}

OS X Provisioning Script

sudo gem install kitchenplan
kitchenplan setup
kitchenplan provision

brew pin ruby

gem install homesick
homesick clone https://github.com/mAAdhaTTah/dotfiles
homesick link dotfiles # or mAAdhaTTah/dotfiles?

git clone pianosa:~/.settings/ # The address is for my home server
mackup restore

python -c "$(curl -fsSL https://raw.githubusercontent.com/fix-macosx/fix-macosx/master/fix-macosx.py)"

save_post Error Reporting Boilerplate

add_action( 'admin_notices', 'my_error_message' );
add_action( 'save_post', 'my_save_post_function' );
function my_save_function( $post_id ) {
    $error = false;

    // Do stuff.

    if ($something_went_wrong) {
        $error = new WP_Error($code, $msg);        
    }

    if ($error) {
        // Handle error.
    }

    return true;
}

Using $_SESSION to Display Errors

if ( !session_id() ) {
    session_start();
}
if ($error) {
    $_SESSION['my_plugin_errors'] = $error->get_error_message();
}
if ( array_key_exists( 'my_plugin_errors', $_SESSION ) ) {?>
    <div class="error">
        <p><?php echo $_SESSION['my_plugin_errors']; ?></p>
    </div><?php

    unset( $_SESSION['my_plugin_errors'] );
}

Using Redirect Args to Display Errors

if ($error) {
    add_filter('redirect_post_location', function( $location ) use ( $error ) {
        return add_query_arg( 'my-plugin-error', $error->get_error_code(), $location );
    });
}
if ( array_key_exists( 'my-plugin-error', $_GET) ) { ?>
    <div class="error">
        <p>
            <?php
                switch($_GET['my-plugin-error']) {
                    case 'an_error_code':
                        echo 'The post failed to save because problems.';
                        break;
                    case 'another_error_code':
                        echo 'The post failed to save because reasons.';
                        break;
                    default:
                        echo 'An error ocurred when saving the post.';
                        break;
                }
            ?>
        </p>
    </div><?php
}

Using Transients to Display Errors

if ($error) {
    set_transient("my_save_post_errors_{$post_id}_{$user_id}", $error, 45);
}
if ( $error = get_transient( "my_save_post_errors_{$post_id}_{$user_id}" ) ) { ?>
    <div class="error">
        <p><?php echo $error->get_error_message(); ?></p>
    </div><?php

    delete_transient("my_save_post_errors_{$post_id}_{$user_id}");
}

Shell script to install Netatalk 3 on Ubuntu 14.04

# Get root:

sudo su

# Install prerequisites:

apt-get install build-essential pkg-config checkinstall git avahi-daemon libavahi-client-dev libcrack2-dev libwrap0-dev autotools-dev automake libtool libdb-dev libacl1-dev libdb5.1-dev db-util db5.1-util libgcrypt11 libgcrypt11-dev

# Build libevent from source:
cd /usr/local/src
wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar xfv libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure
 make
checkinstall --pkgname=libevent-2.0.21-stable --pkgversion="$(date +%Y%m%d%H%M)" --backup=no --deldoc=yes --default --fstrans=no
cd ../

# Download src:
git clone git://git.code.sf.net/p/netatalk/code netatalk-code
cd netatalk-code
./bootstrap

# Configure install

./configure --enable-debian --enable-zeroconf --with-cracklib --with-acls --enable-tcp-wrappers --with-init-style=debian
make

# Build!

checkinstall --pkgname=netatalk --pkgversion="$(date +%Y%m%d%H%M)" --backup=no --deldoc=yes --default --fstrans=no

# Config is in /usr/local/etc/afp.conf
;/usr/local/etc/afp.conf
; Netatalk 3.x configuration file
;
 
[Global]
; Global server settings
vol preset = default_for_all_vol
hostname = TimeCapsule
log file = /var/log/netatalk.log
log level = default:info
uam list = uams_dhx.so,uams_dhx2.so
save password = no
disconnect time = 168
dsireadbuf = 96
sleep time = 24
tcprcvbuf = 524288
tcpsndbuf = 524288
dircachesize = 131072
keep sessions = yes
mimic model = Xserve
 
[default_for_all_vol]
file perm = 0664
directory perm = 0774
;cnid scheme = cbd
valid users = @tm
 
[Homes]
basedir regex = /home
cnid scheme = dbd
home name = Home: $u
 
[TimeMachine]
path = /home/tm
time machine = yes
;vol size limit = 953674

CMB2 as Composer Library

{
 "require": {
    "php": ">=5.3.0",
    "composer/installers": "v1.0.12",
    "webdevstudios/cmb2": "dev-master",
  },
  "autoload": {
    "files": ["vendor/cmb2/init.php"]
  },
  "extra": {
    "installer-paths": {
      "vendor/{$name}/": ["webdevstudios/cmb2"]
    }
  } 
}