createdoc.py
branchdevel
changeset 271 b218238e76b9
parent 251 3caa803a2dec
child 277 f65edc0382cc
equal deleted inserted replaced
270:665c3ea02d35 271:b218238e76b9
     1 #!/usr/bin/env python2.7
     1 #!/usr/bin/env python2.7
     2 # -*- coding: utf-8 -*- 
     2 # -*- coding: utf-8 -*- 
     3 
     3 
     4 from genshi.template import TemplateLoader
     4 from genshi.template import TemplateLoader
     5 
     5 from genshi import Markup
     6 loader = TemplateLoader('doc/tmpl', auto_reload=True)
     6 loader = TemplateLoader('doc/tmpl', auto_reload=True)
     7 
     7 
     8 import re
       
     9 import inspect
     8 import inspect
    10 from iro.view.xmlrpc_old import User as Current
     9 from docutils.core import publish_doctree
    11 from iro.controller.viewinterface import Interface as New
    10 import docutils
       
    11 
       
    12 #--
       
    13 from docutils import core
       
    14 from docutils.writers.html4css1 import Writer,HTMLTranslator
       
    15 
       
    16 class NoHeaderHTMLTranslator(HTMLTranslator):
       
    17     def __init__(self, document):
       
    18         HTMLTranslator.__init__(self,document)
       
    19         self.body_prefix = []
       
    20         self.body_suffix = []
       
    21 
       
    22 _w = Writer()
       
    23 _w.translator_class = NoHeaderHTMLTranslator
       
    24 _w.visitor_attributes = ("html_body",)
       
    25 
       
    26 def d():
       
    27     subs = _w.interpolation_dict()
       
    28     return "%(html_body)s"%subs
       
    29 
       
    30 _w.apply_template = d
       
    31 
       
    32 def reSTify(s):
       
    33     d =docutils.utils.new_document("")
       
    34     if s.tagname == "paragraph":
       
    35         d.append(s[0])
       
    36     else:
       
    37         d.append(s)
       
    38 
       
    39     return core.publish_from_doctree(d, writer=_w)
       
    40 
       
    41 from iro.view.xmlrpc import TwistedInterface as Current 
    12 
    42 
    13 from createerm import createSchemaPlot, tables, tables_cls
    43 from createerm import createSchemaPlot, tables, tables_cls
    14 
    44 
    15 class Link():
    45 class Link():
    16     def __init__(self,name,title):
    46     def __init__(self,name,title):
    27 
    57 
    28 class Site(Link):
    58 class Site(Link):
    29     pass
    59     pass
    30 
    60 
    31 class Keyword():
    61 class Keyword():
    32     def __init__(self,name,typ,description):
    62     def __init__(self, name=None, typ=None, description=None):
    33         self.name=name
    63         self.name=name
    34         self.typ=typ
    64         self.typ=typ
    35         self.description=description
    65         self.description=description
    36 
    66 
    37 def section(text):
    67     def __repr__(self):
    38     ret={}
    68         return '<Keyword("%s", "%s", "%s")>'%(self.name, self.typ, self.description)
    39     li=[]
       
    40     kw=None
       
    41     for line in text.split("\n"):
       
    42         if re.match("^\s*$",line):
       
    43             continue
       
    44 
       
    45         if line[0] not in (" ","\t"):
       
    46             if kw:
       
    47                 ret[kw.name]=kw
       
    48                 li.append(kw)
       
    49             l=re.match(r"^(?P<name>[a-zA-Z0-9-_.]*)\[(?P<typ>[a-zA-Z0-9-_|]*)\]:(?P<d>.*)$",line)
       
    50             kw=Keyword(name=l.group("name"),typ=l.group("typ"),description=l.group("d"))
       
    51         else:
       
    52             kw.description+="\n"+line.strip()
       
    53     if kw:
       
    54         ret[kw.name]=kw
       
    55         li.append(kw)
       
    56     return ret,li
       
    57 
       
    58 
       
    59 
    69 
    60 def keywords(f):
    70 def keywords(f):
    61     doc=f.__doc__.decode('utf8')
    71     NORMAL = 0
    62     kwds=re.search("Keywords:\n(?P<keywords>(?P<whitespace>\s*)(.+\n)*)\n",doc)
    72     TYPE = 1
    63     k=kwds.group("keywords")
    73     pd = publish_doctree(f.__doc__.decode('utf8'))
    64     #get rid of beginning whitespaces
    74 
    65     k=re.sub(re.compile(r"^"+kwds.group("whitespace"),re.M),"",k)
    75     kws={}
    66     return section(k)
    76     for child in pd[1][0]:
       
    77         kw = Keyword()
       
    78         ftyp = NORMAL
       
    79         for sc in child:
       
    80             if sc.tagname == "field_name":
       
    81                 p = sc.astext().split()
       
    82                 if p[0] in ["param",]:
       
    83                     if len(p) == 3:             #param typ name
       
    84                         kw.name = p[2]
       
    85                         kw.typ = p[1]
       
    86                     if len(p) == 2:
       
    87                         kw.name = p[1]
       
    88                 elif p[0] == "type":
       
    89                     kw = kws[p[1]]
       
    90                     ftyp=TYPE
       
    91                 elif p[0] in ["return","rtyp"]:
       
    92                     break
       
    93                 else:
       
    94                     raise Exception("Unknown field_name: %s"%(p[0]))
       
    95             if sc.tagname == "field_body":
       
    96                 if ftyp == NORMAL:
       
    97                     kw.description = Markup(reSTify(sc[0]))
       
    98                 if ftyp == TYPE:
       
    99                     kw.typ = sc[0][0]
       
   100         else:
       
   101             kws[kw.name] = kw
       
   102     return kws
    67 
   103 
    68 def ret(f):
   104 def ret(f):
    69     doc=f.__doc__.decode('utf8')
   105     NORMAL = 0
    70     kwds=re.search("Return:\n(?P<ret>(?P<whitespace>\s*)(.+\n)*)\n",doc)
   106     TYPE = 1
    71     k=kwds.group("ret")
   107     
    72     #get rid of beginning whitespaces
   108     pd = publish_doctree(f.__doc__.decode('utf8'))
    73     k=re.sub(re.compile(r"^"+kwds.group("whitespace"),re.M),"",k)
   109     for child in pd[1][0]:
    74     return section(k)
   110         kw = Keyword(name="return")
    75 
   111         ftyp = NORMAL
    76 
   112         for sc in child:
    77 
   113             if sc.tagname == "field_name":
       
   114                 p = sc.astext().split()
       
   115                 if p[0] == "return":
       
   116                     if len(p) == 2:
       
   117                         kw.typ = p[1]
       
   118                 elif p[0] == "rtype":
       
   119                     ftyp=TYPE
       
   120                 elif p[0] in ["param","type"]:
       
   121                     break
       
   122                 else:
       
   123                     raise Exception("Unknown field_name: %s"%(p[0]))
       
   124             if sc.tagname == "field_body":
       
   125                 if ftyp == NORMAL:
       
   126                     kw.description = Markup(reSTify(sc[0]))
       
   127                 if ftyp == TYPE:
       
   128                     kw.typ = sc[0][0]
       
   129         else:
       
   130             return kw
       
   131     
       
   132     raise Exception("no return description")
       
   133  
    78 class Arg():
   134 class Arg():
    79     def __init__(self,name,f):
   135     def __init__(self,name,f):
    80         self.name=name
   136         self.name=name
    81         k,_ = keywords(f)
   137         k = keywords(f)
    82         kwd=k[name]
   138         kwd=k[name]
    83         self.typ=kwd.typ
   139         self.typ=kwd.typ
    84         self.description=kwd.description
   140         self.description=kwd.description
    85 
       
    86         
       
    87 
   141 
    88 class Method(Link):
   142 class Method(Link):
    89     def __init__(self,name,methods):
   143     def __init__(self,name,methods):
    90         title=name[0].upper()+name[1:]
   144         title=name[0].upper()+name[1:]
    91         Link.__init__(self,name,title)
   145         Link.__init__(self,name,title)
    93         (args, varargs, keywords, defaults)=inspect.getargspec(m)
   147         (args, varargs, keywords, defaults)=inspect.getargspec(m)
    94         a=[]
   148         a=[]
    95         for b in args:
   149         for b in args:
    96             if b in ("self","session"):
   150             if b in ("self","session"):
    97                 continue
   151                 continue
    98             if b == "user":
       
    99                 a.append("apikey")
       
   100             else:
   152             else:
   101                 a.append(b)
   153                 a.append(b)
   102         
   154         
   103         args = a
   155         args = a
   104         self.func_line=inspect.formatargspec(args, varargs, keywords, defaults)
   156         self.func_line=inspect.formatargspec(args, varargs, keywords, defaults)
   105         self.description = m.__doc__.split("\n")[0].decode("utf8")
   157         pd = publish_doctree(m.__doc__)
       
   158         if pd[0].tagname == "paragraph":
       
   159             self.description = pd[0].astext()
   106         self.args=[Arg(a,m) for a in args]
   160         self.args=[Arg(a,m) for a in args]
   107         _, self.rets=ret(m)
   161         self.rets=[ret(m)]
   108 
   162 
   109 class Table(Link):
   163 class Table(Link):
   110     def __init__(self,cls):
   164     def __init__(self,cls):
   111         name=cls.__name__
   165         name=cls.__name__
   112         self.tablename=cls.__tablename__
   166         self.tablename=cls.__tablename__
   113         title=self.tablename[0].upper()+self.tablename[1:]
   167         title=self.tablename[0].upper()+self.tablename[1:]
   114         Link.__init__(self,name,title)
   168         Link.__init__(self,name,title)
   115         self.description = cls.__doc__.split("\n")[0].decode("utf8") 
   169         
       
   170         self.description = Markup(core.publish_string(cls.__doc__,writer=_w))
   116 
   171 
   117 
   172 
   118 def main():
   173 def main():
   119     sites=[Site("index.html","Iro"),
   174     sites=[Site("index.html","Iro"),
   120            Site("current.html","API Documentation"),
   175            Site("current.html","API Documentation"),
   121            Site("new.html","geplante API Documentation"),
   176            Site("database.html","Datenbase Schema"),
   122            Site("database.html","Datenbank Schema"),
   177            Site("about.html","About us"),
   123            Site("impressum.html","Impressum"),
       
   124            ]
   178            ]
   125 
   179 
   126     current_methods = dict(inspect.getmembers(Current(None,None)))
   180     current_methods = dict(inspect.getmembers(Current()))
   127     current=[
   181     current=[ Method(i,current_methods) for i in Current().listMethods() if i  != "listMethods" ]
   128             Method("startSMS",current_methods),
       
   129             Method("startFAX",current_methods),
       
   130             Method("startMail",current_methods),
       
   131             
       
   132             Method("status",current_methods),
       
   133             Method("stop",current_methods),
       
   134             
       
   135             Method("getProvider",current_methods),
       
   136             Method("getDefaultProvider",current_methods),
       
   137             ]
       
   138 
       
   139     new_methods = dict(inspect.getmembers(New()))
       
   140     newm=[
       
   141             Method("sms",new_methods),
       
   142             Method("fax",new_methods),
       
   143             Method("mail",new_methods),
       
   144             
       
   145             Method("status",new_methods),
       
   146             Method("stop",new_methods),
       
   147             
       
   148             Method("routes",new_methods),
       
   149             Method("defaultRoute",new_methods),
       
   150             ]
       
   151     
   182     
   152     t = [Table(tables_cls[str(f)]) for f in tables]
   183     t = [Table(tables_cls[str(f)]) for f in tables]
   153     createSchemaPlot('doc/images/db-schema.svg')
   184     createSchemaPlot('doc/images/db-schema.svg')
   154 
   185 
   155     for site in sites:
   186     for site in sites:
   156         print("generiere %s" % site.name)
   187         print("generiere %s" % site.name)
   157         tmpl = loader.load(site.name)
   188         tmpl = loader.load(site.name)
   158         def a(s):
   189         def a(s):
   159             if s == site:
   190             if s == site:
   160                 return {"class":"menu active"}
   191                 return {"class":"menu active"}
   161         stream = tmpl.generate(sites=sites,active=a,current=current,new=newm,tables=t)
   192         stream = tmpl.generate(sites=sites, active=a, current=current, tables=t)
   162         with open('doc/'+site.name, "w") as g:
   193         with open('doc/'+site.name, "w") as g:
   163             g.write(stream.render('html', doctype='html'))
   194             g.write(stream.render('html', doctype='html'))
   164 
   195 
   165 if __name__ == '__main__':
   196 if __name__ == '__main__':
   166     main()
   197     main()