Upgrade to Ubuntu 12.04 – Ruby on Rails gem mysql2 error: libmysqlclient_r.so.16

When upgrading from Ubuntu 11.10 to 12.04, you may experience the following error with the Ruby on Rails gem mysql2:

.rvm/gems/ruby-1.9.2-p180/gems/mysql2-0.3.11/lib/mysql2.rb:9:in `require': libmysqlclient_r.so.16: cannot open shared object file: No such file or directory

This is because Ubuntu 12.04 is now using the newer libmysqlclient 18. Creating a symlink won’t fix the problem– the mysql2 gem needs to be re-installed (and therefore recompiled) to support the latest version.

gem uninstall mysql2
# (all versions)
gem install mysql2

Shell script for cloning a WordPress installation

The shell script below will copy a WordPress installation from one server to another- including the database. The script uses the ‘sed’ command to update the new wp-config.php with the new server information, as well as replace all references to the original domain (such as in post_content) in the new DB with references to the new domain.  I wrote the script in order to create a ‘one-click’ solution to mirroring a WP installation.  It will work with both single and multisite installations.

WARNING: Use at your own risk.  I recommend that you manually back up the original WP installation until you are confident that the script is configured correctly.  It is possible to inadvertently alter or erase your original installation if you do not configure the script’s variables correctly. The script was written in the Mac OS environment and may require some alterations to work in your environment.

#!/bin/sh
echo "WP Clone Start"
START=$(date +%s)
 
SH_PATH="/Users/johndoe/Desktop/" # Path to this shell script
MYSQL_PATH="/usr/local/mysql-5.1.60-osx10.6-x86_64/bin" # Path to mysql and mysqldump
 
OLD_PATH="/Volumes/live" # Path to original WP
OLD_DOMAIN="live.myserver.com" # Domain for original WP
OLD_HOST="db.myserver.com" # Database host for original WP
OLD_USER="liveuser" # Database user for original WP
OLD_PASS="livepassword" # Database password for original WP
OLD_DB="wp_live" # Database name for original WP
 
NEW_PATH="/Volumes/dev" # Path to new WP, folder must already exist
NEW_DOMAIN="dev.myserver.com" # Domain for new WP
NEW_HOST="db.myserver.com" # Database host for new WP
NEW_USER="devuser" # Database user for new WP
NEW_PASS="devpassword" # Database password for new WP
NEW_DB="wp_dev" # Database name for new WP, database must already exist
 
datetime() { echo `date "+%Y-%m-%d %H:%M:%S"` ;}
 
echo $(datetime) "Dumping $OLD_DB"
 
cd "$MYSQL_PATH"
./mysqldump $OLD_DB -h$OLD_HOST -u$OLD_USER -p$OLD_PASS > "$SH_PATH/$OLD_DB.sql"
 
echo $(datetime) "Editing $OLD_DB.sql > $NEW_DB.sql"
 
cd "$SH_PATH"
sed 's/'$OLD_DOMAIN'/'$NEW_DOMAIN'/g' $OLD_DB.sql > $NEW_DB.sql
 
echo $(datetime) "Importing $NEW_DB.sql to $NEW_DB"
 
cd "$MYSQL_PATH"
./mysql $NEW_DB -h$NEW_HOST -u$NEW_USER -p$NEW_PASS < "$SH_PATH/$NEW_DB.sql"
 
echo $(datetime) "Removing $OLD_DB.sql and $NEW_DB.sql"
 
cd "$SH_PATH"
rm $OLD_DB.sql
rm $NEW_DB.sql
 
echo $(datetime) "Removing $NEW_PATH contents"
 
rm -rf "$NEW_PATH/"*
 
echo $(datetime) "Copying files from $OLD_PATH to $NEW_PATH"
 
cp -r "$OLD_PATH/"* "$NEW_PATH"
 
echo $(datetime) "Editing wp-config.php"
 
cd "$NEW_PATH"
sed 's/'$OLD_DOMAIN'/'$NEW_DOMAIN'/g' wp-config.php > wp-config-temp.php
rm wp-config.php
mv wp-config-temp.php wp-config.php
sed 's/'$OLD_USER'/'$NEW_USER'/g' wp-config.php > wp-config-temp.php
rm wp-config.php
mv wp-config-temp.php wp-config.php
sed 's/'$OLD_DB'/'$NEW_DB'/g' wp-config.php > wp-config-temp.php
rm wp-config.php
mv wp-config-temp.php wp-config.php
sed 's/'$OLD_PASS'/'$NEW_PASS'/g' wp-config.php > wp-config-temp.php
rm wp-config.php
mv wp-config-temp.php wp-config.php
 
DIFF=$(( $(date +%s) - $START ))
echo $(datetime) "WP Clone Complete in $DIFF seconds"

Use PHP and LDAP to list members of an Active Directory group (Improved)

PHP function that gets the members of an Active Directory group, and returns the Users’ attributes as an array.

This is an improved version of the snippet posted on 2/10/2011

The Function

<?php
function get_members($group=FALSE,$inclusive=FALSE) {
    // Active Directory server
    $ldap_host = "ad.domain";
 
    // Active Directory DN
    $ldap_dn = "CN=Users,DC=ad,DC=domain";
 
    // Domain, for purposes of constructing $user
    $ldap_usr_dom = "@".$ldap_host;
 
    // Active Directory user
    $user = "jdoe";
    $password = "password1234!";
 
    // User attributes we want to keep
    // List of User Object properties:
    // http://www.dotnetactivedirectory.com/Understanding_LDAP_Active_Directory_User_Object_Properties.html
    $keep = array(
        "samaccountname",
        "distinguishedname"
    );
 
    // Connect to AD
    $ldap = ldap_connect($ldap_host) or die("Could not connect to LDAP");
    ldap_bind($ldap,$user.$ldap_usr_dom,$password) or die("Could not bind to LDAP");
 
 	// Begin building query
 	if($group) $query = "(&"; else $query = "";
 
 	$query .= "(&(objectClass=user)(objectCategory=person))";
 
    // Filter by memberOf, if group is set
    if(is_array($group)) {
    	// Looking for a members amongst multiple groups
    		if($inclusive) {
    			// Inclusive - get users that are in any of the groups
    			// Add OR operator
    			$query .= "(|";
    		} else {
				// Exclusive - only get users that are in all of the groups
				// Add AND operator
				$query .= "(&";
    		}
 
    		// Append each group
    		foreach($group as $g) $query .= "(memberOf=CN=$g,$ldap_dn)";
 
    		$query .= ")";
    } elseif($group) {
    	// Just looking for membership of one group
    	$query .= "(memberOf=CN=$group,$ldap_dn)";
    }
 
    // Close query
    if($group) $query .= ")"; else $query .= "";
 
	// Uncomment to output queries onto page for debugging
	// print_r($query);
 
    // Search AD
    $results = ldap_search($ldap,$ldap_dn,$query);
    $entries = ldap_get_entries($ldap, $results);
 
    // Remove first entry (it's always blank)
    array_shift($entries);
 
    $output = array(); // Declare the output array
 
    $i = 0; // Counter
    // Build output array
    foreach($entries as $u) {
        foreach($keep as $x) {
        	// Check for attribute
    		if(isset($u[$x][0])) $attrval = $u[$x][0]; else $attrval = NULL;
 
        	// Append attribute to output array
        	$output[$i][$x] = $attrval;
        }
        $i++;
    }
 
    return $output;
}
 
// Example Output
 
print_r(get_members()); // Gets all users in 'Users'
 
print_r(get_members("Test Group")); // Gets all members of 'Test Group'
 
print_r(get_members(
			array("Test Group","Test Group 2")
		)); // EXCLUSIVE: Gets only members that belong to BOTH 'Test Group' AND 'Test Group 2'
 
print_r(get_members(
			array("Test Group","Test Group 2"),TRUE
		)); // INCLUSIVE: Gets members that belong to EITHER 'Test Group' OR 'Test Group 2'
?>

Example Output

Array
(
    [0] => Array
        (
            [samaccountname] => sam
            [distinguishedname] => CN=sam,CN=Users,DC=ad,DC=domain
        )
 
    [1] => Array
        (
            [samaccountname] => jdoe
            [distinguishedname] => CN=John Doe,CN=Users,DC=ad,DC=domain
        )
 
)

Foscam Cameras: Scheduling Reboots, Brightness Changes, etc.

Foscam cameras are controlled through a web interface. The web interface has commands for changing brightness, contrast, and even rebooting the camera. You can run these commands by visiting specific URL’s. For example, to reboot the camera visit:
http://192.168.1.110:8080/reboot.cgi?user=admin&pwd=password
Where 192.* is your address and port, and user=<your username>, and pwd=<your password>. This will reboot the camera without you having to login and actually click Reboot.

Because we have the ability to execute commands from a single URL, they can be automated by having a web browser run them at a specific time and interval. Instead of keeping open a web browser on our computer – and having to refresh the commands using META or JavaScript, we can use a command-line web browser like Lynx with Windows Task Scheduler.

Below I explain how this is done.

Continue reading

MySQL Levenshtein and Damerau-Levenshtein UDF’s

Levenshtein distance is a helpful metric to use when creating a “Fuzzy search” or “Nearest match” query. It also comes in handy when trying to find and eliminate duplicate records. MySQL doesn’t come with a Levenshtein function. A few generous souls have created Levenshtein UDF’s: Joshua Drew, Sean Collins (Damerau-Levenshtein), and Nicholas Sherlock. I am providing compiled versions and some guidance on how to compile them yourself.

Traditional Levenshtein

levenshtein.zip
The zip file contains two UDF’s, one by Joshua Drew that comes with original C++ source code, a Win32 (compiled on Server 2008 with MySQL 5.5, Windows SDK v7.0A, and VC+ 2010 Express), a Win64 (compiled on Server 2008 with MySQL 5.5, Windows SDK v7.1, and VC+ 2010 Express) and Ubuntu (10.10 with MySQL 5.5) binary are present. The other, by Nicholas Sherlock, has a third argument for distance limit. This UDF comes with original Delphi code, Win32 binary (don’t know when/how it was compiled), and unfortunately no Win64 or Ubuntu binary.

Damerau-Levenshtein UDF

damlev.zip
The Damerau-Levenshtein metric is a slightly modified version of the Levenshtein metric, a description of the differences can be found on Wikipedia and on Sean Collins’ site.

There are three versions (damlev, damlevlim, damlevlim256) of this metric in the zip file, all created by Sean Collins. Visit his site for information on how to use each version. A Win32 (compiled on Server 2008 with MySQL 5.5, Windows SDK v7.0A, and VC+ 2010 Express), a Win64 (compiled on Server 2008 with MySQL 5.5, Windows SDK v7.1, and VC+ 2010 Express), and Ubuntu (10.10 with MySQL 5.5) binary are present.

Continue reading

Use PHP and LDAP to list members of an Active Directory group

An improved/updated version of this function was posted on 10/19/2011, get it here

PHP function that gets the members of an Active Directory group, and returns the data as an array.

Input for the function: group name, user name, password

<?php
// explode DN into array
function explode_dn($dn, $with_attributes=0)
{
    $result = ldap_explode_dn($dn, $with_attributes);
    //translate hex code into ascii again
    foreach($result as $key => $value) $result[$key] = preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $value);
    return $result;
}
 
// get members list from AD
function get_members($group,$user,$password) {
 
	// Active Directory server
	$ldap_host = "server.college.school.edu";
 
	// Active Directory DN
	$ldap_dn = "OU=Departments,DC=college,DC=school,DC=edu";
 
	// Domain, for purposes of constructing $user
	$ldap_usr_dom = "@college.school.edu";
 
	// connect and search ldap
	$ldap = ldap_connect($ldap_host) or die("Could not connect to LDAP");
	@ldap_bind($ldap, $user . $ldap_usr_dom, $password) or die("Could not bind to LDAP");
	$results = ldap_search($ldap,$ldap_dn, "cn=" . $group);
	$entries = ldap_get_entries($ldap, $results);
 
	$dirty = 0;
 
	// build array of members for this group, first item is count - skipped using $dirty
	foreach($entries[0]['member'] as $member) {
		if($dirty == 0) {
			$dirty = 1;
		} else {
			$member_dets = explode_dn($member);
			$members[] = str_replace("CN=","",$member_dets[0]);
		}
	}
 
	return $members;
}
?>
 
The Manager Group contains:<br />
<?php foreach(get_members("group name","user name","password") as $e) { // replace with your values
	echo $e . "<br />";
} ?>

Related Post: PHP login script using LDAP, verify group membership

Live Cams, great iPhone app for Blue Iris and other home surveillance software

A follow-up to How to set up home video surveillance for a few hundred dollars or less

Live Cams is a great iPhone app for viewing security cameras remotely. The app works with Blue Iris and other security camera software. In addition to showing your own cameras, Live Cams comes with links to thousands of public cameras around the world.