PHP|Tek and a Hackathon

A couple of weeks ago I had the pleasure of speaking at php|tek in Chicago. As usual there were a few great talks, a good crowd of new folk and a selection of established speakers all at the event and I had a great time. This year, there was one particular highlight that I wanted to share: the hackathon.

Continue reading

A Prototype API for Joind.In

Following the principle of "release early, release often", I put live a very early version of the v2 API for joind.in today (so that I can use it in another project!). I haven't updated the documentation yet but in case anyone was thinking of consuming data from joind.in, this at least gives you an idea of the direction of the project so I thought I'd share.

Things you need to know:

  • The service is an HTTP Web Service. Meaning it's RESTful apart from when it isn't
  • The endpoint is here: http://api.joind.in
  • You can fetch data about events and talks (read-only) at this point
  • Formats available are HTML or JSON. The service will guess from your accept header but you can override it with ?format=json or ?format=html
  • If you need more columns than you get by default, you can add ?verbose=yes to your request
  • Pagination is available, with parameters resultsperpage (default 20, set to zero for no limits) and start (default zero)
  • The service supports OAuth1.0a, which isn't useful at this point as we're read-only but it will come into play as we add functionality

Examples

Events list: http://api.joind.in/v2/events

Information about DPC11: http://api.joind.in/v2/events/603

Talks at DPC11: http://api.joind.in/v2/events/603/talks

Your Thoughts

Comments are welcome on this post. Bugs and feature requests should go to http://joindin.jira.com, read more about Joind.in and its community at http://joind.in/about

Git Tip: What Did I Just Merge?

As a lead on an open source project, I spend a lot of time merging awesome contributions from our community into our main repo on github. Sadly, some of them are slightly less awesome (rarely but it does happen) and I sometimes need to unpick what happened to understand the problem and give good feedback. Since the project is hosted on Github, this means having some git tricks up my sleeve, and I thought I'd share.

I have the main repo cloned onto my local machine. Before I do anything, I fetch and merge from the origin and then push back to it, so I know my repo is in sync with the github one. Then I fetch the branch I want to merge - usually one that we've got a pull request for. To see what's in the branch:

git log [branch] --not master

This is nice because it doesn't show what's in the master branch of this repo but missing from the incoming branch, it just shows me what's new on this branch.

I can diff and merge at this point, but more than once I've merged and then wondered what changes I have in my repo that aren't in the github one (this is where it is helpful to have fetched from the remote one first). I have the github repo mapped as "origin" as per the excellent documentation so I can just do:

git diff origin/master..HEAD

This shows me the differences that are in my current repo as compared to origin/master, which is the tip of the main repo shown at the version it was when I last fetched it. I particularly use this when I've merged someone's changes in for testing and am wondering quite what was supposed to happen - sometimes just reading the diff beforehand isn't enough, it's only when I get the code merged I realise something unexpected is happening!

Github To Jira Bug Migration Script

Recently I mentioned the github API and retrieving issues from it. This is because the joind.in project agreed to move its issue tracking from github to JIRA, since the issue tracker on github is far from feature complete. I migrated only our open issues, and comments (and the comments ended up a bit weirdly formatted on the other end but this was the best they could do). It was nothing pretty or clever but in case it's useful to someone else, here's the script:

Continue reading

Working with Branches in Git

Recently I've been doing more git than I ever intended to, working with the Joind.in codebase, contributing and managing contributions to that. I quickly realised that I needed to make changes on branches, and since I'm new to git, it took a while to figure some of this out. I'm pretty confident now* so I thought I'd share how I work with branches in git.

Available Branches and The Current Branch

This is the easy bit:

$ git branch
* api
  master
$

The entry with the star next to it is the current branch, so here you can see that I have branches "master" and "api" and I'm currently working on the "api" branch. If you only have one branch it will usually be called "master".

Creating and Changing Branches

My experience is with Subversion until now, and branching is really different in git (because it actually has branches rather than just copies, this is definitely a feature, but it is a different approach from how I had used them before). So you can switch your working copy around to look at different branches, which threw me a bit to begin with. To change branches, just checkout the one you want:

$ git checkout master
Switched to branch 'master'
$

If you actually wanted a new branch simply name it and ask checkout to create it if it doesn't exist, by using the -b switch:

$ git checkout -b demo
Switched to a new branch 'demo'
$

So now my branch command shows me this:

$ git branch
  api
* demo
  master
$

Pushing Branches

This is very much an optional step. Many of my branches are private branches - meaning that I branch on the development server, finish the feature at hand, and then merge the changes into my master branch without pushing the branch to anywhere else. To share changes with others though, I sometimes like to push my changes up to github - which is my "origin" remote on my repo. So to push the demo branch we just made, I would simply do:

$git push origin demo
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:lornajane/joind.in.git
 * [new branch]      demo -> demo
$

If you use "git push" on its own, it will push all branches which exist on both the local repo and the origin - but will not push any private branches unless you specify that it should.

Resources

The http://help.github.com site, Github's own documentation, is actually brilliant and has really helped me to get up to speed with working with my own code and contributions from others.

* The only problem I've had with code on github recently is that I merged totally the wrong changeset into the main project root. Which really isn't the fault of the source control system :)

WordPress Plugin for Joind.In

In case anyone thinks I've gone joind.in crazy after already writing about its import functionality this week, I really haven't. Its just that some months of pulling a few things together have finally bourne fruit and so I can actually write about them now they are done! The good news is that this includes a plugin for wordpress, which pulls data from the joind.in website. You can find its official page on the wordpress plugin directory here: http://wordpress.org/extend/plugins/joindin-sidebar-widget/

Plugin Features

At the moment the plugin can display one of two data sets: The hot events on joind.in; or the talks from an event on joind.in. You can change the title on the block, limit the maximum number of records returned, specify which event the talks should come from and also indicate if you'd like the order randomised. You can see the plugin in action on techPortal, where it is picking a few sessions at this year's Dutch PHP Conference to tempt you with!

Technical Information

I hadn't written a wordpress plugin before although I was very familiar with the joind.in API and how to work with it from PHP. The plugin was relatively easy to write, there are plenty of tutorials on the web and I didn't need to do anything particularly clever. I looked at a twitter plugin, tweetblend, which was a similar sort of idea in that it had settings, talked over an API, and stored data, and used that when I got stuck. My plugin is much simpler but that's OK (and probably makes it a good example for me next time I want to write one of these things!!)

The plugin creates a database table when it is activated (and drops it when deactivated) which caches the data pulled from joind.in for a few minutes. This helps avoid lots of users having to wait for the data to load and also hopefully stops the plugin from pushing too much load to the joind.in servers. Since there is no limit or pagination on the joind.in API, even though only a few records are shown the whole result is cached. This means that if you turn on the randomise then the cache is still useful! The "random" is a bit contrived in that it just picks elements out of the array that haven't been used but it looks fine to me.

Initially I was just going to put something together and upload it to the techportal site but I was persuaded that it would be a useful thing to share - so there it is. Comments and suggestions are all welcome - and if you are using it to publicise your event, let me know!

Importing Data to Joind.In

Update! This post is now outdated - the import functionality on joind.in has been replaced with a CSV import.

As a conference organiser I work extensively with the site joind.in, which allows attendees to comment on sessions at a conference. Recently the site has also started supporting sessions with both times and tracks, making it indispensable as a way of keeping track of all the sessions during an event. The only downside is entering all the data into it!! Joind.in does have some import functionality, which I recently rebuilt to reflect the timings and track changes, however this only accepts XML at present, so there is still some preparation work to get your data ready to import.

I know I'm not the only conference organiser who will have this problem so here's my step-by-step guide to getting talk information into joind.in, easily and quickly. For up-to-date documentation on the joind.in import process and the official data format description, see http://joind.in/about/import.

Set up Event and Tracks

Step one is to submit your event to joind.in. When it is approved by the administrators you will receive notification and it will appear publicly on the site (joind.in also supports private events, see the website for more information).

Once it is approved, make sure the timezone is set correctly by editing your event. For me this is Europe/Amsterdam, since I'm setting up data for the Dutch PHP Conference.

If you are going to include information about the different tracks, either rooms or subject tracks, you can set these up now (if not, then skip to the next section). When viewing an event, if you are logged in and have admin rights on that event, you will see an "Event Admin" box. The "Event Tracks" screen will let you add, edit and remove the tracks for your event.

Prepare Your Data

I had the talks in a spreadsheet and I found this was a good starting point. Each row is imported independently so each one needs to contain all the information about the session. My spreadsheet had the following columns:

  • Date
  • Time
  • Track (string name matching the track you set up earlier)
  • Type (either "Social Event", "Talk", "Keynote", or "Workshop")
  • Speaker
  • Session
  • Abstract

There was a lot of duplication here, for example lots of copied and pasted dates, but for each row to be evaluated separately, we need it to look like this. At this point I exported the spreadsheet to .csv format but joind.in currently only supports XML so I still had to built the format it could understand.

Generate the XML

I wrote a little script that processed my CSV file and spat out the XML that joind.in was expecting. There are a few pitfalls with this step:

  • I'm British, so my date formats assume dd/mm/yyyy
  • The import doesn't support languages (see http://github.com/enygma/joind.in/issues#issue/91)
  • The script contains a function copy/pasted out of the joind.in codebase to handle the timezones calculation (because I already had it working once, I just stole it)
  • The first row in the spreadsheet is assumed to contain titles and is ignored
  • The script has a hardcoded timezone in it for Europe/Amsterdam

By now you can guess this use-once script is a bit of a mess but in case it is useful I am uploading it here (if nothing else, I guess I might use it again!). I considered adding support for CSV files into joind.in itself (I'm a contributor) but I was short on time - if this would be useful to you or if you have any other comments on the process then add them here and I will do my best to reply!

Resources

  • Conversion script for CSV files to Joind.in XML format (use at your own peril!) csvToXml.txt - change the file extension to .php
  • My original spreadsheet, in case an example is helpful talks.csv - this is the data for DPC 2010

An iPhone App for Joind.in

Recently I've been doing some bits and pieces with the open sourced event feedback site joind.in, including some work on its API to facilitate development of an iphone app. As a conference attendee, speaker and organiser, I use this site a lot for the various events that I am involved with and its a great asset.

My boyfriend Kevin was thinking of developing an iphone app, mostly to find out more about the technology, and I suggested he take a look at the API for joind.in and consider building something on that. The joind.in project belongs to enygma, a.k.a. Chris Cornutt from phpdeveloper.org and he has the code available on github - so we grabbed it. The API wasn't previously used by much so we were able to tidy it up a bit and then consume it from the iphone to suit our needs. Chris has accepted my alterations to his existing project with grace - even when I've totally broken the live site with them!!

The joind.in site is a classic MVC setup and the API already existed within the application. It is implemented with a separate set of controllers for the various actions supported by the API, which all inherit from a controller which handles the output formats etc for the XML and JSON responses. It isn't the world's best API but its perfectly sufficient for the task at hand - I intend to write some examples for using it but until then you can read this post from Derick about how he used the joind.in API to pull in comments on his talks onto his own site.

The app itself has the core functionality of joind.in that an attendee would want in his pocket at an event. The events and their details are there, along with the talks at each event. Attendees can leave comments on the various talks and socials, and these can be browsed in the app as well. To give you a little taste of the app, here are some screenshots:

img_0023 img_0024 img_0025

If you have an iphone or ipod touch and you're attending an event any time soon, then download the app - its under "utilities" in the app store. Comments, suggestions, bug reports and feature requests are all gratefully received (no promises about fixing/implementing them but we'll do our best!). Our app went from submission to approved in 3 days which is very fast - thanks apple!

Stopping CodeIgniter from Escaping SQL

I'm adding some small features to the API for joind.in when I have a moment and this is my first experience of working with CodeIgniter. I've been getting increasingly impatient with its tendency to try to escape my SQL code for me - this is a really useful default feature but it seems to assume I don't know what I'm doing and so it puts backticks all over perfectly acceptable SQL code, very annoying!

One night when I was getting exasperated with it tangling up my SQL expressions, I tweeted my frustration in the hope that I was just missing something simple. A prompt reply from @damiangostomski told me that this was indeed the case ... I dug around for the API docs on codeigniter - it's an established framework and has a good reputation. I knew it would have API docs even though I hadn't used the framework before, and I found them:

$this->db->select() accepts an optional second parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks. This is useful if you need a compound select statement.

That quote is from this API docs page - so a big thankyou to Damian for replying to me on twitter, and to the good people at codeigniter for adding a useful option to their framework and documenting it so nicely :)

Contributing to Projects on GitHub

Recently I've been contributing to the code project behind joind.in, the event information and feedback site. I rely on joind.in a lot and after putting up with a frankly astonishing volume of feature requests from me, its owner Chris Cornutt very politely suggested that I might like to fix some of them myself. The project is hosted on github and I haven't traditionally been much of a git fan, but I wanted to contribute so I set off to work out how to begin.

Register on Github

To do anything useful I first needed to sign up for an account. Github has a range of accounts but I found that with one of their free accounts I would be able to get started and contribute to the project. This gives me a project space of my own and a user to tie all my activities to.

Set up SSH Key

In order to authenticate against the github servers, you need to set up an ssh key and give them your public key so they know you are you. You'll then need to tell git to use this key whenever it makes contact with the github servers. I do quite a bit with ssh and ssh keys myself so I was comfortable with this step. Even if you are totally new, its still pretty straightforward and they have a great howto on github itself which will help.

I had issues with git not picking up that it needed to use a non-standard ssh key, but I found the answers in this entry on the git website. In a nutshell, set up an ssh alias, set the key in there and then use the alias instead of the actual URL when giving the repo location to git. This now works like a charm for me.

Fork the Project

Now, github uses "fork" where I might choose to say "checkout" - fork in my world means something else completely. But in this case you're just making your own copy of the project repository. This is where you will commit your changes to and it retains its link with the original repository making it easy for anyone with commit access to that to pull in your changes. Patch files are nowhere to be seen, and although I was wary at first, this is project collaboration at its most painless, I'm impressed! Forking was relatively simple and again there was great documentation on the github site. In particular I recommend that you take the time to follow the bit about adding an alias for the "upstream" repository - this made committing my changes to the main joind.in repo really easy.

The forking instructions linked above also gave a description of how to actually use git, how to get my changes applied to my local repo, and how to push them to my remote repo on github itself.

Make a Pull Request

Once I'd fixed a few things, I was ready to push the code back to the main project so that Chris could consider it for inclusion. This is done by making a pull request from the main project page - you can add a comment about the changes you are supplying to help the maintainers to manage all the incoming patches.

Go Forth and Contribute

It was easier than I expected to get set up to contribute to a project using github, so find something you want to improve and/or be involved with, and do it. I began by fixing the docs for joind.in, which was a great place to start since it allowed me to make a useful contribution without touching the code in the first instance :)