Content tagged with "python"
Python, PIL and Gaussian Blur Post on May 28, 2011
I have been searching high and low for a good gaussian blur for Python, I looked at ScyPy, Numpy, a bunch of random hand-coded versions around the internet, and it turns out that there's one built into PIL (v1.1.5). Not sure how fast it is compared to other versions, but the important part for me is, it's there. Just not documented (that I could find...)
The other problem
Turns out, if you look at the source, ImageFilter.py line 156(ish).
class GaussianBlur(Filter):
name = "GaussianBlur"
def __init__(self, radius=2):
self.radius = 2
def filter(self, image):
return image.gaussian_blur(self.radius)
...but if you look closely under the constructor, self.radius isn't assigned to the value passed into to method, it's hard-coded to 2!!! Blasphemy!
So I borrowed theirs and fixed it:
class MyGaussianBlur(ImageFilter.Filter):
name = "GaussianBlur"
def __init__(self, radius=2):
self.radius = radius
def filter(self, image):
return image.gaussian_blur(self.radius)
Sweetness, gaussian blur for PIL.
af
Twisted.web, WSGI and Django Post on Apr 26, 2011
W00t!
Now this is fun, I think I just said 'adios' to Apache (for the time being, anyway). Thanks to this post I just married my django site with twisted.
# web.application means 'web.py' twistd -no web --wsgi=web.application
Couple that with node.js reverse proxy and I'm one happy dude.
Fun fun!
[edit]
# bind to local interface twistd -no web --wsgi=web.application --port tcp:interface=127.0.0.1:port=8080 --logfile=foo.log
PyAMF and _version issue Post on Mar 23, 2011
I ran into this dumb issue trying to run an old project today:
... Could not import myapp.views. Error was: cannot import name _version ...
I had to actually break into the Django shell and try to import views from there to get a meaningful traceback, turns out the PyAMF __init__.py file was trying to do this:
from pyamf import util, _version
... and it wasn't lying, there was no _verion.py or _version folder or anything. A little googling found this page which revealed on the first line that the _version.py file is generated when "python setup.py install" is run to install pyamf. Well, that's all fine and good unless you're like me and almost never install modules into the main Python library unless absolutely necessary, I like to just put them on the python path, it makes upgrading modules much easier. So I cracked into the FBI mainframe and forced an assertion on the library (read: being super-stealthy, I created the file and pasted the expected code into it):
# THIS FILE IS GENERATED BY PYAMF SETUP.PY from pyamf.versions import Version version = Version(*(0, 6, 1))
Cheers! af
Bazaar DVCS upload plugin Post on Oct 26, 2010
I've known that I needed to move to a DVCS for a while, but, being busy as usual, I haven't had the time to try out one of the few popular systems. Recently I have been faced with a recurring challenge: managing Wordpress template and plugin customizations on client sites where I don't have shell access.
The first couple I didn't weren't a really big deal, just jump in and edit some files, upload via FTP, no problem. But, as usual, it started to bite me in the ass: more changes were being requested, and it was often easier to edit the files online through the Wordpress admin interface than locally and then upload, rinse and repeat.
So, I received a request from a client to work on a site from a couple months ago. It became clear to me that I was losing my mind: were the local files most recent, or were the remote files most recent? I couldn't take it any more. I was bound to find a bloody VCS that would work over FTP.
Turns out it's Bazaar
Not to be confused with 'bizarre'.
Bazaar is a version control system written in Python (yay!), and while it doesn't have the functionality built right in, there's a little plugin called Bazaar Upload which installs in seconds (python setup.py install) and works like a dream.
Workflow
I learned what I needed to know about Bazaar in about 5 minutes. Just a quick tutorial from their documentation and I was up and running. Here's the rundown (by the way, I'm using Unix Utils in Windows):
// change to an existing wordpress directory locally $ cd wordpress // set up bazaar in the current folder $ bzr init Created a standalone tree (format: 2a) // add some files to the repo (let's say the theme) $ bzr add wp-content/themes/some-theme adding wp-content adding wp-content/themes ... // now commit the files to the repo $ bzr commit -m "Added only the files I want to keep track of" Committing to: C:/wamp/www/wordpress/ added wp-content/ added wp-content/themes added ... Committed revision 1. // now the fun part: send the files we've changed to //our production environment, make sure you have //the bzr_upload plugin installed $ bzr upload sftp://aaron@someproject.com/~/public_html/new-site // Asks for authentication... Uploading wp-content Uploading... // alternatively, we can use ftp also, but notice // the path is different $ bzr upload ftp://aaron@someproject.com/new-site // Asks for authentication Uploading wp-content Uploading ... // A note on sftp vs ftp: sftp uses the SSH protocol so it logs // you into the ~ (home) folder of your web server, so you specify // the path like you would in a unix environment. Ftp logs you // in as if you were the ftp user, so the path may be different
Now, the next time you make a change to a file, you just
$ bzr upload
Done and done.
Awesome! The end.
Flex Django and AMF Post on Dec 15, 2009
Been working back in Flex again a bit, using Vim in Linux for a while, but I been really impressed with the short compile times in FlashDevelop for Windows.
Besides the point
Having become increasingly frustrated with the shortcomings of Django-amf, I've decided to give pyamf another try. I tried it the first time around, and got hung up on an error that made me bail out on it:
Cannot find a view for the path ['/gateway/cardservice/echo'], 'DjangoGateway' object has no attribute '__name__'
Some poking around in the source didn't help any, but the fix turned out to be easy. I stumbled on this post on StackOverflow, the author answered his own question in his comment. Turns out, leaving the django-amf middleware turned on in the settings.py file messed up the operation.
I don't have enough clout on StackOverflow to tell the author thanks there, so I'll do it here...
Aaron
Dreamhost, Django, Premature end of script headers: dispatch.fcgi Post on Oct 28, 2009
This problem comes up from time to time on my Dreamhost account, I get a long page load, finally ending with a 500 error in the browser. Tail'ing the apache error_log shows:
... [Wed Oct 28 13:48:37 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:48:37 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:48:40 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:49:18 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:49:21 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:49:58 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi [Wed Oct 28 13:50:39 2009] [error] [client 198.53.10.99] Premature end of script headers: dispatch.fcgi ...
But where's the real error?
A little trick for you: go to the folder where your dispatch.fcgi file is and type:
./dispatch.fcgi
Basically you are executing the script, similar to an incoming request. You should then see the original traceback.
Hth,
Aaron
Understanding dates in python Link on Nov 27, 2008
http://pleac.sourceforge.net/pleac_python/datesandtimes.html
Awesome Python Tutorial Link on Nov 24, 2008
Why Python Link on Nov 24, 2008
Lightroom -like histogram in Python Post on Nov 19, 2008
I just added a dynamically-generated histogram to the image items on my site. It's not really usefull information in the context of viewing a photograph, it's more functional when editing, but being the uber-geek that I am, I thought it would still be interesting information to have on my site, right along with the exif data (aperature, focal length, etc).
But not just any histo
I didn't just want a black and white representation of all the image histogram, I wanted something like the pretty histogram in Adobe Photoshop Lightroom:
All in all the final version took me about 1.5 hours to write in Python using PIL. The semi-tricky part was getting the overlapping colors. It turned out to be about 70 lines of code, and could probably be done much better. On my local Ubuntu install, a typical image histogram is generated in about 5-10 ms, not bad for a skinny white guy :)
Check out an image or two to see the pretty histogram in action :) Next step, drop shadows on the layers...
Cheers, Aaron
Automatic moderation with Django 1.0 Comments Post on Oct 16, 2008
This one was actually a lot easier than I thought it would be. The Django comments framework was totally revamped for the Django 1.0 release, and it is now way mo betta :)
But! Even with all the new anti-spam stuff built in, I needed all comments to go into a moderation queue for a client site. At first I tried the pre_save hook to change the is_public flag on the comment, but there's no way (that I could tell) how to distinguish when the comment was submitted, and when it was moderated.
The solution
The Django folks are always thinking :) Then put in a sweet little hook called comment_will_be_posted that gets called when the user submits the comment. Hook in and change the 'is_public' flag to 'False', and the comments automatically go into the moderation queue.
The Code
from django.contrib.comments.models import Comment from django.core.mail import send_mail from django.contrib.sites.models import Site from django.contrib.comments.signals import comment_will_be_posted from django.conf import settings def comment_set_public(sender, comment, request, **kwargs): # set the flag to false so it hits moderation comment.is_public = False # send an email subject = '%s > New Comment on %s' % (Site.objects.get_current(), comment.content_object.title) msg = """ You have a new comment on the item:\n%s\n\n Comment text:\n%s\n\n To moderate comments, visit the link below:\n http://%s/comments/moderate/ """ % (comment.content_object.title, comment.comment, Site.objects.get_current()) send_mail(subject, msg, settings.COMMENT_FROM_EMAIL, [settings.COMMENT_TO_EMAIL]) # from the docs: "If any receiver returns False the comment will be discarded..." # so there's much more potential for spam checking/protection return True # the hook comment_will_be_posted.connect(comment_set_public, sender=Comment)
Other goodies
Just for good measure, we put email notification in the same place which is handy (otherwise, how would you know comments were added?). The other super handy goodie with Comments 1.0 is they have added views for moderation also. Just point your browser to:
http://mysite.com/comments/moderate/
and you get a nice little view that looks just like the admin interface with which to moderate your comments. Obviously, if you're not logged in, it will prompt you to do so :)
Cheers, Af
PS: Here's a little screen to give you a taste:
Django TimeSelect widget Snippet on Oct 15, 2008
# based on the DateSelect widget from django, tested with newforms-admin, need to test with 1.0 class SelectTimeWidget(Widget): """ A Widget that splits time input into two <select> boxes. This also serves as an example of a Widget that has more than one HTML element and hence implements value_from_datadict. """ hour_field = '%s_hour' minute_field = '%s_minute' apm_field = '%s_apm' def __init__(self, attrs=None): # years is an optional list/tuple of years to use in the "year" select box. self.attrs = attrs or {} def render(self, name, value, attrs=None): hour_val = minute_val = apm_val = None try: value = datetime.time(*map(int, value.split(':'))) #value = datetime.date(*map(int, value.split('-'))) #pdb.set_trace() #year_val, month_val, day_val = value.year, value.month, value.day if value.hour > 12: value.hour -= 12 apm_val = 'pm' else: hour_val = value.hour apm_val = 'am' minute_val = value.minute except (AttributeError, TypeError, ValueError): hour_val = '8' minute_val = apm_val = None output = [] hour_choices = ( ('1','1'), ('2','2'), ('3','3'), ('4','4'), ('5','5'), ('6','6'), ('7','7'), ('8','8'), ('9','9'), ('10','10'), ('11','11'), ('12','12'), ) select_html = Select(choices=hour_choices).render(self.hour_field % name, hour_val) output.append(select_html) minute_choices = (('00','00'), ('15','15'), ('30','30'), ('45','45')) select_html = Select(choices=minute_choices).render(self.minute_field % name, minute_val) output.append(select_html) apm_choices = (('am','AM'), ('pm','PM')) select_html = Select(choices=apm_choices).render(self.apm_field % name, apm_val) output.append(select_html) return mark_safe(u'\n'.join(output)) def value_from_datadict(self, data, files, name): #y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name) h, m, a = data.get(self.hour_field % name), data.get(self.minute_field % name), data.get(self.apm_field % name) if a == 'pm': h = int(h) + 12 if h and m: return '%s:%s:%s' % (h,m,'00') #if y and m and d: # return '%s-%s-%s' % (y, m, d) return data.get(name, None) </select>
Ubuntu and PyQt Post on Oct 14, 2008
I just went through the nightmare of trying to install PyQt and all its dependancies. I had originally searched for an ubuntu package (coz we loves packages, doesn't we precious?) I couldn't seem to find one.
Turns out (after failing 'configure's and 'make's and missing dependancies), there is a package (a couple, actually).
To install PyQt on Ubuntu:
sudo apt-get install libqt4-core libqt4-dev libqt4-gui qt4-dev-tools python-qt4 pyqt4-dev-tools
I'm not sure if all the packages before the last one are necessary, but I didn't think it would hurt to have them.
Thanks again, Ubuntu Forums.
af
Installing Pygments on Webfaction Post on Oct 10, 2008
I just wanted to share the command, it took a little tinkering to get it right:
easy_install --always-unzip --install-dir=$HOME/lib/python --script-dir=$HOME/bin Pygments
Cheers, Aaron