portrait

Masud Khokhar

Digital strategy, Innovation and Code Monkeyism

Easter cupcakes anyone? I couldn’t resist so the missing one has been consumed already :)

Easter cupcakes anyone? I couldn’t resist so the missing one has been consumed already :)

Apr 13, 2014

Hydra as a Digital Asset Management System

We are currently looking for a solution to store the different forms of digital objects/assets that are generated by various researchers/academics/departments/faculties at Lancaster University. The traditional repository model does not feel like it is best suited to accommodate the ever expanding range of digital assets. We are talking about Research Data, Digitised objects, Open Educational Resources, Video and Audio files, Software packages, etc. So we started looking into other appropriate solutions.

From my previous experience, I remember Fedora was designed for this very purpose. The hint is in the name, Flexible Extensible Digital Object Repository Architecture. We are really keen on the flexible and extensible aspects. However, experience has also taught me that Fedora can become very complex to manage very quickly. Something, we at Lancaster, can’t afford at this time with our limited resources.

At the same time, we are also looking into two wrappers/solutions on top of Fedora, aptly named as Hydra and Islandora. Hydra is based on Rails (Ruby) whereas Islandora is based on Drupal (Php). Considering we have expertise in neither (we are primarily a Django/Python shop), we are open to both solutions, or something else completely. Between Hydra and Islandora, however, it seems like Hydra has a more mature user base, development partners, and more major players involved in supporting it. At the moment, Hull and LSE are development partners for Hydra in the UK, which is also a plus point.

Hull has very kindly agreed to talk to us about Hydra in a few days time. Some of us will go there and speak to them about what Hydra can do for Lancaster, and hopefully take it from there. Not to forget, we are also an Alma customer and Alma Digital (Alma-D) is also evolving considerably and may provide a solution in the future.

Mar 24, 2014

Sencha Touch 2.3, hasMany association, and duplication of store entries

If you are working with Sencha Touch 2.3 (ST from this point onwards), then you may have developed a love/hate relationship with the platform like myself. Some aspects of the framework are great, whereas some others are sadly atrocious. The lack of coherent document, and the wide variety of conflicting information also does not help.

In a recent incident, I am using a hasMany association in the model and found a peculiar issue happening. To give you background of the issue, I have a model called Session which has a hasMany relationship with another model called Participant. Both models below:

The Session model:

    Ext.define('MyApp.model.Session', {
    extend: 'Ext.data.Model',

    requires: ['MyApp.model.Participant'],

    config: {

        idProperty: 'id',
        fields: [
            { name: 'id', type: 'int' },
            { name: 'number', type: 'string' },
            { name: 'time', type: 'string' },
            { name: 'date', type: 'string' },
            { name: 'day', type: 'string' },
            { name: 'title', type: 'string' },
            { name: 'abstract', type: 'string' },
            { name: 'track', type: 'string' },
            { name: 'room', type: 'string' },
            { name: 'building', type: 'string' }
        ],
        hasMany:
        {
            model: 'MyApp.model.Participant',
            name: 'participants',
            primaryKey: 'id',
            foreignKey: 'session_id',
            associationKey: 'participants'
        }
    }
});

The Participant model:

    Ext.define('MyApp.model.Participant', {
    extend: 'Ext.data.Model',

    config: {

        idProperty: 'id',

        fields: [
            { name: 'id', type: 'int' },
            { name: 'firstname', type: 'string' },
            { name: 'lastname', type: 'string' },
            { name: 'job_title', type: 'string' },
            { name: 'company', type: 'string' },
            { name: 'country', type: 'string' },
            { name: 'email', type: 'string' },
            { name: 'session_id', type: 'string' }
        ]
    }
});

The issue starts when you want to filter the Sessions store and show the changes immediately to the list that the store values are attached with.

The sessions store is as follows:

Ext.define('MyApp.store.Sessions', {
    extend: 'Ext.data.Store',

    config: {

        autoLoad: true,
        model: 'MyApp.model.Session',
        grouper: {
            groupFn: function (record) {
                return record.get('day') + " " + record.get('date');
            },
            sortProperty: 'id'
        },

        proxy: {
            type: 'ajax',
            url: 'resources/data/SessionsData.json',
            reader: {
                type: 'json',
                rootProperty: 'sessions'
            }
        }
    }
});
    

Suppose we want to do an anyMatch in the Sessions store. We have a search field introduced and here is the controller snippet to work with it.

        doSessionSearch: function(searchBox) {
            // Grab a reference to the Sessions store
            var mySessionsStore = Ext.getStore('Sessions');
            
            // Grab the current search string in the search box
            var searchValue = searchBox.getValue();
            
            // Generate a query out of the search string
            var query = new RegExp(searchValue, "i");
            
            // Clear all existing filters on the store
            mySessionsStore.clearFilter();
            
            // Apply the new filter
            mySessionsStore.filter('title', searchValue, true);
    }

However, this will result in your hasMany model duplicating the values. To avoid it, you will need to attach a listener to the calling store, which will clear values in the hasMany store. In our case, this means associating a listener to the Sessions store and clearing the entries for the Participants store.

The revised Sessions store will look like:

    Ext.define('MyApp.store.Sessions', {
    extend: 'Ext.data.Store',

    config: {

        autoLoad: true,
        model: 'MyApp.model.Session',
        grouper: {
            groupFn: function (record) {
                return record.get('day') + " " + record.get('date');
            },
            sortProperty: 'id'
        },

        listeners: {
            beforeload: function(operation) {
                for(var i=0; i<this.data.all.length; i++) {
                    if (this.data.all[i].participantsStore) {
                        this.data.all[i].participantsStore.removeAll();
                    }
                }
            }
        },

        proxy: {
            type: 'ajax',
            url: 'resources/data/SessionsData.json',
            reader: {
                type: 'json',
                rootProperty: 'sessions'
            }
        }
    }
});

I would have never reached this solution without the help provided by Martin Willitts in his original post over here.

Mar 21, 2014
Had loads of fun at the GOTO project sprint. On a different note, I love Sublime Text :)

Had loads of fun at the GOTO project sprint. On a different note, I love Sublime Text :)

Dec 25, 2012

DNS configuration - Ubuntu Server with Static IP

I was trying to install Ubuntu Server 12.10 on my shiny new HP ProLiant Microserver. The installation went smoothly with a couple of hiccups that are as follows:

First of all, beware of the tiny grey rectangle that shows at the bottom left of your screen when you boot from a USB disk.

I was looking at it wondering why this is happening, is it a hardware issue, a disk issue? I created the Ubuntu Server 12.10 image on multiple disks, tested it on multiple machines, then did the same with Ubuntu Server 12.04 LTE. However, every time I boot from the USB disk, all I see is the small grey rectangle at the bottom left of the screen. A bit of Googling helped and I realised that all you need to do is to leave the grey rectangle on the screen for a couple of minutes, then press “Enter”, then leave the next screen for a couple of minutes, and press “Enter” again, and magically the Ubuntu server installation screen would be in front of you. Ubuntu installation used to be easier than this, and to be fair, the rest of the installation was a breeze.

Secondly, as with most server installations, I wanted to assign my machine a static IP. One can do this by modifying the /etc/network/interfaces file. For my em1 interface, the configuration is as follows:

auto em1
iface em1 inet static
    address 192.168.0.8
    netmask 255.255.255.0
    network 192.168.0.1
    broadcast 192.168.0.255
    gateway 192.168.0.1

where my router is on 192.168.0.1 and the static IP that I have assigned is: 192.168.0.8.

However, this configuration made my DNS resolution to fail. The reason I knew the DNS was failing is because I was able to ping www.yahoo.com or www.google.co.uk by their IP addresses. After a bit of more Googling, I found that you will need to explicitly specify DNS nameservers to provide DNS resolution. I chose to use Google’s nameservers here which are:

8.8.8.8 (google-public-dns-a.google.com)
8.8.4.4 (google-public-dns-b.google.com)

To use these name servers, modify the /etc/network/interfaces file and add the following line after the em1 configuration:

dns-nameservers 8.8.8.8 8.8.4.4

The full file now looks like:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto em1
iface em1 inet static
    address 192.168.0.8
    netmask 255.255.255.0
    network 192.168.0.1
    broadcast 192.168.0.255
    gateway 192.168.0.1

dns-nameservers 8.8.8.8 8.8.4.4

Now just restart your networking service by using the following command:

sudo service networking restart

and all should be good.

Nov 13, 2012

Copyright © Masud Khokhar 2014