Tuesday, December 15, 2009

Books: My Reading List

what am i reading at the moment? i guess everyone's got some kind of a list of books one currently reads or is interested in reading; the same goes for music, which albums to listen to or crave for, and also what movies one has seen and which ones one might consider to collect as DVD issues. here's my recent reading list:

Thomas Pynchon: Inherent Vice

Alex Halberstadt: Lonely Avenue: The Unlikely Life and Times of Doc Pomus
this title reminded my of the song i first heard on a Van Morrison record and only later on a Ray Charles album. touchingly written!

Mark Twain: The Complete Interviews (Studies in American Literary Realism and Naturalism)
very interesting reading; i didn't know that Mark Twain at his own time was popularly known as a humorist. in my youth i'd never consider his Adventures of Tom Sawyer and Huckleberry Finn as humorous literature.

Mark Twain: Bummel durch Deutschland
Mark Twain: Bummel durch Europe
i'm considering getting these about Mark Twain's travels through Germany and Europe. they will certainly make facinating reading about Europe at the time.

Mark Twain: Die Schreckliche Deutsche Sprache (the awful german language)
i haven't seen this one at local bookstores, but it definitely sounds like an inviting title after what i've read so far about Mark Twain.

J. R. Moehringer: The Tender Bar: A Memoir (Audio Book)
i'm not a big fan of audiobooks, i'd rather read; but this one i find interesting since it's being read by the author 'n' i guess he'd put the pronounciations appropriately there where he'd 've wished to highlight or obscure in this tender memoir.

tom.paine


PHP: list all files of a local directory

... i haven't written an article since march ... here's a short script.

the issue: i wanted to save a list of a music albums i'd converted from CD to mp3 format. to avoid typing it all out i got myself a little script to do the work for me at mouse click:

<pre>
<?php
define('DEFAULT_DIR','D(rive):\\MyFolder\\');
$dir = (isset($_GET['dir'])) ? $_GET['dir'] : DEFAULT_DIR;
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
echo $file . "\n";
}
closedir($dh);
}
}
?>
</pre>


this code simply lists all files and folders of the MyFolder directory.

there was another code snippet i worked on: i wanted a list of the songtitles of a particular album without the .mp3 file extension; the code looks like this:

<?php
define('DEFAULT_DIR','D(rive):/MyFolder');
$dir = (isset($_GET['dir'])) ? $_GET['dir'] : DEFAULT_DIR;
?>
<html>
<head>
<title>List-All-Files : <?=$dir;?></title>
<script language="JavaScript" type="text/javascript">
<!--
function copyit(theField) {
var tempval=eval("document.linktable.list_table");
tempval.focus();
tempval.select();
therange=tempval.createTextRange();
therange.execCommand("Copy");
}
//-->
</script>
<style type="text/css">
<!--
body {font-family:'Trebuchet MS'; color:#AB0000;}
form {font-family:'Courier New', Courier; font-size: 12px;}
.button {font-family: Verdana, Helvetica, sans-serif; font-size: 11px; font-weight: bold; cursor: hand; color: #AB0000; margin-top: 3mm; border: 2px; border-color: #DDDDDD; border-style: outset; background-color: #FFFFFF; width: 150;}
.button1 {font-family: Verdana, Helvetica, sans-serif; font-size: 11px; font-weight: bold; cursor: hand; color: #AB0000; margin-top: 3mm; border: 2px; border-color: #DDDDDD; border-style: outset; background-color: #FFFFFF; width: 150;}
.button2 {font-family: Verdana, Helvetica, sans-serif; font-size: 11px; font-weight: bold; cursor: hand; color: #FFFFFF; margin-top: 3mm; border: 2px; border-color: #DDDDDD; border-style: outset; background-color: #AB0000; width: 150;}
-->
</style>
</head>
<body topmargin="0">
<center><h3><u><i>List-All-Files</i></u> : <?=$dir?></h3></center>
<form name="linktable">
<div><input class="button" type="button" value="COPY & PASTE" onclick="copyit();" onmouseover="this.className='button2'" onmouseout="this.className='button1'"></div><br>
<textarea style="width:875px; height:1000px; color:#FFFFFF; background-color:#AB0000;" name="list_table" readonly="readonly">
<?php
filesInDir($dir);
function filesInDir($tdir)
{
$dirs = scandir($tdir);
foreach($dirs as $file) {
if (($file == '.') || ($file == '..')) { }
elseif (is_dir($tdir.'/'.$file)) { filesInDir($tdir.'/'.$file); }
else { echo substr($file,0,strlen($file)-4)."\n"; } }
}
?>
</textarea>
</form>
</body>
</html>


this will list all files of the directory MyFolder minus the last 4 digits of the complete filename. of course if the file-extension would be .html it would still include the . (dot) in the filename; furthermore, this code displays the list in an easy to use copy and paste form field.

well, at least it's something, isn't it?

tom.paine


Monday, March 09, 2009

PHP: how to rename a bunch of files / Windows XP

last weekend i was looking for a solution to rename a bunch of .mp3 files that had underscores and small letters as filenames while i prefered spaces instead of the underscores and capital letters for the individual words of the filename.

fortunately PHP has some built in functions to replace one character with another as well as renaming files altogether. i assumed that someone had already done something like it, so i went looking for a code-snippet on the internet again.

i came across this link.

this person was struggling with the renaming of some image files. i started to try the examples and various explanations as given when i stumbled across the problem that Windows XP is a bit fuzzy about renaming files. just search this document for Permission Denied and you'll know what i mean.

here's one solution:

function rename_win($oldfile,$newfile) {
if (!rename($oldfile,$newfile)) {
if (copy ($oldfile,$newfile)) {
unlink($oldfile);
return TRUE;
}
return FALSE;
}
return TRUE;
}


but that one didn't work for me either. another problem i had was defining the directory that contained the files to be renamed. after a number of struggles i came up with this solution:

first i placed all the .mp3 files into one folder together with the following code-snippet i saved to a file that i named rename-a-file.php.

<?php
// source: http://forum.de.selfhtml.org/archiv/2004/11/t95097/
$handle = opendir ('.');
while ( $file = readdir ( $handle ) ) {
if ( $file == "." or $file == ".." ) {
} else {
if ( rename( $file, (ucwords(str_replace('_',' ',$file).$new)) ) ) {
echo "File $file found <br>";
} else {
echo "File $file not found <br>";
}
}
} closedir( $handle );
?>


running the script at first i didn't see the changes in the folder until i pressed the refresh button. now all the files had no more underscores and capital letters, even the rename-a-file.php which is now called Rename-a-file.php :-)

i keep the Rename-a-file.php file now in a separate folder named rename that i may not accidentally run the script and rename the files in the folder where i kept the copy originally, with all my other .php files.

here is another example, in this case i didn't need to replace any characters; i only needed to change the lowercase to uppercase characters:

<?php
// source: http://forum.de.selfhtml.org/archiv/2004/11/t95097/
$handle = opendir ('.');
while ( $file = readdir ( $handle ) ) {
if ( $file == "." or $file == ".." ) {
} else {
if ( rename( $file, (ucwords($file).$new) ) ) {
echo "File $file found <br>";
} else {
echo "File $file not found <br>";
}
}
} closedir( $handle );
?>


in these examples i have used the following PHP functions:

opendir
readdir
rename
ucwords
str_replace
closedir

Hopefully this may prove helpful to other users, too. Don't overdo it!

tom.paine


A Strange Way To Search

in my previous article i mentioned a link i came across while searching for a solution to my CSV problem.

i merely entered php csv if in the form field of the Google Search Engine and grabbed the first link on the list.

here's my original search for php csv if.

Have Fun!

tom.paine


Saturday, February 21, 2009

PHP: how to make amendments to a CSV file

in my third article for today i want to write about a problem i had with a massive csv file the other night:

i got this big CSV file which contains over 3300 lines of entries. those entries include a date, but i can't use that date for sorting. first of all it's written among a string of other details; it's written as 20 February 2000 or February 20, 2000 or February 20 2000. that's 3 different ways. i decided that i needed another column in my CSV file where i'd store the date as a sortable value. i found that a leading id-number was followed by 3 whitespaces, and that those 3 whitespaces were otherwise not used in the document. so i decided to open my CSV file with WordPad and change the 3 whitespaces to 2 pipes thus: ||. inbetween those pipes i would store the date value i want to use for sorting. i spent about 2 nights entering the date by copying and pasting it right there when on the second night my screen got stuck again and i had to re-start my computer. i was just paging down the document when it happened; and i thought that i had just saved the document.

after re-starting my laptop i found out that the document had been in the process of saving when the screen got stuck. only a third of this document was still available to me. of course i had some kind of a backup copy, but that was the copy without the pipes. now i had to decide: do i start from scratch or am i going to look around for a script that could maybe do it with PHP which i wanted to do all the while anyway?.

i was a bit upset about all this since it was such a boring job to do and i knew i would be glad once i'd reached the end of the file.

alright, let me search the internet for some kind of a solution that may come close to what i want to achieve. now, what am i going to search for? how about php amend csv file?

in a german forum i found someone who tried to search for results in a CSV document: http://forum.de.selfhtml.org/archiv/2008/5/t171322/.

i started playing with that one. the person couldn't get his script to work.

here's my version of the script:

<pre style="font-family:'Courier New', Courier; font-size:11px; color:blue;">
<?php
define('SEARCH', '1961');
$s = (isset($_GET['s'])) ? $_GET['s'] : SEARCH;
$csv_file_open = fopen("worksheet.csv", "r");
$row = 1;
while ($data = fgetcsv ($csv_file_open, 1000, "|")) {
if (stristr ( $data[2], $s )) {
echo $data[0] . "|" . $s . "-";
echo $data[1] . "|";
echo $data[2] . "\n";
}
$row++;
}
fclose($csv_file_open);
?>
</pre>


this code snippet lets me search my document for the date 1961 (as a default value) and squeezes it between the id number and the other string devided by the pipe symbol, provided it finds the date value i've given. if i want another search result i could add ?s=1980, for instance, as a url parameter after the file name. the problem is, if i search for New York City, it would enter New York City, where found, between those 2 pipe symbols ... hm ... not exactly what i had in mind.

i gave the idea some more thought and came up with a solution that uses $y as a variable for the year, $m as a variable for the month and $d as a variable for the day. hm, that looks pretty good for starters.

as usual, i made a copy of my first example for keepsake and decided to work with a new php file i named csv-add-date.php.

i kept some of the old code, but for the moment i wouldn't need the $s variable.

here's my code in the csv-add-date.php file:

<pre style="font-family:'Courier New', Courier; font-size:11px; color:blue;">
<?php
define('SEARCH', '1961');
$s = (isset($_GET['s'])) ? $_GET['s'] : SEARCH;
$csv_file_open = fopen("clean_sheet.csv", "r");
$row = 1;
while ($data = fgetcsv ($csv_file_open, 1000, "|")) {
include ( 'csv-calculate-year.php' );
include ( 'csv-calculate-01-jan-day.php' );
include ( 'csv-calculate-02-feb-day.php' );
include ( 'csv-calculate-03-mar-day.php' );
include ( 'csv-calculate-04-apr-day.php' );
include ( 'csv-calculate-05-may-day.php' );
include ( 'csv-calculate-06-jun-day.php' );
include ( 'csv-calculate-07-jul-day.php' );
include ( 'csv-calculate-08-aug-day.php' );
include ( 'csv-calculate-09-sep-day.php' );
include ( 'csv-calculate-10-oct-day.php' );
include ( 'csv-calculate-11-nov-day.php' );
include ( 'csv-calculate-12-dec-day.php' );
echo $data[0] . "|" . $y . "-" . $m . "-" . $d;
echo $data[1] . "|";
echo $data[2] . "\n";
$row++;
}
fclose($csv_file_open);
?>
</pre>


i'm also using a new CSV file which i named clean_sheet.csv.

... and here is an excerpt from my csv-calculate-year.php:

<?php
if (stristr ( $data[2], '1958' )) { $y = '1958'; }
elseif (stristr ( $data[2], '1960' )) { $y = '1960'; }
elseif (stristr ( $data[2], '1961' )) { $y = '1961'; }
elseif (stristr ( $data[2], '1962' )) { $y = '1962'; }
elseif (stristr ( $data[2], '1963' )) { $y = '1963'; }
elseif (stristr ( $data[2], '1964' )) { $y = '1964'; }
elseif (stristr ( $data[2], '1965' )) { $y = '1965'; }
elseif (stristr ( $data[2], '1966' )) { $y = '1966'; }
elseif (stristr ( $data[2], '1967' )) { $y = '1967'; }
elseif (stristr ( $data[2], '1968' )) { $y = '1968'; }
elseif (stristr ( $data[2], '1969' )) { $y = '1969'; }
elseif (stristr ( $data[2], '1970' )) { $y = '1970'; }
...
?>


another example from one of the files that calculate the month and day:

<?php
if ( (stristr ( $data[2], ' 1 January ' )) || (stristr ( $data[2], ' January 1 ' )) || (stristr ( $data[2], ' January 1,' )) ) { $m = '01'; $d = '01'; }
elseif ( (stristr ( $data[2], ' 2 January ' )) || (stristr ( $data[2], ' January 2 ' )) || (stristr ( $data[2], ' January 2,' )) ) { $m = '01'; $d = '02'; }
elseif ( (stristr ( $data[2], ' 3 January ' )) || (stristr ( $data[2], ' January 3 ' )) || (stristr ( $data[2], ' January 3,' )) ) { $m = '01'; $d = '03'; }
elseif ( (stristr ( $data[2], ' 4 January ' )) || (stristr ( $data[2], ' January 4 ' )) || (stristr ( $data[2], ' January 4,' )) ) { $m = '01'; $d = '04'; }
elseif ( (stristr ( $data[2], ' 5 January ' )) || (stristr ( $data[2], ' January 5 ' )) || (stristr ( $data[2], ' January 5,' )) ) { $m = '01'; $d = '05'; }
elseif ( (stristr ( $data[2], ' 6 January ' )) || (stristr ( $data[2], ' January 6 ' )) || (stristr ( $data[2], ' January 6,' )) ) { $m = '01'; $d = '06'; }
elseif ( (stristr ( $data[2], ' 7 January ' )) || (stristr ( $data[2], ' January 7 ' )) || (stristr ( $data[2], ' January 7,' )) ) { $m = '01'; $d = '07'; }
elseif ( (stristr ( $data[2], ' 8 January ' )) || (stristr ( $data[2], ' January 8 ' )) || (stristr ( $data[2], ' January 8,' )) ) { $m = '01'; $d = '08'; }
elseif ( (stristr ( $data[2], ' 9 January ' )) || (stristr ( $data[2], ' January 9 ' )) || (stristr ( $data[2], ' January 9,' )) ) { $m = '01'; $d = '09'; }
elseif ( (stristr ( $data[2], ' 10 January ' )) || (stristr ( $data[2], ' January 10 ' )) || (stristr ( $data[2], ' January 10,' )) ) { $m = '01'; $d = '10'; }
...
?>


that last code is included in 12 files one for each month. in each one i had to replace the name of the month, say January with March for instance; and $m = '01 ought to be replaced with $m = '02 in the case of February.

those year and month/day files are included in the csv-add-date.php file using PHP's include function.

this csv-add-date.php file basically loads the clean_sheet.csv file and adds the year, month and day before it displays the content on the screen. it does not write the content to the clean_sheet.csv file. i think i'm going to get that done in another step to another new CSV file ... in case something should go wrong again.

now i can save myself a lot of time ... and boredom ... and repeat the process if necessary. this exercise has also taught me how to search through CSV files and display the results. that may be the topic of another article ...

i hope that this has been of some help to PHP coders.

Good Luck!

tom.paine


PHP: how to delete the last line of a file?

i'm a little friend of MySQL, but a big friend of writing content to files, text files or csv (comma-separated-value) files. one reason is that i haven't really worked that much with MySQL. i just know the basics and have usually worked with them when setting up a forum or webshop. those scripts are readily available all across the internet.

i was going to set up a table using either XML or PHP's array function with a script that would write either the XML file, or a PHP fie that i could include in another script which in turn could be used to create an XML file or simply HTML.

i looked at various examples and tutorials on the internet on how to manipulate XML files with PHP, but i wasn't too happy about where the new elements would be placed in the XML document eventually.

of course one of the problems would always be: how would i squeeze a new set of elements before the closing root element; or how would i get rid of the ?> at the end of the php file i wish to include somewhere else.

the basic idea i found here: http://bytes.com/groups/php/11847-how-delete-last-line-file.

below is the code snippet from that page that got me going:

$inp = file('yourfile.name');
$out = fopen('yourfile.name','w');
for ($i=0;$i<count($inp)-1;$i++)
fwrite($out,$inp[$i]);
fclose($out);


in this particular case the information of one file is written to another file. (not 100% what i was looking for).

in the end i started using this example:

$my_input = '$my_'.$_GET['my_number'].' = array ( $my_date => \''.$_GET['my_date'].'\', $my_city => \''.$_GET['my_city'].'\', $my_links => \''.$_GET['my_links'].'\', \'$my_update => \''.$_GET['my_update'].'\', );'."\n";
// load the data and delete the line from the array
$lines = file('#_MyIncludeFile.inc.php');
$last = sizeof($lines)-1;
unset($lines[$last]);

// write the new data to the file
$input = fopen('#_MyIncludeFile.inc.php','w');
fwrite($input, implode('', $lines));
fwrite($input, $my_input);
fwrite($input, "?>");
fclose($input);


the $_GET variables are submitted from a form:
<form method="GET" action="WriteToFile.php">
<table>
<tr><td>my my number:</td><td><input type="text" name="my_number" /></td></tr>
<tr><td>my my date:</td><td><input type="text" name="my_date" /></td></tr>
<tr><td>my my city:</td><td><input type="text" name="my_city" /></td></tr>
<tr><td>my my links:</td><td><input type="text" name="my_links" /></td></tr>
<tr><td><input type="hidden" name="my_update" value="<?=time();?>" /><br />
<br /><input type="submit" value="send" /></td></tr>
</table>
</form>


the WriteToFile.php file also contains this form for further input.

this script writes CSV data to a PHP file which can then be used elsewhere for further analyzes.

i think that says it all ... or are there any questions?

Good Luck again!

tom.paine


"Class 'XSLTProcessor' not found"

the other day i was trying an example from an xsl tutorial and couldn't get it to work, instead i got the error message "Class 'XSLTProcessor' not found".

here is how i solved it:

first i thought my php versions were not up to date. i'm running php4 and php5 with Apache 1.3 under OS Windows XP. i downloaded the Windows Binaries ZIP folders, unpacked them and placed the contents into my c:\php4 and c:\php5 directories respectively and re-started Apache. trying the example again i still got the same error message.

i thought that maybe something wasn't right in the php.ini files. therefore i made a copy of the php.ini-recommended and renamed it php.ini. i opened the php.ini file with WordPad and searched the document for xsl. the search went to the line that reads ;extension=php_xsl.dll. i uncommented that line by removing the semi-colon. now the line reads: extension=php_xsl.dll. After re-starting the server again i tried the script example once more and still got the same error message: "Class 'XSLTProcessor' not found".

alright ... i was wondering which php.ini file php was looking at and saved the following code snippet in a file named test.php:


<?php
phpinfo();
?>


after i ran this test.php file php displayed the current settings and i found that it was not looking for the php.ini file in the c:\php4 or c:\php5 directories at all, but in the c:\WINDOWS directory.

okay ... i looked for that php.ini file in the c:\WINDOWS directory, opend the file, searched for xsl again and made the change as described above.

after re-starting the server and running the script example again, believe it or not, it still gave me that error message. things like that can become quite frustrating, especially if one tests a script in the localhost environment where it won't and at the webhosting server, where it may work.

i'm not giving up so easily. i knew that the xsl extension under windows is a .dll file that can be found in the ext dirctory. and i also knew that this was a feature only introduced with php5. i checked to see if the php_xsl.dll file existed in the ext folder, which it did; then i went back to the php documentation to see how i would have to set up php under windows and came across this comment: http://de2.php.net/manual/de/book.xsl.php#65277.

alright, so i had to change the path to this ext directory.

i had the php.ini file still open (WordPad) and searched for extension_dir. the line read:

extension_dir = "./"

which i changed to read:

extension_dir = "./ext"

re-starting the Apache Server one more time and running the example script once more at last i saw the expected result on the screen and could go to rest happily after all.

so before someone else has to battle with this issue:
first: check to see if the php_xsl.dll file exists;
second: check to see which php.ini file you gotta change;
third: uncomment ;extension=php_xsl.dll and change the extension directory to extension_dir = "./ext" in the relevant php.ini file.

... and don't forget to re-start the Apache Server!

Good Luck!

tom.paine


Saturday, November 08, 2008

A Free-Fallin' Introduction to Amazon Web Services

going through my old email folder the other day i came across Amazon Web Services Newsletter #3 dated 27 August 2003.
the summaries of that newsletter are given below:

===========
1. AWS News
===========

Summary
-------
* Product Description Returned
* Availability in Lite Results
* Japanese Marketplace Access
* Japanese Search
* UPC Search
* Scratchpad for UK
* RSS Feeds
* Shopping Cart Similarities
* ASIN Link Changes
* Honor System Payment API Beta Test
* SOAP Error Response
* Proper use of International Servers

=============
2. AWS Issues
=============

Summary
-------
* Determining Buyability Using Availability
* Developer Token Usage
* Using Older Versions of AWS
* Storing ASINs
* NuSOAP Compatibility

===================
3. In the Community
===================

Summary
-------
* Discussion Board
* Board Summary
* Weekly Chats
* Newsletter
* Featured Sites and Applications
* Press

==================
4. Tips and Tricks
==================

Summary
-------
* Featured style sheet
* Featured code snippet
* Featured tip
* Your contributions welcome
* Local Associates Programs

among Featured Sites and Applications is a link to an article for a Mozilla tool for browing the Amazon Catalog:
http://www.oreillynet.com/pub/a/mozilla/2003/05/02/casestudy2.html
today i took a look at another chapter referred to at the beginning of this casestudy:
http://www.oreillynet.com/pub/a/mozilla/2002/12/17/app_dev.html.

That same newsletter also features a link to an interesting article on RSS by author: Ravikiran Muvva at Code101.com:
http://www.code101.com/Code101/DisplayArticle.aspx?cid=41.

going through my email archive looking for more information i discovered that this newsletter was the oldest one i'd kept. some time after that i changed my email account setup and seem to have stored everything related to Amazon Web Services from newsletter #10 onwards. that means i can document quite a history on the development of Amazon Web Services to the present stage.

with this article i would like to guide the reader through an example of how i recently migrated a script from Amazon Web Services 3.0 -- which was the stage we were in on August 27th, 2003 -- to the present version Amazon E-Commerce Service 4.0.

on 6 February 2007 Amazon informed its Web Service Subscribers as follows:

*****************************************************************
AMAZON ECS 3.0 SUNSET: PLEASE MIGRATE TO AMAZON ECS 4.0
*****************************************************************
After many years of useful service, the Amazon E-Commerce Service 3.0
(Amazon ECS 3.0) web service will be shut down on March 31, 2008. Since
the introduction of Amazon ECS 4.0 in late 2004 the usage of Amazon ECS 3.0
has steadily declined as sites and applications have naturally migrated to
Amazon ECS 4.0. In June of 2006 (Version: 2006-06-28), we achieved
complete feature and data parity between the two services and are now
requesting that all existing sites and applications be migrated to Amazon
ECS 4.0 within the next 12 months. Beginning March 31, 2008, we will no
longer be accepting Amazon ECS 3.0 requests. The existing maintenance
effort saved by shutting down Amazon ECS 3.0 will be re-invested into
Amazon ECS 4.0 to allow for the introduction of more features and
capabilities.
Let's take a look at Chapter 6 from Paul Bausch's Amazon Hacks Book:

Amazon Hacks
Hack 80 Program AWS with Perl

below is the original code listing:
#!/usr/bin/perl
# amazon_http.pl
# A typical Amazon Web API Perl script using the XML/HTTP interface
# Usage: amazon_http.pl <keyword>

#Your Amazon developer's token
my $dev_key='insert developer token';

#Your Amazon affiliate code
my $af_tag='insert associate tag';

#Take the keyword from the command-line
my $keyword =shift @ARGV or die "Usage:perl amazon_http.pl <keyword>\n";

#Assemble the URL
my $url = "http://xml.amazon.com/onca/xml3?t=" . $af_tag . "&dev-t=" . $dev_key . "&type=lite&f=xml&mode=books&" . "KeywordSearch=" . $keyword;

use strict;

#Use the XML::Parser and LWP::Simple Perl modules
use XML::Simple;
use LWP::Simple;

my $content = get($url);
die "Could not retrieve $url" unless $content;

my $xmlsimple = XML::Simple->new( );
my $response = $xmlsimple->XMLin($content);

foreach my $result (@{$response->{Details}}){
#Print out the main bits of each result
print
join "\n",
$result->{ProductName}||"no title",
"ASIN: " . $result->{Asin} . ", " .
$result->{OurPrice} . "\n\n";
}
as we can see this code is meant to be used from the command line. however, i wanted to execute this code from my host's server using my browser. therefore i changed the following line from
#Take the keyword from the command-line
my $keyword =shift @ARGV or die "Usage:perl amazon_http.pl \n";
to
#Take the keyword from the command-line
my $keyword = 'Bob%20Dylan';
now my code looks like this:
#!/usr/bin/perl -w
# amazon_http.pl
# A typical Amazon Web API Perl script using the XML/HTTP interface
# Usage: amazon_http.pl <keyword>

BEGIN {
$| = 1;
open (STDERR, ">&STDOUT");
print qq~Content-type: text/html\n\n~;
}

#Your Amazon developer's token
my $dev_key='D23VNPYO8ODZL6';

#Your Amazon affiliate code
my $af_tag='downinthefloo-20';

#Take the keyword from the command-line
my $keyword = 'Bob%20Dylan';

#Assemble the URL
my $url = "http://xml.amazon.com/onca/xml3?t=" . $af_tag . "&dev-t=" . $dev_key . "&type=lite&f=xml&mode=books&" . "KeywordSearch=" . $keyword;

print "<a href=\"".$url."\" target=\"new\">The Request</a><br> <br>";

use strict;

#Use the XML::Parser and LWP::Simple Perl modules
use XML::Simple;
use LWP::Simple;

my $content = get($url);
die "Could not retrieve $url" unless $content;

my $xmlsimple = XML::Simple->new( );
my $response = $xmlsimple->XMLin($content);

foreach my $result (@{$response->{Details}}){
#Print out the main bits of each result
print
join "\n",
$result->{ProductName}||"no title",
"ASIN: " . $result->{Asin} . ", " .
$result->{OurPrice} . "\n\n";
}
other differences to the original code snippet are:
a) use of the Warning switch -w;
b) use of a code snippet that will allow me to display the details of a possible error 500 message if there is any;
c) inclusion of a link to Amazon's xml document in case of:
   ca) no items being displayed;
   cb) an error message being displayed;

alright: the script has been uploaded to the cgi-bin folder on the server and we are able to access the script using our preferred browser: http://localhost/cgi-bin/amazon_http_old.pl (i added _old to the file name since i know it's not gonna work and i got a new version ready to go :-) )

running the script will display the following error message:
The Request

Could not retrieve http://xml.amazon.com/onca/xml3?t=downinthefloo-20&dev-t=D23VNPYO8ODZL6&type=lite&f=xml&mode=books&KeywordSearch=Bob%20Dylan at PATH/TO/htdocs/cgi-bin/amazon_http_old.pl line 33.
where The Request is an active link to Amazon's xml document:

once we click on that link to see what went wrong we are being re-directed to an error page:
Amazon.com
We're Sorry - Service Gone

Amazon Ecommerce Web Service 3.0 has been deprecated after many years of useful service
on March 31st 2008. Please upgrade to the Amazon Associates Web Service 4.0 as detailed
in the migration guide. Please visit Amazon Associates Web Service Developer Forum for more
information. If you came to this page from an RSS feed, visit Amazon's Product RSS Feeds
page for an upgrade.
visiting the migration guide we can quickly detect a few things that have changed; for instance: the base url:
http://xml.amazon.com/onca/xml3
would now be
http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService
the Developer Token (dev-t) has now become the AWSAccessKeyId;
the search "mode" would now be a SearchIndex value;
the request "type" has in the past been lite or heavy;
the xml feed result would display more details with the heavy type than with the lite type.
this request parameter is now being named "ResponseGroup" and allows for a number of various feed results.
the main ResponseGroups are Small, Medium and Large.
to be on the safe side when we now alter our request url we are going to use &ResponseGroup=Large.
i should mention here that all those terms are case-sensitive.
when we go back to our migration guide once again for the KeywordSearch paramter we find now that Amazon states two values instead of just one: SearchIndex, Keywords; this means for a KeywordSearch we also require the SearchIndex value; since our mode was books, our SearchIndex should be Books (in this case with a capital 'B'), also the SearchIndex values are case-sensitive. furthermore, these SearchIndices vary from country to country (locale to locale).
our parameters now look like this: &SearchIndex=Books&Keywords=Bob%20Dylan. with ECS 4.0 two further parameters have been introduced, of which the first one (Operation) is required, the second one (Version) is not obligatory.
to lookup the details of a single item we would use the parameter &Operation=ItemLookup; however, we would need the ASIN or ISBN number of that item, but since we do not know such a number yet we will use the &Operation=ItemSearch parameter.

Amazon is continually adding features for making ECS requests. recently, for example, they have added links to add items to a WishList, Baby-, or WeddingRegistry, or to Tell-A-Friend to their xml response documents. sometimes when they have added a new product range to a particular locale it may be added to the list of available SearchIndex values. to use these added features it may be necessary to add the paramter &Version=2008-08-19 to the request url.

here you may find the latest Developer Guide with many more details than i would be able to cover within this article.

it looks like we can now start to assemble our new request url:

well, i forgot about the associate id: in the past that used to be just "t"; that has now become: "AssociateTag".

http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService
&AssociateTag=downinthefloo-20
&AWSAccessKeyId=1BZ9VRA5AKNBPYJM6YR2
&Operation=ItemSearch
&SearchIndex=Books
&ResponseGroup=Large
&Keywords=Bob%20Dylan
let's see if this request will give us a new xml feed document (try this link): The Request.

it worked: this time we see no error message but the xml feed document we expected and can now analyze the elements we need within the foreach loop of our script in order to display some items in our browser window:

here are the details i have chosen for my short example:

foreach my $result (@{$response->{Items}->{Item}}){
#Print out the main bits of each result
print
join
"\n",
"<a href=\"".$result->{LargeImage}->{URL}."\" target=\"image\"><img src=\"".$result->{MediumImage}->{URL},"\" border=\"0\" alt=\"".$result->{ItemAttributes}->{Title}."\"></a>",
"<br>Title: ".$result->{ItemAttributes}->{Title},
"<br>Author: ".$result->{ItemAttributes}->{Author},
"<br>Binding: ".$result->{ItemAttributes}->{Binding},
"<br>ASIN: ".$result->{ASIN},
"<br>Price: ".$result->{ItemAttributes}->{ListPrice}->{FormattedPrice} || "price unavailable",
"<br><a href=\"".$result->{DetailPageURL}."\" target=\"_blank\">buy now</a><hr>",
"<br>\n\n";
}
my complete code example now looks as follows:

#!/usr/bin/perl
# amazon_http.pl
# A typical Amazon Web API Perl script using the XML/HTTP interface
# Usage: amazon_http.pl <keyword>

#Your Amazon developer's token
my $dev_key='1BZ9VRA5AKNBPYJM6YR2';

#Your Amazon affiliate code
my $af_tag='downinthefloo-20';

#Take the keyword from the command-line
my $keyword = 'Bob%20Dylan';

#Assemble the URL
my $url = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AssociateTag=" . $af_tag . "&AWSAccessKeyId=" . $dev_key . "&Operation=ItemSearch&SearchIndex=Books&&Keywords=" . $keyword . "&ResponseGroup=Large";

print "<a href=\"".$url."\" target=\"new\">The Request</a><br> <br>";

use strict;

#Use the XML::Parser and LWP::Simple Perl modules
use XML::Simple;
use LWP::Simple;

my $content = get($url);
die "Could not retrieve $url" unless $content;

my $xmlsimple = XML::Simple->new( );
my $response = $xmlsimple->XMLin($content);
foreach my $result (@{$response->{Items}->{Item}}){
#Print out the main bits of each result
print
join
"\n",
"<a href=\"".$result->{LargeImage}->{URL}."\" target=\"image\"><img src=\"".$result->{MediumImage}->{URL},"\" border=\"0\" alt=\"".$result->{ItemAttributes}->{Title}."\"></a>",
"<br>Title: ".$result->{ItemAttributes}->{Title},
"<br>Author: ".$result->{ItemAttributes}->{Author},
"<br>Binding: ".$result->{ItemAttributes}->{Binding},
"<br>ASIN: ".$result->{ASIN},
"<br>Price: ".$result->{ItemAttributes}->{ListPrice}->{FormattedPrice} || "price unavailable",
"<br><a href=\"".$result->{DetailPageURL}."\" target=\"_blank\">buy now</a><hr>",
"<br>\n\n";
}
at last you can see what the result of this short script will look like on the screen:
http://www.downintheflood.com/cgi-bin/amazon_http.pl

hope you enjoyed this rather short example from a long article!

tom.paine


Thursday, May 08, 2008

The Wish List Widget

today the Wish List Widget has officially been published: visit downintheflood.com or outlawblues.de. one issue that wasn't mentioned in the process are the css style details used to display the Wish List on the right side of the screen, so i just decided to write about them here:

first i would like to display the external stylesheet used to display the Wish List as seen at the above two links:

#wishlist_div              {position:absolute; top:0; right:0;}
#wishlist_img              {font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#CC0000;}
#wishlist_price            {font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#0000FF;}
#wishlist_product          {font-family:Arial, Helvetica, sans-serif; font-size:11px; color:#0000FF;}
a#wishlist_ahref:link      {color:#CC0000; font-family:Tahoma, sans-serif, Arial; font-size:11px; text-decoration:none;}
a#wishlist_ahref:hover     {color:#CC0000; font-family:Tahoma, sans-serif, Arial; font-size:11px; text-decoration:underline;}
a#wishlist_ahref:active    {color:#FFFF00; font-family:Tahoma, sans-serif, Arial; font-size:11px; text-decoration:underline;}
a#wishlist_ahref:visited   {color:#FF0000; font-family:Tahoma, sans-serif, Arial; font-size:11px; text-decoration:underline;}


you may notice that the styles all consist of a id for wishlist. this has been done to avoid any conflict with existing CMS styles. in addition to that wishlist links are being referred to with the id wishlist_ahref; similarily the wishlist_div and wishlist_img id's refer to the relevant <div> and <img> elements. there are several more: the following css styles display all the available id's that can be used in conjunction with the Wish List Widget; either from an external css file of from within the html page:

@charset "utf-8";
a#wishlist_ahref:link    { font-weight:bold; text-decoration:none; color:#000066; }
a#wishlist_ahref:visited { font-weight:bold; text-decoration:none; color:#003366; }
a#wishlist_ahref:hover   { text-decoration:underline; color:#AB0000; }
a#wishlist_ahref:active  { text-decoration:underline; color:#CC0000; }
#wishlist_div            { background-color:#339A99; width:355px; font-family:Trebuchet MS, Verdana, Tahoma, sans-serif; font-size:8pt; position:absolute; top:0px; left:0px; }
#wishlist_img            { background-color:#0000FF; padding-top:5px; padding-bottom:3px; padding-left:8px; padding-right:15px; }
#wishlist_list_price     { color:#990000; }
#wishlist_price          { color:#AB0000; font-size:10pt;}
#wishlist_product        { background-color:#CC0000; color:#F6F6F6; font-size:10pt; font-weight:bold; }
#wishlist_table          { background-color:#FFFF80; width:250px; padding:5px; }
#wishlist_td_img         { background-color:#CC00CC; width:150px; padding:5px; text-align:center; }
#wishlist_td_product     { background-color:#FFFFFF; width:150px; padding:0px; }
#wishlist_your_price     { color:#0000FF; }


to see what the colorful layout looks like when the above styles are being used take a look at Mr Rat's Wishlist; if you think that i may have overdone it somewhat on the colors, it is obvious that this has only been done so for demonstration purposes. take special note of the @charset "utf-8"; on the first line of this css style section!

the JavaScript uses PHP in the background to retrieve the Wish List from Amazon's server by making use of Amazon Associates Web Services features. the XML result returned by Amazon is utf-8 encoded, thus the page needs to be utf-8 encoded in order to display special characters properly.

if you use

#wishlist_div              {position:absolute; top:0; left:0;}


from the first css example, instead of

#wishlist_div              {position:absolute; top:0; right:0;}


it will display the Wish List Widget on the left side of the screen instead of the right side;

from the optical point of view it looks better to have the image to the left side when the Widget is displayed on the left side of the screen, and on the right side should the Widget be displayed on the right side of the screen. that's why there is a choice in the setup file to choose between left and right; two separate PHP files are being used to display it so.

some users may have a question about the slot(s); i called them that for lack of a better explanation. it's a kind of a place to fit in. if a growing number of users should implement the Widget on their websites, the demand on one file could slow down the Widget to show up, especially since the information has first to be gathered from Amazon's servers. that's why i have spread the files over altogether 52 directories, 26 on each site mentioned above so people can choose a different site or directory and it will not all come out of one pot. there's no other purpose than that. besides that: Amazon has made it obligatory that one can make only 1 request to their servers per second; that means the request sleeps for a sec before being processed.

i guess that's all that's gotta be said about this project besides what's already been mentioned elsewhere, if so. ... the story continues ...

tom.paine

Thursday, April 24, 2008

AJAX: Online-Editor

in today's article i would like to introduce the reader to the AJAX: Online-Editor which i mentioned in yesterday's post referring to the book Praxiswissen Ajax.

since the book and the source code are in german i translated it (hopefully all of it) into english and made it available for download at http://www.downintheflood.com/download/ajax-online-editor.zip

you can see it also online at: http://www.downintheflood.com/source/ajax/

however, in order to avoid people entering or deleting any code or files, or adding files with content that i wouldn't want there i have removed the [New File]   [Save File]   [Save As ...]   [Delete File] buttons from my online application. furthermore i have set the textarea field on the right to readonly. just the [update] button works.

but i won't leave you that much in the dark here, i have created a few screenshots so you can roughly see what it looks like. if you are going to use it online you should, however, keep the folder contents in a password protected area where those users whom you'd grant access to the application will have the liberty to create, alter or delete files.

the first screen shot shows the layout of the page as it comes up on the screen the first time, that is, when you load the index.html into your browser (the application requires PHP4).



once you have clicked on a file name on the left side of the screen, the content of that file shows up in the textarea element on the right side of the screen as seen below:



if you want to delete a file an alert message asks you if you really want to delete this file:



if you confirm the O.K. the contents will be removed from the screen, the file will be removed from the file list on the left and a message appears in the status bar at the bottom of the editor that the file has been deleted:



with the last screenshot i wanted to display the error message that comes up when the client (browser) is unable to load the list from the server. the browsers behave differently, Firefox pops up an alert window while Internet Explorer will show the yellow warning triangle on the bottom left of the screen. here is the screenshot with the blank editor unable to load the files:



i changed the layout somewhat from the original layout. the original is smaller. i also changed the color setting of the original layout. if you want to use the smaller version you can download the stylesheet at this link.

now i hope you'll enjoy this little toy and learn about AJAX by studying the code in greater detail and using it perhaps in other applications.

until then.

tom.paine

Wednesday, April 23, 2008

JavaScript ... PHP Array sorting plus ...

after i've spent several hours last sunday always battling to insert the code snippets into this blog without having a special facility to show code content i decided to upload one of the old source viewer scripts that i had in my archive and use links to the source viewer in future to highlight the code examples ... unless they are less complex.

in today's article i would like to take a brief look at JavaScript examples as well as the various effects of sorting an array with php.

let me start with the php examples, because they are all ready for take off:
the results of this source code can be seen here: http://www.downintheflood.com/source/examples.php5.

at the top you see the example array and below you see the various sort functions to sort the array forwards and backwards and by key forwards and backwards or naturally.

there is another issue i worked on today: one of my bigger projects involves the capturing of the Song Set Lists to all the Bob Dylan Concerts into a MySql Database. i got all the information from PDF files from another site and just needed to copy the set lists into text files for later use, when i want to insert them with the help of php (hopefully) somewhat speedily and automatically into the database.

but to capture them first i had the option of copying and pasting into a text file and save each one using Save As, but i found that to tedious after a while and was scared to make mistakes, which is what happens quickly when you have to perform a repititive function.

i got this book (here he comes with his books again) Praxiswissen Ajax



and in this book there is a chapter about an Ajax Online Editor (short: aoe). i have somewhat re-designed the layout a little to fill the whole screen with it for my purposes. (i will discuss this example in another article.) this editor uses php to read the files of a particular directory on the left part of the screen; one clicks on a filename and the contents of the file appear on the right side of the screen.

i show you a screenshot:



now i wanted all the files to exist already so i wrote myself a little code snippet that would write empty files with the names ready-made from an array in split seconds. and here is the code (the filenames just have reference numbers):


<?php
$id_number = array(
'29930',
'29940',
'29950',
'29960',
'29970',
'29980',
'29990',
'30000',
'30010',
'30020',
'30030',
'30040',
'30050',
'30060',
'30070',
'30080',
);
$inhalt = utf8_encode(" ");
foreach($id_number as $value) {
$filename = $value.".txt";
$fh = fopen($filename, "w+");
fwrite($fh,$inhalt);
fclose($fh);
}
?>


this code snippet enters a blank space (" ") into each of those files.

my next problem came when i wanted to copy those files as a backup from the server, where i will need them, to my computer. as i came back from having a shower an error message awaited me that the server had been reset and the copying had not been completed. so i thought alright, let me create a zip file and download them as a zip file. using the google search engine again i went to look for create zip files using php. i downloaded 4 examples, the last one was in php5 and i decided to try that one first and it didn't work for some reason, so i discarded that one already. then i tested the third one which looked best and easiest for me. it requires PEAR but that wasn't a big problem either. it further requires the PEAR Archive_ZIP Package.

downloaded those, unpacked and copied them to the server. then i got the code working which i took from PHPit. i made a few adjustments to it, like the path to pear and of it went. here is the code snippet i used:


<?php
// Original Source: http://www.phpit.net/article/creating-zip-tar-archives-dynamically-php/
include ('../pear/archive_zip.php');

// Create instance of Archive_Zip class, and pass the name of our zipfile
$zipfile = New Archive_Zip('bdcdb.zip');

// Create a list of files and directories
$list = array(
'00003.txt',
'00005.txt',
'00007.txt',
'......txt',
);

// Create the zip file
$zipfile->create($list);

echo 'Zip file created';
?>


of course my list has over 3.000 items, so the $list array is accordingly much longer. i waited a few seconds and then i was able to download my text files in a zip folder named bdcdb which stands for Bob Dylan Concert Data Base.

End of Project.

now for the JavaScript.

i think it's best to create a JavaScript file (i have JavaScript snippets all over my pages as well as in files). and here is an example.

the first example you can see working on the source.php file if you click into the field with the url. it clears the text in that field.

the second example you can use with a URL like
<a href="http://someurl.com" onClick="MyWindow(this.href,'name','1000','650','yes');return false">some url</a>
. it opens the link in a new window at the size of 1000x650.

the third example uses a copy and paste button (also to be seen at the lower section of the source.php file). in Firefox it only highlights the code, but using the Internet Explorer it actually puts the code into the copy and paste cache. i have explained the usage of that code already on the source.php page.

the fourth example you can use with the <select> tag of a drop-down menu as shown in the example in the source.php file.

for all these examples to work you only need one line of code in the <head> section of your .html or .php file, and that is:
<script language="JavaScript" type="text/javascript" src="javascript.code.lib.js"></script>. of course your JavaScript file's name is javascript.code.lib.js :-)

another book i'm learning from at the moment is PHP und MySQL -- Dynamik für Ihre Webseiten



one thing i learnt from it is if i want to use a variable within html and i'm just outside of the php parameters i can use <?=$color;?> instead of <?php echo $color; ?> as i used to in the past.

and that rounds off today's article on code snippets. stay tuned and see you soon.

tom.paine

Sunday, April 20, 2008

Amazon Web Services (AWS)

it's been recommended to me by some friends to start a blog on code snippets since i'm not just into music and literature, but also spend a considerable amount of time on the computer trying to figure out how i can make a script work that i've seen somewhere or whatever the case may be. i guess first i gotta go through a short and sweet amount of history on how i teach myself:

when i started off in 2001 someone showed me how to figure out the source code by clicking view --> view source code on the Netscape 4.7 browser at the time. first i created mostly pages with links of websites i liked and which i'd visit regularly, but which could also be of interested to others on a particular subject. in one such case i created a webpage for a friend of mine and she asked me to insert the right-click JavaScript.

<script language="JavaScript" type="text/javascript">
<!--
var message="You can't have this, but you can print it out or contact us for 
permission to borrow something. Have a great day and thanks for visiting us!";

function click(e) {
if (document.all) {
if (event.button == 2) {
alert(message);
return false;
}
}

if (document.layers) {
if (e.which == 3) {
alert(message);
return false;
}
}
}
if (document.layers) {

document.captureEvents(Event.MOUSEDOWN);
}
document.onmousedown=click;
//-->
</script>

that was the code i used in my page; i found that code snippet on the internet; she used a different code at the time and i noticed it wasn't working in Netscape, so i asked "what code are you talking about?" well, and that's how i got started using JavaScript.

in one of my more complicated examples i created a page with 4 framesets, whereby if one moves the cursor over a link to a music album, the album cover changes accordingly in the other frame. that was a nightmare which took me about 8 hours to resolve. here again i searched around on the internet to find a suitable code snippet.

<frameset cols="313,*" border="0" framespacing="0" frameborder="0">
<frameset rows="434,*" border="0" framespacing="0" frameborder="0">
<frame src="AppleBobDylan.html" scrolling="auto" name="Think different.">
<frame src="DylanAlbumImages.html"  scrolling="auto" name="DylanAlbumImages">
</frameset>
<frameset rows="9%,*" border="0" framespacing="0" frameborder="0">
<frame src="DylanAlbumHeader.html" scrolling="auto" name="DylanAlbumHeader">
<frame src="DylanAlbumLinks.html" scrolling="auto" name="DylanAlbumLinks">
</frameset>
</frameset>
<noframes>
<body>
</body>
</noframes>


the code snippet that would have to be used with the link would be:


onmouseover="parent.DylanAlbumImages.document.albumcover.src='CURRENT_COVER.jpg'"
onmouseout="parent.DylanAlbumImages.document.albumcover.src='DEFAULT_IMAGE.jpg'"


CURRENT_COVER is here only sort of a variable for the image related to the current cover. those have been preloaded at the head of the script in the .html file that contains the links.

but what am i writing about? you thought this article would be about Amazon Web Services; well it is, we're slowly getting there.

before i get into that i should mention a few books that may be essential to the cause:


Programming PHP


Web Database Applications with PHP & MySQL


Learning Perl


Programming Perl


and of course my main guide: the AWS Book titled: The Web Developer's Guide To Amazon E-Commerce Service: Developing Web Applications Using Amazon Web Services And PHP

this last book not only helps you to learn php but also apply it already in reallife applications. example scripts can be seen as well as downloaded from www.awsbook.com.

i could go more into details about books, Ajax Hacks, Amazon Hacks (now somewhat outdated due to the termination of Amazon Web Services 3.0) and Google Hacks or any other from the Hacks series.

enough of this! now let me give an example of how i sometimes work. you can find already lots of usable code related to Amazon Web Services on the internet, you don't have to write your own. but you should at least have a fundamental knowledge of how Amazon Web Services works:

Step 1: you formulate your request url
Step 2: you send that request to Amazon's server (using your browser)
Step 3: Amazon returns a document with a XML structure related to your request, if neccessary with an error message which tells you what parameter was wrong.
Step 4: you write some kind of script that can turn the XML document into something more sensible to the visitors of your website.

the start of your url will always look like this:
http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]
http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]
http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]
http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]
http://ecs.amazonaws.fr/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]
http://ecs.amazonaws.jp/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[YOUR ID]

you obtain the AWSAccessKeyId from Amazon and it's the same for all these locales.

next you need an Operation (no no, don't panik, not at the hospital! you should remember that these terms are case-sensitive!) for instance Operation=ItemSearch. you find those in the documentation from Amazon. i don't want to get into those details too much here.

certain Operations (like ItemSearch) require certain parameters that are a must. in this case for instance a SearchIndex is required. a SearchIndex is something like Books, DVD or VHS. the SearchIndex values vary from country to country (locale to locale); for instance, MusicalInstruments you get only under the US locale whereas Hobbies you will only find under the JP locale (for Japan). apropos Japan: i did not make a mistake with the url above, it is .jp and not .co.jp in this case.

now what are we searching for? one can search for a particular Author under Books, or Artist under Music, Actor or Director among DVD and VHS. the simplest would be the Keywords search (one can also use a BrowseNode, but who knows those offhand?).

we're almost there. we could add a Sort parameter or even which Version of Amazon Web Services we'd prefer to use in our request, but those will be returned as default parameters and we don't have to worry about that for now.

i almost forgot about the ResponseGroup: the information you're about to get depends on the ResponseGroup, Small, Medium or Large are the basic ones.

we got everything? let's give it a try, shall we?

http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[where's your id?]&Operation=ItemSearch&SearchIndex=Books&Keywords=Bob%20Dylan&ResponseGroup=Large

O.K. that work's after a number of false starts (i hate links that don't work!)

now that we've had the basics i will show an example i found on the internet and changed it to suit my own purposes. nothing spectacular!

i found this code snippet in the Ajax Community:


<?php
class aws {
    function 
aws($aki$asin) {
        
$fs=fopen("http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService&AWSAccessKeyId="$aki ."&AssociateTag=22&Version=2006-09-11&Operation=ItemLookup&ItemId="$asin ."&ResponseGroup=Medium,Offers","r");                
        
$this->responseXML=simplexml_load_string(fgets($fs));
    }
    
    function 
getValue($pValue) {    
        
$myValue '';
        eval (  
'$myValue = $this->responseXML->'.$pValue.';' );
        if(empty(
$myValue)) $myValue='n.V.' ;                            
        return 
$myValue;
    }
}

$produkt = new aws('AccessKeyId''Produkt ASIN');
$preis =  $produkt->getValue('Items->Item->Offers->Offer->OfferListing->Price->FormattedPrice');
$bild  =  $produkt->getValue('Items->Item->LargeImage->URL');

echo 
'<img src="'.$bild.'" />';
echo 
'Preis: '$preis;
?>


and this is what i made of it:

<?php
class aws {
function 
aws($aki$affid$asin) {
        
$aki '1BZ9VRA5AKNBPYJM6YR2';
        
$affid 'downinthefl04-21';
        
$asin '3100744314';
        
$fs=fopen("http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService&AWSAccessKeyId="$aki ."&AssociateTag="$affid ."&Version=2006-09-11&Operation=ItemLookup&ItemId="$asin ."&ResponseGroup=Medium,Offers","r");                
        
$this->responseXML=simplexml_load_string(fgets($fs));
    }
    
    function 
getValue($pValue) {    
        
$myValue '';
        eval (  
'$myValue = $this->responseXML->'.$pValue.';' );
        if(empty(
$myValue)) $myValue='n.V.' ;                            
        return 
$myValue;
    }
}

$produkt = new aws('AccessKeyId''AffiliateId''Produkt ASIN');
$preis =  $produkt->getValue('Items->Item->Offers->Offer->OfferListing->Price->FormattedPrice');
$bild  =  $produkt->getValue('Items->Item->LargeImage->URL');
$link  =  $produkt->getValue('Items->Item->DetailPageURL');
$titel =  $produkt->getValue('Items->Item->ItemAttributes->Title');
echo 
'<img src="'.$bild.'" /><br />'."\n";
echo 
'<a href="'.$link.'" target="new">'.$titel.'</a><br />'."\n";
echo 
'<a href="http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=1BZ9VRA5AKNBPYJM6YR2&AssociateTag=downinthefl04-21&Version=2006-09-11&Operation=ItemLookup&ItemId=3100744314&ResponseGroup=Medium,Offers" target="new">XML Dokument</a><br />'."\n";
echo 
'Preis: 'str_replace('EUR','&#128;',$preis);
?>


i added my affiliate id and i display a link below the large image, as well as a link to the request i made. i always do this as an easy reference in case nothing shows up. the script is written in php5 which you can easily recognize by the use of the simplexml_load_string function.

writing this all up has now taken me a considerable amount of time; so i'm gonna knock off with a last link to the PHP: Documentation where the reader will find the simplexml_load_string as well as the simplexml_load_file functions explained in greater detail together with examples from other users. for some resource links on Amazon Web Services you can also visit my documentary.

Cheers for now!

tom.paine