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:
| Aluminum | 0.056 mg/L |
| Alkalinity | 57-74 ppm as CaCO3 |
| Calcium Hardness | 45-56 ppm as CaCO3 |
| Total Hardness | 61 ppm as CaCO3 (3.6 grains/gal) |
| Chloride | 17 ppm |
| Foaming Agents | less than 0.1ppm |
| Total Organic Carbon (TOC) | 2.10 ppm (1.49-2.74) |
| Conductivity | 182 µS/cm (158-202) |
| pH | 7.66 (7.4-7.94) |
| Total Dissolved Solids | 113 ppm |
| Iron | less than 0.01ppm |
| Manganese | .006 mg/L (0 – 0.023) |
| Sodium | 7.5ppm |
| Potassium | 1.31 ppm |
| Sulfate | 15 ppm |
| Silver | less than 0.005 ppm |
| Silica | 1.4 ppm |
| Silicon | 0.67 ppm |
| Bromide | less tahn 0.010 ppm |
| Iodide | less than 1 ppm |
| Flouride | 0.96 mg/L (0.71 – 1.19) |
| Ammonium Ion | 0.12 ppm (0.02-0.23) |
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
}
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
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.
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:
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)
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
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.
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.
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.