From ad4ebb100129becc3888cccf3607e0a76951499f Mon Sep 17 00:00:00 2001 From: robert schouten Date: Fri, 25 Nov 2016 18:32:31 +0800 Subject: [PATCH 1/7] allow permission for communication based on timeline not just reference (#2366) --- frappe/core/doctype/communication/communication.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 From ee0225899923b8e98a9e8f157e2ba819010c5049 Mon Sep 17 00:00:00 2001 From: Viet Pham Date: Fri, 25 Nov 2016 17:39:36 +0700 Subject: [PATCH 2/7] Ability to publish realtime event from bench (#2369) --- frappe/commands/site.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/frappe/commands/site.py b/frappe/commands/site.py index c6939990af..40b4760651 100755 --- a/frappe/commands/site.py +++ b/frappe/commands/site.py @@ -483,6 +483,27 @@ def set_last_active_for_user(context, user=None): set_last_active_to_now(user) frappe.db.commit() +@click.command('publish-realtime') +@click.argument('event') +@click.option('--message') +@click.option('--room') +@click.option('--user') +@click.option('--doctype') +@click.option('--docname') +@click.option('--after-commit') +@pass_context +def publish_realtime(context, event, message, room, user, doctype, docname, after_commit): + "Publish realtime event from bench" + from frappe import publish_realtime + for site in context.sites: + try: + frappe.init(site=site) + frappe.connect() + publish_realtime(event, message=message, room=room, user=user, doctype=doctype, docname=docname, + after_commit=after_commit) + frappe.db.commit() + finally: + frappe.destroy() commands = [ add_system_manager, @@ -506,4 +527,5 @@ commands = [ disable_user, _use, set_last_active_for_user, + publish_realtime, ] From 570f24284150c226124ad4d4cd5352c78d9a69c6 Mon Sep 17 00:00:00 2001 From: robert schouten Date: Fri, 25 Nov 2016 18:40:07 +0800 Subject: [PATCH 3/7] move newsletter to tools (#2370) --- frappe/config/desk.py | 5 +++++ frappe/config/setup.py | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) 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", From e03d56adb62d24150539ac3aa20b7f55437ea346 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 25 Nov 2016 16:10:42 +0530 Subject: [PATCH 4/7] [Fix] Multiple letter head printing issue on print format (#2365) --- frappe/__init__.py | 4 ++-- frappe/utils/pdf.py | 17 +++++++++++++---- frappe/utils/print_format.py | 32 +++++++++++++++----------------- requirements.txt | 1 + 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 1b93302cce..41cf683fc5 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -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/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 From a7477d564169aa1f0f141a42df54dc67ef12239f Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 25 Nov 2016 16:11:18 +0530 Subject: [PATCH 5/7] Minor fix (#2371) --- frappe/email/doctype/auto_email_report/auto_email_report.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: { From 6f59a23f472f893ffaa6ddf392a40091b68735af Mon Sep 17 00:00:00 2001 From: Shreyas Patil Date: Mon, 28 Nov 2016 12:38:20 +0530 Subject: [PATCH 6/7] [Minor] Removed not available scheduler commands 'dump-queue-status' (#2385) --- frappe/commands/scheduler.py | 10 ---------- 1 file changed, 10 deletions(-) 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, From c3ab1cf86b34abe3b060cd7f435a9b8aae8721d0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 28 Nov 2016 14:54:40 +0600 Subject: [PATCH 7/7] bumped to version 7.1.20 --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 41cf683fc5..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()