Deleting Unversioned SVN Files

Here’s a silly bash trick that will delete all unversioned SVN files

svn st | grep "^?" | sed s/?[[:space:]]*// | xargs rm -rf

Use with care, obviously. If there’s a more concise method, please let me know.

And here’s how you might use similar commands to apply fmresolve to all conflicted files, and then resolve them.

for f in $(svn st | grep "^C" | sed s/C[[:space:]]*//); do fmresolve $f; done
svn st | grep "^C" | sed s/C[[:space:]]*// | xargs svn resolved

Active Record Model Adapters

I recently refactored some code in iNaturalist that fetches taxon names from external name providers like uBio and the Catalogue of Life. They return names and classification data that are similar but (of course) not identical to ActiveRecord models we use in iNat, so I figured I’d write adapters for them, and I thought a really smart solution would be to subclass the models themselves, simply overriding the attributes with getters that mined a private instance variable holding an XML response from one of the web services. Big mistake. ActiveRecord mixes in all kinds of magic into the models that doesn’t necessarily get passed on to child classes. I ran into all sorts of fun errors and problems until I remembered the Adapter implementation described here, which takes a much more sensible approach: don’t sublcass, and instead hold an internal copy of the adaptee, passing calls to anything you don’t want to override to the adaptee.

Read the rest of this entry »

Git Cheatsheet

It’s small, fast, and github is rad. So I am trying to learn it.

# Setup
git config --global --list
git config --global user.name "Ken-ichi"
git config --global user.email "fortinbras@norway.net"
 
# The colors, children.  Mm-hey
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
 
# Getting Info
git remote -v # Display the remote repository URL
git log # duh
git show COMMIT # equivalent of svn log -r REV_NUM, but with diffs
 
# Committing
git add .
git commit -a
 
# Amending
git commit -a --amend
 
# Reverting
git reset --hard HEAD # revert everything to HEAD
git checkout path/to/file # reset a single file
 
# Checking out previous states
git checkout COMMIT
git checkout master # to get back
 
# Stashing
git stash # stash changes on this branch so you can switch and work on something else
git stash pop # bring back the stashed changes
 
# Pushing to another repos
# could be local like /path/to/somewhere 
# or ssh://me@there.net/path/to/repos
git push path/to/repos
git push origin master # if you cloned from a remote named origin
 
# to switch origins
git remote rm origin
git remote add origin 'path/to/a/bare/repo'
 
# note that when sharing a repo with others, you will all want to push/pull from a *bare* repo made with 
git clone --bare path/to/repo
# See http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#public-repositories
 
# Branching and merging
git branch new_branch && git checkout new_branch # make a new branch and switch to it
git checkout -b new_branch # same as above
git diff master..new_branch # diff two branches
git merge other_branch
git mergetool -t opendiff # resolve conflicts in a merge with FileMerge
 
# Adding a submodule
git submodule init
git submodule add path/to/remote/repo path/to/local/checkout
git submodule update
git commit -m "I just added a submodule"
 
# Updating a submodule
cd path/to/local/checkout
git pull origin master # or wherever you're pulling from
cd ../back/to/main/repo
git submodule update
git commit -m "I just updated a submodule"

GoodReads iPhone App

This may already exist in some form, but here’s an imaginary feature list:

  • adds to GoodReads library based on a photo of a bar code and/or ISBN
  • page-based annotations based on photo or entry of page #, including word-lookups, favorite words, or just random notes
  • maybe you could print out a bookmark with a barcode for a given book, and when you want to leave a note for the book your reading, you use your iPhone to scan the bar code first

I usually have a bookmark and pen by my side as I read, and I keep note of cool or unknown words, choice quotes, or whatever thoughts occur to me while reading.  I don’t think the iPhone can really serve as a replacement (too thick, too expensive), but it might make for an interesting way to enhance social reading sites like GoodReads, Shelfari, or LibraryThing.

There is a small, seasonal creek that runs through the Temescal Farmer’s market.  As far as I can tell, it runs above ground from around Frog Park, under CA-24, down to around 51st St.  It only seems to run in the summer, and kids at the market play poohsticks and splash around in it.  I have found this stream confusing for a while and have a few questions

  • where does it come from?
  • why does flow in summer?
  • is it really safe for children?

My Ubuntu Cheat Sheet

Looks like I’m maintaining an Ubuntu server these days…

Package Management

# Finding Installed Dependent Packages
apt-cache rdepends --installed packageX
 
# Installing Individual .deb Packages
sudo dpkg -i package_file.deb
 
# Ubuntu version info
cat /etc/lsb-release

Trust not to aptitude…

Sometimes aptitude does silly things, like install X11 when all you wanted was ImageMagick. Try apt-get as well to see if it doesn’t have a different set of deps (this is true of ImageMagick as of December 2008).

Someone asked this among a group of perfectly intelligent UC Berkeley staffers and no one had a good answer, so I think this is a good exscuse to start using this blog in one of the ways I originally intended it: answering my own questions.  More to come…

Answer

First of all, not all of California has a Mediterranean climate. A Mediterranean climate is one in which summers are hot and dry and winters are mild and rainy, similar to the regions bordering the Mediterranean Sea. These conditions exist in CA from about Cape Medocino south to Baja, and east to the Sierra Foothills.

Read the rest of this entry »

I’m just getting started with git.  Turns out if your git binaries are in a path specified in something like .bash_profile on your remote machine, something like git clone ssh://you.com/~you/repos.git will fail with an error like bash: git-upload-pack: command not found because sshd ignores .bash_profile, so git won’t find its binaries. So you need to alter the PATH env var in .bashrc instead. Fun.  The git-clone-pack man page is worth a look.

Django 1.0 is coming, and it’s bringing needed but backwards-incompatible changes to the admin site, ostensibly the best thing about Django.  One problem I’ve run into while migrating to the new version is inline editing of related classes in existing classes.  For example, it’s pretty common (and recommended) to “extend” Django’s built-in User model by creating your own, related Profile model.  For the old admin site, you specified the ability to edit a relate Profile in the User form in the Profile model:

class Profile(models.Model):
    user = models.ForeignKey(User, unique=True, edit_inline=True)

That was simple, but kinda quirky. Changing the way the User form looks by changing the related Profile model? Weird. BUT, it did let you make changes to the User model w/o mucking with the built in Django code.

The new way of doing things is to specify all your admin site options in a separate file, and inline editing is now a little more reasonable: if you want to edit related objects in a model’s form, you specify that in that model’s admin options. But this means you need to alter Django’s built-in User model’s admin options, which could mean muckiness. So here’s what I did in my myapp/admin.py:

from django.contrib import admin
from django.contrib.auth.models import User
from myapp.models import *
 
class ProfileAdmin(admin.ModelAdmin):
    # just some stuff for my profile forms
    filter_horizontal = ('teams',)
    radio_fields = {'appointment': admin.HORIZONTAL}
    list_display = ('user', 'picture', 'appointment', 'affiliation')
admin.site.register(Profile, ProfileAdmin)
 
# need to make an inline class...  ick
class ProfileInline(admin.StackedInline):
    model = Profile
    max_num = 1
 
# the meat: grab the existing UserAdmin class, modify it, unregister User,
# and re-register User with the modified UserAdmin
UserAdmin = admin.site._registry[User].__class__
UserAdmin.inlines = [ProfileInline,]
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

Took me a while to realize admin.site._registry held instances of the ModelAdmin classes, not the classes themselves. This technique also assumes that User gets registered with the admin site before you run this code. I’m guessing the order in which admin.autodiscover() registers models is the same as the INSTALLED_APPS setting in settings.py.

In case you’re working through Developing Facebook Platform Applications with Rails, you might have run into problems with authenticity tokens and FBML forms.  Quick dumb fix to save you 2 seconds:

<fb:fbml>
  <fb:request-form
    action="<%= new_invitation_path %>"
    method="POST"
    invite="true"
    type="Karate Poke"
    content="YAYS I added this facebbok app">
    <fb:multi-friend-selector
      showborder="false"
      actiontext="Invite your friends to use Karate Poke"
    />
    <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
  </fb:request-form>
</fb:fbml>