@@ -109,6 +109,7 @@ def init(site, sites_path=None): | |||||
local.restrictions = None | local.restrictions = None | ||||
local.user_perms = {} | local.user_perms = {} | ||||
local.test_objects = {} | local.test_objects = {} | ||||
local.jenv = None | |||||
setup_module_map() | setup_module_map() | ||||
@@ -544,11 +545,8 @@ def get_list(doctype, filters=None, fields=None, docstatus=None, | |||||
group_by=group_by, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length, | group_by=group_by, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length, | ||||
as_list=as_list, debug=debug) | as_list=as_list, debug=debug) | ||||
jenv = None | |||||
def get_jenv(): | def get_jenv(): | ||||
global jenv | |||||
if not jenv: | |||||
if not local.jenv: | |||||
from jinja2 import Environment, ChoiceLoader, PackageLoader, DebugUndefined | from jinja2 import Environment, ChoiceLoader, PackageLoader, DebugUndefined | ||||
import webnotes.utils | import webnotes.utils | ||||
@@ -567,7 +565,9 @@ def get_jenv(): | |||||
"_": _ | "_": _ | ||||
}) | }) | ||||
return jenv | |||||
local.jenv = jenv | |||||
return local.jenv | |||||
def set_filters(jenv): | def set_filters(jenv): | ||||
from webnotes.utils import global_date_format | from webnotes.utils import global_date_format | ||||
@@ -37,7 +37,7 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = | |||||
raise webnotes.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format( | raise webnotes.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format( | ||||
doctype=doctype, name=name)) | doctype=doctype, name=name)) | ||||
_send(doctype=doctype, name=name, content=content, subject=subject, sent_or_received=sent_or_received, | |||||
_make(doctype=doctype, name=name, content=content, subject=subject, sent_or_received=sent_or_received, | |||||
sender=sender, recipients=recipients, communication_medium=communication_medium, send_email=send_email, | sender=sender, recipients=recipients, communication_medium=communication_medium, send_email=send_email, | ||||
print_html=print_html, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, | print_html=print_html, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, | ||||
date=date) | date=date) | ||||
@@ -116,9 +116,13 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s | |||||
d.content = sent_via.get_content(d) | d.content = sent_via.get_content(d) | ||||
footer = set_portal_link(sent_via, d) | footer = set_portal_link(sent_via, d) | ||||
send_print_in_body = webnotes.conn.get_value("Email Settings", None, "send_print_in_body_and_attachment") | |||||
if not send_print_in_body: | |||||
d.content += "<p>Please see attachment for document details.</p>" | |||||
mail = get_email(d.recipients, sender=d.sender, subject=d.subject, | mail = get_email(d.recipients, sender=d.sender, subject=d.subject, | ||||
msg=d.content, footer=footer) | |||||
msg=d.content, footer=footer, print_html=print_html if send_print_in_body else None) | |||||
if send_me_a_copy: | if send_me_a_copy: | ||||
mail.cc.append(webnotes.conn.get_value("Profile", webnotes.session.user, "email")) | mail.cc.append(webnotes.conn.get_value("Profile", webnotes.session.user, "email")) | ||||
@@ -43,7 +43,7 @@ class DocType: | |||||
pass # email server not set, don't send email | pass # email server not set, don't send email | ||||
self.doc.new_password = "" | self.doc.new_password = "" | ||||
self.update_gravatar() | |||||
def check_enable_disable(self): | def check_enable_disable(self): | ||||
# do not allow disabling administrator/guest | # do not allow disabling administrator/guest | ||||
@@ -106,6 +106,15 @@ class DocType: | |||||
# owner is always name | # owner is always name | ||||
webnotes.conn.set(self.doc, 'owner', self.doc.name) | webnotes.conn.set(self.doc, 'owner', self.doc.name) | ||||
webnotes.clear_cache(user=self.doc.name) | webnotes.clear_cache(user=self.doc.name) | ||||
def update_gravatar(self): | |||||
import md5 | |||||
if not self.doc.user_image: | |||||
if self.doc.fb_username: | |||||
self.doc.user_image = "https://graph.facebook.com/" + self.doc.fb_username + "/picture" | |||||
else: | |||||
self.doc.user_image = "https://secure.gravatar.com/avatar/" + md5.md5(self.doc.name).hexdigest() \ | |||||
+ "?d=retro" | |||||
def reset_password(self): | def reset_password(self): | ||||
from webnotes.utils import random_string, get_url | from webnotes.utils import random_string, get_url | ||||
@@ -2,7 +2,7 @@ | |||||
{ | { | ||||
"creation": "2012-06-14 15:07:28", | "creation": "2012-06-14 15:07:28", | ||||
"docstatus": 0, | "docstatus": 0, | ||||
"modified": "2014-02-07 14:48:08", | |||||
"modified": "2014-02-07 14:50:08", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"owner": "Administrator" | "owner": "Administrator" | ||||
}, | }, | ||||
@@ -31,6 +31,7 @@ scheduler_event = all:webnotes.utils.email_lib.bulk.flush | |||||
scheduler_event = daily:webnotes.utils.email_lib.bulk.clear_outbox | scheduler_event = daily:webnotes.utils.email_lib.bulk.clear_outbox | ||||
scheduler_event = daily:webnotes.core.doctype.notification_count.notification_count.delete_event_notification_count | scheduler_event = daily:webnotes.core.doctype.notification_count.notification_count.delete_event_notification_count | ||||
scheduler_event = daily:webnotes.core.doctype.event.event.send_event_digest | scheduler_event = daily:webnotes.core.doctype.event.event.send_event_digest | ||||
scheduler_event = hourly:webnotes.templates.generator.website_group.clear_event_cache | |||||
on_session_creation = webnotes.auth.notify_administrator_login | on_session_creation = webnotes.auth.notify_administrator_login | ||||
@@ -274,22 +274,13 @@ wn.views.CommunicationComposer = Class.extend({ | |||||
}); | }); | ||||
}, | }, | ||||
send_email: function(btn, form_values, selected_attachments, print_format_html) { | |||||
send_email: function(btn, form_values, selected_attachments, print_html) { | |||||
var me = this; | var me = this; | ||||
if(form_values.attach_document_print) { | |||||
var print_html = print_format_html; | |||||
if(cint(wn.boot.send_print_in_body_and_attachment)) { | |||||
form_values.content = form_values.content | |||||
+ "<p></p><hr>" + print_html; | |||||
} else { | |||||
form_values.content = form_values.content + "<p>" | |||||
+ "Please see attachment for document details.</p>" | |||||
} | |||||
} else { | |||||
var print_html = ""; | |||||
if(!form_values.attach_document_print) { | |||||
print_html = ""; | |||||
} | } | ||||
if(form_values.send_email) { | if(form_values.send_email) { | ||||
if(cur_frm && !wn.model.can_email(me.doc.doctype, cur_frm)) { | if(cur_frm && !wn.model.can_email(me.doc.doctype, cur_frm)) { | ||||
msgprint(wn._("You are not allowed to send emails related to this document.")); | msgprint(wn._("You are not allowed to send emails related to this document.")); | ||||
@@ -60,7 +60,12 @@ | |||||
<div class="container page-container" id="page-{{ name or page_name }}"> | <div class="container page-container" id="page-{{ name or page_name }}"> | ||||
<div class="row"> | <div class="row"> | ||||
<div class="col-sm-3 col-sm-push-9 page-sidebar hidden-xs" data-html-block="sidebar"> | <div class="col-sm-3 col-sm-push-9 page-sidebar hidden-xs" data-html-block="sidebar"> | ||||
{%- block sidebar -%}{%- if sidebar is defined -%}{{ sidebar }}{%- endif -%}{%- endblock -%} | |||||
{%- block sidebar -%} | |||||
{%- if sidebar is defined -%} | |||||
{{ sidebar }} | |||||
{{ private_pages or "" }} | |||||
{%- endif -%} | |||||
{%- endblock -%} | |||||
</div> | </div> | ||||
<div class="col-sm-9 col-sm-pull-3 page-content" data-html-block="content"> | <div class="col-sm-9 col-sm-pull-3 page-content" data-html-block="content"> | ||||
<div class="text-right"><a class="visible-xs toggle-sidebar no-decoration"> | <div class="text-right"><a class="visible-xs toggle-sidebar no-decoration"> | ||||
@@ -8,14 +8,6 @@ | |||||
/* ------------------------------------- | /* ------------------------------------- | ||||
GLOBAL | GLOBAL | ||||
------------------------------------- */ | ------------------------------------- */ | ||||
* { | |||||
margin:0; | |||||
padding:0; | |||||
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; | |||||
font-size: 100%; | |||||
line-height: 1.6; | |||||
} | |||||
img { | img { | ||||
max-width: 100%; | max-width: 100%; | ||||
} | } | ||||
@@ -23,15 +15,26 @@ img { | |||||
body { | body { | ||||
-webkit-font-smoothing:antialiased; | -webkit-font-smoothing:antialiased; | ||||
-webkit-text-size-adjust:none; | -webkit-text-size-adjust:none; | ||||
width: 100%!important; | |||||
width: 100% !important; | |||||
height: 100%; | height: 100%; | ||||
} | |||||
.wrapper { | |||||
background-color: #eee; | background-color: #eee; | ||||
} | } | ||||
.wrapper * { | |||||
margin:0; | |||||
padding:0; | |||||
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; | |||||
font-size: 100%; | |||||
line-height: 1.6; | |||||
} | |||||
/* ------------------------------------- | /* ------------------------------------- | ||||
ELEMENTS | ELEMENTS | ||||
------------------------------------- */ | ------------------------------------- */ | ||||
a { | |||||
.wrapper a { | |||||
color: #348eda; | color: #348eda; | ||||
} | } | ||||
@@ -69,7 +72,7 @@ a { | |||||
margin-bottom: 0; | margin-bottom: 0; | ||||
} | } | ||||
.first{ | |||||
.first { | |||||
margin-top: 0; | margin-top: 0; | ||||
} | } | ||||
@@ -113,7 +116,9 @@ table.footer-wrap a{ | |||||
/* ------------------------------------- | /* ------------------------------------- | ||||
TYPOGRAPHY | TYPOGRAPHY | ||||
------------------------------------- */ | ------------------------------------- */ | ||||
h1,h2,h3{ | |||||
.wrapper h1, | |||||
.wrapper h2, | |||||
.wrapper h3{ | |||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; | font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; | ||||
line-height: 1.1; | line-height: 1.1; | ||||
margin-top:15px; | margin-top:15px; | ||||
@@ -123,26 +128,29 @@ h1,h2,h3{ | |||||
font-weight:200; | font-weight:200; | ||||
} | } | ||||
h1 { | |||||
.wrapper h1 { | |||||
font-size: 36px; | font-size: 36px; | ||||
} | } | ||||
h2 { | |||||
.wrapper h2 { | |||||
font-size: 28px; | font-size: 28px; | ||||
} | } | ||||
h3 { | |||||
.wrapper h3 { | |||||
font-size: 22px; | font-size: 22px; | ||||
} | } | ||||
hr { | |||||
.wrapper hr { | |||||
margin: 20px 0; | margin: 20px 0; | ||||
border-top: 1px solid #eee; | border-top: 1px solid #eee; | ||||
} | } | ||||
p, ul, ol { | |||||
.wrapper p, | |||||
.wrapper ul, | |||||
.wrapper ol { | |||||
margin-bottom: 10px; | margin-bottom: 10px; | ||||
font-weight: normal; | font-weight: normal; | ||||
font-size:14px; | font-size:14px; | ||||
} | } | ||||
ul li, ol li { | |||||
.wrapper ul li, | |||||
.wrapper ol li { | |||||
margin-left:5px; | margin-left:5px; | ||||
list-style-position: inside; | list-style-position: inside; | ||||
} | } | ||||
@@ -180,7 +188,9 @@ ul li, ol li { | |||||
</style> | </style> | ||||
</head> | </head> | ||||
<body bgcolor="#f6f6f6"> | |||||
<body> | |||||
<div class="wrapper"> | |||||
<!-- body --> | <!-- body --> | ||||
<table class="body-wrap"> | <table class="body-wrap"> | ||||
@@ -230,5 +240,9 @@ ul li, ol li { | |||||
</table> | </table> | ||||
<!-- /footer --> | <!-- /footer --> | ||||
</div> | |||||
<div class="print-html">{{ print_html }}</div> | |||||
</body> | </body> | ||||
</html> | </html> |
@@ -17,7 +17,6 @@ def get_context(context): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
group_context = get_group_context(group, view, bean, context) | group_context = get_group_context(group, view, bean, context) | ||||
group_context["access"] = get_access(group) | |||||
group_context.update(context) | group_context.update(context) | ||||
return group_context | return group_context | ||||
@@ -122,3 +121,7 @@ def clear_cache(page_name=None, website_group=None): | |||||
for group in website_groups: | for group in website_groups: | ||||
for view in get_views(group.group_type): | for view in get_views(group.group_type): | ||||
cache.delete_value("website_group_context:{}:{}".format(group.page_name, view)) | cache.delete_value("website_group_context:{}:{}".format(group.page_name, view)) | ||||
def clear_event_cache(): | |||||
for group in webnotes.conn.sql_list("""select name from `tabWebsite Group` where group_type='Event'"""): | |||||
clear_unit_views(website_group=group) |
@@ -9,12 +9,12 @@ import email.utils | |||||
from inlinestyler.utils import inline_css | from inlinestyler.utils import inline_css | ||||
def get_email(recipients, sender='', msg='', subject='[No Subject]', | def get_email(recipients, sender='', msg='', subject='[No Subject]', | ||||
text_content = None, footer=None, formatted=None): | |||||
text_content = None, footer=None, print_html=None, formatted=None): | |||||
"""send an html email as multipart with attachments and all""" | """send an html email as multipart with attachments and all""" | ||||
email = EMail(sender, recipients, subject) | email = EMail(sender, recipients, subject) | ||||
if (not '<br>' in msg) and (not '<p>' in msg) and (not '<div' in msg): | if (not '<br>' in msg) and (not '<p>' in msg) and (not '<div' in msg): | ||||
msg = msg.replace('\n', '<br>') | msg = msg.replace('\n', '<br>') | ||||
email.set_html(msg, text_content, footer=footer, formatted=formatted) | |||||
email.set_html(msg, text_content, footer=footer, print_html=print_html, formatted=formatted) | |||||
return email | return email | ||||
@@ -47,10 +47,10 @@ class EMail: | |||||
self.cc = [] | self.cc = [] | ||||
self.html_set = False | self.html_set = False | ||||
def set_html(self, message, text_content = None, footer=None, formatted=None): | |||||
def set_html(self, message, text_content = None, footer=None, print_html=None, formatted=None): | |||||
"""Attach message in the html portion of multipart/alternative""" | """Attach message in the html portion of multipart/alternative""" | ||||
if not formatted: | if not formatted: | ||||
formatted = get_formatted_html(self.subject, message, footer) | |||||
formatted = get_formatted_html(self.subject, message, footer, print_html) | |||||
# this is the first html part of a multi-part message, | # this is the first html part of a multi-part message, | ||||
# convert to text well | # convert to text well | ||||
@@ -68,12 +68,12 @@ class EMail: | |||||
Attach message in the text portion of multipart/alternative | Attach message in the text portion of multipart/alternative | ||||
""" | """ | ||||
from email.mime.text import MIMEText | from email.mime.text import MIMEText | ||||
part = MIMEText(message.encode('utf-8'), 'plain', 'utf-8') | |||||
part = MIMEText(message, 'plain', 'utf-8') | |||||
self.msg_multipart.attach(part) | self.msg_multipart.attach(part) | ||||
def set_part_html(self, message): | def set_part_html(self, message): | ||||
from email.mime.text import MIMEText | from email.mime.text import MIMEText | ||||
part = MIMEText(message.encode('utf-8'), 'html', 'utf-8') | |||||
part = MIMEText(message, 'html', 'utf-8') | |||||
self.msg_multipart.attach(part) | self.msg_multipart.attach(part) | ||||
def set_html_as_text(self, html): | def set_html_as_text(self, html): | ||||
@@ -191,13 +191,14 @@ class EMail: | |||||
self.make() | self.make() | ||||
return self.msg_root.as_string() | return self.msg_root.as_string() | ||||
def get_formatted_html(subject, message, footer=None): | |||||
def get_formatted_html(subject, message, footer=None, print_html=None): | |||||
message = scrub_urls(message) | message = scrub_urls(message) | ||||
return inline_css(webnotes.get_template("templates/emails/standard.html").render({ | return inline_css(webnotes.get_template("templates/emails/standard.html").render({ | ||||
"content": message, | "content": message, | ||||
"footer": get_footer(footer), | "footer": get_footer(footer), | ||||
"title": subject | |||||
"title": subject, | |||||
"print_html": print_html | |||||
})) | })) | ||||
def get_footer(footer=None): | def get_footer(footer=None): | ||||
@@ -91,13 +91,24 @@ def get_context(page_name): | |||||
if can_cache(): | if can_cache(): | ||||
context = webnotes.cache().get_value(cache_key) | context = webnotes.cache().get_value(cache_key) | ||||
access = get_access(page_name) | |||||
if not context: | if not context: | ||||
sitemap_options = get_sitemap_options(page_name) | |||||
context = build_context(sitemap_options) | |||||
context = get_sitemap_options(page_name) | |||||
# permission may be required for rendering | |||||
context["access"] = access | |||||
context = build_context(context) | |||||
if can_cache(context.no_cache): | if can_cache(context.no_cache): | ||||
del context["access"] | |||||
webnotes.cache().set_value(cache_key, context) | webnotes.cache().set_value(cache_key, context) | ||||
context["access"] = access | |||||
context.update(context.data or {}) | context.update(context.data or {}) | ||||
# TODO private pages | |||||
return context | return context | ||||
def get_sitemap_options(page_name): | def get_sitemap_options(page_name): | ||||
@@ -133,8 +144,8 @@ def build_sitemap_options(page_name): | |||||
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True) | where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True) | ||||
sitemap_options.children = webnotes.conn.sql("""select * from `tabWebsite Sitemap` | sitemap_options.children = webnotes.conn.sql("""select * from `tabWebsite Sitemap` | ||||
where parent_website_sitemap=%s""", (sitemap_options.page_name,), as_dict=True) | |||||
where parent_website_sitemap=%s and public_read=1""", (sitemap_options.page_name,), as_dict=True) | |||||
# determine templates to be used | # determine templates to be used | ||||
if not sitemap_options.base_template_path: | if not sitemap_options.base_template_path: | ||||
sitemap_options.base_template_path = "templates/base.html" | sitemap_options.base_template_path = "templates/base.html" | ||||