--- a/createdoc.py Wed Dec 21 22:07:48 2011 +0100
+++ b/createdoc.py Thu Sep 27 17:15:46 2012 +0200
@@ -1,14 +1,73 @@
#!/usr/bin/env python2.7
+
+# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
+#
+# This file is part of Iro.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+# #Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
# -*- coding: utf-8 -*-
from genshi.template import TemplateLoader
-
+from genshi import Markup
loader = TemplateLoader('doc/tmpl', auto_reload=True)
+
+from glob import glob
import re
+import os.path
import inspect
-from iro.user import User as Current
-from iro.newuser import User as New
+from pkg_resources import parse_version
+
+from docutils.core import publish_doctree, publish_from_doctree, publish_string
+from docutils.utils import new_document
+from docutils.writers.html4css1 import Writer,HTMLTranslator
+
+from iro.view.xmlrpc import TwistedInterface as Current
+from iro import __version__
+from createerm import createSchemaPlot, tables, tables_cls
+
+#redering text with rest syntax
+class NoHeaderHTMLTranslator(HTMLTranslator):
+ def __init__(self, document):
+ HTMLTranslator.__init__(self,document)
+ self.body_prefix = []
+ self.body_suffix = []
+
+_w = Writer()
+_w.translator_class = NoHeaderHTMLTranslator
+_w.visitor_attributes = ("html_body",)
+
+def d():
+ subs = _w.interpolation_dict()
+ return "%(html_body)s"%subs
+
+_w.apply_template = d
+
+def reSTify(s):
+ d = new_document("")
+ if s.tagname == "paragraph":
+ d.append(s[0])
+ else:
+ d.append(s)
+
+ return publish_from_doctree(d, writer=_w)
+
@@ -30,108 +89,145 @@
class Keyword():
- def __init__(self,name,typ,description):
+ def __init__(self, name=None, typ=None, description=None):
self.name=name
self.typ=typ
self.description=description
-def section(text):
- ret={}
- li=[]
- kw=None
- for line in text.split("\n"):
- if re.match("^\s*$",line):
- continue
-
- if line[0] not in (" ","\t"):
- if kw:
- ret[kw.name]=kw
- li.append(kw)
- l=re.match(r"^(?P<name>[a-zA-Z0-9-_.]*)\[(?P<typ>[a-zA-Z0-9-_|]*)\]:(?P<d>.*)$",line)
- kw=Keyword(name=l.group("name"),typ=l.group("typ"),description=l.group("d"))
- else:
- kw.description+="\n"+line.strip()
- if kw:
- ret[kw.name]=kw
- li.append(kw)
- return ret,li
-
-
+ def __repr__(self):
+ return '<Keyword("%s", "%s", "%s")>'%(self.name, self.typ, self.description)
def keywords(f):
- doc=f.__doc__
- kwds=re.search("Keywords:\n(?P<keywords>(?P<whitespace>\s*)(.+\n)*)\n",doc)
- k=kwds.group("keywords")
- #get rid of beginning whitespaces
- k=re.sub(re.compile(r"^"+kwds.group("whitespace"),re.M),"",k)
- return section(k)
+ NORMAL = 0
+ TYPE = 1
+ pd = publish_doctree(f.__doc__.decode('utf8'))
+
+ kws={}
+ for child in pd[1][0]:
+ kw = Keyword()
+ ftyp = NORMAL
+ for sc in child:
+ if sc.tagname == "field_name":
+ p = sc.astext().split()
+ if p[0] in ["param",]:
+ if len(p) == 3: #param typ name
+ kw.name = p[2]
+ kw.typ = p[1]
+ if len(p) == 2:
+ kw.name = p[1]
+ elif p[0] == "type":
+ kw = kws[p[1]]
+ ftyp=TYPE
+ elif p[0] in ["return","rtyp"]:
+ break
+ else:
+ raise Exception("Unknown field_name: %s"%(p[0]))
+ if sc.tagname == "field_body":
+ if ftyp == NORMAL:
+ kw.description = Markup(reSTify(sc[0]))
+ if ftyp == TYPE:
+ kw.typ = sc[0][0]
+ else:
+ kws[kw.name] = kw
+ return kws
def ret(f):
- doc=f.__doc__
- kwds=re.search("Return:\n(?P<ret>(?P<whitespace>\s*)(.+\n)*)\n",doc)
- k=kwds.group("ret")
- #get rid of beginning whitespaces
- k=re.sub(re.compile(r"^"+kwds.group("whitespace"),re.M),"",k)
- return section(k)
-
-
-
+ NORMAL = 0
+ TYPE = 1
+
+ pd = publish_doctree(f.__doc__.decode('utf8'))
+ for child in pd[1][0]:
+ kw = Keyword(name="return")
+ ftyp = NORMAL
+ for sc in child:
+ if sc.tagname == "field_name":
+ p = sc.astext().split()
+ if p[0] == "return":
+ if len(p) == 2:
+ kw.typ = p[1]
+ elif p[0] == "rtype":
+ ftyp=TYPE
+ elif p[0] in ["param","type"]:
+ break
+ else:
+ raise Exception("Unknown field_name: %s"%(p[0]))
+ if sc.tagname == "field_body":
+ if ftyp == NORMAL:
+ kw.description = Markup(reSTify(sc[0]))
+ if ftyp == TYPE:
+ kw.typ = sc[0][0]
+ else:
+ return kw
+
+ raise Exception("no return description")
+
class Arg():
def __init__(self,name,f):
self.name=name
- k,_ = keywords(f)
+ k = keywords(f)
kwd=k[name]
self.typ=kwd.typ
self.description=kwd.description
-
-
class Method(Link):
def __init__(self,name,methods):
title=name[0].upper()+name[1:]
Link.__init__(self,name,title)
m=methods[name]
(args, varargs, keywords, defaults)=inspect.getargspec(m)
- args= [b for b in args if b is not "self"]
+ a=[]
+ for b in args:
+ if b in ("self","session"):
+ continue
+ else:
+ a.append(b)
+
+ args = a
self.func_line=inspect.formatargspec(args, varargs, keywords, defaults)
- self.description = m.__doc__.split("\n")[0]
+ pd = publish_doctree(m.__doc__)
+ if pd[0].tagname == "paragraph":
+ self.description = pd[0].astext()
self.args=[Arg(a,m) for a in args]
- _, self.rets=ret(m)
+ self.rets=[ret(m)]
+
+class Table(Link):
+ def __init__(self,cls):
+ name=cls.__name__
+ self.tablename=cls.__tablename__
+ title=self.tablename[0].upper()+self.tablename[1:]
+ Link.__init__(self,name,title)
+
+ self.description = Markup(publish_string(cls.__doc__,writer=_w))
+
+class File:
+ def __init__(self,path):
+ self.version = re.search("/iro-(.*).tar.gz",path).group(1)
+ self.name = os.path.basename(path)
def main():
sites=[Site("index.html","Iro"),
Site("current.html","API Documentation"),
- Site("new.html","geplante API Documentation"),
- Site("impressum.html","Impressum"),
+ Site("database.html","Datenbase Schema"),
+ Site("about.html","About us"),
]
- current_methods = dict(inspect.getmembers(Current(None,None)))
- current=[
- Method("startSMS",current_methods),
- Method("startFAX",current_methods),
- Method("startMail",current_methods),
-
- Method("status",current_methods),
- Method("stop",current_methods),
-
- Method("getProvider",current_methods),
- Method("getDefaultProvider",current_methods),
- ]
+ files=[File(f) for f in glob("web/files/*tar.gz")]
+ files.sort(key=lambda a:parse_version(a.version),reverse=True)
+ code ="files/iro-%s.tar.gz"%__version__
- new_methods = dict(inspect.getmembers(New()))
- newm=[
- Method("sms",new_methods),
- Method("fax",new_methods),
- Method("mail",new_methods),
-
- Method("status",new_methods),
- Method("stop",new_methods),
-
- Method("routes",new_methods),
- Method("defaultRoute",new_methods),
- ]
+ current_methods = dict(inspect.getmembers(Current()))
+ current=[ Method(i,current_methods) for i in Current().listMethods() if i != "listMethods" ]
+
+ t = [Table(tables_cls[str(f)]) for f in tables]
+ createSchemaPlot('web/images/db-schema.svg')
+ gd = {"sites":sites,
+ "current":current,
+ "tables": t,
+ "code":code,
+ "files":files
+ }
for site in sites:
print("generiere %s" % site.name)
@@ -139,8 +235,8 @@
def a(s):
if s == site:
return {"class":"menu active"}
- stream = tmpl.generate(sites=sites,active=a,current=current,new=newm)
- with open('doc/'+site.name, "w") as g:
+ stream = tmpl.generate(active=a, **gd)
+ with open('web/'+site.name, "w") as g:
g.write(stream.render('html', doctype='html'))
if __name__ == '__main__':