Here’s the source article http www frederico araujo…

Here’s the source article:
http://www.frederico-araujo.com/2011/07/30/installing-rails-on-os-x-lion-with-homebrew-rvm-and-mysql/

My goals here are to update an environment and move to a new Susy release: http://susy.oddbird.net/

1. Install and upgrade XCode from the Mac App Store (4.3.2 in this case). Also install the Command Line Tools found in the Preferences pane.

2. Install Homebrew. Not entirely necessary, but I’m enjoying it lately.

Install Homebrew Package Manager
$ /usr/bin/ruby -e "$(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)"

3. Install RVM – Ruby Version Manager

// Install RVM
$  bash -s master < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
// Reset some paths
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
// Run to reset your open terminals
$ source ~/.bash_profile
// Make sure RVM is updated
$ rvm get stable
// Had to do a reinstall for Ruby stable
$ rvm reinstall 1.9.3-p194
// Use Ruby 1.9.3-p194
$ rvm use 1.9.3-p194 --default
// Check my ruby version
$ ruby -v

4. Install Compass

// Make sure all is good
$ sudo gem update --system
// Some XML Tools
$ sudo gem install builder
// Install Compass
$ sudo gem install compass
// Here's where things went wacky, so Installed the kitchen sink - over-install-panic-attack!
$ sudo gem install haml
$ sudo gem install haml-edge
$ sudo gem install rails
// Oh it's a damn bug see: 
// http://stackoverflow.com/questions/10610254/cant-install-compass-via-rvm
$ rubygems-bundler-uninstaller
// Test Compass
$ compass version

5. Install my favorite Compass add-ons

// Oily_PNG to for sprite creation performance
$ sudo gem install oily_png
// Susy because grids are awesome - Now this will install some alpha SASS and Compass code but why not.
$ sudo gem install susy --pre
// Normailze CSS sortof-reset
$ sudo gem install compass-normalize

Unfollow Non-twitter followers


// ==UserScript==
// @name           Twitter Remove Non-Followers
// @namespace      http://userscripts.org/users/28
// @description    Remove Twitter friends who don't follow you back. Click the "Remove marked users" button at the bottom of the list to activate.
// @include        http*://*twitter.com/following*
// @include        http*://*twitter.com/*/following*
// ==/UserScript==

/*
ABOUT
=====

This script highlights the "remove" buttons for "friends" who don't follow you 
back on your Twitter Friends pages. A new action button is added at the bottom
of the page. When you click this button, all marked friends will be removed.

The scrip marks only users who:
<ul>
<li>don't follow you ("don't return the love")</li>
<li>have their updates unprotected (you can always remove these manually if you want).</li>
</ul>
By default, no action is taken, so you have the chance to inspect which users will
be removed before clicking the "Remove Marked" button.

Auto-mode: set property TwitterRemoveNonFollowers.autoMode to true and open
the "following" page, http://twitter.com/following
The script will auto-advance one page at a time.


NOTE: make sure you also allow scripts included from twimg.com if you're using the NoScript add-on!!!

LICENSE
=======

(c) 2009 Johannes la Poutre


This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


CHANGELOG
=========

Version 1.23 - 20091005
	- Fix for auto mode: just follow "next" link

Version 1.23 - 20090915
	- Fix for changed Twitter CSS
	- Thanks Coree Silvera for letting me know!

Version 1.22 - 20090820
	- Minor fix when running in auto-mode
	- Added note about NoScript

Version 1.21 - 20090702
	- Extra @include rule for /username/following pages

Version 1.20 - 20090702
	- complete rewrite for new Twitter user interface

Version 1.01 - 20090403
	- updated color scheme, removed debugging code

Version 1.00 - 20090403
	- initial release
	- does NOT remove users whose timeline is protected

*/

var TwitterRemoveNonFollowers = {
	hitlist: [], // the list of 'friends' to remove
	autoMode: false,
	authenticity_token: '',
	
	init: function() {
		// select users w/o DM command link and no Lock icon image
//		var rows = document.evaluate("//button[contains(@class, 'remove-button')][not(following-sibling::span/a[contains(@href, '/direct_messages/create/')])]", 
//					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
//		<tr id="user_15356378" class="user following direct-message-able odd">
		var rows = document.evaluate("//tr[contains(@class, 'following')][not(contains(@class, 'direct-messageable'))]", 
					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		for (var i = 0; i < rows.snapshotLength; i++) {
			var btn = rows.snapshotItem(i);
			btn.style.backgroundColor = '#bbb';
			btn.setAttribute('class', 'user following');
			// id="user_20707860"
			var id = rows.snapshotItem(i).getAttribute('id').substring(5);
			this.hitlist.push(id);
		}
		if (this.hitlist.length) {		
			this.authenticity_token = unsafeWindow.twttr.form_authenticity_token;
			var rmBtn = document.createElement('input');
			rmBtn.setAttribute('type', 'button');
			rmBtn.setAttribute('id', 'TwitterRemoveNonFollowersBtn');
			rmBtn.setAttribute('value', 'Remove marked (' + this.hitlist.length + ')');
			rmBtn.setAttribute('style', 'float:right;border: 1px solid lime');
			document.getElementById("pagination").appendChild(rmBtn);
			rmBtn.addEventListener('click', function() {
					rmBtn.setAttribute('disabled', 'disabled');
					rmBtn.style.border = '1px solid silver';
					TwitterRemoveNonFollowers.remove(); 
				}, true);
			if (this.autoMode) {
				rmBtn.click();
			}
		} else {
			if (this.autoMode) {
				this.nextPage();
			}
		}
		// FIX...
		unsafeWindow.alert = function(msg) {
			GM_log("" + msg);
		}
	},
	
	nextPage: function() {
		var rows = document.evaluate("//a[contains(@rel, 'next')]", 
					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		if (rows.snapshotLength) {
			var next = rows.snapshotItem(0);
			var link = next.getAttribute('href');
//			var page = link.match(/page=(d+)/)[1];
//			if (parseInt(page, 10) > this.keepPages) {
				if (0 === link.indexOf('/')) {
					link = window.location.protocol + '//' + window.location.host + link;
				}
				GM_log(link);
				window.location.href = link;
//			}
		}
	},
	

	remove: function() {
		if (this.hitlist.length) {
			document.getElementById("TwitterRemoveNonFollowersBtn").setAttribute('value', 'Removing: ' + this.hitlist.length + ' to go...');
			
			// use native XMLHttpRequest otherwise the referrer gets not set correctly
			var data = 'authenticity_token='+this.authenticity_token+'&twttr=true';
			var uid = this.hitlist.shift();
			var url = window.location.protocol + '//' + window.location.host +'/friendships/destroy/' + uid;
			var req = new XMLHttpRequest();
			req.onreadystatechange =  function() {
					TwitterRemoveNonFollowers.remove_callback(req, uid);
				};
			req.open("POST", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			req.setRequestHeader("Accept", "application/json, text/javascript, */*");
			req.setRequestHeader("Referer", window.location.href);
			req.setRequestHeader("Content-Length", data.length);
			req.send(data);
			// id="user_20707860"
			document.getElementById('user_'+uid).style.backgroundColor = 'orange';
			
			setTimeout(function() { TwitterRemoveNonFollowers.remove(); }, 1000);
		} else {
			document.getElementById("TwitterRemoveNonFollowersBtn").setAttribute('value', 'All done.');
			if (this.autoMode) {
				this.nextPage();
			}
		}
	},
	
	remove_callback: function(req, uid) {
	    if (req.readyState == 4) {
	        // only if "OK"
	        if (req.status == 200) {
			// {"result":"unfollowed","success":true}
			// GM_log(req.responseText);
			document.getElementById('user_'+uid).style.display = 'none';
	        } else {
			GM_log("There was a problem retrieving the XML data:n" + req.statusText);
				document.getElementById('user_'+uid).style.backgroundColor = 'red';
	        }
	    }
//		GM_log(req.responseText);
	}
};

TwitterRemoveNonFollowers.init();

HTML5 Articles

Some HTML5 Articles I want to read when I have time.

http://diveintohtml5.org/

http://www.456bereastreet.com/archive/201103/html5_sectioning_elements_headings_and_document_outlines/

Mac OSX 10.6 Shell Script to Configure, Launch, and Shutdown Screen Sharing

Apple’s MacOS has a tidy built in remote access client and service generically known as “Screen Sharing”. Yay! This works great for headless machines, testing servers, and annoying your spouse. The paranoid and performance conscious user may not want these services continuously running. Rogue services hanging out, listening, and waiting for some punk to probe them in an Internet dark alley. This cobbled together shell script might be for you!

This shell script has four simple commands (I use sudo because I really should):

  • # sudo ./share-screen.sh start
  • # sudo ./share-screen.sh stop
  • # sudo ./share-screen.sh allow {username}
  • # sudo ./share-screen.sh deny {username}

I use this in terminal. Make sure you put a copy of this script on the target machine and make it executable. First I make sure that Remote Login is active on the target computer. It’s under Sharing in System Preferences. Then I login remotely using ssh. I fire up the script, activate Screen Sharing, do my business, shutdown Screen Sharing, log off, and go home.

Of course, no warranty, no guaranty. Good Luck!

#!/bin/bash

if [ $# == 0 ]; then
	echo  "Commands: start, stop, allow <username>, deny <username>"
	exit
fi

case "$1" in
	start)
		echo 'Starting Remote Access'
		# Activate Apple Remote Access with current settings
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate
		;;
	stop)
		echo 'Stopping Remote Access'
		# Deactivate Apple Remote Access
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -stop
		;;
	allow)
		if [ -z "$2" ]; then
			echo  "ERROR: Provide a valid user"
			exit
		fi
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -specifiedUsers
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -access -on -privs -all -users ${2}
		;;
	deny)
		if [ -z "$2" ]; then
			echo  "ERROR: Provide a valid user"
			exit
		fi  
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -specifiedUsers
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -access -off -privs -none -users ${2}  
		;;  
esac

I almost forgot. Credit where credit is due! Inspiration from these articles and resources:

http://www.macosxhints.com/article.php?story=20080318190503111

http://rentzsch.tumblr.com/post/515009165/starting-vnc-remotely-via-kickstart

My Reply to E-mail with Text File AppleScript

At work I deal with a large volume of e-mail. There just aren’t enough people to handle all the e-mail requests or questions. When I have people to help handle e-mail, I still answer some of the same questions over and over and over. You just don’t want to know the volume or scope of my daily e-mail chores.

As a long time MacOS user I have repeatedly turned to AppleScript as a useful tool for dealing with making the same e-mail replies constantly (the real solution is to fix the breakdown in communication, but that’s a whole other story). Here is the most recent incarnation of my AppleScript solution using Apple Mail on MacOS 10.6.

My solution is simple; Highlight the message, run the script, select a pre-written text file to include, customize the reply, and send. The respondent gets a solution or reply that is usually edited over time for clarity, and I get to customize it a bit so it doesn’t seem too much like an auto-reply.

tell application "Mail"
		
	set theSelection to selection
	set theSelectedMessage to item 1 of theSelection
	set theSelectedMessageSender to sender of theSelectedMessage
	
	set theSelectedMessageSenderName to extract name from sender of theSelectedMessage
	set theSelectedMessageSenderAddress to extract address from sender of theSelectedMessage
	
	set theSelectedMessageSubject to subject of theSelectedMessage
	set theSelectedMessageContent to content of theSelectedMessage
		
	set myHomeDefault to the path to home folder
	set myHomeDefault to myHomeDefault & "nicholls:Documents:e-mail_templates:" as text
	set myHomeDefault to myHomeDefault as alias
		
	set myTemplateFile to (choose file with prompt "Select E-mail Template File:" of type {"TEXT"} default location myHomeDefault)
	
	open for access myTemplateFile
	set prefsContents to read myTemplateFile using delimiter {"#--#"}
	close access myTemplateFile
	set MessageText to item 1 of prefsContents
		
	set theMessage to make new outgoing message with properties {visible:true, subject:"Re: " & theSelectedMessageSubject, content:MessageText & theSelectedMessageContent}
	tell theMessage
		make new to recipient at end of to recipients with properties {name:theSelectedMessageSenderName, address:theSelectedMessageSenderAddress}
		make new bcc recipient at end of bcc recipients with properties {name:"Website Manager", address:"nichweb@nicholls.edu"}
	end tell
end tell

This is a sample text file I might use. I made this really basic. You should note the #–# deliminator used. I have that so I can do some other interesting things with the templates, like BCC: my boss if I have too. Anyway this would be saved something like email-reply-standard.txt and I would load it through the dialog created by the script when it runs.

Thank you for your interest!


If you have further questions, please let me know.

Jess Planck

<ul>
<li>---------------------------
Nice Signature with phone 
---------------------------
Probably has the website too</li>
<li><ul>
<li><ul>
<li><ul>
<li>[ Your Original Message Follows ]----</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
#--#

For some reason the syntaxhighligher I’ve got here doesn’t like AppleScript comments, so I’ve removed them.

My Ugly WordPress, HyperDB, & BuddyPress Deployment Shell Script

This is the source of some of the website deployment scripts I have. This is one is fairly complex and it is my pocket tool of choice for development of big nasty WordPress sites. Probably only interesting to folks who deal with unix shells and do mildly heavy WordPress work.

It’s designed to update from SVN trunk for WordPress, HyperDB, & BuddyPress. My favorite is quick rsync for folders and subfolders so you can upload theme changes quickly because the web is my sketchpad.

Common List of Commands:

# Get the configured site 
./wp-work.sh get
# Put the configured site 
./wp-work.sh put
# Upgrade the configured site to latest WordPress, HyperDB, &amp;amp; BuddyPress
./wp-work.sh upgrade
# Put specific folders in the sites root
./wp-work.sh work put the-site-folder
# get specific folders in the sites root
./wp-work.sh work get the-site-folder

The Big Ugly Script:

You will really want to customize the top values for sure.

#!/bin/sh

# Batch Update jess
#
# Uses flat array list of site locations, updates using latest source from SVN and performs all update steps.
#

# Website Name
WEB_ROOT_NAME=&quot;example.com&quot;

# Web Direcory locations Using $HOME is good.
WEB_ROOT_LOCAL=&quot;${HOME}/luser/${WEB_ROOT_NAME}/&quot;
WEB_ROOT_REMOTE=&quot;/home/luser/${WEB_ROOT_NAME}/&quot;

# Archive -a mode is -rlptgoD -pgo is permission, user, group and be an issue had to add -vz
RSYNC_SWITCH='-vzrltD'
# SSH command because you might need: 'ssh -i /shh/secret-key/master-magic-key -p 56232'
RSYNC_SSH='ssh'
# Remember the ssh account is where your files land.
RSYNC_SSH_ACCOUNT='me@example.com'

# Tools location for exclude files ans stuff. Using $HOME is good.
TOOLS_ROOT_LOCAL=&quot;${HOME}/luser/stuff/&quot;
TOOLS_ROOT_EXCLUDES=&quot;${HOME}/luser/stuff/&quot;

# Temp files
TEMP_ROOT_LOCAL=&quot;${HOME}/luser/tmp/&quot;

# Putting the path into a variable gets tricky
WORKING_TEMP_LOCATION=$( readlink -nf ${TEMP_ROOT_LOCAL} )

# Move to tools directory so we can find things easier.
cd ${TOOLS_ROOT_LOCAL}

# Print good ole help if no command
if [ $# == 0 ]; then
	echo  &quot;${WEB_ROOT_NAME} Commands: get, put, upgrade, work [put or get] [directory]&quot;
	exit	
fi

# Get all remote
if [ $1 == &quot;get&quot; ]; then
  echo '----- Start Site Download -----'
  echo  &quot;Get all stuff with a few exceptions.&quot;
  rsync ${RSYNC_SWITCH} --delete -e &quot;${RSYNC_SSH}&quot; ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE} ${WEB_ROOT_LOCAL}
  exit
fi

# Put all with some exceptions
if [ $1 == &quot;put&quot; ]; then
  echo '----- Start Site Upload -----'
  echo  &quot;Put all stuff with a few exceptions.&quot;
  rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e &quot;${RSYNC_SSH}&quot; ${WEB_ROOT_LOCAL} ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE}
  exit
fi

# Upgrade with merge from several sources
if [ $1 == &quot;upgrade&quot; ]; then

	echo  &quot;Don't have this for work.funroe.net&quot;

	exit
	
	mkdir ${WORKING_TEMP_LOCATION}
	mkdir ${WORKING_TEMP_LOCATION}/wordpress
	mkdir ${WORKING_TEMP_LOCATION}/buddypress
	mkdir ${WORKING_TEMP_LOCATION}/hyperdb
	
	svn co http://svn.automattic.com/wordpress/trunk/ ${WORKING_TEMP_LOCATION}/wordpress/
	svn co http://svn.buddypress.org/trunk/ ${WORKING_TEMP_LOCATION}/buddypress/
	svn co http://svn.wp-plugins.org/hyperdb/trunk/ ${WORKING_TEMP_LOCATION}/hyperdb/
	 
	mv -f ${WORKING_TEMP_LOCATION}/buddypress ${WORKING_TEMP_LOCATION}/wordpress/wp-content/plugins/buddypress
	mv -f ${WORKING_TEMP_LOCATION}/hyperdb/db.php ${WORKING_TEMP_LOCATION}/wordpress/wp-content/db.php
	
	echo '----- Update local site -----'
	rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wpmu-bbpres-bp-exclude.txt  ${WORKING_TEMP_LOCATION}/wordpress/ ${WEB_ROOT_LOCAL}
	
	echo  &quot;----- Remove temp working directory! -----&quot;
	rm -Rf ${WORKING_TEMP_LOCATION}
	
	echo  &quot;----- Update remote site! -----&quot;	
	rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e &quot;${RSYNC_SSH}&quot; ${WEB_ROOT_LOCAL} ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE}
	echo '----- DONE! -----'
	
	exit
fi

# Work allows get and put of specific directories starting at web root ie. this.command work put wp-content/themes
if [ $1 == &quot;work&quot; ]; then

 	# Putting the path into a variable gets tricky
 	WORKING_LOCAL_LOCATION=$( readlink -nf ${WEB_ROOT_LOCAL}${3} )
	
	if [ ! -d &quot;${WORKING_LOCAL_LOCATION}&quot; ]; then
		if [ ! -f &quot;${WORKING_LOCAL_LOCATION}&quot; ]; then
			 echo &quot;Not a valid work site! Please try again.&quot;
			 exit
		fi
	fi
	
	# Set remote location
	WORKING_REMOTE_LOCATION=${WEB_ROOT_REMOTE}${3}
			
	# Add slashes to end if they were omitted
	if [ `echo &quot;$WORKING_LOCAL_LOCATION&quot; | grep &quot;[^/]$&quot;` ]; then 
		WORKING_LOCAL_LOCATION=&quot;${WORKING_LOCAL_LOCATION}/&quot;; 
		WORKING_REMOTE_LOCATION=&quot;${WORKING_REMOTE_LOCATION}/&quot;; 
	fi
	
	# Remove double slashes
	WORKING_LOCAL_LOCATION=${WORKING_REMOTE_LOCATION//////}	
	WORKING_REMOTE_LOCATION=${WORKING_REMOTE_LOCATION//////}

	echo &quot;rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e &quot;${RSYNC_SSH}&quot; ${WORKING_LOCAL_LOCATION}  ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION}&quot;

	if [ $2 == &quot;get&quot; ]; then
	  echo &quot;----- Get All ${WEB_ROOT_NAME} -----&quot;
	  echo  &quot;Downloading all work.funroe.net/$work_site files...&quot;
	  rsync ${RSYNC_SWITCH} --delete -e &quot;${RSYNC_SSH}&quot; ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION} ${WORKING_LOCAL_LOCATION}
	  exit
	fi
	
	if [ $2 == &quot;put&quot; ]; then
	  echo &quot;----- Put ${WEB_ROOT_NAME} -----&quot;
	  echo  &quot;Uploading selected work.funroe.net/$work_site files...&quot;
      rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e &quot;${RSYNC_SSH}&quot; ${WORKING_LOCAL_LOCATION}  ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION}
	  exit
	fi	

fi

Exclude file: wordpress-exclude.txt needs to be in that TOOLS_ROOT_EXCLUDES directory. I use it skip stuff that I don’t want to be synced on upload because the remote file changes are most important.

.htaccess
wp-config.php
bb-config.php
cache/
blogs.dir
uploads
wp-content/advanced-cache.php
wp-cache-config.php
sitemap.xml.gz
robots.txt
sitemap.xml
googlee-thingyfile.html

Exclude file: wpmu-bbpress-bp.txt needs to be in that TOOLS_ROOT_EXCLUDES directory. This is to keep files from being overwritten when a package is created from the SVN repositories and moved to the local site staging area. This really may need customized to protect your personal themes, plugins, and files.

# WP Core excludes
<ul>
<li>.htaccess</li>
<li>wp-config.php</li>
<li>bb-config.php</li>
<li>/cgi-bin</li>
<li>/cache</li>
<li>blogs.dir</li>
<li>uploads</li>
</ul>
# Themes
+ themes/index.php
+ themes/classic
+ themes/default
+ themes/twentyten
- themes/*

# Plugins
+ plugins/readme.txt
+ plugins/index.php
+ plugins/buddypress
- plugins/*

# MU Plugins
+ mu-plugins/readme.txt
+ mu-plugins/index.php
- mu-plugins/*

# Hyper DB
- db-settings.php