Archive for the ‘GitHub’ Category

h1

My latest project – CVMe

December 21, 2010

Well its been a good little while since I’ve written anything here for a number of reason.

Well I’m out of the cave I spent the last year of so in a thought it was time to write about my latest project CVMe.

What is CVMe?
I wanted an application that made it easy for me to add content to my CV and allow me to export it just as easily. As things progressed I noticed that I was getting unexpected benefits from the system such as being able to identify the skills I use most often and what roles I work in the most. This lead me to creating the dashboard area of the application. This area provides users with profile summary information and notification to help guide the user through the process of building up their profile.

I use CVMe to centralise my CV and allow me get a up to date copy of it quick and easily. The application has a alerts system that alerts me when an entry type has not been updated period of time (a period which can be defined by myself). There is also a notification system that can be customised and which displays notifications on the dashboard if the application thinks I should update a specific entry type. This helps to indicate to the user when there profile is at a stage where it can be exported as there is no point in exporting a CV with just personal details.

Why create CVMe?
In my profession I have to keep my CV up to date. This has proven to be somewhat of a chore for a number of reasons the main reason being that I tend to forget to update my CV unless I really need to. Which generally ends up in me scratching my head and trying to remember what the hell I actually did when I was at X or doing Y.

Where is it now?
There is the web application which is a the main online application which stores your information online and in the near future will allow people to retrieve their profile via a third party plugin. The other version is open source and can be download and used for personal and non-profit use.

h1

Salad, adding cucumber

October 9, 2009

Well I was hoping to get this post published a month or so ago but better late than never.

As some of you may know, I’ve taken some time to learn Ruby & Rails over the past few months and have been using RSpec & Cucumber quite a bit to roll out new functionality.

It soon came to my attention that though Cucumber is a wonderful tool it would be nice to be able to manage scenarios and stories a lot easier and give stack holders a front-end to which they can get a view of what features are to be implemented and how what steps are required to complete a story.

This is where Salad was born, inspired by my latest blog series ‘Jumping on the Rails‘ I decided to make a small rails app that allows users to import and create features for a specific project.

My aim is to integrate the functionality of cucumber along with the other major project management tool (BaseCamp, LightHouse, etc) giving stakeholders and developers alike an easy way to manage, prioritise and understand the stories needed to complete a given scenario.

Functionality

  • Create project features
  • Upload project features
  • Manage features, stories & steps
  • Link stories to a project
  • Link steps to a story

Future Features

  • Sychronise feature, stories & steps
  • Link a feature to a milestone
  • Estimate feature implementation

Over the next few weeks I’ll hopefully have time to improve the general layout of the application, making it more visually pleasing but for the moment it has all the basic functionality necessary to manage your projects new & present features.

Salad can be found here and is easy to install, as outlined below.

Installation

  1. Download from here.
  2. cd to the applications directory
  3. Run script/server
  4. Point your browser to http://localhost:3000/projects
  5. Enjoy

Comments and contributions are more than welcome, my main goal is to provide a simple application that can help bridge the gap between stakeholders and developers.

h1

Changes in Chatterl

July 23, 2009

I haven’t worked on Chatterl for a few months but there are some fundemental changes that had been made back in March, apologies for the slow update but honestly I haven’t had much time with learning Rails & freelance work.

Summary

Well the main changes in chatterl are the following:

  • Message storage
  • Registration
  • Introduction of unit tests
  • CWIGA now RESTFUL
  • API calls

I’ll go over each section, highlighting the main changes & who it affects Chatterl as a whole.

Meet CWIGA

After implementing Chatterl‘s basic functionality (see chatterl post). The next step was to create to implement CWIGA, Chatterl Web Interface Gateway API. With this new module Chatterl is able to be interacted with purely via HTTP. The first implementation was rough, the original source can be found here, though it allowed me to get a decent understanding of mochiweb at the time helped me produce this article. After implementing unit tests to cover the project as a whole I felt comfortable to make a few fundamental changes to CWIGA’s API and requests to Chatterl.

Registration

I’ve added very basic registration functionality to Chatterl, allowing users to register to the system, giving them the ability to retrieve archived messages & later creation of their own chat groups. In hindsight I’d like to move this functionality to the front-end (which I’ll more than likely be in Rails).

Message Storage

Again this was more experimental on my part and something I would like to move over to couchDB when I get the chance, for the moment, Chatterluses mnesia to store users messages when they are not logged into the system.

Added test cases

One of the main issues I’ve been having with Sinan more than anything else, was seperating my tests from the source code. I really hated the idea of having test & implementation code mixed in, so I stayed away from any kind of real testing until I got my head around it. Thanks to Kev Smith‘s own code, I finally got my head around EUnit, which I posted a short post on here.

Before I was comfortable with implementing any more functionality I had set out to cover as much of Chatterl‘s code as possible. In doing so I uncovered a number of silly little bugs (oversights) in the coding logics & made the necessary changes.

General cleanup

The way chatterl is called has also been improved, instead of having to go into erl you can simple run ./start-server.sh within the cd _build/development/apps/chatterl-0.1.2.0/ directory. This will start up all the processes need to use chatterl.

CWIGA is setup to listen on port 9000, so you can call it using curl or via a browser of your choice. It accepts XML & JSON requests & has been made more RESTful.

Hopefully in the near future I’ll have time to rewrite the code base and improve on the basic functionality but for the meantime I hope this helps others as much as its been an experience for me.

h1

Lighting up the tunnErl part 7 – Chatterl meets Nitrogen

March 13, 2009

Well it’s been a has been a while since I have posted a blog, mainly down to the amount of time I’ve been spending playing around with Chatterl & Nitrogen. I have come a way since first playing around with Erlang I decided a few months ago to make Chatterl my main personal project. I played around with BeepBeep around the same time as Nitrogen, for one reason or another I picked up Nitrogen quite quickly and decided to run with that as Chatterl‘s prototype frontend.

I have to admit though I have never really been a fan of event driven frameworks, especially those that mask mark up language but after a day or two of messing around with Nitrogen I found it quite a pleasant experience.

The learning curve can be somewhat steep as the documentation is not as good as it could be, I also have issues with having the root directory starting with /web/, so the admin directory would be http://blah.com/web/admin, hopefully this will be changed in the near future. Besides those minor gripes Nitrogen is starting off as a nice framework.

Well I wish I had some time to run through a little tutorial, for the moment the best I can do is show you how I implemented some of the functionality need for Chatterl‘s front-end. Below is a list of features I’ll be concentration on:

  • Main body
  • Validate Message
  • Client Panel
  • Message Panel
  • Groups Body
  • Users Panel

We’re working with Chatterl‘s Web Interface API (CWIGA) which works on 127.0.0.1:9000, I prefer JSON so I’ve only implemented functionality to handle this. The implementation code is very similar to that I’ve written about previous so I wont waste bytes (see Twitterl), I’ll just say that we need to connect to CWIGA via HTTP.

For the curious, the code can be found the functionality needed to interact with Chatterl can be found in the file chatterl_cwiga_handler.erl. The actual calls are defined within Chatterl interface.

Now we have the basics for interacting with Chatterl over HTTP, lets have a look at how this all ties in with working with Nitrogen. I won’t go over how Nitrogen works as that part is pretty well documented in a few placed (Nitrogen, Jón Grétar) but I will explain the functionality I’ve implemented for chatterl_nitrogen.

Main body
body() ->
ChatBody = [ #panel { id=messageBodyPanel} ],
Left = [ #panel
{ id=leftPanel,body=[client_panel(),message_panel(),
[#panel { id=groupsPanel, body=[groups_body()]}],users_panel()] } ],
Right = [ #panel { id=rightPanel, body=[ChatBody] } ],
Container = #panel { id=containerPanel, body=[Left,Right] },
validate_message(),
wf:render(Container).

Ok now what the hell is all that??? Well it doesn’t look like it but this is how Nitrogen renders HTML, we structure our HTML using Nitrogen‘s elements & actions which in turns renders our pages for us.

Firstly we define the containers needed to organise the chat window, Allowing me to have the chat box on the right, whilst having all the other features (message box, groups list, etc) on the left. As you may of already guessed the element #panel represents a div with XHTML, id’s act as you would expect & can be manipulated with CSS as usual.

Validate Message
validate_message() ->
wf:wire(messageTextBox, messageTextBox, #validate
{ validators=[
#is_required { text="You forgot to submit a message." },
#min_length { length=2, text="Title must be at least 2 characters long." }]}).

Here we use the method wf:wire which basically connects an element to another, so a input box could be ‘wired’ to a submit button. In this case we want to make sure that we validation only when the messageTextBox has data, validate it. The next two lines do exactly that, firstly #is_required makes sure that we actually have a value, whilst #min_length gives a validation error if it has not been adhered to. The response are triggered by AJAX using JQuery, so as soon as an event is caught it is handled asynchronously.

Client Panel
client_panel() ->
[#panel { id=clientPanel, body=[get_client_panel()]}].

This panel is pretty straight forward, it simply defines a DIV elements which calls get_client_panel/0 which in turn determine what actions are needed. This method will be explained better shortly.

Message Panel
message_panel() ->
[#panel { id=messagePanel, body=[
#label { id=messageLabel, text="Message:" },
#textbox { id=messageTextBox, text="", style="width: 100px;", postback=group_message}
]}].

This is the the DIV element that is used by the user to send messages to chatterl. We have a couple of things we have encountered yet, our postback, which will be explained shortly & two elements (#label & #textbox). Pretty straight forward right. What about this postback thingie? Well postbacks are in fact our AJAX calls, allowing the user to interact with the systems backend seemlessly. We’ll see how these are handled in the Events section.

Groups Body
groups_body() ->
SelectedGroup = wf:q(groupsDropDown),
#panel { class=groupsPanel, body=[
#h1 { text="Groups" },
#label { text="Select a group to join:" },
#dropdown { id=groupsDropDown, value=SelectedGroup,
options = [ #option { value=Group, text=Group }
|| Group <- chatterl_interface:get_groups()],
postback=join_group} ] }.

Here we have an panel which allows users to select a group to join, we again use a postback to handle our AJAX call & use the chatterl_interface module to retrieve a list of groups from Chatterl.

Users Panel
users_panel() ->
SelectedUser = wf:q(usersDropDown),
[#panel { id=usersPanel, body=[
#label { id=usersLabel, text="Select a user:" },
#dropdown { id=usersDropDown, value=SelectedUser,
options = [ #option { value=User, text=User }
|| User <- chatterl_interface:get_users()] } ]}].

This should be pretty self explanatory as it is more aless the same functionality as groups_body/0.

Get client Panel
get_client_panel() ->
case wf:session(client) of
undefined ->
wf:wire(groupsPanel, #hide {}),
wf:wire(messagePanel, #hide {}),
client_login_panel();
Client ->
wf:comet(fun() -> update_status("messages",1000) end),
wf:wire(groupsPanel, #show {}),
wf:wire(messagePanel, #show {}),
client_logout_panel(Client)
end.

Well this method basically checks to see if a user is connected if they are then we display the messagePanel, groupsPanel along with groupsJoinedPanel. We allow the messages panel to update, giving the user the most up to date messages from Chatterl. We lastly set the client_panel to client_logout_panel/1, which we’ll have a look at shortly, this method basically allows the user to disconnect once they have connected successfully to Chatterl.

Client login Panel
client_login_panel() ->
#panel { id=loginPanel,
body=[
#label { text="Client name:" },
#textbox { id=userNameTextBox, text="", style="width: 100px;", html_encode=true, postback=connect }]}.

Client logout panel
client_logout_panel(Client) ->
#panel { id=logoutPanel,
body=[
#inplace_textbox { id=userNameTextBox, text=Client, html_encode=true, start_mode=view },
#button { id=theButton, text="Disconnect", postback=disconnect }]}.

This method is pretty much the same the the client_login_panel/0, with 1 small change, instead of connecting to Chatterl we want to disconnect. The principle is still the same, create an event, passing the postback (disconnect).
which in turn disconnects the user from Chatterl.

Update status
update_status(Type,Timeout) ->
process_flag(trap_exit, true),
case Type of
undefined -> ok;
"messages" -> loop_messages(Timeout);
{"general",StatusType} -> loop_status(Timeout,StatusType);
_ -> io:format("Unknown loop type: ~s",[Type])
end,
wf:comet_flush(),
update_status(Type,Timeout).

Events

Connect Event
event(connect) ->
[Client] = wf:q(userNameTextBox),
case chatterl_interface:connect(Client) of
{ok,Message} ->
wf:flash(Message),
wf:session(client,Client),
wf:update(clientPanel, #panel { body=[get_client_panel()] });
{error,Error} -> wf:wire(#alert { text=Error })
end.

Above is the actually postback method call event(connect) which utilises chatterl_interface:connect/1 allowing us to make a connection to Chatterl directly. If the request is successful we create a new session wf:session(client,Client) & update our clientPanel so that they user can logout as you would expect.We do this by using the wf:update/2 method that dynamically changes XHTML elements on the fly.

Disconnect Event
event(disconnect) ->
case chatterl_interface:disconnect(wf:session(client)) of
{ok,Message} ->
wf:flash(Message),
wf:session(client,undefined),
wf:session(selectedGroup,undefined),
wf:update(messageBodyPanel, #panel { body=[] }),
wf:update(clientPanel, #panel { body=[get_client_panel()] }); % Should redirect here.
{error,Error} ->
wf:wire(#alert { text=Error })
end.

Well there’s the disconnect event, nothing to dramatic here, simply unregister the client & selectedGroup cookies& update the page so that the client_panel is set back to its default.

h1

Chatterl – Erlang based chat engine

January 1, 2009

Well I’ve been hacking around for the past few months trying to get my head around Erlang. After playing around with Twitterl I decided I should start a new project (OTP based) which I have a decent understanding of & have wanted to work on for some time. A chat system was the first thing that came to mind, I’ve worked on and built a few in my time and thought Erlang would be a good language to build a chat engine from scratch.

For those not interested in the long description and prefer to dive in source, you can find a copy of the project at github.

Description

A chat system that can be housed over a number of nodes and track clients over varying devices, at the time of the writing the system works over multiple nodes and is able to do the basics (connect to a group, send message to other clients and connected groups).

The main focus of this project is to create a chat system that is highly reliable as well as scaleable. Other developers will be able to create add-on modules that are able to interact with chatterl and further enhance the functionality of chatterl and the chatterl clients experience.

As mentioned the system is OTP based, of which it uses Sinan to maintain its builds.

Installing Chatterl

At the moment of this writing Chatterl is still in alpha so their is no real release at the moment, to get it running you will need to do the following:

git-clone git://github.com/baphled/chatterl.git &&
cd chatterl &&
sinan doc && 
sinan dist &&
cd _/build/development/tar &&
sudo faxien install-release chatterl-0.1.0.2.tar.gz

The above presumes that you have Sinan configured & installed, if you haven’t refer to erlware.
You will need to change to cookie & name values to something else, doing so should drop you into the erlang shell & ready to run the Chatterl application. To run a client on a different machine you will need to do the above if (making sure that the -sname is not the same as any other connected nodes & that the cookie is the same) if connecting on the same box simply cd to the ebin directory and run the following command:

erl -name bar -setcookie abc

From here you will need to make sure that they nodes can connect via:

net_adm:ping(foo@bar.net).

Where foo is the node name & bar.net is the tld of the node box (indicated within yout hosts file or dns server).
Once you receive the infamous pong response you are ready to roll.

Features

  • Client login/logout to Chatterl.
  • List Chatterl groups.
  • List Chatterl users.
  • Login/logout of a chatterl group.
  • Send message to a group and other clients.

Future Features

  • Centralised Error logging and data storage.
  • Client customisable routines (able to poll RSS feeds, twitter, FB and the such like).
  • Better handling of errors.
  • User registration.
  • FB Connect.
  • Chat bots (AIML based).
  • Web interface/API.
  • Chat modules handler(banning, censorship, chatbots).

Useage

Starting the server
Chatterl server runs as an OTP application and uses a supervisor to manage it (in later versions there will be options to spawn multiple servers, allowing for a more fault tolerant chat system). To start up the server you simply need to run the following command:

application:start(chatterl).

Which will initialise the server allowing clients to connect and groups to be created. Groups can be created on differing nodes as long as the node can communicate with the chatterl_serv.

Starting a group
Chatterl groups can be started on any node that can communicate with the server, this allows the user to create a number of groups on varying nodes, helping with general organisation as well a performance and reliablity.

A group can be initialised by calling the command:

chatterl_serv:create("room","description").

which will spawn a group process which users can connect to.

Connection to chatterl
At the time of this writing chatterl_clients can only spawn a client per node, this will later be changed once the web interface has been fully implemented, possibly to a refactoring the client to a parameterised module.
For the moment node users must follow the basic OTP configurations (same cookie, valid DNS name, etc). Creating a connection to the server is done by using the following command.

chatter_client:start(UserName).

This will initialise a user and connect them to chatterl_serv (must be done before users can join a group or communicate with other chatterl users).

Disconnecting from chatterl
Chatterl clients can simply disconnect from chatterl by issuing the following command:

chatterl_client:stop().

This will disconnect the user from all the groups they are currently connected to as well as the actual Chatterl server.

Joining a group
This can be done by using the following command:

chatterl_client:join(GroupName).

If the group exists the user is able to join the group allowing them to send message to the room.

Dropping from a group
This is as simple as connection, simply supply the following command:

chatterl_client:drop(GroupName).

This will send a message to the group, which will handle the termination.

Sending group message

chatterl_client:send_msg(GroupName,Message).

GroupName being the name of the group the client is connected to, Message being the message that you want to send to the receiving client. If the message is sent successfully all users connected to the group will receive the message.

Sending a private message
This allows a Chatterl client to send a private message to another client, by executing the following:

chatterl_client:private_msg(RecipientName,Message).

If the message is sent successfully then the sender will receive follow message:

{ok,msg_sent}

in turn sending the message to the receipients node.

h1

Zend_PHPUnit_Fixtures uploaded to GitHub

December 4, 2008

Well I’ve been working on this project (Zend PHPUnit Fixtures) along with a few collegues over the past few months, It was my intension to submit it to Zend some point in the new year but thought I’d put it out in the wild for others to pick at.

Well I use TDD (PHPUnit is my friend) on a daily basis within ZendFramework and soon found it cumbersome to create test data (fixtures) ending up in huge test cases with more test data setup than actual assertions, this matched up with the fact that I hate integrating DB into my tests (mainly because the tables would still contain old test data & fail depending on whether the data was added in previous tests or not) So I decided to do some digging, the best solution seemed to be to create a fixture handling system that plugs into ZendFramework, leaving myself and others with more time actually testing and less time building up test data and removing fixtures from a database (which can be near impossible when it comes to automated testing).

With this realisation I decided to create my own which I’ve reversed engineered from CakePHP. When I have the time (hopefully over the holidays) I’ll go into how the mini framework can be used. For now I’ll just describe the features or each class and what they are for:-

PHPUnit_Fixtures

Basic fixture handler, used for creating test data that does not interact with a DB. With this object we are able to create basic fixtures that we can use for dummy data with our test cases. Each piece of test data can have an alias (‘ALIAS’) with the aliases name as the value, doing so will allow us to use the PHPUnit_Fixtures::find($aliasName) which will retrieve the desired fixture.

PHPUnit_Fixtures_DB

Has the same functionality as PHPUnit_Fixtures but used specifically for DB centric tests, DB test data will be added to our ‘_test’ DB, and cleaned up (truncated) on each test case, to make sure that we have the expected data.

PHPUnit_Fixtures_DynamicDB

Has the same functionality as PHPUnit_Fixture_DB, with the added functionality of being able to create tables setup my MySQL Workbench. With an child object of this class we are able to specify retrieving all schema or a specific on (denoted by the schema table name).

DevelopmentHandler

Used to handle our development environments, there are times when we want to quickly place test data on our staging DB for functionality testing and the such like, this class along with one of our PHPUnit_Fixtures, will easily allow us to populate this environment with the data we have been using for our unit tests, making it quicker to migrate test data from one place to another.

You can find the project at GitHub, If anyones interested in adding to this project or have any comments/questions drop me a line.

h1

Finally got myself on Github

December 1, 2008

Well after a while of staying away from learning yet another versioning system, I’ve fallen in line, I decided last night that it would be a good idea to put all my Erlang based work up on github.  I was hoping to use TDD with this project but that will have to be looked at later (TDD & Erlang is a bit much for me ATM).

I’ve submitted my second attempt at an Twitter client (Twitterl), which I’ll be using with other projects, for now feel free to have a look & possibly take part. Over time I’ll gradually add more functionality to the system an blog my experiences as I go along.