Tune-Up Eclipse 3.4 with PDT 2

          0 votes
July 11th, 2008

If your one of those people like me who get excited when a new version of software comes out you put everything behind yourself rush right away to download it and install regardless of any new bugs it might bring. At first it was great but then the more you use it the more you notice things that aren't quite working right and a few gotchas here and there.

PHP Development Tools

You'll notice that you cannot open code declarations (F3) when any versions of PDT 1.0 - 2.0 Integration Build (as of this witting). However this bug is apparently fixed in the nightly build so go ahead and download that version of PDT to get it working... There is a download link below under My Setup...

Next, if you notice your IDE hang almost forever every time you start typing variables you can fix this by going to Windows -> Preferences -> PHP -> Editor -> Code Assist and un-checking Enable auto activation. This seems to be really laggy and extremely buggy even if you set the Auto activation delay higher. Usually you'll get the error below with this:

Problems During Content Assist

The good news is that you still get your code completion when you hit Ctrl + Space and it seems to come up a little faster.

The Right Runtime for the Job

During this hateful quest I decided to try out a few different IDEs. BEAs JRockit (now Oracle's) seem to have given me the best performance on Windows. I've heard good reports about IBMs JRE but since I'm not on a IBM platform they won't let me install it! If you're on linux I've also heard good things about IcedTea Java.

My Setup

Conclusion

Aside from what's listed above the only last bug I notice with PDT is the Path Variables settings not workgin (Window -> Preferences -> PHP -> Path Variables). That was useful feature for me in previous versions of PDT but it looks like they've got a few other ways not to define external sources for your project that will work for now.

Of course this is also all development so as time progresses these issues may all be resolved but you like to live on the bleeding edge like me then you might get cut as they say :) Oddly enough I notice much more better results with the same setup on my Mac :-P Mac owns!

Share/Save/Bookmark

Run Ruby Code on Google App Engine!

          0 votes
July 7th, 2008

Oh wait what? Google App Engine is for Python you say? Ah yes that is correct but apparently this person named Why (not sure if that's his alias or his real name) has created a byte code decompiler which recompiles your Ruby code into Python code! Is that nutty or what?!?!

Of course this is far from stable and should only be done for fun but if you want to read about it here it is: Sneaking Ruby Through Google App Engine (and Other Strictly Python Places)

In theory you should be able to do this wherever Python code is ran, right?

Happy Hacking!

Share/Save/Bookmark

Compressing JavaScript … TO THE MAX!

          0 votes
July 6th, 2008

Here is the best recipe I've came up with so far to compress JavaScript. The goal here is to get our JavaScript file the smallest possible. In a nutshell, first we will obfuscate and then we "minify" it.

With obfuscation we'll convert all of our meaningless variables to the shortest meaningful variable needed. "Huh?" What I mean by that is basically all of our variables that we don't have access to or need, specifically variables within functions don't really need any meaning as long as they get the job done... per se... When we write code we name variables in a way so that they make sense to us, humans. There's obviously nothing wrong with that but on the computer's side of things they're just a set of instructions where the naming doesn't mean anything. totalPrice + tax = price means the same to a computer as foo + bar = result which means the same as _1 + _2 = X. We're going to use obfuscation to save space of our useless variable names.

Clarification: The variables aren't useless, their long names are.

After doing what we can with variables we then need to minify our script. This is very simple, just removing all useless white-space and line breaks. It may not sound like much but your web browser would also have an easier time parsing your code if it was all on one line.

The tools for the job

And walla! Go ahead and download these tools off their sites. For JSMin just download the C source code for now if you're on Mac or *nix but if you're on Windows they should have a zip file containing an .exe on the bottom of the page somewhere. For the prior, simply compile the source like so:


$ gcc -o jsmin jsmin.c

  1. Custom Rhino: This is what we'll use to obfuscate our JavaScript code. Custom Rhino is a modified version of Mozilla's Rhino JavaScript interpretor which has an obfuscation feature added to it.
  2. JSMin: And this would obviously be our minify tool! There are actually quite a few other tools that do the same thing JSMin does but I chose to use JSMin because its available in many programming languages. This is a plus for me because I love getting my hands dirty in other languages and it just works.

Doing It!

Lets get started with our ever so boring Hello World! test but because this project is so exciting it will make up for it! Right? Hehe anyways here goes our little JavaScript code, put this and the programs we've downloaded above all into one directory just for the sake of testing for now (you can organize them into somewhere more meaningful later) and save the JavaScript code as test.js:

var message = "Hello Richard!";
 
helloWorld = function(msg)
{
	var message = msg.toUpperCase();
	alert(message);
}
 
helloWorld(message);

Very simple. We got a global variable named message, and function named helloWorld. Now its time to pack this baby together! Open up a console window and lets do it step by step:

$ java -jar custom_rhino.jar -strict -1 -opt -c test.js > tmp.js

If you take a peek at tmp.js then Rhino should have generated this:

var message="Hello Richard!";
helloWorld=function(_1){
var _2=_1.toUpperCase();
alert(_2);
};
helloWorld(message);

What's really important to note here is that our global variable names remained the same and so did our function. The only code that is obfuscated is the code that means nothing to us anyways :-) ... Nothing in that we don't access it anyways.

Next we minify the code with JSMin:

$ ./jsmin < tmp.js > test_compressed.js

Our code should look like:

var message="Hello Richard!";helloWorld=function(_1){var _2=_1.toUpperCase();alert(_2);};helloWorld(message);

And walla! Isn't that beautiful! Of course the space savings isn't tremendous with this small script but I've tested it with Prototype v1.6.0.2 and it went from 123kb to 83kb! That's about a ~40% save right? Not so bad.

So now we've got our code obfuscated and compressed on the client end as much as possible. This should definitely help with transferring over all your JavaScript much faster and your browser should have an better time rendering it.

We can also eliminate the need for tmp.js and perform the above operation with one command:

$ java -jar custom_rhino.jar -strict -opt -1 -c test.js | ./jsmin > test_compressed.js

Conclusion

Well there you have it. Its also good to note to always start and end loops and conditions with opening and closing brackets even if you have those one liners for compatibilities sake. Your code should be packed for distribution when you are sure its at a stable state otherwise debugging can be problem and a headache fast.

If you want to take things further you can optimize your server end by adding gzip compression to Apache or whatever you use and also refactoring your code. The lesser try/catches would help as well.

Here are a few other tools:

  • Dojo Shrinksafe: An online compression tool made with Dojo's custom_rhino.jar.
  • Rhino: This is the homepage of the Rhino JavaScript interpreter that the Dojo developers extended to give obfuscation capabilities to.
  • Dean Edwards Packer: A pretty popular JavaScript packer. Source also available
  • Packer JavaScript in PHP: Same as the one above but made in PHP

Share/Save/Bookmark

Bitwise Configurations - Crash Course

          0 votes
July 3rd, 2008

Using bitwise configurations in software can have its advantages when you want to store a multiple configuration values within a single value. The only disadvantage (I see) with this technique is you cannot exactly query for a specific permission in your database if you are storing the configuration there but otherwise if that's not necessary it might be an advantage along with the fact of its simplicity.

Note: It might help if you have any knowledge of binary numbers but its not necessary.

Jumping Right In!

That's right! Its a crash course so lets just jump right in! With bitwise configurations each configuration is a number, but not just any number, they go by multiples of 2 starting from 1. For our example, I'm going to make up five configuration settings to play with that will determine my application's error settings. These can be anything of course. People sometimes use bitwise operations with permissions but anyways here we go...

ERROR_WARNING = 1
ERROR_CRITICAL = 2
ERROR_UNSUPPORTED = 4
ERROR_DEPRECATED = 8
ERROR_FATAL = 16

There we have our configuration, as you see each setting starts at 1 and goes up by multiples of 2.

So now lets say I want to configure my program to report all critical, deprecated, and fatal errors. That would simply be the sum of those configurations:

ERROR_SETTINGS = ERROR_CRITICAL[2] + ERROR_DEPRECATED[8] + ERROR_FATAL[16]

Usually when you configure *nix programs with something like this you don't use the + operator but instead a pipe, |:

ERROR_SETTINGS = ERROR_CRITICAL | ERROR_DEPRECATED | ERROR_FATAL

The above syntax is usually valid in most programming languages. At least Python, Java, C, and PHP off the top of my head. So now we have ERROR_SETTINGS equal to 26.

To check if we have a specific setting configured in ERROR_SETTINGS, such as ERROR_UNSUPPORTED we could simple do:

ERROR_SETTINGS & ERROR_UNSUPPORTED

That will return 0 because ERROR_UNSUPPORTED has no bits that match 26. To explain it further lets take our numbers and look at them at as binary numbers:

26 = 11010
4 = 100

As you see the 1st 0 from left needs to be 1 in order for 4 to match 26. So if our ERROR_SETTING included ERROR_UNSUPPORTED its value would 30 and its binary number 11110 thus 4 (binary 100) would match.

When testing if your configuration contains a certain setting using &, as long as it returns anything greater than 0 then your good! ... Otherwise its not part of the configuration.

Conclusion

I hope this crash course made sense to you. If you are still a little unclear how it works wikipedia has a thorough tutorial explaining how bitwise operations work and a good explanation of binary numbers.

Also, if you are programmer it sometimes might make sense to use bitwise operations to store configuration values because as we know, computers are mathematical machines and its what they do best. Its by far way less expensive to check if a configuration exists using the bitwise technique as opposed to storing your configurations in a list or dictionary and looping through them to check if what you are looking for exists.

Share/Save/Bookmark

Python and .NET playing together!

* * * * * 1 votes
June 27th, 2008

Intro

Lately my head has been up in the clouds playing around with a few languages, Python, C#, and Java (we'll get into Java later) as I usually do for fun and I thought how fun would it be to mix them!

Of course this is nothing new. There have been interpreters to mix and match them all you like for some time now and in this blog we'll focus on Python and .NET for now.

IronPython

IronPython is an implementation of the Python interpreter written completely in .NET. Being that it is written in .NET you can access all the .NET libraries with the interpreter and run it on any platform.

To run IronPython on any other than MS Windows (*nix, Mac, etc) you will need to install Mono. Mono provides the necessary software to run and develop .NET software on other platforms.

Note: The Mac package of Mono comes with IronPython. If you are on *nix you can probably find a package for your distro or have to compile it for yourself. If you are on MS Windows you can get the latest .NET run time from your Windows Update.

It takes two to tangle!

So after all that babble lets get started! Out of all the .NET languages I am currently most familiar with C# so I'm going to be taking some C# examples and showing you how to do them with Python using the IronPython interpreter which is invoked via the ipy command.

We'll start first with the ever so boring "Hello World" program.

In C# we would do something like this:

using System;
 
public class HelloWorld
{
	public static void Main()
	{
		Console.WriteLine("Hello Richard!");
	}
}

The above code should be extremely obvious, if not I suggest some polishing up of your C# skills.

Now with Python, I'm going to write the same exact thing (minus wrapping it in a class since its unnecessary with Python at this point) and I'm going to output "Hello Richard" using the same C# libraries:

from System import *
 
Console.WriteLine("Hello Richard")

That's it! An extremely simple 2 lines! Not bad huh? Of course that was cool but not something so useful.

All we've done was imported the System library into the current name space. We could have also done import System but then we would have had to write the whole System.Console.WriteLine() command. In some cases that might be useful if you don't want certain things to conflict.

Now lets do something a little more cool like interacting with a DLL created completely in .NET. If you want to know how to create a DLL file yourself then Google it but for now I'm going to take one already made.

For this example I'm going to use the MySQL .NET Connector and query some junk from my database.

Here would be the C# way (borrowed from here):

using System;
using System.Data;
using MySql.Data.MySqlClient;
 
public class Test
{
	public static void Main(string[] args)
	{
		string connectionString =
			"Server=localhost;" +
			"Database=test;" +
			"User ID=myuserid;" +
			"Password=mypassword;" +
			"Pooling=false";
 
		IDbConnection dbcon;
		dbcon = new MySqlConnection(connectionString);
		dbcon.Open();
		IDbCommand dbcmd = dbcon.CreateCommand();
		// requires a table to be created named employee
		// with columns firstname and lastname
		// such as,
		//        CREATE TABLE employee (
		//           firstname varchar(32),
		//           lastname varchar(32));
		string sql =
			"SELECT firstname, lastname " +
			"FROM employee";
		dbcmd.CommandText = sql;
		IDataReader reader = dbcmd.ExecuteReader();
		while(reader.Read()) {
			string FirstName = (string) reader["firstname"];
			string LastName = (string) reader["lastname"];
			Console.WriteLine("Name: " +
				FirstName + " " + LastName);
		}
		// clean up
		reader.Close();
		reader = null;
		dbcmd.Dispose();
		dbcmd = null;
		dbcon.Close();
		dbcon = null;
	}
}

Now, lets do this the Python way with the same rules as the last example; using the same C# libraries.

import clr
clr.AddReferenceToFile("MySql.Data.dll") # MySql.Data.dll must be located in the same directory as this script
 
from System import *;
from MySql.Data.MySqlClient import *;
 
connStr = (
	"Server=localhost;"
	"Database=test;"
	"User ID=myuserid;"
	"Password=mypassword;"
	"Pooling=false"
)
 
conn = MySqlConnection(connStr)
conn.Open()
cmd = conn.CreateCommand()
"""
requires a table to be created named employee
with columns firstname and lastname
such as,
   CREATE TABLE employee (
      firstname varchar(32),
      lastname varchar(32));
"""
sql = "SELECT firstname, lastname FROM employee"
cmd.CommandText = sql
reader = cmd.ExecuteReader()
while reader.Read():
	firstName = reader["firstname"]
	lastName = reader["lastname"]
	Console.WriteLine("Name: %s %s" % (firstName, lastName));
 
# clean up
reader.Close()
reader = None
cmd.Dispose()
cmd = None
conn.Close()
conn = None

And walla! You have to admit, that is pretty awesome! We've got the power of simplicity from Python along with the power of .NET at our finger tips!

You can also import libs that you've gac'd (installed via gacutil) by replacing line 2 with clr.AddReference("MySql.Data") which might be more useful in some cases.

Conclusion

There's so much we can do with this such as prototype, making simple test cases, or even utilities for your .NET application. I've found this lots of fun and hope you do too. Stay tuned and keep your eyes peeled for another article on roasting the same blend of code with Jython!

Be sure to also take a look at these other links that might interest you as well!

Share/Save/Bookmark

Friendly Cross-Site Scripting

          0 votes
May 14th, 2008

Recently I was faced with the issue of loading an iFrame from our main site to one of our child sites and they needed to communicate with each other through JavaScript. While developing on our test servers the problem wasn't obvious because everything was on the same domain but when it was near time to deploy on the production servers the shit hit the fan! The reason wasn't so obvious at first but luckily the solution wasn't very hard to implement, it was just a matter of finding it.

Welcome document.domain

Say we have a script at http://foo.mysite.com that needs to communicate with another friendly script at http://bar.mysite.com through means of an iFrame or something. By default your browsers' security won't let them because the full domains aren't the same same (including the sub-domain).

In order to allow both sub-domains to communicate together you must set the document.domain property in JavaScript to the same domain name. So in our case we would need to set the document.domain property on both sites to mysite.com which is the common domain between the two.

 
document.domain="mysite.com";

You can't however set both to foo.mysite.com or bar.mysite.com and you cannot set both of them to another domain such as mysite1.com or anything else. That's the limitation.

Hint: You could use this technique to share cookies across similar domains as well. When setting a cookie you can set it for the parent domain to be accessible from multiple sub-domains.

Be aware that setting this property incorrectly can compromise the security of your site. It is suggested to determine the value by the server, do not set this property by a value determined by the client.

Share/Save/Bookmark

Compiling MySQL-Python on Mac OS X

          0 votes
May 6th, 2008

Compiling is so 80s and not the Mac way :???: . If any system should have packages for everything it should be Mac! Well, before I drift off into why I think there should be packages for everything lets get back on topic.

I did this with Mac OS X 10.5 (Leopard) but it should work with older versions (and newer ones). If you tried them and they work please post up!

Developer Utils

If you haven't already, find your install disc of Mac OS X and poke through it and install Developer Tools. You can also download it from ADC (Apple Developer Connection) for free from here. You'll need to do that before continuing.

MySQL

Next you'll need to download the latest stable version of MySQL from here (version 5.0.45) as of this writting. Unpack it by double clicking it, install, blah blah blah.

MySQL-Python

Lastly, download the latest mysql-python from here (version 1.2.2 as of this writting). Unpack it by double clicking and open up _mysql.c in your favorite text editor as they usually say.

Find the following lines and delete them (line ~36):

#ifndef uint
#define uint unsigned int
#endif

Next find these following lines:

uint port = MYSQL_PORT;
uint client_flag = 0;

... and chane them to:

unsigned port = MYSQL_PORT;
unsigned client_flag = 0;

Some people reported having problems trying to build this because for some odd reason they are missing a `mysql` link in its lib directory to itself. Peek inside of /usr/loocal/mysql/lib and see if you have a symbolic link named `mysql` pointing to itself. If you don't, open up your Terminal and run the following command:

sudo ln -s /usr/local/mysql/lib /usr/local/mysql/lib/mysql

We're almost done :) Open up your Terminal into the directory you unpacked mysql-python and run the following:

python setup.py build
sudo python setup.py install

Thats it! Enjoy!

Share/Save/Bookmark

Compiling PHP on Mac OS X

* * * * * 4 votes
March 29th, 2008

Getting Started

You may want to recompile PHP on your Mac for a number reasons such as need a newer version, missing some features you need, testing, or whatever. Some of the most common reasons I found were people needing GD support because the version of PHP that comes with Mac OS X doesn't have it. In this I'll let you know what you need and how to get it done.

Apache

We'll need to recompile Apache even though it already comes with our system because for some unknown reason (to me) the compiled version of Apache that comes with our systems doesn't play too well when we compile PHP. Anyways without going into further details, read through this article real quick, Compiling Apache on Mac OS X, and come back here. Should only take ya like 5 minutes...

Time for PHP

Welcome back! Next, download the latest copy of the PHP source (5.2.5 as of this writting) compressed in tar.gz format from this URL, http://www.php.net/downloads.php. Once complete and you don't care about compiling PHP with any other options such as GD Support, MySQL, etc, and you just want the basic PHP then you can go back to your Terminal, cd into the directory where you downloaded PHP and run the following commands:

$ tar -xvzf php-5.2.5.tar.gz
$ cd php-5.2.5
$ ./configure --enable-layout=Darwin --enable-mods-shared=all --prefix=/usr --mandir=/usr/share/man --localstatedir=/var --infodir=/usr/share/info --disable-dependency-tracking --with-apxs2=/usr/sbin/apxs --with-kerberos=/usr --enable-cli
$ make
$ sudo make install

Like Apache, you would need your root password to install PHP with the last command. Once everything is complete you can go into Sharing from your System Preferences and restart Web Sharing and you will notice you are running the version of PHP that you downloaded!

Note: Whenever editing your apache configuration you will need to restart it in order to see the new changes.

If you do want to build PHP with additional features then proceed below and follow the setup of instructions for each and either feature. For starters we can unpack PHP.

$ tar -xvzf php-5.2.5.tar.gz

Later when I say to build PHP with whatever ./configure command I just mean running the command from your Terminal while being in the directory where you unpacked PHP.

GD Support?

I won't leave you hanging wondering how to install GD since I brought it up earlier and its quite easy so lets do it! If you want jpeg support with GD then you need to install libjpeg. You can download the latest stable source code from http://www.ijg.org/files/. Once you get it go back to your terminal and run the following commands:

$ tar -zxvf jpegsrc.v6b.tar.gz
$ cd jpeg-6b
$ cp /usr/share/libtool/config.sub .
$ cp /usr/share/libtool/config.guess .
$ env CFLAGS="-O -g -arch i386 -arch ppc" LDFLAGS="-arch i386 -arch ppc" ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --mandir=/usr/share/man --enable-shared --enable-static
$ make
$ sudo make install
$ sudo ranlib /usr/local/lib/libjpeg.a

That's that for libjpeg. Now if you also want png support we need to grab libpng from http://www.libpng.org/pub/png/libpng.html. When done, lets go back into our terminal and run the following commands:

$ tar -xvzf libpng-1.2.22.tar.gz
$ cd libpng-1.2.22
$ env CFLAGS="-O -g -arch i386 -arch ppc" LDFLAGS="-arch i386 -arch ppc" ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --mandir=/usr/share/man --disable-dependency-tracking
$ make
$ sudo make install
$ sudo ranlib /usr/local/lib/libpng.a

Alright all set! Now we just have to go back to PHP and configure it with the options for GD. Below is the command:

$ ./configure --enable-layout=Darwin --enable-mods-shared=all --prefix=/usr --mandir=/usr/share/man --localstatedir=/var --infodir=/usr/share/info --disable-dependency-tracking --with-apxs2=/usr/sbin/apxs --with-kerberos=/usr --enable-cli --with-jpeg-dir=/usr/local/bin --with-png-dir=/usr/local/bin --with-gd

All I added were the last 3 options. If you didn't add libjpeg or libpng then you can remove them from the options respectively. After done configuring just remember to make and make install and your done!

MySQL

What PHP build would be complete without MySQL support? This step is super easy, simply go to http://www.mysql.com and download the latest stable version (5.0.45 as of this writing) for your platform and install it. The installation will place the files in a mysql directory in /usr/local. You can see which directory it was installed in by running the following command:

$ ls -lah /usr/local | grep mysql

Now that you've got the MySQL installation directory its helpful to create an alias directory without the version number at the end that will point to your current working version. This is also helpful so you can install multiple versions of software and when you want to switch between them you could simply change where the alias points to. If your MySQL directory was installed to /usr/local/mysql-5.0.45-osx10.4-i686 then this would be your command to create an alias:

$ sudo ln -s /usr/local/mysql-5.0.45-osx10.4-i686 /usr/local/mysql

Also, if you would like to access MySQL from the command line without having to type the full path to the binaries each them then I'd recommend appending your MySQL path to your $PATH environment variable:

$ echo "export PATH=\$PATH:/usr/local/mysql/bin" >> ~/.profile

The above line appends MySQL to your $PATH environment variable and from here on every Terminal window you open will find its way to MySQL.

Continuing on with PHP, depending which MySQL support you want (MySQL, MySQLi, PDO, or all) then just pick out whatever you want and don't want from the line below:

--with-mysql-sock=/var/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql

Conclusion

There are many more options you can add to the configure script to set certain features. To view all the options available you can run ./configure --help and that will spit out just about all the ways you can configure your build. Below is the configure command I used:

$ ./configure --enable-layout=Darwin --enable-mods-shared=all --prefix=/usr --mandir=/usr/share/man --localstatedir=/var --infodir=/usr/share/info --disable-dependency-tracking --with-apxs2=/usr/sbin/apxs --with-ldap=/usr --with-kerberos=/usr --enable-cli --with-zlib-dir=/usr --enable-trans-sid --with-xml --enable-exif --enable-ftp --enable-mbstring --enable-mbregex --enable-dbx --enable-sockets --with-iodbc=/usr --with-curl=/usr --with-config-file-path=/etc --sysconfdir=/private/etc --with-mysql-sock=/var/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-mysql=/usr/local/mysql --with-xmlrpc --with-xsl=/usr --with-pdo-mysql=/usr/local/mysql --enable-soap --with-pear --with-jpeg-dir=/usr/local/bin
--with-png-dir=/usr/local/bin --with-gd

Its also important to note that when doing system updates, not just little security updates or other application updates, but big critical system updates that brings you from something like 10.5.0 to 10.5.1 might rid your Apache and/or PHP setup. Nothing bad will happen, they will just overwrite your setup with their update. If you happened to keep your build then you can just go back and run sudo make install or you can just download the latest versions of the software we used here and redo the steps.

Share/Save/Bookmark