Klangworks.org


Code Snippets


A scons SContruct file and rake Rakefile that do the same thing 

I've been trying to figure out how to use Rake - and how to use Scons. Scons has been around a while and seems further along in some ways. At the same time, for someone that doesn't know anything (me) it's hard to even figure out how to copy files. There has to be a better way, but this is what I came up with

In Ant this would be easy, and I could be more recursive about it

<copy dir="${build.dir}" includes="**/.*py, **/.*kid, **/*.xsl"/>
or something to that effect. So for now Ant seems easier.


# THE RAKE FILE
directory "deploy/bin"
directory "deploy/pyscripts/whs"
directory "deploy/pyscripts/whs/stylesheet"
directory "deploy/pyscripts/whs/templates"

task :default => [:deploy]

file "publish.pyw" => ["publish.py"] do |f|
   cp "publish.py", f.name
end

task :publish => 'publish.pyw'

task :deploy => [:publish, "deploy/bin", "deploy/pyscripts/whs", 
    "deploy/pyscripts/whs/stylesheet", 
    "deploy/pyscripts/whs/templates"]

file "deploy/bin" do |f|
    cp Dir["**.pyw"], f.name
end

file "deploy/pyscripts/whs" do |f|
    cp Dir["whs/**.py"], f.name
end

file "deploy/pyscripts/whs/stylesheet" do |f|
    cp Dir["whs/stylesheet/**.xsl"], f.name 
end

file "deploy/pyscripts/whs/templates" do |f|
    cp Dir["whs/templates/**.kid"], f.name 
end

#END RAKE

# THE SCONS FILE
import glob
import os

environment = Environment(ENV = {'PATH' : os.environ['PATH']})

make_windows_file = environment.InstallAs('publish.pyw', 
        File('publish.py'))
copy_main = environment.Install(dir=Dir('deploy/bin'), 
        source=glob.glob("*.py[w]"))
copy_module = environment.Install(dir=Dir('deploy/pyscripts/whs'), 
        source=glob.glob("whs/*.py"))
copy_templates = environment.Install(dir=Dir('deploy/pyscripts/whs/templates'), 
        source=glob.glob("whs/templates/*.kid"))
copy_xsl = environment.Install(dir=Dir('deploy/pyscripts/whs/stylesheet'), 
        source=glob.glob("whs/stylesheet/*.xsl"))

Alias("make_windows_file", make_windows_file)
Alias("main", copy_main)
Alias("module", copy_module)
Alias("templates", copy_templates)
Alias("xsl", copy_xsl)

Default("make_windows_file", "main","module","templates","xsl")

# END SCONS

03/30/06

Add leading zeros to a number 

This is kind of stupid, but it took a while to find this. The number (3) determines the number of digits total


number = 5
new_number = "%(#)03d" % {"#": number}

returns 005

05/08/06

Getting the current directory 

I lost this the other day, and found it difficult to find on the internet. It's stupid simple, but I never quite remember


from os import path
MODULE_HOME = path.dirname(path.abspath(__file__)) 

05/08/06

Calling Django from Scons 

Note I've updated this recently. It only works using Django > 0.95


# UPDATE - this has gotten easier as of Django 0.95 (Magic Removal)

from django.conf import settings as django_settings

MODULE_HOME = path.dirname('.')

template_dirs = (
    path.join(MODULE_HOME, 'templates'), 
)

django_settings.configure(DEBUG=True, 
        TEMPLATE_DEBUG=True,
        TEMPLATE_DIRS=template_dirs,
)

from django.template import Context, Template
from django.template import loader


""" run django templates"""
def run_django(target, source, env):
    """ runs a django template, given target and source and dict of values"""
    input_file = str(source[0]).encode('utf-8')
    output_file = str(target[0]).encode('utf-8')
    
    t = Template(open(input_file).read())
    # FIXME: could use this
    #django.template.loader.get_template(template_name)

    c = Context(env['context'])

    outfile = file(output_file, 'w')
    outfile.write(t.render(c))
    outfile.close()
    return None
       
django = Builder(action = run_django, suffix='.html', src_suffix='.html')

env = Environment(ENV = {'PATH' : os.environ['PATH']},
                          BUILDERS = {'Django' : django}
                          )

index_context = {"current_page": "default"}
index = env.Django(source="templates/default.html",target="site/default.html",context=index_context)

env.Alias("index", index)
env.Default("index")


09/13/06

Keeping a log of updates to records in Django 

I had the task of creating an RSS feed for wiki items as they are updated. I figured I would just use Django's post_save method. But then there was the classic chicken/egg problem. Luckily Django has the undocumented replaces_module meta attribute.

2/14/2007: I've changed this recently. After the "magic-removal" branch - this was much easier. So this only works for Django >= 0.95 and the replaces_module is no longer used. In fact that makes this bit of code trivial and typical, but I'm leaving it here anyway


from django.db import models
import datetime

class Tag(models.Model):
    """Tag (subject) of a Wikipage"""

    name = models.SlugField(maxlength=75)

    class Admin:
        pass

    class Meta:
        db_table = "wiki_tags"

    def __str__(self):
        return self.name


class Wikihistory(models.Model):
    """Wiki History for RSS"""

    wikipage = models.ForeignKey("Wikipage",db_column="wiki_page_id")
    created_at = models.DateTimeField(auto_now_add=True)

    class Admin:
        pass

    class Meta:
        db_table = "wiki_history"

    def __str__(self):
        if self.wikipage:
            return self.wikipage.title + " " + self.created_at.strftime("%m/%d/%y %I:%M %p")
        else:
            return self.created_at

    def get_absolute_url(self):
        date_formatted = self.created_at.strftime("%Y%m%d:%I:%M:%p")

        if self.wikipage:
            return "/wiki/view/%s" % (self.wikipage.title)
        else:
            return ""

class Wikipage(models.Model):
    """Wiki page"""

    title = models.CharField(maxlength=75)
    content = models.TextField(null=True,blank=True)
    
    tags = models.ManyToManyField(Tag,null=True,blank=True)

    class Admin:
        pass

    class Meta:
        db_table = "wiki_wikipages"

    def first_letter(self):
        return self.title[0].upper()

    def __str__(self):
        return self.title
    
    def save(self):
        super(Wikipage, self).save()
        entry = Wikihistory(wikipage=self)
        entry.save()

    def get_absolute_url(self):
        return "/wiki/%s/" % self.title


02/14/07