Saving Pocket Links to a New File Every Day using Dropbox, IFTTT, and launchd

March 27th, 2013

For the past year, I’ve been saving interesting links by copying and pasting their URLs into Markdown files in a Git repository that were then browsable through a Gollum wiki. I created a new file each day and just made an unordered list of links that I found on that day. There were a few problems with this method:

  1. While it was possible for me to create an automator action or something that would facilitate the process, I never bothered to do so and copying and pasting the links from the Chrome location bar into Sublime Text took too much time.
  2. The title of the page wasn’t included and the URLs alone weren’t always enough to tell what the page included (ex. YouTube permalinks don’t provide very much information).
  3. Technically, just pasting links into Markdown isn’t proper formatting. While most Markdown parsers will automatically link URLs, it’s more proper to wrap them in < and > if they’re bare URLs or using [] and ().

The solution:

  1. Use Pocket to gather interesting links. I chose Pocket because it has tagging (although I don’t really use them because it takes time to enter them), excerpts (which come into play later), and a plethora of browser extensions, mobile apps, etc.
  2. Use IFTTT to automatically take new links added to Pocket and insert them into text files in Dropbox which are then synced into Gollum.

IFTTT can be set to trigger a Dropbox append action whenever a new link is added to Pocket. The parameters that IFTTT offers are also useful as they allow for some more information to be added to the link than just the URL, such as the page title and an excerpt (although the excerpts don’t always come out nicely). Here’s what I have in the “content” section of my IFTTT receipe:

### [{{Title}}]({{Url}})<br><br><i>{{Excerpt}}</i><br><br>
{{AddedAt}}<br><br>
- - -<br><br>

I tried to use the AddedAt ingredient in the file name, but the ingredient returns the date and time the link was added in the following format: March 22, 2013 at 12:40PM, which isn’t very useful for our purposes.

I’ve also shared my receipe, in case anyone else wants to use and/or modify it.

There was only one problem with this: for some reason, IFTTT’s Dropbox actions don’t let you change the filename of the file you wish to append text to. In other words, rather than getting one text file of links for each day, one massive text file containing links from all days is created. I came up with a quick way to fix this: use launchd.

I created a launchd file that runs a bash script every day at midnight that does the following:

  1. Append a Markdown title with the date to the top of the text file (ex. "# March 27, 2013 Links").
  2. Rename the file in Dropbox created by IFTTT to the YYYY-MM-DD.md format.

Here’s my launchd task:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.christophersu.dailylinks</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/day.sh</string>
    </array>
    <key>RunAtLoad</key>
    <false/>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>23</integer>
            <key>Minute</key>
            <integer>59</integer>
        </dict>
    </array>
</dict>
</plist>

You’ll notice that it runs at 11:59 PM. This is because I wanted to append the proper title to the top of the file ("# March 27, 2013") and have the correct date in the filename without having to write additional code in order to decrement the day counter and compensate for the last days of the month and such (if the decrement method is used, then when a “1″ is decremented, additional code is going to be needed to determine whether it should decrement to a “28″, “29″, “30″, or “31″). I didn’t want to have to deal with leap years and everything just to catch links that might have been saved between 11:59 PM and 12:00 PM.

Here’s the bash script it runs:

#!/bin/bash  
thedate=`date +%Y-%-m-%d`
titlevar=`date '+%B %e, %Y'`
# cd /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket
echo -e "# $titlevar\n" | cat - /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/links.txt > /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/temp && mv /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/temp /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/links.txt
mv /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Pocket/links.txt /Users/christophersu/Dropbox-Gamma/Dropbox/Personal/Links/$thedate.md

Automatically Committing to Git in TextMate

December 6th, 2012

With my Gollum installation and Jekyll powered website, I often commit changes after saving a file. This two-step process can be reduced to a single step by having TextMate commit to git automatically after a file save. This is done by going to “Bundles” in the menubar, going to Bundle Editor > Edit Commands…, creating a new command to save and commit to git, and assigning it a keyboard shortcut.

Here is the command that I use:

#!/usr/bin/env ruby
filename = ENV["TM_FILEPATH"].split("/").last
`git add #{ENV["TM_FILEPATH"]}`
`git commit -m "Updated #{filename} (TextMate)"`

I set the command to save the “Current File” and input the “Entire Document”. I assigned the key-binding to Commmand+S because I intend on committing almost every file I save. To have the command request a commit message for the commit, this command can be used, which displays a pop up dialog requesting a message:

#!/usr/bin/env ruby
filename = ENV["TM_FILEPATH"].split("/").last

require ENV['TM_SUPPORT_PATH'] + '/lib/ui'
message = TextMate::UI.request_string(:title => "Commiting changes of #{filename}", :prompt => "Please enter the commit message for your changes.")

add = `git add #{ENV["TM_FILEPATH"]} 2>&1`
commit = `git commit -m "#{message}" 2>&1`

git_answer = add + commit
unless git_answer.grep(/fatal/).empty?
  puts "Please initialize git repository first!"
end

Markdown on Mac

October 5th, 2012

I’ve been writing pretty much everything from notes and blog posts to  todo lists and essays in Markdown for quite some time now, and I’ve found some applications and tools for Mac that make it especially convenient.

iA Writer — Writing

iA Writer is often regarded as the very best minimalistic text editor available for Mac. The focus mode is brilliant and the typeface is perfect for writing. I also like the way the HTML exports from iA Writer look. However, as part of its minimalistic approach, it really lacks features and customization. Even the font size cannot be changed.

TextMate — Writing

Because iA Writer doesn’t allow for the changing of font size (and it the font size is rather large), I use TextMate with the Solarized style to write long documents (ex. documentation, long blog posts, etc.) rather than iA Writer. The plethora of text wrangling features in TextMate also make it a breeze to perform actions like indenting large blocks of code. TextMate can also export and preview Markdown with HTML, but I prefer using Marked for those functions. TextMate can also open entire folders of files at once. This makes writing Markdown easier in cases involving multiple files (ex. writing Markdoc).

Sublime Text 2 is a very popular alternative to TextMate (especially since TextMate 2 was not very well received).

TextSoap — Text Wrangling

I use TextSoap in conjunction with all of my Markdown text editors. I have created a variety of “cleaners” that help me quickly add Markdown line breaks, add bullets, and perform other handy Markdown edits.

Marked — Previewing and Exporting

Marked is currently my favorite Markdown preview and export application. I used to use Mou, but Marked has since taken its place. Marked supports exporting into a wide variety of formats, including RTF and HTML. It also allows for custom CSS stylesheets to be added. Perhaps the best feature is the automatically updating preview. When I edit text in iA Writer, the preview is updated in Marked with an indicator showing the latest change, without me even having to save the file in iA Writer.

I really like the Solarized color palette. I found some CSS stylesheets that may be added to Marked to export Solarized-looking HTML. It isn’t a perfect adaptation though, and some of the font and color choices bother me a little bit, but nonetheless, it has more or less the same colors as Solarized.

Day One — Organizing and Writing

I use Day One, developed by Bloom Built, to keep notes, links, journal entries, etc. Entires are written in Markdown. It’s ability to organize entries chronologically and its automatic timestamping is nice. The new photo feature is useful as well.

TextExpander — Text Wrangling

I have a variety of TextExpander macros or “snippets” that assist in inserting certain Markdown elements (like tables), especially those with parameters that need to be changed each time (ex. the column headings for tables). It really saves a lot of typing.

Beginning iOS Development with Apache Cordova

October 1st, 2012

A quick guide to installing and beginning to develop with Apache Cordova on Mac.

  1. Download Phonegap
  2. Unzip the archive. Move the folder to a permanent location.
  3. Open the folder, go to the lib folder, go to iOS folder, go to the bin folder.
  4. Open up a Terminal window.
  5. Drag the create executable into the Terminal window. Type in the location of where you would like your project created. Type in the identifier for your project (ex. com.christophersu.project). Type in the name of your project. Hit enter. Example of what this should look like: Christopher-Su:~ christophersu$ /Users/christophersu/Code/phonegap/lib/ios/bin/create ~/Code/ExampleProject com.christophersu.ExampleProject ExampleProject
  6. Type in cd followed by the path to your project (ex. Christopher-Su:~ christophersu$ cd ~/Code/ExampleProject)
  7. Type in cordova/debug to run the debug executable and build your project.
  8. To emulate or simulate your project from the command line, run the cordova/emulate executable. Note that this requires ios-sim to be installed (see below).

If you get an error telling you to install ios-sim when running the emulate executable, this is the fastest way to install ios-sim:

  1. Run ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)" in Terminal. This installs Homebrew.
  2. Run brew install ios-sim. Wait for it to complete.

That’s it! Output should look like this:

Christopher-Su:~ christophersu$ brew install ios-sim
==> Downloading https://github.com/phonegap/ios-sim/tarball/1.5
######################################################################## 100.0%
==> rake install prefix=/usr/local/Cellar/ios-sim/1.5
/usr/local/Cellar/ios-sim/1.5: 4 files, 76K, built in 10 seconds
Christopher-Su:~ christophersu$

Playing with WordPress: Categories, Tags, Simply Exclude, and Page Templates

September 17th, 2012

Convert Categories to Tags and Vice Versa

  1. Go to the WordPress dashboard
  2. Go to Tools > Import
  3. Choose the “Categories and Tags Converter”
  4. Install it through the prompt
  5. Select which categories you wish to convert to tags (or click at the top to switch to converting tags to categories) and confirm

Exclude Categories and Tags from the Home Page

  1. Install the “Simply Exclude” plugin
  2. Set Home Page from the default “Include only” to “Exclude” in the “Simply Exclude” settings
  3. Go to the categories section of the WordPress dashboard
  4. Check the checkboxes next to which sections you would like to exclude from the home page

Note: it is also possible to do this by editing the WordPress functions.php file.

Create a Page with Full Text Posts from One Category

  1. Go to the WordPress dashboard, Appearance > Editor
  2. Open up your “loop.php” file, or the file that contains your while loop with has_posts
  3. Copy that, and paste it into a new php file titled name-of-your-page-template.php
  4. After get_header(); add query_posts('cat=13');, replace 13 with the ID of the category or categories you want
  5. Find the if-statement containing is_search and replace the_excerpt(); with the_content();
  6. Upload your php file into your theme directory
  7. Create a new page in WordPress, set it to the page template you just created, and publish it

Starting Out with the Yii PHP Framework

September 3rd, 2012

Developers are quickly switching from older frameworks like CodeIgniter to Yii, which allows for quicker deployment of PHP web applications. Here are some steps to get started with Yii on Mac:

  1. Download the Yii framework.
  2. Unarchive the download, enter your command line of choice, and run chmod -R 755 on the directory to make the necessary files accessible and executable.
  3. cd into the framework folder and run this command:

    $ yiic webapp your/htdocs/location
  4. Now you’ve created a “skeleton” for your web application. Start up your Apache server, if you haven’t already, and open the webpage that you chose before. Ex: http://localhost/your/location/index.php.

  5. You should see the Yii welcome page. Now open your/location/protected/config/main.php in your text editor and add this to the configuration:

    return array(
        ......
        'import'=>array(
            'application.models.',
            'application.components.',
        ),
    
        'modules'=>array(
            'gii'=>array(
                'class'=>'system.gii.GiiModule',
                'password'=>'enter-a-password-here',
            ),
        ),
    );
  6. Point your web browser to http://localhost/your/location/index.php?r=gii and open the Model Generator.

  7. Use Yii to generate code for a model with the Table Name tbl_user and the Model Class User.
  8. In the sidebar, select the CRUD Generator to generate code to implement CRUD operations. Create code for the Model Class User and the Controller ID user. Once again preview and generate the code.
  9. Now, if you open http://localhost/your/location/index.php?r=user in your web browser, you should see a list of all the entries in the default tbl_user database table.
  10. Go to http://localhost/your/location/index.php?r=user/admin (the admin function of the user class) and log in using the gii password you choose earlier (in the main configuration file). From here, you can perform the various CRUD operations such as listing, editing, and creating entries in the database.

Yii allows for the quick development of PHP applications by simplifying processes such as writing code to perform CRUD operations by generating the code for you.

Migrating iOS Certificates and Profiles

September 1st, 2012

Moving iOS developer and distribution certificates and provisioning profiles from one computer to another is a simple process, but it may end up being a real pain if done incorrectly.

Exporting Certificates from Keychain

Follow these steps on your old computer to export your certificates:

  1. Open Keychain Access.
  2. Right click on your developer certificate.
  3. Select “Export”, choose the Personal Information Exchange (.p12) format, set a password, and choose a location to export your certificates to.
  4. Repeat steps two and three for your distribution profile.

Don’t worry about moving provisioning profiles for now, Xcode 4 has some handy feature to help with that.

Importing Certificates

On your new computer, ensure you set up your system and Xcode with your developer Apple ID.

  1. Open Keychain access and go to File, Import and select your exported certificates.
  2. Enter the password you set earlier to import your certificates. This may take some time.
  3. Open Xcode after importing your certificates and open the organizer (Command+Shift+2).
  4. Check that your Teams and their respective certificates appear in the organizer’s sidebar.

Importing Provisioning Profiles

This is the easiest part. After you’ve confirmed that your certificates are seen by Xcode, simply go to the Provisioning Profiles tab in the organizer sidebar, press the glorious refresh button in the bottom right corner, enter your Apple ID credentials, and wait for Xcode to sync up your profiles.

Xcode Organizer Refresh Provisioning Profiles

Acquiring Past Growl Notifications in Shell

September 1st, 2012

As of version 1.3, Growl stores recent notifications in its history. Should you ever need to access these entries via shell script (ex. checking every once and a while using a cronjob to performs certain tasks should a certain growl notification appear), it is quite easy to access this history.

Growl’s history is stored in an SQLite database in its application support folder: /Users/christophersu/Library/Application Support/Growl/notifications.history. The entries can be easily read from this database in shell using sqlite3:

Depending on what part of the notification you want (each one has a title and body), you may want to request more information by adding more behind ZTITLE in SELECT ZTITLE FROM ZNOTIFICATION. I didn’t want all of the entries in the database, but if you do, you can remove the tail -5 at the end, or alter its parameters to meet your needs. You can also use other SQL commands, such as WHERE if you only want entries in the database that meet specific requirements (although I prefer to filter them out in shell).

Importing Plain Text Files into Day One with Date Created

September 1st, 2012

Prior to using Day One to organize my notes, I used nvALT coupled with iA Writer and other various Markdown editors. After deciding I wanted some more organization, security, syncing, and other features, I took the leap and switched to Day One. Importing all of my plain text files into Day One was rather annoying. Here are the steps I had to take (I also created a project on GitHub for anyone who’s interested in the exact code I used):

  1. Copy all of my notes into a new folder (extra precaution, didn’t want to mess with the originals, this later proved to be a good idea).
  2. Make an Automator workflow to run a TextSoap cleaner on all files in a directory.
  3. Write a TextSoap cleaner to convert my dailies markdown (iA Writer allowed for sloppier Markdown) to Day One markdown (this was a lot of trial and error as I would constantly find new things that needed to be changed).
  4. Create a shell script to change the timestamps on the new files back to the original timestamps (when you copy the files, they retain their original creation date, but after running the TextSoap cleaner, it changes to today).
  5. Create a shell script to import them all into Day One via the Day One command line interface.

Dropbox on Linux

August 31st, 2012

Should you ever need to another way to store and save files from your server besides, downloading them directly (ex. your internet is too slow), you can send them to Dropbox.

Installing Dropbox

This part is quite simple. Enter your user home directory, download, and unarchive Dropbox for Linux:

cd ~
wget -O dropbox.tar.gz "http://www.dropbox.com/download/?plat=lnx.x86"
tar -tzf dropbox.tar.gz     
tar -xvzf dropbox.tar.gz

This should create a folder titled .dropbox_dist in your home directory. This is for Dropbox for Linux itself lives, but your files will be stored in ~/Dropbox (so don’t worry or move it!).

Setting up Dropbox

Open up the Dropbox client with this:

~/.dropbox-dist/dropboxd

This will give you a link and some instructions to follow. Open the link provided to link your server as “computer” on your Dropbox account. After linking your account, close the client by pressing control+C.

Sending Files to Dropbox

Move files you want to backup or send to dropbox by using the mv command to move them to ~/Dropbox. I sometimes send encrypted archives and MySQL dumps to Dropbox for backup purposes.

After moving your files, open Dropbox and keep it open in the background using this:

~/.dropbox-dist/dropboxd &

It will automatically begin syncing your ~/Dropbox folder with your account. I have noticed that dropboxd takes up quite a bit of processing power though. I suspect it’s indexing and checking which files were updated and need to be uploaded or updated.