Git Today

I have updated the script to show the correct output. Currently filtering by user is broken. (Sorry!)

Recently, my friend Jonas was wondering how one might go about showing a diff of all the work they’ve done in a day. Turns out, it’s not that straight foward.

What did I do yesterday?

This is exactly what git-today does. Optionally you can also look at what other people have done, and change the timeframe too.

By default (with no arguments) git-today will show you everything you have done in the last day. General usage:

git today [arguments...]

Arguments:
  -h
    Show this help.

  -u
    User to find diff for. Default is current user.

  -s
    Date to search since. Default is the last day.

Examples:
  git today

  git today -s "14 days ago"

  git today -u some@email.tld

  git today -s "7 days ago" -u person@email.tld

Get It

 

#!/usr/bin/env zsh
# git-today
# Written by: Gianni Chiappetta <gianni@runlevel6.org>
# Requires: git 1.7.5+, zsh 4.3.11+

function get_user { git config user.email }

function git_branch() {
  ref=$(git symbolic-ref HEAD 2> /dev/null) || return
  echo ${ref#refs/heads/}
}

# Command normalisation
branch_name="git-today-tmp"
cmd="go"
user=$(get_user)
since="1 day ago"

while getopts "hu:s:" option
do
  case $option in
    h)
      cmd="help"
      ;;
    u)
      user=$OPTARG
      ;;
    s)
      since=$OPTARG
      ;;
    ?)
      cmd="help"
      ;;
  esac
done
# Help
read -d '' help_text <<"EOS"
Git Today - Show one big diff of the work you have done in the past day.
Written by: Gianni Chiappetta <gianni@runlevel6.org>

Usage:
  git today [arguments...]

  Arguments:
    -h
      Show this help.

    -u
      User to find diff for. Default is current user. *Currently broken*

    -s
      Date to search since. Default is the last day.

  Examples:
    git today

    git today -s "14 days ago"

    git today -u some@email.tld

    git today -s "7 days ago" -u person@email.tld
EOS
# Meat... mmm
if [[ $cmd = 'help' ]]; then
  echo $help_text
  return
elif [[ $cmd = 'go' ]]; then
  eval $'commits=( ${(s.\n.)"$(git log --pretty="%H %ae" --since="$since" | grep $user | grep -oE \'^[a-f0-9]+\')"} )'

  if [ ${#commits} -eq 1 ]; then
    if [ -z $commits ]; then
      echo "No commits!"
    else
      git show $commits
    fi
  else
    orig=$(git_branch)
    git branch -d $branch_name &> /dev/null
    git branch $branch_name $orig &> /dev/null
    git checkout $branch_name &> /dev/null
    git reset --soft $commits[-1] &> /dev/null
    git diff --staged
    git reset --hard $orig &> /dev/null
    git checkout $orig &> /dev/null
    git branch -d $branch_name &> /dev/null
  fi
fi

# vim: set filetype=zsh :

 

Android Gingerbread on WIND Mobile

Not so long ago I purchased a Nexus S for use on WIND Mobile. First off, it’s a great phone and I recommend it to everyone. As well Gingerbread is a must, none of that < 2.3 crap. However I did have a bit of trouble getting my mobile data and MMS messaging working at the same time, so I thought I’d save you some time and post my settings here.

APN Settings

To get everything working probably, you’ll have to create two APNs. First up, go to your APN settings at Settings > Wireless & networks > Mobile networks > Access Point Names.

The first APN you create will be for your data. It should have the following settings:

 

Name:     WIND
APN:      internet.windmobile.ca
MCC:      302
MNC:      490
APN type: default

The second APN will be for your MMS messages. It should have the following settings:

 

Name:      MMS
APN:       mms.windmobile.ca
MMSC:      http://mms.windmobile.ca
MMS proxy: 74.115.197.70
MMS port:  8080
MCC:       302
MNC:       490
APN type:  mms

BOOM! Did you are unimpressed? and now?

How-To: Conditional HTML tag with HAML

Many of you may have probably seen Paul Irish’s clever conditional <html> tag solution which is now part of HTML5 Boilerplate. Yet you may be left wondering how to do this in your HAML templates without making a big mess. Luckily, I’ve written a simple Rails/Padrino helper for you!

Helper

def conditional_html( lang = "en", &block )
  haml_concat Haml::Util::html_safe <<-"HTML".gsub( /^\s+/, '' )
    <!--[if lt IE 7 ]>              <html lang="#{lang}" class="no-js ie6"> <![endif]-->
    <!--[if IE 7 ]>                 <html lang="#{lang}" class="no-js ie7"> <![endif]-->
    <!--[if IE 8 ]>                 <html lang="#{lang}" class="no-js ie8"> <![endif]-->
    <!--[if IE 9 ]>                 <html lang="#{lang}" class="no-js ie9"> <![endif]-->
    <!--[if (gte IE 9)|!(IE)]><!--> <html lang="#{lang}" class="no-js"> <!--<![endif]-->      
  HTML
  haml_concat capture( &block ) << Haml::Util::html_safe( "\n</html>" ) if block_given?
end

Note: For Padrino you’ll have to replace haml_concat with concat_content and capture with capture_html.

Usage

You can choose to pass it a block or not, personally, I prefer not to. Less indenting == more win, as well, the closing </html> tag is optional.

!!! 5

- conditional_html 'en-CA'

%head
  %title Website

%body
  = yield

 

peg.vim

Parsing Expression Grammars in Vim

Recently I’ve been doing quite a bit of work with Parsing Expression Grammars (or PEG for short). They’re very powerful tools for matching complex patterns. Inimino’s PanPG is the awesome PEG library I’ve been working with to make some cool stuff (you should check it out!). Anyway, lack of syntax highlighting in Vim has caused me to overlook small errors at times, this has prompted me to write peg.vim, a syntax definition for vim.

Get It

I recommend using pathogen to install peg.vim as a bundle.

You can grab the latest version from the peg.vim Github repo.

Here’s what it looks like in my colour scheme:

 

Screenshot

Javascript Experiments – Executable Instances

This is a proof-of-concept for executable child instances in Javascript. This’ll only work in VMs that support the non-standard __proto__ (so not IE). I’ve tested it in node.

Implementation

Here’s the implementation:

/* ------------------------------ Main Class ------------------------------ */
// Returns "instances" of itself which are actually functions.
function User ( username ) { var Parent, scope
  function Scope () {
    // Here is where you put your normal constructor junk
    this.username = username
    this.colours = [ 'yellow', 0xFF ]
  }

  // Magic
  function Proxy() {
    Scope.prototype.init.apply( scope, arguments )
  }
  Parent = arguments.callee
  function Dummy() {}
  Dummy.prototype = Parent.prototype
  Scope.prototype = new Dummy()
  scope = new Scope()
  Proxy.__proto__ = scope
  
  // Go time!
  return Proxy
}

User.prototype.init = function( username ) {
  this.username = username
  console.log( 'My name is now: ' + this.username + '.' )
}

User.prototype.lol = function() {
  console.log( '"' + this.username + '" is a silly name!' )
}

Explanation

It might seem a little tricky at first glance, but it’s pretty straight forward. Scope is the context of the instances. Parent is a reference to the “current” class (in this case it’s User). Dummy is simply used for prototype chaining (Scope is chained to Parent). Proxy is where the real magic happens. Proxy is a normal function which, when executed, calls the Parent.prototype.init function in the correct context. As well it’s __proto__ is set to that of the current instance. This is the crucial part as it allows Proxy to still act like a function and a plain object at the same time.

Demo

/* ------------------------------ Demo ------------------------------ */
var b = User( 'Ben' )

console.log( b.username ) // Ben
console.log( b.colours )  // [ 'yellow', 255 ]

b.lol()                   // "Ben" is a silly name!
b( 'Benne' )              // My name is now: Benne.
b.lol()                   // "Benne" is a silly name!

Caveats

  • Requires non-standard __proto__
  • Cannot be used with new keyword
  • Not very useful?

Case Sensitive to Insensitive

Today I was about to format my computer, but first I had to backup my files. So I dragged my home folder over to an external hard drive. Turns out the external drive was formatted as case-insensitive and my internal drive is case-sensitive (the true UNIX way). Anyway, the transfer failed because many of my files had the same name, just different case. I freaked out and thought that this would be impossible to fix. But then I remembered that I was a programmer, so I quickly wrote a couple ruby scripts to quickly find files with conflicting names.

I thought some of you might find these useful, so I’m posting them here:

Code

casechecker.rb

#!/usr/bin/env ruby -w

def find_caseinsensitive_duplicates(dir)
  # INIT
  conflicts = {}
  
  # Load file list
  files = Dir.entries(dir).collect{|f| f.downcase }
  
  # Do yo thang!
  files.each do |f|
    files.each do |o|
      if f == o
        conflicts[f].nil? ? conflicts[f] = 1 : conflicts[f] += 1
      end
    end
  end
  
  conflicts = conflicts.delete_if{|w, o| o == 1}
  
  if conflicts.empty?
    puts "You're good to go! [#{dir}]"
  else
    puts "Conflicts found! [#{dir}]"
    conflicts.sort.each do |c|
      puts "conflict found on '#{c[0]}'"
    end
    puts "\n#{conflicts.length} conflict(s) in total."
  end
end

# Main
if $0 == __FILE__
  find_caseinsensitive_duplicates(ARGV[0] || Dir.pwd)
end

casechecker_recursive.rb

#!/usr/bin/env ruby -w

require "casechecker"

def recursively_find_caseinsensitive_duplicates(dir)
  Dir.entries(dir).each do |file|
    unless ["..", "."].include? file
      new_path = File.join(dir, file)
      recursively_find_caseinsensitive_duplicates(new_path) if File.directory? new_path
    end
  end
  find_caseinsensitive_duplicates dir
end

# Main
if $0 == __FILE__
  recursively_find_caseinsensitive_duplicates(ARGV[0] || Dir.pwd)
end

Usage

./casechecker_recursive.rb /path/to/directory

PS

Never format your Mac as case-sensitive, you’ll have major compatibility issues. Trust me.

LanSchool Threatens Compsci.ca

LanSchool, publisher of “classroom management solutions”, has threatened to take legal action against Dan and Tony (founders of the massively popular compsci.ca), for publishing a review and proof-of-concept exploit for an old version of their software over two years ago.

When the exploit was discovered in early 2006, Dan (one of the founders of compsci.ca) promptly notified the developers of the LanSchool application. LanSchool disregarded his discovery, and told Dan that his school could take action against him in the form of suspension, detention, &c… As such, after a period of time, a review of LanSchool including a proof-of-concept exploit was published online at compsci.ca.

Fast forward to 2008, LanSchool has released a new version of their self-titled software; exploit fixed. However, they have now decided to take legal action against compsci.ca. Their claims and demands are as follows:

Claims

  1. “unauthorized use of its trade-mark” — even though they have no registered trademark in Canada.
  2. “unauthorized use of its logo” — using their logo to refer to the company should fall under fair use.
  3. “In other postings you offer detailed advice about how to use “LanSchooled” to breach the security inherent in our client’s software.” — but earlier in the document they stated “you identified and made LanSchool aware of a potential security flaw in LanSchool version 6.5 (which does not exist in the current version 7.1).”
  4. “you describe our client’s software as a “trojan horse type program that is used by many school boards in Ontario to spy on their students as well as controlling one or all computers in a given lab … LanSchool has many flaws in its design, and thus many security holes…” — this would amount to defamation only if the statement was untrue. Though considering that LanSchool is designed to allow remote access to the system, to monitor and log activity, I feel like that is an accurate description. Furthermore LanSchool’s #1 FAQ question is:

    My Anti-Virus software is reporting LanSchool as a virus, what should I do? Suggesting that the LanSchool software indeed acts in a manner similar enough to a malicious program, to trigger some Anti-Virus applications. The flaws in the design were demonstrated by the proof-of-concept application in question, and were true at the time of publication.

  5. “It is evident that you have intentionally set out on a course to harm our client’s software and business.” — absolutely not. The original review explicitly states that “This page detials a proof of conspect expolite of the lanschool program. CompSci.ca and Hacker Dan do not support, condone or recomend the use of it in real life”. Once again, the company has been made aware of the issue well before the publication.

Demands

  1. Removal of the critical review of their software.
  2. Destruction of author’s intellectual property, in the form of the proof-of-concept application.
  3. Not making use of any of LanSchool’s software in the future.

LanSchool is clearly inhibiting free speech with their outrageous claims and demands, and they are trying to punish Tony and Dan for correctly going about disclosing a product vulnerability.

Support

Tony and Dan are trying to raise money for legal representation via donations, and in the event that LanSchool doesn’t proceed with legal action, the money will be donated to EFF.org — “the leading civil liberties group defending your rights in the digital world”. Even a comment of support on their blog post would help. You can donate and read more on the compsci.ca blog post.

Update: Thankfully the issue has been resolved amicably, you can read about the process on the compsci.ca wiki page.

Dear Rogers

Your new iPhone data plans are absolutely ridiculous. Virtually every other country offering the iPhone includes unlimited data at no extra premium. The fact that the data bandwidth offered for each iPhone plan is so low coupled with the latest 3G capabilities effectively renders the device useless. The estimated usage scenarios per plan are not realistic and do not factor in secondary data usage options (i.e. 3G applications, iTunes Store, &c…). Not to mention next to no minutes and SMS, and lack of a rollover minutes capability. It’s as if you are barely offering a service, and simply charging for iPhone ownership. You are locking Canadians in to what seem to be third world plans from nearly a decade ago. It’s not fair to your loyal customers who are being forced to pay these exorbitant prices.

It’s truly a sad day for Canadians and tech enthusiasts, knowing we have been abandoned by the one company that really could have made a difference.

Sincerely,

Gianni Chiappetta

Update: Rogers replies, and yes they spelled my last name wrong.

Dear Gianni Chiapetta,

Thank you for taking the time to write to us, we appreciate your use of online customer service.

In your recent email, you have informed us that you are unhappy with the data plans for the upcoming iPhone 3G.

We are sorry to hear that our iPhone 3G voice and data packages are less than you were expecting.  We would like to point out that they do offer more data and airtime than our traditional packages and they also come with the added features of bonus text messages and visual voicemail.

However, we appreciate that this release has come with expectations from our customers.  At Rogers we are always aiming to improve service to better meet the needs of our customers and we appreciate  your feedback. Your comments will be passed along for further review and consideration.

Thank you for contacting Rogers.

For future email correspondence with respect to this e-mail, please quote reference number redacted

Regards, Heather N. Rogers Online Customer Service http://www.rogers.com

LOL Security

Recently a family member’s credit card had been compromised, so I thought it high-time that I update my personal online banking password. That’s when I encountered a certain French-Canadian bank’s impenetrable password scheme:

Password must be 6 numbers and/or letters in length.

All I can say is they just made my brute-forcer exponentially faster.