tag:blogger.com,1999:blog-67294833760572903592024-02-07T15:16:55.309+01:00Problem HerculesProblems encountered, solutions found. Simple.Sam Critchleyhttp://www.blogger.com/profile/18282256632959813584noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-6729483376057290359.post-2239772893582079812011-04-12T18:06:00.005+02:002011-07-31T23:42:22.767+02:00Accessing Google's Content API for Shopping using OAuth in PHP***Update 31st July 2011 - edited the post to replace my Google API account number with "XXXXXXX" in a couple of URIs - you'll need to replace with your own to get this working. Thanks to Robert for suggesting this in the comments section.****<br />
<br />
Trying to get OAuth working against Google's APIs using the standard PHP libraries like <a href="http://code.google.com/p/oauth-php/">oauth-php</a> and the Zend library supplied by Google was turning out to be a nightmare. Nothing would work and I kept running into problems. In the end I built scripts based on <a href="http://code.google.com/p/oauth-php/">oauth-php</a> using the following useful pages to guide me:<br />
<div><br />
</div><div><ul><li><a href="http://code.google.com/apis/shopping/content/getting-started/usingapi-products.html">Google Content API for Shopping documentation</a></li>
<li><a href="http://code.google.com/apis/accounts/docs/OAuth_ref.html">Google OAuth 1.0 API Reference</a></li>
<li>Google's very useful <a href="http://googlecodesamples.com/oauth_playground/">OAuth Playground</a></li>
<li><a href="http://code.google.com/apis/gdata/docs/2.0/reference.html">Google Data Protocol Reference</a></li>
<li>Elance's <a href="http://www.elance.com/p/api/examples/oauth/php">documentation</a> on how to use OAuth to access their own API</li>
</ul><div>After installing the <a href="http://code.google.com/p/oauth-php/">oauth-php</a> library and running the MySQL store install script in the library/store/mysql directory of the library files in order to set up the right MySQL database structure, I was heading in the right direction. Step-by-step, through a lot of trial and error, and by watching the apache and MySQL logs, I got to three scripts which are shown below.<br />
<br />
<b><u>1. Google OAuth Consumer Generation Script</u></b><br />
name: test-oauth-google-consumer.php<br />
Call this script in your browser and it will take you to Google's OAuth interface where you grant your application permission to access Google services which use OAuth (in this case the Content API for Shopping). It will then redirect you back to your own site. Meanwhile, in the background the php-oauth library is taking care of getting all the right token details etc into the database.<br />
<br />
<pre><?php
// Script name = test-oauth-google-consumer.php
//
// Script editor Sam Critchley - sam@l3bv.com
//
// This is a script to manage OAuth against the Google OAuth service.
// It uses php-oauth library and a set of tips gained from a web page at
// http://www.elance.com/p/api/examples/oauth/php
// In doing so, it pretty much follows the Google OAuth flow which is at
// http://code.google.com/apis/accounts/docs/OAuth_ref.html
// First include the relevant files from the oauth-php library which is in
// <YOUR_PATH>/oauth-php/library
// Also make sure you include OAuthRequestLogger to log requests
require_once '/oauth-php/library/OAuthDiscovery.php';
require_once '/oauth-php/library/OAuthRequester.php';
require_once '/oauth-php/library/OAuthRequestVerifier.php';
require_once '/oauth-php/library/OAuthServer.php';
require_once '/oauth-php/library/OAuthRequestLogger.php';
// Now add some code to initialise the OAuth store, with oauth-php connecting
// to the MySQL database using the set of parameters supplied
// N.B. Make sure you've run the install script in the oauth-php library/store/mysql
// directory to install the right tables in the database
$store_options = array('server' => 'localhost', 'username' => '<YOUR_MYSQL_USERNAME>',
'password' => '<YOUR_MYSQL_PASSWORD>', 'database' => '<YOUR_MYSQL_DATABASE');
$store = OAuthStore::instance("MySQL", $store_options);
// Now register the Google OAuth API with the local OAuth store. It first calls
// $store->getServer() to test if the server is already registered, and if it isn't
// then it registers it with the OAuth store.
// It's necessary to fill in the values below such as consumer_key
// For Google you get these from your domain management page at https://www.google.com/accounts/ManageDomains
// First the consumer key e.g. $consumer_key = 'www.example.com';
$consumer_key = '<YOUR_CONSUMER_KEY>';
// Then the consumer secret e.g. $consumer_secret = 'GRp9MrOW4+HHWKoRI34Le609'
$consumer_secret = '<YOUR_CONSUMER_SECRET>';
// Set the user_id for use in the database. This can, of course, be dynamic if you've got many many users
$user_id = 1;
// The $params values get added to the request
// Add the API scope which you get from the Content API for Shopping page at:
// http://code.google.com/apis/shopping/content/getting-started/usingapi-products.html
// NOTE - the scope will vary if you are accessing other Google APIs than the
// Content API for Shopping, so you'll need to change it
//
$scope = "https://www.googleapis.com/auth/structuredcontent"; // fill with the scope
// If you set $xoauth_displayname it sets the description on the Google verification
// page and gives you an error about not being able to verify the application as it's
// "on your computer and not on a registered web service"
// $xoauth_displayname = ('<YOUR_SERVICE_DISPLAY_NAME');
//
// The $params array if you're going to include the xoauth_displayname in it - if you don't
// it just uses the default from your domain management page
//$params = array('scope' => $scope, 'oauth_callback' => $callback_url, 'xoauth_displayname' => $xoauth_displayname);
//
// Don't forget to include the oauth_callback as Google requires it at this stage rather than later
$callback_url = "http://<YOUR_WEB_SERVER>/test-oauth-google-consumer-callback.php?user_id=1";
$params = array('scope' => $scope, 'oauth_callback' => $callback_url);
$store = OAuthStore::instance("MySQL", $store_options);
$server = null;
try {
$server = $store->getServer($consumer_key, $user_id);
} catch (OAuthException2 $e) {
$server = array(
'consumer_key' => $consumer_key,
'consumer_secret' => $consumer_secret,
// Note that server_uri needs to be the URI of the API you'll be accessing or else it will throw
// an error which you'll have to use MySQL to debug. In this case the URI is obtained from the
// Google Content API for Shopping documentation at
// http://code.google.com/apis/shopping/content/getting-started/usingapi-products.html
// It will be different for different Google APIs
'server_uri' => 'https://content.googleapis.com/content/v1/XXXXXXX/items/products/generic',
'signature_methods' => array('HMAC-SHA1'),
'request_token_uri' => 'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_uri' => 'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_token_uri' => 'https://www.google.com/accounts/OAuthGetAccessToken'
);
$store->updateServer($server, $user_id);
}
// Now we've got everything lined up locally including all the variables necessary to
// go out and hit the Google OAuth URI, all you have to do is call OAuthRequester and
// it goes out and does it for you. Don't forget to include $params in the request
// - it wasn't included by default in the Elance documentation
// Also don't forget that if you're missing one of the parameters defined in the Google
// OAuth documentation then you will get a 400 exception error saying something like:
//
// Unexpected result from the server "https://www.google.com/accounts/OAuthGetRequestToken" (400) while requesting a request token
//
// Use the new error handling method in PHP with tryand catch
try {
$token = OAuthRequester::requestRequestToken($consumer_key, $user_id, $params);
}
catch(OAuthException2 $e)
{
echo "Exception:<br>" . $e->getMessage();
}
// If this works successfully the oauth-php library will get back info from Google
// containing the token, token_secret, and authorize_uri values. You can test this by
// printing out the array $token, but note that it doesn't contain the token_secret
// although oauth-php should have grabbed this. You can check by looking in the
// oauth_consumer_registry and oauth_consumer_token tables in MySQL as this happens
// and watch the entries in the tables changing during the process
// TEST print out the $token array, comment this out if you don't want that at the moment
/*
echo '<br><br>OAuthRequester response:<br>';
echo '<PRE>';
print_r($token);
echo '</PRE>';
echo '<br><br>';
*/
// Now that the token and token_secret have been obtained from Google, redirect the
// user to the authorisation URI to run the OAuthAuthorizeToken process
//
// Then construct the right authorisation uri from the values at the beginning
$authorization_uri = $token['authorize_uri'] . '?oauth_token=' . $token['token'];
// Then redirect the user to it
header("Location: " . $authorization_uri);
// Then exit the script
exit();
?>
</pre></div><div><br />
<b><u>2. Google OAuth Callback Script</u></b><br />
name: test-oauth-google-consumer-callback.php<br />
After you've successfully authenticated over at Google, you'll be redirected back to the callback script running on your server. As well as displaying a success message the script will extract the OAuth access token Google sends back in the URL (as a GET parameter) and will store it in the database.<br />
<br />
<pre><?php
// Script name = test-oauth-google-consumer-callback.php
//
// Script editor Sam Critchley - sam@l3bv.com
// This is a callback script for managing OAuth against the Google OAuth service.
// You will be redirected to this page by Google if authenticating your signup
// request is successful
//
// The script uses php-oauth library and a set of tips gained from a web page at
// http://www.elance.com/p/api/examples/oauth/php
// In doing so, it pretty much follows the Google OAuth flow which is at
// http://code.google.com/apis/accounts/docs/OAuth_ref.html
// First include the relevant files from the oauth-php library which is in
// <YOUR_PATH>/oauth-php/library
// Also make sure you include OAuthRequestLogger to log requests
require_once '/oauth-php/library/OAuthDiscovery.php';
require_once '/oauth-php/library/OAuthRequester.php';
require_once '/oauth-php/library/OAuthRequestVerifier.php';
require_once '/oauth-php/library/OAuthServer.php';
require_once '/oauth-php/library/OAuthRequestLogger.php';
// Now add some code to initialise the OAuth store, with oauth-php connecting
// to the MySQL database using the set of parameters supplied
// N.B. Make sure you've run the install script in the oauth-php library/store/mysql
// directory to install the right tables in the database
$store_options = array('server' => 'localhost', 'username' => '<YOUR_MYSQL_USERNAME>',
'password' => '<YOUR_MYSQL_PASSWORD>', 'database' => '<YOUR_MYSQL_DATABASE');
$store = OAuthStore::instance("MySQL", $store_options);
// Now call OAuthRequester::requestAccessToken() in oauth-php to exchange your Request Token for an Access Token
// It's necessary to fill in the values below such as consumer_key
// First the consumer key e.g. $consumer_key = 'www.example.com';
$consumer_key = '<YOUR_CONSUMER_KEY>';
// Grab the user_id from the incoming GET value in the URL
$user_id = $_GET['user_id'];
// Now process the options received as the Google stuff returns
$options = array();
$options['oauth_verifier'] = $_GET['oauth_verifier'];
try
{
OAuthRequester::requestAccessToken($consumer_key, $_GET['oauth_token'], $user_id, 'POST', $options);
}
catch (OAuthException $e)
{
echo "Exception:<br>" . $e->getMessage();
}
// If OAuthRequester::requestAccessToken() does not throw an exception, then the request was successful.
// Google grants your application an Access Token and an Access Token Secret, which oauth-php inserts into
// the OAuth store. These values will be included with and used to sign all requests you make against any
// authenticated methods.
echo 'Google account request successful';
?>
</pre></div><div><br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><u>3. Content API for Shopping query script</u></b></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">name: test-oauth-google-shopping-api.php</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">This is a simple script which goes and queries the Google Content API for Shopping for all the items you have listed. The content is returned in an ATOM feed so you may need to "view source" in your browser (or modify the script) to be able to view the items.</div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
<pre><?php
// Script name = test-oauth-google-shopping-api.php
//
// Script editor Sam Critchley - sam@l3bv.com
//
// This is a script to manage OAuth against the Google OAuth service.
// It uses php-oauth library and a set of tips gained from a web page at
// http://www.elance.com/p/api/examples/oauth/php
// In doing so, it pretty much follows the Google OAuth flow which is at
// http://code.google.com/apis/accounts/docs/OAuth_ref.html
// First include the relevant files from the oauth-php library which is in
// <YOUR_PATH>/oauth-php/library
// Also make sure you include OAuthRequestLogger to log requests
require_once '/oauth-php/library/OAuthDiscovery.php';
require_once '/oauth-php/library/OAuthRequester.php';
require_once '/oauth-php/library/OAuthRequestVerifier.php';
require_once '/oauth-php/library/OAuthServer.php';
require_once '/oauth-php/library/OAuthRequestLogger.php';
// Now add some code to initialise the OAuth store, with oauth-php connecting
// to the MySQL database using the set of parameters supplied
// N.B. Make sure you've run the install script in the oauth-php library/store/mysql
// directory to install the right tables in the database
$store_options = array('server' => 'localhost', 'username' => '<YOUR_MYSQL_USERNAME>',
'password' => '<YOUR_MYSQL_PASSWORD>', 'database' => '<YOUR_MYSQL_DATABASE');
// Set the user_id (used in the OAuth MySQL store) as an example for this script
$user_id = 1;
$store = OAuthStore::instance("MySQL", $store_options);
// Need to set a couple of options including (optionally) GData-Version=1.0
// see http://code.google.com/apis/gdata/docs/developers-guide.html for details
$options = array('max-results' => '10', 'v' => '1.0');
// Run the API call using the php-oauth library
$manage_request = new OAuthRequester("https://content.googleapis.com/content/v1/XXXXXXX/items/products/generic", 'GET', $options);
try {
$result = $manage_request->doRequest($user_id);
} catch (OAuthException $e){
// Handle error if it occurs (will appear in your apache logs).
echo "Exception:<br>" . $e->getMessage();
}
/*
The output from <span style="font-family:monospace;">doRequest()</span> is the full array of header and body values
returned by the cUrl HTTP library. We access the JSON response using the body array key.
*/
// Print out the results of the API poll
// These are in an ATOM feed so in a normal browser you'll need to
// look at the page source if the content on screen is blank
$text = $result['body'];
echo $text;
?>
</pre><br />
</div><div>I hope these scripts are useful. Leave a comment if you have any questions.</div><br />
</div><br />
</div>Sam Critchleyhttp://www.blogger.com/profile/18282256632959813584noreply@blogger.com9tag:blogger.com,1999:blog-6729483376057290359.post-12211650355077233842011-03-04T16:51:00.000+01:002013-12-10T11:28:18.832+01:00Installing a UDF in MySQL in Mac OS X Snow LeopardI was having a bit of trouble getting a MySQL user-defined function (UDF) running in MySQL in Snow Leopard on my Mac. In the end I came across <a href="http://www.bytebot.net/blog/archives/2008/04/14/compiling-mysql-udfs-on-mac-os-x">this page</a> and its comments, which helped a lot. So here's the procedure:<br />
<br />
1. Move the C++ UDF file into /usr/local/mysql/bin on your Mac. You should know how to do this in terminal, if not, use the "mv" or "cp" command.<br />
<br />
2. Compile the C++ UDF file using g++ - here's the command I used:<br />
<br />
<i>> sudo g++ -Wall -bundle -bundle_loader /usr/local/mysql/bin/mysqld -o udf_name.so `/usr/local/mysql/bin/mysql_config --cflags` udf_name.cc</i><br />
<br />
This should give you a file called udf.so in the /usr/local/mysql/bin directory. Note that when you compile on Mac OS X the compiler automatically creates an associated directory called ufo.so.dSYM - you can find out why <a href="http://stackoverflow.com/questions/584825/dsym-directories-while-compiling-c-code-in-macos">here</a>.<br />
<br />
3. Move the udf.so file and the udf.so.dSYM directory into the MySQL plugin directory in /usr/local/mysql/lib/plugin:<br />
<br />
<br />
<i>> sudo mv udf.so ../lib/plugin/</i><br />
<i>> sudo mv udf.so.dSYM/ ../lib/plugin/</i><br />
<i><br />
</i><br />
4. Install the function in MySQL, making sure you're running a MySQL user with full privileges:<br />
<br />
<br />
<i>mysql> CREATE FUNCTION udf_name RETURNS REAL SONAME "udf.so";</i><br />
<i>Query OK, 0 rows affected (0.02 sec)</i><br />
<i><br />
</i><br />
Once you've done this you should be able to use the UDF in your MySQL queries.Sam Critchleyhttp://www.blogger.com/profile/18282256632959813584noreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-26332894976512261432010-10-17T14:25:00.008+02:002010-11-05T14:02:52.668+01:00Exporting call logs, text messages and other info from a BlackberryI need a way to extract the record of calls I've made and received on my Blackberry. It would also be handy to be able to archive old text (SMS) messages and other info. In addition to providing a good record of the time and duration of your calls, it's also nice to have an archive of your text messages going back over time.<br />
<div><br />
</div><div>After searching for a while, I came across a couple of ways to do this. The first way is an app called <a href="http://www.sbsh.net/products/blackberry/historia">SBSH Historia</a> which you can buy on Blackberry App World for a couple of €€/$$. This looks like a neat app, and very professional, but I didn't need to pay for it in the end as I found a way to do it for free using the Desktop Manager software on my Mac and a Java app called <a href="http://code.google.com/p/ipddump/">ipddump</a> I found on Google Code.</div><div><br />
</div><div>Here are the instructions for how to do it on a Mac. The Windows procedure is broadly similar.<br />
<a name='more'></a></div><div><br />
</div><div><b>Step 1 - Extracting the Call Log to your Mac</b></div><div>1. Start Blackberry Desktop Manager on your Mac.</div><div>2. Now plug your Blackberry into your Mac (or connect via Bluetooth if that's the way you do it). If it normally auto-syncs when you plug it in, let it finish.</div><div>3. In Blackberry Desktop Manager, go to Device -> Back Up Data...</div><div>4. Click the "Selected Data" option, scroll down to "Phone Call Logs" and select it by clicking the check box.</div><div>5. Make sure the "Encrypt backup file" box below is NOT selected.</div><div>6. Alter the "Backup File Name" so you the file is clearly identifiable - I do this by putting "Call Log" on the end of the filename.</div><div>7. Click "Back Up" and Blackberry Desktop Manager will get to work extracting the log to your computer. Wait until it's done.</div><div>8. Now go to the Blackberry Desktop Manager menu in the app and select Preferences. Make a note of where backup files are stored in the Backup Location box. It's usually /Users/<username>/Documents/Blackberry Backups but you could have specified another location.</username></div><div><br />
</div><div>On a Windows PC, similar steps should apply in Desktop Manager.</div><div><br />
</div><div><b>Step 2 - Making the Desktop Backup File Readable</b></div><div>Blackberry Desktop Manager stores its log files in a type of file called an IPD file, which is some kind of old format used for storing pager messages back 10-15 years ago. The IPD file is kept inside a folder structure inside the zipped-up Backup file itself. So you're going to have to find the file and extract it before you can view it. Here's how you do it:</div><div><br />
</div><div>1. Open Finder on your Mac and navigate to the location where Blackberry Desktop Manager stores your backup files. On my Mac this is /Users/<username>/Documents/Blackberry Backups - you should be able to see it in your home directory.</username></div><div>2. Locate the backup file you have just created - if you followed the way I recommended it will easily identifiable as it will have "Call Log" at the end of the name. The file will end with .bbb (on a PC this may just be .ipd).</div><div>3. Copy the backup file to somewhere you can work on it easily. Your desktop is a pretty easy place.</div><div>4. Once you've moved the file, click on it once and change the .bbb part of the filename to .zip - yes, that's right, it's already zipped up and you're changing the filename so that your zip program will recognise it.</div><div>5. Now double click the zip file to unzip it. It will leave you with a folder of files.</div><div>6. Double click the folder and then click on the "Databases" sub-folder. You should see a file called <i>Databases.ipd</i> - this is the file you need.</div><div><br />
</div><div><b>Step 3 - Viewing and Saving the Call Log to Another Format</b></div><div>Now you've isolated your call log file, you need to be able to view it and save it in a useful format. I use the excellent <a href="http://code.google.com/p/ipddump/">ipddump</a> utility for this. As it's a Java executable it should work equally well on a Mac as on Windows. Here's how to do it.</div><div><br />
</div><div>1. Go to the <a href="http://code.google.com/p/ipddump/">ipddump</a> site on Google Code and download the latest version to your usual download location on your Mac.</div><div>2. Double-click the IpdDumpXXXX,jar file to run it. As long as you have a Java Runtime installed this should work fine, although it may take a few seconds to start up.</div><div>3. You should see the IPDdump program window open up.</div><div>4. Click on File -> Open and then navigate to where you unzipped your Desktop Manager backup file in the previous section.</div><div>5. Double-click the Databases.ipd file and ipddump should read in the call log.</div><div>6. Now you can select all or some of your calls and then go to File -> Save Selected As to save them as a text file, XML file or CSV doc for import into a spreadsheet.</div><div><br />
</div><div>On a Windows machine the procedure should be pretty similar, just find the .ipd file and open it with ipddump.</div><div><br />
</div><div>Hope this helps, and let me know if there are any comments or questions.</div>Sam Critchleyhttp://www.blogger.com/profile/15068419712042530197noreply@blogger.com22tag:blogger.com,1999:blog-6729483376057290359.post-17979847680925453452010-03-23T11:15:00.002+01:002010-03-23T11:17:30.287+01:00Carriage return in Excel on the MacIf you are entering text in a cell in Excel in Mac Office 2008 (or other versions), hitting the return key will move the focus to the cell below. To enter a carriage return inside the cell when typing, hit ctrl-option-return instead.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-6729483376057290359.post-62467051657963135442010-02-10T21:55:00.002+01:002010-02-10T22:09:12.034+01:00Photos appear blank in iPhoto on the MacAt home I've got an iMac (2009 version). We run iPhoto on it to manage our family photos - the photo library lives in a shared directory - both of us have separate accounts on the computer but we want to share the same photo library. Occasionally we run into a problem where you can see photo thumbnails in iPhoto, but when you double-click to open the photo, it goes blank and you just see a black screen where the photo should be.<div><br /></div><div>After some searching I managed to find a few other people who'd run into the same problem. The solution is to rebuild your photo library in iPhoto. Exit the application, whilst holding down the command and option keys on the keyboard, restart iPhoto. You will see a prompt asking which parts of the library you'd like to rebuild. For me, examining and repairing iPhoto library permissions is what's worked.</div><div><br /></div><div>If you want to know more you can find an Apple support article <a href="http://support.apple.com/kb/HT2638">here</a>. </div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-16133961819279394952009-12-01T10:47:00.003+01:002010-11-05T13:58:42.650+01:00Using MySQL to retrieve substring from the middle of a string<div>In MySQL it's hard to grab part of a string out of the middle of a VARCHAR or other text-based field, especially if you don't know exactly how far into the string the text you want begins, and it's of variable length, so you don't know where it ends either. Here's a way to do it.<br />
<a name='more'></a></div><div><br />
</div><div>Here's an example. The following two strings are mobile device user agent strings captured on a web server - one is for an iPhone and the other for the iPod Touch:</div><div><br />
</div><span class="Apple-style-span" style="font-family: monospace, sans-serif; font-size: 13px; line-height: 19px;">Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3</span><br />
<div><span class="Apple-style-span" style="font-family: monospace, sans-serif; font-size: 100%;"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">Mozilla/5.0 (iPod; U; CPU iPhone OS 3_1_1 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Mobile/7C145<br />
</span></span><br />
<div>Let's say you're recording hundreds of these in a column in MySQL and you want to give a list of every AppleWebKit version out there. How do you extract just the number from after the part which says "AppleWebKit/" and before the "(KHTML..."?</div><div><br />
</div><div>To solve this problem, you can use a nested combination of MySQL's SUBSTRING and LOCATE operators:</div><div><br />
</div><div><i>mysql> SELECT</i></div><div><span class="Apple-style-span" style="font-style: italic;">SUBSTRING(column_name,</span></div><div><i> LOCATE('AppleWebKit/', column_name) +12,</i></div><div><i> (LOCATE(' (KHTML', column_name)) - (LOCATE('AppleWebKit/', column_name) +12)</i></div><div><i>)</i></div><div><i>AS string_you_need</i></div><div><i>FROM table_name</i></div><div><i>;</i></div><div><i><br />
</i></div><div>In plain English, this says "select the substring located in <i>column_name</i> which i) <b>starts</b> at the position number which is 12 positions after the start of the text '<i>AppleWebKit/</i>' and ii) <b>ends</b> at the position number which is the position of the beginning of the text '<i> (KHTML</i>' MINUS the position number which is 12 positions after the start of the text '<i>AppleWebKit/</i>' ".</div><div><br />
</div><div>This will give you a result looking like this:</div><div><br />
</div><div><div></div>+----------------------+<br />
<div></div></div><div>| string_you_need |</div><div>+----------------------+</div><div>| 420.1 |</div><div>| 528.18 |</div><div>+----------------------+</div><div><br />
</div><div><div>You can of course supplement this using GROUP BY and ORDER BY operators when working on a larger number of rows.</div><div><br />
</div></div><div><br />
</div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-35618314203158697622009-11-17T11:29:00.004+01:002011-09-16T14:55:04.294+02:00Capturing screenshots on your Blackberry****UPDATE September 16th 2011 - download link updated****<br />
<br />
Ever since I first got a Blackberry I've been looking for a good way to capture screenshots of apps running on the device. Including, of course, our very own <a href="http://www.gypsii.com/">GyPSii</a>. Now, thanks to Amit Agarwal's <a href="http://www.labnol.org/gadgets/capture-blackberry-screenshot-images/6192/">blog entry</a>, I've found it.<br />
<a name='more'></a><br />
<div><br />
</div><div>Just point your Blackberry browser at <a href="http://www.captureitota.com/">http://www.captureitota.com/</a> and install the free CaptureIt app. Then a "CaptureIt" item will appear in your Blackberry menu (when you hit the Blackberry key on your device) in most places. Select it and CaptureIt will grab a screenshot and save it in your default photo location. You can then do whatever you do with all your other photos - send it, save it, delete it, whatever. Great stuff!</div><div><br />
</div><div>In some apps you can't see a CaptureIt menu item when you hit the Blackberry key. Here's how to get around that. On your Blackberry, go to Options -> Screen/Keyboard and scroll down to the convenience key section. Now assign one of your convenience keys to the CaptureIt application. Hit save. Now, when you hit the convenience key CaptureIt will grab a screenshot and save it for you. Hey presto! Simple hey?</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-80469491743779924402009-09-25T11:48:00.005+02:002010-01-29T11:59:43.905+01:00Vanishing formula bar in Mac Office Excel 2008A couple of weeks ago my formula bar in Excel 2008 on my Mac just vanished into thin air - gone. I tried various remedies to get it to reappear, but none worked, including the obvious, turning on "formula bar" in the view menu. Eventually I managed to track down a Macrumors forum <a href="http://forums.macrumors.com/archive/index.php/t-188587.html">thread</a> where someone had fixed the problem. Here's what you do:<br /><br />- Close Excel and any other running Office apps<br />- In Finder, go to your home directory and then to <your>/Library/Preferences/Microsoft/Office 2008/<br />- Delete the file called "Excel Toolbars"<br />- Restart Excel<br /><br />This should restore the formula bar for you.</your>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-18964647067327248502009-08-06T10:55:00.003+02:002010-11-05T14:00:30.067+01:00Getting MySQL running with PHP on a MacI've just been trying to get PHP and MySQL running with Apache on a Mac (PHP 5.2.8 and MySQL 5.1.33 running OS X 10.5.7). Somehow I kept running into the following error when trying to get a PHP script to connect to MySQL:<br />
<br />
<h3 class="entry-header" style="font-style: italic;"><span class="Apple-style-span" style="font-size: medium;">mysql_connect(): Can't connect to local MySQL server through socket '/var/mysql/mysql.sock'</span></h3><div><span class="Apple-style-span" style="font-size: medium;">Here's how I fixed it.<a name='more'></a></span></div><div><span class="Apple-style-span" style="font-size: medium;"><br />
</span></div>After a bit of research I tracked this down to a difference between PHP and MySQL on the Mac. PHP defaults to look at /var/tmp/mysql.sock for its connection, but MySQL on the Mac sets it up at /private/tmp/mysql.sock instead.<br />
<br />
The solution is to edit your php.ini file (after making a backup copy first in case something goes wrong, and looking for the line for mysql.default_socket, which you should change so it looks like this:<br />
<br />
<span style="font-style: italic;">; Default socket name for local MySQL connects. If empty, uses the built-in</span><br />
<span style="font-style: italic;">; MySQL defaults.</span><br />
<span style="font-style: italic;">mysql.default_socket = /private/tmp/mysql.sock</span><br />
<br />
See an article <a href="http://www.idealog.us/2006/05/how_to_fixwarni.html">here</a> for more details. There's also a handy test script <a href="http://www.washington.edu/computing/web/publishing/mysql-script.html">here</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6729483376057290359.post-39785710406957284272009-08-03T12:59:00.021+02:002010-11-05T14:02:00.558+01:00How to configure an Airport on/off shortcut key on a Mac<span style="font-size: 130%; font-weight: bold;"></span><br />
<div><span style="font-weight: bold;">****Update - 10th February 2010****</span></div><div><span style="font-size: 130%; font-weight: bold;"><span class="Apple-style-span" style="font-size: 16px; font-weight: normal;">This worked well in Leopard, but I haven't got it to work since upgrading to Snow Leopard. Does anyone have a fix?</span></span></div><div><span style="font-size: 130%; font-weight: bold;"><br />
</span></div><span style="font-size: 130%; font-weight: bold;">The Problem</span><br />
One of the things which has always bugged me about my Mac is the lack of a shortcut key to turn the Airport WiFi on and off. At home I connect using WiFi and in the office I plug into a wired ethernet connection, so I wanted to be able to turn the Airport on or off with a shortcut key instead of having to use my fat fingers and the mouse to click on the fiddly little Airport symbol in the menu bar. Unfortunately, Apple didn't build an Airport shortcut key into OS X. I'd been looking for a solution to this problem for ages, and now I've finally got it worked out.<br />
<a name='more'></a><br />
<br />
<span style="font-size: 130%; font-weight: bold;">What You'll Need</span><br />
<ol><li><a href="http://free.abracode.com/cmworkshop/on_my_command.html">OnMyCommand</a> (OMC) - a great tool which allows you to run Unix commands (which you normally type in terminal on your Mac) with the click of a mouse or using a shortcut key. You'll be using OMC's OMCedit and Shortcuts applications.<br />
</li>
<li>Admin user permissions on your Mac - or at least the ability to run commands using "sudo" in terminal.<br />
</li>
<li>Your trusty Mac.</li>
<li>A little bit of confidence. Typing system-level commands into your machine shouldn't scare you.<br />
</li>
</ol><br />
<span style="font-size: 130%; font-weight: bold;">What You'll End Up With</span><br />
At the end of this exercise you'll be able to use a keyboard shortcut, ⌘-ALT-W, to turn Airport (W for Wireless) on, and ⌘-ALT-Q (for Quit) to turn it off.<br />
<br />
<span style="font-size: 130%; font-weight: bold;">Here's What You Have To Do</span><br />
1. Download and install <a href="http://free.abracode.com/cmworkshop/on_my_command.html">OMC</a> on your Mac<br />
OMC is a utility which allows you to run Unix (terminal) commands on your apple from inside a context menu. With this app, you can ⌘-click or right-click anywhere on your desktop and in various applications, and run Unix commands, start applications etc through the GUI. Here's a good <a href="http://www.kadavy.net/blog/posts/onmycommand-puts-your-most-common-tasks-a-right-click-away/">tutorial</a>. OMC comes with two applications bundled - <a href="http://free.abracode.com/cmworkshop/omcedit.html">OMCEdit</a> and Shortcuts. OMCEdit gives you a GUI editor to create and change the script files which OMC uses to run Unix.<br />
<br />
2. Get familiar with the <span style="font-style: italic;">networksetup</span> command<br />
MAC OS X has a Unix command you can run in terminal which turns your Airport device on or off. You'll need to get familiar with what it does. Here's how it works:<br />
<ul><li>Start the Terminal app on your mac<br />
</li>
<li>Type in "sudo networksetup -setairportpower off" and hit return<br />
</li>
<li>Enter the password when asked</li>
<li>Airport on your Mac will turn off</li>
<li>Type in "sudo networksetup -setairportpower on"</li>
<li>Airport turns on again</li>
</ul>Note that this command requires system-level priviledges. The "sudo" part of the command tells the Mac to run the command as root (admin) user. If you don't have admin access, you won't be able to run it.<br />
<br />
3. Write an "Airport On" OMC script using OMCEdit<br />
Using OMCEdit you're going to write a script which runs the Unix command you tried in the step above. Here's how:<br />
<br />
<ul><li>Start the OMCEdit application. If you can't find it, it's in the OMC application folder which got added when you downloaded and installed OMC (step 1 above).</li>
<li>Create a new OMC command. Go to Command => New in OMCEdit. A new command window will open called "Untitled":<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhScw9Hesn1aW9ekWsXcY-MReDdwfx1fIDvF7n5sHLdNGCTW3wQZTRLGQa1naDvzT-KADBxCfqI62i3VAj9JZU2QyOBOjIn9D2Rsio6GvzvDE2jvGEzkn4QD-1JI7Y6xa8TFhaHF-alsgqg/s1600-h/OMC-new-command.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365735454653485074" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhScw9Hesn1aW9ekWsXcY-MReDdwfx1fIDvF7n5sHLdNGCTW3wQZTRLGQa1naDvzT-KADBxCfqI62i3VAj9JZU2QyOBOjIn9D2Rsio6GvzvDE2jvGEzkn4QD-1JI7Y6xa8TFhaHF-alsgqg/s320/OMC-new-command.jpg" style="cursor: pointer; display: block; height: 185px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
</ul><ul><li>The first thing I do now is change the name of the command to "Turn airport on" by typing the name into the "Command Name" box, then hit save:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-wX7nrDrS9TFfDM1I6UodkXXugBDvQfZ3IrcJk50Bj5JUWbE9pntfhjzHK-RRe-ZgU51dYFfuhZLDNTenwpNzwtsFVGi8MujuRTj3eJKxCFTLwq1pVuBBrBL8xre2SRvf99GgdjXW4t5x/s1600-h/OMC-2-command-name.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365737044733683458" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-wX7nrDrS9TFfDM1I6UodkXXugBDvQfZ3IrcJk50Bj5JUWbE9pntfhjzHK-RRe-ZgU51dYFfuhZLDNTenwpNzwtsFVGi8MujuRTj3eJKxCFTLwq1pVuBBrBL8xre2SRvf99GgdjXW4t5x/s320/OMC-2-command-name.jpg" style="cursor: pointer; display: block; height: 185px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
</ul><ul><li>Now you need to configure the OMC command to run the <span style="font-style: italic;">networksetup</span> command as before. I've also added a <span style="font-style: italic;">sudo -K</span> line to clear the sudo password cache. This adds extra security. Here's the screenshot:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLBxmi-iwvlZDrfiwXYtsFH4uw0mxKScw98TlWFfOGty4X8T7Gt4g7KZy3yakaqDH8dByNO11pVZ23bCWhPeNjcwpnfvgcOcX12bTIT3f5g49TXKFLJRI0XtFR9zUvHXwxNYJPRWFn8v13/s1600-h/OMC-3-general.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365738017087739442" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLBxmi-iwvlZDrfiwXYtsFH4uw0mxKScw98TlWFfOGty4X8T7Gt4g7KZy3yakaqDH8dByNO11pVZ23bCWhPeNjcwpnfvgcOcX12bTIT3f5g49TXKFLJRI0XtFR9zUvHXwxNYJPRWFn8v13/s320/OMC-3-general.jpg" style="cursor: pointer; display: block; height: 185px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
<li>You also need to configure the Activation and Execution screens as follows:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8J24P2Djd9lXi3lLPqx1pcVK2Nexc5gL7Ny9tVocDmdiyWN7NaM18YqZyNsBy1RD5XyZmiH-tpID0SIsnsJNeCP5I814_sPNQzjRW6QUsY_ulFVRKsx-rYuUFP2KL60AFeKUzOtPa4O0g/s1600-h/OMC-4-activation.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365740648970209266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8J24P2Djd9lXi3lLPqx1pcVK2Nexc5gL7Ny9tVocDmdiyWN7NaM18YqZyNsBy1RD5XyZmiH-tpID0SIsnsJNeCP5I814_sPNQzjRW6QUsY_ulFVRKsx-rYuUFP2KL60AFeKUzOtPa4O0g/s320/OMC-4-activation.jpg" style="cursor: pointer; display: block; height: 185px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoG13PbKV8eST8rbLkulJUuA9Xaqw9BSu8WN_uiqSgx0T8QluboV7JaCInvwqVyT3nEKk6BHIbv9Ye12RKaodZoPlif9wAAi0MfSaItqFdAItlqKW1wCGH3VJcbeeqpgew_9tVv44nQJb5/s1600-h/OMC-4-execution.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365741306407359234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoG13PbKV8eST8rbLkulJUuA9Xaqw9BSu8WN_uiqSgx0T8QluboV7JaCInvwqVyT3nEKk6BHIbv9Ye12RKaodZoPlif9wAAi0MfSaItqFdAItlqKW1wCGH3VJcbeeqpgew_9tVv44nQJb5/s320/OMC-4-execution.jpg" style="cursor: pointer; display: block; height: 185px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
<li>Once you're done, save your command and quit the application.</li>
</ul>4. Use the <span style="font-style: italic;">visudo</span> tool to set up <span style="font-style: italic;">sudo</span> so it runs without a password only for the <span style="font-style: italic;">networksetup</span> command<br />
<br />
<span style="font-style: italic;">Sudo</span> is a great command as it lets you run system-level (root) commands without needing to log in as root. However, because you're running commands at root level, you need to type in your password for it to work. This is a problem because you can't configure OMC to type in a password when you run commands. You can get around this by configuring <span style="font-style: italic;">sudo</span> to allow only the <span style="font-style: italic;">networksetup</span> command to run without a password, and only for your username.<br />
<span style="font-weight: bold;">***WARNING: Before proceeding, note that incorrectly configuring </span><span style="font-style: italic; font-weight: bold;">sudo</span><span style="font-weight: bold;"> can remove your permissions to run any command on your Mac. Proceed with extreme caution.***</span><br />
<br />
Who can run <span style="font-style: italic;">sudo</span> and how on a Mac is controlled by a file called <span style="font-style: italic;">sudoers</span> which can be found in the directory <span style="font-style: italic;">/private/etc/</span> - have a look at what it contains using the command <span style="font-style: italic;">cat /private/etc/sudoers</span> in Terminal. You should see a section containing user priviledge specifications:<br />
<br />
# User privilege specification<br />
root ALL=(ALL) ALL<br />
%admin ALL=(ALL) ALL<br />
<br />
Here's what my file looks like:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPI-Ljw_MSXsluZDjgurc0ZQ0ftE7-7tQ2VNiacoCR7QAsCVkUv9aDETS82JVuufENgjOMPjC9SI5PXan-jZs8XHdn3p06YnU1J6h5buI56BcU9evgSL6RtyMe0lScfdfd_3iiEVN1COjH/s1600-h/OMC-5-cat-sudoers.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365748765735940066" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPI-Ljw_MSXsluZDjgurc0ZQ0ftE7-7tQ2VNiacoCR7QAsCVkUv9aDETS82JVuufENgjOMPjC9SI5PXan-jZs8XHdn3p06YnU1J6h5buI56BcU9evgSL6RtyMe0lScfdfd_3iiEVN1COjH/s320/OMC-5-cat-sudoers.jpg" style="cursor: pointer; display: block; height: 246px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
This is used to set specific priviledges for the <span style="font-style: italic;">sudo</span> command. Here's how to edit it so you can run <span style="font-style: italic;">sudo networksetup</span> without needing to type in the password every time:<br />
<ul><li>Work out your username. You can do this by tying the command <span style="font-style: italic;">whoami</span> into terminal:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl1TSvuJQnchiT7JfrXb96qW7DREobWBIL2k5qYCMlcmQMt1ZUZcu8FjNV8HgxD3GJDe6c53MErOlfDCDA6EYASRXsm5SLWgNJCfXige5hcwLyMVJntZyuyJKQYawFxoj2z64h5_y0B3-r/s1600-h/OMC-5-whoami.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365747032668948930" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl1TSvuJQnchiT7JfrXb96qW7DREobWBIL2k5qYCMlcmQMt1ZUZcu8FjNV8HgxD3GJDe6c53MErOlfDCDA6EYASRXsm5SLWgNJCfXige5hcwLyMVJntZyuyJKQYawFxoj2z64h5_y0B3-r/s320/OMC-5-whoami.jpg" style="cursor: pointer; display: block; height: 50px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
<li>Let's label your username as "<span style="font-style: italic;">yourusername</span>" in the commands we're using.<br />
</li>
<li>Now you need to go in and configure the sudo file to add an exception which allows you to run <span style="font-style: italic;">sudo networksetup</span> for your username without needing to enter a password. You do by using the <span style="font-style: italic;">visudo</span> tool to edit the <span style="font-style: italic;">sudoers</span> file. <span style="font-style: italic;">Visudo</span> uses the <a href="http://en.wikipedia.org/wiki/Vi"><span style="font-style: italic;">vi</span></a> editor, which is built into Mac OS X, to edit the file. If you are not familiar with <span style="font-style: italic;">vi</span>, I'd recommend getting a <a href="http://www.eng.hawaii.edu/Tutor/vi.html">short vi tutorial</a> and practising on another file before you go ahead and edit this important system file.<br />
</li>
<li>Use the command <span style="font-style: italic;">sudo visudo</span> to edit the sudoers file and add an exception line for the <span style="font-style: italic;">networksetup</span> command for your username. The exception should be the following line:</li>
</ul><span style="font-style: italic;">yourusername ALL=(ALL) NOPASSWD: /usr/sbin/networksetup</span><br />
<ul><li>Note that there are tabs, not spaces, before the first "<span style="font-style: italic;">ALL</span>" and the "<span style="font-style: italic;">NOPASSWD</span>". Here's a screenshot for how it looks on my machine:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhANz9bJoOn3fsB32z3iuBgK7mmdgpibKxMkZ0KYGi2YV247irTFeqoMjS1CSHVEg1oLnneG8QW5P3Oy_G0SSyYtGQKRYyqwdEWnZ4wnkj6ECw5irCdGKhXrJ0-ao7FrDmYaiWwl2tf-V1c/s1600-h/OMC-6-exception.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365750559452629874" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhANz9bJoOn3fsB32z3iuBgK7mmdgpibKxMkZ0KYGi2YV247irTFeqoMjS1CSHVEg1oLnneG8QW5P3Oy_G0SSyYtGQKRYyqwdEWnZ4wnkj6ECw5irCdGKhXrJ0-ao7FrDmYaiWwl2tf-V1c/s320/OMC-6-exception.jpg" style="cursor: pointer; display: block; height: 56px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a></li>
<li>Now save the file in <span style="font-style: italic;">vi</span> (usually by pressing <span style="font-style: italic;">ESC</span> and then typing <span style="font-style: italic;">:wq</span> followed by return).</li>
<li>You should now be able to run the <span style="font-style: italic;">networksetup</span> command without needing to type a password. You can test this by clearing the <span style="font-style: italic;">sudo<span style="font-style: italic;"><span style="font-style: italic;"> <span style="font-style: italic;"><span style="font-style: italic;"></span></span></span></span></span>cache using the command <span style="font-style: italic;">sudo -K</span> and then trying <span style="font-style: italic;">sudo networksetup -setairportpower on</span> or <span style="font-style: italic;">sudo networksetup -setairportpower off</span> - if you need to type a sudo password your edit hasn't worked.</li>
<li>You can also test by running the OMCEdit app, selecting your command and clicking the "Run" button. You should get something popping up on screen to tell you the command has run okay.<br />
</li>
</ul>5. Use shortcuts.app to add a keyboard shortcut for your OMC command<br />
Now you've written your OMC command and got it working without needing a <span style="font-style: italic;">sudo</span> password it's time to assign a keyboard shortcut to the command. For this, you'll need the Shortcuts app which comes with OMC. It runs in the background and listens for shortcut keys you've configured. Set this up so that it runs in the background when your machine first starts up:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfAGS7WH-lmSx0a7OF01cAOR3mqKnK3evKBobVLOjZufJ9YDyMC3GKhsbTIULHiSTAkJXxSbAs3wx8BD0v3PecNdHq_4Xdhsp34UMXfwZYDnjD0unbCZnoWE0GqXHAfawK7VMk4g4Q8o7T/s1600-h/OMC-7-shortcuts-config.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365753937442440578" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfAGS7WH-lmSx0a7OF01cAOR3mqKnK3evKBobVLOjZufJ9YDyMC3GKhsbTIULHiSTAkJXxSbAs3wx8BD0v3PecNdHq_4Xdhsp34UMXfwZYDnjD0unbCZnoWE0GqXHAfawK7VMk4g4Q8o7T/s320/OMC-7-shortcuts-config.jpg" style="cursor: pointer; display: block; height: 270px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>Now, assign the shortcut keys in the "Assign Hot Keys" tab. You'll need to select your script name in each of the drop-down menus:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3us6vgFuUmYE2m5f2j3L1ryFYodSdrZoR2gVkyHLeX5kkbP6f9g3R0EYdzpbpOdvTxVLSbvDSEOyOgl_aRuNRNZNfMSdJpUWjDrmQ99RXIiGuEPhk2rpYpanTzjexRurVDAmnJ1FjlgBM/s1600-h/OMC-8-shortcuts-assign.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365754688670543874" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3us6vgFuUmYE2m5f2j3L1ryFYodSdrZoR2gVkyHLeX5kkbP6f9g3R0EYdzpbpOdvTxVLSbvDSEOyOgl_aRuNRNZNfMSdJpUWjDrmQ99RXIiGuEPhk2rpYpanTzjexRurVDAmnJ1FjlgBM/s320/OMC-8-shortcuts-assign.jpg" style="cursor: pointer; display: block; height: 270px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>Each time you do this, a dialogue screen should come up where you can type in the shortcut key combination you want to use:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdG9hju-47r3qrPOHCcff48iLHPbrmB18LJabaxz45Q3IFCO3nH2xTDjfWL0_sx1myZbc5nfTCw7UUKS6c1eyw8FFLDPAXk3mMqx3VRc7qC419FYwXTihxV-gvosAxDmSuTgd7SZ4wPDsw/s1600-h/OMC-11-shortcuts-assign-dialogue.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365754907808925474" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdG9hju-47r3qrPOHCcff48iLHPbrmB18LJabaxz45Q3IFCO3nH2xTDjfWL0_sx1myZbc5nfTCw7UUKS6c1eyw8FFLDPAXk3mMqx3VRc7qC419FYwXTihxV-gvosAxDmSuTgd7SZ4wPDsw/s320/OMC-11-shortcuts-assign-dialogue.jpg" style="cursor: pointer; display: block; height: 142px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>You should then check this has registered by going to the Shortcut List tab:<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBfJVN_exV0oxfzwp3DJQcYP7XgP7ISLYyZy_wPEfwx3Ym_rQBqV72tpStfamZ_TSBbsMIaKqrdK4D2_eWl5IDEtk4SQ1r1VFaCm2yszgpUCgxK4rf0lEcLT3NFetHjR4uPdzYlRtxPzd_/s1600-h/OMC-9-shortcuts-check.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5365755143575069938" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBfJVN_exV0oxfzwp3DJQcYP7XgP7ISLYyZy_wPEfwx3Ym_rQBqV72tpStfamZ_TSBbsMIaKqrdK4D2_eWl5IDEtk4SQ1r1VFaCm2yszgpUCgxK4rf0lEcLT3NFetHjR4uPdzYlRtxPzd_/s320/OMC-9-shortcuts-check.jpg" style="cursor: pointer; display: block; height: 270px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
Now test your shortcut key by quitting the shortcuts application and hitting your keyboard shortcut combination to turn your Airport on.<br />
<br />
6. Repeat for Airport Off<br />
Now all you have to do to add an "Turn airport off" keyboard combination is add another OMC command using OMCEdit and then do the same in Shortcuts.<br />
<br />
Enjoy!Unknownnoreply@blogger.com0