Champlain Valley Water Quality, 2009

I missed putting up the water quality numbers from this spring, but in the mean time it turns out the Champlain Water District has the Water Quality Reports up on the web. Unfortunately, they’re huge PDFs since they seem to be simply bitmap scans of the paper report. :(

In any case, here’s the relevant homebrewer water quality details:

Aluminum0.056 mg/L
Alkalinity57-74 ppm as CaCO3
Calcium Hardness45-56 ppm as CaCO3
Total Hardness61 ppm as CaCO3 (3.6 grains/gal)
Chloride17 ppm
Foaming Agentsless than 0.1ppm
Total Organic Carbon (TOC)2.10 ppm (1.49-2.74)
Conductivity182 µS/cm (158-202)
pH7.66 (7.4-7.94)
Total Dissolved Solids113 ppm
Ironless than 0.01ppm
Manganese.006 mg/L (0 – 0.023)
Sodium7.5ppm
Potassium1.31 ppm
Sulfate15 ppm
Silverless than 0.005 ppm
Silica1.4 ppm
Silicon0.67 ppm
Bromideless tahn 0.010 ppm
Iodideless than 1 ppm
Flouride0.96 mg/L (0.71 – 1.19)
Ammonium Ion0.12 ppm (0.02-0.23)

mysql[-bin]-5.1.40 ebuild

I had a pressing need for mysql-5.1.40 to be installed for work reasons a couple of weeks ago, and found the state of mysql releases in gentoo to be lacking. I cobbled together the following ebuild using the binary RPM distribution from mysql.com. It should probably be called “mysql-bin”, but whatever.

inherit eutils rpm
 
# http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-server-5.1.40-0.glibc23.x86_64.rpm/from/pick
 
MY_P=MySQL-server-${PV}
 
SRC_URI="http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-server-${PV}-0.glibc23.x86_64.rpm
    http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-client-${PV}-0.glibc23.x86_64.rpm
    http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-shared-${PV}-0.glibc23.x86_64.rpm
    http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-devel-${PV}-0.glibc23.x86_64.rpm"
DESCRIPTION="MySQL-5.1.40 RPM"
HOMEPAGE="http://www.mysql.com"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="amd64"
IUSE=""
 
src_install() {
    dobin usr/bin/*
 
    dosbin usr/sbin/*
 
    dolib usr/lib64/*
 
    insinto /usr/include/mysql
    doins usr/include/mysql/*
 
    insinto /usr/share/aclocal/mysql
    doins usr/share/aclocal/mysql.m4
 
    dodoc usr/share/doc/MySQL-server-5.1.40/*
 
    doman usr/share/man/man1/*
    doman usr/share/man/man8/*
 
    insinto /usr/share/mysql
    doins usr/share/mysql/*
    insinto /usr/share/mysql/charsets
    doins usr/share/mysql/charsets/*
    insinto /usr/share/mysql/english
    doins usr/share/mysql/english/*
 
#/etc/logrotate.d
#/etc/logrotate.d/mysql
}

django timezone view handling

One simple way to handle user-time-zone localization in an app is to always store the timestamp in UTC, and localize viewing/editing of that timestamp in a specific timezone.

By default, Django traffics in the single settings.py-configured timezone.

Timezone handling appear incomplete. The two options you’ll run across are this snippet for a timezone-localizing filter and django-timezones.

django-timezones has support for a TimeZone model/view field, and a model/view LocalizedDateTimeField. The View field, however, will only do the parse-time conversion of the datetime value in to the settings-defined TZ. This only solves half of the problem, since you still need to convert the settings-defined TZ into the user’s TZ, and there’s no component for that.

The following is a LocalizedDateTimeInput widget which will handle this last step, building on django.forms.DateTimeInput and django-timezones’ utility code:

from django import forms
from timezones.utils import adjust_datetime_to_timezone
 
class LocalizedDateTimeInput (forms.DateTimeInput):
    def __init__(self, tz):
        self._tz = tz
        super(LocalizedDateTimeInput, self).__init__()
 
    def render(self, name, value, attrs=None):
        if isinstance(value, datetime):
            value = adjust_datetime_to_timezone(value, 'UTC', self._tz)
        # @fixme: output the string rep of the timezone, probably after the <input />
        return super(LocalizedDateTimeInput, self).render(name, value, attrs)

Unfortunately, you’ll need to add a level of indirection to your view Form constructors to bind the ‘tz’ argument on the widget. Instead of a normal:

class MumbleForm (forms.Form):
    name = forms.CharField()
    date = forms.DateTimeField()

You’ll want to do something like:

def MumbleForm(user, *args, **kwargs):
    tz = settings.TIME_ZONE
    if user and hasattr(user, 'get_profile'):
        tz = user.get_profile().timezone
 
    class _MumbleForm (forms.Form):
        name = forms.CharField()
        date = LocalizedDateTimeField(tz, widget=LocalizedDateTimeInput(tz))
 
    return _MumbleForm(*args, **kwargs)

You can see more usage examples from the brew-journal commit.

Any tips or improvements welcome, of course.

Update, 2009-11-28: I finally got around to moving to using mysql instead of sqlite for this project, and discovered that the above solution needs one more piece. The default LocalizedDatetimeField seems to return datetimes which are “[tz] aware” in python’s vernacular, but mysql complains that datetimes with a tz portion are not allowed. So, we add a SafeLocalizedDateTimeField that returns “naive” datetimes instead:

class SafeLocalizedDateTimeField (LocalizedDateTimeField):
    def clean(self, value):
        val = super(SafeLocalizedDateTimeField, self).clean(value)
        if val is not None:
            val = val.replace(tzinfo=None)
        return val

configuring tomcat6 for https with cargo

cargo is a nifty tool for launching containers from, say, ant. While it doesn’t contain official support for Tomcat6, the Tomcat5 support works just fine with Tomcat6.

There is a property, cargo.protocol, where you can specify https, however, the resulting server.xml that it generates will not be quite correct. A hack-fix is to edit org/codehaus/cargo/container/internal/resources/tomcat5x/server.xml in the jar file to include «SSLEnabled=”true”». As well, you might want to add the appropriate attributes for the relevant keyfile-path, otherwise, it seemed to use $(HOME)/.keystore, which I was happy to provide.

Champlain Valley water analysis, Spring 2008

As a South Burlington homeowner (water-bill-payer, really), the Champlain Water District sends me a report about how their water is the best water. Of note to me as a homebrewer is the analysis of certain chemical properties of the water. Since a few google searches for this information basically turned up my previous post and not the actual source of the data, here’s the data:

  • aluminum: < 0.06ppm
  • color: 2 units
  • alkalinity: 57-74 ppm as CaCO3
  • calcium hardness: 45-56 ppm as CaCO3
  • total hardness: 61 ppm as CaCO3
  • chloride: 17ppm
  • foaming agents: < 0.1 ppm
  • total organic carbon: 2.04 pm (1.49-2.61)
  • conductivity: 192 micro-S/cm (156-194)
  • pH: 7.62 (7.39-7.79)

  • total disolved solids: 113 ppm

  • iron: < 0.01ppm
  • manganese: .007ppm
  • sodium: 7.5ppm
  • potassium: 1.31 ppm
  • sulfate: 15 ppm
  • silver: < 0.05ppm
  • silica: 1.4ppm
  • silicon: 0.67 ppm
  • bromide: < 0.010 ppm
  • iodide: < 1 ppm
  • flouride: 1.01 ppm (0.74 – 1.28)
  • ammonium ion: 0.15 ppm (0.01 – 0.32)

Champlain Valley water anlysis, 2007

Since the previous water analysis from 2005, I’ve since bought a house, which means the Champlain Water District sends me a report about how their water is the best water. Of note to me as a homebrewer is the analysis of certain chemical properties of the water. Since a few google searches for this information basically turned up my previous post and not the actual source of the data, here’s the data:

  • aluminum: < 0.06ppm
  • color: 2 units
  • alkalinity: 42-56 ppm as CaCO3
  • calcium hardness: 45-56 ppm as CaCO3
  • total hardness: 61 ppm as CaCO3
  • chloride: 17ppm
  • foaming agents: < 0.1 ppm
  • total organic carbon: 2.22 pm (1.60-3.1)
  • conductivity: 189 micro-S/cm (163-208)
  • pH: 7.56 (7.29 – 7.89)
  • total disolved solids: 113 ppm
  • iron: < 0.01ppm
  • manganese: .007ppm
  • sodium: 7.5ppm
  • potassium: 1.31 ppm
  • sulfate: 15 ppm
  • silver: < 0.05ppm
  • silica: 1.4ppm
  • silicon: 0.67 ppm
  • bromide: < 0.010 ppm
  • iodide: < 1 ppm
  • flouride: 0.97 ppm (0.71 – 1.21)
  • ammonium ion: 0.20 ppm (0.04 – 0.048)

java array iteration

Java5 now has language support for iteration of the form:

    for (Type var : someIterable) { ... }

As well, there is now an Iterable<t> interface, and Arrays are directly iterable, allowing you to write:

    String[] thingys = {"a","b","c"};
    for (String thingy : thingys) { ... }

At work, we have a collection of utility iterators, most written before these were available. As such, we have an ArrayIter utility, and a ZipIterator, inspired by Python’s itertools.izip.

I’ve been going through these classes and their usages on a lazy basis to update them to the new syntax. I finally got around to a usage of the ZipIterator, which happened to compose an ArrayIter … it zipped together an array of String names with the results of a test.

So, I changed it to:

    String[] names = { "foo", "bar", "baz" };
    List results;
    for (Object[] pair : new ZipIterator(names, results))
    {
    // ...

No dice, says Java:

/home/jsled/stuff/work/[...]TestMumble.java:46: cannot find symbol symbol  : constructor ZipIterator(java.lang.String[],java.util.List)
location: class com.spokesoftware.util.iterator.ZipIterator
for (Object pairObj : new ZipIterator(data, results))

WTF? Okay, let me help you out:

    for (Object[] pair : new ZipIterator((Iterable)names, results))
    // ...

FUCK YOU, says Java:

/home/jsled/stuff/work/[...]/TestMumble.java:46: inconvertible types
found   : java.lang.String[]
required: java.lang.Iterable
for (Object pairObj : new ZipIterator((Iterable)data, results))

It turns out that the string “iter” isn’t even in the text of the section about Arrays in the Java Language Spec. Array instances aren’t Iterable. They’re a special case in the handling of the for-each loop syntax.

This code ended up as:

    for (Object pair : new ZipIterator(Arrays.asList(names), results))

Java is totally shitrude.

edit 2009-10-10: added some formatting/syntax highlighting of the java blocks

rstiki-1.1

Felix Wiemann of docutils was kind enough to write and point out that docutils doesn’t protect against various kinds of malicious markup and content inclusion. He notes that there are a couple of options to prevent such inclusion.

While I don’t intend to use rstiki on a public-facing web server, others might, and docutils makes it very easy to disable such inclusion. So, it does by default, now.

rstiki-1.1 also sports a new link to the rST quickref.

rstiki – minimalist wiki using reStructuredText

I used to use phpwiki for a personal, behind-the-firewall wiki. It was simple, though it was many files, and gentoo packaged it. Then, there was a version upgrade that required a database and lost all my (handful of) content. I switched to pwyky because it was a single file, simple, and SBP wrote it. But its syntax doesn’t support nested lists, and it’s not reStructuredText.

rstiki is a minimalist single-file CGI wiki, in python, which uses docutils to render reStructuredText markup.

wish (x10dev) 2.1.5 ebuild

I got frustrated last week and fixed the wish-2.1.3 ebuild to install the /dev/x10 nodes into /lib/udev/devices/. It was relatively hard to find this out, but when traditional mknod-created nodes are in this directory, they’ll be copied into the otherwise-dynamic /dev tree at boot time. As such, wish finally boots cleanly.

In the course of trying to track down other system lockups, I upgraded to the 2.6.18 kernel, and wish-2.1.3 stopped building for me. A devfs header file that it used was finally deprecated out of the module-building header directory. Luckily, in the mean time, wish-2.1.5 was released without this dependence on devfs. I re-generated the patches, and updated the bug to be an ebuild for wish-2.1.5, a.k.a. x10dev.