-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplate.py
369 lines (343 loc) · 12.4 KB
/
template.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
import os
import sys
try:
import _winreg
hasWindowsRegistry=True
except ImportError:
hasWindowsRegistry=False
if hasWindowsRegistry:
def registerMenu(key,menuName,command):
"""
Registers a given context menu command with a certain file type
"""
hkcr=_winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,None)
while key[0]==".":
try:
val=_winreg.QueryValue(hkcr,key)
except WindowsError:
val=None
if val==None or val=="" or val==key:
break
key=val
print "Registering \""+key+"\" menu \""+menuName+"\""
reg=_winreg.CreateKey(hkcr,key)
reg=_winreg.CreateKey(reg,"shell")
shortName=""
for c in menuName:
if c!=' ':
shortName=shortName+c
reg1=_winreg.CreateKey(reg,shortName)
_winreg.SetValue(reg,shortName,_winreg.REG_SZ,menuName);
reg=_winreg.CreateKey(reg1,"command")
_winreg.SetValue(reg1,"command",_winreg.REG_SZ,command)
else:
def registerMenu(key,menuName,command):
print "ERR: Unable to register file extension with this OS!"
def register(filenames=None):
"""
registers the given template(s) or all the templates in the "templates"
directory if unspecified
"""
class MT():pass
def breakout(key,val,context):
if val!="":
setattr(context,"break",0)
return context
def savekey(key,val,context):
setattr(context,key,fixString(val))
return context
def savearray(key,val,context):
setattr(context,key,stringArray(val))
return context
fns={}
fns["*"]=breakout
fns["template_name"]=savekey
fns["sources"]=savearray
# figure out path
path=os.path.abspath(__file__)
path=path[0:path.rfind(os.sep)+1]+"templates"+os.sep
if filenames==None:
# list everything in the templates folder
files=os.listdir(path)
filenames=[]
for filename in files:
filenames.append(path+filename)
if type(filenames).__name__!='list':
filenames=[filenames]
for filename in filenames:
context=MT()
processTemplate(filename, fns, context)
if hasattr(context,"template_name")==False:
print "File \"",filename,"\" missing $(template_name). Skipping."
elif hasattr(context,"sources")==False:
print "File \"",filename,"\" missing $(sources). Skipping."
else:
# register it for all sources and "folder"
cmd="python \""+path+"template.py\" --template=\""+filename+"\" \"%1\""
registerMenu("folder",context.template_name,cmd)
for extn in context.sources:
if extn!=None and extn!="":
if extn[0]!=".":
extn="."+extn
registerMenu(extn,context.template_name,cmd)
def template(templateFile, files, outDir=None):
"""
runs the given template on the given list of files
(any directories in with the files will start a recursive template)
"""
class MT():pass
if outDir==None:
outDir=""
else:
os.makedirs(outDir)
def generate(key,var,context):
print "generate(",key,var,context,")"
print "\tgenerating "+var
params=stringArray(var)
fileMappings={}
for filename in context.files:
if os.path.isfile(filename):
# TODO: if this file is one of the applicable sources, generate
resultFilename=""
fileMappings[filename]=resultFilename
context.mappings[params[3]]=fileMappings
return context
def sources(key,var,context):
print "sources(",key,var,context,")"
setattr(context,"sources",stringArray(var))
return context
def printout(key,var,context):
print "printout(",key,var,context,")"
if context.out==None:
outFilename=outDir+filename[filename.rfind(os.sep):]
context.out=open(outFilename,"w")
context.out.write(var)
return context
def count(key,var,context):
print "count(",key,var,context,")"
if context.out==None:
outFilename=outDir+context.filename[context.filename.rfind(os.sep):]
context.out=open(outFilename,"w")
context.out.write(str(len(files)))
return context
def switchFile(key,var,context):
print "switchFile(",key,var,context,")"
if context.out!=None:
context.out.close()
context.out=None
context.filename=var
return context
def foreach(key,var,context):
print "foreach(",key,var,context,")"
if context.out==None:
outFilename=outDir+context.filename[context.filename.rfind(os.sep):]
context.out=open(outFilename,"w")
var=var.split("$(")
context.out.write(var[0])
for i in range(1,len(var)):
column=var[i]
pos=column.find(")")
sub=column[0:pos-1]
not exactly sure what I was going for here...
if sub==currentSource:
context.out.write(currentSource)
else:
context.out.write(context.mappings[sub][currentSource])
context.out.write(column[pos+1:])
return context
fns={}
fns["*"]=printout
fns["generate"]=generate
fns["sources"]=sources
fns["count"]=count
fns["foreach"]=foreach
context=MT()
setattr(context,"mappings",{})
setattr(context,"out",None)
setattr(context,"filename",templateFile)
if type(files).__name__!='list':
files=[files]
# first thing, recurse (aka depth-first recursion)
context.files=[]
context.subdirs=[]
for filename in files:
if os.path.isdir(filename):
# generate subdirs
template(templateFile, os.listdir(filename), outDir)
context.subdirs.append(filename)
else:
context.files.append(filename)
# now generate the template for this dir
processTemplate(templateFile, fns, context)
# shut things down
if context.out!=None:
context.out.close()
def fixString(string):
"""
Takes a string, trims it, and un-quotes it as necessary
"""
while string[-1]==" " or string[-1]=="\t" or string[-1]=="\r" or string[-1]=="\n":
string=string[:-1]
while string[0]==" " or string[0]=="\t":
string=string[1:]
while string[0]=='"' and string[-1]=='"':
string=string[1:-1]
return string
def stringArray(string):
"""
Takes a string that looks anything like " a",b, c,47 and parses it into a viable array
of strings like [" a","b","c","47"]
TODO: currently "a", "b" yields ["a", "", "b"] and I can't see why??
"""
result=[]
start=-1
for i in range(len(string)):
if string[i]=='"':
if start!=-1:
result.append(string[start:i])
while i<len(string) and string[i]!=',':
i=i+1
if i<len(string):
i=i+1
start=-1
else:
start=i+1
elif string[i]==',':
if start!=-1:
result.append(string[start:i])
start=-1
else:
start=i+1
elif string[i]==' ':
pass
elif start==-1:
start=i
if start!=-1 and start<len(string):
result.append(string[start:])
return result
def processTemplate(filename, fns, context=None):
"""
This reads a filename and for each $(key=val) item it will call fn["key"](key,val,context).
For text outside of $() it will call fn["*"]("*",val,context).
Finally, the $() can span multiple lines and can include $()'s within it. (Though these
will be ignored at this level and must be processed manually by the called function.
If the context object contains the special variable "break", after a fn[] call,
we will break with the exit code given.
"""
template=open(filename,"r")
if template==None:
print "Template file \"",filename,"\" not found!"
return -1
leftover=""
lineOffs=0
lineNo=0
stack=0
while True:
lineNo=lineNo+1
line=template.readline()
print lineNo,": ",line
if line==None or line=="": # should at least have a newline character
template.close()
return 0
# trim trailing characters
while line!="" and (line[-1]=="\n" or line[-1]=="\r" or line[-1]=="\t" or line[-1]==" "):
line=line[:-1]
if line=="":
continue
while True:
pos = line.find("$(")
if pos!=-1:
if fns.has_key("*"):
context=fns["*"]("*",line[0:pos],context)
if hasattr(context,"break"):
return getattr(context,"break")
line=line[pos+2:]
next=line.find("=")
close=line.find(")")
if close<next and close!=-1:
key=line[0:close]
line=line[close+1:]
if fns.has_key(key):
context=fns[key](key,"",context)
if hasattr(context,"break"):
return getattr(context,"break")
else:
print "Unknown key $("+key+")"
# skip unknown keys
pass
continue
key=line[0:next]
line=line[next+1:]
stack=stack+1
while True:
for i in range(len(line)):
c=line[i]
if c==")":
stack=stack-1
elif c=="(":
stack=stack+1
if stack<=0:
break
if stack<=0:
print "Calling "+key
if fns.has_key(key):
context=fns[key](key,leftover+line[0:i],context)
if hasattr(context,"break"):
return getattr(context,"break")
else:
print "Unknown key $("+key+")"
# skip unknown keys
pass
leftover=""
lineNo=lineNo+lineOffs
line=line[i+1:]
lineOffs=0
break
else:
leftover=leftover+line
line=template.readline()
lineOffs=lineOffs+1
if line==None or line=="":
template.close()
print "Template error unterminated \"$(\" in \"",filename,"\" line ",str(lineNo)
return -1
while line!="" and (line[-1]=="\n" or line[-1]=="\r" or line[-1]=="\t" or line[-1]==" "):
line=line[:-1]
else:
if fns.has_key("*"):
context=fns["*"]("*",line,context)
if hasattr(context,"break"):
return getattr(context,"break")
break
if __name__ == '__main__':
"""
This will generate a webpage based on images in this directory from a template.
"""
unknownArg=None
templateName=None
registerFlag=False
outDir=None
files=[]
for i in range(1,len(sys.argv)):
arg=sys.argv[i]
if arg[0]=="-":
while arg[0]=="-":
arg=arg[1:]
arg=arg.split("=")
if arg[0]=="register":
registerFlag=True
elif arg[0]=="template":
templateName=arg[1]
elif arg[0]=="outdir":
outDir=arg[1]
else:
unknownArg=True
else:
files.append(arg)
if unknownArg!=None or (templateName==None and registerFlag==None):
print "USAGE: python template.py [--register] [--template=template] [--outdir=dir] [filename(s)]"
else:
if registerFlag:
register (templateName)
else:
template (templateName, files, outDir)