Panasonic LUMIX MapTool.pkg – Open Source edition

0 Comments

The Panasonic LUMIX DMC-TZ40 Digital Camera

The Panasonic LUMIX DMC-TZ40 Digital Camera, in a word, excellent!

I recently upgraded my compact travel zoom camera from the tried and trusted Sony DMC-HX9V to the Panasonic DMC-TZ40. It's quite an upgrade and while I'm delighted by my new purchase, the review will have to wait now that I can use a major feature: MAPS!

Maps! On a Digital Camera! What ever will they think of next!

Maps! On a Digital Camera! What ever will they think of next!

Yes, as well as GPS Geotagging of photographs, the Panasonic LUMIX DMC-TZ30 (ZS20) and Panasonic LUMIX DMC-TZ40 (LZ30) come with Map Data that you can use to find your way to your next photo shooting location, or back to your hostel if you find yourself lost!

The Map Data comes on the CD-ROM / DVD with the camera, along with a little application called the LUMIX Map Tool. There's a version for Microsoft Windows and Apple Mac OSX, but not for Linux.

To save on space I'd copied the contents of the DVD onto a USB drive so I could update the map data while travelling, but the only thing that didn't copy was the Apple Mac OSX version of the LUMIX MapTool.pkg!

It took a bit of Googling, but I eventually found a great blog post by Roland Kluge where he'd written a simple script version of the tool for his LUMIX DMC-TZ31 - and after reading the comments I was able to modify his script to make it work for my new LUMIX DMC-TZ40.

I cannot stress how thankful I am for his work and the comments on his post - thank you Roland, and thank you commenter Falk

Introducing LUMIX Map Tool - Open Source edition :o)

My contribution to Roland Kluge's Simple Replacement for Lumix Map Tool

My contribution to Roland Kluge's Simple Replacement for Lumix Map Tool

I've forked Roland's code and added support for the Lumix DMC-TZ40, and I thought I'd make it a little more interactive as I'm not likely to change the Map Data too often.

Simply download the maptool.py file from the GitHub repository and run it with..

$ python maptool.py

.. and it will prompt you for the information it needs to get the Map Data from your DVD onto a formatted SD Card - maps away!

Setting up Django on Windows Azure Websites

0 Comments

A couple of things caught me out when I was trying to deploy a Django application to Windows Azure, so I'm making a note of them here for future reference. Oh, and I hope they might be of use to you as well :smiley:

Configuring Azure Websites to run Python and Django

The Windows Azure Websites and Django getting started tutorial directs us to put the required settings into the Azure management portal, but that's not how Microsoft do it in the Gallery, oh no. If we create a Django application from the Windows Azure Website gallery, the resulting site puts all the configuration into a web.config.

Personally, I like the management portal approach, but I did play with the web.config and got it working for my custom site, so I present it here in case this works for you:

<configuration>
  <appSettings>
    <add key="PYTHONPATH" value="D:\home\site\wwwroot;D:\home\site\wwwroot\site-packages" />
    <add key="WSGI_HANDLER" value="django.core.handlers.wsgi.WSGIHandler()" />
    <add key="DJANGO_SETTINGS_MODULE" value="{django-app-name}.settings" />   
  </appSettings>
  <system.webServer>
    <handlers>
      <add name="Python_FastCGI"
           path="handler.fcgi"
           verb="\*"
           modules="FastCgiModule"
           scriptProcessor="D:\Python27\python.exe|D:\Python27\Scripts\wfastcgi.py"
           resourceType="Either"
           requireAccess="Script" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="Django Application" stopProcessing="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="handler.fcgi/{R:1}" appendQueryString="false" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

There are three things you need to do to get this working:

  1. Check the PYTHONPATH - It needs pointing to the root of your Django Application (the directory that holds manage.py, and the location of the directory site-packages (obviously, copy that directory into Azure from your development environment if it's not there)
  2. Set DJANGO_SETTINGS_MODULE - Point this to your settings.py file. Replace directory slashes / with dots, and omit the .py from the end
  3. Create the file handler.fcgi - This is required, and it's a just a plain text file containing two double-quotes (i.e. "") on the first line followed by a return carriage

Seriously though, just put the settings into the Azure management portal. It's easier :smiley:

Bad Request (400)

Following the advice in settings.py the first thing I did after copying the files into Azure and seeing the Django "cool, now get cracking" default page was to trip DEBUG to False (DEBUG = False), then refresh the web browser..

"Django on Windows Azure Websites - Bad Request (400)"

Django on Windows Azure Websites - Bad Request (400)

Ouch.

Essentially, if DEBUG is False, we have to put our server's URL into the ALLOWED_HOSTS setting. Now, we could do that in settings.py but this is really Azure specific just like the configuration above, so it really belongs in Azure.

In the Azure management portal, under the "Website > Configure" tab, find the "app settings"; section near the bottom and add the following:

Setting Value
ALLOWED_HOSTS Your Azure URL: e.g. mydjangosite.azurewebsites.net

If you have custom domains pointed at Azure, you can use a space-separated list like so: mydjangosite.azurewebsites.net myjangosite.com
SECRET_KEY While we're adding new application settings, create a new 50 character random string and copy it here. We'll use it in a second

Now, we could just modify our settings.py, but it's much better to have a configuration file specifically for production / Azure, so first of all, copy your existing settings.py to a new file in the same directory - I like to use the filename settings_azure.py.

Now, assuming you have a shiny new settings_azure.py file, delete everything in it and replace it with this:

from settings import *

Now just overwrite the important settings

SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = os.getenv('SECRET_KEY')  #  - defined in Windows Azure app settings

SECURITY WARNING: don't run with debug turned on in production!

DEBUG = False

TEMPLATE_DEBUG = DEBUG

ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS').split()  #  - defined in Windows Azure app settings

Handy file logging, in case we run into problems on production

### Uncomment to log Django errors to the root of your Azure Website
"""
LOGGING = {
  'version': 1,
  'disable_existing_loggers': False,
  'filters': {
    'require_debug_false': {
      '()': 'django.utils.log.RequireDebugFalse'
    }
  },
  'handlers': {
    'logfile': {
      'class': 'logging.handlers.WatchedFileHandler',
      'filename': 'D:/home/site/wwwroot/error.log'
    },
  },
  'loggers': {
    'django': {
      'handlers': ['logfile'],
      'level': 'ERROR',
      'propagate': False,
    },
  }
}
"""

If you created this new settings_azure.py file, don't forget to adjust the DJANGO_SETTINGS_MODULE value to point to it in the Azure management portal, or your web.config if you went that route, you heathen!

Extending System.Data.Linq.Table<T> – Exportable Linq2SQL Classes

0 Comments

Wouldn't this be handy?:

using (var db = new DataContext()) {
    return db.StockItems.ToXElement();
}

I've found this approach useful when working on API's which essentially provide access to data that closely mirrors Linq2SQL generated classes. It makes it easy to control which properties are included, and how they are formatted.

First, we declare an interface that we can decorate our Linq2SQL classes with. Note that I'm returning an XElement here, but this could be JSON or something else:

IXElementable.cs:

using System;
using System.Xml.Linq;

public interface IXElementable {
    XElement ToXElement();
}

Then we augment the Linq2SQL classes we wish to be exportable, using Partial Classes as we'd normally do:

e.g. StockItem.cs:

public partial class StockItem: implements IXElementable {
  // ..
  public XElement ToXElement() {
    return new XElement("StockItem",
           new XElement("StockItemId", Id),
           new XElement("PartNo", PartNo),
           new XElement("QtyInStock", QtyInStock),
           new XElement("QtyOnOrder", StockOrders
             .Where(o => o.Status == (int)StockOrderStatuses.Outstanding)
             .Count()),
           new XElement("CreatedDate", CreatedDate.ToString("u")));
  }
  // ..
}

Finally, we extend the Linq Table class itself:

TableExtensions.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
using System.Xml.Linq;

public static class TableExtensions {

  /// <summary>
  /// Returns an XElement (XML) representation of the Table and its data
  /// <remarks>Note that data objects in the Table need to implement IXElementable&lt;/remarks>
  /// </summary>
  public static XElement ToXElement<T>(this Table<T> table) where T: class {

    var xml = new XElement(GetTableName(table));

    foreach (var item in table) {
      try {
        xml.Add(((IXElementable)item).ToXElement());

      } catch (Exception ex) {
        Log.Write(string.Format("Table: {0}.ToXElement", xml.Name), ex);
        
        // no point continuing..
        break;
      }
    }

    return xml;

  }

  private static string GetTableName<T>(Table<T> table) where T: class {
    // a bit of a hack, but there doesn't seem to be a nice way to get the Linq2SQL table name

    string tableName = table.GetType().ToString().Split('.').Last().Trim(']');

    // pluralise it..
    if (tableName.EndsWith("y"))
      tableName = tableName.TrimEnd('y') + "ies";
    else
      tableName += 's';

    return tableName;
  }
}

And that's it!

As you can see, this approach affords us complete control over the Linq2SQL generated properties and the format they're serialised to, and it makes it really easy to omit properties without having to re-implement them in the Partial class just so we can add the [XmlIgnore] attribute.