25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

setup_docs.py 6.2 KiB

10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. """Automatically setup docs for a project
  2. Call from command line:
  3. bench setup-docs app path
  4. """
  5. import os, json, frappe, markdown2, shutil
  6. import frappe.website.statics
  7. from frappe.website.context import get_context
  8. class setup_docs(object):
  9. def __init__(self, app, docs_version, target):
  10. """Generate source templates for models reference and module API
  11. and templates at `templates/autodoc`
  12. """
  13. self.app = app
  14. self.path = frappe.get_app_path(app, "docs", docs_version)
  15. self.target = target
  16. # build apis
  17. # self.build()
  18. # sync docs
  19. sync = frappe.website.statics.sync()
  20. sync.start(path="docs", rebuild=True)
  21. # write in target path
  22. self.write_files()
  23. def build(self):
  24. hooks = frappe.get_hooks(app_name = self.app)
  25. self.app_title = hooks.get("app_title")[0]
  26. self.app_path = frappe.get_app_path(self.app)
  27. print "Deleting current..."
  28. shutil.rmtree(self.path, ignore_errors = True)
  29. os.makedirs(self.path)
  30. self.app_context = {
  31. "app": {
  32. "name": self.app,
  33. "title": self.app_title,
  34. "description": markdown2.markdown(hooks.get("app_description")[0]),
  35. "version": hooks.get("app_version")[0],
  36. "publisher": hooks.get("app_publisher")[0],
  37. "github_link": hooks.get("github_link")[0],
  38. }
  39. }
  40. # make home page
  41. with open(os.path.join(self.path, "index.html"), "w") as home:
  42. home.write(frappe.render_template("templates/autodoc/docs_home.html",
  43. self.app_context))
  44. # make folders
  45. self.models_base_path = os.path.join(self.path, "models")
  46. self.make_folder(self.models_base_path,
  47. template = "templates/autodoc/models_home.html")
  48. self.api_base_path = os.path.join(self.path, "api")
  49. self.make_folder(self.api_base_path,
  50. template = "templates/autodoc/api_home.html")
  51. for basepath, folders, files in os.walk(self.app_path):
  52. if "doctype" not in basepath:
  53. if "doctype" in folders:
  54. module = os.path.basename(basepath)
  55. module_folder = os.path.join(self.models_base_path, module)
  56. self.make_folder(module_folder,
  57. template = "templates/autodoc/module_home.html",
  58. context = {"name": module})
  59. self.update_index_txt(module_folder)
  60. if "doctype" in basepath:
  61. parts = basepath.split("/")
  62. #print parts
  63. module, doctype = parts[-3], parts[-1]
  64. if doctype not in ("doctype", "boilerplate"):
  65. self.write_model_file(basepath, module, doctype)
  66. elif self.is_py_module(basepath, folders, files):
  67. self.write_modules(basepath, folders, files)
  68. def is_py_module(self, basepath, folders, files):
  69. return "__init__.py" in files \
  70. and (not "/doctype" in basepath) \
  71. and (not "/patches" in basepath) \
  72. and (not "/change_log" in basepath) \
  73. and (not "/report" in basepath) \
  74. and (not "/page" in basepath) \
  75. and (not "/templates" in basepath) \
  76. and (not "/tests" in basepath) \
  77. and (not "doctype" in folders)
  78. def write_modules(self, basepath, folders, files):
  79. module_folder = os.path.join(self.api_base_path, os.path.relpath(basepath, self.app_path))
  80. self.make_folder(module_folder)
  81. for f in files:
  82. if f.endswith(".py"):
  83. module_name = os.path.relpath(os.path.join(basepath, f),
  84. self.app_path)[:-3].replace("/", ".").replace(".__init__", "")
  85. module_doc_path = os.path.join(module_folder,
  86. self.app + "." + module_name + ".html")
  87. self.make_folder(basepath)
  88. if not os.path.exists(module_doc_path):
  89. print "Writing " + module_doc_path
  90. with open(module_doc_path, "w") as f:
  91. context = {"name": self.app + "." + module_name}
  92. context.update(self.app_context)
  93. f.write(frappe.render_template("templates/autodoc/pymodule.html",
  94. context))
  95. self.update_index_txt(module_folder)
  96. def make_folder(self, path, template=None, context=None):
  97. if not template:
  98. template = "templates/autodoc/package_index.html"
  99. if not os.path.exists(path):
  100. os.makedirs(path)
  101. index_txt_path = os.path.join(path, "index.txt")
  102. print "Writing " + index_txt_path
  103. with open(index_txt_path, "w") as f:
  104. f.write("")
  105. index_html_path = os.path.join(path, "index.html")
  106. if not context:
  107. name = os.path.basename(path)
  108. if name==".":
  109. name = self.app
  110. context = {
  111. "title": name
  112. }
  113. context.update(self.app_context)
  114. print "Writing " + index_html_path
  115. with open(index_html_path, "w") as f:
  116. f.write(frappe.render_template(template, context))
  117. def update_index_txt(self, path):
  118. index_txt_path = os.path.join(path, "index.txt")
  119. pages = filter(lambda d: (d.endswith(".html") and d!="index.html") \
  120. or os.path.isdir(os.path.join(path, d)), os.listdir(path))
  121. pages = [d.rsplit(".", 1)[0] for d in pages]
  122. with open(index_txt_path, "r") as f:
  123. index_parts = filter(None, f.read().splitlines())
  124. if not set(pages).issubset(set(index_parts)):
  125. print "Updating " + index_txt_path
  126. with open(index_txt_path, "w") as f:
  127. f.write("\n".join(pages))
  128. def write_model_file(self, basepath, module, doctype):
  129. model_path = os.path.join(self.models_base_path, module, doctype + ".html")
  130. if not os.path.exists(model_path):
  131. model_json_path = os.path.join(basepath, doctype + ".json")
  132. if os.path.exists(model_json_path):
  133. with open(model_json_path, "r") as j:
  134. doctype_real_name = json.loads(j.read()).get("name")
  135. print "Writing " + model_path
  136. with open(model_path, "w") as f:
  137. context = {"doctype": doctype_real_name}
  138. context.update(self.app_context)
  139. f.write(frappe.render_template("templates/autodoc/doctype.html",
  140. context).encode("utf-8"))
  141. def write_files(self):
  142. frappe.local.flags.home_page = "index"
  143. for page in frappe.db.sql("""select parent_website_route,
  144. page_name from `tabWeb Page`""", as_dict=True):
  145. if page.parent_website_route:
  146. path = page.parent_website_route + "/" + page.page_name
  147. else:
  148. path = page.page_name
  149. frappe.local.path = path
  150. context = get_context(path)
  151. html = frappe.get_template(context.base_template_path).render(context)
  152. target_filename = os.path.join(self.target, context.template_path.split('/docs/')[1])
  153. if not os.path.exists(os.path.dirname(target_filename)):
  154. os.makedirs(os.path.dirname(target_filename))
  155. with open(target_filename, "w") as htmlfile:
  156. htmlfile.write(html.encode("utf-8"))
  157. print "wrote {0}".format(target_filename)