#!/usr/bin/python
#
# flow2html.py version 1.0
# 8/29/2005 by W. Rhett Davis (rhett_davis@ncsu.edu)
#
# (c) 2005, North Carolina State University. All rights reserved.
#
# Use and copying of this software and preparation of derivative works based
# upon this software are permitted. However, any distribution of this
# software or derivative works must include the above copyright notice.
# It is requested that modifications to this software be sent to the
# original author for inclusion with the primary distribution.
#
# This software is made available AS IS, and NCSU does not make any Warranty
# about the software, its performance or its conformity to any specification.
import sys, os, re, string, time
imagedir='/cygdrive/c/PROGRA~1/ATT/flow2html/images'
class dirlist:
def __init__(self,dirs=''):
# Sets self.dirs to be a list of strings, each containing the
# directory name (no slashes). If the first character in the
# directory name is a slash, then the first entry in self.dirs
# will be an empty string ''.
if type(dirs)==str:
self.dirs=string.split(dirs,'/')
# Get rid of leading blank, if 1st char is not slash
if self.dirs[0]=='':
if len(dirs)==0 or dirs[0]!='/':
self.dirs=self.dirs[1:]
# Get rid of the trailing slash, if it exists
if len(self.dirs)>0 and self.dirs[len(self.dirs)-1]=='':
self.dirs.pop()
elif type(dirs)==list:
self.dirs=list(dirs)
self.compress()
def __str__(self):
return string.join(self.dirs,'/')
def __add__(self,adddir):
if type(adddir)==str:
adddir=dirlist(adddir)
newdir=dirlist(self.dirs+adddir.dirs)
elif type(adddir)==list:
newdir=dirlist(self.dirs+adddir)
elif isinstance(adddir,dirlist):
newdir=dirlist(self.dirs+adddir.dirs)
else:
raise TypeError, str(type(adddir))+" is not one of the expected types (dirlist, str, or list)"
return newdir
def pop(self,num=1):
if len(self.dirs)>=num or (self.dirs[0]=='' and len(self.dirs)>=num+1):
self.dirs=self.dirs[:(len(self.dirs)-num)]
return True
else:
return False
def absolute(self):
if len(self.dirs)>0 and self.dirs[0]=='':
return True
else:
return False
def compress(self):
newdirlist=[]
for d in self.dirs:
if d=='..':
if len(newdirlist)==0:
newdirlist.append('..')
elif newdirlist[0]=='..':
newdirlist.append('..')
elif newdirlist[0]=='':
raise Exception, "No way to chdir to .. from /"
else:
newdirlist.pop()
else:
if d!='.':
newdirlist.append(d)
self.dirs=newdirlist
def verify(self):
for i in range(1,len(self.dirs)+1):
if i==1 and self.dirs[0]=='':
continue
if not os.access(string.join(self.dirs[:i],'/'),os.R_OK):
os.mkdir(string.join(self.dirs[:i],'/'))
def get_dir_prefix(self,rundir):
# Returns a dirlist instance which gives a path to the directory
# specified by this instance when currently in the directory
# specified by the [rundir] argument. For example:
#
# This directory rundir return value
# /usr/local X11/bin ../..
# /usr/local X11/../bin ..
# /usr/local /etc /usr/local
# run/cds .. cds
# run/cds ../dc ../cds
# run/cds ../../.. (error - no way to know)
# run/cds /etc (error - no way to know)
if type(rundir)==str:
rundir=dirlist(rundir)
elif type(rundir)==list:
rundir=dirlist(rundir)
elif isinstance(rundir,dirlist):
pass
else:
raise TypeError, str(type(rundir))+" is not one of the expected types (dirlist, str, or list)"
if len(rundir.dirs)>0 and rundir.dirs[0]=='':
if len(self.dirs)>0 and self.dirs[0]=='':
return self
else:
raise Exception, "No way to get to "+str(self)+" from "+str(rundir)
rundir.compress()
if str(rundir)=='':
return dirlist()
prefix=[]
workingdirs=list(self.dirs)
dirs=[]
for d in reversed(rundir.dirs):
if d!='..':
prefix.append('..')
else:
if len(workingdirs)==0:
raise Exception, "Directory "+str(rundir)+" nonexistent"
dirs.append(workingdirs.pop())
dirs=prefix+dirs
return dirlist(dirs)
def here_to_there(self,there):
# Returns a dirlist instance which gives a path to the directory
# specified by [there] from the directory specified by this instance.
# For example:
#
# here there return value
# run/cds run/dc ../dc
# (none) run/dc run/dc
# run/cds (none) ../..
# /usr /bin ../bin
# /usr run/dc (error - no way to know)
# run/cds /bin /bin
if type(there)==str:
there=dirlist(there)
elif type(there)==list:
there=dirlist(there)
elif isinstance(there,dirlist):
pass
else:
raise TypeError, str(type(there))+" is not one of the expected types (dirlist, str, or list)"
there.compress()
if (self.absolute() and not there.absolute()):
raise Exception, "No way to get to "+str(there)+" from "+str(self)
if (there.absolute() and not self.absolute()):
return there
heredirs=list(self.dirs)
theredirs=list(there.dirs)
# Advance to point where directories diverge
while len(heredirs)>0:
if len(theredirs)==0:
break
else:
if heredirs[0]!=theredirs[0]:
break
if len(theredirs)>1:
theredirs=theredirs[1:]
else:
theredirs.pop()
if len(heredirs)>1:
heredirs=heredirs[1:]
else:
heredirs.pop()
pathdirs=[]
for d in heredirs:
pathdirs.append('..')
return dirlist(pathdirs+theredirs)
def out_of_date(dep,targ):
# If forcing the run, automatically assume it's out of date.
if force:
return True
# Else, check the modification time
if not os.access(targ,os.F_OK):
return True
if not os.access(dep,os.F_OK):
raise Exception, "File "+dep+" does not exist"
if os.stat(dep)[8]>os.stat(targ)[8]:
return True
else:
return False
class htmlleftnav:
def __init__(self,title,navlist,cwd=''):
self.title=title
self.navlist=navlist
self.cwd=dirlist(cwd)
self.imagedir=dirlist('images')
self.cornerimage='flowdb_small.gif'
self.navcolor='white'
def setHeaderFooter(self):
s="\n
\n"+self.title+""
s=s+'''
'''
self.footer=s
def chdir(self,dirs):
self.cwd=self.cwd+dirs
def popdir(self,num=1):
for i in range(num):
self.cwd.dirs.pop()
def write(self,filename,body):
self.setHeaderFooter()
f=open(filename,"w")
f.write(self.header+body+self.footer)
f.close()
class dobj:
def __init__(self,name):
self.name=name
self.doc=''
class stepType:
def __init__(self,id,name):
self.id=id
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.name=name
self.doc=''
self.flow=False
def writedotfile(self,filename,debug=False):
f=open(filename,'w')
f.write("digraph G {\n")
f.write(" node [fontsize=10,height=0.1];\n")
f.write(" nodesep = 0.1;\n")
if debug:
f.write(' '+self.dotid+' [style=filled,fillcolor=green,label="' \
+self.dotid+'"];\n')
else:
f.write(' '+self.dotid+' [style=filled,fillcolor=green,label="' \
+self.name+'"];\n')
f.write('}\n')
f.close()
def html(self):
s='Step Type:
\n'+self.id+'
\n'
s=s+self.name+'
\n'
s=s+'
\n'
s=s+self.doc
return s
class fileType:
def __init__(self,id,name):
self.id=id
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.name=name
self.doc=''
self.flow=False
def writedotfile(self,filename,debug=False):
f=open(filename,'w')
f.write("digraph G {\n")
f.write(" node [fontsize=10,height=0.1];\n")
f.write(" nodesep = 0.1;\n")
if debug:
f.write(' '+self.dotid+' [shape=box,label="'+self.dotid+'"];\n')
else:
f.write(' '+self.dotid+' [shape=box,label="'+self.name+'"];\n')
f.write('}\n')
f.close()
def html(self):
s='File Type:
\n'+self.id+'
\n'
s=s+self.name+'
\n'
s=s+'
\n'
s=s+self.doc
return s
class subStep:
def __init__(self,id,steptype,name):
self.id=id # This id also acts as a pointer to the step object
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.steptype=steptype
self.name=name
self.doc=''
self.cmd=False
self.rundir=False
self.rank=False
class fileNode:
def __init__(self,id,filetype,filename,name):
self.id=id #This id is valid only in the context of a step
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.filetype=filetype # pointer to the list of filetypes
self.filename=filename
self.name=name
self.doc=''
self.rank=False
class observation:
def __init__(self,id,name):
self.id=id #This id is valid only in the context of a step
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.name=name
self.doc=''
self.rank=False
class step:
def __init__(self,id,steptype,filename,name):
self.id=id
self.dotid=re.sub(r"[^a-zA-Z0-9_]","_",id)
self.steptype=steptype
self.filename=filename
self.name=name
self.doc=''
self.flow=False
self.args=[]
self.techvars=[]
self.substeps=[]
self.filenodes=[]
self.observations=[]
self.edges=[]
def writedotfile(self,filename,fl,debug=False):
f=open(filename,'w')
f.write("digraph G {\n")
f.write(" node [fontsize=10,height=0.1];\n")
f.write(" nodesep = 0.1;\n")
if len(self.substeps+self.filenodes)==0:
if debug:
f.write(' '+self.dotid+ \
' [style=filled,fillcolor=green,label="' \
+self.dotid+'"];\n')
else:
f.write(' '+self.dotid+ \
' [style=filled,fillcolor=green,label="' \
+self.name+'"];\n')
else:
for n in self.substeps:
#if fl.findStep(n.id):
# link=n.id+'.html'
#else:
# link='#'+n.dotid
if n.rank:
f.write(' { rank='+n.rank+';\n')
link='#'+n.dotid
if debug:
f.write(' '+n.dotid+ \
' [style=filled,fillcolor=palegreen,label="' \
+n.dotid+'",URL="'+link+'"];\n')
else:
f.write(' '+n.dotid+ \
' [style=filled,fillcolor=palegreen,label="' \
+n.name+'",URL="'+link+'"];\n')
if n.rank:
f.write(' }\n')
for n in self.filenodes:
if n.rank:
f.write(' { rank='+n.rank+';\n')
link='#'+n.dotid
if debug:
f.write(' '+n.dotid+ \
' [shape=box,label="'+n.dotid+'",URL="'+ \
link+'"];\n')
else:
f.write(' '+n.dotid+ \
' [shape=box,label="'+n.name+'",URL="'+ \
link+'"];\n')
if n.rank:
f.write(' }\n')
for n in self.observations:
if n.rank:
f.write(' { rank='+n.rank+';\n')
link='#'+n.dotid
if debug:
f.write(' '+n.dotid+ \
' [style=filled,fillcolor=lightblue,shape=diamond,label="'+n.dotid+'",URL="'+ \
link+'"];\n')
else:
f.write(' '+n.dotid+ \
' [style=filled,fillcolor=lightblue,shape=diamond,label="'+n.name+'",URL="'+ \
link+'"];\n')
if n.rank:
f.write(' }\n')
for e in self.edges:
f.write(' '+e+';\n')
f.write('}\n')
f.close()
def html(self,f,home):
s='| Step:\n'
s=s+' | '+self.id+' \n'
s=s+self.name+'\n'
steptype=f.findStepType(self.steptype)
if not steptype:
print "WARNING: could not find definition for STEPTYPE", \
self.steptype,"in step",self.id
else:
s=s+' |
| Type: | '+steptype.name+'\n'
s=s+' |
| File: | '+self.filename+'\n'
s=s+' |
\n'
s=s+'
\n'
s=s+'
\n'
s=s+self.doc+'\n
\n'
if len(self.args)>0:
s=s+'Arguments:
\n'
for arg in self.args:
s=s+'| '+arg.name+'\n'
s=s+' | '+arg.doc
s=s+' |
\n'
if len(self.techvars)>0:
s=s+'Technology Variables:
\n'
for var in self.techvars:
s=s+'| '+var.name+'\n'
s=s+' | '+var.doc
s=s+' |
\n'
if len(self.filenodes)>0:
s=s+'Files:
\n'
for n in self.filenodes:
s=s+''
s=s+'\n'
s=s+'| File:\n'
s=s+' | '+n.id+' '
s=s+re.sub(r"\\n",' ',n.name)+''
filetype=f.findFileType(n.filetype)
if not filetype:
print "WARNING: could not find definition for FILETYPE", \
n.filetype,"in FILE",n.id
else:
s=s+' |
| Type: | '+filetype.name+'\n'
s=s+' |
| Name:\n'
s=s+' | '+n.filename+'\n'
s=s+' |
\n
'+n.doc+'
\n'
s=s+'
\n'
if len(self.substeps)>0:
s=s+'Substeps:
\n'
for n in self.substeps:
s=s+''
s=s+'\n'
s=s+'| Substep:\n'
stepobj=f.findStep(n.id)
if stepobj:
link=''
else:
link=''
s=s+' | '+link+''+n.id+' '
s=s+re.sub(r"\\n",' ',n.name)+''
if stepobj:
s=s+''
steptype=f.findStepType(stepobj.steptype)
else:
steptype=f.findStepType(n.steptype)
if not steptype:
print "WARNING: could not find definition for STEPTYPE", \
n.steptype,"in SUBSTEP",n.id
else:
s=s+' |
| Type: | '+steptype.name+'\n'
if n.cmd:
s=s+' |
| Command:\n'
s=s+' | '+n.cmd.name+'\n'
if n.rundir:
s=s+' |
| Run Directory:\n'
s=s+' | '+n.rundir.name+'\n'
s=s+' |
\n
'+n.doc+'
\n'
s=s+'
\n'
return s
class flow:
def __init__(self):
self.id=False
self.top=False
self.name=''
self.doc=''
self.date=False
self.insturl=False
self.instname=False
self.filename=False
self.authors=[]
self.steps=[]
self.steptypes=[]
self.filetypes=[]
self.subflows=[]
def readfile(self,filename):
lineno=0
co=False # Initialize the current object
cs=False # Initialize the current step
css=False # Initialize the current substep
self.filename=filename
f=open(filename,'r')
for line in f:
lineno=lineno+1
m=re.search(r"^\s*#(.*)$",line) # Comment
if m:
if co:
co.doc=co.doc+m.group(1).strip()+'\n'
# Otherwise, it's a comment at the beginning of the
# File, and these are ignored
continue
m=re.search(r"^\s*INCLUDE\s+(.*)$",line)
if m:
newdir=dirlist(filename)
newdir.pop()
newdir=newdir+m.group(1).strip()
newdir.compress()
newflow=flow()
newflow.readfile(str(newdir))
self.subflows.append(newflow)
for n in newflow.steps:
self.steps.append(n)
for n in newflow.steptypes:
self.steptypes.append(n)
for n in newflow.filetypes:
self.filetypes.append(n)
for n in newflow.subflows:
self.subflows.append(n)
continue
m=re.search(r"^\s*FLOW\s+(\S+)\s+(\S+)\s+(.*)$",line)
if m:
if self.id:
print "WARNING: Ignoring FLOW redefinition on line",lineno
continue
self.id=m.group(1)
self.top=m.group(2)
self.name=m.group(3).strip()
co=self
continue
m=re.search(r"^\s*AUTHOR\s+(\S+)\s+(.*)$",line)
if m:
self.authors.append([m.group(1),m.group(2).strip()])
continue
m=re.search(r"^\s*INSTITUTION\s+(\S+)\s+(.*)$",line)
if m:
self.insturl=m.group(1)
self.instname=m.group(2).strip()
continue
m=re.search(r"^\s*DATE\s+(\d+\s+[A-Z][a-z][a-z]\s+\d+)\s*$",line)
if m:
self.date=time.strptime(m.group(1),'%d %b %Y')
#s=s+time.strftime('%d %b %Y',self.date)
continue
m=re.search(r"^\s*STEPTYPE\s+(\S+)\s+(.*)$",line)
if m:
co=stepType(m.group(1),m.group(2).strip())
co.flow=self
for st in self.steptypes:
if st.id==co.id:
print "WARNING: STEPTYPE",m.group(1),"redefined",
print "on line "+str(lineno)+", ignoring"
continue
self.steptypes.append(co)
cs=False # re-Initialize cs & css
css=False
continue
m=re.search(r"^\s*FILETYPE\s+(\S+)\s+(.*)$",line)
if m:
co=fileType(m.group(1),m.group(2).strip())
co.flow=self
for ft in self.filetypes:
if ft.id==co.id:
print "WARNING: FILETYPE",m.group(1),"redefined",
print "on line "+str(lineno)+", ignoring"
continue
self.filetypes.append(co)
cs=False # re-Initialize cs & css
css=False
continue
m=re.search(r"^\s*STEP\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$",line)
if m:
co=step(m.group(1),m.group(2),m.group(3),m.group(4).strip())
co.flow=self
for s in self.steps:
if s.id==co.id:
print "WARNING: STEP",m.group(1),"redefined",
print "on line "+str(lineno)+", ignoring"
continue
self.steps.append(co)
cs=co # re-Initialize cs & css
css=False
continue
m=re.search(r"^\s*ARG\s+(.*)$",line)
if m:
if not cs:
print "WARNING: ARG",m.group(1),"found outside a STEP",
print " on line",lineno
continue
co=dobj(m.group(1).strip())
cs.args.append(co)
css=False
continue
m=re.search(r"^\s*TECHVAR\s+(.*)$",line)
if m:
if not cs:
print "WARNING: TECHVAR",m.group(1),"found outside a STEP",
print " on line",lineno
continue
co=dobj(m.group(1).strip())
cs.techvars.append(co)
css=False
continue
m=re.search(r"^\s*SUBSTEP\s+(\S+)\s+(\S+)\s+(.*)$",line)
if m:
if not cs:
print "WARNING: SUBSTEP",m.group(1),"found outside a STEP",
print " on line",lineno
continue
co=subStep(m.group(1),m.group(2),m.group(3).strip())
for n in cs.substeps+cs.filenodes+cs.observations:
if n.dotid==co.dotid:
print "WARNING: SUBSTEP",m.group(1), \
"aliases previously defined",n.id, \
"on line "+str(lineno)
print "Both will be called",n.dotid, \
"in dot file"
break
cs.substeps.append(co)
css=co
continue
m=re.search(r"^\s*CMD\s+(.*)$",line)
if m:
if not css:
print "WARNING: CMD",m.group(1),"found outside a SUBSTEP",
print " on line",lineno
continue
co=dobj(m.group(1).strip())
css.cmd=co
continue
m=re.search(r"^\s*RUNDIR\s+(.*)$",line)
if m:
if not css:
print "WARNING: RUNDIR",m.group(1),"found outside a SUBSTEP",
print " on line",lineno
continue
co=dobj(m.group(1).strip())
css.rundir=co
continue
m=re.search(r"^\s*FILE\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$",line)
if m:
if not cs:
print "WARNING: FILE",m.group(1),"found outside a STEP",
print " on line",lineno
continue
co=fileNode(m.group(1),m.group(2),m.group(3),m.group(4).strip())
for n in cs.substeps+cs.filenodes+cs.observations:
if n.dotid==co.dotid:
print "WARNING: FILE",m.group(1), \
"aliases previously defined",n.id, \
"on line "+str(lineno)
print "Both will be called",n.dotid, \
"in dot file"
break
cs.filenodes.append(co)
css=False
continue
m=re.search(r"^\s*OBSV\s+(\S+)\s+(.*)$",line)
if m:
if not cs:
print "WARNING: OBSV",m.group(1),"found outside a STEP",
print " on line",lineno
continue
co=observation(m.group(1),m.group(2).strip())
for n in cs.substeps+cs.filenodes+cs.observations:
if n.dotid==co.dotid:
print "WARNING: OBSV",m.group(1), \
"aliases previously defined",n.id, \
"on line "+str(lineno)
print "Both will be called",n.dotid, \
"in dot file"
break
cs.observations.append(co)
css=False
continue
m=re.search(r"^\s*RANK\s+(\S+)",line)
if m:
if co:
co.rank=m.group(1)
continue
m=re.search(r"\-\>",line)
if m:
if not cs:
print "WARNING: edge",line.strip(),"found outside a STEP",
print " on line",lineno
continue
cs.edges.append(line.strip())
continue
m=re.search(r"^\s*$",line)
if m:
continue # Ignore blank lines
print "WARNING: line",lineno,"not recognized:",line
f.close()
def findStep(self,id):
for s in self.steps:
if s.id==id:
return s
break
return False
def findStepType(self,id):
for s in self.steptypes:
if s.id==id:
return s
break
return False
def findFileType(self,id):
for s in self.filetypes:
if s.id==id:
return s
break
return False
def publish(self):
home=dirlist(self.id)
home.verify()
subdir=home+'images'
subdir.verify()
os.system('cp '+imagedir+'/flowdb_small.gif '+str(subdir)+ \
'/flowdb_small.gif')
subdir=home+'steptypes'
subdir.verify()
n=[['Top','','index.html'], \
['Steps','steps','index.html'], \
['Step Types','steptypes','index.html'], \
['File Types','filetypes','index.html'], \
['Flow Index','http://www.ece.ncsu.edu/muse/flowdb']]
h=htmlleftnav(self.name,n)
# Write index.html
s='\n'+self.id+'
\n'
s=s+'\n'+self.name+'
\n'
s=s+''
if self.date:
s=s+'| Date: | '+time.strftime('%d %B %Y',self.date)+'\n'
if len(self.authors)>0:
s=s+' |
| Authors: | \n'
for n in self.authors:
s=s+''+n[1]+' \n'
if self.instname:
s=s+' |
| Institution: | \n'
s=s+''+self.instname+''
s=s+' |
\n'
s=s+''+self.doc+'\n'
s=s+'
\n'
h.write(str(home)+'/index.html',s)
# Write steptypes/index.html
subdir=home+'steptypes'
subdir.verify()
s='Step Types
\n\n'
self.steptypes.sort(key=lambda x: x.name)
for n in self.steptypes:
s=s+''+n.name+'
\n'
h.chdir('steptypes')
h.write(str(subdir)+'/index.html',s)
for n in self.steptypes:
gif=str(subdir)+'/'+n.id+'.gif'
dot=str(subdir)+'/'+n.id+'.dot'
cmap=str(subdir)+'/'+n.id+'.cmap'
html=str(subdir)+'/'+n.id+'.html'
if n.flow and out_of_date(n.flow.filename,html):
n.writedotfile(dot)
os.system('dot -Tgif '+dot+' -o '+gif)
os.system('dot -Tcmap '+dot+' -o '+cmap)
h.write(html,n.html())
h.popdir()
# Write filetypes/index..html
subdir=home+'filetypes'
subdir.verify()
s='File Types
\n\n'
self.filetypes.sort(key=lambda x: x.name)
for n in self.filetypes:
s=s+''+n.name+'
\n'
h.chdir('filetypes')
h.write(str(subdir)+'/index.html',s)
for n in self.filetypes:
gif=str(subdir)+'/'+n.id+'.gif'
dot=str(subdir)+'/'+n.id+'.dot'
cmap=str(subdir)+'/'+n.id+'.cmap'
html=str(subdir)+'/'+n.id+'.html'
if n.flow and out_of_date(n.flow.filename,html):
n.writedotfile(dot)
os.system('dot -Tgif '+dot+' -o '+gif)
os.system('dot -Tcmap '+dot+' -o '+cmap)
h.write(html,n.html())
h.popdir()
# Write steps/index..html
subdir=home+'steps'
subdir.verify()
s='Steps
\n\n'
self.steps.sort(key=lambda x: x.name)
for n in self.steps:
s=s+''+n.name+'
\n'
h.chdir('steps')
h.write(str(subdir)+'/index.html',s)
for n in self.steps:
gif=str(subdir)+'/'+n.id+'.gif'
dot=str(subdir)+'/'+n.id+'.dot'
cmap=str(subdir)+'/'+n.id+'.cmap'
html=str(subdir)+'/'+n.id+'.html'
if n.flow and out_of_date(n.flow.filename,html):
n.writedotfile(dot,self)
os.system('dot -Tgif '+dot+' -o '+gif)
os.system('dot -Tcmap '+dot+' -o '+cmap)
h.write(html,n.html(self,home))
h.popdir()
topfile=''
force=0
# Parse arguments
args=sys.argv[1:]
while (len(args)>0):
arg=args[0]
args=args[1:]
if (arg=="-force"):
force=1
elif not topfile:
topfile=arg
else:
print "Unrecognized argument "+arg
f=flow()
f.readfile(topfile)
f.publish()