Archive for September, 2008

New version of FotoLoad

Thursday, September 25th, 2008

FotoLoad is in use for >3 months now by one photo studio and transfered >15 GB of photos already. We haven’t yet started marketing it to others but we will start now. Last 2 weeks we made extensive testing under different browsers and operating systems, under extensive loads and photos of size that you don’t see normally yet (basically 4 photos glued together to get a mega-photo). The load testing showed no problems at all. And the biggest “bug” which was also the reason we started testing then appeared to be “human factor” in admin interface. We changed the admin so that this mistake can’t happen any more and we added some small improvements to the client that I think will make up a much better user experience. The main thing is that now you get visual feedback when something is loading, uploadint, etc in the various stages of the usage (not just image uploading). This was something that I was aware I need to do from the start so I am happy it’s finally done well.

Photo Loading utility

We made a final decision on the prices now also and the website is proofread by a pro now so my stupid typos should be there no more. The website doesn’t have a demo and video updated to this new version though. We will do that on the next major upgrade probably.

After we start the marketing in Slovenia we will start making app available in other languages.

Reblog this post [with Zemanta]

Example of making webapp “distributed” with PHP and STRPC

Tuesday, September 23rd, 2008

Distributing and scaling larger storage needs… buzz buzz buzz words. The thing in short goes like this:

I was making some shop for music and sound files. When you buy for example 3 sounds you get download links that hold a temporary key that expires after certain time or certain number of downloads. The link calls a PHP script that checks key, time, logs it, etc.. and “streams” the file with proper HTTP headers so it downloads as if url was to a normal binary static file.

There are mp3, ogg and wav (uncompressed) files for each music/sfx and they take up HUGE space on HD, so the client wanted to have the ability to have these files on different servers, basically wherever. So I called in my favorite RPC library STRPC (SoTinyRPC) and made the logic already working on a single server work in an DISTRIBUTED fashion. So here is a little simplified before / after code.

before: the class that handles these restricted download ability (DownloadLimiter) is lazily imported and instantiated with _inst(). Then a function is called on that sets up each download and returns a secret keys. (We then store it into database so that we can display download links to the buyer.)

$dl = _inst('DownloadLimiter');
foreach($items as $item)
{
	$item['dl_key'] = $dl->createDownload($orderId, $item['path_to_file']);
}

after: code includes and instantiates phppulp class STRPC. Then we parse the url to the download file to get the domain (and path) and make a RPC call to that specific domain.

$rpc = _instPulp('STRPC');
foreach($items as $item)
{
	$url = parse_url($item['url_to_file']);
	$item['dl_key'] = $rpc->call(URL::getDomain($url),
			'dl', 'createDownload',
			array('order' => $orderId, 'file' => $url['path']));
}

STRPC server: So now we move DownloadLimiter class from here to all these remote servers and make it’s function createDownload available to STRPC calls.

require_once 'bin/globals.php';

$dl = _inst('DownloadLimiter');

echo _instPulp('STRPC')->serve(array(
	array('dl', 'createDownload',
		array(
			array('order', 'string'),
			array('file', 'string'),
		),
		'string'
	),
));

This is the file that makes the STRPC server. The DownloadLimiter class stays exactly the same as it was when that function was called locally.

STRPC was so far used in 7 real life projects and as far as I know only by me. I used/made clients in JavaScript, AS3 (Flex), Haxe (Flash), PHP and Java. STRPC servers were made in PHP And Factor up to now. It’s born out of practice implementation and spec are about to be upgraded to some cool features but I haven’t yet found time to do it.

//EDIT: I changed the client examples a little because they had some app specific logic with 3 kinds of file per music/sfx that only diluted from the point here.

Reblog this post [with Zemanta]

When Ajax Attacks - Interesting slides from talk

Tuesday, September 23rd, 2008

I found this very interesting slides from talk of Simon Willison . I want to bookmark it to study mentioned subjects deeper when I have more time:

Link to blog post: here

Slides:

Reblog this post [with Zemanta]

BraveKid’s Summer Job in Outer Space

Monday, September 22nd, 2008

A little screenie of a second game that is being worked on. This one is made in BlitzMax and Lua as an embedded language for level scripting. Current plan is to release it in 4 episodes each having 25 levels and being sold for around $4. The game is very moddable.

BKSJinOS

I’ve had it that I haven’t managed to make any name for bravekidgames.com yet and that it continues to slog on the ok-but-not-successful edge for so long. Not that I wonder how come, I could wonder.. how would the name be created anyway. So I now plan to make few games featuring Brave Kid and we will see what happens.

Reblog this post [with Zemanta]

Waterisk 2 - some progress

Saturday, September 20th, 2008

I love LWJGL and Java with it. The code falls together quickly and I have so far a feeling of total control over it which is not what always true for my game projects.

Great thanks to kevglass for making such nice tutorials for LWJGL!

v 0001

v 0001

Reblog this post [with Zemanta]

3 Web-projects finishing, Waterisk 2 starting

Wednesday, September 17th, 2008

3 of my web projects I was working lately are finally begining to get “first release” ready. I decided to concentrate on down-to earth stuff this time… These are:

www.klikni-za-pizzo.com - a list of slovene pizzerias

www.fotoloadstudio.com - a tool for photo studios

www.oglasko.com - a search engine thought Slovene classifieds ads

We are in the process of adding the pizzerias at first one, we are doing the bigger test and improve session at the second and we are adding coverage to the third.

I decided that I will start making the long-planned rewrite of WATERISK from processing to LWJGL an Java in my “free time”. I was having problems with sound and sometimes unresponsive keyboard input at processing.

1000 bugs

Bugs already crawl around in new LWJGL version

Otherwise, besides improving existing projects I will start with either another down-to-earth project try to finish and (first-)release already almost functional Ask Robi.

Reblog this post [with Zemanta]

Great talk from the Flickr guy

Wednesday, September 17th, 2008

This is a great talk by Cal Henderson, very funny to listen too… but also gives opinions that I can relate too and are many times pushed aside in this “industry”. On one side from the fashion/CS people and on the other from the Enterprisey people. It also gives straight useful info between the jokes.

DjangoCon 2008 Keynote: Cal Henderson


Reblog this post [with Zemanta]

Installing Java5 to Debian4.0

Wednesday, September 3rd, 2008

Debian OpenLogoImage via Wikipedia Installing Java on Debian is more problematic than it could be because not of technical issues but because Debian’s ultra nice apt-get “gets” only clear open source things and Java (JVM) while it was always free is getting (or got - Java is a big thing) open sourced only recently.

It turns out that the procedure is very simple at the end but the biggest problem was finding out which “how-to” article is the recent one. I read many different tutorials about it but nothing worked and it’s hard to even find out if something you are reading is old 1 month or 10 years. There should be a creation date posted at every doc on the internet!

Ok, so I found the currently working and a normal way of doing it at last in some blog comment!

You need to change sources of apt-get a little. Edit file /etc/apt/sources.list to look like this

deb http://ftp.debian.org/debian/ etch main non-free
deb-src http://ftp.debian.org/debian/ etch main non-free

deb http://security.debian.org/ etch/updates main contrib
deb-src http://security.debian.org/ etch/updates main contrib

And then you can hapily run

apt-get update
apt-get install sun-java5-jdk

in console and life makes sense once again.

Yes, I didn’t get the latest Java but this version is all I need in my case (and most packages/servers support it).

You don’t need to be a a Java programmer to want JVM on your debian VPS. You have a lot of interesting languages on JVM these days. Like Clojure, Groovy and Scala, and ports of C versions like JRuby, Jython, Quercus (php). There is also a bunch of interesting servers written on JVM like adobe/flex related stuff, Red5, OpenLazslo, Tomcat, Jetty

And it is known that JVM people are now interested in making it even better VM for all sorts of dynamic and functional languages.

Reblog this post [with Zemanta]

Web-pipe test : PHP

Monday, September 1st, 2008

I just finished and got paid for big project I was working for more than a year, and wire transfer for another one is also on it’s way. So I decided I will have some fun in the next weeks and try something I was thinking of for some time. To explore the known languages and to learn some new ones I will write this code in multiple languages and see what the different languages offer me.

The system is simple, frontend consists of two “public” groups of functions

Actions
begins with act_ and recieves HTTP POST data as $p argument, returns array of messages
Display functions
begins with show_ and recieves HTTP GET data as $g argument, returns HTML output

Backend consists of perfectly usage neutral DB and bussines logic functions.

I have one action that ads the news item to the database and two display functions, one shows a list of all news and another a single news item selected by id in GET.

News_f is a class that represents frontend. News_b represents backend. _instb() is an utility functions that includes and instantiates a backend class (_instf and _inst also exist). This makes inclusion of our application classes lazy and includes only the files/classes that are absolutely needed to process the current request. Frontend and backend are not coupled together.

file: News_f.php
----------------

class News_f
{

	function act_addNews($p)
	{
		if (isset($p['act_addNews']))
		{
			$d = Arr::filterKeys(array('title', 'content'), $p);

			$msgs = $this->validate_addNews($d);
			$d = $this->prepare_addNews($d);

			return count($msgs) ? $msgs : (
					_instb('News')->addNews($d) ? array('News added.') : array('Error happened!')
			)
		}
		else
		{
			return array();
		}
	}

	function show_single($g)
	{
		return isset($g['id']) ?
			Tpl::do(_instb('News')->getSingle(intval($g['id'])), "<h2>{title}</h2><p>{content}</p>" ) :
			"This item doesn't exist." ;
	}

	function show_all($g)
	{
		return '<ul>'.Tpl::doOver(
				_instb('News')->getAll(),
				"<li><a href='single.php?id={id}'>{title}</a>"
			).'</ul>';
	}

	function validate_addNews($d)
	{
		return Validator::validate(array(
					'title' => array('required'),
					'content' => array('required', 'length>10'),
				), $d);
	}

	function prepare_addNews($d)
	{
		$d['title'] = ucwords($d['title']);
		return $d;
	}
}

file: News_b
------------

class News_b
{

	function addNews($d)
	{
		return $this->db->insertRow(array(
				'into' => 'news',
				'pairs' => $d,));
	}

	function getSingle($id)
	{
		Core::dieIfNot(is_int($id));

		return $this->db->selectRow(array(
				'from' => 'news',
				'where' => 'id = ?',), array($id));
	}

	function getAll()
	{
		return $this->db->selectRows(array('from' => 'news'));
	}
}



You can see the nicely formatted code here


I didn’t run this code so there might be bugs in it. It’s also not exactly like I write PHP code when I work as I was more playing with the code and various ideas here.

I will explain more in next posts.

Any comments, likes, dislikes of the code are very welcome of course.