Elmpowered with elm trees on your side, you can do anything

30Mar/120

First, there was DOCTYPE…

Per W3 HTML doctype declaration,

The <!DOCTYPE> declaration must be the very first thing in your HTML document, before the <html> tag.

 Remembering that can save you quite a number of headaches.

I've been developing a Website using Django and Twitter's Bootstrap CSS library. After my HTML templates were rendered, an HTML comment, not the DOCTYPE declaration, ended up as the first line. I didn't catch the oversight at first, as the pages rendered correctly in Chrome and Firefox. Internet Explorer, however, was a completely different story.

Easy enough to fix, as long as you know where to look.

9Mar/124

Accessing an element’s parent with ElementTree

Today I ran across a situation where I needed to programmatically remove specific elements from a KML file. I was already using Python's ElementTree library for my KML processing, so I attempted to use ElementTree's remove() method. The remove() method can only remove subelements, requiring access to the undesired element's parent.

No problem, right? Even though there isn't a parent attribute or getparent() method for elements, ElementTree 1.3 introduced an XPath expression to get an element's parent.

Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as et
>>> et.VERSION
'1.3.0'
>>> tree = et.parse('test.kml')
>>> xmlns = '{http://www.opengis.net/kml/2.2}'
>>> elem = tree.find('.//%scolorMode' % xmlns)
>>> elem
<Element '{http://www.opengis.net/kml/2.2}colorMode' at 0x7f4bfc04a650>
>>>
>>> elem.find('..')
>>>

Turns out, that's not how things work in the world of ElementTree. An element actually has no reference back to its parent, thus explaining the lack of a getparent() type method for the element...and why elem.find('..') returns None.

There are a couple different solutions at this point. You can create a generator that will iterate over your tree, returning (parent, child) tuples (detailed here) or use lxml, which is ElementTree compliant and supports a getparent() method for elements.

However, if you're like me, you'll feel an inability to move on until you figure out why the XPath isn't working like you think it should. You might be tempted to think that something is broken with ElementTree, but, as is almost always the case, the problem is a user error.

It actually took a fair amount of thinking and a suggestion from my good friend Ryan to figure this out. Basically, since the element doesn't contain a reference to its parent, we need to go up a level (to the tree) in order to get the parent node using the '..' XPath expression.

>>> tree.find('.//%scolorMode/..' % xmlns)
<Element '{http://www.opengis.net/kml/2.2}LineStyle' at 0x7f4bfc04a490>

Now you have the parent element, so removing the undesired child element (colorMode, in this case) is relatively simple.

>>> parents = tree.findall('.//%scolorMode/..' % xmlns)
>>>
>>> for parent in parents:
...         parent.remove(parent.find('%scolorMode' % xmlns))
...
>>>

11Jan/120

Installing Git man pages

http://www.codeography.com/2009/09/15/install-git-man-pages-the-easy-way.html

6Jan/122

Getting rid of the Master Password Prompt in Netbeans 7.0.1

I recently installed Linux Mint 12 on my work computer (which I recommend if you're having trouble adjusting to Gnome 3. It's a nice in between option). Part of getting everything setup was to install Netbeans. Nice and easy, except that I started getting prompted for a master password every single time I launched Netbeans. Not only was this severely annoying, but it was causing Netbeans to freeze (this is most likely a problem with my work's NFS mounts, not Netbeans). No good.

A quick Google search brough me to the Netbeans Master Password Wiki entry, which does a good job of explaining what's going on. Basically, Netbeans was having some problems using Gnome's keyring.

I followed the suggestion and started Netbeans up with -J-Dorg.netbeans.modules.keyring.level=FINE and looked at the log file (located at ~/.netbeans/7.0/var/log/ in my case). Toward  the end fo file, I saw:

java.lang.UnsatisfiedLinkError: Unable to load library 'gnome-keyring': libgnome-keyring.so: cannot open shared object file: No such file or directory

which was odd, since libgnome-keyring was already installed.

More by chance than anything else, I noticed that libgnome-keyring-dev wasn't installed. Taking a shot in the dark, I installed it (sudo apt-get install libgnome-keyring-dev) and restarted Netbeans. Guess what? I wasn't prompted for a master password.

Sweet, sweet bliss.

1Sep/110

Running tinyca2 via a link

I recently downloaded and installed (re: uncompressed) tinyca2. I plan on using it to aid in creating PKI certificates and blah blah blah. That part really isn't the point.

tinyca2 launches via a Perl script. Within the Perl script, there are two locations that need to be modified if you want to make a link to the executable (to add it to the $PATH, for example). By the way, this is mentioned in step 2 of the INSTALL file.

On line 21, change

BEGIN { unshift(@INC, './lib'); }

to point to where tinyca2 is actually installed:

BEGIN { unshift(@INC, '/home/skawaii/apps/tinyca2-0.7.5/lib'); }

Similarly, change line 80 from

$init->{'templatedir'} = "./templates";

to

$init->{'templatedir'} = "/home/skawaii/apps/tinyca2-0.7.5/templates";

After that, assuming your link is in a directory already on your $PATH, you can launch tinyca2 from anywhere.

Tagged as: , , No Comments
28Apr/110

Adding/Removing Branches on GitHub

Recently, GitHub added an auto merge button (detailed here). While this is a really nice feature, some comments raised a concern about auto-merging untested changes into your master branch. The response from GitHub --  don't target your master branch with pull requests. Create an "integration" branch. So, the question that came to my mind immediately was, "How do I add new branches to GitHub?"

Turns out, it's pretty darn easy. After creating the new branch in your local repo, add the new branch to GitHub with a simple git push:

git push origin integration

Conversely, if you want to remove a branch from GitHub:

git push origin :integration

See the git-push man page for more details (especially the examples section).

Tagged as: , , , No Comments
23Sep/100

Trac Email Notifications via sendmail on Hostmonster

While setting up Trac's email notification module to use sendmail, I kept seeing an error in my server's log. Something along the lines of "sendmail: no recipient specified...". That was confusing since I was pretty sure I set a recipient (or rather, I was trusting that Trac was).

After having the bright idea to turn Trac's logging feature on, I got a friendly message while creating a new ticket. The message informed me that I can't use a fake email address (I was attempting to use trac@mydomain.com). That makes sense if you stop to think about it. Hosting companies, such as Hostmonster, don't want you using their servers to spam the world. Allowing the use of a fake email address would allow the very sort of spamming to take place.

So, easy solution: use a real email address; or, in my case, make the fake email address real by creating it in CPanel.

21Sep/102

Enabling Trac Authentication on a Shared Host

As a complete Trac newbie, I thought I'd write up the steps I went through in order to enable Trac authentication on a shared host. I couldn't find these instructions (explicitly) anywhere else, so hopefully others will find them useful. If not, then at least I have written instructions for my own sake.

I did this with Trac 0.12, but the steps should be the same for Trac 0.11. YMMV for older versions of Trac.

Installing Trac on a shared host is a pretty straight-forward operation -- just follow the TracInstall guide. Things get a little bumpy once you get to the  Configuring Authentication section, however. My host (HostMonster) uses FastCGI and the instructions for enabling Trac authentication in a CGI environment entail editing the Apache config files. Being on a shared host, you're not given access to those config files (*shocker*).

Not finding helpful information through various Google searches (I swear I really did look), I turned to the helpful Trac Users Google Group for help (you can see the post here if you'd like).

First suggestion I got was to try adding the Apache config instructions to the .htaccess file. This resulted in a 500 Internal Server Error. The server logs indicated that the <Location> element is not allowed in .htaccess files.

Thankfully, there was a second suggestion -- use the AccountManagerPlugin.

The plugin installed fine with easy_install, although I did have to use "http", rather than "https", for the install URL. The instructions state that you need to restart Apache 2.2.x in order for the plugin to be detected, but this wasn't the case for me. The plugin started working right away.

Configuring the plugin is pretty easy, but the steps aren't laid out very well in the instructions. Below is my attempt to spell them out more explicitly.

Edit trac.ini as follows:

[components]
....
trac.web.auth.loginmodule = disabled
acct_mgr.api = enabled
acct_mgr.web_ui.loginmodule = enabled
acct_mgr.web_ui.registrationmodule = enabled

The first line disables the default Trac authentication module. The second line enables the "core" of the AccountManagerPlugin and is required to use any other components offered by the plugin. The third line enables the AccountManagerPlugin's login module, while the fourth line enables accounts to be created from the webpage. Once you've created all needed accounts, you'll probably want to disable this registration module (so that random people can't create accounts):

acct_mgr.web_ui.registrationmodule = disabled

Before you create accounts, you'll need to enable one of the password storage modules. The HtDigestStore is considered more secure than the HtPasswordStore, so let's use the former.

Continue editing trac.ini as follows:

[components]
acct_mgr.htfile.htdigeststore = enabled

[account-manager]
; configure the plugin to store passwords in the htdigest format
password_store = HtDigestStore
; the file where user accounts are stored. the webserver will need write permissions to this file and its parent folder
password_file = <some path>/trac.htdigest
; the name of the authentication “realm”. it can be any text to identify your site or project
htdigest_realm = TracRealm

After this, you should be able to go to your Trac portal, register a new account, and login.

Update: I tried another Google search and actually found instructions for enabling security in the .htaccess file (on page 2 of the search results...who looks on the 2nd page? Honestly...). If interested, you can read about it on the Sweating the Details blog.

9Sep/100

Django & Hostmonster: Deploying My First App

I am a giant bonehead. I meant to write this post a year-and-a-half ago, so that I could remember the steps I went through to get this working. I did not write said post. Now I'm going through the same process again. Hooray.