I needed a way to create many layers at once in inkscape, it support scripting with any language, the .inx
file allow to define input parameters to insert with a GUI, they will be passed to the script as command line arguments
Place the .inx
file and the python script in the inkscape directory
$HOME/.config/inkscape/extensions/create_layers.inx
$HOME/.config/inkscape/extensions/create_layers.py
create_layers.inx
:
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>Create Layers</_name>
<id>org.xenogenesi.filter.create_layers</id>
<dependency type="executable" location="extensions">create_layers.py</dependency>
<dependency type="executable" location="extensions">inkex.py</dependency>
<param name="basename" type="string" _gui-text="Base name of the new layer">New Layer {0}</param>
<param name="count" type="string" _gui-text="Number of layers to create">10</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="Layers"/>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">create_layers.py</command>
</script>
</inkscape-extension>
create_layers.py
:
#!/usr/bin/env python
import inkex
class CreateLayersEffect(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.OptionParser.add_option('-b', '--basename', action = 'store',
type = 'string', dest = 'basename', default = 'New Layer {0}',
help = 'Base name of the new layer')
self.OptionParser.add_option('-c', '--count', action = 'store',
type = 'string', dest = 'count', default = '10',
help = 'Number of layers to create')
def effect(self):
basename = self.options.basename
count = int(self.options.count)
svg = self.document.getroot()
for i in range(0, count):
layer = inkex.etree.SubElement(svg, 'g')
layer.set(inkex.addNS('label', 'inkscape'), basename.format(i))
layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
effect = CreateLayersEffect()
effect.affect()
github.com/xenogenesi/inkscape-pyext (one more extension to create layers for each selected object)
Here some great reference wiki.inkscape/Script_extensions
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()
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.