Hi,
I'd like to create a dynamic cmd-action. I attempted to do this using
the environment setup in the following example.
After 'doit ffmpeg' the new.flv file should contain:
'ffmpleg -doitexample 20'
def setup(self):
try:
fh=open(origxml,"r")
self.meta=fh.read()
fh.close()
except IOError:
#this is run before the task can generate the xml file
#in that case just exit
print "file does note exist"
return None
fps_re=re.compile(r"""<framerate>(.*)</framerate>""")
fps_reobj=fps_re.search(self.meta)
if fps_reobj:
self.fps=fps_reobj.group(1)
print self.fps
metaA=MetaData()
def task_metaxml():
"generate the metadata xml file for post-processing (get framerate
to determine ffmpeg params for encoding)"
#cmd="""yamdi -i {vid} -x {xml}""".format(vid=origflv,xml=origxml)
cmd="""echo "<framerate>20</framerate>" > {xml}""".format
(xml=origxml)
return {'actions': [cmd],
'targets': [origxml],
'clean':True,
}
#'dependencies':[origflv],
On Wed, Nov 11, 2009 at 12:37 AM, LJN <ljnacco...@emailengine.net> wrote:
> Hi, > I'd like to create a dynamic cmd-action. I attempted to do this using > the environment setup in the following example.
Hi,
No. environment setup is not supposed to be used for that.
what's wrong ===========
Here is an explanation why your code does NOT work. I notice many people get this wrong and I was already planning to improve the docs about this.
"def task_xxx()"... is not the task itself. it is a "task generator". the task is the "dictionary returned by the task generator. The task generators are executed when dodo.py is loaded. So
As I understood... you are trying to use the result of a computed value in task. So lets say the Metada.setup should be a task => task_get_metadata.
So we want to be able to use a value calculated in a task in another task. This is not really supported on doit right now. Lets take a look in the options we have (starting from a hack to a feature proposal in doit):
1 - use subprocess ------------------------ if task_get_metadata is executed only when you call task_ffmpeg, or it is not very expensive operation. You could combine everything in one python-task:
this is far from ideal but can solve your problem right now.
2- save computed value in a file ------------------------------------------ you could save the value of task_get_metadata in a file and then read it on task_ffmepg. actually the reason i created doit was to avoid this kind of file manipulations...
3- make doit save computed values from task ------------------------------------------------------------ actually I've done some work towards this... doit saves a dictionary with some info for every task. so adding and saving some data on it should be quite easy. what i still didnt figure out is how the interface should be.
Please tell what you think about this...
task_get_metada would return a dictionary like return {'fps':20} , doit would save this...
a cmd-action could access this using string formatting. i.e. def task_ffmpeg(): def task_ffmpeg(): cmd="echo ffmpeg -doitexample %(fps)s" return {'actions': [cmd,], 'values': {'fps': ':get_metadata.fps'} # ===> tells doit to get value saved on task_get_metadata 'targets': [newflv], 'dependencies':[origxml], 'clean':True, }
for python-action you would access this values through function patameters like
def task_ffmpeg(): def myaction(fps): print pfs return {'actions': [(myaction,),], 'values': {'fps': ':get_metadata.fps'} # ===> tells doit to get value saved on task_get_metadata 'targets': [newflv], 'dependencies':[origxml], 'clean':True, }
doit would take care of passing the 'values' dictionary to the python-action function.
Thanks for your explanation. I'm now using the subprocess workaround,
but would prefer something similar to your proposal (3) to pass
variable values to the cmd-action.
Some comments on proposal 3
---------------------------
On Thu, Nov 12, 2009 at 6:44 AM, LJN <ljnacco...@emailengine.net> wrote:
> Thanks for your explanation. I'm now using the subprocess workaround, > but would prefer something similar to your proposal (3) to pass > variable values to the cmd-action.
thanks for the feedback.
FYI I am going to try to push doit 0.5 by the end of this month but I am quite busy and I guess this wont make into it 0.5... But I will definitely look into it at some point... or you could try to take a look in it by yourself. I guess it wont be that hard.
<schettin...@gmail.com> wrote: > On Thu, Nov 12, 2009 at 6:44 AM, LJN <ljnacco...@emailengine.net> wrote:
>> Thanks for your explanation. I'm now using the subprocess workaround, >> but would prefer something similar to your proposal (3) to pass >> variable values to the cmd-action.
> thanks for the feedback.
> FYI I am going to try to push doit 0.5 by the end of this month > but I am quite busy and I guess this wont make into it 0.5... But I > will definitely look into it at > some point... or you could try to take a look in it by yourself. I > guess it wont be that hard.
On Wed, Nov 11, 2009 at 8:44 PM, LJN <ljnacco...@emailengine.net> wrote:
> Thanks for your explanation. I'm now using the subprocess workaround, > but would prefer something similar to your proposal (3) to pass > variable values to the cmd-action.
I finally found some time to implement this. Now you can use saved/computed values from another task. Here is a trivial example
> I finally found some time to implement this. Now you can use > saved/computed values from another task. Here is a trivial example
Great - I converted my task to the new method.
> you need latest trunk to test this. I used the name "taskargs" though > i dont like it. suggestions are welcome.
taskargs getargs ?
With the subprocess workaround I built the shell command within the python-action. The shell cmd was several lines and used .format() to substitute many variables. In converting the task I had to move the shell cmd definition to within the task return statement.
The return line is awkward in that it uses .format() as well as the % substitution. return {'actions': ['echo %(x)s %(z)s {c1} - 5 20 1'.format(c1=constantvar1)],
Of course I could have passed all the variables (constantvar1) from the compute task.
I tried another variation: -----------------------
# combining tasks compute2 and use # the following would require support for passing from python-action to cmd-action #- build the shell command outside the return statement #- group the python function that builds the shell command in the same task as the cmd-action
On Fri, Jan 15, 2010 at 10:32 PM, <ljnacco...@emailengine.net> wrote:
> With the subprocess workaround I built the shell command within the > python-action. The shell cmd was several lines and used .format() to > substitute many variables. In converting the task I had to move the > shell cmd definition to within the task return statement.
> based on your example: > -----------------------
> The return line is awkward in that it uses .format() as well as the % > substitution. > return {'actions': ['echo %(x)s %(z)s {c1} - 5 20 > 1'.format(c1=constantvar1)],
> # the following would require support for passing from python-action to > cmd-action > #- build the shell command outside the return statement > #- group the python function that builds the shell command in the same > task as the cmd-action
the implementation of "this.something" would be actually completely different from using taskargs from other tasks. taskargs values are saved only after all task actions are completed successfully.
I guess this feature 'this.something' is not strictly necessary for any use-case (as far as i can see, but i might be wrong). i am trying to avoid adding features to doit that would increase its complexity and brings little gain in functionality.