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