Sports Administrator

Welcome Screen

Welcome Screen

Sports Administrator: Open-sourced Sports Carnival management software.

I have just released a free open-source Sports Carnival management database that may be useful to schools for running their Athletics and Swimming carnivals.

It has many features with some of the main ones listed below:

  • Easy entry of event results
  • Tracking of event records
  • Cumulative house points
  • Age Champions
  • Multiple Reports to print results
  • HTML export of results

Full feature list here:

This was previously a commercial package, but with the kind permission of Andrew Rogers, the original developer, it has been made open source and I have updated it to work with new versions of Access 2010+

If anyone is interested in a great (free) Sport Carnival software please try this out. I always found it much easier to use than MeetManager which is the main commercial package several schools use.

Latest Release

Source Code

No tag for this post.
Posted in General, Utilities, Windows | Leave a comment

Avahi Reflector filtering patch

This is about transmitting Bonjour traffic across VLANs using Avahi Daemon as a reflector with a service filter patch applied.

We have multiple VLANs configured for Wi-Fi, and wired LANs and have AirServer terminals connected to classrooms needing to be discoverable from iPads and Macbooks on the Wi-Fi network.

Originally we were just using the standard Avahi-Daemon package provided by Ubuntu, but found as more BYOD laptops and iPads connected the reflected packets became greater and some services we did not want advertised (e.g. home shared printer, music libraries, etc). For this standard config there are multiple guides already available.

To filter out services we do not want I have written a patch to the Avahi code that allows you to enter a list of services you want to be reflected and only those will appear in other VLANs.

I based my implementation on the suggestion in Extending multicast DNS across local links in Campus and Enterprise Networks and it works by filtering out received packets before they are added to the daemon’s cache. All locally published services are allowed through.

Avahi-Reflector-Filter patches. This includes the main Reflector Filter patch and a patch to add _airplay._tcp to the listed services avahi-browse shows.

For those looking to compile in Ubuntu make sure you also apply all the Ubuntu specific patches

I also needed to modify makefile input for make install to work correctly

--- a/avahi-python/avahi/
+++ b/avahi-python/avahi/
@@ -456,7 +456,7 @@
 $(INSTALL_DATA) $$files "$(DESTDIR)$(avahidir)" || exit $$?; \
 done || exit $$?; \
 if test -n "$$dlist"; then \
- $(am__py_compile) --destdir "$(DESTDIR)" \
+ $(am__py_compile) --destdir $(DESTDIR) \
 --basedir "$(avahidir)" $$dlist; \
 else :; fi

--- a/avahi-python/avahi-discover/
+++ b/avahi-python/avahi-discover/
@@ -477,7 +477,7 @@
 $(INSTALL_DATA) $$files "$(DESTDIR)$(avahi_discoverdir)" || exit $$?; \
 done || exit $$?; \
 if test -n "$$dlist"; then \
- $(am__py_compile) --destdir "$(DESTDIR)" \
+ $(am__py_compile) --destdir $(DESTDIR) \
 --basedir "$(avahi_discoverdir)" $$dlist; \
 else :; fi

To compile Avahi on Ubuntu 14.04 I used the following

./configure \
--disable-autoipd \
--enable-compat-libdns_sd \
--disable-mono \
--disable-monodoc \
--disable-qt3 \
--enable-gtk3 \
--with-systemdsystemunitdir=/lib/systemd/system \
--sysconfdir=/etc \
No tag for this post.
Posted in General | Leave a comment

CAU Local VM Script

Cluster Aware Updating (CAU) introduced in Server 2012 allows you to update your Fail-Over cluster by draining all the Highly Available (HA) roles from the node, performing the updates and then restoring the roles.

While this works great for Clustered HA VMs on a Hyper-V cluster, it appears CUA completely ignores any unclustered VMs on the Nodes. We have non-HA VMs on our Hyper-V Hosts that act as nodes in a File server Fail-Over Cluster and Exchange DAG groups. When CUA runs it ignores the shutdown settings of these VMs and just powers them off, this can causes loss of data in nodes and causes the cluster to have to bring up a down resource rather than just transfer the role.

To fix this we had to create scripts that shut down all the local VMs and then start them back up. These can then be set in the PreUpdateScript and PostUpdateScript profile settings for CUA. I stored the scripts on the CSV volume in C:\ClusterStorage\Volume1\Hyper-V\CAU\. These could then be added as a local file in CAU configuration wizard.

PreUpdateScript = ShutdownLocal.ps1

# VM Delay
$CheckDelay = 30

# Local VMs
$LocalVMs = Get-VM | Where-Object { ($_.IsClustered -eq $false) -and ($_.State -ne "Off")} 

$Node = $env:computername
$LogFile = "C:\ClusterStorage\Volume1\Hyper-V\CAU\Log\$(get-date -f yyyy-MM-dd)-$Node.log"

(Get-Date -Format s) + " CAU Shutdown Script" >> $LogFile

#Shutdown Each VM
ForEach ($VM in $LocalVMs) {
    $VMName = $VM.Name
    # Check State
    If ($VM.State -ne "Off") {
        If ($VM.AutomaticStopAction -eq "ShutDown") {
            # Change State
            (Get-Date -Format s) + " Shutting Down $VMName" >> $LogFile
            Stop-VM -AsJob -VM $VM  #-WhatIf
        ElseIf ($VM.AutomaticStopAction -eq "Save") {
            # Change State
            (Get-Date -Format s) + " Saving $VMName" >> $LogFile
            Stop-VM -AsJob -VM $VM -Save  #-WhatIf

# Wait for all VMs to Shutdown
$i = 0
Do {
    $VMon = 0
    $TimeWait = $CheckDelay * $i
    Start-Sleep -Seconds $CheckDelay
    (Get-Date -Format s) + " Waited $TimeWait seconds for:" >> $LogFile
    ForEach ($VM in $LocalVMs) {      
        $VMName = $VM.Name
        # Check State
        If ((Get-VM -Name $VMName).State -ne "Off" -and (Get-VM -Name $VMName).State -ne "Saved") {
            # Report State
            (Get-Date -Format s) + " -$VMName" >> $LogFile
Until ( ($i -gt 10) -or ($VMon -eq 0) )

(Get-Date -Format s) + " CAU Shutdown Script Completed" >> $LogFile

PostUpdateScript = StartLocal.ps1

$Node = $env:computername
$LogFile = "C:\ClusterStorage\Volume1\Hyper-V\CAU\Log\$(get-date -f yyyy-MM-dd)-$Node.log"

$PauseDelay = 300
# Local VMs
$LocalVMs = Get-VM | 
  Where-Object { ($_.IsClustered -eq $false) -and  ($_.AutomaticStartAction -like 'Start*') -and ($_.State -ne "Running")} | 
  Sort-Object AutomaticStartDelay

(Get-Date -Format s) + " CAU Startup Script" >> $LogFile

$DelayElapsed = 0
#Start Each VM
ForEach ($VM in $LocalVMs) {
    $VMName = $VM.Name
    $VMDelay = $VM.AutomaticStartDelay
    # Check State
    If ($VM.State -ne "Running") {
        $VMDiff = $VMDelay - $DelayElapsed
        If ($VMDiff -gt 0) { Start-Sleep -Seconds $VMDiff }
        $DelayElapsed += $VMDiff
        # Change State
        (Get-Date -Format s) + " Starting $VMName" >> $LogFile
        Start-VM -AsJob -VM $VM  #-WhatIf
# Delay as will immediately start shutting down next node
(Get-Date -Format s) + " VMs Started waiting $PauseDelay seconds for clusters to stabilise" >> $LogFile
Start-Sleep -Seconds $PauseDelay
(Get-Date -Format s) + " CAU Startup Script Completed" >> $LogFile
Posted in Windows | Tagged , , , , | Leave a comment

Updating Moodle table comments

Recently we updated Moodle to 2.6, after doing so I compared the SQL table structure of our upgraded site database against a clean install with the same addons. I found quite a few differences in table structure (smallint to tinyint, etc) for the 3rd party addons, and most core tables were missing their table comments.

To fix this I wrote the following perl script, it takes in a SQL structure dump from PhpMyAdmin and generates a list of alter commands to apply all the table comments in that file. This can then be run against your actual Moodle DB.


# Designed to read in SQL structure export and generate a list of alter commands to set comments from those tables

use strict; use warnings;

my $fileName = $ARGV[0];

open F, "< $fileName" or die "Can't open $fileName : $!"; my %comments = (); my $currentTable; while (my $line = ){
if ($line =~ /CREATE TABLE `(.+)`/) {
# Set current table name
# CREATE TABLE `mdl_assign`
$currentTable = $1;
if ($line =~ /COMMENT='(.+)'/) {
# Store table comment
$comments{ $currentTable } = $1;
close F;

foreach my $table ( sort keys %comments ) {
print "ALTER TABLE `" . $table . "` COMMENT = '" . $comments{$table} . "';\n";

No tag for this post.
Posted in Moodle | Leave a comment