Wednesday, December 11, 2013

Using the Shopify API from .NET

If you're looking for a way to talk to Shopify from .NET (either C# or VB.NET), you'll probably come across this "lightweight" .NET client.

Word of warning: it's 10 MB, and pretty hard-core.

If you're writing a private app (as opposed to a public one), things are much simpler; you don't need all the OAuth stuff for starters. After a bit of trial and error, I got this to work:




To generate an API key and password, go to http://your-store.myshopify.com/admin/apps, and click "Create a private API key" at the bottom.

Wednesday, July 17, 2013

Finance packages finally synchronising with UK banks

... so when did that happen?  This is an absolute killer feature for UK users, hats off to moneydashboard.com.

Just enter your customer number and password (you trust them, right?) and they do the leg work: automatically downloading statements, importing transactions, setting categories, etc.

So you just get to look at pretty graphs of your money disappearing.

image

The winner of worst online finance package has to be a tie between Buxfer (who can’t even get my balance right) and lovemoney.com, who should have spent as much effort on the app as they did on the error screen I got when registering.

image

Thursday, November 1, 2012

Oops... forgot to attach

Here's a quick and easy way to avoid forgetting that attachment when sending an e-mail in Outlook.

(Adapted slightly from Mark Bird's blog.)

In Outlook 2010:
  • Click on File > Options > Trust Center > Trust Center Settings > Macro Settings > Enable all macros (read the warning first)
  • Click OK twice to save options
  • Press Alt-F11
  • Expand the project tree on the left, and double-click "ThisOutlookSession"
  • Click in the right-hand pane, and paste in the code below
  • Restart Outlook again (saving changes when prompted)
You'll now get a polite message if you mention "attach" or any variation in an e-mail, but forget to attach. It's clever enough to ignore the e-mail trail.

 
Here's the code to paste in:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim m As Variant
Dim strBody As String
Dim intIn As Long
Dim intAttachCount As Integer, intStandardAttachCount As Integer

On Error GoTo handleError

'Edit the following line if you have a signature on your email that includes images or other files. Make intStandardAttachCount equal the number of files in your signature.
intStandardAttachCount = 0

strBody = LCase(Item.Body)

' text-only reply?
intIn = InStr(1, strBody, "original message")
If intIn = 0 Then

    ' html reply?
    intIn = InStr(1, strBody, "from: ")
    If intIn = 0 Then intIn = Len(strBody)

Else
    intIn = Len(strBody)
End If

intIn = InStr(1, Left(strBody, intIn), "attach")

intAttachCount = Item.Attachments.Count

If intIn > 0 And intAttachCount <= intStandardAttachCount Then
    
    m = MsgBox("It appears that you mean to send an attachment," & vbCrLf & "but there is no attachment to this message." & vbCrLf & vbCrLf & "Do you still want to send?", vbQuestion + vbYesNo + vbMsgBoxSetForeground)

    If m = vbNo Then Cancel = True
    
End If

handleError:

If Err.Number <> 0 Then
    MsgBox "Outlook Attachment Reminder Error: " & Err.Description, vbExclamation, "Outlook Attachment Reminder Error"
End If

End Sub

Thursday, June 21, 2012

iTunes and the scary "connection was reset" error

Sometimes I'm reminded why people are afraid of computers.

This morning I tried to turn on Genius in iTunes, and was confronted with a "network connection was reset" message. Helpful Apple, very helpful.

a bit like this one, but less info

From the Apple forums, it looks like a common fix is to sign out of iTunes and back in again (who'd have thought). I tried this, and got the same error trying to sign into my iTunes account.

Brilliant.

Some more Googling later, and it looks like the problem might be caused by my router’s DNS settings. What the f@#k is going on?

Ok, I’ll try pointing my router at a public DNS server. Logging into my Thomson Gateway ST585 router, it doesn't look like I can do this through the fluffy web interface. Thanks PlusNet, thanks a lot.

More Googling, and I’m told I need to spin up telnet to configure my DNS settings. This isn't the sort of thing your Gran could do while watching an episode of Murder, She Wrote*.

why the fuck do I need telnet to do this

Magically, everything now worked in iTunes-land.

I don't know what to think of all this, apart from concluding that:

  1. Software will always be complex (even if it seems like we are being shielded from this)
  2. Users can never be fully protected from the intricate mess that lies beneath a pretty interface.

On the plus side, there will always be a job for technical support staff. And what else was I going to do this morning?

* Apologies if your Gran is some kind of wiz with text-based terminal connections.

Wednesday, November 24, 2010

Visualizing data as circles in Google Maps

Datasets that include geographic or spatial data (“geodata”) are often much easier to digest on a map.  When each data point also includes a measure of size or catchment, it could be helpful to represent the point as a circle on the map, with the radius indicating its relative size.

Here’s an example showing the UK car industry, which was created using the Google Maps API (screenshot):

google_map_circles

Source (zip) – all data is fictitious; runs locally in IE

Notice that the circle radius (number of employees) and colour (status) are used to represent different aspects of each car plant.

This makes use of the latest Google Maps API (v3), which includes the ability to draw overlays.  The big winner for me was that all of this, including loading XML and looking up postcodes, could be done with pure javascript – no hosting or server-side code required.

The body of the HTML is just a single DIV element:

  1. <body>
  2.   <div id="map"></div>
  3. </body>

The rest is all javascript.  Firstly, we need to import the Google Maps and jQuery libraries – jQuery isn’t compulsory, but it makes AJAX and XML handling a lot easier.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

Loading the XML file

We can use jQuery’s .ajax() method to load the XML file, followed by calls to .find() and .each() to iterate over the elements.

$.ajax({
    type: "GET",
    url: "data.xml",
    dataType: ($.browser.msie) ? "text" : "xml",
    success: function(data) {
        var xml = toXmlDom(data);
            
        // Iterate over postcodes
        $(xml).find('project').each(function(){
            var postcode = $(projectXml).find('postcode').text();
            // ...
        });
    }
});

I’m loath to explain why we need the toXmlDom() function and conditional logic on $.browser.ie, but bascially IE returns plain text from the .ajax() call, so this needs to be converted to an XML DOM object before using .find().

Close your eyes for a second :-)

function toXmlDom(data) {
    if (typeof data != "string") return data;

    // Convert text to xml dom (IE hack)
    var xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.async = false;
    xml.loadXML(data);
    return xml;
}

Displaying the map

This just involves replacing the DIV in our HTML body with a “map” object.

var mapCenter = new google.maps.LatLng(52, -2);
var map = new google.maps.Map(document.getElementById('map'), {
    'zoom': 7,
    'center': mapCenter,
    'mapTypeId': google.maps.MapTypeId.ROADMAP
});

The tricky bit here is getting the initial latitude/longitude and zoom right – sites like www.getlatlon.com will give you a start.

Looking up a postcode

For simplicity, the XML file refers to UK postcodes.  Since the Google Maps API doesn’t include suitable geocoding support (licensing issues), we need to call another service first to get the respective Lat/Long co-ordinates.

$.ajax({
    url: 'http://www.geopostcode.org.uk/api/exact/' + postcode.replace(' ','+') + '.json',
    dataType: 'json',
    success: function(response) {
        var lat = response.wgs84.lat;
        var lon = response.wgs84.lon;
        // ...
    }
});

Notice that .ajax() method again, which simplifies the asynchronous HTTP request to www.geopostcode.corg.uk.  By default, the results of the AJAX call are cached by the browser.

Drawing a circle

This is done in two stages: create a Marker, then draw a Circle which is bound to its position (read the full API).

// Create marker
var marker = new google.maps.Marker({
  map: map,
  position: new google.maps.LatLng(53.1, -2.44),
  title: 'The armpit of Cheshire'
});

// Add circle overlay and bind to marker
var circle = new google.maps.Circle({
  map: map,
  radius: 10000,    // metres
  fillColor: '#AA0000'
});
circle.bindTo('center', marker, 'position');

The Marker and Circle are both google.maps.MVCObject instances, so their values can be tied together using bindTo().  So, for example, setting draggable:true on the Marker would mean that the Circle would follow it around the map.

I suggest you download the source code and see how it all hangs together.

Tuesday, November 9, 2010

Gmail Notes syncing missing in iOS 4.1

Rant time…

So the iOS 4.1 update seems to have fixed the speed issues that plagued the iPhone 3G since iOS 4 was introduced.  However, what I’ve only just noticed is that Apple have removed functionality from the 3G in order to do this:

The second one is an absolute PITA for me.  Apple are renowned for adding only minimal functionality to their products over long periods of time (copy-and-paste anyone?) but to remove features after already adding them – that’s much more annoying.

Add to this the fact that iOS 4.1 made me get up late due to the alarm bug it introduced, and I’m definitely not being an early adopter for the next update.  Grr.

Tuesday, August 31, 2010

VMWare black screen of death

Ever had a black screen when loading up a VMWare image?  Try booting into safe mode and deleting your display adapter from Device Manager, then restarting.  (Don’t worry, the adapter should reinstall automatically.)

Device Manager

This issue seems to appear after changing monitors – in my case, when I unplug an external monitor from my laptop.  I’m running a Windows Server 2008 guest VM on a Windows 7 host, under VMWare Player 3.1.0.

Another workaround here.