Documentation

Configuring private keys for ssh access

(On Mac OS X) – This assumes you have already downloaded your priviate keys to your desktop

There are 2 keys, one private and one public (this one has a .pub extension). Using Terminal, move your downloaded keys to your .ssh folder: for each file, type

mv Desktop/{name of key file} ~/.ssh/

Give your keys the proper names:


cd ~/.ssh/
mv {name of private key} id_rsa
mv {name of public key} id_rsa.pub

The private key should have readonly permissions:

chmod 400 ~/.ssh/id_rsa

So now you can login to the server. To simplify the process, you also create a text file ~/.ssh/config , where you can set three lines for ssh login info for your simple ssh use. To create the file, type:

vim ~/.ssh/config

Press ‘I’ (capital i) to go into ‘edit mode’, and then the following 3 lines (using the example of our Vasudeva Server servers:)

Host {server-name}.vasudevaserver.net
Port {port-number}
User {user-name}

Where {server-name} is the name of our server in lower case, {port-number} is the port we use to connect (for security reasons this is very often changed from the default port 22) and {user-name} is your user name to access the server. When you are finished, press escape (to exit edit mode) and then ‘ZZ’ (to exit and save changes)

After you have done that, you can try to log in using the command

ssh {server-name}.vasudevaserver.net

Another tip…

You can also create a simple alias for the server name by adding a line to your /etc/hosts file

{server-ip} {server-name} {server-name}.vasudevaserver.net

So a example for a hypothetical server antara.vasudevaserver.net located at ip address 127.0.0.1 would be

127.0.0.1 antara antara.vasudevaserver.net

This means that when accessing our servers, you can simply type

ssh {server-name}

without the vasudevaserver.net at the end.

Using git to develop sites (developers only)

We have recently moved our Drupal and WordPress repositories to git. We will also be putting our databases and static site filesystems there too, so we can generate test sites locally with a simple script. Here’s how to get started with developing sites:

Installing and configuring Git

  • Mac OS X: Go to download page and download the latest version.
  • On Windows: Go to download page and download Git-{version}-preview{release date}.exe

To configure git, there are some nice instructions here…

(VS Users: Aparajita has supplied in ticket SYSADM-610 to configure your git install: just download it, use Terminal to go to the directory where the script is, and type sh git_setup.sh. You will be asked for full name and email address.)

Using git

To create a version of the Drupal or wordpress repository on your local site, create a directory. Open Terminal, go to that directory and use:

git clone git@{servername}.vasudevaserver.net:drupal.git
or
git clone git@{servername}.vasudevaserver.net:wordpress.git

This will put the contents of the repository in that folder. Note: If the repository uses gitolite to control access via ssh, you must have the appropriate ssh keys on your machine to do this. In addition, you need to have these lines in your .ssh/config file


host gitolite
user git
hostname {server}.vasudevaserver.net
port {port_name}

To make changes to the repository, you have a few options:

  • Use the command line ๐Ÿ™‚
  • There is a git client called SmartGit which is free for non-commercial purposes. We are still in the initial stages of testing it, but right now it seems to have everything we need
  • There is a application called GitX which has a very nice interface that shows all commits and lets you commit to your local version of the repository. However (at the moment) you still need to use the command line to update your local filesystem from the server repository (using Terminal, go to the directory and type git pull) and then push your changes back to the server repository (git push)

Use cases for the JW Media Player

Playing an album list


<embed
src="http://www.srichinmoy.tv/c_/player/mediaplayer.swf"
width="300" height="380"
allowscriptaccess="always"
allowfullscreen="true"
flashvars="height=380&width=300&displayheight=0&showstop=true
&showicons=false&repeat=list&backcolor=0xCCCCFF
&frontcolor=0x000066&lightcolor=0x3333FF&screencolor=0x6666FF&thumbsinplaylist=false
&file=http://www.radiosrichinmoy.org/c_/audio/radio/102/playlist-102.xml"
>

gives you

As you can see, the playlist is stored in the same filesystem location as the music files (see sample playlist here).

The flashvars set all the tweakable aspects – color, positioning ect. You can view all available flashvars here on Jeroen Wijering’s site, and there is also a setup wizard where you can throw in various combinations and see how the code turns out

Playing a video – with youtube-like recommendations!


<embed
src="http://www.srichinmoy.tv/c_/player/mediaplayer.swf"
width="300"
height="220"
allowscriptaccess="always"
allowfullscreen="true"
flashvars="height=220&width=300
&file=http://www.srichinmoy.tv/c_/video/tv/260/260-1-2.mp4
&showicons=false&image=http://www.srichinmoy.tv/images/tv/260-1.jpg
&displayheight=200&searchbar=false
&recommendations=http://www.srichinmoy.tv/c_/player/recommendations/rec-lifevoices.xml"
/>

gives

When the video is finished, a list of recommended videos are displayed. Just like the playlists above, the recommendations are also generated from an xml file (see sample).

Note:

  • The front preview image and the recommendation images already exist on the site. The Flash Player allows them to be jpgs instead of having to convert to mp4
  • Again, the colour of the controlbar at the bottom can be modified by playing with the flashvars
  • The controlbar is on the bottom because we set the displayheight 20px less than the height. If they are the same there is a nicer effect where the controlbar is inline, but then it gets in the way of the recommendations if you want to include them

Custom playlist from different albums


<embed
src="http://www.srichinmoy.tv/c_/player/mediaplayer.swf"
width="300" height="200"
allowscriptaccess="always"
allowfullscreen="true"
flashvars="height=200&width=300&displayheight=0&showstop=true
&showicons=false&repeat=list&backcolor=0xCCCCFF
&frontcolor=0x000066&lightcolor=0x3333FF&screencolor=0x6666FF&thumbsinplaylist=true
&file=http://www.radiosrichinmoy.org/c_/audio/custom_playlists/playlist1.xml"
>

gives you

Here is the link to this playlist – note how we now have a ‘creator’ and ‘album’ tag added. We have also switched the thumbsinplaylist flashvar to true to include creator

Custom TV playlist


<embed
src="http://www.srichinmoy.tv/c_/player/mediaplayer.swf"
width="300" height="400"
allowscriptaccess="always"
allowfullscreen="true"
flashvars="height=400&width=300&displayheight=200&showstop=true
&showicons=true&repeat=list&backcolor=0xCCCCFF
&frontcolor=0x000066&lightcolor=0x3333FF&screencolor=0x6666FF&thumbsinplaylist=true
&file=http://www.srichinmoy.tv/c_/custom_playlists/playlist1.xml"
>

gives you

Here is the link to this playlist – the ‘image tag allows images to be displayed in listing, I just used images already on site.

Thanks to Jeroen Wijering for creating such a great player

Embedding Quicktime videos with preview picture

To embed a quicktime video, use the following code:

<object width="400" height="274">
<embed src="video.mp4" type="application/quicktime"
  wmode="transparent" width="400" height="274" autoplay="true">
</embed></object>

The autoplay argument determines whether the video plays or not immediately the page is loaded.

There are also other arguments you can add just like autoplay:

  • loop="true"/"false"โ€” the movie plays once or continuously.
  • controller="true"/"false" โ€” toggles the playback controls e.g. pause, fast forward, or mute.

The full range of options are available on the Apple Quicktime site:

http://www.apple.com/quicktime/tutorials/embed2.html

Preview Picture

With the above, what you get is basically a black box with a grey control bar below. Perhaps you would like to have a preview picture that loads the film when it is clicked on, just like Youtube embeds

The first thing you need to do is create the picture to be the same size as the video + 16px height to allow for the controllers. If you don’t do this the image gets squeezed/expanded to fit the video screen.

Then you need to save your image as something quicktime can deal with (eg .mp4). For this you need Quicktime Pro (costs $30) or for Mac you can use QTAmateur, available here:

http://www.mikeash.com/?page=software/qtamateur/index.html

Open up your image with either of these and then click File -> Export, and save to MPEG-4 (mp4), I think .mov also works

You can then use this code to embed

 <object width="400" height="274">
<embed src="images/preview_image.mp4" href="video.mp4" target="myself"
  type="application/quicktime" wmode="transparent" width="400" height="274"
  autoplay="false"></embed></object>

where preview_image.mp4 is your created image and video.mp4 is your video

Migrating Blogger blogs to WordPress, and setting up 301 redirects to ensure no links are broken

  1. Ok, basically if your blog is a new Blogger blog (after it was acquited by Google and Google usernames introduced) first step is to be sure have WordPress 2.2.

If you have an old version of WP, you can always upgrade:

http://codex.wordpress.org/Upgrading_WordPress_Extended

WordPress 2.1 allows you to upgrade from Old Blogger blogs, but not New ones.

  1. If your Blogger blog is hosted via FTP, go into the settings of the blogger blog and turn it into a blogspot blog (this change is reversible if anything goes wrong). Your blogger blog url will now be at (some name you choose).blogspot.com
  2. Go to your blog admin on your WP blog. Go to Manage -> Import and select the ‘New Blogger’ option. You will be asked for your blogspot url, blogger username and password. And hey presto, the job is done! (You might want to verify that before we go on)

Some recent users may have trouble signing into their Google account from WordPress due to the fact that Blogger changed their hostname API:

http://wordpress.org/support/topic/131952?replies=2

As you can see here, you just need to make a simple change in wp-admin/import/blogger.php file, changing www2.blogger.com in line 84 to www.blogger.com. This will be automatically fixed in WordPress 2.3.

  1. Ok, here is the time consuming job, setting up redirects from the old posts to the new, so that if someone clicks on a link to the old address they are automatically forwarded. Make sure you first are happy with the permalink structure on your WP blog (Go to Options -> Permalinks to change this)

Now open up some text editor to write the redirects. Suppose your old blogger blog was at

http://www.mysite.com/{old address}

and your new WP address is at

http://www.mysite.com/{new address}

basically all you do is type

redirect 301 /{old address} http://www.mysite.com/{new address}

301 is basically a code that tells Google that the item has permanently moved to the new address and you aren’t trying to pull any funny stuff on them. For each entry, type in the proper 301 redirect on a separate line. You can still get the old url address by looking at the blogspot blog.

You need to type in the full URL of the new address. Why? Basically, it allows you to redirect your posts to entries on a completely different site if you so choose!

Now you need to use an FTP client to go into the filesystem of where you host your blog. At root there should be a file called .htaccess; if not, create one (all files with . in front are system files and might be hidden unless you tell your FTP client to show hidden files). Then just copy and paste your redirects into this file, save, and try it out by typing in an old blogger address

  1. I’ve heard (although i don’t know the logic behind it) that its good to keep the FTP site going for a couple of days. So go to your Blogger blog and move it back to ftp, and then delete it after a few days.

Archetypes and ATContentTypes, part 1: The Archetype Schema

All the default types in Plone – file, image, folder – are part of the ATContentTypes product, and are examples of archetypes. Archetypes were integrated into Plone 2.1, and allow you to create content types easily by providing a range of readymade tools so you can generate edit forms without using any HTML.

An example will perhaps best explain how Archetypes works – lets look at the familiar ‘image’ type. The edit form of an Archetype is generated using a schema, and the schema for image can be found in Products/ATContentTypes/content/image.py: here we’ve taken out some of the code to focus on the essentials:

ATImageSchema = ATContentTypeSchema.copy() + Schema((
  ImageField('image',
        required=True,
                ....(lots of other stuff here, to do with image sizing and such).....
        validators = (('isNonEmptyFile', V_REQUIRED),
                      ('checkImageMaxSize', V_REQUIRED)),
        widget = ImageWidget(
                   #description = "Select the image to be added by
                                   clicking the 'Browse' button.",
                   #description_msgid = "help_image",
                   description = "",
                   label= "Image",
                   label_msgid = "label_image",
                   i18n_domain = "plone",
                   show_content_type = False,)),

  ), marshall=PrimaryFieldMarshaller()
  )

That’s all a bit of a mouthful, so we’ll break it up and isolate the essential parts:

ATImageSchema = ATContentTypeSchema.copy() + Schema((
     ImageField(

Every schema contains a collection of fields; in the edit form the short name is one field , the Title is another and so on… The reason we don’t see the title, id, or description in the above schema is they are already defined in ATContentSchema (they are common to all types); the first line of the code joins ATContentTypeSchema to the schema we are creating above.

For an image, there is only one extra field, the ImageField. Lets say we want another field to specify the camera the image was taken with; our schema will then look like:

ATImageSchema = ATContentTypeSchema.copy() + Schema((
      ImageField(   # all the stuff above
           ),

       StringField('camera',
                  required=1,
                  widget=TextAreaWidget(),),

   ), marshall=PrimaryFieldMarshaller()
       )

Archetypes provides many different kinds of field you can include – TextField, BooleanField (for yes/no values) ect. In plone.org there is a list of available Archetypes fields….

OK, lets look at the arguments of ImageField:

ImageField('image',
       required=True,
               ....(lots of other stuff here).....
       validators = (('isNonEmptyFile', V_REQUIRED),
                     ('checkImageMaxSize', V_REQUIRED)),
       widget = ImageWidget(
                                # whatever goes here we'll explain
                                # when we talk about widgets
        )),

 )

The first argument ‘image’ is the title of the field, the required=True puts the little red ‘required’ dot beside the title. Now, the next two are important:

  • validators: these are classes which check that whatever we’ve entered into the field satisfies a set of conditions, and it won’t accept it if it doesn’t. For example, ImageField calls instances of two validator classes: one of them makes sure the uploaded file isn’t empty, and the other rejects the uploaded file if it is too large. There is some readymade validators at Products/validation/validators, although quite often people have the need to add extra ones of their own.
  • widget: the widget is the graphical layout that the field will take; it defines how to render the field into HTML/XML. For example a StringWidget will set out a one-line box; a TextAreaWidget will set out a bigger box, like what is used for the Description. On plone.org you can see pictures of all the available Archetypes widgets ; it is very unlikely you will need to make your own. In many cases, the field type suggests what widget type to use: an ImageField will use an ImageWidget, for example.

The arguments of ImageWidget are quite straightforward:

widget = ImageWidget(
       #description = "Select the image to be added by clicking the 'Browse' button.",
       #description_msgid = "help_image",
       description = "",
       label= "Image",
       label_msgid = "label_image",
       i18n_domain = "plone",
       show_content_type = False,)),

The _msgid label is used by the internationalization (i18n) mechanism to generate translations in other languages.

Ok, one final thing to deal with, the marshaller, this makes Archetype fields understandable to clients such as WebDAV. As you can see above, the schema took two arguments, the field and the marshaller.

Schema (    (ImageField( all the stuff we discussed ),),
                                    marshall=PrimaryFieldMarshaller()
     )

PrimaryFieldMarshaller is the most common marshaller used, apparently.

Ok, so that’s the first part of my ATContentTypes exploration; the second part will deal with the question I first asked when I saw a type schema: how does all this called by a template and end up on our screens?

Good Documentation – some musings

A ‘speed is better than perfection’ philosophy might be applied to many areas of life, but documentation is not one of them. Unfortunately the standard of documentation needed so that 90% of people can follow it is, well, 90% perfect.

It actually doesnt take all that much longer to write good documentation once you sit back and think for a moment about what it was like when you had to perform the task for the first time yourself. Its no coincidence that much of the better documentation written on this site comes from things the documenter just recently found out how to do.

Documentation doesnt have to be austere, the tone can be warm and conversational, especially if the user is not all that au fait with computers.

However the most important things are still the obvious ones: check after each sentence and see if if you have relayed to the user exactly what he needs to do (and where to find things – screenshots can be of enormous help) and lastly, get your completely computer illiterate auntie/uncle/person-dragged-in-off-the-street to try using your documentation!

Error reporting and screenshots

Here is a very good article on bug reporting, discovered by Atmasamarpan:

http://www.chiark.greenend.org.uk/~sgtatham/bugs.html

It certainly helped me sympathise with poor developers and curb my linguistic excesses when reporting problems.

Whenever possible, screenshots really help to pinpoint the problem by making the developer or Plone admin see what you’re seeing. Below are some instructions for screenshots for both Windows and Mac…..

1. Windows

You can capture the screen and paste it into any graphics program: by pressing the ‘print screen button’ (up there somewhere to the right of F12). This appears to do nothing when you press it, but the screen is then stored in memory. One can then open any graphics program like Photoshop or even Microsoft Paint and paste in the image. (For Photoshop one should first create a new document)

If you dont want to save the whole screen, pressing ‘Alt’ and ‘Print Screen’ together will capture only the window you have open.

This is a slightly clumsy way to do it; there are freeware programs out there which do the job much quicker (and which personally I’m happy enough with, for example MWSnap) but I understand the words ‘windows’ + ‘freeware’ together can be enough to send a chill up the stoutest of spines……

2. Mac

The keyboard shortcuts are:

Apple-Shift-3: Capture the entire screen
Apple-Shift-4: Capture a self-selected portion of the screen
Apple-Shift-4 then Space: Capture a window

Both options automatically create an image for you named "Picture 1.png" on your desktop.

There is also an application named "Grab" in the Utilities folder which allows screen captures with more options. Grabs features can also be accessed from the "File" menu within the application Preview.

Further in-depth information on screen captures in Mac OSX 10.4 can be found here: http://www.macworld.com/weblogs/macgems/2005/09/tigerscreenshots/index.php

(thanks to John-Paul for the info)

Creating proper internal links

Images

Images are the same: .. image:: /images/vasudevaserver.gif

This is bad: /images/vasudevaserver.gif/

The bottom line is: Never add a trailing slash!

Also, please make sure images always have the type of file at the end (.jpg or .gif)

vasudevaserver