Adding an External SVN Resource With Tortoise SVN

Most of my projects are usually checked out at several different computers and several different operating systems. For Windows, there is The One SVN Client Above All Else, namely TortoiseSVN. As Christer and I’ve been working on an unnamed project lately, we’ve built up a set of resources in regards to basic functionality (user registration, user verification, access management, etc). These resources have become a small framework for a basic site, so I’ve adopted the set of files for several other projects. When using the “Framework” in other codebases, I still want to keep the framework versioned against the original SVN repository, so that if Christer commits his Überkool Must Have Feature v2.5 to the framework, I get all the magic with a single svn up.

The magical way ofdoing this is using the svn:external property to tell svn that you depend on an external repository. The property is set on the parent directory, and contains the value Directory RepositoryURL; i.e:

Property Value
svn:externals Framework https://svn.example.com/Framework/trunk/Framework
OtherRepository https://svn.example.com/OtherRepository/trunk/

To set a property using TortoiseSVN, right click on the parent directory (i.e. libs or whatever you prefer to call your directory of common code), and select “TortoiseSVN” and “Properties”. Click “Add” and select svn:externals from the pulldown menu. In the value field you simply add Framework https://svn.example.com/Framework/trunk/Framework. Close the dialogs and select SVN Update when right clicking on your libs directory. This will create a directory named Framework in libs and check out the svn repository to the directory.

If you want several repositories as external dependencies in the same directory, add each repository on a new line.

Voilá!

UPDATE: Erik Hansen adds:
In order for Tortoise to “Update” your local copy with the external files, you first need to commit the property change to the REPO before it will do that.

UPDATE: Harry asked:

How do I provide other usernames and passwords for the other repositories? If my memory serves me right, as long as you’ve checked out the resource previously with TortoiseSVN, it will remember your username and password. I’d like an update for this, tho, as I’ve not been able to test it myself at the present time.

UPDATE: Chris added:
If you want several repositories checked out as external sources, add each repository on a new line under the same svn:externals property. Each directory can only have one externals entry, but the property may contain several repositories as long as they’re each put on a new line.

Randy Shoup on Lessons of Scaling eBay

InfoQ has an article about scaling ebay online written by Randy Shoup about some of the lessons they’ve learned over at eBay during the years when it comes to scaling one of the largest internet sites in the world. The article is a very interesting read, and I’ll sum up the seven main points:

  1. Partition by Function
  2. Split Horizontally
  3. Avoid Distributed Transactions
  4. Decouple Functions Asynchronously
  5. Move Processing To Asynchronous Flows
  6. Virtualize At All Levels
  7. Cache Appropriately

The Norwegian PHP TestFest is Done!

Just got back from Oslo after The Norwegian PHP TestFest. We were a total of seven people and Hannes Magnusson (hm, familiar title for that blog: We don’t either.) held an introduction to how to write .phpt tests. I had read a bit about the stuff previously and written at test or two, but I finally got some time to play around with the run-tests.php-script and other small tidbits.

I think everyone had a good time, and according to Flyspray for the PHP TestFest, we managed to write a total of 13 tests. The two tests for similar_text() and the two tests for using sqlite as a session save handler were the product of yours truly. I’ll try to contribute more in the future, I’ll just have to get gcov and a few other tidbits up and running here first.

In regards to writing phpt tests for the session module; anyone have a good idea how to force the garbage collector of a session save handler to be run? I’ve tried both using session.gc_divisor 1 and session.gc_maxlifetime 1 (and then sleep(2)), but didn’t get things working. Any suggestions would be appreciated.

New Book: Sources of Power: How People Make Decisions

I finished up A Culture of Corruption a couple of days ago. Good book, although a bit academic, but as I’ve not read anything within the field of Anthropology since .. the beginning of time, it was still very enjoyable. Suggested read if you can live with all the references and academic language. Also contained a collection of good stories which really illustrates the daily life in Nigeria, and makes you look on both the 419-scammers and the general consensus of corruption in Nigeria in a new light.

As I finished that book, I’ve now started the next book reading project: Sources of Power: How People Make Decisions. The book has been very enjoyable through the first five chapters, and provides a unique insight into how people make decisions when time is the most limiting factor. I feel very familiar in regards to my own experiences from situations where time has been the primary constraint in finding a good solution to a problem. The situations from the research that gave rise to book is very serious in nature, such as firefighters, nurses, rescue personell etc, but I’ve experienced the exact same thought patterns in less serious issues. A downed important webserver, a web application that does not work as it should for some reason or the other, an internet connection malfunctioning and making your entire business unavailable from the internet are not life-threatening in any way, but still important in just that moment.

Anyways, I’m really looking forward to reading the rest of the book as it’s been both easy to read and have very good insights into an unfamiliar field of research for me.

Short Array Syntax for PHP

En route from the aggregated stream of Planet PHP comes a small post from Brian Moon about Stan’s suggestion for introducing the [] syntax for creating lists in PHP.

I like Python. This is like Python. By association, I like this. This would mean that you now could do:

$a = [1, 2, 3];

instead of $a = array(1,2,3); and:

$a = [‘one’ => 1, ‘two’ => 2]

instead of $a = array(‘one’ => 1, ‘two’ => 2);

Syntactial sugar, but still, sweet sugar.

If we just could get [:]-syntax for slicing and dicing too now..

A Group Is It Own Worst Enemy

Read an article about Clay Shirky a day or two ago on one of the blogs I follow (sorry, I don’t remember which (edit: Coding Horror: It’s Clay Shirky’s Internet, We Just Live In It)), which linked to a writeup of a presentation he had done about the structure and workings of social networks and some thoughts about the issues that surround it. It’s insight delivered one word at a time and most certainly worth a read for anyone in the online business.

All The Memes in Weezer’s Pork and Beans

Well, I was smart enough to tell Jan-Petter that someone should make a list of all the memes featured in the Weezer video posted previously by me, since someone arrived at my blog with that query from google according to my logs. Well. He did. I present you with:

List of Memes References in Pork and Beans by Weezer

BTW: this post fell yet again victim to the NO TAGS and NO CATEGORIES usability attack from wordpress. :(

Followup on WordPress Usability Issues

I’ve now spent a fair amount of time with WordPress since I ported my blog over to it from Serendipity. My first experiences were collected in my post titled WordPress Usability Issues, and I’ll further extend on this here.

  • I’ve gotten used to having the “Save”-button on the right side, but this comes from having to learn the location by hand. I still move to the bottom of the page from time to time, but I’m not lost like I were earlier.
  • The location of the “Save”-button has however trigged another problem: since I now move my focus to the right of the page when I’m done writing my post, 9 of 10 times I fail to give my posts any tags or assign any categories to it. This is done beneath the text of the post, but since I no longer move vertically to progress from the post field (my eyes now move horizontally to the save/publish button instead), I never think about adding those. Guess I’ll have to learn that too, instead of following the flow of the application.
  • “Preview this Post” does not save the post before showing the preview. That means I’ll have to press Save, then “Preview this Post”, even though “Preview this post” is placed all by itself and seem to function independent of the other buttons.
  • Not a usability-issue, but probably a simple bug: some times my posts does not allow for comments, and I’ll have to enable them manually by going to the details of the post. I’m pretty sure that I’m not turning them off by accident, as the option is buried even further down from the tags and categories that I’m already having trouble finding without thinking explicitly about it.

The Progress Events 1.0 W3C Draft

While working on Swoooosh I stumbled across this draft from the W3C regarding “Progress Events 1.0”. The specification defines a set of standardized progress events and is intended for use with XMLHttpRequest and MAE. From their Abstract:

This document describes event types that can be used for monitoring the progress of an operation. It is primarily intended for contexts such as data transfer operations specified by XMLHTTPRequest [XHR], or Media Access Events [MAE].

Read more about Progress Events at the W3C.

Swoooosh – Free Open Source Flash-based Multi File Uploader

As I’ve mentioned a few times before I’ve been playing around with Adobe Flex. I finally got some more time to play with it tonight, so I got everything together to a semi-usable shape. A few things are still missing, such as moving the active uploads to the top and handling more than a total number of x queued uploads (at a certain level the progress bars will just disappear out of the Flash area, then magically appear as enough other items are finished).

Download Swoooosh.tar.bz2!

I’m looking for any response on this, and if anyone want to play around with it, please go ahead. It should be fairly simple to set up. I’ve included a brief description of the arguments it accepts below. Everything is released under a slightly modified MIT-based license, where the only change is that I’ve removed the need for keeping the copyright notice in anything that’s not the source code itself. Use it for anything you’d like, and if you make something useful, I’d be happy if you would contribute at patch back to me so that I could update the library itself.

You can see the application in action at my test installation. I’ll remove this test later, and be advised that the files actually will be transferred to my webserver. I’m just going to run rm -f * anyways, but if anyone breaks in and steals your precious uploaded files, you’re the one to blame.

== ARGUMENTS ==

The arguments to the flash file are provided in the flashVars attribute.

There are two required parameters:

destinationURL
The destination where all files are uploaded.

redirectWhenDoneURL
The URL the client is redirected to when all files have been uploaded.

Remember to urlencode both values.

Example:

<SEE THE INSTALL FILE IN THE ARCHIVE>

Optional parameters that are available is:

progressIndicatorColor: "#bfbfbf"
The color of the progress bar.

progressIndicatorBackgroundColor: "white"
The color of the empty bar before any progress has been made.

progressIndicatorWidth: 300
The width of the progress bar indicator.

uploadButtonText: "Click here to upload files!"
The text of the button the user has to click to start uploading files.


== COMPILING ==

To compile the SWF-file from the source code, download the Adobe Flex 3 SDK,
then run mxmlc against Swoooosh/Swoooosh.mxml:

mxmlc Swoooosh/Swoooosh.mxml


== CONTACT ==

Any and all comments are welcome. See the included LICENSE file for
information about usage. Short words: do whatever you want, just don't
claim you wrote it without contributing.

All patches are of course welcome.

UPDATE

As I’ve received many comments about the contents of test.php (the file that receives the post), here is the smallest version:

if (is_array($_FILES))
{
    foreach($_FILES as $file)
    {
        file_put_contents('directory_name_to_write_files_to/' . uniqid(), file_get_contents($file['tmp_name']));
    }
}

This will simply loop through all submitted files and write them to the temporary directory. As with other file uploads in PHP, you can access the original name of the file with the ‘name’ element in the $file array. DO NOT USE FILE NAME FROM ‘name’ WHEN WRITING THE FILE TO DISK. DOING THAT IS A VERY BAD IDEA, AS IT ALLOWS PEOPLE TO CREATE ANY FILE WITH ANY NAME (INCLUDING PHP-FILES WHICH CAN BE RUN IF THEY’RE AVAILABLE THROUGH THE WEB SERVER. YEP.). CAPS OFF.

Remember to make the directory you’re saving the files in WRITABLE for the process that writes the files (might be www-data or whatever user your webserver is running under). If you want to debug the response from the server regardless of what’s shown in the flash UI, use Wireshark to see the raw contents of packets and the conversions between the client and the server.