diff --git a/frappe/__init__.py b/frappe/__init__.py index 1b93302cce..cf3f2583c8 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template -__version__ = '7.1.19' +__version__ = '7.1.20' __title__ = "Frappe Framework" local = Local() @@ -1152,7 +1152,7 @@ def format(*args, **kwargs): import frappe.utils.formatters return frappe.utils.formatters.format_value(*args, **kwargs) -def get_print(doctype=None, name=None, print_format=None, style=None, html=None, as_pdf=False, doc=None): +def get_print(doctype=None, name=None, print_format=None, style=None, html=None, as_pdf=False, doc=None, output = None): """Get Print Format for given document. :param doctype: DocType of document. @@ -1173,7 +1173,7 @@ def get_print(doctype=None, name=None, print_format=None, style=None, html=None, html = build_page("print") if as_pdf: - return get_pdf(html) + return get_pdf(html, output = output) else: return html diff --git a/frappe/commands/scheduler.py b/frappe/commands/scheduler.py index 3b2e81c44b..c7b0b30d38 100755 --- a/frappe/commands/scheduler.py +++ b/frappe/commands/scheduler.py @@ -145,15 +145,6 @@ def purge_jobs(site=None, queue=None, event=None): count = purge_pending_jobs(event=event, site=site, queue=queue) print "Purged {} jobs".format(count) -@click.command('dump-queue-status') -def dump_queue_status(): - "Dump detailed diagnostic infomation for task queues in JSON format" - frappe.init('') - from frappe.utils.doctor import dump_queue_status as _dump_queue_status, inspect_queue - print json.dumps(_dump_queue_status(), indent=1) - inspect_queue() - - @click.command('schedule') def start_scheduler(): from frappe.utils.scheduler import start_scheduler @@ -192,7 +183,6 @@ def ready_for_migration(context, site=None): commands = [ disable_scheduler, doctor, - dump_queue_status, enable_scheduler, purge_jobs, ready_for_migration, diff --git a/frappe/config/desk.py b/frappe/config/desk.py index 229336c971..0975136596 100644 --- a/frappe/config/desk.py +++ b/frappe/config/desk.py @@ -7,6 +7,11 @@ def get_data(): "label": _("Tools"), "icon": "octicon octicon-briefcase", "items": [ + { + "type": "doctype", + "name": "Newsletter", + "description": _("Newsletters to contacts, leads."), + }, { "type": "doctype", "name": "ToDo", diff --git a/frappe/config/setup.py b/frappe/config/setup.py index 07b96ea85f..2bdeddb564 100644 --- a/frappe/config/setup.py +++ b/frappe/config/setup.py @@ -144,11 +144,6 @@ def get_data(): "name": "Standard Reply", "description": _("Standard replies to common queries.") }, - { - "type": "doctype", - "name": "Newsletter", - "description": _("Newsletters to contacts, leads."), - }, { "type": "doctype", "name": "Email Group", diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 9e34dbb876..2b18c16a0e 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -231,6 +231,10 @@ def on_doctype_update(): frappe.db.add_index("Communication", ["modified"]) def has_permission(doc, ptype, user): - if ptype=="read" and doc.reference_doctype and doc.reference_name: - if frappe.has_permission(doc.reference_doctype, ptype="read", doc=doc.reference_name): - return True + if ptype=="read": + if doc.reference_doctype and doc.reference_name: + if frappe.has_permission(doc.reference_doctype, ptype="read", doc=doc.reference_name): + return True + if doc.timeline_doctype and doc.timeline_name: + if frappe.has_permission(doc.timeline_doctype, ptype="read", doc=doc.timeline_name): + return True diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.js b/frappe/email/doctype/auto_email_report/auto_email_report.js index 456ddff18f..019cdc6a52 100644 --- a/frappe/email/doctype/auto_email_report/auto_email_report.js +++ b/frappe/email/doctype/auto_email_report/auto_email_report.js @@ -4,7 +4,7 @@ frappe.ui.form.on('Auto Email Report', { refresh: function(frm) { if(frm.doc.report_type !== 'Report Builder') { - if(frm.script_setup_for !== frm.doc.report) { + if(frm.script_setup_for !== frm.doc.report && !frm.doc.__islocal) { frappe.call({ method:"frappe.desk.query_report.get_script", args: { diff --git a/frappe/utils/pdf.py b/frappe/utils/pdf.py index 2cd778034f..c56ea8e483 100644 --- a/frappe/utils/pdf.py +++ b/frappe/utils/pdf.py @@ -6,17 +6,20 @@ import pdfkit, os, frappe from frappe.utils import scrub_urls from frappe import _ from bs4 import BeautifulSoup +from pyPdf import PdfFileWriter, PdfFileReader -def get_pdf(html, options=None): +def get_pdf(html, options=None, output = None): html = scrub_urls(html) html, options = prepare_options(html, options) fname = os.path.join("/tmp", "frappe-pdf-{0}.pdf".format(frappe.generate_hash())) try: pdfkit.from_string(html, fname, options=options or {}) - - with open(fname, "rb") as fileobj: - filedata = fileobj.read() + if output: + append_pdf(PdfFileReader(file(fname,"rb")),output) + else: + with open(fname, "rb") as fileobj: + filedata = fileobj.read() except IOError, e: if ("ContentNotFoundError" in e.message @@ -37,9 +40,15 @@ def get_pdf(html, options=None): finally: cleanup(fname, options) + if output: + return output return filedata +def append_pdf(input,output): + # Merging multiple pdf files + [output.addPage(input.getPage(page_num)) for page_num in range(input.numPages)] + def prepare_options(html, options): if not options: options = {} diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index 5160ff985c..3602c13d3d 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -7,6 +7,7 @@ from frappe.modules import get_doc_path from jinja2 import TemplateNotFound from frappe.utils import cint, strip_html from frappe.utils.pdf import get_pdf +from pyPdf import PdfFileWriter, PdfFileReader no_cache = 1 no_sitemap = 1 @@ -17,31 +18,28 @@ standard_format = "templates/print_formats/standard.html" @frappe.whitelist() def download_multi_pdf(doctype, name, format=None): # name can include names of many docs of the same doctype. - totalhtml = "" - # Pagebreak to be added between each doc html - pagebreak = """

""" - - options = {} import json result = json.loads(name) - # Get html of each doc and combine including page breaks + + # Concatenating pdf files + output = PdfFileWriter() for i, ss in enumerate(result): - html = frappe.get_print(doctype, ss, format) - if i == len(result)-1: - totalhtml = totalhtml + html - else: - totalhtml = totalhtml + html + pagebreak + output = frappe.get_print(doctype, ss, format, as_pdf = True, output = output) frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) + frappe.local.response.filecontent = read_multi_pdf(output) + frappe.local.response.type = "download" - # Title of pdf - options.update({ - 'title': doctype, - }) +def read_multi_pdf(output): + # Get the content of the merged pdf files + fname = os.path.join("/tmp", "frappe-pdf-{0}.pdf".format(frappe.generate_hash())) + output.write(open(fname,"wb")) - frappe.local.response.filecontent = get_pdf(totalhtml, options) - frappe.local.response.type = "download" + with open(fname, "rb") as fileobj: + filedata = fileobj.read() + + return filedata @frappe.whitelist() def download_pdf(doctype, name, format=None, doc=None): diff --git a/requirements.txt b/requirements.txt index 486e96a8a7..ece246e579 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,3 +39,4 @@ psutil unittest-xml-reporting xlwt oauthlib +pypdf \ No newline at end of file