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