
For better or worse here are some samples of code I've written to
share with the community and give you, my casual visitor, a look at
some of the code I hack together from day to day.
I'll eventually get all this into some sort of tagged, searchable
system... But I don't have that much right now any way.
Django Admin Auto Register
I'll just be honest- I get tired of writing the same thing over and over in every admin.py so I wrote this to automagically register every class in my models. I find that 9 out of 10 times I want to ignore less than I want to register so this uses "negative trapping" where you specify what you want to skip. It also supports admin classes by matching the model class with the associated admin class in the MODEL_ADMINS dictionary. Makes me smile every time I roll out a new app.
from django.contrib import admin
from my_awesome_app import models
# models that shouldn't be registered
# list of model names as lowered strings
# ['mymodel', 'myothermodel']
EXCLUDE_MODELS = []
# models that have admin classes
# dict of model name strings as keys, admin classes as values
# {'MyModel':MyModelAdmin}
MODEL_ADMINS = {}
for attr in dir(models):
skip = False
for model_name in EXCLUDE_MODELS:
if model_name.lower() in attr.lower():
skip = True
if skip: continue
model_attr = getattr(models, attr)
if type(model_attr) is type(models.models.Model):
if attr in MODEL_ADMINS:
admin.site.register(model_attr, MODEL_ADMINS[attr])
else:
try:
admin.site.register(model_attr)
except:
continue
IP Address Range Search
The need arose to be able to see if an IP address belonged in one of several various blocks. These blocks had several available ranges so I wrote this script to search a dictionary of IP address range definitions.
# ip_ranges is a dictionary (keyed off the first octet as an integer) that contains
# a three-tuple of single octet values or two-tuple octet value ranges.
# The dictionary below represents the following ranges:
# 68.24.0.1 - 68.27.255.254
# 68.29.0.1 - 68.29.255.254
# 68.30.0.1 - 68.31.255.254
# 68.240.0.1 - 68.247.255.254
ip_ranges = {
68:[
(
(24,27),(0,255),(1,254),
),
(
29,(0,255),(1,254),
),
(
(30,31),(0,255),(1,254),
),
(
(240,247),(0,255),(1,254),
),
]
}
def split_ip(ip):
"""
Returns a list comprehension of ip address octet values as integers.
>>> split_ip('10.0.0.1')
... [10, 0, 0, 1]
"""
return [int(x) for x in ip.split('.')]
def check_range(ranges, ip):
"""
Loops through an ip range dictionary determining if the given ip is contained
within the given ranges.
"""
in_ranges = True
count = 1
for r in ranges:
if in_ranges:
if type(r) is tuple:
if ip[count] in range(r[0], r[1]+1):
in_ranges = True
else:
in_ranges = False
else:
if r == ip[count]:
in_ranges = True
else:
in_ranges = False
count += 1
return in_ranges
def is_target_ip(ip):
"""
Determines whether the given ip matches any of our defined ip ranges.
"""
ip = split_ip(ip)
if ip_ranges.has_key(ip[0]):
ranges = ip_ranges[ip[0]]
for r in ranges:
if check_range(r, ip):
return True
return False
Django Bound Form Field Data
There's not an easy way to get to the data of a bound form
field in Django but the community has a solution in the form of
a filter. You can read about it at http://code.djangoproject.com/ticket/10427.
As most of those fixes go, at least for me, it didn't solve
the problem I had: getting the bound data from a model multiple
choice field. My template tags module contains field_tags.py
that looks like this...
from django.forms import ChoiceField, FileField, ModelMultipleChoiceField
from django import template
register = template.Library()
@register.filter(name='field_value')
def field_value(field):
"""
Returns the value for this BoundField, as rendered in widgets.
"""
if field.form.is_bound:
if isinstance(field.field, FileField) and field.data is None:
val = field.form.initial.get(field.name, field.field.initial)
else:
val = field.data
else:
val = field.form.initial.get(field.name, field.field.initial)
if callable(val):
val = val()
if val is None:
val = ''
return val
@register.filter(name='display_value')
def display_value(field):
"""
Returns the displayed value for this BoundField, as rendered in widgets or
a list of displayed values.
"""
value = field_value(field)
if isinstance(field.field, ChoiceField):
for (val, desc) in field.field.choices:
if val == value:
return desc
if isinstance(field.field, ModelMultipleChoiceField):
if type(value) is list:
descs = []
for val2 in value:
for (val, desc) in field.field.choices:
if val == val2:
descs.append(desc)
if descs:
return descs
return value
@register.filter(name='display_value_pairs')
def display_value_pairs(field):
"""
Returns the displayed value for this BoundField, as rendered in widgets or
a list of tuples [("value", "displayed value")]
"""
value = field_value(field)
if isinstance(field.field, ModelMultipleChoiceField):
if type(value) is list:
ret = []
for val2 in value:
for (val, desc) in field.field.choices:
if val == val2:
ret.append((val2,desc))
if ret:
return ret
return value
Matrix Orbital MX 2xx Display Class
I spent the better part of a Saturday figuring out how to talk to my Matrix Orbital LCD with Python. I couldn't find any documentation any where so I did a write up on LCD Forums to help the next lost soul. This hacked class is the result of my day's efforts. On a related note I lost half of a Monday getting this to work on my Mac. I still need to write up how I did that hack before I forget forever...
import os
import re
import serial
import sys
import thread
import time
class Display():
'''
Display class for Matrix Orbital MX LCD Screens.
Essentially a wrapper for serial.Serial with Matrix Orbital functions.
>>> d = Display(2)
>>> d.clear()
>>> d.send("Hello World!")
'''
#constants
## basic utils
NULL = '\x00'
CLEAR = '\xfe\x58'
CMD = '\xfe'
BACKLIGHT_ON = '\xfe\x42\x00'
BACKLIGHT_OFF = '\xfe\x46'
## bar graphs
INIT_VBG_THIN = '\xfe\x73'
INIT_VBG_THICK = '\xfe\x76'
INIT_HBG = '\xfe\x68'
## input
KEYS_IN = []
LISTEN_FOR_KEYS = True
def clear(self):
'''Clears the screen'''
self.send(self.CLEAR)
def __init__(self, port, baud=19200):
self._serial = serial.Serial(port, baud)
self.clear()
def send(self, data):
'''Wrapper for our serial instance's write method'''
self._serial.write(data)
def close(self):
'''Wrapper for our serial instance's close method'''
self._serial.close()
def draw_vbg(self, cols=[], kind="thin"):
'''Method to draw a vertical bar graph
cols is an array of two-tuples [(column, height)]
example usage:
my_display.draw_vbg([(1,2),(2,4),(3,6)])
The example would draw a bar graph with bars on
columns 1, 2, & 3 with heights 2, 4, & 6 (respectively)
'''
if kind == "thin":
self.send(self.INIT_VBG_THIN)
else:
self.send(self.INIT_VBG_THICK)
for col in cols:
c = int(col[0]) # column to draw
h = int(col[1]) # height of bar (0-14?)
try:
self.send(self.CMD+'\x3d'+chr(c)+chr(h))
except:
raise
def clear_keys(self):
'''Clears out the KEYS_IN array'''
self.KEYS_IN = []
# should not be called outside of class! use key_listen()
def _thread_key_listen(self):
while self.LISTEN_FOR_KEYS:
key = self._serial.read()
self.KEYS_IN.append(key)
#clean up on fail or exit
self.key_listen_thread = None
def key_listen(self):
'''starts a new thread to listen for key presses and
inserts them into the KEYS_IN array'''
self.key_listen_thread = thread.start_new_thread(self._thread_key_listen, ())
TimeSpace Tag Filter
TimeSpace has some very complicated filtering
that takes place in the back end. What makes it complicated is
the simplicity we try to give the user when creating a filter.
When I originally designed the filter system there were different
types of filters to accomplish specific tasks. After we started
working on the front end we realized that was too confusing so I
hacked the "Tag Filter" to provide the needed functionality.
Here's the rub: We had a generic model to represent all the different
filters. This was accomplished my having a text field that contained
configuration parameters as JSON. This worked well since the UI
was done with AJAX and we could toss the JSON config out and the
JS on the page could draw out whatever was needed and display
the associated values. When the form was saved the additional
properties (display and value) were just baked back in as JSON.
With that basic explanation out of the way, the code below extrapolates
the additional options and creates a Django Q object from the
properties of the filter instance.
# # # # # # # # # #
# filters/tag.py
# Tag filter
#
# Filters MUST be imported into filters/__init__.py
#
# # # # # # # # # #
import re
from django.db.models import Q
from django import forms
from timespace.forms import BaseFilterForm
from timespace.options import IPTC_KEY_TYPES, FILTER_TYPES, IPTC_TYPE_KEYS
from timespace.utils.json import *
# the module must contain a class of the same name,
# sentence cased (first letter capitolized)
class Tag():
object = None
terms = None
term = None
operator = None
params = None
def __init__(self, filter=None):
self.object = filter
if filter is not None:
self.terms = self.split_terms(filter.term.lower())
self.term = filter.term.lower()
self.operator = filter.operator
self.parse_params()
def __str__(self):
return self.__unicode__()
def __unicode__(self):
return '%s - %s' % (str(self.operator), str(self.term))
# The get Q method. This returns the filters query
def get_q(self):
"""Get Q
Returns a django Q object based on the filter operator and terms.
"""
q = None
if '*' in self.terms:
q = '*'
if self.params is not None and q != '*':
params = self.params
# sanity check
if q is None:
q = Q()
# establish each sections q object as none
descq = None
titleq = None
tagsq = None
iptcq = None
# set the filter type
if params.has_key('exact_match') and params['exact_match']:
filter_type = '__iexact'
else:
filter_type = '__icontains'
# create the title q object
if params.has_key('search_title') and params['search_title']:
for term in self.terms:
tq = Q(('title%s'%filter_type,term))
if titleq is None:
titleq = tq if self.operator is not 'not' else ~tq
else:
if self.operator == 'can':
titleq = titleq | tq
if self.operator == 'must':
titleq = titleq & tq
if self.operator == 'not':
titleq = titleq & ~tq
if titleq is not None:
if self.operator == 'can':
q = q | titleq
if self.operator == 'must':
q = q & titleq
if self.operator == 'not':
q = q & ~titleq
# create the description q object
if params.has_key('search_description') and params['search_description']:
for term in self.terms:
tq = Q(('description%s'%filter_type,term))
if descq is None:
descq = tq if self.operator is not 'not' else ~tq
else:
if self.operator == 'can':
descq = descq | tq
if self.operator == 'must':
descq = descq & tq
if self.operator == 'not':
descq = descq & ~tq
if descq is not None:
if self.operator == 'can':
q = q | descq
if self.operator == 'must':
q = q & descq
if self.operator == 'not':
q = q & ~descq
# create the tags q object
if params.has_key('search_tags') and params['search_tags']:
for term in self.terms:
tq = Q(('description%s'%filter_type,term))
if tagsq is None:
tagsq = tq if self.operator is not 'not' else ~tq
else:
if self.operator == 'can':
tagsq = tagsq | tq
if self.operator == 'must':
tagsq = tagsq & tq
if self.operator == 'not':
tagsq = tagsq & ~tq
if tagsq is not None:
if self.operator == 'can':
q = q | tagsq
if self.operator == 'must':
q = q & tagsq
if self.operator == 'not':
q = q & ~tagsq
# create the iptc q object
fields = params['iptc_search_fields']
if fields and params.has_key('search_iptc') and params['search_iptc']:
for term in self.terms:
for field in fields:
field = IPTC_KEY_TYPES[int(field)]
# field Q
fq = Q(('iptc_info__type__iexact',field))
# term Q
tq = Q(('iptc_info__value%s'%filter_type,term))
# pair Q
pq = Q(tq & fq)
if self.operator == 'can':
if iptcq is None:
iptcq = pq
else:
iptcq = iptcq | pq
if self.operator == 'must':
if iptcq is None:
iptcq = pq
else:
iptcq = iptcq & pq
if self.operator == 'not':
if iptcq is None:
iptcq = ~pq
else:
iptcq = iptcq & ~pq
if iptcq is not None:
if self.operator == 'can':
q = q | iptcq
if self.operator == 'must':
q = q & iptcq
if self.operator == 'not':
q = q & ~iptcq
return q
# form fields for the form defined below
# {field_name:"default value"}
form_fields = {
"exact_match":False,
"search_title":True,
"search_description":True,
"search_tags":True,
"search_iptc":False,
"iptc_search_fields":[],
}
def get_form(self):
# changes here need to be updated in self.form_fields
class FilterForm(BaseFilterForm):
exact_match = forms.BooleanField(initial=False, required=False)
search_title = forms.BooleanField(initial=True, required=False)
search_description = forms.BooleanField(initial=True, required=False)
search_tags = forms.BooleanField(initial=True, required=False)
search_iptc = forms.BooleanField(initial=False, required=False)
iptc_choices = [(x[0],x[1].title()) for x in IPTC_KEY_TYPES.items()]
iptc_search_fields = forms.CharField(max_length=255, widget=forms.widgets.SelectMultiple(choices=iptc_choices), required=False)
type = forms.CharField(max_length=100, widget=forms.HiddenInput(), initial='tag')
return FilterForm
def filter(self, data):
"""Filter method
Searches the given data (string) for a match for the filter instance's
terms. Will return False if a match is found and the operator is "not"
Returns boolean
"""
for term in self.terms:
data = data.lower()
if term in data:
if self.operator != 'not':
return True
else:
return False
elif term == '*':
if self.operator != 'not':
return True
else:
return False
if self.operator != 'not':
return False
else:
return True
def filter_objects(self, objects, search_field='description'):
"""Object list filtration
Iterates through a list of objects inspecting the specified search_field
and determing whether the object matches the filters or not.
Returns a list of matching objects
filter_objects([], "the_data_field_to_search")
"""
results = []
for o in objects:
data = getattr(o, search_field, None)
if data is not None:
for term in self.terms:
if self.filter(data):
if o not in results:
results.append(o)
return results
def parse_params(self):
o = self.object
if o is not None:
if o.params is not None and o.params != '':
params_as_string = o.params
params = utils_json_load(params_as_string)
self.params = params
else:
self.params = self.form_fields
def split_terms(self, term):
terms = []
p = re.compile(r'"(.*?)"')
groups = p.findall(term)
terms.extend(groups)
for t in terms:
term = term.replace(t,'')
term = term.replace('""', '')
unclean_list = [x.strip() for x in term.split(' ')]
for x in unclean_list:
if x != '':
terms.append(x)
return terms
def load_params(self, filter=None, data=None, form=None):
"""Filter Parser - params load
Loads json into filter.params from filter instance
>>> filter.load_params(myFilterModelInstance, {"iptc_only":True})
"""
json = {}
if filter is None:
filter = self.object
if form is not None:
data = form.cleaned_data
if data is not None:
# confirm that at least 1 field is in the data, if not, this should
# probably be set to defaults
set_defaults = True
for field in self.form_fields.keys():
if data.has_key(field):
set_defaults = False
if not set_defaults:
for field, default in self.form_fields.items():
if data.has_key(field):
value = data[field]
# set checkboxes back to boolean values
json.update({field:value if value != 'on' else True})
# unchecked options don't come in the post data so if a field
# is missing and it's a bool then it should be false
elif type(default) is bool:
json.update({field:False})
else:
for field, default in self.form_fields.items():
json.update({field:default})
else:
data = self.form_fields
try:
json = utils_json_dump(json)
filter.params = json
except:
pass
return json
def dump_params(self, filter=None, alter_instance=False):
"""Filter Parser - params dump
BASIC TAG PARAM
{
'iptc_only':True
'iptc_fields':['subcategory', 'title']
}
"""
json = {}
if filter is None:
filter = self.object
try:
if filter.params is not None and filter.params != '':
json = utils_json_load(filter.params)
else:
json = self.form_fields
except:
pass
return json




