Twitter Widget – filter by @username and #hashtag

If you want to embed tweets in your blog or website from a @username but only show those with a given #hashtag, Twitter’s Widgets makes it easy:

For example, to show only tweets from my @allotmentor account which are tagged with #allotment, I simply enter

from: @allotmentor AND #allotment

in the Search Query box on the Configure a search widget page. Then copy and paste the generated code into your site. See it in action here.

Thanks to this answer on Stack Overflow

Award hat trick

A duo of awards over the summer:

was topped off yesterday by news that we have been awarded FENS Funding for European Neuroscience History Projects in 2013 to capture and make available on our History of Medical Sciences website ‘3-dimensional images of physiological apparatus and models with historic interest’.
See all our summer news in the MSDLT Update

 

 

iCases freely and publicly available!

iCases are action mazes on the web which deliver complex and engaging learning. They have been used in the Medical Sciences Division for the last few years, and have been very well received by students.

iCases give students the opportunity to interact with experimental data in a realistic context. For example, with limited time and money, students must decide what tests are needed to resolve a complex situation typical in biomedical sciences. Research is needed before students can begin the case, background information and references are provided. A simple quiz is used to show that they are ready to proceed to the case itself.

Find out more about iCases

Use iCases NOW!

The following iCases are now freely and publicly available, supported by the HEA Bioscience OER project:

Please note that your attempts at these iCases, and any written answers you enter, will be available for anyone else to see.

 Interested in Using iCases in your Institution?

The above iCases are freely available for use under the specified license. If you wish to have individual accounts for your users (so that an individual will only be able to see their own attempts/answers), there are two options available:

  • iCases is a LTI Tool Provider, and so can be integrated into any VLE/LMS that conforms to the LTI standard. User access will then be controlled by the VLE/LMS.
  • We can, on a limited basis depending on demand, provide accounts within WebLearn (the University of Oxford’s VLE) for use by your users.

If you wish to discuss either of these options further, please contact MSD Learning Technologies.

Allowing access to iCases through LTI

This post follows on from my Early Thoughts on LTI.

We have now fully implemented LTI for our iCases system. This has many benefits, including:

  • We no longer have to maintain authentication/permissions information within iCases, this can instead be done by WebLearn (Sakai), the Univeristy’s VLE.
  • Previously, it was only possible to log in to iCases if you had an Oxford Single Sign On username, so non-Oxford users had to use a single ‘anonymous’ account. That meant all non-Oxford users could see each other’s attempts and answers, and it was very difficult for them to pause and resume an attempt, due to the difficulty of finding the previous attempt among a long list of anonymous attempts.
  • iCases can be integrated into WebLearn making it very easy to add an iCase to a course.
  • Other institutions with a VLE/LMS that conforms to the LTI standard can easily use our public iCases.

We have already successfully made an iCase available to both Oxford and non-Oxford users through WebLearn/LTI, and are beginning to roll out our remaining iCases using this method. This includes making a number of iCases available publicly – see https://learntech.medsci.ox.ac.uk/wordpress-blog/?p=295.

As it currently works, the following is the process for adding an LTI Tool Provider to a site in WebLearn (the LTI Tool Consumer):

  1. Add a Basic LTI Tool to the site
  2. An individual with “Instructor” privileges (in WebLearn this means someone with a maintain/contribute role) can set up the Basic LTI Tool to point to the Tool Provider. This requires, at the very least, setting the URL and entering a key and secret (held/provided by us) into WebLearn.
  3. The Instructor can also set some launch/display settings. These settings include whether to open the Tool Provider in a new window and whether to pass information about the user, e.g. name/email address, to it, both of which we do.
  4. When the LTI Tool is launched, it sends a signed LTI request to the Tool Provider (i.e. iCases)

Turning iCases into an LTI Tool Provider wasn’t totally easy, but wasn’t as difficult as I had expected, and was made much easier by using the IMS Global Bsaic LTI PHP class – http://ims-dev.googlecode.com/svn/trunk/basiclti/php-simple/ims-blti/. The way I have got the LTI launch to work, at the Tool Provider end is a follows:

  1. Check that we have received an LTI request – iCases is set up so that it can only be accessed through LTI, although it would be possible to allow other access routes.
  2. Get the oauth_consumer_key from the launch data, and use this to look up the corresponding secret in a table to keys/secrets in our database.
  3. Create a new BLTI object (using the IMS Global class) which does all of the “is this a valid LTI launch?”/OAuth stuff for you.
  4. If this is the first time iCases has been launched from this context (i.e. a site in WebLearn), add the context to the database.
  5. If this is the first time that this user (defined by their WebLearn unique ID) has accessed iCases, add the user to the database.
  6. If this is the first time iCases has been launched from this context and the user has an Instructor role, allow them to choose an iCase to associate with this LTI tool instance. If this is the first launch from this context, and the user is not an Instructor, send them to an access denied page.
  7. Any future launches from this context will now send users directly to the associated iCase.
  8. As well as being the only ones who can link a Basic LTI Tool instance to an iCase, Instructors also get extra privileges within iCases, e.g. they can mark student attempts.

And that’s it! We are very excited by the options LTI opens up for us, in particular the fact that it enables us to make WebLearn a single, consistent route to many tools, and that we no longer have to worry about maintaining user accounts/passwords within our tools (which has security benefits for users). It would be possible to make Tool Providers appear as though they are actually part of WebLearn, although we haven’t done this for iCases.

We are anticipating LTI-ing a number of other tools in the near future, including CSlide and a project/module option choosing system – watch this space!

Resetting the root password/privileges for MySQL/PHPMyAdmin (XAMPP 1.7.3, MySQL 5.1.41)

We use XAMPP for our local development (on Windows), and I have a habit of messing around with the database and doing bad things by mistake, because it’s only for local development, so it doesn’t matter that much. It’s still annoying when I lock myself out of all my databases though!

While setting up a wordpress site locally for testing, I managed to remove the global privileges of the root user in PHPMyAdmin, thinking it was the user for the wordpress database. I did the usual thing of searching for solutions online, and after trying a few different things involving the command line and MySQL Workbench, I came across this Apache Friends forum thread: http://www.apachefriends.org/f/viewtopic.php?f=16&t=46832. The instructions boil down to the following:

  • Open mysql/resetroot.bat in a text editor
  • Add “–datadir=c:/xampp/mysql/data” into the “mysql\bin\mysqld.exe…” line (line 18), after “–no-defaults”. Change the datadir parameter to the path to your data directory – the one shown is the default.
  • Run resetroot.bat – this should reset the MySQL root password and privileges. You can then login to MySQL/PHPMyAdmin using the username root and no password. For security, you should set a password for the MySQL admin user in the XAMPP Security panel: http://localhost/security/

CakePHP Session data being lost on redirect

Having successfully enabled access using LTI to a local version of iCases – see https://learntech.medsci.ox.ac.uk/wordpress-blog/?p=229 – I got it set up on a live server, assuming that it would work without any trouble. However, I was unable to login successfully through WebLearn, which is our Tool Consumer.

It turned out that this was due to the session data being lost when redirecting from the login page within the CakePHP app to the scenario page. Authentication using LTI relies on session data, as the LTI context information is saved to the session. Therefore, when the session data was lost, the app could no longer tell that the user had accessed it through a valid LTI request, and so the user was denied access.

I fixed this by changing Security.level in core.php to ‘low’ (it had previously been medium). From the CakePHP docs, this increases the multiplier for the ‘Session.timeout’ value (from 100 to 300) and disables (or, to be pedantic, does not enable) PHP’s session.referer_check. It seems to be the latter that was the problem. However, in the php.ini file we have ‘session.referer_check = ‘, which should mean that session.referer_check is not enabled anyway. So I am not sure why changing the security level had an effect, unless setting the Security.level to medium enables session.referer_check, even if it was not already enabled.

As far as I can tell from reading around, disabling session.referer_check should not cause any problems, as it is only possible to access the LTI-ed iCases through WebLearn. Checking that the LTI launch is valid includes checking that the launch request has come from a valid location.

Shock News (to me anyway): Windows Command Line is actually useful

Having used Windows since my earliest memories, I’ve only rarely used the command line. I never found it that useful and was always annoyed by the fact that I couldn’t click somewhere in my command to edit it, and instead had to use the arrow keys to move it forwards and backwards.

However, I’ve recently had to carry out quite a few batch tasks in Windows and have, to my surprise, found the command line to be pretty useful. So, as much to remind myself as anything, I thought I would note down the things that have helped me.

Changing File Extensions

This is easy using the REN command, e.g. REN *.svs *.tif

FOR Loops

As you would expect, this loops over a set of files/directories and carries out a command on each. The basic structure of a FOR command is as follows:

FOR %V IN (set) DO command [command-parameters]

The %V is a variable (it does not have to be ‘v’, but must be a single letter, and it is case sensitive, i.e. %v and %V are different) that can be used in the command parameters to refer to each of the files matched by set. As a spurious example, to echo all of the files in the current working directory, you would give the following command:

FOR %V IN (*) DO echo %V

Variable Modifiers

Variable modifiers can be used to output the variable in a variety of ways, e.g. for %V above:

  • %~fV outputs the full path name for the file
  • %~nV outputs the file name only
  • %~xV outputs the file extension

There are others apart from those mentioned above – see the FOR command help for more.

FOR /D

If the /D extension is used, the FOR command will match  directories rather than files.

For example, to separately zip up all of the subdirectories in the current working directory

FOR /D %D IN (*) DO C:\zip\zip.exe -r "%~fD.zip" "%~fD"

Using FOR in batch files

If you are using a FOR command in a batch file, it is necessary to use, for example, %%V, rather than %V for the variables.

START /WAIT

I was using the START command in a batch file to carry out a certain command on multiple files, but I needed it to wait until one command had finished executing before it called the next. Thankfully there is the /WAIT parameter, which means that the next command will not be called until the previous one has finished.

Phonegap for Android JSCallback error meaning OnDeviceReady not called

Struggled for hours last night while trying to migrate this great example app Sample App using the PhoneGap Database API to work on Android using Eclipse and an Android emulator. Everything was going well until I tried to link to a second page using a query string parameter to pass through the id of the the employee. This resulted in:

JSCallback Error: Request failed. at file:///android_asset/www/js/cordova.js:3698

Eventually stumbled across PhoneGap – migrating iOS applications to Android (Part 1) which pointed out that this is a documented Android issue and proposed the following workaround:

function loadEmployeeDetail(id) {
localStorage.setItem( “employeeId”, id );
navigator.app.loadUrl(“file:///android_asset/www/employeedirectory/employeedetails.html”);
}

And then reading this  in employeedetails.html using:

id = localStorage.getItem( “employeeId”);

However, I was still having problems calling OnDeviceReady() until I stumbled across deviceReady not working in PhoneGap application, how to? which suggested that adding brackets into the function name in the eventListener method might be the problem, giving:

 document.addEventListener(“deviceready”, onDeviceReady(), false);

Problem solved.

 

 

Preventing IE from caching Ajax requests

We are increasingly using AJAX (Asynchronous JavaScript and XML) to deliver content on our pages, but often have problems due to Internet Explorer, every web developers favourite browser, caching AJAX requests. This means that the results presented are not updated when a new request is made to the same URL, even if the data has changed.

This is annoying, but does not go against the HTTP specification, which states that GET requests are cacheable, whereas POST results are not. AJAX requests seem to generally default to GET (JQuery certainly does), so IE caches them.

Therefore, the solution is to make sure that AJAX requests use POST rather than GET. In jQuery, you can do this by setting:

type: 'POST'

For Prototype, you can set:

method: 'get'

In the jQuery.ajax() method, there is also a ‘cache’ setting, which is true by default, but can be set to false, which prevents caching. It does this by appending a TIMESTAMP to the URL, so that each request is made to a different URL, so a cached result cannot be returned. If not using jQuery, an alternative to ensuring that your request is a POST request rather a GET request is to add a ‘cache-busting’ parameter, e.g. a timestamp, to the end of the request URL, e.g.:

var cacheBuster = new Date().getTime();  //Get timestamp
var url  = 'http://www.example.com/getdata?cb=' + cacheBuster;  //Add timestamp to URL