Bladeren bron

refacted webnotes.webutils

version-14
Rushabh Mehta 11 jaren geleden
bovenliggende
commit
d2fe902b4e
41 gewijzigde bestanden met toevoegingen van 669 en 627 verwijderingen
  1. +1
    -1
      webnotes/__init__.py
  2. +2
    -2
      webnotes/app.py
  3. +0
    -1
      webnotes/boot.py
  4. +2
    -2
      webnotes/cli.py
  5. +1
    -1
      webnotes/core/doctype/communication/communication.py
  6. +5
    -5
      webnotes/templates/base.html
  7. +1
    -3
      webnotes/templates/generators/blog_category.html
  8. +4
    -4
      webnotes/templates/generators/blog_post.py
  9. +2
    -1
      webnotes/templates/generators/website_group.py
  10. +4
    -2
      webnotes/templates/includes/blog.js
  11. +2
    -1
      webnotes/templates/includes/comments.py
  12. +0
    -1
      webnotes/templates/pages/sitemap.py
  13. +1
    -1
      webnotes/templates/website_group/forum.py
  14. +1
    -1
      webnotes/templates/website_group/post.py
  15. +1
    -1
      webnotes/templates/website_group/settings.py
  16. +1
    -1
      webnotes/utils/response.py
  17. +0
    -8
      webnotes/website/README.md
  18. +64
    -0
      webnotes/website/context.py
  19. +1
    -1
      webnotes/website/doctype/about_us_settings/about_us_settings.py
  20. +2
    -4
      webnotes/website/doctype/blog_category/blog_category.py
  21. +9
    -4
      webnotes/website/doctype/blog_post/blog_post.py
  22. +1
    -1
      webnotes/website/doctype/blog_settings/blog_settings.py
  23. +1
    -1
      webnotes/website/doctype/contact_us_settings/contact_us_settings.py
  24. +1
    -1
      webnotes/website/doctype/style_settings/style_settings.py
  25. +1
    -1
      webnotes/website/doctype/user_vote/user_vote.py
  26. +3
    -3
      webnotes/website/doctype/web_page/web_page.py
  27. +1
    -1
      webnotes/website/doctype/website_group/website_group.py
  28. +1
    -1
      webnotes/website/doctype/website_script/website_script.py
  29. +60
    -2
      webnotes/website/doctype/website_settings/website_settings.py
  30. +9
    -7
      webnotes/website/doctype/website_sitemap/website_sitemap.py
  31. +2
    -1
      webnotes/website/doctype/website_sitemap_config/website_sitemap_config.py
  32. +7
    -1
      webnotes/website/doctype/website_sitemap_config/website_sitemap_config.txt
  33. +2
    -65
      webnotes/website/doctype/website_sitemap_permission/website_sitemap_permission.py
  34. +1
    -1
      webnotes/website/doctype/website_slideshow/website_slideshow.py
  35. +72
    -0
      webnotes/website/permissions.py
  36. +128
    -0
      webnotes/website/render.py
  37. +61
    -0
      webnotes/website/sitemap.py
  38. +48
    -0
      webnotes/website/template.py
  39. +67
    -0
      webnotes/website/utils.py
  40. +99
    -0
      webnotes/website/website_generator.py
  41. +0
    -496
      webnotes/webutils.py

+ 1
- 1
webnotes/__init__.py Bestand weergeven

@@ -588,7 +588,7 @@ def get_jloader():
def set_filters(jenv):
from webnotes.utils import global_date_format
from webnotes.webutils import get_hex_shade
from webnotes.website.utils import get_hex_shade
from markdown2 import markdown
from json import dumps


+ 2
- 2
webnotes/app.py Bestand weergeven

@@ -15,7 +15,7 @@ import webnotes
import webnotes.handler
import webnotes.auth
import webnotes.api
import webnotes.webutils
import webnotes.website.render
from webnotes.utils import get_site_name

local_manager = LocalManager([webnotes.local])
@@ -58,7 +58,7 @@ def application(request):
elif webnotes.request.path.startswith("/api/"):
webnotes.api.handle()
elif webnotes.local.request.method in ('GET', 'HEAD'):
webnotes.webutils.render(webnotes.request.path[1:])
webnotes.website.render.render(webnotes.request.path[1:])
else:
raise NotFound



+ 0
- 1
webnotes/boot.py Bestand weergeven

@@ -11,7 +11,6 @@ import webnotes.defaults
import webnotes.model.doc
import webnotes.widgets.page
import json
import webnotes.webutils

def get_bootinfo():
"""build and return boot info"""


+ 2
- 2
webnotes/cli.py Bestand weergeven

@@ -430,9 +430,9 @@ def clear_cache():

@cmd
def clear_web():
import webnotes.webutils
import webnotes.website.render
webnotes.connect()
webnotes.webutils.clear_cache()
webnotes.website.render.clear_cache()
webnotes.destroy()

@cmd


+ 1
- 1
webnotes/core/doctype/communication/communication.py Bestand weergeven

@@ -6,7 +6,7 @@ import webnotes
import json
import urllib
from email.utils import formataddr
from webnotes.webutils import is_signup_enabled
from webnotes.website.utils import is_signup_enabled
from webnotes.utils import get_url, cstr
from webnotes.utils.email_lib.email_body import get_email
from webnotes.utils.email_lib.smtp import send


+ 5
- 5
webnotes/templates/base.html Bestand weergeven

@@ -29,6 +29,11 @@
</style>
{%- endblock %}

{% block script -%}
<script data-html-block="script">
{%- if script is defined -%}{{ script }}{%- endif -%}
</script>
{%- endblock %}
{%- endblock %}
</head>
<body>
@@ -80,10 +85,5 @@
<div id="wrap-footer">
{%- block footer -%}{% include "templates/includes/footer.html" %}{%- endblock -%}
</div>
{% block script -%}
<script data-html-block="script">
{%- if script is defined -%}{{ script }}{%- endif -%}
</script>
{%- endblock %}
</body>
</html>

+ 1
- 3
webnotes/templates/generators/blog_category.html Bestand weergeven

@@ -5,7 +5,5 @@
{% block header %}<h2>{{ title }}</h2>{% endblock %}

{% block script %}
$(function() {
window.category = "{{ docname }}";
});
window.category = "{{ docname }}";
{% endblock %}

+ 4
- 4
webnotes/templates/generators/blog_post.py Bestand weergeven

@@ -46,14 +46,16 @@ def get_blog_list(start=0, by=None, category=None):
condition += " and t1.blog_category='%s'" % category.replace("'", "\'")
query = """\
select
t1.title, t1.name, t1.page_name, t1.published_on as creation,
t1.title, t1.name, t3.name as page_name, t1.published_on as creation,
ifnull(t1.blog_intro, t1.content) as content,
t2.full_name, t2.avatar, t1.blogger,
(select count(name) from `tabComment` where
comment_doctype='Blog Post' and comment_docname=t1.name) as comments
from `tabBlog Post` t1, `tabBlogger` t2
from `tabBlog Post` t1, `tabBlogger` t2, `tabWebsite Sitemap` t3
where ifnull(t1.published,0)=1
and t1.blogger = t2.name
and t3.docname = t1.name
and t3.ref_doctype = "Blog Post"
%(condition)s
order by published_on desc, name asc
limit %(start)s, 20""" % {"start": start, "condition": condition}
@@ -63,8 +65,6 @@ def get_blog_list(start=0, by=None, category=None):
# strip html tags from content
for res in result:
res['published'] = global_date_format(res['creation'])
if not res['content']:
res['content'] = webnotes.webutils.get_html(res['page_name'])
res['content'] = res['content'][:140]
return result

+ 2
- 1
webnotes/templates/generators/website_group.py Bestand weergeven

@@ -2,7 +2,8 @@
# MIT License. See license.txt

import webnotes
from webnotes.webutils import get_access, can_cache
from webnotes.website.permissions import get_access
from webnotes.website.render import can_cache
from webnotes.templates.website_group.forum import get_post_list_html

doctype = "Website Group"


+ 4
- 2
webnotes/templates/includes/blog.js Bestand weergeven

@@ -36,7 +36,9 @@ var blog = {
b.comment_text = b.comments + ' comments.'
}
b.page_name = encodeURIComponent(b.page_name);
b.page_name = $.map(b.page_name.split("/"), function(p)
{ return encodeURIComponent(p); }).join("/");
b.avatar = b.avatar || "";
$(repl('<div class="row">\
@@ -71,7 +73,7 @@ var blog = {

$(document).ready(function() {
// make list of blogs
blog.get_list();
setTimeout(blog.get_list, 100);
$("#next-page").click(function() {
blog.get_list();


+ 2
- 1
webnotes/templates/includes/comments.py Bestand weergeven

@@ -3,6 +3,7 @@

import webnotes
import webnotes.utils, markdown2
from webnotes.website.render import clear_cache

from webnotes import _

@@ -34,7 +35,7 @@ def add_comment(args=None):
comment.insert()
# since comments are embedded in the page, clear the web cache
webnotes.webutils.clear_cache(page_name)
clear_cache(page_name)

# notify commentors
commentors = [d[0] for d in webnotes.conn.sql("""select comment_by from tabComment where


+ 0
- 1
webnotes/templates/pages/sitemap.py Bestand weergeven

@@ -5,7 +5,6 @@ from __future__ import unicode_literals

import urllib
import webnotes
import webnotes.webutils
from webnotes.utils import get_request_site_address

no_cache = 1


+ 1
- 1
webnotes/templates/website_group/forum.py Bestand weergeven

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import now_datetime, get_datetime_str
from webnotes.webutils import get_access
from webnotes.website.permissions import get_access

@webnotes.whitelist(allow_guest=True)
def get_post_list_html(group, view, limit_start=0, limit_length=20):


+ 1
- 1
webnotes/templates/website_group/post.py Bestand weergeven

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import get_fullname
from webnotes.webutils import get_access
from webnotes.website.permissions import get_access
from webnotes.utils.file_manager import save_file
from webnotes.templates.generators.website_group import get_pathname



+ 1
- 1
webnotes/templates/website_group/settings.py Bestand weergeven

@@ -3,7 +3,7 @@

from __future__ import unicode_literals
import webnotes
from webnotes.webutils import get_access, clear_permissions
from webnotes.website.permissions import get_access, clear_permissions
from webnotes.templates.generators.website_group import get_pathname
from webnotes.utils.email_lib.bulk import send



+ 1
- 1
webnotes/utils/response.py Bestand weergeven

@@ -30,7 +30,7 @@ def build_response():

def print_page():
"""print web page"""
from webnotes.webutils import render
from webnotes.website.render import render
render(webnotes.response['page_name'])

def print_json():


+ 0
- 8
webnotes/website/README.md Bestand weergeven

@@ -1,8 +0,0 @@
Module for website management.

Contains:

- DocTypes for Web Page, Blogs
- Templates
- Settings
- Generators for Item, Blog Post, Item Group

+ 64
- 0
webnotes/website/context.py Bestand weergeven

@@ -0,0 +1,64 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes

# frequently used imports (used by other modules)
from webnotes.website.permissions import get_access
from webnotes.website.doctype.website_settings.website_settings import get_website_settings
from webnotes.website.template import render_blocks
from webnotes.website.sitemap import get_sitemap_options
from webnotes.website.utils import can_cache

def get_context(path):
context = None
cache_key = "page_context:{}".format(path)
# try from memcache
if can_cache():
context = webnotes.cache().get_value(cache_key)

if not context:
context = get_sitemap_options(path)

# permission may be required for rendering
context["access"] = get_access(context.pathname)

context = build_context(context)

if can_cache(context.no_cache):
webnotes.cache().set_value(cache_key, context)

else:
context["access"] = get_access(context.pathname)
context.update(context.data or {})
# TODO private pages
return context
def build_context(sitemap_options):
"""get_context method of bean or module is supposed to render content templates and push it into context"""
context = webnotes._dict(sitemap_options)
context.update(get_website_settings())
# provide bean
if context.doctype and context.docname:
context.bean = webnotes.bean(context.doctype, context.docname)
if context.controller:
module = webnotes.get_module(context.controller)
if module and hasattr(module, "get_context"):
context.update(module.get_context(context) or {})
if context.get("base_template_path") != context.get("template_path") and not context.get("rendered"):
context.data = render_blocks(context)
# remove bean, as it is not pickle friendly and its purpose is over
if context.bean:
del context["bean"]
return context

+ 1
- 1
webnotes/website/doctype/about_us_settings/about_us_settings.py Bestand weergeven

@@ -11,7 +11,7 @@ class DocType:
self.doc, self.doclist = d, dl
def on_update(self):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache("about")
def get_args():


+ 2
- 4
webnotes/website/doctype/blog_category/blog_category.py Bestand weergeven

@@ -3,7 +3,8 @@

from __future__ import unicode_literals
import webnotes
from webnotes.webutils import WebsiteGenerator, cleanup_page_name, clear_cache
from webnotes.website.website_generator import WebsiteGenerator
from webnotes.website.render import clear_cache

class DocType(WebsiteGenerator):
def __init__(self, d, dl):
@@ -18,7 +19,4 @@ class DocType(WebsiteGenerator):
def on_update(self):
WebsiteGenerator.on_update(self)

from webnotes.webutils import clear_cache
clear_cache()

+ 9
- 4
webnotes/website/doctype/blog_post/blog_post.py Bestand weergeven

@@ -4,16 +4,21 @@
from __future__ import unicode_literals

import webnotes
from webnotes.webutils import WebsiteGenerator, cleanup_page_name, clear_cache

from webnotes.website.website_generator import WebsiteGenerator
from webnotes.website.render import clear_cache
from webnotes import _
from webnotes.utils import today

class DocType(WebsiteGenerator):
def __init__(self, d, dl):
self.doc, self.doclist = d, dl

def autoname(self):
self.doc.name = cleanup_page_name(self.doc.title)
def get_page_title(self):
return self.doc.title
def get_parent_website_sitemap(self):
return webnotes.conn.get_value("Website Sitemap", {"ref_doctype": "Blog Category", "docname": self.doc.blog_category})

def validate(self):
if self.doc.blog_intro:


+ 1
- 1
webnotes/website/doctype/blog_settings/blog_settings.py Bestand weergeven

@@ -11,6 +11,6 @@ class DocType:
self.doc, self.doclist = d, dl
def on_update(self):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache("blog")
clear_cache("writers")

+ 1
- 1
webnotes/website/doctype/contact_us_settings/contact_us_settings.py Bestand weergeven

@@ -11,5 +11,5 @@ class DocType:
self.doc, self.doclist = d, dl

def on_update(self):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache("contact")

+ 1
- 1
webnotes/website/doctype/style_settings/style_settings.py Bestand weergeven

@@ -31,5 +31,5 @@ class DocType:
from webnotes.sessions import clear_cache
clear_cache('Guest')

from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()

+ 1
- 1
webnotes/website/doctype/user_vote/user_vote.py Bestand weergeven

@@ -3,7 +3,7 @@

from __future__ import unicode_literals
import webnotes
from webnotes.webutils import get_access
from webnotes.website.permissions import get_access

class DocType:
def __init__(self, d, dl):


+ 3
- 3
webnotes/website/doctype/web_page/web_page.py Bestand weergeven

@@ -3,7 +3,7 @@

from __future__ import unicode_literals
import webnotes, os, time
from webnotes.webutils import WebsiteGenerator
from webnotes.website.website_generator import WebsiteGenerator
from webnotes import _
from webnotes.utils import cint
from markdown2 import markdown
@@ -21,7 +21,7 @@ class DocType(WebsiteGenerator):
# clear all cache if it has toc
if self.doclist.get({"parentfield": "toc"}):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()
def on_trash(self):
@@ -33,7 +33,7 @@ class DocType(WebsiteGenerator):
# clear all cache if it has toc
if self.doclist.get({"parentfield": "toc"}):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()

def sync_statics():


+ 1
- 1
webnotes/website/doctype/website_group/website_group.py Bestand weergeven

@@ -3,7 +3,7 @@

from __future__ import unicode_literals
import webnotes
from webnotes.webutils import WebsiteGenerator
from webnotes.website.website_generator import WebsiteGenerator
from webnotes.templates.generators.website_group import clear_cache
from webnotes.model.doc import make_autoname



+ 1
- 1
webnotes/website/doctype/website_script/website_script.py Bestand weergeven

@@ -15,5 +15,5 @@ class DocType:
from webnotes.sessions import clear_cache
clear_cache('Guest')

from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()

+ 60
- 2
webnotes/website/doctype/website_settings/website_settings.py Bestand weergeven

@@ -4,7 +4,9 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes.utils import get_request_site_address, encode
from webnotes.model.controller import DocListController
from urllib import quote

class DocType(DocListController):
def validate(self):
@@ -43,6 +45,62 @@ class DocType(DocListController):
# make js and css
# clear web cache (for menus!)

from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()

def get_website_settings():
hooks = webnotes.get_hooks()
all_top_items = webnotes.conn.sql("""\
select * from `tabTop Bar Item`
where parent='Website Settings' and parentfield='top_bar_items'
order by idx asc""", as_dict=1)
top_items = [d for d in all_top_items if not d['parent_label']]
# attach child items to top bar
for d in all_top_items:
if d['parent_label']:
for t in top_items:
if t['label']==d['parent_label']:
if not 'child_items' in t:
t['child_items'] = []
t['child_items'].append(d)
break
context = webnotes._dict({
'top_bar_items': top_items,
'footer_items': webnotes.conn.sql("""\
select * from `tabTop Bar Item`
where parent='Website Settings' and parentfield='footer_items'
order by idx asc""", as_dict=1),
"post_login": [
{"label": "Reset Password", "url": "update-password", "icon": "icon-key"},
{"label": "Logout", "url": "?cmd=web_logout", "icon": "icon-signout"}
]
})
settings = webnotes.doc("Website Settings", "Website Settings")
for k in ["banner_html", "brand_html", "copyright", "twitter_share_via",
"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup"]:
if k in settings.fields:
context[k] = settings.fields.get(k)
if settings.address:
context["footer_address"] = settings.address

for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup"]:
context[k] = int(context.get(k) or 0)
context.url = quote(str(get_request_site_address(full_address=True)), safe="/:")
context.encoded_title = quote(encode(context.title or ""), str(""))
for update_website_context in hooks.update_website_context or []:
webnotes.get_attr(update_website_context)(context)
context.web_include_js = hooks.web_include_js or []
context.web_include_css = hooks.web_include_css or []
return context

+ 9
- 7
webnotes/website/doctype/website_sitemap/website_sitemap.py Bestand weergeven

@@ -1,8 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

# For license information, please see license.txt

from __future__ import unicode_literals
import webnotes
from webnotes import _
@@ -20,12 +18,16 @@ class DocType(DocTypeNestedSet):
self.doc.name = self.get_url()

def get_url(self):
parent_website_sitemap = self.get_parent_website_sitemap()
url = self.doc.page_name
if self.doc.parent_website_sitemap:
url = self.doc.parent_website_sitemap + "/" + url
if parent_website_sitemap:
url = parent_website_sitemap + "/" + url
return url
def get_parent_website_sitemap(self):
return self.doc.parent_website_sitemap
def validate(self):
if self.get_url() != self.doc.name:
self.rename()
@@ -33,7 +35,7 @@ class DocType(DocTypeNestedSet):
self.make_private_if_parent_is_private()
def rename(self):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
self.old_name = self.doc.name
self.doc.name = self.get_url()
webnotes.conn.sql("""update `tabWebsite Sitemap` set name=%s where name=%s""",
@@ -86,7 +88,7 @@ class DocType(DocTypeNestedSet):
self.doc.public_read = self.doc.public_write = 0
def on_trash(self):
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
# remove website sitemap permissions
to_remove = webnotes.conn.sql_list("""select name from `tabWebsite Sitemap Permission`
where website_sitemap=%s""", (self.doc.name,))


+ 2
- 1
webnotes/website/doctype/website_sitemap_config/website_sitemap_config.py Bestand weergeven

@@ -7,7 +7,7 @@ from __future__ import unicode_literals
import webnotes
import webnotes.utils
import os
from webnotes import _
from webnotes.website.doctype.website_sitemap.website_sitemap import add_to_sitemap, update_sitemap, cleanup_sitemap
from webnotes.utils.nestedset import rebuild_tree

@@ -95,6 +95,7 @@ def add_website_sitemap_config(page_or_generator, app, path, fname, basepath):
wsc.page_name_field = getattr(module, "page_name_field", "page_name")
wsc.condition_field = getattr(module, "condition_field", None)
wsc.base_template_path = getattr(module, "base_template_path", None)
wsc.page_title = getattr(module, "page_title", _(name.title()))
if webnotes.conn.exists("Website Sitemap Config", wsc.link_name):
# found by earlier app, override


+ 7
- 1
webnotes/website/doctype/website_sitemap_config/website_sitemap_config.txt Bestand weergeven

@@ -2,7 +2,7 @@
{
"creation": "2013-11-18 15:35:00",
"docstatus": 0,
"modified": "2014-02-13 15:48:16",
"modified": "2014-02-14 12:48:54",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -62,6 +62,12 @@
"label": "Link Name",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "page_title",
"fieldtype": "Data",
"label": "Page Title"
},
{
"doctype": "DocField",
"fieldname": "base_template_path",


+ 2
- 65
webnotes/website/doctype/website_sitemap_permission/website_sitemap_permission.py Bestand weergeven

@@ -4,6 +4,8 @@
from __future__ import unicode_literals
import webnotes

from webnotes.website.permissions import remove_empty_permissions, clear_permissions

class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
@@ -12,68 +14,3 @@ class DocType:
remove_empty_permissions()
clear_permissions(self.doc.profile)
def remove_empty_permissions():
permissions_cache_to_be_cleared = webnotes.conn.sql_list("""select distinct profile
from `tabWebsite Sitemap Permission`
where ifnull(`read`, 0)=0 and ifnull(`write`, 0)=0 and ifnull(`admin`, 0)=0""")
webnotes.conn.sql("""delete from `tabWebsite Sitemap Permission`
where ifnull(`read`, 0)=0 and ifnull(`write`, 0)=0 and ifnull(`admin`, 0)=0""")
clear_permissions(permissions_cache_to_be_cleared)

def get_access(sitemap_page, profile=None):
profile = profile or webnotes.session.user
key = "website_sitemap_permissions:{}".format(profile)
cache = webnotes.cache()
permissions = cache.get_value(key) or {}
if not permissions.get(sitemap_page):
permissions[sitemap_page] = _get_access(sitemap_page, profile)
cache.set_value(key, permissions)
return permissions.get(sitemap_page)
def _get_access(sitemap_page, profile):
lft, rgt, public_read, public_write = webnotes.conn.get_value("Website Sitemap", sitemap_page,
["lft", "rgt", "public_read", "public_write"])

if not (lft and rgt):
raise webnotes.ValidationError("Please rebuild Website Sitemap Tree")
if profile == "Guest":
return { "read": public_read, "write": 0, "admin": 0 }
read = write = admin = private_read = 0

if public_write:
read = write = 1
elif public_read:
read = 1

for perm in webnotes.conn.sql("""select wsp.`read`, wsp.`write`, wsp.`admin`,
ws.lft, ws.rgt, ws.name
from `tabWebsite Sitemap Permission` wsp, `tabWebsite Sitemap` ws
where wsp.profile = %s and wsp.website_sitemap = ws.name
order by lft asc""", (profile,), as_dict=True):
if perm.lft <= lft and perm.rgt >= rgt:
if not (public_read or private_read): private_read = perm.read
if not read: read = perm.read
if not write: write = perm.write
if not admin: admin = perm.admin
if write: read = write
if read and write and admin:
break

return { "read": read, "write": write, "admin": admin, "private_read": private_read }

def clear_permissions(profiles=None):
if isinstance(profiles, basestring):
profiles = [profiles]
elif profiles is None:
profiles = webnotes.conn.sql_list("""select name from `tabProfile`""")
cache = webnotes.cache()
for profile in profiles:
cache.delete_value("website_sitemap_permissions:{}".format(profile))

+ 1
- 1
webnotes/website/doctype/website_slideshow/website_slideshow.py Bestand weergeven

@@ -12,7 +12,7 @@ class DocType:
def on_update(self):
# a slide show can be in use and any change in it should get reflected
from webnotes.webutils import clear_cache
from webnotes.website.render import clear_cache
clear_cache()
def get_slideshow(bean):


+ 72
- 0
webnotes/website/permissions.py Bestand weergeven

@@ -0,0 +1,72 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes


def remove_empty_permissions():
permissions_cache_to_be_cleared = webnotes.conn.sql_list("""select distinct profile
from `tabWebsite Sitemap Permission`
where ifnull(`read`, 0)=0 and ifnull(`write`, 0)=0 and ifnull(`admin`, 0)=0""")
webnotes.conn.sql("""delete from `tabWebsite Sitemap Permission`
where ifnull(`read`, 0)=0 and ifnull(`write`, 0)=0 and ifnull(`admin`, 0)=0""")
clear_permissions(permissions_cache_to_be_cleared)

def get_access(sitemap_page, profile=None):
profile = profile or webnotes.session.user
key = "website_sitemap_permissions:{}".format(profile)
cache = webnotes.cache()
permissions = cache.get_value(key) or {}
if not permissions.get(sitemap_page):
permissions[sitemap_page] = _get_access(sitemap_page, profile)
cache.set_value(key, permissions)
return permissions.get(sitemap_page)
def _get_access(sitemap_page, profile):
lft, rgt, public_read, public_write = webnotes.conn.get_value("Website Sitemap", sitemap_page,
["lft", "rgt", "public_read", "public_write"])

if not (lft and rgt):
raise webnotes.ValidationError("Please rebuild Website Sitemap Tree")
if profile == "Guest":
return { "read": public_read, "write": 0, "admin": 0 }
read = write = admin = private_read = 0

if public_write:
read = write = 1
elif public_read:
read = 1

for perm in webnotes.conn.sql("""select wsp.`read`, wsp.`write`, wsp.`admin`,
ws.lft, ws.rgt, ws.name
from `tabWebsite Sitemap Permission` wsp, `tabWebsite Sitemap` ws
where wsp.profile = %s and wsp.website_sitemap = ws.name
order by lft asc""", (profile,), as_dict=True):
if perm.lft <= lft and perm.rgt >= rgt:
if not (public_read or private_read): private_read = perm.read
if not read: read = perm.read
if not write: write = perm.write
if not admin: admin = perm.admin
if write: read = write
if read and write and admin:
break

return { "read": read, "write": write, "admin": admin, "private_read": private_read }

def clear_permissions(profiles=None):
if isinstance(profiles, basestring):
profiles = [profiles]
elif profiles is None:
profiles = webnotes.conn.sql_list("""select name from `tabProfile`""")
cache = webnotes.cache()
for profile in profiles:
cache.delete_value("website_sitemap_permissions:{}".format(profile))

+ 128
- 0
webnotes/website/render.py Bestand weergeven

@@ -0,0 +1,128 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes
import mimetypes, json

from webnotes.website.context import get_context
from webnotes.website.utils import scrub_relative_urls, get_home_page, can_cache

from webnotes.website.permissions import get_access, clear_permissions

class PageNotFoundError(Exception): pass

def render(path):
"""render html page"""
path = resolve_path(path)
try:
data = render_page(path)
except Exception:
path = "error"
data = render_page(path)
data = set_content_type(data, path)
webnotes._response.data = data
webnotes._response.headers[b"Page Name"] = path.encode("utf-8")
def render_page(path):
"""get page html"""
cache_key = ("page_context:{}" if is_ajax() else "page:{}").format(path)

out = None
# try memcache
if can_cache():
out = webnotes.cache().get_value(cache_key)
if out and is_ajax():
out = out.get("data")
if out:
if hasattr(webnotes, "_response"):
webnotes._response.headers[b"From Cache"] = True
return out
return build(path)
def build(path):
if not webnotes.conn:
webnotes.connect()
build_method = (build_json if is_ajax() else build_page)
try:
return build_method(path)

except webnotes.DoesNotExistError:
hooks = webnotes.get_hooks()
if hooks.website_catch_all:
return build_method(hooks.website_catch_all[0])
else:
return build_method("404")
def build_json(path):
return get_context(path).data
def build_page(path):
context = get_context(path)
html = webnotes.get_template(context.base_template_path).render(context)
html = scrub_relative_urls(html)
if can_cache(context.no_cache):
webnotes.cache().set_value("page:" + path, html)
return html
def is_ajax():
return webnotes.get_request_header("X-Requested-With")=="XMLHttpRequest"
def resolve_path(path):
if not path:
path = "index"
if path.endswith('.html'):
path = path[:-5]
if path == "index":
path = get_home_page()
return path

def set_content_type(data, path):
if isinstance(data, dict):
webnotes._response.headers[b"Content-Type"] = b"application/json; charset: utf-8"
data = json.dumps(data)
return data
webnotes._response.headers[b"Content-Type"] = b"text/html; charset: utf-8"
if "." in path and not path.endswith(".html"):
content_type, encoding = mimetypes.guess_type(path)
webnotes._response.headers[b"Content-Type"] = content_type.encode("utf-8")
return data

def clear_cache(path=None):
cache = webnotes.cache()
if path:
delete_page_cache(path)
else:
for p in webnotes.conn.sql_list("""select name from `tabWebsite Sitemap`"""):
if p is not None:
delete_page_cache(p)
cache.delete_value("home_page")
clear_permissions()
for method in webnotes.get_hooks("website_clear_cache"):
webnotes.get_attr(method)(path)

def delete_page_cache(path):
cache = webnotes.cache()
cache.delete_value("page:" + path)
cache.delete_value("page_context:" + path)
cache.delete_value("sitemap_options:" + path)

+ 61
- 0
webnotes/website/sitemap.py Bestand weergeven

@@ -0,0 +1,61 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes

from webnotes.website.utils import scrub_relative_urls, get_home_page, can_cache

def get_sitemap_options(path):
sitemap_options = None
cache_key = "sitemap_options:{}".format(path)

if can_cache():
sitemap_options = webnotes.cache().get_value(cache_key)

if not sitemap_options:
sitemap_options = build_sitemap_options(path)
if can_cache(sitemap_options.no_cache):
webnotes.cache().set_value(cache_key, sitemap_options)
return webnotes._dict(sitemap_options)
def build_sitemap_options(path):
sitemap_options = webnotes.doc("Website Sitemap", path).fields
home_page = get_home_page()
sitemap_config = webnotes.doc("Website Sitemap Config",
sitemap_options.get("website_sitemap_config")).fields
# get sitemap config fields too
for fieldname in ("base_template_path", "template_path", "controller", "no_cache", "no_sitemap",
"page_name_field", "condition_field"):
sitemap_options[fieldname] = sitemap_config.get(fieldname)
sitemap_options.doctype = sitemap_options.ref_doctype
sitemap_options.title = sitemap_options.page_title
sitemap_options.pathname = sitemap_options.name
def set_sidebar_items(pathname):
if pathname==home_page or not pathname:
sitemap_options.children = webnotes.conn.sql("""select url as name, label as page_title,
1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items' order by idx""", as_dict=True)
else:
sitemap_options.children = webnotes.conn.sql("""select * from `tabWebsite Sitemap`
where ifnull(parent_website_sitemap,'')=%s
and public_read=1 order by -idx desc, page_title asc""", pathname, as_dict=True)
# establish hierarchy
sitemap_options.parents = webnotes.conn.sql("""select name, page_title from `tabWebsite Sitemap`
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True)

if not sitemap_options.no_sidebar:
set_sidebar_items(sitemap_options.pathname)
if not sitemap_options.children:
set_sidebar_items(sitemap_options.parent_website_sitemap)

# determine templates to be used
if not sitemap_options.base_template_path:
sitemap_options.base_template_path = "templates/base.html"
return sitemap_options

+ 48
- 0
webnotes/website/template.py Bestand weergeven

@@ -0,0 +1,48 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes

from webnotes.website.utils import scrub_relative_urls
from jinja2.utils import concat
from jinja2 import meta

def render_blocks(context):
"""returns a dict of block name and its rendered content"""

out = {}
env = webnotes.get_jenv()
def _render_blocks(template_path):
source = webnotes.local.jloader.get_source(webnotes.local.jenv, template_path)[0]
for referenced_template_path in meta.find_referenced_templates(env.parse(source)):
if referenced_template_path:
_render_blocks(referenced_template_path)
template = webnotes.get_template(template_path)
for block, render in template.blocks.items():
out[block] = scrub_relative_urls(concat(render(template.new_context(context))))
_render_blocks(context["template_path"])

# default blocks if not found
if "title" not in out:
out["title"] = context.get("title")
if "header" not in out:
out["header"] = out["title"]

if not out["header"].startswith("<h"):
out["header"] = "<h2>" + out["header"] + "</h2>"
if "breadcrumbs" not in out:
out["breadcrumbs"] = scrub_relative_urls(
webnotes.get_template("templates/includes/breadcrumbs.html").render(context))
if "sidebar" not in out:
out["sidebar"] = scrub_relative_urls(
webnotes.get_template("templates/includes/sidebar.html").render(context))

return out

+ 67
- 0
webnotes/website/utils.py Bestand weergeven

@@ -0,0 +1,67 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes, re

def scrub_relative_urls(html):
"""prepend a slash before a relative url"""
return re.sub("""(src|href)[^\w'"]*['"](?!http|ftp|/|#)([^'" >]+)['"]""", '\g<1> = "/\g<2>"', html)

def can_cache(no_cache=False):
return not (webnotes.conf.disable_website_cache or no_cache)

def get_home_page():
home_page = webnotes.cache().get_value("home_page", \
lambda: (webnotes.get_hooks("home_page") \
or [webnotes.conn.get_value("Website Settings", None, "home_page") \
or "login"])[0])

return home_page
def is_signup_enabled():
if getattr(webnotes.local, "is_signup_enabled", None) is None:
webnotes.local.is_signup_enabled = True
if webnotes.utils.cint(webnotes.conn.get_value("Website Settings",
"Website Settings", "disable_signup")):
webnotes.local.is_signup_enabled = False
return webnotes.local.is_signup_enabled
def cleanup_page_name(title):
"""make page name from title"""
name = title.lower()
name = re.sub('[~!@#$%^&*+()<>,."\'\?]', '', name)
name = re.sub('[:/]', '-', name)

name = '-'.join(name.split())

# replace repeating hyphens
name = re.sub(r"(-)\1+", r"\1", name)
return name

def get_hex_shade(color, percent):
def p(c):
v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
if v < 0:
v=0
if v > 255:
v=255
h = hex(v)[2:]
if len(h) < 2:
h = "0" + h
return h
r, g, b = color[0:2], color[2:4], color[4:6]
avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
# switch dark and light shades
if avg > 128:
percent = -percent

# stronger diff for darker shades
if percent < 25 and avg < 64:
percent = percent * 2
return p(r) + p(g) + p(b)

+ 99
- 0
webnotes/website/website_generator.py Bestand weergeven

@@ -0,0 +1,99 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes
from webnotes.model.controller import DocListController

from webnotes.website.doctype.website_sitemap.website_sitemap import add_to_sitemap, update_sitemap, remove_sitemap

class WebsiteGenerator(DocListController):
def autoname(self):
from webnotes.website.utils import cleanup_page_name
self.doc.name = cleanup_page_name(self.get_page_title())

def set_page_name(self):
"""set page name based on parent page_name and title"""
page_name = cleanup_page_name(self.get_page_title())

if self.doc.is_new():
self.doc.fields[self._website_config.page_name_field] = page_name
else:
webnotes.conn.set(self.doc, self._website_config.page_name_field, page_name)

def get_parent_website_sitemap(self):
return self.doc.parent_website_sitemap

def setup_generator(self):
self._website_config = webnotes.conn.get_values("Website Sitemap Config",
{"ref_doctype": self.doc.doctype}, "*")[0]

def on_update(self):
self.update_sitemap()
def after_rename(self, olddn, newdn, merge):
webnotes.conn.sql("""update `tabWebsite Sitemap`
set docname=%s where ref_doctype=%s and docname=%s""", (newdn, self.doc.doctype, olddn))
if merge:
self.setup_generator()
remove_sitemap(ref_doctype=self.doc.doctype, docname=olddn)
def on_trash(self):
self.setup_generator()
remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
def update_sitemap(self):
self.setup_generator()
if self._website_config.condition_field and \
not self.doc.fields.get(self._website_config.condition_field):
# condition field failed, remove and return!
remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
return
self.add_or_update_sitemap()
def add_or_update_sitemap(self):
page_name = self.get_page_name()
existing_site_map = webnotes.conn.get_value("Website Sitemap", {"ref_doctype": self.doc.doctype,
"docname": self.doc.name})
opts = webnotes._dict({
"page_or_generator": "Generator",
"ref_doctype":self.doc.doctype,
"docname": self.doc.name,
"page_name": page_name,
"link_name": self._website_config.name,
"lastmod": webnotes.utils.get_datetime(self.doc.modified).strftime("%Y-%m-%d"),
"parent_website_sitemap": self.get_parent_website_sitemap(),
"page_title": self.get_page_title(),
"public_read": 1 if not self._website_config.no_sidebar else 0
})

self.update_permissions(opts)
if existing_site_map:
update_sitemap(existing_site_map, opts)
else:
add_to_sitemap(opts)
def update_permissions(self, opts):
if self.meta.get_field("public_read"):
opts.public_read = self.doc.public_read
opts.public_write = self.doc.public_write
else:
opts.public_read = 1
def get_page_name(self):
if not self._get_page_name():
self.set_page_name()
return self._get_page_name()
def _get_page_name(self):
return self.doc.fields.get(self._website_config.page_name_field)
def get_page_title(self):
return self.doc.title or (self.doc.name.replace("-", " ").replace("_", " ").title())

+ 0
- 496
webnotes/webutils.py Bestand weergeven

@@ -1,496 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import webnotes
import json, os, time, re
from webnotes import _
import webnotes.utils
from webnotes.utils import get_request_site_address, encode, cint
from webnotes.model import default_fields
from webnotes.model.controller import DocListController
from urllib import quote

import mimetypes
from webnotes.website.doctype.website_sitemap.website_sitemap import add_to_sitemap, update_sitemap, remove_sitemap

# frequently used imports (used by other modules)
from webnotes.website.doctype.website_sitemap_permission.website_sitemap_permission \
import get_access, clear_permissions

class PageNotFoundError(Exception): pass

def render(path):
"""render html page"""
path = resolve_path(path)
try:
data = render_page(path)
except Exception:
path = "error"
data = render_page(path)
data = set_content_type(data, path)
webnotes._response.data = data
webnotes._response.headers[b"Page Name"] = path.encode("utf-8")
def render_page(path):
"""get page html"""
cache_key = ("page_context:{}" if is_ajax() else "page:{}").format(path)

out = None
# try memcache
if can_cache():
out = webnotes.cache().get_value(cache_key)
if out and is_ajax():
out = out.get("data")
if out:
if hasattr(webnotes, "_response"):
webnotes._response.headers[b"From Cache"] = True
return out
return build(path)
def build(path):
if not webnotes.conn:
webnotes.connect()
build_method = (build_json if is_ajax() else build_page)
try:
return build_method(path)

except webnotes.DoesNotExistError:
hooks = webnotes.get_hooks()
if hooks.website_catch_all:
return build_method(hooks.website_catch_all[0])
else:
return build_method("404")
def build_json(path):
return get_context(path).data
def build_page(path):
context = get_context(path)
html = webnotes.get_template(context.base_template_path).render(context)
html = scrub_relative_urls(html)
if can_cache(context.no_cache):
webnotes.cache().set_value("page:" + path, html)
return html

def get_context(path):
context = None
cache_key = "page_context:{}".format(path)
from pickle import dump
from StringIO import StringIO
# try from memcache
if can_cache():
context = webnotes.cache().get_value(cache_key)

if not context:
context = get_sitemap_options(path)

# permission may be required for rendering
context["access"] = get_access(context.pathname)

context = build_context(context)

if can_cache(context.no_cache):
webnotes.cache().set_value(cache_key, context)

else:
context["access"] = get_access(context.pathname)
context.update(context.data or {})
# TODO private pages
return context
def get_sitemap_options(path):
sitemap_options = None
cache_key = "sitemap_options:{}".format(path)
if can_cache():
sitemap_options = webnotes.cache().get_value(cache_key)

if not sitemap_options:
sitemap_options = build_sitemap_options(path)
if can_cache(sitemap_options.no_cache):
webnotes.cache().set_value(cache_key, sitemap_options)
return webnotes._dict(sitemap_options)
def build_sitemap_options(path):
sitemap_options = webnotes.doc("Website Sitemap", path).fields
home_page = get_home_page()
sitemap_config = webnotes.doc("Website Sitemap Config",
sitemap_options.get("website_sitemap_config")).fields
# get sitemap config fields too
for fieldname in ("base_template_path", "template_path", "controller", "no_cache", "no_sitemap",
"page_name_field", "condition_field"):
sitemap_options[fieldname] = sitemap_config.get(fieldname)
sitemap_options.doctype = sitemap_options.ref_doctype
sitemap_options.title = sitemap_options.page_title
sitemap_options.pathname = sitemap_options.name
def set_sidebar_items(pathname):
if pathname==home_page or not pathname:
sitemap_options.children = webnotes.conn.sql("""select url as name, label as page_title,
1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items' order by idx""", as_dict=True)
else:
sitemap_options.children = webnotes.conn.sql("""select * from `tabWebsite Sitemap`
where ifnull(parent_website_sitemap,'')=%s
and public_read=1 order by -idx desc, page_title asc""", pathname, as_dict=True)
# establish hierarchy
sitemap_options.parents = webnotes.conn.sql("""select name, page_title from `tabWebsite Sitemap`
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True)

if not sitemap_options.no_sidebar:
set_sidebar_items(sitemap_options.pathname)
if not sitemap_options.children:
set_sidebar_items(sitemap_options.parent_website_sitemap)

# determine templates to be used
if not sitemap_options.base_template_path:
sitemap_options.base_template_path = "templates/base.html"
return sitemap_options
def build_context(sitemap_options):
"""get_context method of bean or module is supposed to render content templates and push it into context"""
context = webnotes._dict(sitemap_options)
context.update(get_website_settings())
# provide bean
if context.doctype and context.docname:
context.bean = webnotes.bean(context.doctype, context.docname)
if context.controller:
module = webnotes.get_module(context.controller)
if module and hasattr(module, "get_context"):
context.update(module.get_context(context) or {})
if context.get("base_template_path") != context.get("template_path") and not context.get("rendered"):
context.data = render_blocks(context)
# remove bean, as it is not pickle friendly and its purpose is over
if context.bean:
del context["bean"]
return context
def can_cache(no_cache=False):
return not (webnotes.conf.disable_website_cache or no_cache)
def get_home_page():
home_page = webnotes.cache().get_value("home_page", \
lambda: (webnotes.get_hooks("home_page") \
or [webnotes.conn.get_value("Website Settings", None, "home_page") \
or "login"])[0])

return home_page
def get_website_settings():
# TODO Cache this
hooks = webnotes.get_hooks()
all_top_items = webnotes.conn.sql("""\
select * from `tabTop Bar Item`
where parent='Website Settings' and parentfield='top_bar_items'
order by idx asc""", as_dict=1)
top_items = [d for d in all_top_items if not d['parent_label']]
# attach child items to top bar
for d in all_top_items:
if d['parent_label']:
for t in top_items:
if t['label']==d['parent_label']:
if not 'child_items' in t:
t['child_items'] = []
t['child_items'].append(d)
break
context = webnotes._dict({
'top_bar_items': top_items,
'footer_items': webnotes.conn.sql("""\
select * from `tabTop Bar Item`
where parent='Website Settings' and parentfield='footer_items'
order by idx asc""", as_dict=1),
"post_login": [
{"label": "Reset Password", "url": "update-password", "icon": "icon-key"},
{"label": "Logout", "url": "?cmd=web_logout", "icon": "icon-signout"}
]
})
settings = webnotes.doc("Website Settings", "Website Settings")
for k in ["banner_html", "brand_html", "copyright", "twitter_share_via",
"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup"]:
if k in settings.fields:
context[k] = settings.fields.get(k)
if settings.address:
context["footer_address"] = settings.address

for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup"]:
context[k] = cint(context.get(k) or 0)
context.url = quote(str(get_request_site_address(full_address=True)), safe="/:")
context.encoded_title = quote(encode(context.title or ""), str(""))
for update_website_context in hooks.update_website_context or []:
webnotes.get_attr(update_website_context)(context)
context.web_include_js = hooks.web_include_js or []
context.web_include_css = hooks.web_include_css or []
return context
def is_ajax():
return webnotes.get_request_header("X-Requested-With")=="XMLHttpRequest"
def resolve_path(path):
if not path:
path = "index"
if path.endswith('.html'):
path = path[:-5]
if path == "index":
path = get_home_page()
return path

def set_content_type(data, path):
if isinstance(data, dict):
webnotes._response.headers[b"Content-Type"] = b"application/json; charset: utf-8"
data = json.dumps(data)
return data
webnotes._response.headers[b"Content-Type"] = b"text/html; charset: utf-8"
if "." in path and not path.endswith(".html"):
content_type, encoding = mimetypes.guess_type(path)
webnotes._response.headers[b"Content-Type"] = content_type.encode("utf-8")
return data

def clear_cache(path=None):
cache = webnotes.cache()
if path:
delete_page_cache(path)
else:
for p in webnotes.conn.sql_list("""select name from `tabWebsite Sitemap`"""):
if p is not None:
delete_page_cache(p)
cache.delete_value("home_page")
clear_permissions()
for method in webnotes.get_hooks("website_clear_cache"):
webnotes.get_attr(method)(path)

def delete_page_cache(path):
cache = webnotes.cache()
cache.delete_value("page:" + path)
cache.delete_value("page_context:" + path)
cache.delete_value("sitemap_options:" + path)
def is_signup_enabled():
if getattr(webnotes.local, "is_signup_enabled", None) is None:
webnotes.local.is_signup_enabled = True
if webnotes.utils.cint(webnotes.conn.get_value("Website Settings",
"Website Settings", "disable_signup")):
webnotes.local.is_signup_enabled = False
return webnotes.local.is_signup_enabled
def call_website_generator(bean, method, *args, **kwargs):
getattr(WebsiteGenerator(bean.doc, bean.doclist), method)(*args, **kwargs)
class WebsiteGenerator(DocListController):
def autoname(self):
from webnotes.webutils import cleanup_page_name
self.doc.name = cleanup_page_name(self.get_page_title())

def set_page_name(self):
"""set page name based on parent page_name and title"""
page_name = cleanup_page_name(self.get_page_title())

if self.doc.is_new():
self.doc.fields[self._website_config.page_name_field] = page_name
else:
webnotes.conn.set(self.doc, self._website_config.page_name_field, page_name)

def setup_generator(self):
self._website_config = webnotes.conn.get_values("Website Sitemap Config",
{"ref_doctype": self.doc.doctype}, "*")[0]

def on_update(self):
self.update_sitemap()
def after_rename(self, olddn, newdn, merge):
webnotes.conn.sql("""update `tabWebsite Sitemap`
set docname=%s where ref_doctype=%s and docname=%s""", (newdn, self.doc.doctype, olddn))
if merge:
self.setup_generator()
remove_sitemap(ref_doctype=self.doc.doctype, docname=olddn)
def on_trash(self):
self.setup_generator()
remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
def update_sitemap(self):
self.setup_generator()
if self._website_config.condition_field and \
not self.doc.fields.get(self._website_config.condition_field):
# condition field failed, remove and return!
remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
return
self.add_or_update_sitemap()
def add_or_update_sitemap(self):
page_name = self.get_page_name()
existing_site_map = webnotes.conn.get_value("Website Sitemap", {"ref_doctype": self.doc.doctype,
"docname": self.doc.name})
opts = webnotes._dict({
"page_or_generator": "Generator",
"ref_doctype":self.doc.doctype,
"docname": self.doc.name,
"page_name": page_name,
"link_name": self._website_config.name,
"lastmod": webnotes.utils.get_datetime(self.doc.modified).strftime("%Y-%m-%d"),
"parent_website_sitemap": self.doc.parent_website_sitemap,
"page_title": self.get_page_title(),
"public_read": 1 if not self._website_config.no_sidebar else 0
})

self.update_permissions(opts)
if existing_site_map:
update_sitemap(existing_site_map, opts)
else:
add_to_sitemap(opts)
def update_permissions(self, opts):
if self.meta.get_field("public_read"):
opts.public_read = self.doc.public_read
opts.public_write = self.doc.public_write
else:
opts.public_read = 1
def get_page_name(self):
if not self._get_page_name():
self.set_page_name()
return self._get_page_name()
def _get_page_name(self):
return self.doc.fields.get(self._website_config.page_name_field)
def get_page_title(self):
return self.doc.title or (self.doc.name.replace("-", " ").replace("_", " ").title())
def cleanup_page_name(title):
"""make page name from title"""
import re
name = title.lower()
name = re.sub('[~!@#$%^&*+()<>,."\'\?]', '', name)
name = re.sub('[:/]', '-', name)

name = '-'.join(name.split())

# replace repeating hyphens
name = re.sub(r"(-)\1+", r"\1", name)
return name

def get_hex_shade(color, percent):
def p(c):
v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
if v < 0:
v=0
if v > 255:
v=255
h = hex(v)[2:]
if len(h) < 2:
h = "0" + h
return h
r, g, b = color[0:2], color[2:4], color[4:6]
avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
# switch dark and light shades
if avg > 128:
percent = -percent

# stronger diff for darker shades
if percent < 25 and avg < 64:
percent = percent * 2
return p(r) + p(g) + p(b)

def render_blocks(context):
"""returns a dict of block name and its rendered content"""
from jinja2.utils import concat
from jinja2 import meta

out = {}
env = webnotes.get_jenv()
def _render_blocks(template_path):
source = webnotes.local.jloader.get_source(webnotes.local.jenv, template_path)[0]
for referenced_template_path in meta.find_referenced_templates(env.parse(source)):
if referenced_template_path:
_render_blocks(referenced_template_path)
template = webnotes.get_template(template_path)
for block, render in template.blocks.items():
out[block] = scrub_relative_urls(concat(render(template.new_context(context))))
_render_blocks(context["template_path"])

# default blocks if not found
if "title" not in out:
out["title"] = context.get("title")
if "header" not in out:
out["header"] = out["title"]
if not out["header"].startswith("<h"):
out["header"] = "<h2>" + out["header"] + "</h2>"
if "breadcrumbs" not in out:
out["breadcrumbs"] = scrub_relative_urls(
webnotes.get_template("templates/includes/breadcrumbs.html").render(context))
if "sidebar" not in out:
out["sidebar"] = scrub_relative_urls(
webnotes.get_template("templates/includes/sidebar.html").render(context))

return out

def scrub_relative_urls(html):
"""prepend a slash before a relative url"""
return re.sub("""(src|href)[^\w'"]*['"](?!http|ftp|/|#)([^'" >]+)['"]""", '\g<1> = "/\g<2>"', html)

Laden…
Annuleren
Opslaan