@@ -683,13 +683,13 @@ def format_value(value, df, doc=None): | |||
return frappe.utils.formatters.format_value(value, df, doc) | |||
def get_print_format(doctype, name, print_format=None, style=None, as_pdf=False): | |||
from frappe.website.render import render_page | |||
from frappe.website.render import build_page | |||
local.form_dict.doctype = doctype | |||
local.form_dict.name = name | |||
local.form_dict.format = print_format | |||
local.form_dict.name = name | |||
local.form_dict.style = style | |||
html = render_page("print") | |||
html = build_page("print") | |||
if as_pdf: | |||
print_settings = db.get_singles_dict("Print Settings") | |||
@@ -34,7 +34,7 @@ class Communication(Document): | |||
@frappe.whitelist() | |||
def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", | |||
sender=None, recipients=None, communication_medium="Email", send_email=False, | |||
print_html=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): | |||
print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): | |||
if doctype and name and not frappe.has_permission(doctype, "email", name): | |||
raise frappe.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format( | |||
@@ -42,12 +42,12 @@ def make(doctype=None, name=None, content=None, subject=None, 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, | |||
print_html=print_html, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, | |||
print_html=print_html, print_format=print_format, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, | |||
date=date) | |||
def _make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", | |||
sender=None, recipients=None, communication_medium="Email", send_email=False, | |||
print_html=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): | |||
print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): | |||
# add to Communication | |||
sent_via = None | |||
@@ -89,7 +89,7 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received | |||
if send_email: | |||
d = comm | |||
send_comm_email(d, name, sent_via, print_html, attachments, send_me_a_copy) | |||
send_comm_email(d, name, sent_via, print_html, print_format, attachments, send_me_a_copy) | |||
@frappe.whitelist() | |||
def get_customer_supplier(args=None): | |||
@@ -110,7 +110,7 @@ def get_customer_supplier(args=None): | |||
} | |||
return {} | |||
def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', send_me_a_copy=False): | |||
def send_comm_email(d, name, sent_via=None, print_html=None, print_format=None, attachments='[]', send_me_a_copy=False): | |||
footer = None | |||
@@ -130,26 +130,8 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s | |||
if send_me_a_copy: | |||
mail.cc.append(frappe.db.get_value("User", frappe.session.user, "email")) | |||
if print_html: | |||
print_html = scrub_urls(print_html) | |||
print_settings = frappe.get_singles_dict("Print Settings") | |||
send_print_as_pdf = cint(print_settings.send_print_as_pdf) | |||
if send_print_as_pdf: | |||
try: | |||
options = { | |||
'page-size': print_settings.pdf_page_size or 'A4' | |||
} | |||
mail.add_pdf_attachment(name.replace(' ','').replace('/','-') + '.pdf', print_html, | |||
options=options) | |||
except Exception: | |||
frappe.msgprint(_("Error generating PDF, attachment sent as HTML")) | |||
send_print_as_pdf = 0 | |||
if not send_print_as_pdf: | |||
mail.add_attachment(name.replace(' ','').replace('/','-') + '.html', | |||
print_html, 'text/html') | |||
if print_html or print_format: | |||
attach_print(mail, sent_via, print_html, print_format) | |||
for a in json.loads(attachments): | |||
try: | |||
@@ -159,6 +141,27 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s | |||
send(mail) | |||
def attach_print(mail, sent_via, print_html, print_format): | |||
name = sent_via.name | |||
if not print_html and print_format: | |||
print_html = frappe.get_print_format(sent_via.doctype, sent_via.name, print_format) | |||
print_settings = frappe.db.get_singles_dict("Print Settings") | |||
send_print_as_pdf = cint(print_settings.send_print_as_pdf) | |||
if send_print_as_pdf: | |||
try: | |||
mail.add_pdf_attachment(name.replace(' ','').replace('/','-') + '.pdf', print_html) | |||
except Exception: | |||
frappe.msgprint(_("Error generating PDF, attachment sent as HTML")) | |||
frappe.errprint(frappe.get_traceback()) | |||
send_print_as_pdf = 0 | |||
if not send_print_as_pdf: | |||
print_html = scrub_urls(print_html) | |||
mail.add_attachment(name.replace(' ','').replace('/','-') + '.html', | |||
print_html, 'text/html') | |||
def set_portal_link(sent_via, comm): | |||
"""set portal link in footer""" | |||
@@ -11,6 +11,7 @@ | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"default": "1", | |||
"description": "Send Email Print Attachments as PDF (Recommended)", | |||
"fieldname": "send_print_as_pdf", | |||
"fieldtype": "Check", | |||
@@ -32,6 +33,7 @@ | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"default": "", | |||
"fieldname": "print_style", | |||
"fieldtype": "Select", | |||
"in_list_view": 1, | |||
@@ -48,7 +50,7 @@ | |||
], | |||
"icon": "icon-cog", | |||
"issingle": 1, | |||
"modified": "2014-07-17 08:08:27.291811", | |||
"modified": "2014-07-23 04:59:45.626239", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "Print Settings", | |||
@@ -41,7 +41,7 @@ execute:frappe.reset_perms("User") #2014-06-13 | |||
execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')=''""") #2014-06-17 | |||
frappe.patches.v4_0.remove_user_owner_custom_field | |||
execute:frappe.delete_doc("DocType", "Website Template") | |||
execute:frappe.reload_doc('website', 'doctype', 'website_route') #20114-06-17 | |||
execute:frappe.reload_doc('website', 'doctype', 'website_route') #2014-06-17 | |||
execute:frappe.db.sql("""update `tabProperty Setter` set property_type='Text' where property in ('options', 'default')""") #2014-06-20 | |||
frappe.patches.v4_1.enable_outgoing_email_settings | |||
execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04 | |||
@@ -6,10 +6,21 @@ import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "print_settings") | |||
frappe.db.set_value("Print Settings", "Print Settings", "print_style", "Modern") | |||
print_settings = frappe.get_doc("Print Settings") | |||
print_settings.print_style = "Modern" | |||
try: | |||
import pdfkit | |||
except ImportError: | |||
pass | |||
else: | |||
frappe.db.set_value("Print Settings", "Print Settings", "send_print_as_pdf", 1) | |||
# if someone has already configured in Outgoing Email Settings | |||
outgoing_email_settings = frappe.db.get_singles_dict("Outgoing Email Settings") | |||
if "send_print_as_pdf" in outgoing_email_settings: | |||
print_settings.send_print_as_pdf = outgoing_email_settings.send_print_as_pdf | |||
print_settings.pdf_page_size = outgoing_email_settings.pdf_page_size | |||
else: | |||
print_settings.send_print_as_pdf = 1 | |||
print_settings.save() |
@@ -189,9 +189,9 @@ th { | |||
} | |||
@media print { | |||
* { | |||
color: #000 !important; | |||
/* color: #000 !important;*/ | |||
text-shadow: none !important; | |||
background: transparent !important; | |||
/* background: transparent !important;*/ | |||
-webkit-box-shadow: none !important; | |||
box-shadow: none !important; | |||
} | |||
@@ -211,7 +211,7 @@ th { | |||
} | |||
pre, | |||
blockquote { | |||
border: 1px solid #999; | |||
/* border: 1px solid #999;*/ | |||
page-break-inside: avoid; | |||
} | |||
@@ -241,24 +241,24 @@ th { | |||
.navbar { | |||
display: none; | |||
} | |||
.table td, | |||
/* .table td, | |||
.table th { | |||
background-color: #fff !important; | |||
} | |||
.btn > .caret, | |||
*/ .btn > .caret, | |||
.dropup > .btn > .caret { | |||
border-top-color: #000 !important; | |||
} | |||
.label { | |||
/* .label { | |||
border: 1px solid #000; | |||
} | |||
.table { | |||
*/ .table { | |||
border-collapse: collapse !important; | |||
} | |||
.table-bordered th, | |||
/*.table-bordered th, | |||
.table-bordered td { | |||
border: 1px solid #ddd !important; | |||
} | |||
}*/ | |||
} | |||
@font-face { | |||
font-family: 'Glyphicons Halflings'; | |||
@@ -17,6 +17,7 @@ frappe.ui.form.PrintPreview = Class.extend({ | |||
<div class="checkbox"><label><input type="checkbox" class="print-letterhead" checked/> Letterhead</label></div></div>\ | |||
<div class="col-xs-6 text-right" style="padding-top: 7px;">\ | |||
<a style="margin-right: 7px;" class="btn-print-preview text-muted small">Preview</a>\ | |||
<a style="margin-right: 7px;" class="btn-download-pdf text-muted small">Download PDF</a>\ | |||
<strong><a style="margin-right: 7px;" class="btn-print-print">Print</a></strong>\ | |||
<a class="close">×</a>\ | |||
</div>\ | |||
@@ -42,11 +43,13 @@ frappe.ui.form.PrintPreview = Class.extend({ | |||
.find(".print-preview-select") | |||
.on("change", function() { | |||
if(me.is_old_style()) { | |||
me.wrapper.find(".btn-download-pdf").toggle(false); | |||
me.preview_old_style(); | |||
} else { | |||
me.wrapper.find(".btn-download-pdf").toggle(true); | |||
me.preview(); | |||
} | |||
}) | |||
}); | |||
this.wrapper.find(".btn-print-print").click(function() { | |||
if(me.is_old_style()) { | |||
@@ -63,6 +66,18 @@ frappe.ui.form.PrintPreview = Class.extend({ | |||
me.new_page_preview(); | |||
} | |||
}); | |||
this.wrapper.find(".btn-download-pdf").click(function() { | |||
if(!me.is_old_style()) { | |||
var w = window.open("/api/method/frappe.templates.pages.print.download_pdf?" | |||
+"doctype="+encodeURIComponent(me.frm.doc.doctype) | |||
+"&name="+encodeURIComponent(me.frm.doc.name) | |||
+"&format="+me.selected_format()); | |||
if(!w) { | |||
msgprint(__("Please enable pop-ups")); return; | |||
} | |||
} | |||
}); | |||
}, | |||
preview: function() { | |||
var me = this; | |||
@@ -102,14 +117,24 @@ frappe.ui.form.PrintPreview = Class.extend({ | |||
}); | |||
}, | |||
preview_old_style: function() { | |||
var me = this; | |||
this.with_old_style({ | |||
format: me.print_sel.val(), | |||
callback: function(html) { | |||
me.wrapper.find(".print-format").html('<div class="alert alert-warning">' | |||
+__("Warning: This Print Format is in old style and cannot be generated via the API.") | |||
+'</div>' | |||
+ html); | |||
}, | |||
no_letterhead: !this.with_letterhead(), | |||
only_body: true, | |||
no_heading: true | |||
}); | |||
}, | |||
with_old_style: function(opts) { | |||
var me = this; | |||
frappe.require("/assets/js/print_format_v3.min.js"); | |||
_p.build(me.print_sel.val(), function(html) { | |||
me.wrapper.find(".print-format").html('<div class="alert alert-warning">' | |||
+__("Warning: This Print Format is in old style and cannot be generated via the API.") | |||
+'</div>' | |||
+ html); | |||
}, !this.with_letterhead(), true, true); | |||
_p.build(opts.format, opts.callback, opts.no_letterhead, opts.only_body, opts.no_heading); | |||
}, | |||
print_old_style: function() { | |||
frappe.require("/assets/js/print_format_v3.min.js"); | |||
@@ -124,11 +149,14 @@ frappe.ui.form.PrintPreview = Class.extend({ | |||
selected_format: function() { | |||
return this.print_sel.val(); | |||
}, | |||
is_old_style: function() { | |||
return this.get_print_format().print_format_type==="Client" | |||
is_old_style: function(format) { | |||
return this.get_print_format(format).print_format_type==="Client"; | |||
}, | |||
get_print_format: function() { | |||
var format = this.selected_format(); | |||
get_print_format: function(format) { | |||
if (!format) { | |||
format = this.selected_format(); | |||
} | |||
if(locals["Print Format"] && locals["Print Format"][format]) { | |||
return locals["Print Format"][format] | |||
} else { | |||
@@ -264,8 +264,8 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
if (cur_frm) { | |||
$(fields.select_print_format.input) | |||
.empty() | |||
.add_options(cur_frm.print_formats) | |||
.val(cur_frm.print_formats[0]); | |||
.add_options(cur_frm.print_preview.print_formats) | |||
.val(cur_frm.print_preview.print_formats[0]); | |||
} else { | |||
$(fields.attach_document_print.wrapper).toggle(false); | |||
} | |||
@@ -324,20 +324,29 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
}) | |||
if(form_values.attach_document_print) { | |||
_p.build(form_values.select_print_format || "", function(print_format_html) { | |||
me.send_email(btn, form_values, selected_attachments, print_format_html); | |||
}); | |||
if (cur_frm.print_preview.is_old_style(form_values.select_print_format || "")) { | |||
cur_frm.print_preview.with_old_style({ | |||
format: form_values.select_print_format, | |||
callback: function(print_html) { | |||
me.send_email(btn, form_values, selected_attachments, print_html); | |||
} | |||
}); | |||
} else { | |||
me.send_email(btn, form_values, selected_attachments, null, form_values.select_print_format || ""); | |||
} | |||
} else { | |||
me.send_email(btn, form_values, selected_attachments); | |||
} | |||
}); | |||
}, | |||
send_email: function(btn, form_values, selected_attachments, print_html) { | |||
send_email: function(btn, form_values, selected_attachments, print_html, print_format) { | |||
var me = this; | |||
if(!form_values.attach_document_print) { | |||
print_html = ""; | |||
print_html = null; | |||
print_format = null; | |||
} | |||
if(form_values.send_email) { | |||
@@ -362,6 +371,7 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
send_me_a_copy: form_values.send_me_a_copy, | |||
send_email: form_values.send_email, | |||
print_html: print_html, | |||
print_format: print_format, | |||
communication_medium: form_values.communication_medium, | |||
sent_or_received: form_values.sent_or_received, | |||
attachments: selected_attachments | |||
@@ -86,7 +86,7 @@ $.extend(_p, { | |||
dialog.onshow = function() { | |||
var $print = dialog.fields_dict.print_format.$input; | |||
$print.empty().add_options(cur_frm.print_formats); | |||
$print.empty().add_options(cur_frm.print_preview.print_formats); | |||
if(cur_frm.$print_view_select && cur_frm.$print_view_select.val()) | |||
$print.val(cur_frm.$print_view_select.val()); | |||
@@ -3,12 +3,13 @@ | |||
from __future__ import unicode_literals | |||
import frappe, os, copy, json | |||
import frappe, os, copy, json, re | |||
from frappe import _ | |||
from frappe.modules import get_doc_path | |||
from jinja2 import TemplateNotFound | |||
from frappe.utils import cint | |||
from frappe.utils.pdf import get_pdf | |||
no_cache = 1 | |||
no_sitemap = 1 | |||
@@ -29,13 +30,6 @@ def get_context(context): | |||
doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name) | |||
for ptype in ("read", "print"): | |||
if not frappe.has_permission(doc.doctype, ptype, doc): | |||
return { | |||
"body": """<h1>Error</h1> | |||
<p>No {ptype} permission</p>""".format(ptype=ptype) | |||
} | |||
meta = frappe.get_meta(doc.doctype) | |||
return { | |||
@@ -59,6 +53,8 @@ def get_html(doc, name=None, print_format=None, meta=None, | |||
if isinstance(doc, basestring): | |||
doc = frappe.get_doc(json.loads(doc)) | |||
validate_print_permission(doc) | |||
if hasattr(doc, "before_print"): | |||
doc.before_print() | |||
@@ -88,6 +84,18 @@ def get_html(doc, name=None, print_format=None, meta=None, | |||
return html | |||
@frappe.whitelist() | |||
def download_pdf(doctype, name, format=None): | |||
html = frappe.get_print_format(doctype, name, format) | |||
frappe.local.response.filename = "{name}.pdf".format(name=name.replace(" ", "-").replace("/", "-")) | |||
frappe.local.response.filecontent = get_pdf(html) | |||
frappe.local.response.type = "download" | |||
def validate_print_permission(doc): | |||
for ptype in ("read", "print"): | |||
if not frappe.has_permission(doc.doctype, ptype, doc): | |||
raise frappe.PermissionError(_("No {0} permission").format(ptype)) | |||
def get_letter_head(doc, no_letterhead): | |||
if no_letterhead: | |||
return "" | |||
@@ -168,12 +176,21 @@ def is_visible(df): | |||
def get_print_style(style=None): | |||
if not style: | |||
style = frappe.db.get_default("print_style") or "Standard" | |||
style = frappe.db.get_single_value("Print Settings", "print_style") or "Standard" | |||
css = frappe.get_template("templates/styles/standard.css").render() | |||
try: | |||
css += frappe.get_template("templates/styles/" + style.lower() + ".css").render() | |||
additional_css = frappe.get_template("templates/styles/" + style.lower() + ".css").render() | |||
# move @import to top | |||
for at_import in list(set(re.findall("(@import url\([^\)]+\)[;]?)", additional_css))): | |||
additional_css = additional_css.replace(at_import, "") | |||
# prepend css with at_import | |||
css = at_import + css | |||
css += additional_css | |||
except TemplateNotFound: | |||
pass | |||
@@ -8,7 +8,7 @@ | |||
{% for section in page %} | |||
<div class="row"> | |||
{% for column in section %} | |||
<div class="col-sm-{{ (12 / section|len)|int }}"> | |||
<div class="col-xs-{{ (12 / section|len)|int }}"> | |||
{% for df in column %} | |||
{{ render_field(df, doc) }} | |||
{% endfor %} | |||
@@ -49,13 +49,13 @@ | |||
{%- macro render_field_with_label(df, doc) -%} | |||
<div class="row"> | |||
<div class="col-sm-5 text-right"> | |||
<div class="col-xs-5 text-right"> | |||
{% if df.fieldtype not in ("Image","HTML") and | |||
doc.get(df.fieldname) != None %} | |||
<label>{{ df.label }}</label> | |||
{% endif %} | |||
</div> | |||
<div class="col-sm-7 {%- if df.fieldtype | |||
<div class="col-xs-7 {%- if df.fieldtype | |||
in ('Int', 'Check', 'Float', 'Currency') %} text-right{% endif %}"> | |||
{% if doc.get(df.fieldname) != None -%} | |||
{{ print_value(df, doc) }}{% endif %} | |||
@@ -75,9 +75,9 @@ | |||
{%- macro print_value(df, doc, parent_doc=None) -%} | |||
{% if df.fieldtype=="Check" %} | |||
<i class="{{ 'icon-check' if doc[df.fieldname] else 'icon-check-empty' }}"></i> | |||
<i class="{{ 'icon-check' if doc[df.fieldname] else 'icon-check-empty' }}"></i> | |||
{% elif df.fieldtype=="Image" %} | |||
<img src="{{ doc[doc.meta.get_field(df.fieldname).options] }}" class="img-responsive"> | |||
<img src="{{ doc[doc.meta.get_field(df.fieldname).options] }}" class="img-responsive"> | |||
{% else %} | |||
{{ doc.get_formatted(df.fieldname, parent_doc or doc) }} | |||
{% endif %} | |||
@@ -1,3 +1,5 @@ | |||
@import url(http://fonts.googleapis.com/css?family=Noto+Serif:400,700); | |||
/* | |||
common style for whole page | |||
This should include: | |||
@@ -12,5 +14,5 @@ | |||
.print-format h2, | |||
.print-format h3, | |||
.print-format h4 { | |||
font-family: serif; | |||
font-family: 'Noto Serif', serif; | |||
} |
@@ -1,3 +1,5 @@ | |||
@import url(http://fonts.googleapis.com/css?family=Noto+Sans:400,700); | |||
@media screen { | |||
.print-format-gutter { | |||
background-color: #ddd; | |||
@@ -26,8 +28,16 @@ | |||
} | |||
} | |||
@media print { | |||
.print-format p { | |||
margin-left: 1px; | |||
margin-right: 1px; | |||
} | |||
} | |||
.print-format { | |||
font-size: 9pt; | |||
-webkit-print-color-adjust:exact; | |||
} | |||
.page-break { | |||
@@ -49,4 +59,3 @@ | |||
table.no-border, table.no-border td { | |||
border: 0px; | |||
} | |||
@@ -348,9 +348,17 @@ def fmt_money(amount, precision=None, currency=None): | |||
""" | |||
Convert to string with commas for thousands, millions etc | |||
""" | |||
number_format = frappe.db.get_default("number_format") or "#,###.##" | |||
decimal_str, comma_str, precision = get_number_format_info(number_format) | |||
number_format = None | |||
if currency: | |||
number_format = frappe.db.get_value("Currency", currency, "number_format") | |||
if not number_format: | |||
number_format = frappe.db.get_default("number_format") or "#,###.##" | |||
decimal_str, comma_str, number_format_precision = get_number_format_info(number_format) | |||
if not precision: | |||
precision = number_format_precision | |||
amount = '%.*f' % (precision, flt(amount)) | |||
if amount.find('.') == -1: | |||
@@ -17,7 +17,7 @@ def get_email(recipients, sender='', msg='', subject='[No Subject]', | |||
msg = markdown(msg) | |||
emailobj.set_html(msg, text_content, footer=footer, print_html=print_html, formatted=formatted) | |||
for attach in attachments: | |||
for attach in (attachments or []): | |||
emailobj.add_attachment(**attach) | |||
return emailobj | |||
@@ -14,7 +14,7 @@ def format_value(value, df, doc=None): | |||
currency=get_field_currency(df, doc) if doc else None) | |||
elif df.fieldtype == "Float": | |||
return fmt_money(value) | |||
return fmt_money(value, precision=get_field_precision(df, doc)) | |||
elif df.fieldtype == "Percent": | |||
return "{}%".format(flt(value, 2)) | |||
@@ -2,13 +2,28 @@ | |||
# MIT License. See license.txt | |||
import pdfkit, os, frappe | |||
from frappe.utils import scrub_urls | |||
def get_pdf(html, options=None): | |||
if not options: | |||
options = {} | |||
options.update({ | |||
"print-media-type": None, | |||
"background": None, | |||
"images": None, | |||
'margin-top': '15mm', | |||
'margin-right': '15mm', | |||
'margin-bottom': '15mm', | |||
'margin-left': '15mm', | |||
'encoding': "UTF-8", | |||
'no-outline': None | |||
}) | |||
if not options.get("page-size"): | |||
options['page-size'] = frappe.df.get_single_value("Print Settings", "pdf_page_size") or "A4" | |||
options['page-size'] = frappe.db.get_single_value("Print Settings", "pdf_page_size") or "A4" | |||
html = scrub_urls(html) | |||
fname = os.path.join("/tmp", frappe.generate_hash() + ".pdf") | |||
pdfkit.from_string(html, fname, options=options or {}) | |||
@@ -49,7 +49,7 @@ def as_csv(): | |||
def as_raw(): | |||
response = Response() | |||
response.headers[b"Content-Type"] = mimetypes.guess_type(frappe.response['filename'])[0] or b"application/unknown" | |||
response.headers[b"Content-Type"] = frappe.response.get("content_type") or mimetypes.guess_type(frappe.response['filename'])[0] or b"application/unknown" | |||
response.headers[b"Content-Disposition"] = ("filename=%s" % frappe.response['filename'].replace(' ', '_')).encode("utf-8") | |||
response.data = frappe.response['filecontent'] | |||
return response | |||
@@ -3,6 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.utils import cstr | |||
import mimetypes, json | |||
from werkzeug.wrappers import Response | |||
@@ -49,7 +50,7 @@ def render(path, http_status_code=None): | |||
def render_403(e): | |||
path = "message" | |||
frappe.local.message = "Did you log out?" | |||
frappe.local.message = "<p><strong>{error}</strong></p><p>Did you log out?</p>".format(error=cstr(e)) | |||
frappe.local.message_title = "Not Permitted" | |||
return render_page(path), e.http_status_code | |||