Mar200919

Top free applications to aid in web design and development

FileZilla FTP Client – http://filezilla-project.org/
A FTP client to upload documents from your computer to your web server. Also supports SFTP for secure transfering of files.

xampp – http://www.apachefriends.org/
A bundled installer of Apache, PHP, MySQL and a few other programs. This allows you to set up a server on your computer accessible through http://localhost which saves you having to upload the files to a server during development.

Notepad++ – http://notepad-plus.sourceforge.net/
An extension of notepad in Windows with more features including syntax highlight for PHP, HTML, javascript and many more languages.

GIMP (GNU Image Maninpulation Program) – http://www.gimp.org/
A worthy alternative to the hugely expensive Photoshop.

Paint.net – http://www.paint.net/
Based on the simplicity of MS Paint, Paint.net takes this a lot further with the introduction of many tools that are present in GIMP and Photoshop.

Jan200913

Windows Vista x64 to Windows 7 Beta

With the new Windows 7 beta out from Microsoft, I decided to try to upgrade an existing Windows Vista x64 which has been very stable and not had a problem, has a fair few applications installed and lots of documents.  I wasn’t putting up much hope, but backed up all the Documents and proceeded to upgrade the Vista installation as opposed to a new installation.

The installation started properly with no issues from within Windows Vista, then the PC required a restart, so restarted and the installation continued.

A message then came up during installation that “a required driver could not be found”.  This could be a problem, once the error had been closed, the window on screen said that all changes made would be reverted to how they were.  So my thoughts here were that it would restart back to Windows Vista like it was before with a heap of temporary installation files on the C drive.

Read the rest of this entry »

Dec200811

HTPC software configuration using MediaPortal

For my HTPC, I now have configured most things up, so it is all working just like it should be. It took a few OS reinstalls to get it exactly where I wanted it, but I more or less have it, just have to sort out Blu-ray & HDDVD playback sorted first.

Here is a list of what I was aiming for:

  1. Be able to play backed up DVD, Blu-ray & HDDVD videos in either .avi, .mkv (H.264) or WMV
  2. Central bit of software to cover everything
  3. Able to play off network shares
  4. Be able to play back Blu-ray and HDDVD easily

For my software I am using the following:

  • Microsoft Windows Vista x64 Ultimate Edition
  • MediaPortal v1.0 (with TVSeries 2.0 plugin and Monochrome 2.2 skin)
  • iMon 7.2

I did try using Ubuntu over Vista but found that Blu-ray support was a bit limited in the way you basically had to manually dump each film on to the harddrive stripping out the DRM.

So I ended up using Vista which has been very reliable. I have turned off Aero to give a small performance increase in playing 1080p MKV files and have disabled UAC for the obvious reason; it’s annoying.

Although the integrated Windows Media Centre that comes with Windows Vista is good, it can be a bit of a chore to get set up correctly to play any video format. So I am using MediaPortal which is a free bit of software which is simply fantastic.

I followed this guide from ProjectHTPC on setting up MediaPortal which is an easy to understand guide and tells you exactly what you need to know.

I then followed this guide on getting the Monochrome skin on Media Portal and getting the sound through to my sound system playing proper DTS. Following on from that guide, I came across a plugin for MediaPortal called TVSeries. It’s fantasic. I followed this guide and have all my TV series on my computer set up with fan art, which has now given me an excuse to get all my box sets on to the harddrive to have them as easy to access as possible.

Media Portal plays off network shares which has ticked off number 3 and allows me to continue on my search to get a NAS set up with a lot of storage to store all my DVDs etc on.

The only problem I still have to overcome is getting Blu-ray and HDDVD to play through MediaPortal properly, which should be OK once I get around to getting PowerDVD 7 or hacking PowerDVD 8 which removed any trace of HDDVD.

iMon has been a pain though, my case came with a CD with it on which I have now misplaced while moving house and have found myself downloading the latest version off the SoundGraph website extremely slowly.

Oct200826

Built my first HTPC (Home Theatre Personal Computer)

The idea of an HTPC is to have a PC that can fit in with your amplifier/receiver underneath your TV which will act as a DVD player but with more features.

Hardware wise it is identical to a normal PC with CPU, RAM, motherboard etc etc but generally put in to more stylish cases specially built to fit in most TV stands.

Case

I opted for an Antec Fusion Black HTPC case which is a fairly nice case, although it can be seen as quite costly at around £100 without a PSU. The case is steal with an aluminium front but even so it doesn’t weigh alot. There is space for 2 hard drives which are secured with rubber grommets to stop vibration and 2 5.25″ slots with one of these slots being used for the LCD display that comes built with the case, but can be taken out. The case has a few ventilation holes around to keep components cool but only has 2 120mm fans which are located on the side of the case near where the CPU will be. Both of these fans are Antec Tri-Cools and as such have the 3 way setting for fan speed, low, medium, high. I have mine set to low which gives off a little bit of noise and gives more than adequate cooling for the rest of the components.

Motherboard

After reading many good reviews I bought the Gigabyte GA-MA78GM-S2H AMD 780G Micro-ATX. The GA-MA78GM-S2H uses the AMD 780G chipset which has onboard audio and graphics. The onboard audio is a Realtek chip with your standard analogue in and outs but also has a digital out. The onboard graphics is called the Radeon HD 3200 which is said to be equal in performance to the Radeon HD 3450. The HD 3200 has AVIVO and allows for full hardware acceleration if the software supports it. The HD 3200 gives you VGA, DVI and HDMI which also carries sound. The motherboard also has a feature called Hybrid Graphics Technology. This allows you to put in another graphics card in to the PCI-e 2.0 slot which will be used in a crossfire like situation although AMD refuses to call it crossfire due to the performance levels not being the same. Unfortunately you can just shove any card in there and get this performance. It is obviously limited to AMD/ATi cards only and even then it will only use the power equivalent to the onboard graphics. In this case the best card to put in would be the HD 3450.

CPU

Keeping to an all AMD affair, I got the AMD Athlon X2 4850e which is a low power CPU said to consume only 45W. This also reduces heat which is a top priority in an HTPC as it means you don’t need a noisy fan on it, and this CPU is more than capable of processing any HD media or x264 rips.

RAM

RAM isn’t used that much in an HTPC compared to a gaming PC so I just got 2GB (2x 1GB sticks) of Corsair DDR2 XMS2 PC2-6400C5 TwinX. Of course you can easily change this to 4GB if you want.

PSU

As I was happy with my current Corsair PSU in my gaming PC I chose to keep my loyalty and got the Corsair CX400W which is more than capable of powering the HTPC with room to spare if I ever wanted to add a new sound card or new graphics card.

Hard drive

Being a Samsung fan due to the low noise from their Spinpoint harddrives, I bought another Samsung SpinPoint F1 500GB to join my growing collection of them. This drive isn’t particularly slow, but obviously won’t keep up with a Western Digital Raptor but is a hell of a lot quieter. This only used up 1 slot, so I still have another slot spare to add another drive in the future if I wanted to.

DVD Drive

Originally I was just going to buy a £20 DVD drive. But then I saw the LG GGC-H20L Blu-Ray Reader & HD-DVD ROM. For only £45 more I now have the ability to play Blu-Ray and HD-DVD. Although HD-DVD has been beaten by Blu-Ray there is still a lot of HD-DVD stock out there with stores trying to get rid of it. So when you have the choice of getting HD films for as little as £3 it seemed obvious to get a dual player. The only thing I forgot to check about this drive before purchasing was the noise, but I was gladly surprised with in once it was installed. Although not quiet, it wasn’t too noticeable, so when you have a film on you are unlikely to hear it.

Software

At the moment, I don’t have any dedicated software for my HTPC but I have got Windows Vista Home Premium 64-bit to install, then I can test with further software to expand the HTPC to be the optimum it can be.

Oct200812

[PHP + MySQL] Making a basic product database – Part 1

Firstly you need a server which supports PHP and Mysql. If you haven’t got one, you can set up your computer as a local web server. If you are on Windows, you can follow this guide to help you Set up your PC as a test environment using Apache, PHP and MySQL.

Create the database and tables

Open up your database management tool (PHPMyAdmin or command prompt or MySQL Query Browser) and create a new database, I will call mine product_db.

Then we want to create 3 tables. Product, companies and ownership.

The products table will contain 3 fields:

pid – A unique ID that is automatically generated for us.
name – The name of the product.
weight – The weight of the product.

This is the SQL for the table I am creating:

CREATE TABLE products (
pid INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR( 100 ) NOT NULL ,
weight FLOAT NOT NULL
)

Next up is the companies table which will contain 3 fields.

cid – A unique ID that is automatically generated for us.
name – The name of the company.
email – A contact email address for the company.

This is the SQL for the table I am creating:

CREATE TABLE companies (
cid INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR( 100 ) NOT NULL ,
email VARCHAR(100) NOT NULL
)

The 3rd table is the ownership table which will link up products to companies.

This will contain 2 fields, pid and cid which relate to the automatic ID of the 2 other tables.

This is the SQL for the table I am creating:

CREATE TABLE ownership (
cid INT NOT NULL,
pid INT NOT NULL
)

Now that we have the tables set up we can write the PHP to interact with the tables.

Connecting to the database using PHP

In your web folder, create a file and call it db_config.php.

In this file we will make the connection to the database.

<?php
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'password';
$db_name = 'product_db';
mysql_connect($db_host,$db_user,$db_pass) or die(mysql_error());
mysql_select_db($db_name) or die(mysql_error());
?>

Change the $db_xxxx variables to your database settings.

Save the file and load it up in your browser. If you get a blank white screen, everything is OK.

Possible Errors

Some possible errors you may get are…

Unknown database 'product1_db'

This will be because $db_name is wrong.

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'loc1alhost' (11001) in D:\xampp\htdocs\product\db_config.php on line 3
Unknown MySQL server host 'loc1alhost' (11001)

This is because the $db_host is wrong.

Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'ro1ot'@'localhost' (using password: YES) in D:\xampp\htdocs\product\db_config.php on line 3
Access denied for user 'ro1ot'@'localhost' (using password: YES)

This could be because $db_user is wrong or $db_pass is wrong.

Inserting new products in to the database

Create a new file and call it index.php and put it in the same location as the db_config.php file and paste the following code in it:

<?php require_once 'db_config.php'; ?>

Previewing the page should result in a blank white page. This means that everything is OK.

Now we will create a function which will used for all our modifying database interactions such as inserting data, updating data and deleting data.

function db_action($data = array()) {
	switch ($data['action']) {
		case 'insert':
			$keys = array(); $values = array();
			foreach ($data['data'] as $key => $value) {
				$keys[$key] = $key;
				$values[$key] = "'".$value."'";
			}
			$keys = implode(', ', $keys);
			$values = implode(', ', $values);
			mysql_query("INSERT INTO ".$data['table']." (".$keys.") VALUES (".$values.")");
			break;
		case 'update':
			mysql_query("UPDATE ".$data['table']." SET ".$values." WHERE ".$key." = ".$id);
			break;
		case 'delete':
			mysql_query("DELETE FROM ".$data['table']." WHERE ".$key." = ".$id);
			break;
	}
	return;
}

This is set up for inserting data only at the moment, both update and delete would fail at the moment, unless the data was passed on properly.

To insert data into the database we will pass all the information the db_function needs in an array like the one below.

$array = array(
  'action' => 'insert',
  'table' => 'products',
  'data' => array(
    'name' => 'Product Name',
    'weight' => '12.5',
  ),
);

By looking at the db_action function you can see that the action part of the array defines what we want to do in the database (insert, update or delete), then we have the table name (products, companies, ownership) and a data array which is in the format of the key (column name in the database) and the value we want to put in to the database.

We draw this data out the array in to a workable format using the following code:

$keys = array(); $values = array();
foreach ($data['data'] as $key => $value) {
  $keys[$key] = $key;
  $values[$key] = "'".$value."'";
}

This goes through the data array within our main array and spits out the $keys and $values that we will use for the database.

Once we have the $keys and $values arrays we need to organise these in a way that MySQL will know to insert correctly.

$keys = implode(', ', $keys);
$values = implode(', ', $values);

This sets the arrays in to strings with each field separated with a comma. Perfect for MySQL.

We then insert the data in to the database using the following code.

mysql_query("INSERT INTO ".$data['table']." (".$keys.") VALUES (".$values.")");

From the above array, the information sent to MySQL would be:

INSERT INTO products (name, weight) VALUES ('Product Name', '12.5')

Inserting new companies in to the database

By changing the array we can completely change the data that is going in to the database. Now lets modify the array to insert a new company.

$array = array(
  'action' => 'insert',
  'table' => 'companies',
  'data' => array(
    'name' => 'Something Enterprise',
    'email' => 'info@somethingenterprise.com',
  ),
);

So with the following code, by viewing the page we will insert data in to both tables.

<?php require_once 'db_config.php'; ?>
<?php
$action = $_POST['action'] ? $_POST['action'] : $_GET['action'];
$pid = $_POST['pid'] ? $_POST['pid'] : $_GET['pid'];
$cid = $_POST['cid'] ? $_POST['cid'] : $_GET['cid'];
 
function db_action($data = array()) {
	switch ($data['action']) {
		case 'insert':
			$keys = array(); $values = array();
			foreach ($data['data'] as $key => $value) {
				$keys[$key] = $key;
				$values[$key] = "'".$value."'";
			}
			$keys = implode(', ', $keys);
			$values = implode(', ', $values);
			mysql_query("INSERT INTO ".$data['table']." (".$keys.") VALUES (".$values.")");
			break;
		case 'update':
			mysql_query("UPDATE ".$data['table']." SET ".$values." WHERE ".$key." = ".$id);
			break;
		case 'delete':
			mysql_query("DELETE FROM ".$data['table']." WHERE ".$key." = ".$id);
			break;
	}
	return;
}
 
$product = array(
	'action' => 'insert',
	'table' => 'products',
	'data' => array(
		'name' => 'Product Name',
		'weight' => '12.5',
	),
);
 
$company = array(
	'action' => 'insert',
	'table' => 'companies',
	'data' => array(
		'name' => 'Something Enterprise',
		'email' => 'info@somethingenterprise.com',
	),
);
 
db_action($product);
db_action($company);
?>

Inserting new ownership in to the database

Now that we have both a company and a product we can try linking them together. Although we will automate this later, check your database, both the product and company should have an ID of 1.

$ownership = array(
	'action' => 'insert',
	'table' => 'ownership',
	'data' => array(
		'pid' => 1,
		'cid' => 1,
	),
);

Then by running

db_action($ownership);

We have the entry added to the ownership table.

Updating existing data

To update data we just need to modify our function a little to get the data in the right format and we can update with ease.

To do this we update the ‘update’ case in our switch statement to the following:

case 'update':
			$items = array();
			foreach ($data['data'] as $key => $value) {
				$items[] = $key .' = "'.$value.'"';
			}
			$values = implode(' , ', $items);
			$key = $data['key'];
			$id = $data['id'];
			mysql_query("UPDATE ".$data['table']." SET ".$values." WHERE ".$key." = ".$id);
			break;

We are using a similar foreach statement but have changed the 2 arrays into 1 array as the SQL format for UPDATE is different to INSERT.

For the update statement to work we need to pass on the values for the WHERE statement. After a minor change to our array we have the following:

$updateproduct = array(
	'action' => 'update',
	'table' => 'products',
	'data' => array(
		'name' => 'New Product Name',
	),
	'key' => 'pid',
	'id' => 1,
);

We have changed the action and added 2 new array keys, 1 called key which is the column name that we will use in our SQL statement and the id which is the cid or pid that needs to be updated.

Deleting data

The DELETE case in our function is even easier than our UPDATE as we don’t need to much around with any data.

case 'delete':
			$key = $data['key'];
			$id = $data['id'];
			mysql_query("DELETE FROM ".$data['table']." WHERE ".$key." = ".$id);
			break;

Our DELETE array is almost identical to our UPDATE array.

$deleteproduct = array(
	'action' => 'delete',
	'table' => 'products',
	'key' => 'pid',
	'id' => 1,
);

All we need is the key and id as no data is needed to delete a row.

In part 2 we will create the HTML to do our functions.

Oct200809

Google Chrome annoyances

It has been over a month now since Google released Chrome to the world and quite a few annoyances have appeared over that time.

Closing multiple tabs

The huge flaw that is extremely irritating is no warning of closing multiple tabs.

If you have 10 tabs open and accidentally close the main window at the top right rather than the tab close button. Goodbye tabs.

You can have the sessions enabled to get it back once you open Chrome again but that isn’t very helpful if you had active downloads going when you accidentally closed the browser.

Earlier today I was download Portal: Prelude, an expansion modification for the game Portal. After download 550MB of the 775MB file, I accidentally closed Chrome forgetting that I had the download going.

IE and FF would of both stopped this from happening as they both open downloads in separate windows rather than the main browser, so if you close the main browser the downloads continue. Chrome does not.

I wasted that time and bandwidth downloading 550MB to be lost in the ether and having to download it again, because something so trivial was missed out of Chrome.

It doesn’t take a lot of common sense to know this is could be a problem, Mozilla, Microsoft and Opera all have implementations in place to stop this happening. The fact that Google took the best parts of all the other browsers in to 1 then deciding that a rather important feature wasn’t in their users best interest is worrying. How many other problems are there going to be under the surface?

Downloads

I have found that on many user initiated downloads that they just fail to start full stop on my Chrome installation at work and some downloads on my Chrome installation at home.

By clicking a download button the file will appear at the bottom of the browser and have ‘starting…’ next to it but never progress past this stage. Right clicking the file and selecting Save as… works for all anchor links, but any downloads that are done through a form button are impossible to download which results in my opening up Firefox to download files.

Dictionary

You don’t seem to have the ability to add new words to the dictionary in Chrome which is rather strange. In Firefox you can and it is helpful when you type in something quite a lot and it isn’t in the dictionary, that little red line becomes annoying.

While writing this post, there are 2 words with red lines underneath them. The first is Firefox. Fair enough, it isn’t an actual word in the dictionary but still, Google do give a lot of money to the Mozilla foundation (which is in the dictionary). But the 2nd underlined word is an odd one indeed. It is Google. The company who have made the browser haven’t even put their name in the dictionary, instead suggesting that I meant to type goggle.

Sep200822

[MySQL] Using MySQL to analyze web usage from Windows ISA logs

This tutorial will teach you how to import a tab delimited file in to a MySQL database. I built a program to do this for Windows ISA Server logs which contained over 500,000 lines which was way too many for Microsoft Excel to handle and too much for notepad to handle properly. What MySQL functions will we be using:

  • Load Date Local Infile
  • Select
  • Delete
  • Drop

Firstly I will show you how to put a tab delimited log from Windows ISA Server in to the MySQL database. With the logs that I have been working with a days worth of information has been between 500,000 and 700,000 which is around 150-200MB in size alone.

You will find that if you use the default PHP timeout settings that you will timeout with large operations such as importing such a large file in to MySQL. 

I suggest that you open a command prompt and run through the process below to import the file and see how long it takes to import. If you have previous logs, choose the biggest one so you can get a worst case scenario. 

Before we can import the data into a MySQL database we need a database and table to import the data in to. I am not going to go in to much depth for this as it is quite simple to do using PHPMyAdmin or a similar program.

For the ISA log table you can use my code that I have here:

CREATE TABLE `tbl_log1` (
`id` int(11) NOT NULL auto_increment,
`ip` varchar(100) collate latin1_general_ci NOT NULL,
`username` varchar(100) collate latin1_general_ci NOT NULL,
`browser` varchar(100) collate latin1_general_ci NOT NULL,
`date` varchar(100) collate latin1_general_ci NOT NULL,
`time` varchar(100) collate latin1_general_ci NOT NULL,
`isa` varchar(100) collate latin1_general_ci NOT NULL,
`blank` varchar(100) collate latin1_general_ci NOT NULL,
`proxy` varchar(100) collate latin1_general_ci NOT NULL,
`proxyip` varchar(100) collate latin1_general_ci NOT NULL,
`proxyport` varchar(100) collate latin1_general_ci NOT NULL,
`num1` varchar(100) collate latin1_general_ci NOT NULL,
`num2` varchar(100) collate latin1_general_ci NOT NULL,
`num3` varchar(100) collate latin1_general_ci NOT NULL,
`protocol` varchar(100) collate latin1_general_ci NOT NULL,
`method` varchar(100) collate latin1_general_ci NOT NULL,
`url` varchar(255) collate latin1_general_ci NOT NULL,
`type` varchar(100) collate latin1_general_ci NOT NULL,
`num4` varchar(100) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci 

Feel free to change the encoding type if you wish. 

Now for the code. To import the data we will use the Load Data Local Infile ability of MySQL. This will load a file that is locally on the machine to the MySQL database given the right parameters.

load data local infile 'C:\\logfile.log'
into table tbl_log1
fields terminated by '\t'
lines terminated by '\n'
(ip,username,browser,date,time,isa,blank,proxy,proxyip,proxyport,num1,num2,num3,protocol,method,url,type,num4)

The last line is a list of the columns in order that are in the log. The only columns we really want are username, date, time and url, although you may want ip as well if you are monitoring network activity on static IP address so you can see where most of the bandwidth is being used. If you are importing a different file then change the columns to the names of your columns in your delimited file. The names of the columns within the brackets are the names that you gave them in the table. 

For example if you have a list of usernames, passwords and emails you will want 3 columns and a last line looking like this:

(username,password,email)

The column names have to be in order. If email is the first column in the file then make it the first word within the brackets. 

The 1st line should be the same for everyone except for the location of the file. Of course using the load data local infile function the file has to be on the machine itself and can not be done through the network. Also note the 2 backward slashes, the first backslash is to espace the following backslash.

The 2nd line is the table that we are importing to, make sure you have set up a table for your data to go in to. 

The 3rd line sets the delimiter type. \t is the delimiter for tab and \r is for a space. I am unaware of what the others are so if anyone knows please let me know.

The 4th line sets the delimiter for the end of the line. In this case each line was a new row on the file in excel so this is \n for new line.

The 5th line is the list of columns that we are importing into. 

The only problem is if you are importing a large log file like I was. What I had to do was cut out all the rubbish that I didn’t need to make the databases faster for queries and the like.

First of all I deleted all the columns I didn’t need.

ALTER TABLE `tbl_log1`
DROP `ip`,
DROP `browser`,
DROP `isa`,
DROP `blank`,
DROP `proxy`,
DROP `proxyip`,
DROP `proxyport`,
DROP `num1`,
DROP `num2`,
DROP `num3`,
DROP `protocol`,
DROP `method`,
DROP `type`,
DROP `num4` 

This took out all of the columns I didn’t need and brought the size of the file down quite a bit.

The second thing was that the log I had, had a lot of anonymous results in it, roughly around a third of the rows. So I ran this little bit of code to remove all the anonymous results.

DELETE FROM tbl_log1 WHERE username like "%anonymous%" 

The problem with this is removed a lot of these results leaves a lot of overhead in the database. So you can either optimize the table after each delete query or you can run it at the end once you start searching. 

OPTIMIZE TABLE tbl_log1

This will remove the overhead on the table and will decrease the query times. 

You can now use queries to search for users internet usage or a certain websites users. You will find a lot of websites in the list, if a user typed in www.microsoft.com it wouldn’t just say www.microsoft.com in the log, it would have the url of every image that the user downloaded, every CSS file, every page….everything. 

You may also want to set up other queries to remove certain websites that you know are safe and don’t mind about such as www.microsoft.com:

DELETE FROM tbl_log1 WHERE url like "%.microsoft.%" 

To search for anyone going on the BBC website you could type the following:

SELECT username FROM tbl_log1 WHERE url like "%bbc.co.uk%" 

This will display a list of users that have been on BBC. But this will come up with multiple duplicates of the usernames due to the issue stated above. To stop this we can add the GROUP BY parameter to our query to group the usernames together so we only have a single result from each user. 

SELECT username FROM tbl_log1 WHERE url like "%bbc.co.uk%" GROUP BY username

This tutorial was originally posted on Skeletorscorpse.com

Sep200802

Google Chrome really Safari in disguise?

While enabling Google Gears from within the newly released Google Chrome, I noticed something odd about the wording.

In Firefox and IE, you get the same text:

Make note of the first paragraph. Now if you open up the same javascript window within Google Chrome, you get this:

Once again, note the first paragraph again.  Within Google Chrome it mentions the Safari menu. Safari is not installed on this computer so there is no reason for Safari to appear there other than Google Chrome being related to Safari in some way.

Also take note that yesterday, typing Google Chrome in to Google search, the results were very different.  In less than 1 day Google appears to have got it’s Chrome site to #1.