Papersaver
Paper is an excellent product. Like all great products, it not only does a thing well, it also makes you want to do that thing more. Paper makes me want to draw more. After drawing with Paper for a few weeks, I wanted a quick way to share my drawings from Paper to the Web. I built Papersaver so I could get that done.
In Dependence
Made with Paper is a showcase of what people are drawing with Paper. I went to submit one of my silly sketches to it and saw that they ask for an attribution link. They suggest–and most submissions are hosted on–Tumblr. Twitter and Facebook are also mentioned as hosting choices. I don’t care for that. I want the canonical location of my brain dumps to be on a server that I control. This is my natural tendency, but I was also inspired by Jeremy and Frank’s articles on the topic of pushing ourselves to take more control over our digital artifacts by self-hosting.
At this point it was clear that I had a fun side project in front of me. With a few days off work for the holidays, I started letting my brain run wild with possibilities. The plan was to build some type of site where I could publish my drawings while digging into a technology or two that was new to me.
Planning
I generally start a new project with a few bullet points for what I want, what I don’t, technologies I’ll use, etc. These points don’t always make it into the final project and some are just questions to think about during the process. Here’s a few I jotted down for Papersaver:
Project goals
- Publish images from Paper to my personal Web site
- Do not rely on third-party platforms for storage
- “In Dependence”
What does it do?
- Static HTML site
- Displays a list of images (maybe thumbnails + click to enlarge)
- Git repo backed up to Github
- Different input methods: email, Twitter, direct to repo
- generate(): image creation, HTML generation, Git commit, publish
- How can others use this?
- Permalinks to each item
At this point I’ll also jot down some pseudo-code to start thinking about core functions of what I’ll be building. In this case I wanted to visualize what the main method of saving a Paper would look like:
newPaper() // takes img
// contents/papers/Date.getTime()
// " "/index.md
// date: D.getTime()
// template: paper.html
// image_path: tylergaw-paper-{date}.jpg
// save img: image_path.jpg
Getting rolling
After a few hours of writing down goals and researching similar projects I had a good idea of what I would build and the tools I would use to build it. I needed a way to get my drawings out of Paper. The App allows drawings to be shared to Tumblr, Facebook, Twitter, Camera Roll, and Email. The first three were out since they’re third-parties. I entertained the idea of using a combination of export to cameral roll and Dropbox to publish, but went away from it because it didn’t feel flexible enough. I’d be going the route of publishing via email.
How I use Papersaver
- Draw in Paper
- Email each drawing I want published to a dedicated email address
- A Node.js script listens for new email at the dedicated email address
- When a new email arrives, the script grabs the attached image and hands it off to Papersaver.js
- Papersaver.js creates the necessary directories and files for Node.js static site generator, Wintersmith
- Wintersmith regenerates the site with the new drawings
- The newly added and created files are commited to the Git repo and those commits are pushed to the remote repo at Github
- The drawings live at http://lab.tylergaw.com/papers
The pieces
Papersaver is a fairly simple hack, but there are a few interesting parts worth talking about in more detail.
Good enough email security
I'm using a node package to access Papersaver emails over IMAP. I don't want to leave the security of my primary email address in the hands of my programming skills so I use a dedicated email address–tylergaw.papersaver@gmail.com–for Papersaver.
I just gave you the email address. So what's to keep you from flooding my Papersaver with all the images you please? (aside from your trustworthy nature) I use a settings file with to and from whitelists to only allow emails to/from certain addresses. Nothing good would come from me adding my actual settings to the public Github repo, but I do include a sample settings file. The from address is really easy to fake, but the to address is a pretty decent way to lock things down.
I use a "+slug" on the email address that I don't publish anywhere.
Fake example; tylergaw.papersaver+71ksk27817@gmail.com. I put that address
in my toWhitelist
settings. The mail listener script
checks to make sure any emails received are to an address in the whitelist,
if not, it bails. Fort Knox an email slug don't make, but for this
little project it gets the job done.
Papersaver Command-line interface
While I was working on Papersaver, I didn't want to have to send an email each time I needed to test that the saving code was working. To make things faster I wrote a simple CLI that allows me to create new Papers from images on my machine. I used the super-cool node package Optimist to handle the arguments I wanted to provide. The Papersaver CLI isn't any type of technological achievement, but it was the first time I've written something like it, so it gets a mention here.
Static site generator
Since I decided to go the Node.js route for this project, I wanted all the pieces to be written in Node.js. Wintersmith is a static site generator written in Node.js. These types of static generators have been written about at length so I don't have anything more to add. I'll just say that Wintersmith gets the job done and if I need a generator written in Node.js, it will be my go-to.
Steal this project!
I didn't build this project just for me. My hope is that other folks that use Paper will find it interesting and start self-hosting the notes, drawings, and sketches they create. Papersaver isn't yet a turnkey project. I had that in mind from the start, but it will require more work to get it there. In the meantime, I'd love to see forks of it that remedy some of the issues that are currently making it not ready for quick re-use. I'm also 100% open to pull requests, so fork it!
Thanks for reading