Using Joda Time To Format Dates

David Horwitz 10 March, 2011 15:48 Sakai Permalink Trackbacks (0)

I recently got round to trying out Joda-time to do some printing of dates in Java. Like most Java developers the standard calendar classes always seemed clunky and while I haven't used its full power it does seem much more powerful and easier to use. Bellow is some example code for printing the current date in a variety of chronologies. In real life probably not that useful but doing this in the standard calendar classes would be a challenge:

 

Locale locale = new Locale("en", "gb");

       
        DateTime dt = new DateTime();
        DateTimeFormatter fmt = DateTimeFormat.longDate();
        String str = fmt.withLocale(locale).print(dt);
        System.out.println("Default: " + str);
        System.out.println("Buddist: " + fmt.withLocale(locale).withChronology( BuddhistChronology.getInstance()).print(dt));
        System.out.println("Islamic: " + fmt.withChronology(IslamicChronology.getInstance()).print(dt));
        System.out.println("Ethiopic: " + fmt.withChronology(EthiopicChronology.getInstance()).print(dt));
        System.out.println("Julian: " + fmt.withChronology(JulianChronology.getInstance()).print(dt));

 

The result is:

 

Default: 10 March 2011
Buddist: 10 March 2554
Islamic: 4 4, 1432
Ethiopic: 7 1, 2003
Julian: February 25, 2011

 

 

 

 


Scripting SMS's Via REST Part 1

David Horwitz 09 January, 2010 10:28 Sakai Permalink Trackbacks (0)

Recently we where posed this use case a faculty* here at UCT wanted to inform users that they had been offered places to study for the 2010 academic year.As each of the SMS's had to contain personalized information - their student number and the degree for which they had been accepted - the SMS user tool would not be practical as they where sending out 1500 of these. They also wanted the students to respond via SMS if they intend to take up the offer (we will cover that in part 2).

 

SO first some terminology for those who haven't used the Sakai SMS service:

SMS Task: a task is a message that can be sent to one or more users. The recipient list is expanded at processing time into individual SMS Messages that are submitted to the gateway. 

So in our case we need a script that will create an SMS task for each recipient containing the custom text.  Fortunatly the SMS service exposes its enteties via REST using the Entity Broker, simply go to /direct/ on an instalation with the SMS service installed and you will see REST endpoints for sms-taks and sms-account. I have chosen to do this in php, but it could eaqualy easily done in perl, python or any number of other scripting languages.The full script can be found here.

 So the first thing we need is a function that will submit the values to the REST using http POST and be able to perform basic authentification. This is easily done with php curl:

function post_it($datastream, $url) {
global $username, $password;

// init curl handle

$ch = curl_init($url) or die("couldn't init curl");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $datastream);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
// this line makes it work under https
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
print "loging in as $username \n";
// perform post
$rr=curl_exec($ch);
curl_close($ch);

#echo $rr;
if ($rr) {
return $rr;
} else {
echo "<br>error: ".curl_errno($ch)."---".curl_error($ch)."<br>";
return $rr;
}

}

 

This is generic code that could be used for any number of operations. It basialy expects an array of the form values to post, keyed by the form filed id, the url to post to and expects global variables containing the username and password its going to use.  The next part is trivial, we need t open a csv file and use the values in it to populat the message and then send the message to the rest endpoint. I'll asume your familiar with php file options and jump to the meaty part. I'll just pause to not tha the getcsv method on the filehandle will save you a couple of lines of code. Ok so the message we want to send is:

$message="Student No.$campusId: UCT Commerce has made you an offer for $degreeCode for 2010. Sms the words: offer COM $campusId accept OR decline to $return_number";

$return_number is the same for all recipients so we needn't get it from the SMS. So we need $campusId and $degreeCode as well as the students modile number. Once populated it should look something like:

Student No.HRWDAV004: UCT Commerce has made you an offer for Bcom for 2010. Sms the words: offer COM HRWDAV004 accept OR decline to 00000

Once we can build that we need to populate our required form fields:

    $data["attemptCount"]=0;
$data["dateToSend"]=$dateToSend;
print "Date to send ".$data["dateToSend"]."\n";
$data["deliveryMobileNumbersSet"] = $number;
$data["groupSizeEstimate"]=1;
$data["messageBody"]=$message;
$data["messageTypeId"]=0;
$data["sakaiSiteId"]=$siteId;
$data["sakaiToolId"]="sakai.sms.user";
$data["senderUserId"]="dhorwitz";
$data["senderUserName"]="01302922";
$data["smsAccountId"]=$accountId;
$data["statusCode"]="P";
$data["creditEstimate"]="1";
 

Most fields are self explanetory, however dateToSend can be ommited if you want the messages sent imidiatly. Once you've done that all that remains is to post the form:

$ret = post_it($data,$url);
print "$ret \n";

if (!is_numeric($ret)) die("Non numeric response received\n");
 

The return value is the id of the newly created task so a non numeric response indicates that something went wrong. Next blog how to handle responses!

*In South African universities a faculty is an organisational unit, larger than a department, smaller then the university. More or less corresponds to the term school in US higher ed.

Managing Local Changes To Maven Bundles Part 1

David Horwitz 22 November, 2009 12:10 Sakai Permalink Trackbacks (0)
In the 2,7 release several tools will have their own release and be deployed by assemblies, much the way that the kernel package in 2.6. This will requireinstitutions deploying Sakai to re-examine some of their practices. While doing this we want to:

1)Speed up our build times by not building code unessesarily
2)be sure of what versions of code we deploy to our production environment
3)simplify our build processes.

 The case I shall be considering is:

"At foo.edu we have modifications to the Test & Quizzes help documentation to meet local needs." (This is a simplification of a use case Seth Theriault posted to sakai-dev a while back - well get to Seth's full case in a follow up post).

Now this kind of change is probably fairly common and usually has some notable feature of being a stable change - you make it once at the start of the release cycle. This makes our job somewhat easier. I shall also be assuming that we are working against released jars, again I shall write about tracking a maintenance branch in a later post.  

To achieve our goal we need to:
1)Build our custom help jar
2)build a custom assembly
3)deploy that assembly to our maven repository

First off lets set up a svn project to do this, I'll be using a msub location but this could easily be a local svn too:
  svn mkdir https://source.sakaiproject.org/svn/msub/foo.edu/sam/
  svn mkdir https://source.sakaiproject.org/svn/msub/foo.edu/sam/trunk
  svn mkdir https://source.sakaiproject.org/svn/msub/foo.edu/sam/tags
  svn mkdir https://source.sakaiproject.org/svn/msub/foo.edu/sam/branches

now into that project we need to copy certain parts of the SAM project:
    svn copy https://source.sakaiproject.org/svn/sam/trunk/pom.xml https://source.sakaiproject.org/svn/msub/foo.edu/sam/trunk

svn copy https://source.sakaiproject.org/svn/sam/trunk/samigo-help https://source.sakaiproject.org/svn/msub/foo.edu/sam/trunk

svn copy https://source.sakaiproject.org/svn/sam/trunk/samigo-assembly https://source.sakaiproject.org/svn/msub/foo.edu/sam/trunk

Now that we have the project we need to do some quick edits to the poms:
1.in the base pom remove all the modules except samigo-help and samigo-assembly
2.edit the locations in the scm tags to point to the msub location
3.Update the distribution management location to point to your own local repository and change the ids of the servers to something institution specific*
4.change the groupIds from "org.sakaiproject.samigo" to "edu.foo.samigo"
5.change the version number to something that makes sense locally (remember to keep the -SNAPSHOT)
2 and 3 will allow us to release our artifacts using maven and 4 & 5 will enable us to easily distinguish our artifacts from the Sakai ones so we can be sure we deploy the right code to production later.

Now we are ready to make the meaningful changes. Firstly apply your changes to samigo-help. Now we need to edit the assembly to include our custom help jar rather than the sakai one. For backgroup you may want to have a look at Steve Swinberg's blog post on assemblies. Firstly we need to fix the version for the samigo dependencies in samigo-assembly/pom.xml change ${project.version} to the version of samigo you want. Now change the dependency for samigo-help so that its group id is foo.edu.samigo and its version stays as ${project.version}. :Lastly we need to edit samigo-assembly/src/main/assembly/deploy.xml and change:
org.sakaiproject.samigo:samigo-help:jar:*
 to
edu.foo.samigo:samigo-help:jar:*

Now we are basicaly done all thats left is to publish our artifacts to our repository. First though lets test . Run mvn clean install

In samigo-assembly/target/ you should now have a zip file with the tomcat overlay. If you open this with a zip application you should see your custom help jar in shared/lib/. Now lets publish our snapshot to the repository, making sure you have a server entry for your snapshot repository run:

mvn clean install deploy

This should push a snaphot artefact to your snaphot repository - you can check by browsing to edu/foo/samigo. Now lets cut a release so we have a stable artifact for our production build. This is a 2 stage process:

mvn release:prepare

Will cut a tag for you version.

mvn release:perform

will compile the binaries and publish them to the repository defined in the distribution management tag of the base pom.

 

* If you don't have a local maven repository you can set one up easily using something like nexus or simply apache or another webserver

Thought Piece: Sakai Naming Practices

David Horwitz 30 May, 2009 13:05 Sakai Permalink Trackbacks (0)

As the "Sakai 3" processes role on its becoming apparent that there is a fair amount of confusion about the relationship of the 2 projects (the UX project and the K2 project) and their relationship to Sakai 3 (the next major version of the Sakia platform). Some of this confusion relates to fairly lax practices and names being used suggesting links to Sakai 3 that could be confusing to those not following the project closely.

 

Some assumption:

  1. Sakai as a product is a collection of components, as such it more closely resebles a Linux Distribution than a single application
  2. Sakai as a product is owned by the community, but managed by the soon to be constituted product council.
  3. Sakai release are managed by the release management group. 

Some things flow out of this:

  1. Sakai as a name is owned by the product council. To have a name like 'Sakai 3' or '3akai' the project must meet the product councils requirements for the name and have their approval.
  2. as such no R&D or incubation project should use names that are similar to the Sakai name or name-space.
  3. Terms like "beta" and "rc" as applied to projects that fall under 1 above are owned by the release management team. i.e. something cant be called Sakai-3.0-Beta till the release management team is satisfied that the code meets the criteria for that designation.

And some suggested best practices:

  1. All projects should be clearly named from inception
  2. Where there is a meta project that consists of two or more project (as in the current case) it should be clearly named at inception. 

1 2 3 4 5 6 7 8  Next»

Powered by LifeType
© 2006 - Design by Omar Romero (all rights reserved)