• SQLSaturday #139 (on a Tuesday)

    PASS SQL Saturday LogoI think continuous learning is an integral part of being a professional. On the 24th April 2012, there's an opportunity for everyone with an interest in SQL Server to further their knowledge at the first SQLSaturday event to be held in Adelaide – SQLSaturday #139 (even though it's on a Tuesday!)

    As the number suggests, these events have been running around the world for a while, but this is the first (hopefully of many) to be held here.

    The schedule is now finalised and includes two tracks. Speakers include Paul White from New Zealand, Paul te Braak and Peter Ward from Brisbane, Raja N from Sydney, and local luminaries such as Rob Farley, Roger Noble, Andrew Butenko and even me!

    So what would you expect to pay for a conference featuring this kind of expertise and experience? $200? $500? $1,000? Well you could pay that if you wanted to, but actually the whole day is free, thanks to the generosity of the event sponsors and speakers.

    So run (don't walk) to the registration page and sign up today. Then go and let your manager/boss/social secretary know where you'll be on the 24th!

    See you there 😀

  • Naked ADSL and VoIP 2012-style

    Last month I decided to take the plunge and switch over to a Naked ADSL service. Late last year Internode had announced that they'd sorted out number porting for customers on existing ADSL2+ connections (like myself). More recently they also introduced a new tier in their Naked plans, so that leaving my old 50G ADSL2+ plan was now viable.

    The switch to a naked line happened on the scheduled day. I didn't realise however that the porting of the phone number would take a few extra days. Not a huge problem, but something to be aware of.

    Going naked means you have no dial-tone. If you want to keep your phone number, it needs to be ported to a VoIP service. In this case to NodePhone (Internode's VoIP offering), with $10/month call credit. I've been using first FreeCall and more recently PennyTel as outgoing VoIP providers for a number of years. It will be interesting to see how NodePhone compares.

    Two nice features that I discovered was it comes with voicemail (you can customise the greeting, and you can get email notifications), and caller ID is included (instead of paying $6/month for the privilege)

    I configured my trusty ATA (a Sipura SPA-3000) with new settings to work with NodePhone. All seemed fine, but it didn't work – the registration was failing. A call to Internode Support didn't identify any issues other than I was using more recent firmware than they were aware of, and that I was using relatively 'old' hardware. In any case just when I was about to give up for the evening, I noticed that it had started working all by itself.

    All seemed fine for a few days, then I noticed that we were getting calls going to voicemail but no missed calls were on the phone. Strangely the ATA was still saying it was registered but most calls never rang the phone – they just redirected to voicemail.

    Another call to Internode support, but again no joy. Nothing looked out of place with my settings, but they could see the registration was dropping out regularly (which would explain the calls not coming through to the handset). Their final suggestion – get some new hardware.

    It turns out I bought the Sipura SPA-3000 way back in 2005. 7 years is a good innings for consumer hardware, so maybe it was time to update to something more current. The Gigaset C610 seemed to be well regarded so I picked up one from Internode's Adelaide office.

    It was pretty straightforward to configure, but annoyingly I then discovered I was having the same problem still. Another call to Internode Support, but this time they said they had TWO active registrations – one for the Gigaset and one for the SPA! That didn't make sense, as the SPA was now sitting on a shelf – no power, no network. They reviewed the modem and Gigaset settings and things seemed to settle down, and I received an incoming call ok.

    So hopefully that's the way things will stay for now on 😀

  • MetroYam–Windows Phone Edition

    Part 3 of a series on developing .NET clients for Yammer. For the Windows Phone version of MetroYam, I'm again making use of RestSharp to handle the REST API work. Once difference when using RestSharp on Windows Phone compared to the desktop is that it only exposes asynchronous methods. So instead of calling Execute, we have to call the ExecuteAsync method. Here's the equivalent code:

    using System; using System.Collections.Generic; using System.Collections.ObjectModel; using Gardiner.MetroYam.Core; using RestSharp; using RestSharp.Authenticators;

    namespace Gardiner.MetroYam.PhoneClient { public class Network { private readonly ObservableCollection \_messages;

        public Network( ObservableCollection<MessageViewModel> messages )
        {
            \_messages = messages;
        }
    
        public void Request()
        {
            var client = new RestClient();
    
            client.BaseUrl = "https://www.yammer.com/";
            string consumerKey = "12312341234243";
            string consumerSecret = "kciud84kf0943kdi4kdk3kr";
    
            var oauth\_token = "84944kf984444";
            var oauth\_token\_secret = "kdiekemfckcfiejekmekduj454j4";
    
            var request = new RestRequest( "api/v1/messages.json", Method.GET );
            client.Authenticator = OAuth1Authenticator.ForProtectedResource(
                consumerKey, consumerSecret, oauth\_token, oauth\_token\_secret
                );
    
            // 2011/03/28 20:39:12 +0000
            request.DateFormat = "yyyy/MM/dd HH:mm:ss zzzzz";
    
            client.ExecuteAsync<MessageList>( request, Callback );
        }
    
        private void Callback( RestResponse<MessageList> response, RestRequestAsyncHandle arg2 )
        {
            var users = new Dictionary<int, User>();
            foreach ( Reference reference in response.Data.References )
            {
                if ( reference.Type == "user" )
                    users.Add( reference.Id, new User { Fullname = reference.FullName, Photo = reference.mugshot\_url } );
            }
    
            foreach ( var message in response.Data.messages )
            {
                var vm = new MessageViewModel();
                vm.Body = message.Body.Plain;
                vm.Created = message.created\_at.LocalDateTime;
                User user = users\[ message.sender\_id \];
                vm.Sender = user.Fullname;
                if ( user.Photo != null )
                    vm.PhotoUrl = user.Photo;
                else
                    vm.PhotoUrl = new Uri( "https://c64.assets-yammer.com/images/no\_photo\_small.gif" );
    
                \_messages.Add( vm );
            }
        }
    } }
    

    Rather than a single method that returns the list of messages, we now have a class that populates an ObservableCollection. A reference to this is passed in via the constructor. The ViewModel page that calls this code is straight forward:

    using System; using System.Collections.ObjectModel; using Caliburn.Micro; using Gardiner.MetroYam.Core;

    namespace Gardiner.MetroYam.PhoneClient { public class MainPageViewModel : Screen { private ObservableCollection \_messages; public ObservableCollection Messages { get { return \_messages; } set { \_messages = value; NotifyOfPropertyChange( () => Messages ); } }

        public MainPageViewModel()
        {
            Messages = new ObservableCollection<MessageViewModel>();
        }
    
        protected override void OnInitialize()
        {
            base.OnInitialize();
    
            var network = new Network( Messages );
    
            network.Request();
        }
    } }
    

    Through the magic of Caliburn Micro, the public properties exposed by this ViewModel class are automatically bound to the View. In this case we are using a simple Panorama-based Windows Phone application template. The result is an application that looks like this: Screenshot of MetroYap on Windows Phone It would be nice leverage the Reactive Extensions (Rx) library to simplify access to the ExecuteAsync method, but because this method doesn't just return an IAsyncResult this is a little more involved. Sergy posted to the RestSharp group an example last year, but I assume the RestSharp and Rx libraries have changed since then as his code no longer compiles for me.