xenogenesi::blog
memento
3d adt android apache2 app apt aria2 build bullet cflags chromium codeigniter debian demoscene dependencies dpkg driver emulator freeglut gcc gfx git glut htaccess javascript json kernel linux make metalink minimal mysql opengl php python raspbian realtime rpi specs template toolchain update-alternatives video wifi wordpress

scripting gimp in python

gimp support being scripted with python (2.7) menu Filters > Python Fu > console, you don’t even need to write a plugin, just type execfile("/some/path/your-script.py") to the console prompt

the python console have a very nice Browse button which allow to find the functions you need from the procedure browser (and their arguments), those may be exported from gimp or plugins

For example, I needed to crop each layer and save it as png file, save the name of the layer and the crop coordinates in a json file, here it is:

savepath="/tmp/slices/"
f=open("{0}images.json".format(savepath),"w")

print >> f, "["

def process_layer(image, layer):
    pdb.gimp_image_set_active_layer(image, layer)
    drawable = pdb.gimp_image_active_drawable(image)
    layer_name = pdb.gimp_item_get_name(drawable)
    if layer_name == "background":
        return

    pdb.gimp_selection_none(image)

    pdb.gimp_context_set_sample_merged(FALSE)
    pdb.gimp_context_set_antialias(FALSE)
    pdb.gimp_context_set_sample_transparent(TRUE)
    pdb.gimp_context_set_feather(FALSE)
    pdb.gimp_context_set_sample_threshold(0)
    pdb.gimp_image_select_contiguous_color(image, 2, drawable, 1, 1)
    pdb.gimp_selection_invert(image)
    non_empty, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image)
    if non_empty:
        pdb.gimp_image_select_rectangle(image, 2, x1, y1, x2-x1, y2-y1)
        non_empty = pdb.gimp_edit_copy(drawable)
        if non_empty:
            image4 = pdb.gimp_edit_paste_as_new()
            active_layer = pdb.gimp_image_get_active_layer(image4)
            pdb.file_png_save2(image4, active_layer, "{0}{1}.png".format(savepath, layer_name), layer_name, TRUE, 9, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE)
            pdb.gimp_image_delete(image4)

            print >> f, "\t{{ \"{0}\": [ {1:d}, {2:d}, {3:d}, {4:d} ] }},".format(layer_name, x1, y1, x2, y2)
        else:
            print("gimp_edit_copy = empty ({0})".format(layer_name))
    else:
        print("gimp_selection_bounds = empty ({0})".format(layer_name))


image = gimp.image_list()[0]

for layer in image.layers:
    process_layer(image, layer)


print >> f, "]"

f.close()

github gist

delete thousands of spam comments from WordPress

A friend with a WordPress website asked for help cleaning up from spam about ~400 thousands comments (about ~200M), he had guests enabled to comment.

I chosen to use python with curses (ncurses) and this pybayesantispam python module.

The curses GUI is a list with an abstract from the comment content and a column with the current spam rating, a cursor to select a comment and some key to tag it as (s)pam or (h)am, the bayesian module require some manual training, (n)ext (p)revious to browse the comments table.

The code is ugly, had a very limited time, but I been impressed how fast got a good result.

The current code include GeoIP and show the country code but isn’t used to filter the spam, in this case was an overhead, but would have been easy to add more weight factors: create a whitelist of emails from manually tagged ham, blacklist from manually tagged spam, guests users have id 0, blacklist/whitelist of ip from manually tagged comments.

py-curses-wp-spam.tgz

python/jinja2 for metaprogramming

A simple example using python and jinja2 template engine, I’m evaluating it for doing some metaprogramming (generating php/html and javascript from a json).
I evaluated also fmpp/freemarker but jinja2 is just so simple and its syntax doesn’t conflict with php/html/javascript/css.

test.py:

from jinja2 import Template
import json

rootJson = json.load(open('test.json', 'r'))

tpl = Template(open('test.jinja', 'r').read().decode('utf-8'))
print tpl.render(root=rootJson).encode('utf-8')

test.json:

{
    "test": "valueèè&&"
}

test.jinja:

Hello {{ root.test|e }}