Quick SVN "mergeinfo" Log Inspector

Posted on

We use Subversion branches to separate development (dev) and production (trunk) code. Eventually we want to move these features and bug fixes from dev to trunk. I wrote this stupid simple script to figure out which revisions from dev have not been merged into trunk.

#!/usr/bin/env php
<?php

$repo  = '[SVN_REPO_URL]';
$dev   = $repo . '/dev/';
$trunk = $repo . '/trunk/';

$revs = shell_exec(sprintf('svn mergeinfo --show-revs eligible %s %s', escapeshellarg($dev), escapeshellarg($trunk)));
$revs = explode(PHP_EOL, str_replace('r', '', trim($revs)));

foreach ($revs as $rev) {
    system(sprintf('svn log -v -r %s %s', escapeshellarg($rev), escapeshellarg($repo)));
}

Hacker News Saved Stories

Posted on

For the Favorites section of my site I wanted to centralize all the stars/bookmarks I was collecting all over the web. Most sites and services have APIs to make gathering this data easy. Hacker News, not so much.

Luckily Hacker News' markup is pretty simple to navigate. I wanted to share a quick script to grab "Saved Stories" from HN. The script depends on @fabpot's Goutte.

<?php

require_once __DIR__.'/vendor/autoload.php';

$username = 'YourUsername';
$password = 'YourPassword';
$client = new \Goutte\Client();

$baseUrl = 'http://news.ycombinator.com/';
$savedStoriesUrl = $baseUrl . 'saved?id=' . $username;

/** @var $crawler \Symfony\Component\DomCrawler\Crawler */
$crawler = $client->request('GET', $baseUrl);

/** @var $link \Symfony\Component\DomCrawler\Link */
$link    = $crawler->selectLink('login')->link();
$crawler = $client->click($link);

/** @var $form \Symfony\Component\DomCrawler\Form */
$form    = $crawler->selectButton('login')->form();
$crawler = $client->submit($form, array(
    'u' => $username,
    'p' => $password,
));

/** @var $crawler \Symfony\Component\DomCrawler\Crawler */
$crawler = $client->request('GET', $savedStoriesUrl);

/** @var $linkRows \Symfony\Component\DomCrawler\Crawler */
$linkRows = $crawler->filter('td.title a');

/** @var $commentRows \Symfony\Component\DomCrawler\Crawler */
$commentRows = $crawler->filter('td.subtext a');

$stories = array();

foreach ($linkRows as $i => $row) {
    /** @var $row \DOMElement */

    $commentLinkPosition = (($i * 2) + 1);

    /** @var $comment \Symfony\Component\DomCrawler\Crawler */
    $comment = $commentRows->eq($commentLinkPosition);

    if ($comment->count() > 0 && $row->nodeValue != 'More') {
        $stories[] = array(
            'title'       => $row->nodeValue,
            'link'        => $row->getAttribute('href'),
            'comment'     => $comment->text(),
            'commentLink' => $baseUrl . $comment->attr('href'),
        );
    }
}

print_r($stories);

Sublime Text 2 Convert?

Posted on

This weekend I spent some time tooling around with Sublime Text 2. Coming from Netbeans, I felt pretty liberated when I started to realized the amount of customization and hackability ST2 offered. Sublime Text 2 plugins are written in Python. I've written some Python in the past to code up small utilities and one liners that would have been way more verbose in PHP. Overall the implementing this functionality was pretty easy, would be even easier for a Python guru.

My first order of business was to implement a plugin that I have longed for in Netbeans but never had the sack to attempt. I usually develop/edit files locally and rsync them to a vm. In the past I used the build functionality in Netbeans to execute the rsync script I prepared. I'd prefer this to happen automatically on save.

I'd like to introduce my first ST2 plugin, Sublime Dev Rsync. The gist of the plugin is to run an rsync command for your project triggered by the on_post_save event. You can configure this rsync command per-project using the dev_rsync.json file. Check out the readme in the GitHub repository.

Some of the other things I like about ST2:

  • Much lighter memory footprint
  • Faster start up
  • Use the same editor for editing one-off files as whole projects
  • Community has some great traction
  • Does not require Java
  • Python plugin API
  • Cross-platform (Netbeans is too)

Cons:

  • Not open source or free ($59)
  • Future could be uncertain, à la TextMate 2
  • Not an IDE. But I think there are some interesting features that ST2 offers that will alleviate the pain of not having an IDE at your fingertips.

Sublime Text 2 links:

OSX Screenshot to Dropbox Tool

Posted on

My buddy Jordan and I like to hack on small utilities at work. Not too long ago we came up with a simple tool that will quickly allow you to take a screenshot in OSX and put it in Dropbox's public folder. The script will also copy the public shortened URL into your clipboard for quick use in a tweet, IM, or email!

You can clone the latest script here: https://gist.github.com/1051544

#!/bin/bash

DATE=$(date +"%Y-%m-%d");
TIME=$(date +"%I.%M.%S");
AMPM=$(date +"%p");
FILENAME=Screen\ shot\ $DATE\ at\ $TIME\ $AMPM.png;

# You can export you DROPBOX_USER_ID in your .profile
# or hardcode it here by replacing YOURDROPBOXUSERID
DB_USER_ID=${DROPBOX_USER_ID-YOURDROPBOXUSERID};
# Make sure you create the Screenshots directory in
# your public directory
DB_BASE_DIR=~/Dropbox/Public/Screenshots;
DB_BASE_URL=http://dl.dropbox.com/u;

screencapture -i "$DB_BASE_DIR/$FILENAME";

# user may have escaped out of the screencapture
if [ -f "$DB_BASE_DIR/$FILENAME" ];
then
    URL_FILENAME=$(python -c "import urllib; print urllib.quote('''$FILENAME''')");
    URL_LONG="$DB_BASE_URL/$DB_USER_ID/Screenshots/$URL_FILENAME";
    URL_SHORT=$(curl https://www.googleapis.com/urlshortener/v1/url -H 'Content-Type: application/json' -d "{\"longUrl\": \"$URL_LONG\"}" 2>/dev/null | grep goo.gl | cut -f 4 -d '"');

    if [ -z "$URL_SHORT" ]; then
        echo $URL_LONG | pbcopy;
    else
        echo $URL_SHORT | pbcopy;
    fi
fi

2010 Macbook Pro Woes

Posted on

So I purchased a Macbook Pro built-to-order back in May 2010. This computer has been rock solid up until a couple weeks ago. I installed Lion mid July this year. It has been running great until 10.7.2, I have experience what I think is described here. Not long after Apple acknowledged that issue, I have been experiencing serious memory malfunctions. I installed a 8GB Crucial RAM kit at the beginning of August. So the only modification I made to the laptop is my memory upgrade.

It became completely unusable on October 13th. I would fire it up and start a task, like syncing pictures to S3 via Transmit. This task would run great for some time and then the screen would go black and it would become unresponsive.

Today I had some free time, I decided to try to use it. I started it up. As soon as I turned it on I had 3 beeps of death. After Googling around a bit I found out that 3 beeps meant "no good banks". Next I figured I would open it up and put in the original 4GB of RAM. Success! I was able to use the computer normally for a few minutes. I shut it down. Powered it back on, "beep, beep, beep". Oh man.

So I have an appointment at the local Apple Store tomorrow. I'll report back after that.

Update: Oct 17

After talking with the Apple Store guys yesterday we determined that I will need a new logic board. I am not sending my hard drive in for repair. So at the moment I am waiting on some new equipment to do a proper back up and format before I send it into Apple.

I am still a little curious about the sequence of events that lead to my current situation, which seems to be a complete hardware failure. Let's recap:

  • May 2010 - Purchased 15" Macbook Pro
  • July 2011 - Installed Lion
  • August 2011 - Installed 8GB Crucial RAM
  • October 2011 - Experiencing random lockups
  • October 2011 - Began experiencing these symptoms
  • October 2011 - Flat out could not use my machine.

So what seemed to start out as a software issue quickly became a hardware issue. Now I guess I could be wrong and this was a hardware issue from the beginning, but it seems the symptoms continuously got worse.

Next step I have to take care of is to backup important files on my MBP's hard drive. I got a big bare OEM drive and hard drive dock from Amazon.

I will then zero out the drive with Disk Utility and take the laptop back to the Apple Store.

Update: Oct 19

Data is backed up and my harddrive is zeroed out. I will drop my laptop off at the Apple Store tonight to send in for repair.

Hello

Posted on

I decided to create a super simple blog engine using Silex and XML. I wanted a place that I owned and operated where I could post thoughts, links, and pictures. I did not need a big and heavy blog engine.

To keep things as simple as posible I am storing each post in a XML file as opposed to a row or document in a database. The file name is simply [unix epoch].xml. Each post contains a created timestamp, title, and body. The body is using Markdown. I am using a PHP Markdown library to process the bodies into HTML before I cache them in memory. Everytime I deploy the blog I refresh the cache. For now I am using APC's user cache to store all the posts as PHP objects.

There are a few benefits here that I see.

  1. My posts are versioned along with my codebase in git.
  2. Dev and prod have the same posts, no database to sync.
  3. Features are easy to add by simply adding to the XML tree.
  4. Markdown!

I'll report in after a few posts.