You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import conf
  5. import webnotes
  6. from webnotes import _
  7. import webnotes.utils
  8. class PageNotFoundError(Exception): pass
  9. def render(page_name):
  10. """render html page"""
  11. try:
  12. html = render_page(page_name or "index")
  13. except PageNotFoundError:
  14. html = render_page("404")
  15. except Exception:
  16. html = render_page('error')
  17. from webnotes.handler import eprint, print_zip
  18. eprint("Content-Type: text/html; charset: utf-8")
  19. print_zip(html)
  20. def render_page(page_name):
  21. """get page html"""
  22. page_name = scrub_page_name(page_name)
  23. html = ''
  24. if page_name=="index":
  25. page_name = get_home_page()
  26. if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
  27. html = webnotes.cache().get_value("page:" + page_name)
  28. from_cache = True
  29. if not html:
  30. from webnotes.auth import HTTPRequest
  31. webnotes.http_request = HTTPRequest()
  32. html = build_page(page_name)
  33. from_cache = False
  34. if not html:
  35. raise PageNotFoundError
  36. if page_name=="error":
  37. html = html.replace("%(error)s", webnotes.getTraceback())
  38. else:
  39. comments = "\n\npage:"+page_name+\
  40. "\nload status: " + (from_cache and "cache" or "fresh")
  41. html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
  42. return html
  43. def build_page(page_name):
  44. from jinja2 import Environment, FileSystemLoader
  45. if not webnotes.conn:
  46. webnotes.connect()
  47. sitemap = webnotes.cache().get_value("website_sitemap", build_sitemap)
  48. page_options = sitemap.get(page_name)
  49. if not page_options:
  50. raise PageNotFoundError
  51. basepath = webnotes.utils.get_base_path()
  52. module = None
  53. no_cache = False
  54. if page_options.get("controller"):
  55. module = webnotes.get_module(page_options["controller"])
  56. no_cache = getattr(module, "no_cache", False)
  57. # if generator, then load bean, pass arguments
  58. if page_options.get("is_generator"):
  59. if not module:
  60. raise Exception("Generator controller not defined")
  61. name = webnotes.conn.get_value(module.doctype, {"page_name": page_name})
  62. obj = webnotes.get_obj(module.doctype, name, with_children=True)
  63. if hasattr(obj, 'get_context'):
  64. obj.get_context()
  65. context = webnotes._dict(obj.doc.fields)
  66. context["obj"] = obj
  67. else:
  68. # page
  69. context = webnotes._dict({ 'name': page_name })
  70. if module and hasattr(module, "get_context"):
  71. context.update(module.get_context())
  72. context.update(get_website_settings())
  73. jenv = Environment(loader = FileSystemLoader(basepath))
  74. context["base_template"] = jenv.get_template(webnotes.get_config().get("base_template"))
  75. template_name = page_options['template']
  76. html = jenv.get_template(template_name).render(context)
  77. if not no_cache:
  78. webnotes.cache().set_value("page:" + page_name, html)
  79. return html
  80. def build_sitemap():
  81. sitemap = {}
  82. config = webnotes.cache().get_value("website_sitemap_config", build_website_sitemap_config)
  83. sitemap.update(config["pages"])
  84. # generators
  85. for g in config["generators"].values():
  86. g["is_generator"] = True
  87. module = webnotes.get_module(g["controller"])
  88. for name in webnotes.conn.sql_list("""select page_name from `tab%s` where
  89. ifnull(%s, 0)=1""" % (module.doctype, module.condition_field)):
  90. sitemap[name] = g
  91. return sitemap
  92. def get_home_page():
  93. if not webnotes.conn:
  94. webnotes.connect()
  95. doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
  96. if doc_name:
  97. page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name')
  98. else:
  99. page_name = 'login'
  100. return page_name
  101. def build_website_sitemap_config():
  102. import os
  103. config = {"pages": {}, "generators":{}}
  104. basepath = webnotes.utils.get_base_path()
  105. def get_options(path, fname):
  106. name = fname[:-5]
  107. options = webnotes._dict({
  108. "link_name": name,
  109. "template": os.path.relpath(os.path.join(path, fname), basepath),
  110. })
  111. controller_path = os.path.join(path, name + ".py")
  112. if os.path.exists(controller_path):
  113. options.controller = os.path.relpath(controller_path[:-3], basepath).replace(os.path.sep, ".")
  114. options.controller = ".".join(options.controller.split(".")[1:])
  115. return options
  116. for path, folders, files in os.walk(basepath):
  117. if os.path.basename(path)=="pages" and os.path.basename(os.path.dirname(path))=="templates":
  118. for fname in files:
  119. if fname.endswith(".html"):
  120. options = get_options(path, fname)
  121. config["pages"][options.link_name] = options
  122. if os.path.basename(path)=="generators" and os.path.basename(os.path.dirname(path))=="templates":
  123. for fname in files:
  124. if fname.endswith(".html"):
  125. options = get_options(path, fname)
  126. config["generators"][fname] = options
  127. return config
  128. def get_website_settings():
  129. from webnotes.utils import get_request_site_address, encode, cint
  130. from urllib import quote
  131. all_top_items = webnotes.conn.sql("""\
  132. select * from `tabTop Bar Item`
  133. where parent='Website Settings' and parentfield='top_bar_items'
  134. order by idx asc""", as_dict=1)
  135. top_items = [d for d in all_top_items if not d['parent_label']]
  136. # attach child items to top bar
  137. for d in all_top_items:
  138. if d['parent_label']:
  139. for t in top_items:
  140. if t['label']==d['parent_label']:
  141. if not 'child_items' in t:
  142. t['child_items'] = []
  143. t['child_items'].append(d)
  144. break
  145. context = webnotes._dict({
  146. 'top_bar_items': top_items,
  147. 'footer_items': webnotes.conn.sql("""\
  148. select * from `tabTop Bar Item`
  149. where parent='Website Settings' and parentfield='footer_items'
  150. order by idx asc""", as_dict=1),
  151. "webnotes": webnotes,
  152. "utils": webnotes.utils,
  153. "post_login": [
  154. {"label": "Logout", "url": "server.py?cmd=web_logout", "icon": "icon-signout"},
  155. ]
  156. })
  157. settings = webnotes.doc("Website Settings", "Website Settings")
  158. for k in ["banner_html", "brand_html", "copyright", "twitter_share_via",
  159. "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
  160. "disable_signup"]:
  161. if k in settings.fields:
  162. context[k] = settings.fields.get(k)
  163. if settings.address:
  164. context["footer_address"] = settings.address
  165. for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
  166. "disable_signup"]:
  167. context[k] = cint(context.get(k) or 0)
  168. context.url = quote(str(get_request_site_address(full_address=True)), str(""))
  169. context.encoded_title = quote(encode(context.title or ""), str(""))
  170. try:
  171. import startup.webutils
  172. if hasattr(startup.webutils, "get_website_settings"):
  173. startup.webutils.get_website_settings(context)
  174. except:
  175. pass
  176. return context
  177. def clear_cache(page_name=None):
  178. if page_name:
  179. delete_page_cache(page_name)
  180. else:
  181. cache = webnotes.cache()
  182. for p in get_all_pages():
  183. cache.delete_value("page:" + p)
  184. cache.delete_value("website_sitemap")
  185. cache.delete_value("website_sitemap_config")
  186. def get_all_pages():
  187. return webnotes.cache().get_value("website_sitemap", build_sitemap).keys()
  188. def delete_page_cache(page_name):
  189. if page_name:
  190. webnotes.cache().delete_value("page:" + page_name)
  191. def get_hex_shade(color, percent):
  192. def p(c):
  193. v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
  194. if v < 0:
  195. v=0
  196. if v > 255:
  197. v=255
  198. h = hex(v)[2:]
  199. if len(h) < 2:
  200. h = "0" + h
  201. return h
  202. r, g, b = color[0:2], color[2:4], color[4:6]
  203. avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
  204. # switch dark and light shades
  205. if avg > 128:
  206. percent = -percent
  207. # stronger diff for darker shades
  208. if percent < 25 and avg < 64:
  209. percent = percent * 2
  210. return p(r) + p(g) + p(b)
  211. def scrub_page_name(page_name):
  212. if page_name.endswith('.html'):
  213. page_name = page_name[:-5]
  214. return page_name
  215. _is_signup_enabled = None
  216. def is_signup_enabled():
  217. global _is_signup_enabled
  218. if _is_signup_enabled is None:
  219. _is_signup_enabled = True
  220. if webnotes.utils.cint(webnotes.conn.get_value("Website Settings",
  221. "Website Settings", "disable_signup")):
  222. _is_signup_enabled = False
  223. return _is_signup_enabled
  224. def update_page_name(doc, title):
  225. """set page_name and check if it is unique"""
  226. webnotes.conn.set(doc, "page_name", page_name(title))
  227. if doc.page_name in get_all_pages():
  228. webnotes.throw("%s: %s. %s: %s" % (doc.page_name, _("Page already exists"),
  229. _("Please change the value"), title))
  230. delete_page_cache(doc.page_name)
  231. def page_name(title):
  232. """make page name from title"""
  233. import re
  234. name = title.lower()
  235. name = re.sub('[~!@#$%^&*()<>,."\']', '', name)
  236. name = re.sub('[:/]', '-', name)
  237. name = '-'.join(name.split())
  238. # replace repeating hyphens
  239. name = re.sub(r"(-)\1+", r"\1", name)
  240. return name