tswebclient.js

Doing some web development, using Chrome’s Developer Tools & got the javascript console open. Every time an HTTP GET fires sync or async, I get 4 lines in the console from “tswebclient.js” spamming my console.

This comes from the TrueSuite software that runs my Eikon USB fingerprint scanner on OS X (Mountain Lion). Disabling the Chrome extension keeps my console nice & clean for my *own* debug messages.

Advertisements

Data Matrix Library

Celebrate!

libdmtx is a library for generating Data Matrix images.

Steps require to install the libdmtx package and python wrapper on CentOS 5.2

yum install ImageMagick
yum install ImageMagick-devel
yum install python-imaging

Untar source, enter libdmtx-x.x.x directory.
./configure
make
(as root) make install

cd wrapper/python/
python setup.py install
/sbin/ldconfig /usr/local/lib
python test.py

Celebrate!

Webware for Python + Apache 2 on CentOS… Inside a VM

This post is a codicil to these instructions when attempting to replicate the described setup in a VM, specifically in VMware Fusion on OS X.

Following standard operating procedure results in:
Error: Can not listen for Adapter on (‘localhost’, 8086)

Make sure to disable or otherwise adjust SELinux and firewall settings to allow connections on port 80 and 8086.

Inside the WebKit-related <Location > directive of the Apache configuration file, use “127.0.0.1” instead of “localhost”.

Inside your WebKit working directory, find the Configs directory, and edit AppServer.config. Change the line:
Host = “localhost”
… to…
Host = “”
… for listening on all interfaces, as the file describes.

Bounce both servers; experience victory.

Calculating Opacity’s Effect on Color

In icon view (or on the desktop), OS X draws a subtle box around the icon when an item is selected. It’s a rounded-corner box with a slightly-darker background, and a slightly-lighter border. This approach guarantees that the user will be able to recognize their selection regardless of background color or brightness (e.g., desktop wallpaper). Check it:

Using Photoshop, I determined that the color changes are equivalent to overlaying the background color with black & white at 30% opacity.

For possible use on various work-related projects, here is how to accurately determine new RGB values to simulate a black or white overlay at various opacities using Python.

def dark (val, pct):
    return int(round(val*(1.0-(pct/100.0))))

def light (val, pct):
    return int(round(val+((255-val)*(pct/100.0))))

def darken (R, G, B, pct):
    return (dark(R, pct), dark(G, pct), dark(B, pct))

def lighten (R, G, B, pct):
    return (light(R, pct), light(G, pct), light(B, pct))

Let’s try it with the following image I created using Layer opacity in Photoshop. The base color green is R:61, G: 136, B: 28. I then created a white layer at 27% opacity and filled in the left third of the image. I filled in the right third with a black layer set to 47% opacity. I then flattened the image & saved it as the PNG shown here.

I then ran the 2 functions.

>>> lighten(61, 136, 28, 27)
(113, 168, 89)
>>> darken(61, 136, 28, 47)
(32, 72, 15)

I compared the output to the RGB values reported by Photoshop in the final, flattened PNG, and they matched.

Installing Python 2.5 on QNAP TS-859

Hardware: QNAP TS-859 with 8 1TB Seagate drives running RAID5 + hot spare.
Firmware: 3.2.7 Build 0526T

In the management web interface, I went to “Applications”, then “QPKG Plugins”. I then clicked the “Get QPKG” button to retrieve the proper Python package for the hardware. Unzipped it.

Attempted the install via the “Installation” tab in the web interface. It got to about 20% completion, then failed. The log was less than helpful:

Python 2.5.2 has been installed in /share/MD0_DATA/.qpkg/Python.

Attempted again. Failed again at the same spot. The log said:

Python 2.5.2 installation failed. /share/MD0_DATA/.qpkg/Python existed. Please remove it first.

After a bit of googling, I found this page, which suggested I SSH into the device as admin, and delete the directory due to some permissions problems.

[~] # cd /share/MD0_DATA/.qpkg/
[/share/MD0_DATA/.qpkg] # rm -rf Python/

I then attempted the install via the web interface one more time. It said it was successful… but just to be sure…

[/share/MD0_DATA] # which python
/usr/bin/python
[/share/MD0_DATA] # python
Python 2.5.2 (r252:60911, Jul 25 2008, 01:52:53)
[GCC 4.2.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Victory.

Things I Needed to Jot Down or Lose Forever

Messing around with SQLite and pysqlite, I compiled some basics & datetime examples.

Erin while nursing the Beanlet: “I don’t know why… but I love this song”. TLC commercial for the midget farmers show & the Jesusfreaks with eight kids.

I realized I was a father when another human being farted directly into my cupped palm mere inches from my face, and I thought it was adorable. Had the diaper not been there, it would have been much less adorable.

Erin scolding me while pointing to Beanlet: “Until you grow boobs… that can produce milk… you are not allowed to wake up our son.”

I roasted a turkey yesterday (my first time) following this recipe; I am embarrassed just linking to it.

On CentOS: “yum install sqlite-devel” is required before attempting to compile pysqlite from source.

To be continued…

Square Peg, Round Hole

Sitting in the wine aisle at the grocery store… wondering which brand to buy. Have we had that before? If so, was it good or did it suck?

I know: I’ll hit our cork’d page to see what we’ve reviewed! On my new cell phone! Shit, that site loads slowly. They only show 15 wines at a time. And, they show the average score for the wine. I don’t care about that shit; I need to know how we ranked it.

Oh, look! They have an RSS feed for us. Uh oh, no RSS reader app on the cell phone. Even then, the feed only supplies the name of the wine, and provides a link to its collective cork’d review.

Gah! This blows.

If you want something done right, do it yourself:

import urllib2
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup

RSS_FEED = 'http://www.corkd.com/feed/journal/xiix'
USERID = u'xiix' # unicode nec.

def getPage(URL):
    page = urllib2.urlopen(URL)
    txt = page.read()
    page.close()
    return txt

def getScore(URL):
    soup = BeautifulSoup(getPage(URL))
    for a in soup('a'):
        al = a.contents
        if USERID in al:
            for abbr in a.findAllNext('abbr'):
                if (u'class', u'rating') in abbr.attrs:
                    return abbr.contents[0]

def fetchScores():
    FINAL = {}
    txt = getPage(RSS_FEED)
    soup = BeautifulStoneSoup(txt)
    for x in soup('item'):
        winename = x.title.string
        revlink = x.link.string
        FINAL[winename] = getScore(revlink)
    return FINAL

Stick that shit in a weekly cronjob. Sort and format the output for victory.

WIN: The Low-Overhead, Fast-Loading, Cell-Phone-Compatible List of Wines and Scores

Unicode Trial by Fire

As part of our Intranet at work, I created a web interface to collect textual data, which then publishes a PDF containing it, as well as other data from other sources. Given this interface, people will inevitably paste text into the form from Microsoft Word.

What appears in Word as:

“this is inside curly quotes”

… when read by Python becomes:

'\xe2\x80\x9cthis is inside curly quotes\xe2\x80\x9d'

I had been using ReportLab 1.21 to generate these PDFs. At that point, I had a function that would replace all the weird Word character encodings with a different encoding that would render properly in the final PDF. Without this function, the PDF generation would hang indefinitely, or throw a nasty traceback. E.g.,:

txt = txt.replace('\xe2\x80\x9c', '\x93') # double left quote
txt = txt.replace('\xe2\x80\x9d', '\x94') # double right quote
... etc.

All this broke when I upgraded the ReportLab installation to version 2.2.

Section 3.1 of the ReportLab 2.2 User Guide states:

Starting with reportlab Version 2.0 (May 2006), all text input you provide to our APIs should be in UTF8 or as Python Unicode objects.

So this was to be my Unicode trial by fire.

I fuckin’ tried everything Unicode-related that I could think of. All of my attempts were semi-educated stabs in the dark. All of my hopes were subsequently dashed by the dreaded UnicodeDecodeError.

Findings:

1. My default encoding is 'ascii', and there’s no simple way to change it.
2. What I now know is that the function used with 1.21 was changing the encoded characters from (ostensibly) UTF-8 to CP-1252.
3. BUT, the information was being saved as a straight ASCII string (see 1) even though the data was (ostensibly) UTF-8 encoded.
4. All attempts to convert this to Unicode failed. Until…

>>> txt = '“crazy shit”'
>>> txt
'\xe2\x80\x9ccrazy shit\xe2\x80\x9d'
>>> print txt
“crazy shit”
>>> txt.decode('utf-8')
u'\u201ccrazy shit\u201d'
>>> print txt.decode('utf-8')
“crazy shit”

Yeah, so it seems logical in retrospect. Word uses something close to UTF-8, so the text with crazy characters in it needs to be converted to Unicode by way of decoding the UTF-8 encoding.

What a huge pain in my ass.

Upshot:
If using ReportLab 1.21, convert UTF-8 to CP-1252 for it to render properly in the PDF. If using ReportLab 2.x, txt.decode('utf-8') and go from there.