Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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