PyOhio 2008 Registration Is Now Open

15.07.2008 14:01

posted by: Benjamin Smith

Posted Under: , ,

PyOhio is a day long mini conference for Python programmers in and around Ohio. It will be held Saturday, July 26, 2008 from 9:00 to 6:00 at the Columbus Metropolitan Library.

We have some great talks scheduled. We are also planning on having Lightning Talks, Open Spaces and a Poster Session.

Did I mention that it is free as in beer?

You can register by going to http://www.pyohio.org/reg/register/.

0 comments | 0 pingbacks

Wow, out of date much?

09.06.2008 22:42

posted by: Benjamin Smith

Posted Under: ,

So, I was installing FormEncode on some servers today and ran across a fun ‘warngin’.

Check it out:

Running FormEncode-1.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-iKCYq0/FormEncode-1.0.1/egg-dist-tmp-3yiKdV
warngin: no files found matching '*.py' under directory '.'
warngin: no files found matching '*.html' under directory 'docs'
no previously-included directories found matching '**/.svn'
zip_safe flag not set; analyzing archive contents...
formencode.fields: module references __file__
formencode.api: module references __file__
formencode.util.doctest24: module references __file__
formencode.util.doctest24: module MAY be using inspect.getsourcefile
FormEncode 1.0.1 is already the active version in easy-install.pth

Installed /usr/lib/python2.3/site-packages/FormEncode-1.0.1-py2.3.egg
Processing dependencies for FormEncode==1.0.1
Finished processing dependencies for FormEncode==1.0.1

At first, I naively emails the modules author, Ian Bicking. Shortly thereafter I realized that the message most likely wasn’t from his module, but the distribution utility used to install it.

I got home and quickly rushed to my Inbox, which revealed that Ian had confirmed my thoughts. A quick google search (which I should have done in the first place) showed that this is an old “bug” from waaay back when with distutils. It kind of hurt to know that some of my servers have code that old on them…Good thing they’re not publicly accessible.

Man, it really helps to do some quick searching/checking before jumping the gun, and man do I need to get these systems up to date!

3 comments | 0 pingbacks

Using python with postfix pipe.

08.06.2008 13:56

posted by: Benjamin Smith

Posted Under: , ,

Dear Lazyweb,

I was wondering if anyone here had experience with using a postfix pipe to a python program for processing mails. Most of my background in mail processing is with qmail, Perl and procmail.

From what I can tell there appears to be a ‘pipe’ command that I could use in an alias to point it at my python program, then use the ‘email.FeedParser’ class to keep it from blocking. For now I’m parsing mails from the maildir via the ‘email.Parser’ class, then moving them around. It would be very nice to process them as they come in. This would eliminate overhead from firing up python whenever I want to parse messages and make my process somewhat real time.

Any ideas/snippets/caveats are greatly appreciated!

P.S. I’m doing this in python to hook into byteflow, the django app powering this site.

5 comments | 0 pingbacks
Posted Under: ,

The PyOhio organizers have extended the Call for Proposals deadline to June 15! Several potential speakers have requested extra time to prepare submissions, and now you can too.

http://wiki.python.org/moin/PyOhio/CallForProposals

Don’t be shy… speaking at an event like PyOhio helps you share your knowledge, deepen your expertise, broaden your horizons, meet people, practice for bigger events like PyCon, and have fun.

See you at PyOhio!

0 comments | 0 pingbacks

Byteflow usability quick change.

05.06.2008 10:11

posted by: Benjamin Smith

Posted Under: , , ,

Submitted this to the byteflow hackers, figured some might be able to use it as well. Code blocks don’t wrap lines (<pre>), probably want to have control of how it overflows.

Here’s the patch:

# HG changeset patch
# User bsmith@linode.just-another.net
# Date 1212606740 14400
# Node ID 9337a362eeacbe88db2da11d38e238db2644e31b
# Parent  93c1106436dd09dde52ec1dd25cfbbeca7cec00b
Add scroll if lines don't wrap in code blocks.

diff -r 93c1106436dd -r 9337a362eeac static/css/highlight.css
--- a/static/css/highlight.css  Wed Jun 04 09:47:44 2008 +0300
+++ b/static/css/highlight.css  Wed Jun 04 15:12:20 2008 -0400
@@ -1,6 +1,7 @@ pre code {
 pre code {
    display: block;
    background: #F0F0F0;
+   overflow:auto;
 }

pre code,
2 comments | 0 pingbacks

Byteflow preview blog post

04.06.2008 10:55

posted by: Benjamin Smith

Posted Under: , ,

Byteflow has a feature when authoring blogs that allows you to save your post as a draft. I use it constantly, but someone requested via a ticket to have a “Preview” option, allowing you to see your blog post (logically the same as saving it as a draft) before you post it. If anyone is interested in utilizing a “Preview” option, see the patch below. Basically all it does is utilize the draft option, but takes you to the generated draft to “Preview” it before you make it public. I don’t think it will be committed into the code base, but if anyone is looking to have this functionality now, see below code.

# HG changeset patch
# User bsmith@linode.just-another.net
# Date 1212543690 14400
# Node ID 4282e3429846d5193a798bdd14807f6c3ef579ac
# Parent  2c4fb2b21cc5c7b9cfbf7a1692af6e34a9bb5391
Preview post (and draft it).

diff -r 2c4fb2b21cc5 -r 4282e3429846 apps/blog/models.py
--- a/apps/blog/models.py       Mon Jun 02 19:41:33 2008 -0400
+++ b/apps/blog/models.py       Tue Jun 03 21:41:30 2008 -0400
@@ -7,7 +7,7 @@ from django.utils.html import strip_tags
 from django.utils.html import strip_tags
 from django.contrib.contenttypes import generic
 from django.dispatch import dispatcher
—
+from lib.exceptions import RedirectException
 from lib.helpers import reverse
 from render import render
 from blog.managers import PostManager, PublicPostManager, FeaturedPostManager
 @@ -38,6 +38,7 @@ class Post(models.Model):
    upd_date = models.DateTimeField(_(u'Date'), auto_now=True, editable=False)
     is_draft = models.BooleanField(verbose_name=u'Post would act as draft', default=False)
     is_featured = models.BooleanField(verbose_name=u'Featured post', default=False)
+    is_preview = models.BooleanField(verbose_name=u'Preview Before Submission', default=True)
    enable_comments = models.BooleanField(default=True)
    tags = TagField()

@@ -53,7 +54,7 @@ class Post(models.Model):
        search_fields = ('name', 'text')
        list_filter = ('date', )
        fields = (
—            (None, {'fields': ('author', ('name', 'slug'), 'tags', 'text', 'render_method', 'date', ('is_draft', 'enable_comments'))}),
+            (None, {'fields': ('author', ('name', 'slug'), 'tags', 'text', 'render_method', 'date',('is_preview','is_draft', 'enable_comments'))}),
            ('Featured post', {'classes': 'collapse', 'fields': ('is_featured', 'teaser')}),
            )
        if settings.WYSIWYG_ENABLE:
@@ -80,7 +81,13 @@ class Post(models.Model):
            self.slug = slugify(self.name)
            self.text = self.text.strip()
            self.html = render(self.text, self.render_method, unsafe=True)
—        super(Post, self).save()
+        if self.is_preview:
+            message = 'This is a preview of your post'
+            self.is_draft = True
+            super(Post, self).save()
+            raise RedirectException(self.get_absolute_url(), notice_message=message)
+        else:
+            super(Post, self).save()

    def comments_open(self):
        if settings.COMMENTS_EXPIRE_DAYS:

And to implement it via a template, try something like this:

{% if object.is_preview %}
  <div id="post-draft">THIS IS A PREVIEW <a href="/admin/blog/post/{{ object.id }}/">Continue Editing</a></div>
{% endif %}
5 comments | 0 pingbacks

Yay for contribution!

02.06.2008 19:45

posted by: Benjamin Smith

Posted Under: , , ,

I was having troubles with the way my rss item categories (tags) were displaying on technorati and other feed readers, so I decided to fix it. This is why I love F/OSS! Since I’ve been using this software I’ve contributed a whopping 2 patches (heh, heh). It might not be a lot, but it matters! I didn’t post my last patch, but I will from now on. Here’s the most recent one:

# HG changeset patch
# User bsmith@linode.just-another.net
# Date 1212450093 14400
# Node ID 2c4fb2b21cc5c7b9cfbf7a1692af6e34a9bb5391
# Parent  fb8d51dd50e13eb7d2b63c646a9f2bb5cf21ec3c
Atom class wants a dict for item categories, django does not.

diff -r fb8d51dd50e1 -r 2c4fb2b21cc5 apps/feed/blog_feeds.py
--- a/apps/feed/blog_feeds.py   Fri May 30 11:13:58 2008 +0300
+++ b/apps/feed/blog_feeds.py   Mon Jun 02 19:41:33 2008 -0400
@@ -59,7 +59,10 @@ def _BlogEntries(Feed, type='atom'):
             return {'type': 'html'}, html

         def item_categories(self, item):
—            return ({'term': unicode(tag)} for tag in item.get_tags())
+            if (type == 'atom'):
+                return ({'term': unicode(tag)} for tag in item.get_tags())
+            else:
+                return (unicode(tag) for tag in item.get_tags())

         def item_links(self, item):
             return ({'rel': u'self', 'href': self.item_id(item)},

Hope this helps!

0 comments | 0 pingbacks

NYT Talks about xkcd, python gets a plug.

26.05.2008 12:11

posted by: Benjamin Smith

Posted Under: , , , ,

Great article about xkcd. Python gets a plug in the article as well. This kind of reading on a popular news site warms my heart.

Take a look

0 comments | 0 pingbacks

Anyone heard of or used this software? - Bcfg2

22.05.2008 20:47

posted by: Benjamin Smith

Posted Under: , ,

I just stumbled onto this promising looking software. We use an awesome distributed configuration engine at the office with similar ideals. Outside of cfengine I really didn’t know anything else existed, and this one is written in python! Let me know if you’ve worked with it, I would love to hear some opinions.

Thanks!

1 comment | 0 pingbacks

I’m spent…and an apology

13.05.2008 20:29

posted by: Benjamin Smith

Posted Under: , , , , ,

I just spent the last few hours polishing up my site for maximum awesomeness. It doesn’t look much different, you say, but under the hood is a completely different beast. As I mentioned in a previous post, I spent last night converting the backend of this site to byteflow, which is built on django (python based) and running on top of lighttpd.

Previously (read; years ago) I had built a blogging system based on a LAMP stack, specifically Apache 2.0, MySQL and PHP. Slowly, over time I added to and ‘improved’ the software. Time and time again it felt like an exercise in futility. It seemed to be a never ending battle to keep up with the times and stay exposed. Since I started working for ag interactive I’ve fallen in love with Python. Quickly thereafter I started searching for a good, ”developing” blog package written in python. I longed for something I could extend and something that is portable. I long no longer…(?) The django project has provided many facilities to build a great blog (and cms type thing) and I’m glad someone has finally stepped up to take advantage of them. I’m sure I’ll be submitting patches to this project as I discover things to tweak or improve.

To the byteflow crew: Great Job so far!

Now onto some of the details about what I did.

I love lighttpd, all of my recent development has taken advantage of it. It’s configuration is intuitive, it’s feature rich for it’s size, and it’s performance is hard to match. Converting the config for this was relatively simple. This is, of course, coming from a sysadmin who deals with hundreds of web servers daily :). Anywho, here’s the config with paths cleaned up for clarity:

# Main server settings
server.modules              = ( 
            "mod_access",
            "mod_alias",
            "mod_accesslog",
            "mod_rewrite", 
            "mod_redirect", 
            "mod_status", 
            "mod_fastcgi",
            "mod_compress",
            "mod_expire",
)

server.document-root       = "/docroot"
server.errorlog            = "/var/log/lighttpd/error.log"
index-file.names           = ( "index.php", "index.html", 
                                        "index.htm", "default.htm" )
accesslog.filename         = "/var/log/lighttpd/access.log"
url.access-deny            = ( "~", ".inc" )
server.pid-file            = "/var/run/lighttpd.pid"
dir-listing.encoding        = "utf-8"
server.dir-listing          = "enable"
debug.dump-unknown-headers  = "enable"
server.username            = "www-data"
server.groupname           = "www-data"
#status.status-url = "/server-status"
#status.config-url = "/server-config"
# Expires stuff, per yahoo tips :)
$HTTP["url"] =~ "^/" {
     expire.url = ( "" => "access 8 hours" )
}
# Set mime-types.
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
# Allow for vhost configs
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
# Compress settings
compress.cache-dir          = "/var/tmp/lighttpd/cache/compress/"
compress.filetype           = ("text/plain", "text/html")

# Custom settings
# Set-up some aliases
alias.url = ( 
              "/admin-media" => "/django/contrib/admin/media",
              "/images" => "/docroot/images",
              "/static" => "/docroot/static"
)
# Startup the fastcgi server, point it at my custom
# fastcgi script.
fastcgi.server = (
    "/byteflow.fcgi" => (
        "main" => (
            "socket" => "/tmp/byteflow.socket",
            "bin-path" => "/docroot/byteflow.fcgi" 
        ) 
    ) 
)
# Make sure we're passing on these urls
# bare, don't process them with django.
url.rewrite-once = (
    "^(/rpc.*)$" => "$1",
    "^(/images.*)$" => "$1",
    "^(/static.*)$" => "$1",
    "^(/admin-media.*)$" => "$1",
    # Then push the rest through django
    "^(/.*)$" => "/byteflow.fcgi$1"
)
# Legacy url, redirect it to new feedburner.
url.redirect = (
    "^/rpc([\/]*)" => "http://feeds.feedburner..truncated..",
)

Here is my fast-cgi script, which resides in my docroot.

#!/bin/sh
# byteflow.fcgi

export PYTHONPATH=$PYTHONPATH:/home/bsmith/Dev
export DJANGO_SETTINGS_MODULE=byteflow.settings

/home/bsmith/Dev/byteflow/manage.py runfcgi

Compared to a run of the mill apache setup, this is cake walk. I commented the important bits so you can get the gist of what’s going on. If you have a question required more detail, let me know.

After spending a few hours converting my data to the model that django built for byteflow, I then focused on cloning my old theme. As you can see, I didn’t to a bad job! I tried to clean it up a bit and make sure I have more content for the search engines to munch on. Other than that bit of extra work, building the templates for this was pretty simple.

As you may have noticed, I also began using feedburner to serve up my rss feeds. That’s where the apology comes in..If you’re subscribed, most likely you have experienced duplicate posts..like..all of them. So, with that said So Sorry!.

0 comments | 0 pingbacks
More Posts: »