tag:blogger.com,1999:blog-144622872024-03-07T21:22:51.114-05:00Speno's Pythonic AvocadoOne python programmer and his avocados.Unknownnoreply@blogger.comBlogger48125tag:blogger.com,1999:blog-14462287.post-46091183068991397782010-01-28T08:18:00.002-05:002010-01-28T08:20:04.674-05:00Excellent new (semi) Python podcast<a href="http://5by5.tv/devshow">The Dev Show</a> is my new favorite Python podcast.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-79097713867925543992009-12-24T14:43:00.005-05:002009-12-24T15:28:04.919-05:00Mac OS X Services - Changes between Tiger, Leopard and Snow LeopardWhen a file or folder is selected in the Finder and a Mac OS X Service is invoked, either through the Services menu or its keyboard shortcut, the input fed to the service depends on what version of Mac OS X is running.<br /><ul><li>In Tiger, (10.4), no input is fed to the service.</li><li>In Leopard (10.5), the absolute path to the file is the input. E.g. "/Users/steve/tablet.rtf"</li><li>In Snow Leopard (10.6), if the service is configured properly to work on files and folders, then the input will be file URL like "file://Users/steve/tablet.rtf".</li></ul><div>In Leopard, any service that accepted selected text would automatically work with selected files or folders in the Finder. However, Snow Leopard changed that. It is still possible for a service to accept both selected text and files plus folders, but if you create a Service using Automator, you are forced to choose one or the other. So, pick one and save your Service. For this example, I'm assuming you picked 'Files and Folders'.</div><div><br /></div><div>Next, edit the ~/Library/Services/Foo.workflow/Contents/Info.plist and change this:</div><br /><pre class="code"><br /> <key>NSSendFileTypes</key><br /> <array><br /> <string>public.item</string><br /> </array><br /></pre><br />to this:<br /><pre class="code"><br /> <key>NSSendFileTypes</key><br /> <array><br /> <string>public.item</string><br /> </array><br /> <key>NSSendTypes</key><br /> <array><br /> <string>NSStringPboardType</string><br /> </array><br /></pre><br /><br />Then, in the Python program that is your service, you may want something like this to detect that your input is a file path:<br /><br /><pre class="code"><br /> if input.starswith('file://') or input.startswith('/'):<br /> # I think I got a file path as input<br /></pre><br /><br />For more details, see <a href="http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/SysServices/Articles/properties.html">Services Properties</a> in the Mac Dev Center. Happy holidays!Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-14462287.post-64470551241832654462009-09-24T23:02:00.007-04:002009-09-25T08:58:21.706-04:00Calculating the keytag of a DNSKEY in PythonIn DNSEC, sometimes you want to know the "keytag" of a DNSKEY record. Here's a Python implementation that uses <a href="http://dnspython.org/">dnspython</a>:<br /><pre class="code"><br />import struct<br /><br />def keytag(dnskey):<br /> """<br /> Given a dns.rdtypes.ANY.DNSKEY dnskey, compute and return its keytag.<br /><br /> For details, see RFC 2535, section 4.1.6<br /> """<br /> if dnskey.algorithm == 1:<br /> a = ord(dnskey.key[-3]) << 8<br /> b = ord(dnskey.key[-2])<br /> return a + b<br /> else:<br /> header = struct.pack("!HBB", dnskey.flags, dnskey.protocol, dnskey.algorithm)<br /> key = header + dnskey.key<br /> ac = 0<br /> for i, value in enumerate(ord(x) for x in key):<br /> if i % 2:<br /> ac += value<br /> else:<br /> ac += (value << 8)<br /> ac += (ac >> 16) & 0xffff<br /> return ac & 0xffff<br /></pre>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-14462287.post-18281964099796877812009-09-15T13:58:00.006-04:002009-09-15T14:08:24.218-04:00Using Django's Syncdb outside of DjangoI'm working on another project that uses Django's ORM that isn't (yet) a web applicaiton. There's no settings.py file as the application has its own configuration system build on ConfigObj and optparase. But, before you can use the app, you need to create the tables that Django's ORM needs for your Models. If you app lives in a python package named 'fooapp', then put your Django models in fooapp.models and try this code:<br /><pre class="code"><br />from django.conf import settings<br />from django.core.management.commands import syncdb<br /><br />opts, args = build_configuration()<br />my_app = 'fooapp'<br />settings.configure(<br /> DATABASE_ENGINE=opts['db_engine'],<br /> DATABASE_NAME=opts['db_name'],<br /> DATABASE_USER=opts['db_user'],<br /> DATABASE_PASSWORD=opts['db_pass'],<br /> DATABASE_HOST=opts['db_host'],<br /> DATABASE_PORT=opts['db_port'],<br /> INSTALLED_APPS=(my_app,)<br />)<br />cmd = syncdb.Command()<br />cmd.handle_noargs()<br /><br /></pre><br /><br />And do let me know if that works. Thanks!Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-14462287.post-76564335686521252812009-07-26T11:05:00.002-04:002009-07-26T11:11:21.804-04:00Running Django with wsgiref that also serves Admin media<div>I wanted to run a Django app using Python's built-in wsgiref module. It also serves Django admin media. Consider this a stepping stone to running your Django app using CherryPy.</div><pre class="code"><div><div>from wsgiref.simple_server import make_server</div><div>from django.core.handlers.wsgi import WSGIHandler</div><div>from django.core.servers.basehttp import AdminMediaHandler</div><div>httpd = make_server('', 8000, AdminMediaHandler(WSGIHandler()))</div><div>httpd.serve_forever()</div><div></pre></div><div><br /></div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-14905222339359372862009-03-19T18:07:00.003-04:002009-03-21T10:09:08.577-04:00Rhymes with PonyYesterday I pushed out <a href="http://github.com/JohnSpeno/owney/tree/master">Owney</a> which does USPS shipment tracking in Python. It uses a bit of Django as well. It's got rough edges, so please watch your fingers! I intend to polish it as time permits. I do want to make it a re-usable Django app, but I need some advice on how to make that work.<div><br /></div><div>The original Owney was a dog with <a href="http://www.postalmuseum.si.edu/exhibits/2c1f_owney.html">a very interesting life</a>.</div><div><br /></div><div>Enjoy!</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-14518923102257767172009-01-17T11:49:00.004-05:002009-02-20T22:01:21.470-05:00Snakes in the bassinet (Baby's first open source project)I pushed out my first open source project this week. It's a Python interface to <a href="http://www.userscape.com/helpdesk/index.php?pg=kb.chapter&id=28">HelpSpot's web services API</a>. <a href="http://www.userscape.com/products/helpspot/">HelpSpot</a> is a help desk application that I use, like and happily recommend.<div><br /></div><div>You can find my project <a href="http://github.com/JohnSpeno/python-helpspot/">python-helpspot</a> on GitHub. I have another open source thing in the works too. That one is going to be a doggy and it'll have a touch of the django.</div>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14462287.post-91744186112171930512009-01-08T12:51:00.003-05:002009-01-08T13:12:13.083-05:00Missteps in Django - Part 3This one will make it obvious that the missteps are my own mistakes, not problems inherit in Django. I'm not terribly embarrassed to look this dumb. Most days, I'm proud of my density. On with the show!<br /><br />I guess this is another template issue. Oh well. I wanted to set the CSS class on an HTML tag based on some dynamic data. In this case, the data was the status field on my Shipment model:<br /><br /><pre class="code"><br />class Shipment(models.Model):<br /> description = models.TextField()<br /> created = models.DateTimeField(auto_now_add=True);<br /> status = models.CharField(max_length=64, default="new",<br /> choices=STATUS_CHOICES)<br /></pre><br />I'm omitting STATUS_CHOICES because its not important to my point. I wanted each displayed shipment to have a different background color. My initial idea was to try something like this:<br /><pre class="code"><br />class={% ifequal thing.status "new" %}"new"{% elifequal thing.status "exception" %}"exception"{% endelifequal %}...<br /></pre><br />Of course, Django doesn't have an <em>elif</em> construct in its templates. Doesn't matter because my idea was stupid and eventually I figured that I could do this:<br /><pre class="code"><br />class="status_{{ shipment.status }}"<br /></pre><br />and be done with it. I hope I had a good laugh at myself.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-17349246812545903722008-12-22T12:34:00.009-05:002008-12-23T20:05:06.092-05:00Missteps in Django - Part 2My next misstep was related to using the regroup tag that I mentioned in the <a href="http://speno.blogspot.com/2008/12/missteps-in-django-part-1.html">previous post</a>.<br /><br />First, let's take a look at the example model I'm working with.<br /><pre class="code"><br />class Shipment(models.Model):<br /> description = models.TextField()<br /> created = models.DateTimeField(auto_now_add=True);<br /></pre><br /><br />I wanted to display these Shipments grouped by they day they had been created and I wanted that day formated like "2008-12-22". Since the 'created' field of the Shipment model is a datetime.datetime instance which, when viewed as a string, looks like "2008-12-23 19:16:06.700114". That was a bit too verbose and besides, I wanted shipments grouped by day, not by microsecond!<br /><br />My solution was to a add a property (of course!) to my model and see if I could use that in the regroup tag. Here's what that looked like:<br /><br /><pre class="code"><br />class Shipment(models.Model):<br /> description = models.TextField()<br /> created = models.DateTimeField(auto_now_add=True);<br /><br /> def _get_ship_date(self):<br /> return self.created.date()<br /><br /> ship_date = property(_get_ship_date)<br /></pre><br />Then in my regroup tag, I could do this:<pre class="code"><br /><ul><br />{% regroup shipments by ship_date as shipments_by_date %}<br />{% for ship_date in shipments_by_date %}<br /> <li>Shipments for {{ ship_date.grouper }} </li><br /> <ol><br /> {% for shipment in ship_date.list %}<br /> <li> {{ shipment.description }} </li><br /> {% endfor %}<br /> </ol><br />{% endfor %}<br /></ul><br /></pre><br /><br />Hey, that worked, but this was another of my newbie missteps because there was an aspect to the regroup tag that I had overlooked (this series should be called RTFM maybe?). You can apply a filter to the attribute you are regrouping on like so:<br /><br /><pre class="code"><br />{% regroup ship_list by created|date:"Y-n-d" as shipments_by_date %}<br /></pre><br />And you're done.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14462287.post-50469804208194519912008-12-17T08:37:00.010-05:002008-12-17T09:29:40.110-05:00Missteps in Django - Part 1Welcome back fellow Avocadoists! I finally got something up and running in Django and I'm going to tell you about some problems I had learning and using Django in the process. I'm working on my own as the programmer and the designer so I'm sure that colors my view of things.<div><br /></div><div>My first issue was with in Django's templates. Namely, there seems to be no way to look things up dynamically in a dictionary based on the value of another template tag. I'm not even sure that makes sense so here's an example of what I was trying to do:</div><pre class="code"># the python part in your view method<br />things_by_day = {<br /> '2008-11-28' : [thing1, thing2],<br /> '2008-11-29' : [thing3, thing4, thing 5],<br /> '2008-11-30' : [thing6],<br />}<br />days = d.keys()<br />days.sort()<br /><br /># The Django template part<br />{% for day in days %}<br /> Here are the things for {{ day }}<br /> {% for thing in things_by_day.day %}<br /> do the thing with the list of things<br /> {% endfor %}<br />{% endfor %}<br /></pre><br />So the part in the template where it says "for thing in things_by_day.day" is the part that doesn't work the way my brain expected it to. I expected the value of "things_by_date.day" to be the Python equivalent of "things_by_day[day]" but instead Django's template language translates this as "things_by_day['day']". It treats the string "day" as the key. Fail.<br /><br />I figured out there was a way to do almost what I wanted using Django's regroup tag, but "No sir! I don't like it!"<br /><br />Here's what the template part looks like using regroup. Note that in the following template "things" is a queryset on a model with a field named "created" instead of a simple dict or list.<br /><br /><pre class="code"><br />{% regroup things by created as things_by_date %}<br />{% for thing_date in things_by_date %}<br /> Here are the things for {{ thing_date.grouper }}<br /> {% for thing in thing_date.list %}<br /> do the thing with the list of things<br /> {% endfor %}<br />{% endfor %}<br /></pre><br /><br />I find this syntax noxious and I can't remember what name to use where. In the process of writing this, I got it wrong in nearly every possible way. It's probably still wrong (I'm sure you'll let me know). What's with the magic names like "grouper" and "list"? I really just want to let Python be Python and use a dictionary in a normal way. I understand the limitations of Django's template system and why they were made and for the most part I support those decisions. Then the ice weasels come.<br /><br />I'm sure someone has made a new template tag to do dict lookups the way I was trying to do. It may be <a href="http://www.djangosnippets.org/snippets/713/">this one</a>. Please feel free to let me know in the comments. I'm still quite new to Django and eager to learn more. Thanks!Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-14462287.post-32066309057716217742008-10-09T08:37:00.008-04:002008-10-09T11:35:31.878-04:00CholecalciferolThere's something I know you need and probably aren't getting enough of. It's Vitamin D, specifically Vitamin D3 also known as <a href="http://en.wikipedia.org/wiki/Cholecalciferol">cholecalciferol</a>. Personally, I take at least 5,000IU of it a day unless I've spent some quality time in the sun. I also give it to my kids in appropriate doses.<div><br /></div><div>To learn about why you might want to get more Vitamin D3 in your life, I recommend starting with <a href="http://www.vitamindcouncil.org/">The Vitamin D Council's site</a>. Their <a href="http://www.vitamindcouncil.org/newsletter/2008-october.shtml">October 2008 newsletter</a> inspired me to post this.<br /><div><br /></div><div>One thing I like about Vitamin D3 is that it's cheap, especially in the summer time when it's free (your skin makes it for you when it is exposed to sunlight)! When it isn't free, I buy it from <a href="http://www.iherb.com/">iHerb.com</a> whom I've used for many years with no complaints. If anyone is interested, feel free to use coupon code PEN753 for $5 off your order for first time customers. <span class="Apple-style-span" style="font-weight: bold;">Disclaimer</span>: If you use that coupon, I get a referral fee.</div><div><br /></div><div>In case you were curious (and I was), the cholecalciferol in commercial supplements is probably derived from <a href="http://en.wikipedia.org/wiki/Lanolin">lanolin</a>.</div><div><br /></div><div>And here is a link to the specific brand of Vitamin D3 that I use:</div><div><br /><a href="http://www.iherb.com/ProductDetails.aspx?c=1&pid=7763">Healthy Origins, Vitamin D3, 2,400 IU, 360 Softgels</a><br /></div><div><br /></div><div>While I'm mentioning it, here's the other supplement I take 400 - 500 mg of nightly:</div><div><br /><a href="http://www.iherb.com/ProductDetails.aspx?c=1&pid=691">Now Foods, Magnesium Citrate, 200 mg, 250 Tablets</a><br /></div><div><br /></div><div>Those magnesium people need to get their act together and form a council so I'd have something to link to. In lieu of that, here's <a href="http://www.proteinpower.com/drmike/uncategorized/magnesium-and-inflammation/">something by Dr. Michael Eades on his favorite supplement</a>.</div></div>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-14462287.post-33079226348926955812008-06-28T22:21:00.003-04:002008-06-28T23:23:49.917-04:00Sweet Somethings!A friend of mine, Mike, just announced the opening of his online store: <a href="http://www.kaiscandy.com/">Kai's Candy Company</a>. I love the look of their site. Their <a href="http://www.kaiscandy.com/">Handmade Japanese candies</a> are unique here in the States. They are currently offering <a href="http://www.kaiscandy.com/obama-mccain-candies">Obama and McCain </a>candies for the 2008 political season. I really need to find out what that super secret surprise candy is too!<div><br /></div><div>Mike and I worked together at Penn. When he came for his interview, he thought we were looking for a perl programmer because that was what he was told by the recruiting agency. We were actually looking for someone with python experience of which he had little to none of at the time. I'm so glad that didn't get in the way of him getting the job because it was my pleasure to work with him. I hope his new venture is a sweet success!</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-15143375775562337652008-06-24T19:19:00.001-04:002008-06-24T19:44:52.088-04:00Netflix Disappointment<a href="http://blog.netflix.com/2008/06/profiles-feature-going-away.html"><span class="Apple-style-span" style="font-family:'lucida grande';">Netflix recently announced that it was removing a feature from its service.</span></a><span class="Apple-style-span" style="font-family:'lucida grande';"> It happens to be a feature that my family relies on. They say the decision is final and there's no indication that they plan to replace it. That said, we dropped two dvds from out account today and we'll drop the rest when they go through with it if not sooner. At least they made that part easy!</span><div><span class="Apple-style-span" style="font-family:'lucida grande';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'lucida grande';">More reactions from users:</span></div><div><ul><li><a href="http://www.hackingnetflix.com/2008/06/netflix-elimina.html"><span class="Apple-style-span" style="font-family:'lucida grande';">Netflix Eliminating Account Profiles</span></a><span class="Apple-style-span" style="font-family:'lucida grande';"><br /></span></li><li><a href="http://community.netflix.com/forum/topic/show?id=1993323%3ATopic%3A194695"><span class="Apple-style-span" style="font-family:'lucida grande';">Profiles Going away!?</span></a></li><li><a href="http://getsatisfaction.com/netflix/topics/netflix_to_break_homes_by_eliminating_profiles"><span class="Apple-style-span" style="font-family:'lucida grande';">Netflix to break homes by eliminating profiles</span></a></li><li><a href="http://digg.com/movies/Netflix_eliminating_Profiles"><span class="Apple-style-span" style="font-family:'lucida grande';">Netflix eliminating profiles</span></a></li><li><span class="Apple-style-span" style="font-family:'lucida grande';"><a href="http://tech.slashdot.org/article.pl?sid=08/06/19/0337233">Netflix to Eliminate Profiles Feature</a></span></li><li><span class="Apple-style-span" style="font-family:'lucida grande';"><a href="http://pogue.blogs.nytimes.com/2008/06/23/monday-2/">David Pogue's Where are the Netflix Profiles?</a></span></li></ul><div><span class="Apple-style-span" style="font-family:'lucida grande';"><br /></span></div></div><div><span class="Apple-style-span" style=" line-height: 19px; font-family:Arial;font-size:13px;"><div class="entry-content" style="position: static; clear: both; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; "><div class="entry-body" style="clear: both; "></div></div></span></div>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-14462287.post-72910824795495405502008-06-11T08:01:00.002-04:002008-06-11T08:39:09.322-04:00This American $152,000I listen to the <a href="http://www.thisamericanlife.org/Radio_Podcast.aspx">This American Life podcast</a> each week and the program has recently started asking for donations to cover their bandwidth costs of $152,000 a year. It seems like a waste of money when things like bittorrent and Amazon S3 exist in the world. I guess they opted for good and fast from their list of three options.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-14462287.post-53741148266837643592008-05-26T08:10:00.001-04:002008-05-26T08:12:35.665-04:00The Python of Record<a href="http://www.nytimes.com/2008/05/26/business/media/26link.html?partner=rssnyt&emc=rss">Python makes the New York Times</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-74999416921678286672008-05-20T13:06:00.002-04:002008-05-20T13:27:46.863-04:00I'm all up in ur topBy way of <a href="http://hivelogic.com/articles/2008/05/alltop">Dan Benjamin</a>, I see this thing called <a href="http://alltop.com">Alltop</a>. Next, I see their <a href="http://python.alltop.com/">python area</a>. Finally, I see that this blog, <a href="http://speno.blogspot.com">Speno's Pythonic Avocado</a>, is listed among the top sources of python news. Clearly, this Alltop thing is not to be trusted.<br /><br />Further proof is that the excellent, <a href="http://junkfoodscience.blogspot.com/">JUNKFOOD SCIENCE</a>,is completely missing from their Health section.<br /><br /><b>*plonk*</b>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14462287.post-63011759421217549872008-04-30T18:37:00.012-04:002008-05-01T00:37:34.371-04:00the machine that goes PING!Meet ~bin/sonar.<br /><pre class="code">#!/bin/sh<br /># usage: sonar <host or ip address><br />while :<br />do<br /> ping -c 1 $1 && say "PING!"<br /> sleep 30<br />done<br /></pre>This is a super fancy network monitoring tool. The original version of this was from another friend named Mark (not he of greenbar fame) and it played a submarine style sonar "ping" sound when a ping was successful. When you're waiting for your server to come back up, and you have time for a nap until it does, a tool like this is just what you need.<br /><br />This version relies on the Mac OS X /usr/bin/say command.<br /><br />Eat your heart out <a href="http://www.usenix.org/events/lisa2000/gilfix/gilfix_html/index.html">peep</a>.<br /><br /><b>EDIT:</b> Yeah, as originally posted the ping command was missing an argument. I blame myself and blogger's difficult to use posting. Thanks, Aaron.Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-14462287.post-29508921446282376112008-04-21T16:02:00.018-04:002008-04-21T17:01:48.846-04:00Drop AnythingSometimes you need drag and drop support for your scripts. Luckily, there's this Mac OS X tool which turns your scripts into applications onto which you can drop files and present their paths as arguments to your script. It's called DropScript and you can find it on <a href="http://www.wsanchez.net/software/">Willfredo Sanchez's software page</a>.<br /><br />I used it to feed input to a remote python program and it works perfectly. Of course you need to give it a cute icon so that people will want to drop files on it. Here's one I like:<br /><br /><img style="display:block; margin:0px auto 10px; text-align:center;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcoXehjJ5MXdqqAkylPJtWZsyjIEBHgfg4yfKpYBeCPhWQK3ayYnUhjIy-GlMtsOV9svCGI4ISl0EbOT0eGfb7b_jGUzMi0EOcsqKXRR4KLouPm9y1zAYpwD6-2je3gZhehj0Ljw/s400/drop.jpg" border="0" alt="DomocunCreature Icon" /><br /><div style="text-align:center"><a href="http://www.fasticon.com/">Icon by: Fasticon.com</a></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-4808490780835034942008-04-18T08:03:00.006-04:002008-04-18T08:46:54.269-04:00This is getting awk-wardIdeas from readers DrewP and Justin have greenbar approaching the size of the original awk version. Thank you both.<br /><pre class="code"><br />#!/usr/bin/python -u<br /><br />import sys<br /><br />try:<br /> pat = sys.argv[1]<br />except IndexError:<br /> pat = None<br /><br />green = True<br />for line in iter(sys.stdin.readline, ""):<br /> if (pat and pat in line) or (not pat and green):<br /> print "\x1b[7m%s\x1b[0m" % line.rstrip()<br /> else:<br /> print line,<br /> green = not green<br /></pre>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-14462287.post-68916399157052534382008-04-11T07:05:00.011-04:002008-04-11T07:53:38.729-04:00Please to dance round for the one called the Greenbar<div>Inspired by what I can only guess is my unsightly python version of greenbar, drewp has created a version with 100 percent more fun to look at. Thanks!</div><br /><div>Drewp's version (see <a href="http://drewp.quickwitretort.com/2008/04/10/0">here</a>) is what I always hoped greenbar would grow up to look like when it was written by someone who was not me. I wish the enumerate thing would work - I tried that originally too, but no, it's not to be. It works fine if the input is a regular file, but not when you want to read the stdout of another process. There's internal buffering in python that chunks up the input making the most common use of greenbar, watching a growing log file, hopeless.</div><div><br /></div><div>Combining the two versions results in a super hybrid that works and is easy on your eyes. Tada!<br /></div><div><pre class="code">#!/usr/bin/python -u<br /><br />import sys<br /><br />try:<br />pat = sys.argv[1]<br />except IndexError:<br />pat = None<br /><br />lineno = 0<br />while 1:<br /> line = sys.stdin.readline()<br /> if not line:<br /> break<br /> if (pat and pat in line) or (not pat and lineno % 2 == 0):<br /> print "\x1b[7m%s\x1b[0m" % line.rstrip()<br /> else:<br /> print line,<br /> lineno = lineno + 1</pre></div><div>P.s. The original awk version was shorter still. If I find a copy, I'll bury it so that python looks better.</div>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-14462287.post-47749422350766943662008-04-08T23:02:00.008-04:002008-04-09T00:18:01.368-04:00spice up your tail minus effs with greenbarI've been missing this tool for a while now. The original "greenbar" was in written in awk, probably by my friend Mark S. It took input and inverted the text of every other line (like greenbar printer paper). It made watching log files scroll up your terminal much easier to parse.<br /><br />Here's my python version which has one new feature. It can be given a string argument in which case it will only highlight lines in its input that contain that string.<br /><br /><pre class="code"><br />#!/usr/bin/python -u<br /><br />import sys<br /><br />REG = "\x1b[0m"<br />INV = "\x1b[7m"<br /><br />try:<br /> pat = sys.argv[1]<br />except IndexError:<br /> pat = None<br /><br />i = 0<br />while 1:<br /> line = sys.stdin.readline()<br /> if not line:<br /> break<br /> if pat:<br /> if pat in line:<br /> print INV, line,<br /> else:<br /> print REG, line,<br /> else:<br /> if i % 2 == 0:<br /> print INV, line,<br /> else:<br /> print REG, line,<br /> i = i + 1<br />if i:<br /> print REG<br /></pre><br />It's important to use unbuffered I/O, thus the "-u" flag to python is used along with sys.stdin.readline().Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-14462287.post-48782162433224018612007-12-08T09:08:00.001-05:002007-12-08T09:09:45.758-05:00Since you didn't mention itAmazon said the Django book has shipped and should be here on Dec 11th.<br /><br />p.s. Hello Jen's dad!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14462287.post-77496532064603895392007-11-15T18:49:00.000-05:002007-11-15T18:58:19.597-05:00That Which Is Not DeadEmail.<br /><br />Usenet is still dead however. Sad really, given how much of my life I spent in the care and feeding of news servers.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-14462287.post-40979509511829810252007-09-18T08:07:00.000-04:002007-09-18T08:14:36.114-04:00Django Bookie - Confusion and Delay?As a follow-up to my last post I present Amazon's new delivery status on the <a href="http://www.djangobook.com/">Django book</a>.<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Zp8LtjlZY8-C3iFXhPeDK5Pk9izTvRWsMGw1XwKShAKFddTR2m6VrBoe5hJXdjdD-UDlj1iGMoH7psXgI64AWGvRi-QdxLiin3aZXHmCyorqIH8o7LXp3fA5Y46hWtVzIxfG9w/s1600-h/book.png"><img style="display:block; margin:5px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Zp8LtjlZY8-C3iFXhPeDK5Pk9izTvRWsMGw1XwKShAKFddTR2m6VrBoe5hJXdjdD-UDlj1iGMoH7psXgI64AWGvRi-QdxLiin3aZXHmCyorqIH8o7LXp3fA5Y46hWtVzIxfG9w/s400/book.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5111515138274155938" /></a><br />Ta ta for now.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14462287.post-34756734326110520922007-09-17T13:18:00.000-04:002007-09-17T13:25:17.578-04:00Django BookieMy delivery widget, the fantastic <a href="http://mikepiontek.com/software/mac/delivery-status.html">Delivery Status</a>, tells me that Amazon will have the <a href="http://www.amazon.com/gp/product/1590597257/">Django book</a> in my hands in two days. Color me skeptical. No, I mean more than usual, smart guy!Unknownnoreply@blogger.com0