MAJOR UPDATE (v1.1): My School Holidays (inc lots of freebies)

Today we are pleased to announce the launch version 1.1 of our popular School Holiday Dates website, My School Holidays.

With over 1 million people every month using My School Holidays it is crucial your school holiday dates are up to date.

Mobile Phone App

We’ve just released a FREE Android school holiday countdown widget for My School Holidays users which can be found on the Android Market here. Or from your phone scan this QR code (or visit the Android Market on your phone and search for My School Holidays).

msh_widget_qr_code

Printable Calendar Cards

Don’t have an Android? But want a way to remember your school holiday dates on the go? How about printing them onto something that fit right in your pocket? Maybe a business card? You can now select your school on My School Holidays and print business card sized calendars with your school’s holidays on. You could even print a few pages, laminate them and give to parents? It’s super easy to do:
Simply find your school on My School Holidays and click the Printable Business Cards link. Print it out double sided and off you go.

Autocomplete on Search

We revamped the search box on the website so our autocomplete search will suggest school names to you as you type in the name of your school. Try it out now at My School Holidays

Going global

We have added more countries dates to My School Holidays. We now currently support: Germany, Canada,
The United Kingdom(includes Wales), Australia, The United States of America and New Zealand with more countries due over the next few months. Also useful if you’re planning to go on holiday in another country and want to find out when the local schools are on holiday.

iCal & GMail support

GMail, Outlook and Thunderbird users can now enjoy a simple iCal import of their school holiday calendar.

To do this visit your school on My School Holidays then click “More options” then select the format you wish your holiday dates.

Edit your own school holiday dates

We want your school to update your school holiday dates but we know how difficult it can be to encourage administrators to do this so we have given this functionality to the hardest working people in the education system, the teachers.

Teachers can now use a really simple interface to insert their own school holiday dates. They can also add casual/training/inset days. To insert your days simply find your school on My School Holidays and Click “Edit the dates”.

Behind the scenes

We have developed a new way of predicting and validating school holiday dates that you will see come to life in Version 1.2. We are currently using this method to quickly collect school holiday dates and publish them live on the website.

We will be using this technique along side other techniques to gather Holiday Data from trusted sources and provide you with the most up to date information on school holidays from around the world.

Report This Post

Handling school closure RSS feeds

Some background information

Some councils (currently 4 in the UK) manage a school closure RSS feed. This RSS feed is updated when a school is closed, this is great news for sites like my school closures as it enables them to dynamically update parents based on verified information supplied by the council. I have been in contact with a lot of schools state side who also want to begin providing closure information via RSS to third parties.  If you don’t know what an RSS feed is then this article probably isn’t for you.

Why is this important?

Globally recording school closures isn’t everyone’s cup of tea.  But if you think about how powerful it would be to compare school closures against weather/disasters etc. and the ability to then predict closures and other local closures based upon a school closure you begin to have a much bigger understanding of the economic and social impact such a system/standard can have.

The problem at the moment is that there is no framework for this information so working with it is a bit of a nightmare.  Therefore the target audience for this article is whoever is making the feeds for the council.

Remember: Computers are only as accurate as the information that goes into them.  RSS school closures feeds from councils may be a new area to explore but it is an area that will inevitably expand so we should get it right early on.

My work in this area

I write the mechanics for my school closures, providing school closure feeds and notifications for well over 5000 schools worldwide. I also work on the Ushahidi project, working on the social aggregation object which is in place to take information from social networks and assign them to schools based on locations. I am also working on a method of predicting school closures based on weather/notifications and/or and global disasters inc. fire, floods etc.

Suggested framework

I think it’s great councils are providing closure information but we need to address a few things.

1.) Provide documentation – We need either a standard for council closure RSS feeds OR councils needs to provide documentation along side their RSS feed.
2.) Do not create ghost items – Councils that create an RSS feed where the item is “No new items exist” is not cool. If your feed has no items then simply keep your feed empty.
3.) Don’t be vague – Councils need to fill their feed with as much information possible, I don’t expect lat/long but at least the street name.  Just putting the school name in the feed is not enough information, there is often two “St Matthews(replace Matthews with whatever you want) primary school’s” in the same district/council area.  Include in the feed if the school is open or closed and the reason for the closure (if this is the case).
4.) Don’t break your feed – Councils have to keep their RSS feeds working and up to date, this is a no brainer but is ignored on the previously mentioned closure feeds.
5.) Understand copyright law – Don’t put a copyright on public information RSS feeds (sighs).
6.) Use Geo tags on your feed – Consider putting some geo tags into your actual feed header, there are quite a few councils with the same name so a feed named “York Council RSS feed (new)” would get confused with New York, if you include a location tag such as “York, UK” then it will be a lot easier to aggregate this information.
7.) Use Geo tags on your items – Consider putting some geo tags into your items. I appreciate this is a bit of a pain to do but it will help us avoid matching the wrong notification to the wrong school.
8). Use the appropriate ttl on your feed.  Is 5 minutes really how frequently readers need to update this information?
9.) Create unique guids for each information update. Obvious really yet this is being ignored.
10.) Use open/closed in the title. If you use the word open or closed in the title it will save us creating a tag, however we should do that anyway.

An example of a bad feed

<rss version="2.0" xmlns:schools="http://purl.org/dc/elements/1.1/">
<channel>
<title>Barmon Schools - School Closures</title>
<link>https://rss.Barmon.com</link>
<description>This feed provides a list of schools that are closed in the Barmon District https://rss.Barmon.com</description>
<copyright>(c) Barmon Schools</copyright>
<pubDate>Thu, 08 Jul 2010 09:56:11 GMT</pubDate>
<ttl>5</ttl>
<item>
<title>- No Schools Closed Today -</title>
<description>- No Schools Closed Today -</description>
<link>https://rss.Barmon.com/Schools/SchoolClosure_Index.aspx</link>
<pubDate>Thu, 15 Jul 2010 17:20:16 GMT</pubDate>
<guid>https://rss.Barmon.com/Schools/SchoolClosure_Index.aspx</guid>
</item>
</channel>
</rss>

An example of a good feed

<rss version="2.0">
<channel>
<title>Barmon Schools - School Closures</title>
<link>https://rss.Barmon.com</link>
<description>This feed provides a list of schools that are closed in the Barmon District https://rss.Barmon.com</description>
<pubDate>Thu, 08 Jul 2010 09:56:11 GMT</pubDate>
<ttl>600</ttl>
<item>
<title>Moleswood Primary School is closed due to a fire</title>
<description>A fire swept through Moleswood Primary School, BA1 2AM.  The school is closed for an unspecified period</description>
<link>https://rss.Barmon.com/Schools/SchoolClosure_Index.aspx?school=1&view=rss</link>
<pubDate>Thu, 15 Jul 2010 17:20:16 GMT</pubDate>
<guid>82291559asdh22184</guid>
<geo:lat>53.795740</geo:lat>
<geo:lon>-1.758306</geo:lon>
<schoolinfo:name>Moleswood Primary School</schoolinfo:name>
<schoolinfo:type>closed</schoolinfo:type>
<schoolinfo:reason>Fire</schoolinfo:reason>
</item>
</channel>
</rss>

Why this standard is better than the current mechanism

We basically chose to extend the RSS schema to include some school specific info. Surprisingly to some people is why we didn’t include something such as the UPN or “code” of the school. This is because the scope of this standard is global and most countries have their own coding structure.

We chose name for obvious reasons.  The schoolinfo:type allows different values such as closed, open, halfday, holiday etc. so can be extended reasonably well and the reason is simply complimentary for these values.

Why is Latitude and Longitude SO important?  Quite a few reasons, firstly is mapping, it is much easier to map based on lat and lon.  Second is conflicting school names and thirdly is very close by schools.  Lat and Lon of a location allows accurate location based results and also allows us to update records in case a school moves.

I can guarantee that councils will eventually adopt either this standard or a standard similar to this, be it through a smart management decision or through consumer demands.  A standard like this allows for much smarter closure announcements and future proofing of the quality of service delivered by educational institutions.

Ushahidi post tweets to API php example

The below code takes an rss search result from twitter, detects the authors location then posts the information to Ushahidi via the API.

Application I used it inMy School Closures for detecting people who tweet about school closures.  Unfortunately I have to use pipes for the location builder which isn’t elegant as Yahoo Pipes sucks and I wish I never started playing with it.  Feel free to play with the pipe I created to get geo location information from a location name, it is the pipe that has the json_decode.

You will need mysql and a table for the guids (this stops us from spamming twitter for authors we have already located). Make sure you change the configuration settings and create a table in mysql.

The method is simple, the code isn’t pretty and will require polishing but here it is:

<pre>
<?php
//CONFIGURE THE SETTINGS BELOW
//twitter settings
$twitterusername = "mytwitteraccount";
$twitterpassword = "apasswordgoeshere";

//database settings
$host = "databasehostname";
$user = "databaseusername";
$pass = "databasepassword";
$dbname = 'databasename';

// You should create a table called tweetguids in your database
$tablename = "tweetguids";

// Change the below feed to a rss feed similar to below
$rssurl = "http://pipes.yahoo.com/pipes/pipe.run?_id=a9663ebc09e69b9195fb2407fba9f2bc&_render=rss";

// END OF CONFIG

$conn = mysql_connect($host, $user, $pass) or die                      ('Error connecting to mysql');
mysql_select_db($dbname);

ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(E_ALL);

$rss = simplexml_load_file($rssurl) or die("failure");
$count = 0;
foreach ($rss->channel as $chan)
{
$time = $chan->pubDate;
}
foreach ($rss->channel as $chan){$time = $chan->pubDate;}
foreach ($rss->channel->item as $item)
        {
        // only do first 10 records
        if ($count < 10)
                {
                $foundguid=0;
                $guidnew=$item->guid;
                // Check to see if guid exists in db already
                $sql="SELECT * FROM $tablename where guid = \"$guidnew\"";
                $result=mysql_query($sql, $conn);
                while ($row=mysql_fetch_array($result))
                        {
                        $foundguid=1;
                        echo "Foundguid: $foundguid";
                        }
                if($foundguid==1)
                        {
                        echo "We found an alredy existing guid...";
                        }
else
                        {
                        $count = $count + 1;
                        $task="report";
                        $incident_title=$item->title;
                        $guidnew=$item->guid;
                        $incident_title=str_replace(" ","+",$incident_title);
                        $incident_description=$item->description;
                        $incident_description=str_replace(" ","+",$incident_description);
                        $incident_date=date("m/d/Y",$time);
                        $incident_hour=date("H",$time);
                        $incident_minute=date("i",$time);
                        $incident_ampm=date("a",$time);
                        $incident_category="Possible Closure";
                        $location_name="Unknown";
                        $author = $item->author;
                        $author = str_replace(" ","+",$author);
                        $pos = strpos($author,"+");
                        //$author = substr($author,0,$pos);
                        $author = str_ireplace("http://twitter.com/","",$author);
                        $url = "http://$twitterusername:$twitterpassword@api.twitter.com/1/users/lookup.xml?screen_name=$author";
                        //echo $url;
                        $output = simplexml_load_file($url) or die("badauth");
                        foreach ($output->user as $item)
                                {
                                // Get the values out of the XML
                                $location=$item->location;
                                // Clean up the location
                                $location=str_ireplace("-",",",$location);
                                $location=str_ireplace(" ",",",$location);
//                              $location=preg_replace("/[^a-zA-Z0-9\s]/", "", $location);
                                echo "<br/><b>Location content: $location<br/>";
                                // Pass the location to yahoo pipe
                                $location = str_ireplace(" ","",$location);
                                //echo "<br/>Loc: $location";
                                $locationurl = "http://pipes.yahoo.com/pipes/pipe.run?_id=03539616e4cdd62eb15ed26b81e3041e&_render=json&q=$location";

                                 $ch = curl_init();
                                curl_setopt($ch, CURLOPT_URL, $locationurl);
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

                                //make the request
                                $json = curl_exec($ch);
                                $arr = (json_decode($json,true));
                                $blah = $arr['value']['items'][0]['name']['loc'];
                                //print_r($blah);
                                $latitude = $blah['lat'];
                                $longitude = $blah['lon'];
                                $location_name = $blah['city'];
                        }

                        $incident_description="Closure reported from twitter";
                        $url = "task=report&incident_title=$incident_title&incident_description=$incident_description&incident_date=$incident_date&incident_hour=$incident_hour&incident_minute=$incident_minu$
                        $posturl = "http://myschoolclosures.com/ushahidi/api";
                        $Curl_Session = curl_init($posturl);
                         curl_setopt ($Curl_Session, CURLOPT_POST, 1);
                         curl_setopt ($Curl_Session, CURLOPT_POSTFIELDS,
                        $url);
                        curl_setopt ($Curl_Session, CURLOPT_FOLLOWLOCATION, 1);
                        curl_exec ($Curl_Session);
                        curl_close ($Curl_Session);
                        //Write to the database
                        $sqlgo="INSERT INTO $tablename VALUES (\"$guidnew\")";
                        $result=mysql_query($sqlgo, $conn);
                }
        }
        //Write anything else to DB just in case anything trails behind
        $sql="INSERT INTO $tablename VALUES (\"$guidnew\")";
        $result=mysql_query($sql, $conn);
        $row=mysql_fetch_array($result);
        //echo "<br/>$sql<br/>";
}
?>

Ye Olde Android adventure – Day 2

Today as I ventured towards Droidville I met a sage who reminded me about some useful keystokes.

Eclipse: Control Alt Down duplicates line
Emulator: Rotate screen – Control F11

As I moved closer to Droidville the air began to fill with hope, thousands of hopeful children and teachers poored into the streets, so I quickly hid and jumped into Bar Youtube (Part of the Starbucks chain) and watched another video to further my understanding of the power of Android, another good one this time by Ye old O’Reilly

Building my team to fight the forces of evil

I got in touch with a developer through rent-a-coder called Kumar Bibek who has 3 years experience fighting the forces of evil (developing Android apps). We had a conversation that went something line:  “I can make the bow, can ye make the arrow?”  We agree’d on 100$ for the array (final bits of the work that were out of my skill set).

Overview of the bits I’m doing:
Making Classdroid look fit for a princess (Layout design/User interfaces)
Making Classdroid easy to use  (Application flow)
Making Classdroid link together (Intent assignments)
Designing how Classdroid will save our princesses minions (Database design)

Overview of the bits he’s doing:
Not shooting the messenger (Code to read/write preferences/settings to/from SQLite)
Carrier Pigeon nurturing (Control method for post to WordPress)
Controlling the Eye of  Gondor (Camera SDK modifications)

In the Sage’s library I found a piece of parchment with some notes scribbled on it:
Resource = text,pictures, sound objects, layout….
Intent = change the page
View = new page layout/display
\n = newline when using text elements

Very cryptic clues, maybe I will need them to enter the great hall of Droidville?

It’s been a long day…..

As the day drew to a close and the Sun nestled the hills of Azrowilsden I discovered WordPress have an android application that does 80% of what I want to do from a control point of view so I’m going to hack into that to save me needing to write the function that posts the RPC over XML to WordPress.  This is why the world should embrace more open source, it empowers us all instead of dumbing us down like iLem users who are too scared to google how to create an android application (or don’t see it being a valuable use of their time).

As the iLem users fall off their platform I am gently warmed inside by the knowledge that we are creating a better, more open world without any corporate borders.  One application at a time.

Enhanced by Zemanta

Simple tool to help educators vote

Worried the general election might be about leaders and not policies? Not to worry, remove any external influences by simply voting on 26 educational policies. Say which you like then it tells you which parties policies you prefer. The site has no government ties or associations and only takes a minute or so.

Important or not?  This is the link to the tool.

Reblog this post [with Zemanta]