1 # Pyvconv - A simple frontend for ffmpeg/mencoder
2 # Copyright (C) 2008, Kristian Rumberg (kristianrumberg@gmail.com)
4 # Permission to use, copy, modify, and/or distribute this software for any
5 # purpose with or without fee is hereby granted, provided that the above
6 # copyright notice and this permission notice appear in all copies.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 class Error(Exception):
20 def __init__(self
, value
):
21 Exception.__init
__(self
)
24 return repr(self
.value
)
27 def __init__(self
, namestr
, defaultstr
, exprstr
):
28 self
.namestr
= namestr
29 self
.defaultstr
= defaultstr
30 self
.exprstr
= exprstr
36 return self
.defaultstr
!= None
39 if self
.defaultstr
== None:
40 raise Error("Error: Trying to eval variable " + self
.namestr
+ " with no value")
41 return self
.defaultstr
43 class OptionalSetting
:
44 def __init__(self
, namestr
, exprstr
):
45 self
.namestr
= namestr
46 self
.exprstr
= exprstr
51 def evaluate(self
, var_list
):
54 if var_list
[var
].has_value():
55 p
= re
.compile( "\$\{" + var
+ "\}")
56 instr
= p
.sub( var_list
[var
].evaluate(), instr
)
57 if instr
.find("$") != -1:
58 instr
= "" # if not all variables were found, return empty option
62 def __init__(self
, namestr
, callstr
, var_list
, optset_list
):
63 self
.namestr
= namestr
64 self
.callstr
= callstr
65 self
.var_list
= var_list
66 self
.optset_list
= optset_list
71 def put_var(self
, var
):
72 self
.var_list
[str(var
)] = var
80 p
= re
.compile("\$\[(\w+)\]")
81 for o
in p
.findall(instr
):
82 if o
not in self
.optset_list
:
83 raise Error("Error: Optional variable not defined")
84 instr
= p
.sub(self
.optset_list
[o
].evaluate(self
.var_list
), instr
)
86 p
= re
.compile("\$\{(\w+)\}")
87 for o
in p
.findall(instr
):
88 if o
not in self
.var_list
:
89 raise Error("Error: Variable \"" + o
+ "\" has not been assigned")
90 val
= self
.var_list
[o
].evaluate()
91 instr
= instr
.replace("${" + o
+ "}", val
)
93 if instr
.find("$") != -1:
94 raise Error("Error: all variables were not expanded")
98 return self
.evaluate()
100 class RenderCommands
:
102 self
.cmdcall_dict
= {}
105 def _read_properties(self
, propnode
, mand_propnames
, opt_propnames
= []):
109 if p
.name
in mand_propnames
:
110 propdict
[p
.name
] = str(p
.content
)
111 elif p
.name
!= "text" and p
.name
not in opt_propnames
:
112 raise Error("Error parsing XML: only name and call are accepted properties in the element command, found " + str(p
.name
))
114 if len(mand_propnames
) != len(propdict
.keys()):
115 raise Error("Error parsing XML: must supply both name and call in element command")
118 if p
.name
in opt_propnames
:
119 propdict
[p
.name
] = str(p
.content
)
120 elif p
.name
!= "text" and p
.name
not in mand_propnames
:
121 raise Error("Error parsing XML: only name and call are accepted properties in the element command, found " + str(p
.name
))
125 def _read_config(self
):
126 doc
= libxml2
.parseFile("rendercommands.xml")
127 cmd_xmllist
= doc
.xpathEval( '//command')
129 # read all commands from XML description
130 for cmdnode
in cmd_xmllist
:
131 if cmdnode
.type == "element" and cmdnode
.name
== "command":
137 for varsetnode
in cmdnode
.children
:
138 if varsetnode
.type == "element" and varsetnode
.name
== "variable":
139 props
= self
._read
_properties
(varsetnode
.properties
, ["name", "expr"], ["default"])
141 if "default" in props
:
142 defprop
= props
["default"]
143 var_list
[props
["name"]] = Variable(props
["name"], defprop
, props
["expr"])
145 elif varsetnode
.type == "element" and varsetnode
.name
== "optionalsetting":
146 props
= self
._read
_properties
(varsetnode
.properties
, ["name", "expr"])
147 optset_list
[props
["name"]] = OptionalSetting(props
["name"], props
["expr"])
149 elif varsetnode
.name
!= "text":
150 raise Error("Error parsing XML: only variable and optionalsetting elements allowed in command")
152 props
= self
._read
_properties
(cmdnode
.properties
, ["name", "call"])
153 self
.cmdcall_dict
[props
["name"]] = RenderCommand(props
["name"], props
["call"], var_list
, optset_list
)
156 raise Error("Error parsing XML: only command elements are supported")
159 return self
.cmdcall_dict
.values().__iter
__()
162 commands
= RenderCommands()
164 c
.put_var(Variable("in", "src.avi", None))
165 c
.put_var(Variable("out", "dest.avi", None))
168 if __name__
== "__main__":