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.

webutils.py 8.8 KiB

11 jaren geleden
12 jaren geleden
11 jaren geleden
12 jaren geleden
12 jaren geleden
12 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. from webnotes import conf
  5. import webnotes
  6. import json, os, time
  7. from webnotes import _
  8. import webnotes.utils
  9. import mimetypes
  10. from website.doctype.website_sitemap.website_sitemap import add_to_sitemap
  11. class PageNotFoundError(Exception): pass
  12. def render(page_name):
  13. """render html page"""
  14. if not page_name:
  15. page_name = "index"
  16. try:
  17. html = render_page(page_name)
  18. except PageNotFoundError:
  19. html = render_page("404")
  20. except webnotes.DoesNotExistError:
  21. if page_name in ("index", "index.html"):
  22. html = render_page("login")
  23. else:
  24. html = render_page("404")
  25. except Exception:
  26. html = render_page("error")
  27. webnotes._response.data = html
  28. def render_page(page_name):
  29. """get page html"""
  30. set_content_type(page_name)
  31. if page_name.endswith('.html'):
  32. page_name = page_name[:-5]
  33. html = ''
  34. if not conf.auto_cache_clear:
  35. html = webnotes.cache().get_value("page:" + page_name)
  36. from_cache = True
  37. if not html:
  38. html = build_page(page_name)
  39. from_cache = False
  40. if not html:
  41. raise PageNotFoundError
  42. if page_name=="error":
  43. html = html.replace("%(error)s", webnotes.getTraceback())
  44. elif "text/html" in webnotes._response.headers["Content-Type"]:
  45. comments = "\npage:"+page_name+\
  46. "\nload status: " + (from_cache and "cache" or "fresh")
  47. html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
  48. return html
  49. def set_content_type(page_name):
  50. webnotes._response.headers["Content-Type"] = "text/html; charset: utf-8"
  51. if "." in page_name and not page_name.endswith(".html"):
  52. content_type, encoding = mimetypes.guess_type(page_name)
  53. webnotes._response.headers["Content-Type"] = content_type
  54. def build_page(page_name):
  55. if not webnotes.conn:
  56. webnotes.connect()
  57. sitemap_options = webnotes.doc("Website Sitemap", page_name).fields
  58. page_options = webnotes.doc("Website Sitemap Config",
  59. sitemap_options.get("website_sitemap_config")).fields.update({
  60. "page_name":sitemap_options.page_name,
  61. "docname":sitemap_options.docname
  62. })
  63. if not page_options:
  64. raise PageNotFoundError
  65. else:
  66. page_options["page_name"] = page_name
  67. basepath = webnotes.utils.get_base_path()
  68. no_cache = page_options.get("no_cache")
  69. # if generator, then load bean, pass arguments
  70. if page_options.get("page_or_generator")=="Generator":
  71. doctype = page_options.get("ref_doctype")
  72. obj = webnotes.get_obj(doctype, page_options["docname"], with_children=True)
  73. if hasattr(obj, 'get_context'):
  74. obj.get_context()
  75. context = webnotes._dict(obj.doc.fields)
  76. context["obj"] = obj
  77. else:
  78. # page
  79. context = webnotes._dict({ 'name': page_name })
  80. if page_options.get("controller"):
  81. module = webnotes.get_module(page_options.get("controller"))
  82. if module and hasattr(module, "get_context"):
  83. context.update(module.get_context())
  84. context.update(get_website_settings())
  85. jenv = webnotes.get_jenv()
  86. context["base_template"] = jenv.get_template(webnotes.get_config().get("base_template"))
  87. template_name = page_options['template_path']
  88. html = jenv.get_template(template_name).render(context)
  89. if not no_cache:
  90. webnotes.cache().set_value("page:" + page_name, html)
  91. return html
  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 get_website_settings():
  102. from webnotes.utils import get_request_site_address, encode, cint
  103. from urllib import quote
  104. all_top_items = webnotes.conn.sql("""\
  105. select * from `tabTop Bar Item`
  106. where parent='Website Settings' and parentfield='top_bar_items'
  107. order by idx asc""", as_dict=1)
  108. top_items = [d for d in all_top_items if not d['parent_label']]
  109. # attach child items to top bar
  110. for d in all_top_items:
  111. if d['parent_label']:
  112. for t in top_items:
  113. if t['label']==d['parent_label']:
  114. if not 'child_items' in t:
  115. t['child_items'] = []
  116. t['child_items'].append(d)
  117. break
  118. context = webnotes._dict({
  119. 'top_bar_items': top_items,
  120. 'footer_items': webnotes.conn.sql("""\
  121. select * from `tabTop Bar Item`
  122. where parent='Website Settings' and parentfield='footer_items'
  123. order by idx asc""", as_dict=1),
  124. "webnotes": webnotes,
  125. "utils": webnotes.utils,
  126. "post_login": [
  127. {"label": "Reset Password", "url": "update-password", "icon": "icon-key"},
  128. {"label": "Logout", "url": "/?cmd=web_logout", "icon": "icon-signout"}
  129. ]
  130. })
  131. settings = webnotes.doc("Website Settings", "Website Settings")
  132. for k in ["banner_html", "brand_html", "copyright", "twitter_share_via",
  133. "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
  134. "disable_signup"]:
  135. if k in settings.fields:
  136. context[k] = settings.fields.get(k)
  137. if settings.address:
  138. context["footer_address"] = settings.address
  139. for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
  140. "disable_signup"]:
  141. context[k] = cint(context.get(k) or 0)
  142. context.url = quote(str(get_request_site_address(full_address=True)), str(""))
  143. context.encoded_title = quote(encode(context.title or ""), str(""))
  144. try:
  145. import startup.webutils
  146. if hasattr(startup.webutils, "get_website_settings"):
  147. startup.webutils.get_website_settings(context)
  148. except:
  149. pass
  150. return context
  151. def clear_cache(page_name=None):
  152. if page_name:
  153. delete_page_cache(page_name)
  154. else:
  155. cache = webnotes.cache()
  156. for p in webnotes.conn.sql_list("""select name from `tabWebsite Sitemap`"""):
  157. if p is not None:
  158. cache.delete_value("page:" + p)
  159. cache.delete_value("page:index")
  160. cache.delete_value("website_sitemap")
  161. cache.delete_value("website_sitemap_config")
  162. def delete_page_cache(page_name):
  163. if page_name:
  164. cache = webnotes.cache()
  165. cache.delete_value("page:" + page_name)
  166. cache.delete_value("website_sitemap")
  167. def is_signup_enabled():
  168. if getattr(webnotes.local, "is_signup_enabled", None) is None:
  169. webnotes.local.is_signup_enabled = True
  170. if webnotes.utils.cint(webnotes.conn.get_value("Website Settings",
  171. "Website Settings", "disable_signup")):
  172. webnotes.local.is_signup_enabled = False
  173. return webnotes.local.is_signup_enabled
  174. class WebsiteGenerator(object):
  175. def setup_generator(self):
  176. self._website_config = webnotes.conn.get_values("Website Sitemap Config",
  177. {"ref_doctype": self.doc.doctype}, "*")[0]
  178. def on_update(self, page_name=None):
  179. self.setup_generator()
  180. if self._website_config.condition_field:
  181. if not self.doc.fields.get(self._website_config.condition_field):
  182. # condition field failed, return
  183. remove_page(self.doc.fields.get(self._website_config.page_name_field))
  184. return
  185. if not page_name:
  186. new_page_name = cleanup_page_name(self.get_page_title() \
  187. if hasattr(self, "get_page_title") else (self.doc.title or self.doc.name))
  188. self.check_if_page_name_is_unique(new_page_name)
  189. remove_page(self.doc.page_name)
  190. if self.doc.fields.get(self._website_config.page_name_field)!=new_page_name:
  191. webnotes.conn.set(self.doc, self._website_config.page_name_field, new_page_name)
  192. page_name = new_page_name
  193. add_to_sitemap(webnotes._dict({
  194. "ref_doctype":self.doc.doctype,
  195. "docname": self.doc.name,
  196. "page_name": page_name,
  197. "link_name": self._website_config.name,
  198. "lastmod": webnotes.utils.get_datetime(self.doc.modified).strftime("%Y-%m-%d")
  199. }))
  200. def check_if_page_name_is_unique(self, new_page_name):
  201. if webnotes.conn.sql("""select name from `tabWebsite Sitemap` where name=%s
  202. and website_sitemap_config!=%s and docname!=%s""", (new_page_name,
  203. self._website_config.name, self.doc.name)):
  204. webnotes.throw("%s: %s. %s: <b>%s<b>" % (new_page_name, _("Page already exists"),
  205. _("Please change the value"), self.doc.title))
  206. def on_trash(self):
  207. self.setup_generator()
  208. remove_page(self.doc.fields[self._website_config.page_name_field])
  209. def remove_page(page_name):
  210. if page_name:
  211. delete_page_cache(page_name)
  212. webnotes.conn.sql("delete from `tabWebsite Sitemap` where name=%s", page_name)
  213. def cleanup_page_name(title):
  214. """make page name from title"""
  215. import re
  216. name = title.lower()
  217. name = re.sub('[~!@#$%^&*+()<>,."\'\?]', '', name)
  218. name = re.sub('[:/]', '-', name)
  219. name = '-'.join(name.split())
  220. # replace repeating hyphens
  221. name = re.sub(r"(-)\1+", r"\1", name)
  222. return name
  223. def get_hex_shade(color, percent):
  224. def p(c):
  225. v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
  226. if v < 0:
  227. v=0
  228. if v > 255:
  229. v=255
  230. h = hex(v)[2:]
  231. if len(h) < 2:
  232. h = "0" + h
  233. return h
  234. r, g, b = color[0:2], color[2:4], color[4:6]
  235. avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
  236. # switch dark and light shades
  237. if avg > 128:
  238. percent = -percent
  239. # stronger diff for darker shades
  240. if percent < 25 and avg < 64:
  241. percent = percent * 2
  242. return p(r) + p(g) + p(b)