<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Non-Python Actions</title>
		<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions</link>
		<description>Posts in the discussion thread &quot;Non-Python Actions&quot; - Tool to allow definition of actions implemented by external tools.</description>
				<copyright></copyright>
		<lastBuildDate>Fri, 13 Mar 2026 20:33:11 +0000</lastBuildDate>
		
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-572828</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-572828</link>
				<description></description>
				<pubDate>Mon, 31 Aug 2009 02:57:41 +0000</pubDate>
				<wikidot:authorName>stani</wikidot:authorName>				<wikidot:authorUserId>60092</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hi, a geek command for any task is integrated in Phatch 0.2:<br /> <a href="https://launchpad.net/~stani/+archive/ppa">https://launchpad.net/~stani/+archive/ppa</a></p> <p>There is even a separate imagemagick action.</p> <p>Please test.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-126329</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-126329</link>
				<description></description>
				<pubDate>Mon, 17 Mar 2008 10:41:40 +0000</pubDate>
				<wikidot:authorName>stani</wikidot:authorName>				<wikidot:authorUserId>60092</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>You can now vote for the main feature for the next version of Phatch:<br /> <a href="http://ubuntuforums.org/showthread.php?t=726547">http://ubuntuforums.org/showthread.php?t=726547</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-125662</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-125662</link>
				<description></description>
				<pubDate>Sat, 15 Mar 2008 23:07:13 +0000</pubDate>
				<wikidot:authorName>stani</wikidot:authorName>				<wikidot:authorUserId>60092</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>For the sake of completeness, this is the blueprint for people following this thread:<br /> <a href="https://blueprints.launchpad.net/phatch/+spec/external-actions">https://blueprints.launchpad.net/phatch/+spec/external-actions</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-123948</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-123948</link>
				<description></description>
				<pubDate>Wed, 12 Mar 2008 21:26:06 +0000</pubDate>
				<wikidot:authorName>kwhitefoot</wikidot:authorName>				<wikidot:authorUserId>90079</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Ah, now I see what you mean by file a blueprint. I hadn't seen the Launchpad page before. I'll add a note there.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-123871</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-123871</link>
				<description></description>
				<pubDate>Wed, 12 Mar 2008 19:14:16 +0000</pubDate>
				<wikidot:authorName>kwhitefoot</wikidot:authorName>				<wikidot:authorUserId>90079</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I'm not entirely sure where I should file a blueprint so I'll post<br /> what I have so far in this message.</p> <p>The basic idea is to have a tool that reads a description of a command<br /> line together with a description of the allowed values of the<br /> arguments that then either generates the action classes on the fly or<br /> write files for later use by Phatch.</p> <p>Because I don't really understand the inner workings of Phatch (and<br /> also because I suspect that the architecture doesn't support multiple<br /> action classes in the same file) I chose to make a simple tool that<br /> would create action class files.</p> <p>Of course on the fly generation is preferable for a production version<br /> but I think that might need some changes to Phatch itself.</p> <p>The prototype code only handles slider and choice fields but I think<br /> it serves well enough as a proof of concept.</p> <p>As you point out the overhead is considerable but the convenience of<br /> being able to generate syntactically correct command lines every time<br /> makes experimentation much more comfortable as you can concentrate on<br /> the effect instead of the technicalities of shell scripting.</p> <p>Also the technique can be used to execute scripts that do not actually<br /> process the image but do some meta-data processing (in principle at least<br /> but I must learn more about Phatch before I can say what might be done).</p> <p>The other reason for doing it is that there are a lot of image<br /> manipulation command line programs about and it seems to me much<br /> better to make them available to Phatch users as they are rather than<br /> to expect the same effects to be added to Phatch.</p> <p>It is reasonable to expect people to prefer one implementation of,<br /> say, edge detection over another and by adding such a feature we can<br /> give people the best of both worlds.</p> <p>In the prototype I have chosen to describe the actions using small<br /> Python scripts to be executed in a restricted environment by execfile.<br /> I have given them the extension .gph so that they will be easy to<br /> distinguish from other Python scripts</p> <p>As you can see the structure closely resemble the essential parts of<br /> the action template.</p> <p>To create the action classes from these I run the generic.py script in<br /> the same folder (see under).</p> <p>the script is not especially elegantly written and it has pretty much<br /> zero error checking. In particular it wll fail if any of the label,<br /> author, etc., variables are not set.</p> <p>Here are two example descriptions files and the script that transforms them into action files:</p> <div class="code"> <pre><code>-- begin imsolarize.gph ------------------------------- # ImageMagick solarize label='IM Solarize' author = 'KJW' email = 'kwhitefoot@hotmail.com' tags = ['ImageMagick'] doc = 'Solarize' cmd='convert &quot;%(source)s&quot; -solarize %(threshold)s &quot;%(dest)s&quot;' fields = [ {'name': 'threshold', 'min': 1,'max':100, 'default':50} ] -- end imsolarize.gph ------------------------------- -- begin imdither.gph -------------------------------- # ImageMagick Floyd-Steinberg dither label='IM Dither' author = 'KJW' email = 'kwhitefoot@hotmail.com' tags = ['ImageMagick'] doc = 'Dither' cmd='convert &quot;%(source)s&quot; -colorspace %(colorspace)s -colors %(colors)s -dither &quot;%(dest)s&quot;' fields = [ {'name': 'colors', 'min': 1,'max':100, 'default':50}, {'name': 'colorspace', 'choices':['CMYK', 'GRAY', 'HSL', 'HWB', 'OHTA', 'Rec601Luma', 'Rec709Luma', 'RGB', 'Transparent', 'XYZ', 'YCbCr', 'YIQ', 'YPbPr', 'YUV'], 'default': 'RGB'}] -- end imdither.py ------------------------------- -- begin generic.py ------------------------------- #! /usr/bin/python # # Phatch custom action - generic two port # Copyright (C) 2008 Kevin Whitefoot # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ # Notes: # Convert is used instead of mogrify because mogrify fails on my # Ubuntu 7.04 machine. I don't know why but it simply does nothing # even when I run it by hand in a terminal window. # Also subprocess.call is used with a string command line and # shell=True because convert fails if you try to use a sequence. # The point here is to create Phatch Action classes on the fly from a # text file listing the attributes and a command line template. # Finally the save command must save to png not jpeg because saving to # jpeg gives this error message: 'Cannot write modeP as JPEG' #from core import models #from core.translation import _t #import os #from tempfile import mkstemp #import subprocess import glob import os templatePhatch = r&quot;&quot;&quot; from core import models from core.translation import _t import os from tempfile import mkstemp import subprocess def init(): global Image, ImageOps import Image, ImageOps def impil(image %(pilargs)s): (handle,source) = mkstemp('.png', 'temp') os.close(handle) (handle,dest) = mkstemp('.png', 'temp') os.close(handle) image.save(source) cmd = '%(cmd)s' %% %(cmdargs)s print &quot;cmd:&quot; + cmd subprocess.call(cmd, shell=True) # reload the file result = Image.open(dest) # delete it #os.remove(source) #os.remove(dest) return result #--- Phatch Action class Action(models.Action): label = _t('%(label)s') author = '%(author)s' email = '%(email)s' init = staticmethod(init) pil = staticmethod(impil) version = '0.1' tags = %(tags)s __doc__ = _t('%(doc)s') def interface(self,fields): %(fields)s &quot;&quot;&quot; # templates for various fields templateSlider = &quot;SliderField(%(default)u, %(min)u, %(max)u)&quot; templateChoice = &quot;ChoiceField('%(default)s', %(choices)s)&quot; # fields[_t('Boolean')] = self.BooleanField(True) # fields[_t('String')] = self.CharField('hello world') # fields[_t('Choice')] = self.ChoiceField(CHOICES[0], CHOICES) # fields[_t('Colour')] = self.ColourField('#FFFFFF') # fields[_t('Resolution')]= self.DpiField('&lt;dpi&gt;') # fields[_t('File')] = self.FileField('/home/images/logo.jpg') # fields[_t('Filename')] = self.FileNameField('&lt;filename&gt;') # fields[_t('In')] = self.FilePathField('&lt;folder&gt;') #folder # fields[_t('Float')] = self.FloatField(3.14) # fields[_t('As')] = self.ImageTypeField('&lt;type&gt;')#png, jpg # fields[_t('As')] = self.ImageReadTypeField('&lt;type&gt;')#png, jpg # fields[_t('As')] = self.ImageWriteTypeField('&lt;type&gt;')#png, jpg # fields[_t('Mode')] = self.ImageModeField('&lt;mode&gt;')#png, jpg # fields[_t('Resample')] = self.ImageResampleField(_t('bicubic')) # fields[_t('Integer')] = self.IntegerField(-4) # fields[_t('Integer+')] = self.PositiveIntegerField(0) # fields[_t('Integer+0')] = self.PositiveNoneZeroIntegerField(0) # fields[_t('Horizontal')]= self.PixelField('5%') #accepts %,cm, inch # fields[_t('Slider')] = self.SliderField(60,1,100) # Load all the gph files and create action classes for each one. def loadgphs(): # get a list of gph files # for each gph file do: # read file into variable d = glob.glob(&quot;*.gph&quot;) for f in d: print f l = {} execfile(f, {}, l) print 'cmd: ', l['cmd'] pilargs, cmdargs, fields = makefields(l['fields']) print fields l['fields'] = fields l['pilargs'] = pilargs l['cmdargs'] = cmdargs tags = '' for t in l['tags']: tags += ',' &quot;_t('&quot; + t + &quot;')&quot; l['tags'] = '[' + tags[1:] + ']' fout = open(os.path.splitext(f)[0] + '.py', &quot;w+&quot;) print fout.name s = templatePhatch % l fout.write(s) def makefields(fieldsdef): indent = ' ' fields = '' pilargs = '' cmdargs = '' for fielddef in fieldsdef: name, field = makefield(fielddef) fields += indent + field + '\n' pilargs += &quot;, &quot; + name cmdargs = cmdargs + &quot;, '%s': %s&quot; % (name, name) cmdargs = '{&quot;source&quot;: source, &quot;dest&quot;: dest, ' + cmdargs[1:] + '}' return pilargs, cmdargs, fields def makefield(fdef): print 'makefield' print fdef if 'min' in fdef: # use slider f = (&quot;fields[_t('%(name)s')] = self.&quot; + templateSlider) % fdef elif 'choices' in fdef: # use choice field f = (&quot;fields[_t('%(name)s')] = self.&quot; + templateChoice) % fdef else: print 'Unexpected field type: %s' % fdef return fdef['name'], f # Load all gph files and create all classes loadgphs() print 'finished' -- end generic.py ------------------------------- insert the code here</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-116564</guid>
				<title>Re: Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-116564</link>
				<description></description>
				<pubDate>Sat, 01 Mar 2008 22:11:47 +0000</pubDate>
				<wikidot:authorName>stani</wikidot:authorName>				<wikidot:authorUserId>60092</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Please file a blueprint for this. Note that this will create quite some overhead as images have to be saved from memory to disk and immediately afterwards be reloaded in memory. On the other hand you get the advantage that the complexity dissappears.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://photobatch.wikidot.com/forum/t-44277#post-116514</guid>
				<title>Non-Python Actions</title>
				<link>http://photobatch.wikidot.com/forum/t-44277/non-python-actions#post-116514</link>
				<description></description>
				<pubDate>Sat, 01 Mar 2008 19:31:48 +0000</pubDate>
				<wikidot:authorName>kwhitefoot</wikidot:authorName>				<wikidot:authorUserId>90079</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>This tool looks very useful. It could save me a lot of work if only it had the actions I want. Unfortunately one tool cannot do everything but what this tool could do is act as a launcher for other tools. It seems a shame to have to reinvent all the actions that already exist in other tools</p> <p>In particular it would be really neat if it could execute ImageMagick/GraphicsMagick/NetPBM commands. IM/GM command lines are irritatingly difficult to construct when you try to do more than one action so a graphical composer for a pipeline of actions would be very handy</p> <p>One way to make it do this and at the same time make it almost future-proof would be to allow the user to define new actions based on simple command lines with macro substitution of file names and other parameters.</p> <p>What I have in mind is a dialog box that would allow for the creation of a new command and the naming of all the possible parameters and a template command line. The definition could be saved in a simple text file one line for each item. A subdirectory could be defined under .phatch for user defined external tool actions. In fact in the beginning the dialog box could be omitted and the tool could simply read user defined action files from the subdirectory.</p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>