sam keen's corner of the web

Microformats: Path to Sematic Web?

In the past I have looked into technologies promising to lead us to the promised land of Semantic Web. RDF and OWL are a couple of examples. Though they are powerful and capable formats they are a bit of a chore to come up to speed on and not to easy to implement into something usable and scalable. You see folks using them to solve specific problems in niche and primarily vertical scopes but you don’t seem to see signs of any widespread adoption by the masses.

Then comes along Microformates. From what I’ve read, XFN is what evolved into the first microformat. Today there are many more useful formats. MF’s are sort of a grassroots effort to stitch semantics into the content being published to the web by those who do much of the publishing. Some of the microfomat goals are to solve specific real world problems, start as simple as possible, and reuse existing, widely adopted standards. These concepts make microformats very easy to pick up and start utilizing immediately.

Links I found useful

When Adventurous Coders get Bored

vm-vm

I convinced a friend to try this, hopefully space/time fabric was unaffected.

One more rule for the universe

  • You may not travel faster than the speed of light
  • You may not power on a virtual machine in a virtual machine

Amazon Simple Storage Service [S3]

What is S3??

Simple Storage Service: Is a web service that allows any developer to gain access to highly scalable, very reliable, inexpensive storage space. Your data is replicated to multiple servers at multiple data centers.

How to get started

Go to Amazon’s AWS page, then to the S3 page and sign up (check out the other services while you are there)

Pricing (From Amazon’s site…)

Pricing

New Pricing (effective June 1st, 2007)

Storage
$0.15 per GB-Month of storage used

Data Transfer
$0.10 per GB – all data uploaded

$0.18 per GB – first 10 TB / month data downloaded
$0.16 per GB – next 40 TB / month data downloaded
$0.13 per GB – data downloaded / month over 50 TB

Data transferred between Amazon S3 and Amazon EC2 is free of charge

Requests
$0.01 per 1,000 PUT or LIST requests
$0.01 per 10,000 GET and all other requests*
* No charge for delete requests

Storage and bandwidth size includes all file overhead

I looked around the web for similar services (hard to find someone that posts prices), and for 180 gig’s of reduntantly stored data, it was in the $200/month price range.

The same 180Gb on S3 would be

$27 to store for 30 days

$18 to xmit (the entire 180Gb) to S3

In addition to price, with S3, you are in full control of how and when you put and/or get your data.

Only pay for what you actually use

One of the niceties about S3 (and the other Amz web services) is that you pay just for what you use.

Didn’t use that service last month: Pay $0.

This allows you to ‘tinker’ all you want for mere pennies

Amazon S3 – Objects

What is an Object?

Object is the term we use in S3 for the ‘thing’ (file/data) you want to store.
Once an object is stored in S3, it contains the original data (contents of the file), plus a given amount of meta-data (name/value pairs).

You can add your own metadata but some of the standards are ‘Last-Modified‘ and ‘Content-Type

A given Object can be from 1byte to 5GBs

Amazon S3 – Buckets

Why Buckets?

Buckets provides a unique namespace for management of objects contained in the bucket

Bucket namespaces are Global across all of S3 (all users of S3. Similar concept as ‘domain names‘)

An S3 account is allowed 100 buckets

Amazon S3 – Keys

Key

A key is the unique identifier for an object within a bucket

Locating an object

Any Object can be located by its [bucket + key] using a RESTful formatted URL

   http://s3.amazonaws.com/foo-products/2006/may/1845.prd


foo-products is the bucket & 2006/may/1845.prd is the Key

S3 – Authentication

Most requests to S3 require authentication, this ensures that you don’t get charged for operations you didn’t authorize, and that nobody else sees your private data.

You can grant various access models (acl) for an Object or an entire Bucket

  • private
  • public-read
  • public-read-write
  • authenticated-read

To set the ACL, when you PUT the Object to S3, you set a x-amz-acl header. For example…

x-amz-acl: public-read

ACl defaults to private if not set on the PUT

S3: Putting it all Together

How do you speak to S3?

At this point, all interaction is done with the HTTP protocol (the current exception is that you can retrieve objects using http or BitTorrent).

So, creating a program to interact with S3 is just a matter of creating HTTP requests and reading HTTP responses. Something PHP is quite capable of (especially with a little help from PEAR HTTP_Request and Crypt_HMAC)

First get an account and your Keys

  • Access Key ID: You add this to any requests to S3. Essentially it is your unique identifier that tells S3 a given request is targeted for your account.
  • Secret Access Key: For requests to S3 for Objects with acl’s that require authentication (i.e. private, authenticated-read), you ’sign’ your request with this secret key.

The following code examples are based on what is in the Amazon S3 developer docs

Create a Bucket

# create bucket request

PUT /[bucket-name] HTTP/1.0Date: Wed, 08 May 2007 08:45:09 GMTAuthorization: AWS [aws-access-key-id]:[header-signature]Host: s3.amazonaws.com

# create bucket response

HTTP/1.1 200 OKx-amz-id-2: VjzdTviQorQtSjcgLshzCZSzN+7CnewvHA+6sNxR3VRcUPyO5fmSmo8bWnIS52qax-amz-request-id: 91A8CC60F9FC49E7Date: Wed, 08 Mar 2006 04:06:15 GMTLocation: /[bucket-name]Content-Length: 0Connection: keep-aliveServer: AmazonS3

Put Objects in your Bucket

# put object request

PUT /[bucket-name]/[key-name] HTTP/1.0Date: Wed, 08 Mar 2006 04:06:16 GMTAuthorization: AWS [aws-access-key-id]:[header-signature]Host: s3.amazonaws.comContent-Length: 14x-amz-meta-title: my titleContent-Type: text/plain

this is a test

# put object response

HTTP/1.1 200 OKx-amz-id-2: wc15E1LUrjDZhNtT4QZtsbtadnOMKGjw5QTxkRDVO1owwbA6YoiqJJEuKShopufwx-amz-request-id: 7487CD42C5CA7524Date: Wed, 08 Mar 2006 04:06:16 GMTETag: "54b0c58c7ce9f2a8b551351102ee0938"Content-Length: 0Connection: keep-aliveServer: AmazonS3

Retrieve Objects from your bucket

# get object request
GET /[bucket-name]/[key-name] HTTP/1.0Date: Wed, 08 Mar 2006 04:06:18 GMTAuthorization: AWS [aws-access-key-id]:[header-signature]Host: s3.amazonaws.com
# get object response
HTTP/1.1 200 OKx-amz-id-2: FbGpiykb9oJEdJd0bcfwkL6S3lc06X0y7XSeA/GWyRdvlNEZ0irthljxKoeGFfB6x-amz-request-id: 9298531013923634Date: Wed, 08 Mar 2006 04:06:18 GMTLast-Modified: Wed, 08 Mar 2006 04:06:16 GMTETag: "54b0c58c7ce9f2a8b551351102ee0938"x-amz-meta-title: my titleContent-Type: text/plainContent-Length: 14Connection: keep-aliveServer: AmazonS3
this is a test

S3 – The PHP way

Implementing an API to S3 with PHP

Prerequisites

You’ll need the PEAR libraries Crypt_HMAC & HTTP_Request (at least things are much easier if you have these)

# sudo pear install Crypt_HMACpear.php.net" to updatedownloading Crypt_HMAC-1.0.1.tgz ...Starting to download Crypt_HMAC-1.0.1.tgz (2,149 bytes)....done: 2,149 bytesinstall ok: channel://pear.php.net/Crypt_HMAC-1.0.1
sam$ sudo pear install HTTP_Requestpear.php.net" to updatedownloading HTTP_Request-1.4.0.tgz ...Starting to download HTTP_Request-1.4.0.tgz (15,262 bytes).....done: 15,262 bytesdownloading Net_URL-1.0.14.tgz ...Starting to download Net_URL-1.0.14.tgz (5,173 bytes)...done: 5,173 bytesdownloading Net_Socket-1.0.7.tgz ...Starting to download Net_Socket-1.0.7.tgz (5,419 bytes)...done: 5,419 bytesinstall ok: channel://pear.php.net/Net_URL-1.0.14install ok: channel://pear.php.net/Net_Socket-1.0.7install ok: channel://pear.php.net/HTTP_Request-1.4.0

Creating the API

At this point all you really need to do is create a function for each needed interaction with S3 (or better yet, a PHP Object with a method for each). So something like…

createBucket()
putObject()
getObject()
getBucketListing()
   ...

These functions are going to be creating http requests and reading http responses. Sometimes this can be a bit tricky (one missing ‘\n’ and you’re screwed), so leverage what what other have done befor you. The Amazon web services site has some good examples but in particular, I would recommend you look at ‘Test Utility for Amazon S3 in PHP‘ which does a good job of demo’ing most of the S3 functionality using PHP.

I used this code as a starting point to develop a very simple ‘Rsync’ type application for Amazon S3.


Resources

Portland Oregon BarCamp

I went to the last organizing meeting for this. It looks to be quite a bit of fun.

Don’t forget to remind all of your techie friends that BarCamp is
coming to Portland on May 11-12! We will also be kicking off the
regular DemoCamp event series during BarCamp to highlight tech startup
activity in the Portland area.

How can you help promote BarCamp Portland?
- email your friends (you may find the text below helpful)
- add a button to your blog http://barcamp.org/BarcampPortlandChiclet
- hand out some flyers at local events http://barcamp.org/BarCampPortlandFlyers

More about the event for use in emails, etc …

Tech + Geek + Culture. The event for the Portland tech community,
produced BY the Portland tech community.

What is BarCamp? It is an ad-hoc gathering born from the desire for
people to share and learn in an open environment. It is an intense
event with discussions, demos, and interaction from participants.

BarCamp is a FREE event and the content is determined by the
attendees. The event will be hosted at CubeSpace, which has a number
of conference rooms for breakout sessions, a large main meeting area,
wireless access, easy access to public transportation, bike storage,
and ample parking.

We need your help to make BarCamp Portland a fantastic event for the
tech community in Portland. Here’s what you can do…

1) Forward this email on to people in the Portland area that may have
an interest in attending. As we have done little marketing of the
event (so far), assume that your local tech social network doesn’t
know about it yet.

2) If you have not already added yourself to the BarCamp Portland wiki
page as an attendee, please do so. This will help us get a more accurate attendance count and plan accordingly (you want food,
right?):

http://barcamp.org/BarCampPortland

3) Add a session idea for the event. This could be a talk, a demo, a
roundtable discussion – whatever! Please add it to the Proposed
Sessions section on the wiki page:

http://barcamp.org/BarCampPortland

4) Attend the BarCamp Portland Meetup this Thursday (04/26/07) evening
5:30-8pm at Jive Software downtown. Free beer on tap (thanks, Jive!),
the opportunity to network with the tech community in Portland, and
help plan for BarCamp Portland. More details:

http://barcamp.org/BarCampPortlandMeetups

OpenQA Selenium

Selenium

is a functional/acceptance testing tool for web applications. It in in the same space as tools like

Selenium Advantages

  • The core is written in javascript so it runs directly in a browser, just as real users do
  • Supported on OS X, Linux, and Windows
  • Very simple to learn and use
  • Open Source (Apache License 2.0)
  • Selenium Remote Control!!!

Key Components

  • Selenium Core – The core of Selenium written in pure JavaScript/DHTML. This is all that is required in order to start using Selenium
  • Selenium IDE (Firefox Addon) – Integrated development environment for recording and playing tests.
  • Selenium RC (Remote Control) – Allows you to write automated web functional/acceptance tests in any programming language.

Selenium Core

Installation

  • Download the latest release
  • Place the downloaded folder (i.e. selenium-core-0.8.2) in the webroot of the webserver with the app to be tested. This is a JavaScript security requirement, ‘same origin‘ policy. (Later in this talk we’ll explain how to get around this).

Writing your First Test

Where to put the tests

The tests can really reside anywhere on the web server (just need to accessable from same domain of the app you are testing). So, just place them in the area that makes most sense for you organization wise.
For this example we will place them in the web app to be tested in a ‘tests’ folder.

What we will be testing

For this talk I have written a VERY tiny PHP application with a simple login page. We’ll use this to test some of the aspets of Selenium.


How test cases are constructed

OpenQA used a very KISS method for creating a test case. You simply take your favorite HTML editor and create an HTML table with 3 columns (). Then add a row () for each test step (called a command).

The general pattern for these command rows are

Depending on the command, target or value can be optional or required. (more about this later).

Below is about the simplest test possible. It just useses the open command to load the browser with a value of the Login page and then uses the assertTitle command to verify that the title element (<title>) for the page has the value “Selenium Demo: login”.

Note that any table row with <> 3 columns is ignored so it can be use for commenting your tests as we do in row 1 below.

This test writing syntax is refered to as ‘HTML Selenese’

This file is saved in the tests folder of the app as TestLoginPageLoads.html

Running Your First Test

First, need a Test Suite to house the Test Case(s)

Test Cases are organized into collections using Test Suites.
Again, in the spirit of keeping things simple, a Test Suite is an HTML
file with a 1 column table. In each row of that table you put a
hyper-link pointing to the test you want to run.

This file is also saved in the tests directory with the name TestSuite.html

Now to actually run it…

Open a browser and navigate to the TestRunner file in Selenium core that you installed locally. It is located at…

{selenium-install-dir}/core/TestRunner.html

You should see something simmilar to this

In the upper left “Test Suite:” text box, type the relative path to the …/tests/TestSuite.html file created above (/selenium-talk/tests/selenium/TestSuite.html in this case) and click the Go button

The Test Suite should load in the left frame and the middle frame will list the Test Cases along with their individual steps

Click the Run selected test button to run this test.

This is a very simple test so things happen very quicly but the web app reference in the suite will load in the bottom frame and the test will interact with it there. The summary section will show the passed/failed stats for the Test Suite run and the Test Suite and Test Cases lists will colorize depending on the test outcome (green=pass / red=fail)

Some examples of tests

A Closer Look at Test Cases

Commands

There are 3 types of commands

1 Actions

example actions are click(locator), goBack(), setCursorPosition(locator,position), keyPress(locator,keySequence), dragdrop(locator,movementsString), …

Selenium Actions mimic the actions the user would take in interacting with the web app.

2 Accessors

Accessors examine the state of the applications and store the result in variables. Examples would be storeElementWidth(locator, variableName), storeBodyText(variableName), storeSelectedId(selectLocator,variableName), …

3 Assertions

For any given Accessor there are typically one or more related Assertions. Assertions, like Accessors, are able to examine the state of the application but instead of storing the value they retrieve, they verify that it meets a pre-defined expected value.

Assertions themselves com in 3 versions

  • assert – If this fails, the test is aborted
  • verify – If this fails, the test will log the failure, but continue
  • waitFor – These wait for the tested condition to become true. They will fail and hault the test after the the value for current timeout setting expires (see the setTimeout(timeout) Action)

For example the AccessorstoreLocation(storageVariable) retrieves the absolute URL of the current page and stores it in the variable, storageVariable.
its (automatically generated) assertions are

  • assertLocation ( pattern )
  • assertNotLocation ( pattern )
  • verifyLocation ( pattern )
  • verifyNotLocation ( pattern )
  • waitForLocation ( pattern )
  • waitForNotLocation ( pattern )

Note: You do not need to use an Accessor prior to using one of its related Assertions. As in our example Test Case, TestLoginPageLoads, we simply used assertTitle directly after the open command (and never used storeTitle).

There are many, many Actions, Accessors, and Assertions (and you can also easily define your own) so be sure to give the Selenium reference a good read as it details them all.

Element Locators and Patterns

On the previous page for the Action, Accessor, and Assertion commands, you may have noticed the references to ‘locator‘ and/or ‘pattern‘ in the parameters for those Commands.

(Element) Locators

The Element Locator concerns the Target that a given Command uses. They tell Selenium which HTML element a Command refers to. There are quite a few techniques the Locator can use so you are sure to find one that works for you.

ElementLocators are in the form: {locator-prefix}={locator-string}

ex.

command target value

verifyText id=koan_body *mary had a little lamb*

—————

<following descriptions are from the OpenQA site>

  • identifier=id: Select the element with the specified @id attribute. If no match is found, select the first element whose @name attribute is id. (This is normally the default; see below.)
  • id=id: Select the element with the specified @id attribute.
  • name=name: Select the first element with the specified @name attribute.
    • username
    • name=username

The name may optionally be followed by one or more element-filters, separated from the name by whitespace. If the filterType is not specified, value is assumed.

    • name=flavour value=chocolate (useful for check-boxes and radio-buttons)
  • dom=javascriptExpression: Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block.
    • dom=document.forms['myForm'].myDropdown
    • dom=document.images[56]
    • dom=function foo() { return document.links[1]; }; foo();
  • xpath=xpathExpression: Locate an element using an XPath expression.
    • xpath=//img[@alt='The image alt text']
    • xpath=//table[@id='table1']//tr[4]/td[2]
    • xpath=//a[contains(@href,'#id1')]
    • xpath=//a[contains(@href,'#id1')]/@class
    • xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
    • xpath=//input[@name='name2' and @value='yes']
    • xpath=//*[text()="right"]
  • link=textPattern: Select the link (anchor) element which contains text matching the specified pattern.
    • link=The link text
  • css=cssSelectorSyntax: Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package.
    • css=a[href="#id3"]
    • css=span#firstChild + span

Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :o nly-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after).

Without an explicit locator-prefix, Selenium uses the following default strategies:

  • dom, for locators starting with “document.”
  • xpath, for locators starting with “//”
  • identifier, otherwise

Patterns

Patterns concern the Value that a given Command is looking for.
Patterns are in the form {pattern-prefix}:{pattern}
The Pattern techniques are:

  • glob:{pattern}
    • globs are simple pattern matchers. ‘*‘ matches any sequence of characters and ‘?‘ matches any single character.
  • regex:{regular-expression}
    • The pattern matcher we know and love. See your javascript engine for the specifics of the regex engine in use.
  • exact:{literal-sting}
    • self explanitory.

If no pattern-prefix is given then Selenium defaults to glob

Often for simple ElementLocators you can get away with id=locator-string. For more complex locators I would recoment you get aquanted with xpath. You can go here for a good xpath tutorial and Viktor Zigo has written an excellent xpath firefox plugin. For Patterns use globs for simple matches and regex when you need a bit more sophisticated match.
You can go here for a good xpath tutorial

Selenium IDE

This is implemented as a Firefox add-on. It is a graphical tool you can use to quickly record edit and debug tests.

It installs like any other FF plugin so go to OpenQA’s site and download and install. Once you restart Firefox, SeleniumIDE should be listed under the tools menu.

To use it, simple navigate to the page in the application where you want to start testing, then go to Tools -> SeleniumIDE to launch the tool.

Selenium IDE starts in record mode so you can jsut start interacting with the browser and your actions will be recorded in the IDE. A movie is worth (a bunch) of words, so see this screen cast on OpenQA’s site for a quick walk through.

So essentially to use the IDE to record a test

  • After determining an interaction with the web application to test.
  • Navaigate (in FF) to the first page of the interaction
  • Start the Selenium IDE
  • Follow the steps of the interaction
  • Click the stop recored button of the IDE
  • In the Selenium Menu, go to File -> Save Test and save the test into your web app’s tests directory.
  • Add the saved test to the approprieate Test Suite.

note: During the test recording, you can right-click elements in the page and get a menu showing all the available Commands for the element.


Selenium Remote Control

This quote for the OpenQA site pretty much sums up the power of Selenium RC

“Selenium Remote Control is a test tool that allows you to write automated web application UI tests in any programming language against any HTTP website using any mainstream JavaScript-enabled browser.”

Installing SeleniumRC

Install Using PEAR

On my first atempt to install the PHP client driver with PEAR I got this

sudo pear install Testing_Selenium
Failed to download pear/Testing_Selenium within preferred state"stable", latest release is version 0.3.0, stability "beta",

use "channel://pear.php.net/Testing_Selenium-0.3.0" to install
Cannot initialize 'Testing_Selenium', invalid or missing package file
Package "Testing_Selenium" is not valid
install failed

Selenium is still in Beta, no problem… using the suggested command worked fine. If you have any trouble here see PEAR’s docs

sudo pear install channel://pear.php.net/Testing_Selenium-0.3.0
downloading Testing_Selenium-0.3.0.tgz ...
Starting to download Testing_Selenium-0.3.0.tgz (2,414,300 bytes)
...........................................done: 2,414,300 bytes
install ok: channel://pear.php.net/Testing_Selenium-0.3.0

Then just be sure that your PEAR directory is in your PHP include path and you are good to go.

Install Manually

Just grab the package from PEAR and place the Testing_Selenium-0.3.0 directory where it will be found in the PHP include_path. Also it is noted on the OpenQA site that the PHP client will be included in future releases of the SeleniumRC download ( >= 0.9.1) so that will be a second way to manually install.

Source

If you want to view or check out the source, you can do that…

you can check ou the source for SeleniumRC at

svn co https://svn.openqa.org/svn/selenium-rc/trunk

you can view the source at

http://svn.openqa.org/fisheye/viewrep/selenium-rc/trunk

Writing the test in PHP

The Code


The Selenium Server

Selenium Server

To run your test using the PHP client (or any of the clients) you need to have the Selenium Server running in a separate process.

Selenium Server is a Java program and requires a JRE >= 1.5.0. You can check your version by typing java -version on the commandline.

$ java -versionjava version "1.5.0_07"Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164)Java HotSpot(TM) Client VM (build 1.5.0_07-87, mixed mode, sharing)

If you get something like ‘java: command not found’ or your version is < href="http://java.sun.com/javase/downloads/index_jdk5.jsp">Java Runtime Environment (JRE) 5.0.

Compatible Browser

Best supported is Firefox and IE. If you have these installed in their default locations you should be good. If not place their corresponding executables in your OS’s PATH environment variable.

Starting The Server

The command to start the server is in the form java -jar {path to selenium-server.jar}. If you installed the server with PEAR, the jar file should be in your {pear install dir}/data/Testing_Selenium/

$ java -jar /usr/local/php/lib/php/data/Testing_Selenium/selenium-server.jarapplication/xhtml+xmlMar 5, 2007 8:53:50 PM org.mortbay.http.HttpServer doStartINFO: Version Jetty/0.9.0Mar 5, 2007 8:53:50 PM org.mortbay.util.Container startINFO: Started HttpContext[/,/]Mar 5, 2007 8:53:50 PM org.mortbay.util.Container startINFO: Started HttpContext[/selenium-server,/selenium-server]Mar 5, 2007 8:53:50 PM org.mortbay.util.Container startINFO: Started HttpContext[/selenium-server/driver,/selenium-server/driver]Mar 5, 2007 8:53:50 PM org.mortbay.http.SocketListener startINFO: Started SocketListener on 0.0.0.0:4444Mar 5, 2007 8:53:50 PM org.mortbay.util.Container start
INFO: Started org.mortbay.jetty.Server@6672d6

Just leave this server running during your tests. There is no need to stop/start it between test runs.

Running Your First PHP Test

In a terminal window other than the on the server is running in. Navigate to the directory in the web app holding the test written in PHP.

When you run the PHP file…

$ php test-login.php

In the Selenium Server window you should see something like…

Got result: OK,Selenium Demo App: login on session 218697GET: cmd=testComplete&sessionId=218697Killing Firefox...Got result: OK on session 218697

Then you should see the output of the PHP file.

Title Equal: 'Selenium Demo App: login'

know bug on OS X : launching FireFox

Using SeleniumRC with xUnit Frameworks

Stitching SeleniumRC into your Testing Framework

In order to make SeleniumRC more maintainable and scalable you can leverage your language’s xUnit framework (PHPUnit) in this case.

Example PHPUint/SeleniumRC Test (from the OpenQA) site. Notice that we are overcoming the Javascript’s “Same Origin Policy“.

With this setup, you SeleniumRC tests can easily be incorperated into an existing Unit Testing framework. The SeleniumRC test benefit from all the ease of use and scalability of the xUnit frameworks.

One more note, to get a headstart on building SeleniumRC tests you can use the export option of SeleniumIDE


Selenium: Further Reading, Examples

PCC giving an AJAX class and one on Eclipse this term

The faculty asked me to pass this on…

Building Websites with AJAX

Bring richness and responsiveness to your website using the
methods that make Google maps so much fun. Learn the techniques and tools of AJAX to bring speed and interactivity to your web presence. With Asynchronous JavaScript and XML you
will find a new way to impress your web visitors. An AJAX toolkit will also be used to develop
projects. Suggested prerequisites: HTML and JavaScript knowledge.

CRN Location Time Days Dates
Cost
26670 SE Center TABOR 118 06:00PM-09:00PM MW 21-May-2007
to 18-Jun-2007 $400

Using the Eclipse Platform IDE

Provide the skills for productive use of the Eclipse Integrated
Development Environment tool for software development and debugging.

CRN Location Time Days Dates
Cost
26739 Cent. Ptlnd CPWTC 207 06:00 PM-09:00PM TTh 29-May-2007
to 21-Jun-2007 $480

To register, go to https://my.pcc.edu/cp/home/displaylogin

Find and Replace in Mysql

Simple but very useful MySQL trick…

UPDATE `table` SET `field` = REPLACE (
`field` ,
‘{string to find}’,
‘{replacement string}’
)

Getting Around Clients that only allow connection from a single IP

As a freelance Web Developer, I often find myself this circumstance.
Client X states…

We can allow you access to our network but only through your single dedicated IP

I won’t go into how ‘un’-realword this is in this day and age (what freelance coder always works behind a single IP?). I tend to work from coffee shops and at home I prefer (cheaper) dynamic ip broadband.

Overview: We will use a ‘trusted’ server we have ssh access to as a ‘proxy’ to connect to the ClientX server. From ClientX’s point of view, it will simply look as though you are connecting directly from the proxy server but you will be able to connect to clientX from any server (through the proxy server).

Step 1:

Give clientX the IP to any “trusted” static IP server you have ssh access to (this will be the proxy server).

Step 2:

The setup

On local, issue this command…

$ ssh -L2001:clientX:22 proxy

You are instructing SSH to encrypt traffic from port 2001 (chosen arbitrarily, you can choose any unprivleged port that is available) on your local computer and send it to port 22 on clientX, using the SSH server on proxy.

Leave this terminal open (where you issue the above command. It will be logged into proxy through ssh).

Now in a new terminal window you can ssh, scp, sftp to clientX by using local port 2001. You can even use your favorite graphical ssh, scp,or sftp client, just point it to localhost and port 2001.

ex:

$ ssh -p2001 user@localhostuser@localhost's password:Last login: Fri Jan 19 17:29:23 2007 from 99.99.180.136[user@clientX user]$ hostnameclientX.com[user@clientX user]$

As you can see, you ssh to localhost port 2001 and end up on clientX

Shown below, you can take your GUI sftp client and point it to localhost and port 2011, after logging in (with your clientX credentials), you will see your files on clientX

To close the connection, disconnect any ssh, scp, or sftp clients then simply type exit in the original terminal where you typed $ ssh -L2001:clientX:22 proxy

Running PHP5 fast cgi with lighttpd on OS X

Lighttpd is a lightweight (lighter than Apache) http server. It has been gaining more an more press lately (The Ruby crowd uses it often for Rails).
You can run PHP on lighttpd as a CGI (Fast CGI prefferably). You can even keep your existing Apache/PHP install and run Lighttpd/PHP side by side (on another port)

Step 1: Install lighttpd.

By far the easiest way to do this on a OSX is with darwin ports (easy to install, easy to upgrade). In a terminal just issue:

$ sudo port install lighttpd

It will most likley install a few prerecusits and then lighttpd. If you are not a dp fan, compiling and installing lighttpd is not dificult either, see their docs for that.
Step 2: Install a Fast CGI enabled PHP5.

Download the latest PHP5 tarball (at the time of this writing that was 5.2.0)
cd to the unpacked php-5.2.0 directory and run your configure command. In my case I used…

./configure –prefix=/usr/local/php-fcgi
–enable-fastcgi
–with-mysqli=/usr/local/mysql/bin/mysql_config
–with-mysql=/usr/local/mysql
–with-curl=/usr/include
–with-xsl
–with-gd
–with-png-dir=/opt/local
–with-jpeg-dir=/opt/local
–enable-sockets
–with-gettext=/opt/local
–with-zlib-dir=/opt/local
–with-config-file-path=/etc
–with-xml-rpc
–enable-mbstring
–with-iconv
–enable-memory-limit

Two things are important here.

1. –prefix=/usr/local/php-fcgi : This needs to be different than your existing php install. If not you will overwrite/corrupt that existing install.
2. –enable-fastcgi : Self explanitory

As for the other config flag, just use what you need, this example is just what I use.
When configure completes run make then sudo make install
You will end up with a php install at what was used for ‘–prefix=…’ (/usr/local/php-fcgi in my case)
Take PHP’s example php.ini file ({php-source-dir}/php.ini-recommended) and move it to /etc/php-fast-cgi.ini (in my case since I used –with-config-file-path=/etc). Naming the file php-fast-cgi.ini rather than php.ini caused this cgi version of PHP to use that ini file rather than say another php.ini file there that Apache is using. This lets you run Apache mod PHP and cgi PHP on the same box and keep the ini files centaly located.
Step 3: Configure Lighttpd.

Lighttpd has aconfig file (similar to httpd.conf) and after a darwin ports install it can be found at /opt/local/etc/lighttpd/lighttpd.conf.default. First make a copy of that file

$ sudo cp /opt/local/etc/lighttpd/lighttpd.conf.default /opt/local/etc/lighttpd/lighttpd.conf

Now with you favorite editor, make these changes to lighttpd.conf.

within server.modules, uncomment (delete the ‘#’) for “mod_fastcgi”,

set the document-root to something appropriate, I used…

server.document-root = “/Users/sam/Sites/lighttpd/root/”

set the erorlog to something appropriate, I used…

server.errorlog = “/Users/sam/Sites/lighttpd/logs/lighttpd.error.log”

for OS X uncomment server.event-handler…

## set the event-handler (read the performance section in the manual)

server.event-handler = “freebsd-kqueue” # needed on OS X

Set the accesslog to something appropriate…

accesslog.filename = “/Users/sam/Sites/lighttpd/logs/access.log”

Set the server.port (I used 8181, you can use any available port)…

server.port = 8181

Set up the fast-cgi section. This is the minimum needed, see the lighttpd docs for more info.

fastcgi.server = ( “.php” => ((

“bin-path” => “/usr/local/php-fcgi/bin/php”,

“socket” => “/tmp/phpfcgi.socket”

)))

Set up the user and group for lighttpd to run as. I chose www (should exist on OSX, you can use any ‘unprivileged’ user)

server.username = “www”

server.groupname = “www”

Okay, save that file and quickly create the directories we refered to in the config file (if they do not exist) and change there ownership to the server.username:server.groupname you chose above (www:www in my case)

$ mkdir -p /Users/sam/Sites/lighttpd/root /Users/sam/Sites/lighttpd/logs

$ sudo chgown -R www:www /Users/sam/Sites/lighttpd/logs

Now we are ready to test our config file with this command (-t signifies test and -f tells lighttpd which config file to use)

$ /opt/local/sbin/lighttpd -t -f /opt/local/etc/lighttpd/lighttpd.conf

If all is well, you should see “Syntax OK”. If not, google your error or look at the docs for lighttpd
Step 4: Start lighttpd.

From the terminal issue

$ sudo /opt/local/sbin/lighttpd -f /opt/local/etc/lighttpd/lighttpd.conf

Now place a test php file in your lighttpd web-root (/Users/sam/Sites/lighttpd/root/index.php in my case) and put these lines in it.

Save the file and then open abrowser and go to http://localhost:8181/index.php and you should see something like

php-fcgi.png

Ths important thing here is that you go to localhost:8181 (not localhost or localhost:80). The nice thing is, if you already had PHP/Apache installed, you can still use that on whatever local URL you had setup (i.e. http://localhost)

So welcome to lighttpd. There is a vast amount on lighttpd that was not covered here, so be sure to check out the lighttpd site for more details.

Insta’ favicon

Dynamic Drive has a very nice favicon tool. I’ve been a fan of the Drive for many years now. Great place to find DHTML widgets