Wednesday, July 20, 2011

I became a believer in Google DNS today

My home ISP, which ryhmes with Shomcast, kept failing on me. I was worried either my new router or modem were causing the issue, but thank goodness for browser error messages. You know, those pages you don't really pay attention to when things go wrong? Turns out I was having DNS errors. Switching my home network to Google's public dns system ( and fixed the problem right up.

Thanks Google!

Tuesday, July 19, 2011

How to describe a CSS file to another developer so they can use it?

I think this is one of the bigger issues with CSS technology. This question was raised by one of my co-workers. If I were to design the most beautiful CSS possible, but then I left the company - how would my replacement begin to use my 1200 line CSS document?

Do we need the equivalent of a javadoc for css files? A meta-file for css is an interesting proposition...

A musing.

Unity3 and web services

We wanted to be able to stream data into our Unity3D environment from our joomla website. I have rewritten the component from the ground-up twice but I thought I would share my design methodology (and technology) with the masses.

The humble backbone through all the iterations has been the WWW class (docs). By sending GET (and later POST) requests to the server, I would serve back information about articles, resources, images and other content. To being with, I wrote a couple extra methods in our joomla server's resource controller that send back the number of resources, the path to files. But this was all plain unformatted text, and one response per attribute - it was tiresome to use. I then moved to creating an XML structured response, and unity would then parse the XML. But because the XML readers required additional code, and I was trying to keep the codebase as lean as possible, I moved to JSON. A nice JSON reader comes prepackaged with the unity3 API for smartfox server - and I had already built a JSON web services API for a google web toolkit client... so the match was made in heaven - I was going to build a JSON web services api.

The result:
Picture! Images dynamically downloaded into Unity based on web services

So what follows is a big chunk of semi-source code of how that is integrated to Unity. The basic flow is:

  • a UnityGameObject starts a coroutene asking for web data
  • Generate request inside unity, and send using WWW class
  • Server receives call, retrieves data from database, creates an encode a PHP object to JSON, sends this as response
  • Unity receives object, decodes using libJSON, calls back original UnityGameObject with data

Example client functions for send request and decode response (C#):

    //Download and add image to billboard
    public static IEnumerator DownloadResource(int id, IHasResourceResult attachpoint)

        WWW request = new WWW(baseURL() + hubCommandBaseUrl + "&task=jsonlist&jtask=detail&rid=" + id.ToString() + hubNoHtmlUrl);
//formats a url that look similar to:
            yield return request;

            //attach resource callback
            //This is inside a loader help class, and called via a coroutene with a self reference passed as a callback
            //we need to callback the caller and give them the resource          attachpoint.AttachResource(loadFromJSON(request.text.Replace("[","").Replace("]","")));

            yield return null;

//decode the JSON data

    private static ResourceResult loadFromJSON(String JSON)
        LitJson.JsonData jResponse = LitJson.JsonMapper.ToObject(JSON);
        ResourceResult result = new ResourceResult();

        result.introtext = Escape((string)jResponse["introtext"]); = (int) jResponse["id"];
        result.title = Escape((string)jResponse["title"]);
        result.thumbnail = Escape((string)jResponse["image"]);
        result.document = Escape((string)jResponse["document"]);

        return result;

Example server functions to send response (PHP):

   //encode objects into JSON
function JSONObj($object)
$json =  json_encode($object);
$json = preg_replace( "/\"(\d+)\"/", '$1', $json );

return $json;
function startList()
echo '[ ';
function endList()
echo ' ]';

//called by controller to switch off to correct task
function JSONResponse($task)
switch ($task)
//switch off to task function

function exampletaskfunction()
$database =& JFactory::getDBO();
$id = JRequest::getInt( 'rid', 0 );

                                       //make an object to convert into JSON
$obj = array();
$obj['introtext'] = htmlentities($resource->introtext);
$obj['image'] = '';
$obj['title'] = $resource->title;
$obj['id'] = $resource->id;
$obj['fulltext'] = $resource->fulltext? htmlentities($resource->fulltext): '' ;
$obj['document'] = '';

echo $this->JSONObj($obj)."\n";


Example JSON response data from server:

[ {"introtext":" \n\n\t The primary purpose of this paper is to present the instrumentation plan of a fullâ","image":"2011\/07\/03081\/.thumb\/.thumbfile.1.jpg","title":"SEISMIC RESPONSE OF STRUCTURAL PILE\u2010WHARF DECK CONNECTIONS FOR PORT STRUCTURES ","id":3080,"fulltext":"\t<p>\n\t <\/p>\n<p>\n\t The primary purpose of this paper is to present the instrumentation plan of a fullâ","document":"MjAxMS8wNy8wMzA4MS8ud2Vidmlldy8ud2Vidmlldy5zd2Y="}

So that shows a basic concept of how to program a web service architecture into unity.

Crossdomain policy file for Unity3 and SmartfoxServer

A little tip, now with Unity3, the webplayer will require a crossdomain XML policy for security (Info here). Make sure the xml file is utf-8 encoded, it saves a bunch of issues.

<?xml version="1.0"?>
  <allow-access-from domain="*" />

Make sure if you are using Smartfox Server (Product Website) (we use version 1.6 for our virtual classroom software) that you have auto send policy file to true. Without this, the socket connection will be block by the webplayer security model. Make sure you set the correct line in your config.xml and restart the server.


Joomla error on authentication

So we just recently upgraded the database with fresh production data , but then the joomla site would not let us log on to either the front or back (admin) end. It would show a 500 error when you submitted the login form. We do use a LDAP authentication system, but surely that wasn't the problem?

In the error log the following line was repeated:

[Tue Jul 19 10:22:08 2011] [error] [client XXX.XX.XXX.XXX] PHP Fatal error:  Call to undefined method stdClass::onAuthenticate() in /www/neeshub/libraries/joomla/user/authentication.php on line 121

This was a call to onAuthenticate inside the (foreach $plugins as $plugin) block.

The fix: To actually get into the website and see what was going on, I needed to selectively disable our authentication plugins to find which one was failing. Of course I had to do this directly in the database, because I couldn't even get in to the plugin manager in joomla.

Monday, July 18, 2011

Making thumnails of all pdfs present in a folder structure

So I wanted to share a tip, it combines some bash scripting and ghostscript - for searching for all files recusively and then creating a thumbnail from the pdf (one for each page) and placing them in a newly create .thumb folder. This will overwrite any previous images - beware!

# Loop over resources in directory, looking for pdf and image files to create thumbnails of
find . -name \*.pdf | while read file; do
        echo "Processing $file"
        mkdir "${directory}${thumbdir}"
        gs -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -dNOPAUSE -dBATCH -sDEVICE=jpeg  -g450x600 -dPDFFitPage  -r9.06531732174037 -sOutputFile=${directory}${thumbdir}/${thumbprefix}.%d.jpg -c "save$
currentglobal true
setglobal false/product where{pop product(Ghostscript)search{pop pop pop revision 600 ge{pop true}if}{pop}ifelse}if{/pdfdict where{pop pdfdict
begin/pdfshowpage_setpage[pdfdict/pdfshowpage_setpage get{dup type/nametype eq{dup/OutputFile eq{pop/AntiRotationHack}{dup/MediaBox eq revision 650 ge and{/THB.CropHack{1 index/CropBox
pget{2 index exch/MediaBox exch put}if}def/THB.CropHack cvx}if}ifelse}if}forall]cvx def end}if}if setglobal" -f $file

Now this could be done in a more compact script, but I re-use this for-each file structure in a bunch of like scripts.