Made Media Ltd. 105 Carver Street, Birmingham B1 3AP

mail@mademedia.co.uk +44 (0)121 200 2627

Made Media Ltd

Posted in diarised, life, linux, news, php, technology by Josh on June 5th, 2007

Give your web app international appeal

Think Vitamin

You may have noticed that Diarised is now available in Spanish as well as English. More languages are on the way and this is now pretty easy thanks to the 'internationalisation' of your little meeting application.

Steve, our lead developer, has just had his first article published on Think Vitamin where he talks about the work involved.

Give your web app international appeal is the first in a two-part series offering fairly technical guidance on how to internationalise web apps generally. It's a good read if you're into that kind of thing. Watch out for part two coming soon.

Oh, and if you would like to see Diarised in your language then let us know. If you (or someone you know) can do the translation then we'll add the code and make it happen. It's a simple process - we just send you a text file which you can translate and send us back.

UPDATE: Part two is now online.

0 Comments

Posted in linux, technology by Jake on March 21st, 2007

Partial Downtime. TAO.

Everbody’s favourite Linux server Tao was down for ten minutes today between 13:40 and 13:50.
Websites and Email on that domain were effected. It’s back up now, and we’re investigating the cause of the problem.

0 Comments

Posted in linux, technology by Jake on December 12th, 2006

mmNet. Now with less spam

You can’t have failed to notice the meteoric rise in spam in recent months. Many commentators characterise the fluctuations in spam rates as an arms race. Spammers come up with new techniques, the anti-spam houses respond with new rules. Just recently the spammers have started winning the race again. The worst of the new breed of spam are image-based, stock scams because they are not susceptible to most common spam-catching techniques. There has also been a rise in advertising for – ahem – ‘upsizing’ products as well as the usual pharmaceuticals.

We know that some of our customers have been struggling under the load recently, and we have been working to improve the situation. We’ve finally brought it under control, to the point where we are now seeing just one or two unwanted emails slipping through the net per day.

Here’s what we’re doing:

  1. We’re now checking all incoming mail against the SpamHaus SBL and XBL list, and rejecting mail from IP addresses listed in their database. Using IP blacklists can be controversial, but SpamHaus make a real effort to be fair and avoid blacklisting innocent IPs. This gets rid of about 50% of spam before it even gets near your email account.
  2. We’ve tweaked the SpamAssassin rules on our server so that they are now much more accurate. We’ve even managed to successfully detect image spam. We’re seeing close to zero false-positives though, so we’re not just blocking images indiscriminately.

What you should do:

  1. Set up a filter rule. Whenever we detect a message that we suspect is spam we mark the subject line, so that it begins: [spam?] . Most email clients will allow you to easily create a folder/mailbox called ‘spam’ and set up a rule to divert all mail marked [spam?] to that folder. You can then review the folder periodically to check that no legitimate mail has slipped in. Doing this should leave you with next to no spam in your in-box. If you’re lucky enough to have an e-mail client with Bayes spam filtering built in then it should begin locking onto the word [spam?] automatically, so you may not even need to add a rule.
  2. Switch off catchalls. If you are still using a catch-all email address (an address which picks up mail for unknown names at your domain) now is the time to switch it off. Spammers often just guess at the first part of email addresses, so catch-all addresses are a magnet for spam. It’s much better to bounce email to unknown addresses. That way, even if someone does spell your name wrong, they will know about it.

What if you’re still getting spam?

If you’re still receiving unmarked spam, just forward it on to: spamcop@mmnet.co.uk. We’ll take a look and see if we can tweak the rules to prevent mail like that from slipping through in the future. At the very least it will be added to our Bayes database.

What if a genuine email gets marked [spam?]

Forward it on to spamcop@mmnet.co.uk. We’ll recognise that the email has been marked incorrectly, and add it to the ‘good’ Bayes database . This will help to prevent similar mis-identification in the future.

What about viruses?

Happily the SpamHaus SBL/XBL list is catching most viruses and phishing schemes before they get near your email account. If one does slip through, the Dr Web service kicks in and isolates the email.

In the spam arms race we’ve just taken the advantage back. Hopefully our clients can breathe a sigh of relief until the spammers come up with something new. We’re also working on some black secret technology to provide the same relief to people who don’t even host their email with us. Watch this space.

0 Comments

Posted in linux, technology by Jake on December 1st, 2006

Free ISP-in-a-box ISO

If you need to manage more than a handful of domains on your own box, and you’re not man enough to do everything the raw way (I’m not), you probably use some kind of virtual host control panel software. At Made Media, we use Plesk. It has its quirks, but it’s one of the best. It’s not cheap though, and you could argue it’s a little over-complex.

But we didn’t get into Open Source to pay for stuff did we?

A bit of aimless web surfing led me to a post on Scripting News, where Dave Weiner reveals that he picked up a Cobalt Cube from eBay for $125. This got me googling for Cobalt stuff.

For the uninitiated, Cobalt were the first company to really push the idea of Linux-based Internet Appliances. While the Cube was a kind of all-in-one Linux-based Exchange equivalent for the tech savvy office, the RaQ was a Web Hosting service appliance. It was pretty-much the fore-bearer of the explosion of data-centre ‘blade’ servers, and also the grand-daddy of hosting control panels like Plesk, Ensim, Cpanel et al. With it you could manage up to 100 websites on a tiny purple box, with a web-based control panel that made it easy to configure domains, and even pass a level of control out to your clients.

Sun snapped up Cobalt in 2000 but didn’t develop the products a whole lot further before discontinuing the line in 2003. By that time the rest of the web-hosting scene had caught onto the idea and were developing similar systems on top of white-box hardware.

And there the story ended. Or so I thought, until I did a bit of googling last night.

It turns out that in a typical exmple of doing the right thing, Sun open-sourced the Cobalt software. A crack team of Japanese hackers have been working on the code ever since, resulting in an Open Source version, Blue Quartz.

Even better, some bright people have got it working on top of CentOS, which is a hardened, community-supported clone of Red Hat Enterprise Linux (which we use on our main webservers at Made). The great advantage of this is that you can use the latest apache, mysql and PHP, and security fixes are a simple ‘yum update’ away.

But ultimately, the thing that really tweaked my interest is that one enterprising Linux Hacker has produced an all-in-one, free combined ISO installer that will install the whole lot on pretty-much any old PC in around 20 minutes.

So from reading Dave Wiener’s post, to having a fully-running, control panelled, reseller web-host box in my spare room took about two-hours all-in. The computer was an ancient 500mhz celeron machine that really needs freecycling. As it happens the fan-noise is irritating so this little project will probably go no further. But for charities, companies on a budget, or just garage enthusiasts this offers a great opportunity to run their own budget web-server in the spirit of open source.

Take a look!

0 Comments

Posted in linux, local, news, technology by Jake on November 14th, 2006

Server Lover - Apply Within

Thank Spock!Due to continued expansion of our technical offerings, we are in desperate need of a full time Network Support Manager to join our small, but perfectly-formed team in Birmingham, England. You will keep our network running at 99.9% availability, applying patches, maintaining backup procedures, negotiating bandwidth, doing fresh server installs, and supporting the development team. You will also provide first-line support to our clients, both for hosting services and for our own web applications. You possess the patience of a saint, the organisational skills of a librarian, enough charm and telephone manner to soothe the most irate, confused client, and experience with some combination of the following:

Linux, Apache, MySQL, Shell Scripting, Plesk, OS X, Windows, Subversion, Ruby-on-Rails, SpamAssassin, Hardware, RAID, M0n0wall, Cisco Routers, Rsync, DNS

Our systems are well documented, and we can provide training on most aspects of the job, so we’ll consider candidates from a wide range of commercial backgrounds. Salary will be dependent upon your level of experience.

Please send your CV and a covering email to tim.kitchen@mademedia.co.uk. Sorry – no agencies please.

0 Comments

Posted in linux, technology by Jake on October 9th, 2006

MyActiveRecord - New Release

I've finally got it together to release an update to the MyActiveRecord class.

There's nothing like open-sourcing some code to teach you a few lessons:

  1. Not everyone is using the same version of PHP, MySQL or OS as you
  2. Not everyone is using English as their first language
  3. Whilst you might not be dealing with the kind of databases that trigger out-of-memory errors in your script, some of your users most definitely are...

So after releasing MyActiveRecord via phpclasses last March, I was overwhelmed with the response in both good and bad ways. Almost everyone who wrote said that the class had really helped them speed up a major project they were working on (good!). Also most people really got my motivations for developing the class; Many were quite familiar with Ruby on Rails but for whatever reason were sticking with PHP. Most were after a class they could use to cut down on basic SQL hoop-jumping, but they didn't want to learn an entire framework, and they wanted the flexibility to do things their own way. Many were developing in a PHP4 environment and deploying on PHP5 or vice-versa.

In my update I tried to incorporate bug-fixes, some of the nicer ideas, and stuff that I'd implemented half-heartedly and wanted to do properly. The major new features are:

  1. SQL Logging (handy for debugging)
  2. Query Caching (improves performance)
  3. Single Table Inheritance (allowing you to store a class hierarchy in a single table)

There are also some new, useful methods:

The Prepare() Method allows you to escape SQL parameters in a hassle-free way, using sprintf syntax. Eg:


$condition = MyActiveRecord::Prepare("first_name LIKE '%s' AND age > '%d'", $_GET['first_name'], $_GET['age']); 
$people = MyActiveRecord::FindAll('Person', $condition); 

The FreqDist() Method will provide you with an array containing the distribution of unique values for a given table/field. Eg:


foreach( MyActiveRecord::FreqDist('Person', 'name') as $name=>$total ) { 	print "There are $total people with the name $name"; 
} 

The TableExists() is a utility method to tell you if a table exists in the database or not

 if(MyActiveRecord::TableExists('person')) print '`person` table exists!'; 

The add_child() method provides a convenient way of creating new child objects:

 $comment = $post->add_child('Comment', $_POST); $comment->save(); 

The validadate_uniqueness_of() method allows you to check whether a field value is unique before attempting to save it in the database:

 $person->validate_uniqueness_of('username', 'username is already in use'); 

Most of the changes are under the hood. One you do need to know about is the way MyActiveRecord maps classes to tables. Originally classes were supposed to be named identically to the table in your database. So a Person class would map to a Person table. Unfortunately a bug in PHP4's get_class method meant that this could not be sustained. The get_class function always returns a lowercase string in PHP4. The only reason this didn't cause problems for most users is that most combinations of OS & MySQL effectively give you case-insensitive table-names. However this wasn't true for everyone. The only way to get 100% compatibility for all cases is to mandate that table-names are specified in lowercase. So a Person class will map to a person database table. It's one of those classic PHP frustrations, and it annoyed me no end, but you could say that this whole project was born out of a desire to circumvent PHP's foibles

What didn't make it.

A lot of people asked for stuff that seems perfectly reasonable, but that I decided to leave out anyway. Here's what got left out:

  1. Changes to mappingPeople wanted to be able to append stuff to the front of their table names i.e. myapp_person mapping to Person. People wanted to be able to change the name of the field that acted as primary key etc. I've resisted this because whilst on the surface these things seem simple enough to implement, in practice they add complexity and ambiguities at every level of the class. MyActiveRecord wasn't my first attempt at a mapping class, and defining a few simple, solid rules about naming and IDs was what freed me up to finally build a class that I felt had some elegance and integrity. It also allowed me to document and explain the class without constant caveats and exceptions. So I'm not bending on this yet. (Actually, working around the get_class() bug required me to add a Class2Table method, so in theory, adding a prefix to your table names would be easy enough and I might consider it.)
  2. View logic in the mapper classA few people supplied me with some helpful methods for getting HTML out of the class. Pre-formed error lists and the like. Obviously this is evil, I even feel a bit icky about the h() method, but it's just so damn handy and I stole the idea from Ning. Actually, I do have a class that takes a MyActiveRecord object and then uses methods to spit out helpful HTML fragments, but it's not quite ready for production yet...
  3. Event hook methodsSome people supplied rails-esque event-hook methods like before_save(); before_destroy() etc.. After some deliberation I decided not to add these. Why? Because I think you can achieve exactly the same thing by extending the class. That is one of the key advantages of OO after all! For example:
     Class Person extends MyActiveRecord { 	function save() 	{ 		return $this->some_cleanup_or_test_method() ? parent::save() : false; 	} } 
    If someone can make a good argument as to the advantage of putting blank event hook methods into the class I'll look into it again, but for now I'd rather prevent the base class from getting any broader!

  4. Shorter NameSo some people are developing RSI typing the same 14 characters over and over. I admit, the name is ugly and too long, but it has several marketing advantages with regards to describing what the class does, picking up search engines and so on. This one is easily solved anyway:
     Class AR extends MyActiveRecord{} Class Person extends AR{} $people = AR::FindAll('Person'); 
    Actually I really recommend this approach whenever you build a serious application, as this gives you an opportunity to extend all sorts of basic functionality like saving etc.. at your application level. For example, you might decide to extend the save method so that it stores a serialised copy of every object that's ever updated, giving you a complete transactional history of every object in your application. It's easy to do. Plus when you develop some great ideas in your extended classes you can send them to me and I'll have nice cleanly separated code to incorporate into the next version of the base class.

What's next?

Apart from the fact that I'm extremely busy anyway I don't really intend to develop this class a whole lot further. It does a pretty nice job, and it's already a lot bigger than I would really like. There will be bugs in this release, and I will fix any that are reported. Other than that, I intend to improve the general integrity of the class and add some magic field names (datetimes called modified_on and created_on will get time-stamped automatically, stuff like that). I want to deal with the caching and encapsulation of related objects so that - for example - saving a post object will automatically save changes to any child comment objects.

Once those basic features and bug fixes are implemented I'll declare the class at version 1(beta) and after a reasonable time to fix any bugs I'll declare it 1.0.

I'd like to thank Walter Lee Davis, Mark Kaye, Mike Stupak and Mihael Konjevic in particular for their help and feedback to date.

0 Comments

links

categories


archives