Create a bootable Ubuntu USB drive from an ISO in Mac OS X

Some months ago I burned a Xubuntu distro into a USB drive to use an old barebone computer (BTW I used this link as a guide).

usb-drive

To do that from a Mac OS X system first you have to convert the ISO image to a UDRW format:

$ hdiutil convert -format UDRW -o target xubuntu-10.04-desktop-i386.iso

Then insert the USB drive and list all connected disks:

$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *320.1 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            319.2 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                            Xubuntu 10.04 i3       *2.1 GB     disk1

Once you know the USB drive’s identifier (disk1 in my case) unmount it, inject the image you created before and eject the drive.

$ diskutil unmountDisk /dev/disk1
$ sudo dd if=target.dmg of=/dev/rdisk1 bs=1m
$ diskutil eject /dev/disk1

We can use now that drive to boot on any computer.

Raspberry Pi GPIO port to IDC26/DB-25 ribbon cable

Using a IDC26/DB-25 ribbon cable with the GPIO of a Raspberry Pi is quite useful. It fits perfect on the GPIO port. But there are 2 drawbacks:

  • GPIO7 is not connected because DB-25 port has only 25 pins and Raspberry Pi’s GPIO port has 26.
  • The pinout numbers on the DB-25 side does not match the pinout numbers in the GPIO side.

Raspberry Pi IDC26 DB-25

TL;DR: This is the pinout in the DB-25 side if you use a IDC26/DB-25 ribbon cable:

DB-25

In case you want to know why look first at the pinout of the Raspberry Pi’s GPIO:

basic-gpio-layout

And now the pinout correspondence on both DB-25 and IDC26 side of the ribbon cable:

DB-25 IDC26

As you can see the pin 2 in the GPIO port corresponds to the pin 14 in the DB-25 port, etc. This are the functions of every pin in the DB-25 port if you use a IDC26/DB-25 ribbon cable with your Raspberry Pi:

  1. 3.3V
  2. GPIO2 (I2C)
  3. GPIO3 (I2C)
  4. GPIO4
  5. GND
  6. GPIO17
  7. GPIO27
  8. GPIO22
  9. 3.3V
  10. GPIO10 (SPI)
  11. GPIO9 (SPI)
  12. GPIO11 (SPI)
  13. GND
  14. 5V
  15. 5V
  16. GND
  17. GPIO14 (UART)
  18. GPIO15 (UART)
  19. GPIO18 (PWM)
  20. GND
  21. GPIO23
  22. GPIO24
  23. GND
  24. GPIO25
  25. GPIO8 (SPI)

Raspberry Pi GPIO image by raspberrypi.org

http://es.wikipedia.org/wiki/Conector_IDC

http://es.wikipedia.org/wiki/D-sub

Using dbDelta with WordPress to create and alter tables

dbDelta is used in WordPress to create and update tables in the database and you will usually use it in the register_activation_hook with the plugin installation process. Either you want to create or update a table you always have to give dbDelta a CREATE TABLE SQL query. It will automatically detect that the table already exists in case of an update and do the necessary changes.

430px-WP3.8-ERD

This function is defined in wp-admin/includes/upgrade.php and you have to import it BEFORE calling dbDeta:

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

But this function is a little bit tricky. You can’t just give it any CREATE TABLE query. As pointed out in the documentation:

  • You must put each field on its own line in your SQL statement.
  • You must have two spaces between the words PRIMARY KEY and the definition of your primary key.
  • You must use the key word KEY rather than its synonym INDEX and you must include at least one KEY.
  • You must not use any apostrophes or backticks around field names.

Based on those premises, this SQL wouldn’t work and would SILENTLY do nothing:

global $wpdb;
$sql = "CREATE TABLE table_name(`id` int(10) NOT NULL AUTO_INCREMENT, `extra_id` int(5) NOT NULL,`username` tinytext NOT NULL);";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

As you can see all fields are in the same line, there is no PRIMARY KEY defined and field names use backticks. The correct SQL query would be:

global $wpdb;
$sql = "CREATE TABLE table_name (
    id int(10) NOT NULL AUTO_INCREMENT,
    extra_id int(5) NOT NULL,
    username tinytext NOT NULL,
    PRIMARY KEY  (id,extra_id)
);";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

I used this 2 field PRIMARY KEY example because there is another trick with dbDelta: there can’t be any spaces in the definition of the primary key.

Hope you find this useful. Those silent “errors” are pretty dificult to catch.

browscap and get_browser in PHP

If you want to know the capabilities of the current users browser in PHP you can use the get_browser() function.

mixed get_browser ([ string $user_agent [, bool $return_array = false ]] )

But first you have to configure the browscap option in php.ini with a browscap.ini file containing browsers information.

get_browser error

You can download different browscap.ini file versions from http://browscap.org/, copy it along with php.ini and then configure the browscap option with the ABSOLUTE path to it:

[browscap]
; http://php.net/browscap
browscap = /opt/local/etc/php5/full_php_browscap.ini

Once the web server is restarted verify it’s configured with php_info():

php_info-browscap

And then you may call get_browser(), for example with this:

$browser = get_browser();
var_dump($browser);

You’ll get something like this:

object(stdClass)[1]
  public 'browser_name_regex' => string '§^mozilla/5\.0 \(.*mac os x 10_9.*\) applewebkit/.* \(khtml, like gecko\).*chrome/36\..*safari/.*$§' (length=99)
  public 'browser_name_pattern' => string 'Mozilla/5.0 (*Mac OS X 10_9*) AppleWebKit/* (KHTML, like Gecko)*Chrome/36.*Safari/*' (length=83)
  public 'parent' => string 'Chrome 36.0' (length=11)
  public 'browser_bits' => string '32' (length=2)
  public 'platform' => string 'MacOSX' (length=6)
  public 'platform_version' => string '10.9' (length=4)
  public 'platform_description' => string 'Mac OS X' (length=8)
  public 'platform_bits' => string '32' (length=2)
  public 'platform_maker' => string 'Apple Inc' (length=9)
  public 'win32' => string '' (length=0)
  public 'device_name' => string 'Macintosh' (length=9)
  public 'device_maker' => string 'Apple Inc' (length=9)
  public 'device_code_name' => string 'Macintosh' (length=9)
  public 'device_brand_name' => string 'Apple' (length=5)
  public 'comment' => string 'Chrome 36.0' (length=11)
  public 'browser' => string 'Chrome' (length=6)
  public 'browser_type' => string 'Browser' (length=7)
  public 'browser_maker' => string 'Google Inc' (length=10)
  public 'version' => string '36.0' (length=4)
  public 'majorver' => string '36' (length=2)
  public 'frames' => string '1' (length=1)
  public 'iframes' => string '1' (length=1)
  public 'tables' => string '1' (length=1)
  public 'cookies' => string '1' (length=1)
  public 'javascript' => string '1' (length=1)
  public 'javaapplets' => string '1' (length=1)
  public 'cssversion' => string '3' (length=1)
  public 'device_type' => string 'Desktop' (length=7)
  public 'device_pointing_method' => string 'mouse' (length=5)
  public 'renderingengine_name' => string 'Blink' (length=5)
  public 'renderingengine_description' => string 'a WebKit Fork by Google' (length=23)
  public 'renderingengine_maker' => string 'Google Inc' (length=10)
  public 'browser_modus' => string 'unknown' (length=7)
  public 'minorver' => string '0' (length=1)
  public 'alpha' => string '' (length=0)
  public 'beta' => string '' (length=0)
  public 'win16' => string '' (length=0)
  public 'win64' => string '' (length=0)
  public 'backgroundsounds' => string '' (length=0)
  public 'vbscript' => string '' (length=0)
  public 'activexcontrols' => string '' (length=0)
  public 'ismobiledevice' => string '' (length=0)
  public 'istablet' => string '' (length=0)
  public 'issyndicationreader' => string '' (length=0)
  public 'crawler' => string '' (length=0)
  public 'aolversion' => string '0' (length=1)
  public 'renderingengine_version' => string 'unknown' (length=7)

Ref: http://php.net/manual/en/function.get-browser.php
http://php.net/manual/en/misc.configuration.php#ini.browscap

Delete WordPress old revisions

WordPress stores revisions of the posts, pages, etc. while you write them. Without even knowing you may have about 5 or more revisions of each entry. And each revisions represents one entry in your posts database table with post_type column as revision.

revisions

The first thing I thought was to simply delete those old revisions that had post_type equals revision:

DELETE * FROM wp_posts WHERE post_type='revision';

Then, just in case, I did a search and found out I was not completely right. As Ozh explains here:

Note that the above SQL query just deletes post marked as revisions. If for some reason you associated a revision with a tag or a category that was then removed when the final post was published, you will have extra entries in other tables such as terms.

The query then should look like this:

DELETE p, tr, c
FROM wp_posts p
LEFT JOIN wp_term_relationships tr ON (p.ID = tr.object_id)
LEFT JOIN wp_postmeta pm ON (p.ID = pm.post_id)
WHERE p.post_type = 'revision';

Note: use your table prefix and make a backup first just in case!

You may also disable the revision feature (but I wouldn’t recommend it) in the wp-config.php file:

define('WP_POST_REVISIONS', false);

Or just limit the amount of revisions to a fixed number:

define('WP_POST_REVISIONS', 5);

Ref: http://weblogtoolscollection.com/archives/2010/09/28/deleting-wordpress-revisions/