Never been to TextSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

About this user

Jamie Wilkinson http://tramchase.com

« Newer Snippets
Older Snippets »
33 total  XML / RSS feed 

MailMan listserve signup template

Simple template for adding a MailMan mailing list subscribe form to a page. Found on a mailing list somewhere a long time ago and cleaned up dramatically.

Note: I almost always just include the email and digest options, but I've included the whole spiel for completeness.


<h2>Join the XYZ listh2>

/mailman/subscribe/LISTNAME">

Your E-mail address: "text" name="email" size="30" value="">
Your Name (optional): "text" name="fullname" size="30" value="">

You may enter a privacy password below. This provides only mild security, but should
prevent others from messing with your subscription. Do not use a valuable password as it
will occasionally be emailed back to you in cleartext.

If you choose not to enter a password, one will be automatically generated for you, and it will
be sent to you once you've confirmed your subscription. You can always request a mail-back
of your password when you edit your personal options.

Password choice: "password" name="pw" size="15">
Confirm Password: "password" name="pw-conf" size="15">

Would you like to receive list mail batched in a daily digest? (You may choose NoMail after you join.)
"radio" name="digest" value="0" checked> No "radio" name="digest" value="1"> Yes

"submit" name="email-button" value="Subscribe">


Convert MySQL tables to InnoDB

// Slower than MyISAM, but row locking is clutch if you're doing a lot of writes amirite?

for t in $(mysql --batch --column-names=false -e "show tables" mydbname |grep -v "exclude_this");
do
mysql -e "alter table $t type=InnoDB" mydbname;
done


From:
http://ludo.qix.it/archive/2005/04/convert-a-bunch-of-tables-to-innodb.html

Delete duplicate rows from a table

// Whoops, didja forgot to add a unique index to that column? No problem

CREATE TABLE new_table AS
SELECT * FROM old_table WHERE 1 GROUP BY [COLUMN TO remove duplicates BY];
DROP TABLE old_table;
RENAME TABLE new_table TO old_table;

Capistrano task to load production data

# load production data, still needs some polish
# based on code from http://push.cx/2007/capistrano-task-to-load-production-data
# cap 2.0 compatible
# exec is being weird, had to end w/ a syscall :\ any ideas?

desc "Load production data into development database"
task :load_production_data, :roles => :db, :only => { :primary => true } do
  require 'yaml'
  ['config/database.yml'].each do |file|

    database = YAML::load_file(file)

    filename = "dump.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.sql.gz"
    # on_rollback { delete "/tmp/#{filename}" }

    # run "mysqldump -u #{database['production']['username']} --password=#{database['production']['password']} #{database['production']['database']} > /tmp/#{filename}" do |channel, stream, data|
    run "mysqldump -h #{database['production']['host']} -u #{database['production']['username']} --password=#{database['production']['password']} #{database['production']['database']} | gzip > /tmp/#{filename}" do |channel, stream, data|
      puts data
    end
    get "/tmp/#{filename}", filename
    # exec "/tmp/#{filename}"
    password = database['development']['password'].nil? ? '' : "--password=#{database['development']['password']}"  # FIXME pass shows up in process list, do not use in shared hosting!!! Use a .my.cnf instead
    # FIXME exec and run w/ localhost as host not working :\
    # exec "mysql -u #{database['development']['username']} #{password} #{database['development']['database']} < #{filename}; rm -f #{filename}"
    `gunzip -c #{filename} | mysql -u #{database['development']['username']} #{password} #{database['development']['database']} && rm -f gunzip #{filename}`
  end
  
end

Get remote file size, following redirects (PHP)

function get_remote_file_size($url, $readable = true){
   $parsed = parse_url($url);
   $host = $parsed["host"];
   $fp = @fsockopen($host, 80, $errno, $errstr, 20);
   if(!$fp) return false;
   else {
       @fputs($fp, "HEAD $url HTTP/1.1\r\n");
       @fputs($fp, "HOST: $host\r\n");
       @fputs($fp, "Connection: close\r\n\r\n");
       $headers = "";
       while(!@feof($fp))$headers .= @fgets ($fp, 128);
   }
   @fclose ($fp);
   $return = false;
   $arr_headers = explode("\n", $headers);
   foreach($arr_headers as $header) {
                        // follow redirect
                        $s = 'Location: ';
                        if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
                                $url = trim(substr($header, strlen($s)));
                                return get_remote_file_size($url, $readable);
                        }
                        
                        // parse for content length
       $s = "Content-Length: ";
       if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
           $return = trim(substr($header, strlen($s)));
           break;
       }
   }
   if($return && $readable) {
                        $size = round($return / 1024, 2);
                        $sz = "KB"; // Size In KB
                        if ($size > 1024) {
                                $size = round($size / 1024, 2);
                                $sz = "MB"; // Size in MB
                        }
                        $return = "$size $sz";
   }
   return $return;
}

Never render the full layout in a Rails view when called via AJAX

Essential for degradable javascript, when one never knows if a view or partial is being called via XmlHttpRequest or not. Throw the below code in your ApplicationController (application.rb)

More info in this blog post

def render(*args)
        args.first[:layout] = false if request.xhr? and args.first[:layout].nil?
        super
end

Standard CSS helpers

Some really common layout classes I use in almost every CSS file.

/********* helpers *********/
.floatRight { float: right; }
.floatLeft  { float: left; }
.right  { text-align: right; }
.left   { text-align: left; }
.center { text-align: center; }
.clear, .clearer { clear: both; }
.block  { display: block; }

AppleScript to test if application is running

By name:
tell application "System Events" to (name of processes) contains "iTunes"


By creator type, in case it might have a version # appended:
tell application "System Events" to (creator type of processes) contains "InDn"


Grab creator type dynamically like so:
tell application "Finder" to creator type of (selection as alias)


From http://applescriptsourcebook.com/viewtopic.php?pid=46830

Cache a local copy of Google Analytics' urchin.js

Speed up your website by caching Google's urchin.js locally, and then refreshing it @nightly with this here script. Some background: http://tramchase.com/blog/broken-urchintracker-calls-google-analytics-down

#!/bin/sh
# urchin.js local caching by Jamie Wilkinson 

# config
DIR=/directory/where/you/want/js

# work
URCHIN=$DIR/urchin.js
wget http://www.google-analytics.com/urchin.js -O $URCHIN.tmp
if [ -s $URCHIN.tmp ]; then
        rm $URCHIN
        mv $URCHIN.tmp $URCHIN
        chmod 644 $URCHIN
fi

exit 0;

Handling filenames with spaces in a bash for or while loop

// The `find` here gets every directory in my home dir, one level deep, but some of them have spaces... the default 'for i in $(find ...)' behavior treats each individual word boundary as a separate variable, but piping to `read` breaks them on newlines
// Note: OS X `find` does not support "-depth 1" (its -depth opt is for depth-first searching vs. breadth-first), just use an 'ls' with an 'if [ -d $filename]' to test for directories

find ~ -type d -depth 1 | while read filename; do
# ls ~ | while read filename; do
        echo $filename
        # other stuff
done

MediaWiki LDAP configuration

Requires the LdapAuthentication extension. Regarding precise LDAP queries YMMV.

# LDAP authentication
require_once( 'extensions/LdapAuthentication/LdapAuthentication.php' );
$wgAuth = new LdapAuthenticationPlugin();

$wgLDAPDomainNames = array( "domain-ldap" );
$wgLDAPServerNames = array( "domain-ldap" => "ldap.domain.org"  );
$wgLDAPEncryptionType = array( "domain-ldap" => "clear" );   // "testADdomain"=>"tls",
$wgLDAPSearchStrings = array( "domain-ldap"=>"uid=USER-NAME,ou=People,dc=domain,dc=org"  );

$wgLDAPWriterDN                         = array( "domain-ldap" => "cn=Manager,dc=domain,dc=org" ); // for changing passwords; AddLDAPUsers below must be true
$wgLDAPWriterPassword = array( "domain-ldap" => "MANAGERPASSWORD" ); // FIXME
$wgLDAPWriteLocation    = array( "domain-ldap" => "ou=People,dc=domain,dc=org" );

$wgLDAPAddLDAPUsers = array( "domain-ldap" => true ); // allow adding users to LDAP from mediawiki? require WriterDN/Password
$wgLDAPUpdateLDAP = array( "domain-ldap" => true );    // for updating passwords;
$wgLDAPUseLocal = array( "domain-ldap" => true ); // failover to local DB?
$wgLDAPMailPassword = array( "domain-ldap" => true ); // if can't write to LDAP this is basically useless
$wgLDAPRetrievePrefs = array( "domain-ldap" => true );
$wgMinimalPasswordLength = 1;

// Don't automatically create an account for a user if the account exists in LDAP but not in MediaWiki. Default is false.
// this totally breaks things, do not turn it on
$wgLDAPDisableAutoCreate = array( "domain-ldap" => false );

$wgLDAPDebug = 1; // 3 is a lot

vi find/replaces for adding a table prefix to a SQL dump

Was importing a DB but wanted to prefix the tables, but the file was too large for TextMate. Here's all the vim substitutions

%s/DROP TABLE IF EXISTS `/DROP TABLE IF EXISTS `prefix_/g
%s/CREATE TABLE `/CREATE TABLE `prefix_/g
%s/INSERT INTO `/INSERT INTO `prefix_/g
%s/LOCK TABLES `/LOCK TABLES `prefix_/g
%s/ALTER TABLE `/ALTER TABLE `prefix_/g

mongrel_cluster monit script


Copyright (C) 2006 Peter J Jones ([email protected]).

################################################################################
# This script will update your monit configuration file to monitor your
# mongrel cluster by reading the mongrel cluster file and generating monit
# check entries. It places delimiters in the configuration file so that you
# can run this script multiple times without generating duplicate entries.
#
# Run it like this:
#
# mongrel_monit --mongrel=/path/to/mongrel/config.yml --monit=/path/to/monitrc
#
# You can edit the ERB template below to control the generated monit config.
#


TEMPLATE = <<EOT
check process mongrel_<%= @port %> with pidfile <%= @pidfile %>
  group mongrel
  start program = "/usr/local/bin/<%= @start %>"
  stop program = "/usr/local/bin/<%= @stop %>"

  if failed host 127.0.0.1 port <%= @port %> protocol http
    with timeout 10 seconds
    then restart

  if totalmem > 100 Mb then restart
  if cpu is greater than 60% for 2 cycles then alert
  #if cpu > 90% for 5 cycles then restart
  #if loadavg(5min) greater than 10 for 8 cycles then restart
  if 3 restarts within 5 cycles then timeout

EOT
################################################################################
require 'erb'
require 'optparse'
require 'fileutils'
require 'rubygems'
require 'mongrel_cluster/init'
################################################################################
module Kernel
  $commands = []

  # Hack Kernel::` so that we can capture what mongrel_cluster does
  def ` (cmd)
    $commands << cmd
    system(':') # to set $?
  end

  # Hack Kernel::puts to shut mongrel_cluster up
  def puts (str)
    true
  end
end
################################################################################
options = OptionParser.new

options.on('--mongrel=FILE', 'Mongrel configuration file') do |o|
  $mongrel_config = o
end

options.on('--monit=FILE', 'Monit configuration file') do |o|
  $monit_config = o
end

options.parse!

unless $mongrel_config and $monit_config
  puts "please give --mongrel and --monit"
  exit 1
end
################################################################################
mongrel_config_data = YAML.load_file($mongrel_config)
Dir.chdir(mongrel_config_data['cwd']) if mongrel_config_data['cwd']
################################################################################
# This is the only way to access the cmd that mongrel_cluster uses so that we
# can keep things DRY
start = Cluster::Start.new
start.instance_variable_set(:@config_file, $mongrel_config)
start.run
start_commands = $commands.dup
$commands.clear

stop = Cluster::Stop.new
stop.instance_variable_set(:@config_file, $mongrel_config)
stop.run
stop_commands = $commands.dup
$commands.clear
################################################################################
template = ERB.new(TEMPLATE)
config = ''

0.upto(start_commands.length - 1) do |i|
  @port = start_commands[i].match(/-p\s*(\d+)/)[1]
  @pidfile = File.expand_path(start_commands[i].match(/-P\s*(\S+)/)[1])
  @start = start_commands[i]
  @stop = stop_commands[i]
  config << template.result(binding)
end
################################################################################
monit_config_data = File.open($monit_config) {|f| f.read}

# TODO: if you have more than one cluster, this won't do
banner_start = "#= Mongrel_Monit Config Start =#\n"
banner_stop  = "#= Mongrel_Monit Config End =#\n"

if monit_config_data.match(/#{banner_start}.*#{banner_stop}/m)
  monit_config_data.sub!(/#{banner_start}.*#{banner_stop}/m, "#{banner_start}#{config}#{banner_stop}")
else
  monit_config_data << "#{banner_start}#{config}#{banner_stop}"
end

File.open($monit_config, 'w') {|f| f << monit_config_data}
################################################################################

ssh tunnel with local port forwarding (MySQL)

// ssh tunnel remote mysql to a local port (in this case, 3307)

ssh -2 -f -C -N user@servername.com -L 3307/127.0.0.1/3306

DAAP tunneling / remote iTunes Music Share

// requirements
// * server running mt-daapd/Firefly (alternative server for iTunes music sharing)
// * tunneleling & port-forwading via ssh
// * local bonjour/zeroconf broadcasting using Apple's mDNSProxyResponder
// based on info from
// for more: see Music Blackhole
// Jamie Wilkinson


ssh USER@SERVERNAME -N -f -L 3690:SERVERNAME:3689 && mDNSProxyResponderPosix 127.0.0.1 musicserver "My remote music server" _daap._tcp. 3689 &

"Digg this page" XSS

// To include the nice little live-updated Digg widget

<script src="http://digg.com/tools/diggthis.js" type="text/javascript">script>

Mass find-replace using sed

Replace some widespread nasty hardcoded strings. 'sed $file > $file' doesn't work so hot so we use a temp file, and also make a backup of the old file.

for i in $(find . -type f); do sed 's/oldstring/newstring/g' $i > $i-tmp; mv $i $i-backup; mv $i-tmp $i; done

Close dangling HTML tags

Close open HTML tags, e.g. if you allow HTML in your comments. Not quite as robust as running it through tidy, but tidy is not always available.

function close_dangling_tags($html){
  #put all opened tags into an array
  preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
  $openedtags=$result[1];

  #put all closed tags into an array
  preg_match_all("##iU",$html,$result);
  $closedtags=$result[1];
  $len_opened = count($openedtags);
  # all tags are closed
  if(count($closedtags) == $len_opened){
    return $html;
  }

  $openedtags = array_reverse($openedtags);
  # close tags
  for($i=0;$i < $len_opened;$i++) {
    if (!in_array($openedtags[$i],$closedtags)){
      $html .= ''.$openedtags[$i].'>';
    } else {
      unset($closedtags[array_search($openedtags[$i],$closedtags)]);
    }
  }
  return $html;
}

301 Permanent Redirect rule to consolidate domains

// redirect domain.com to www.domain.com (or vice versa)
// helps substantially with delicious links and other SEO optimization
// see for discussion

RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]

Tar up, excluding common media extensions

Just the code, please! Hop in the dir you want to back up (note: this means it'll expand without a base directory, so do a mkdir/cd first!)

find . ! -type d -print | egrep '/,|%$|~$|\.old$|\.mpg$|\.zip$|\.wmv$|\.mp3$|\.MP3$|\.mp4$|\.MP4$|\.av2$|\.ppt$|\.dir$|\.pps$|\.qt$|SCCS|/core$|\.o$|\.orig$|\.mpeg$|\.mov$|\.doc$|\.xls$|\.pdf$|\.swf$|\.fla$|\.wav$|\.aif$|\.aiff$|\.mp3$|\.jpg$|\.JPG$|\.jpeg$|\.JPEG$|\.gif$|\.GIF$|\.png$|\.PNG$|\.psd$|\.PSD$|\.tar.gz$|\.tgz$|\.TGZ$|\.tif$|\.TIF$|\.tiff$|\.TIFF$|\.tga$|\.TGA$|\.ram$|\.rm$|\.rma$|\.psd$|\.PSD$|\.ai$|\.AI$' > Exclude
tar czfvX ~/backup_text_back.tgz Exclude .
« Newer Snippets
Older Snippets »
33 total  XML / RSS feed