Despite an enthusiastic resistance, napping is something I seem to be destined for. As the afternoons arrive, so does a sleepy warm cloud of squishy goodness - submission seems to be the only answer. A gooddeal of readingfodder seems to support as much.
So in the new week - armed with my handy cheat sheet - I'll be taking 30 minutes each day to spend in slumber.
Over the past year, an upsurge in work has led me to rethink the management of my development server. Trac, Subversion, and WebDAV hung in the background as support services for the project staging areas. With complexity increasing exponentially with each new project, I'd become increasingly desperate to find an elegant solution.
Of course I wasn't alone in my requirements and after a lucky conversation with Tristan Rivoallan I was pointed in the direction of his Cleverbox project.
Cleverbox is a Python CLI tool for managing all the project peripherals which can tend to get a little complex if not handled in some sort of automated manner.
Installation was relatively simple through apt-get -- I won't parrot the detals -- with the only customisation being a change to the shebang of /usr/bin/cleverbox-admin which needed to point to Python 2.4 rather than my default:
#!/usr/bin/python2.4
From the Tracesque CLI interface, client and project administration is a simple matter of: create, activate, deactivate, etc.
Profiles can be created for customised configuration. Here is mine which activates Digest authentication:
## Client : %(client_name)s# Project : %(project_name)s## This configuration file is a variation on the original from the Cleverbox default profile. It# enables three services for each project :# - Subversion : a subversion repository# - Trac : a Trac (http://trac.edgewall.org) instance, linked to the subversion repository# - Documents : a webdav share## All the services require authentication and all from a common single userfile:## %(clients_root)s/%(client_name)s/var/%(project_name)s-htusers## This file can be generated and updated using apache's `htdigest` executable.## Authentication is common to all services
<Location "/%(client_name)s/%(project_name)s">
# Digest authentication is still experimental in apache-2.2 - lets be daring :)
AuthType Digest
# -- mod_rewrite for uri mapping
RewriteEngine On
# -- File based authentification
AuthUserFile %(clients_root)s/%(client_name)s/var/%(project_name)s-htusers
</Location>
# -- Subversion service
<Location /%(client_name)s/%(project_name)s/svn>
DAV svn
SVNPath %(clients_root)s/%(client_name)s/var/svn/%(project_name)s
# This service requires authentication
AuthName "%(client_name)s > %(project_name)s > SVN"Require valid-user
# For authorization, please uncomment the following and create the required file:# AuthzSVNAccessFile %(clients_root)s/%(client_name)s/var/%(project_name)s-svn-auth.ini## This file would typically contain something like:# [groups]# admin = user1,user2# general = user3,user4# # [%(project_name)s:/]# @admin = rw# @general =# * =
</Location>
# -- Trac service
<Location /%(client_name)s/%(project_name)s/trac>
SetHandler mod_python
PythonPath "['%(trac_install_dir)s'] + sys.path"
PythonHandler trac.web.modpython_frontend
PythonOption TracEnv %(clients_root)s/%(client_name)s/var/trac/%(project_name)s
PythonOption TracUriRoot /%(client_name)s/%(project_name)s/trac
SetEnv PYTHON_EGG_CACHE %(clients_root)s/%(client_name)s/tmp
# This service requires authentication
AuthName "%(client_name)s > %(project_name)s > Trac"Require valid-user
</Location>
# -- Documents service
AliasMatch /%(client_name)s/%(project_name)s/documents(.*) %(clients_root)s/%(client_name)s/htdocs/%(project_name)s$1
<Location /%(client_name)s/%(project_name)s/documents>
Dav On
# This service requires authentication
AuthName "%(client_name)s > %(project_name)s > Documents"Require valid-user
</Location>
This tool has already saved me so much time - a huge thanks to the developers.
Well, I've spent some time over the past few days etching out this masterpiece. The CSS is quite a hodgepodge at the moment but more cleaning to come. Overall, I'm quite pleased with the outcome - you know, being an ace designer and all :)
I'll probably turn this into a free theme for Steer CMS - with a more generic skin - working with it over the past day has been simple enough, maybe someone else will find it useful.
The overall weight of the theme has been kept to minimum - just on 20 kb - with only a couple of images.
With a couple Apache tweaks, I got my YSlow performance grade to 99 - yeah!
The Peach Open Movie Project has delivered its brand new short film - Big Buck Bunny. Apart from being an awesome piece of animation work, it's also been released under the Creative Commons license - so downloading, sharing and using it isn't going to bring down a team of lawyers on you.
Symfony's plugin system is very versatile - from simple internal components to integrated and publicly deployable Pear packages, it's all at your fingertips.
Why use plugins?
They make a heap of sense when considering modules which might be used in many projects. Take for instance a custom blogging mechanism you always seem to be adding to your Symfony projects. By separating its code into a plugin, you elegantly maintain a level of separation. This will make you very happy when you realize you can then maintain your blogging code in its own repository area, only adding it into individual projects as a svn:externals.
So What Can Plugins Do?
Well pretty much anything. Commonly you will find people turning libraries, modules and behaviors into plugins since they usually fit nicely within the context of "reusable".
How Symfony sees plugins
Well lets see how Symfony interacts with plugins by creating one to test with.
Please Note: This example is light on details, you should probably feel comfortable with general Symfony coding to fill in the gaps.
Create the plugin
$ cd yourSymfonyProject
$ mkdir plugins/myFirstPlugin
$ symfony cc
And your done! Well sort of, the new plugin is a little... useless to start with.
Adding a library
To add a library, simple create the lib directory in the plugin and add your files:
$ mkdir plugins/myFirstPlugin/lib
$ touch plugins/myFirstPlugin/myToolsLibrary.php
$ symfony cc
And viola! the my myToolsLibrary.php will available to Symfony.
Adding a module
If you take a look in one of your applications modules, that structure is applicable in exactly the same format inside a plugin.
Would give you the required structure for a module. For security reasons, Symfony won't automatically provide access to the plugin, so you will need to authorize it inside an application by editing settings.yml:
Well, these are a little different. Since they are files to be directly accessed by Apache, they will need to be within the web directory. While you could just copy and paste them out, it's probably better to link them.
So this was really just a quick preview, but the patterns and structures shown above basically set the rules on how plugins work across the board. If you want to move beyond this, perhaps give back some code to the community, Pear packaging is a great way to formalize the plugin and its contents. I won't go into details on that since I need to go and get a coffee.
Another thing to remember, as always, learning by example can really fast-track getting up to speed - Symfony plugins included. Some links can be found below.
A vegetarian farm house breakfast consists of two perfectly poached eggs, their centres drizzled out over the thick toast below. Wilted spinach, mushrooms, hash-browns and fried tomatoes to the side and coffee made just right - Le Petit Tart is one of my favourite cafes.
Snacking between main meals, is a sure way to gain excess weight. Making sure your main meals leave you satisfied is a sure way to defeat snacking.
But in the end... if the person next to you insists desert is part of breakfast and every other meal in a day, you're screwed anyway.
I can only imagine how incredible intimidating it is when you are provided with a "Cease and Desist" order from a larger company and its legal minions. Yet after a huge community outcry, Digg have drawn a line and chosen to stand with its community.
For those unaware of the history behind this fork in the road, Digg had previously been removing material which could potentially leave it breach of the Digital Millennium Copyright Act. For instance, Diggs could be removed if they linked to such things as instructional material on how to circumvent DRM technology. But from now on, they will allow Diggs such as these to remain.
Now coming into legal conflict with large companies is not something to be taken lightly. Famous stouts relating to indirect participation in copyright breach have historically proved damaging for the defendants. For example the Napster vs RIAA battle of 2001 left Napster all but a name after it's core business process was shut-down.
With that in mind, I'm not quite sure if Diggs stance is a good idea on a business level - lets not forget that they are a business. But the idealist in me says good for them. Some may snicker and look on at the move more cynically - a forced move for Digg... either a) comply and loose your community then have to shut down, or b) get shut down by a legal injunction. But I think compliance wouldn't have been that damaging to Digg. It seems more likely that they want to reflect the ideals of their user base, even if that includes potentially risky moves. So good idea or not, I like that they are now standing their ground.
With an air of whimsical nonchalance, Kevin Rose puts it:
If we lose, then what the hell, at least we died trying.
Good for them.
So it will be interesting how this plays out, not only for Digg, but as online communities are rapidly evolving in reach and structure, will this mean a new front is opening up for groups like RIAA?
They have traditionally proved a little sluggish at playing ball with the boom of new technologies and social trends. Using there massive legal capabilities may prove effective for a period of time, but it probably just sets themselves into some very inflexible and outdated tactics - just when they need to be more dynamic than ever.
No-one likes an ass hole, especially one that never grows up.