Archive for August, 2013

Recording screencasts with Linux

I am recording some screencasts for a TDD training. I will tell you more about that later. For now, let me write how am I doing it for me to remember in the future.

For recording I am using Kazam, adding the ppa repository to my Ubuntu (apt-get install kazam). The "Audio source 1" is Built-in Audio Analog Stereo in my case. The "Encoder type" is "GStreamer - H264/MP4". Framerate is 10.

Once the screenshot is recorded I am using Kdenlive (apt-get install kdenlive) to cut parts I want to discard. Under the "Project" menu the item "Add Clip" let me load the recorded mp4. Then drag the the clip from the project view at the left hand side dropping it in the white region at the bottom, in the "Video 1" track.

After that "Render" (button) the video to produce another .mp4 file. Then open the .mp4 file with Audacity (apt-get install audacity).  Select a region where there is only noise and go to the "Effects" menu and choose the "Noise removal". Then click on "Get noise profile" in the pop up window. Right after that select the whole track and go again to "Noise removal", this time clicking "OK". Then export the file as .mp3.

Then  go back to Kdenlive and mute the audio, within the video track. There is a small icon for that at the left hand side, at the beginning of the track. Now "Add clip" again including the .mp3 file, to later drag it onto the "Audio 1" track. Finally "Render" again the video to product another .mp4 file.

Is not easy for at least thanks to this nice tools (Kazam, Audacity and Kdenlive) it's possible.

Configuring Targus keyboard

2013-08-17 13.15.10

Steve and Imo during a Code Kata

I've bought a new keyboard to use it with my laptop when I travel and also for coding dojos. It's small, cordless and with US layout which is what I use for coding. Very handy. It's a Targus AKB33US.

But it hasn't been easy to configure on my Ubuntu (I use lxde, known as lubuntu).

First the bluetooth... I needed to try it on Windows and also the help of my friends to get to know how to configure the bluetooth keyboard. I am using "Blueman" desktop app to configure it on Linux. And also a bluetooth-usb adapter. First you search for devices, and once the keyboard is found you select "Pair" from the right mouse button menu. Then it asks for a pin. Choose whatever you want (1234 for example) and click OK, and right after that introduce 1234 in the bluetooth keyboard.  Unfortunately Blueman doesn't tell you this but the Window's app did. Then also select "Trust" from the context menu. Then it should work.

The bad thing about Targus keyboard is that Delete and BackSpace keys are swapped and that is frustrating. This is the way to fix it on my machine.

  1. # reset key map:
  2. setxkbmap us
  3. # swap keys
  4. xmodmap -e "keysym Delete = BackSpace"
  5. xmodmap -e "keycode 22 = Delete"

Thanks to Steve and Imo for the help with the keyboard in our last code kata together.

Rich internet applications bring a powerful user experience. But in order to achieve that, they must be written totally different from traditional webs. The paradigm is totally different and so the architecture.  There is no "server side" as such. In some cases it's just a deployment site, where you have to browse in order to load the app. In some other cases you also need a centralized site to:

  • Initializing the application (deployment).
  • Storing data to be shared among instances/users (persistence).  
  • Connecting instances/users to each other (communication). 
Rather than calling it "server side", let's call it the hub. Its architecture must contemplate mainly:
  • Security
  • Concurrency
  • Scalability 
But everything else, lives in the application. The business domain, lives in the desktop application (which is inside the browser). There might be some security constraints related to the business that need to be tackled by the hub. In those cases, that particular bit of the business lives in the hub.

In order to be productive, the hub must understand JSON very well (assuming the data is sent/loaded via JSON) and serialize/deserialize it to objects automatically, without the need for hand-written mappings. This is one of the reasons why using Node.js in the backend makes sense, because you don't have to rewrite your objects in two different languages. Anyway, I am using C# and Python as the backend languages in two of my projects and the idea is the same.
If there are no particular security constraints, hub must accept data sent from the application and store it without objection.  The best way to avoid objections is using schemaless databases like Mongo.
Fortunately C# with ASP.Net is fantastic for JSON serialization/deserialization. For Python we've had to write code ourselves to get some automated conversion working.

As the hub is not the core, its functional requirements emerge from the incremental design. Such a design starts in the application side which eventually might need to send or retrieve some data to the hub. So my Cucumber scenarios, talk to JavaScript in the application side, specially if they are end to end.

- Adding a "comment" to a "merchant" (where merchant is an entity, and comment is a value object): is done by the application. The hub just stores the entity as sent by the app. It  might have a security check to make sure the logged user can make changes in the merchant.  If there is any additional specific security constraint saying that comments can be made only by certain users, then we need to check that in the hub too, for the sake of data consistency. But that validation would go into the security rule's code. The hub's "merchant service/repository" won't know anything about comments.
- When listing merchants, show only those from  a particular country: is done in the hub. If the security constraint says that logged users from the UK can only work with merchants from the UK, we can't send all the merchants to the app for it to filter them out. Instead, the hub makes sure that only the information that can be seen in the app is sent.

So for rich internet applications, the hub is there just to support the architecture. Don't start the implementation of a feature in the hub, because you don't know if you are going to need it.  Keep your hub layer as thin as possible,  adding complexity only when proven necessary.
This will be probably a  chapter in my upcoming book where I will explain it in more detail.

The rationale behind:
The reason why desktop applications provide much better user experience than server-side web apps, is because they react immediately to user input. They interact in real time. When the user asks the application to save some data, the app should immediately tell the user data is saved, even if it hasn't got confirmation from the hub. If the hub doesn't respond or informs about a problem storing the data, then the application should inform the user, handling that somehow. But it should not make the user wait. So the application must have all the business knowledge to implement this solution.
Imagine a desktop application, a text editor for example. Now imagine it runs in the browser. All you need the hub for, is to load the application. If you want to access your text documents from different machines, then you need a hub to store and serve that information. Why do you need any business logic in the hub? What for?
In a later version, we decide to implement a new feature: collaboration with other users. There might be security restrictions. You might not want to have all the users opening your documents, but just some. Then you go and add a filter in the hub.
So it's not that you design some kind of service in the hub first and then call it from the application. It's the other way around, like in TDD, I might write a call to a centralized service that doesn't exist yet, once I know I need it in my application and once I know how I want it to behave. Then I add that behavior in the hub if necessary.
Eventually if the interaction among users is very complex, the hub will become complex and will contain important business logic, but its design will emerge according to the needs of the application and not the other way around.