For Users

NC Jazz Beat

NC Jazz Beat is a Django CMS application which has been implemented primarily as a public service for the supporters of live jazz performances in Central North Carolina. It provides information about upcoming performances and occasional feature articles.

The site also serves as a testbed for components common to multiple Emptyhammock projects, most of which are listed on this page.

This Django application allows a group of people that walk together to easily post their attendance, without using noisy services like Meetup. It supports login with a Google or Yahoo account. Note: This isn't currently open to the public; you can log in but not do anything, until you are added to a group by an administrator.

Stacktrace management

I have a penchant for stacktraces; in particular, storing them and identifying reoccurrences to avoid duplicate investigation, etc. will let you upload stacktraces and add descriptions in Markdown and identify duplicates in a file upload, etc. Alas, I haven't taken it very far due to a perceived lack of interest among people I have discussed it with. (They don't know how lucky they are.)

For Python

Parsing stack traces (Python, gdb, pstack)

PYTHON_STACKTRACE_1 = u"""[14/Mar/2015 01:37:05] ERROR [django.request:231] Internal Server Error: /walk/ExYu
Traceback (most recent call last):
  File "/home/trawick/git/walking/envs/walking/lib/python2.7/site-packages/django/core/handlers/", line 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/trawick/git/walking/envs/walking/lib/python2.7/site-packages/django/contrib/auth/", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/trawick/git/walking/src/walking/walks/", line 58, in index
    forecast = wo.weather_forecast()
  File "/home/trawick/git/walking/src/walking/walks/", line 81, in weather_forecast
    city, raw_forecast = w.around(start, 4 * 60 * 60)
  File "/home/trawick/git/walking/src/walking/walking/", line 132, in around
    d = Weather._fetch(uri, self._validate_around_weather)
  File "/home/trawick/git/walking/src/walking/walking/", line 42, in _fetch
    c.request('GET', uri)
  File "/home/trawick/python-2.7/lib/python2.7/", line 995, in request
    self._send_request(method, url, body, headers)
  File "/home/trawick/python-2.7/lib/python2.7/", line 1029, in _send_request
  File "/home/trawick/python-2.7/lib/python2.7/", line 991, in endheaders
  File "/home/trawick/python-2.7/lib/python2.7/", line 844, in _send_output
  File "/home/trawick/python-2.7/lib/python2.7/", line 806, in send
  File "/home/trawick/python-2.7/lib/python2.7/", line 787, in connect
    self.timeout, self.source_address)
  File "/home/trawick/python-2.7/lib/python2.7/", line 571, in create_connection
    raise err
error: [Errno 110] Connection timed out""".split('\n')  # noqa

    'processname': 'no-name',
    'threadgroups': [{'thread_ids': [0]}],
    'threads': [
            'failure': u'error: [Errno 110] Connection timed out',
            'frames': [
                {'fn': u'get_response', 'id': 1},
                {'fn': u'_wrapped_view', 'id': 2},
                {'fn': u'index', 'id': 3},
                {'fn': u'weather_forecast', 'id': 4},
                {'fn': u'around', 'id': 5},
                {'fn': u'_fetch', 'id': 6},
                {'fn': u'request', 'id': 7},
                {'fn': u'_send_request', 'id': 8},
                {'fn': u'endheaders', 'id': 9},
                {'fn': u'_send_output', 'id': 10},
                {'fn': u'send', 'id': 11},
                {'fn': u'connect', 'id': 12},
                {'fn': u'create_connection', 'id': 13}

p = get_process_from_traceback(PYTHON_STACKTRACE_1)
self.assertEqual(EXPECTED_DICT_1, p.description(),)

Summing up lengths of time and time ranges in a string. For example:

=> timedelta(hours=19, minutes=2, seconds=57)

Parsing more kinds of time descriptions. For example:

list(parse_repeat_phrase('1st Fridays 8:30pm-12:30am', timedelta(days=40)))
=> [(datetime.datetime(2018, 3, 2, 20, 30), datetime.datetime(2018, 3, 3, 0, 30))]

parse_single_event('january 13 9-11pm')
=> (datetime.datetime(2018, 1, 13, 21, 0), datetime.datetime(2018, 1, 13, 23, 0))

parse_time_range(1, 15, 2018, '9pm-12am', local_tz=pytz.timezone('US/Eastern'))
(datetime.datetime(2018, 1, 15, 21, 0, tzinfo=),
 datetime.datetime(2018, 1, 16, 0, 0, tzinfo=))

Stuff like this, also programmatically:

coverage: 4.4.2
Newer releases:
  4.5: No information about package

Django: 1.11.9
Newer releases:
  1.11.10: SECURITY

Newer releases:
  2.7.4: Non-security bug fixes

Up to date: urllib3, certifi, chardet, click, defusedxml, django-click, django-dotenv, django-timezone-field, django-webpack-loader, flake8, huey, idna, mccabe, oauthlib, pycodestyle, pyflakes, PyJWT, python3-openid, pytz, PyYAML, redis, requests, requests-oauthlib, six, social-auth-app-django, social-auth-core, urllib3

The default package release database covers the tiny fraction of PyPI of interest to my projects; other users will want to override the default database with a different one that covers the packages used by their applications.

Because of that effort, this package could be useful only for people that need to decide on the criticality of package upgrades. They can use this package to find out when new releases are available, then they'll research and document the criticality of updates in the form of a release database that can be processed by this project.

For the projects I support, my maintenance bot captures pip freeze on the production servers, then uses this package to let me know which packages have newer releases on PyPI that either haven't been evaluated or that have been determined to be desirable. I try to perform the evaluation (i.e., read the project's change history) and update the database without delay, in case I find out that the upgrade is critical.

There's also a Django app that allows the package release db to be maintained from admin, providing exports to authorized clients.


For Django and Django CMS

Web Server Configuration

Documentation and commentary on configuring httpd, nginx, uWSGI, etc., for Django, Flask, and other Python web frameworks/libraries


This package implements a way to create content for the web site from admin, and use a combination of Django CMS plugins and other site features to make that content accessible to users of their site, such that the content is maintained separately from where and how it is displayed.

More specifically, the package provides a multi-purpose Article class, a view for articles, and Django CMS plugins which allow the content editor to place particular articles or article teasers or feeds of articles on a CMS page.


Simple plugins which support a simple mechanism for relating project-specific templates to descriptions that the content editor can choose from. E.g., you might have multiple templates available for the URL teaser, and the descriptions the content editor would see in admin would help them choose appropriately.


This is appropriate for applications that need a minimal workflow for contact requests, beyond simply sending an e-mail to the admin or to another designated person. Contact requests can be marked as resolved in the admin, and notes can be saved with the request to document the resolution.

Ansible deployment of Django applications

Various emptyhammock-role-FOO repos

Maybe these are useful as examples of one thing or another. In the long term I should open up my Django project template, which uses these roles.

Utility Programs


Fun with HTTP and carefully controlling I/O to a server you're testing

Summarize file descriptors

for a process group. It lists all the file descriptors for any of the processes in the group (e.g., all the nginx or httpd processes) with the list of process ids for each fd.

$ 8620
fd 0 type CHR name /dev/null
  8620 8621 8622 8623
fd 1 type CHR name /dev/null
  8620 8621 8622 8623
fd 2 type REG name /home/trawick/inst/24-64/logs/error_log
  8620 8621 8622 8623
fd 3 type sock name protocol: TCP
  8620 8621 8622 8623
fd 4 type IPv6 dev 83085 name *:8080
  8620 8622 8623
fd 49 type REG name /home/trawick/inst/24-64/logs/websocket-app-error.log
  8620 8621 8622 8623
fd 50 type REG name /home/trawick/inst/24-64/logs/walking.log
  8620 8621 8622 8623
fd 62 type FIFO name pipe
  8620 8622 8623
fd 4 type unix dev 0x0000000000000000 name /home/trawick/inst/24-64/logs/cgisock.8620 type=STREAM
fd 63 type a_inode name [eventpoll]

For Apache HTTP Server

Popular diagnostic modules

Documentation for mod_whatkilledus and mod_backtrace

Process explorer

Upload backtraces from pstack or gdb and see it differently.

Example httpd hook probes module

Example plug-in module for httpd that tracks module API calls using the hook probes feature

Other stuff

Simple Linux NAS

This repo has Ansible scripts and other information for setting up a NAS, including a test version inside Vagrant.