Merge branch 'develop'

This commit is contained in:
Anand Doshi 2015-11-26 18:11:19 +05:30
commit bcc6de2bda
14 changed files with 167 additions and 40 deletions

View file

@ -1,2 +1,2 @@
from __future__ import unicode_literals
__version__ = "6.10.0"
__version__ = "6.10.1"

View file

@ -25,7 +25,6 @@ import mimetypes, imghdr
from frappe.utils import get_files_path
class FolderNotEmpty(frappe.ValidationError): pass
class ThumbnailError(frappe.ValidationError): pass
exclude_from_linked_with = True
@ -154,13 +153,16 @@ class File(NestedSet):
def make_thumbnail(self):
if self.file_url:
if self.file_url.startswith("/files"):
image, filename, extn = get_local_image(self.file_url)
try:
image, filename, extn = get_local_image(self.file_url)
except IOError:
return
else:
try:
image, filename, extn = get_web_image(self.file_url)
except ThumbnailError:
frappe.msgprint("Unable to write file format for {0}".format(self.file_url))
except requests.exceptions.HTTPError:
return
thumbnail = ImageOps.fit(
image,
@ -177,6 +179,7 @@ class File(NestedSet):
self.db_set("thumbnail_url", thumbnail_url)
except IOError:
frappe.msgprint("Unable to write file format for {0}".format(path))
return
return thumbnail_url
@ -289,7 +292,7 @@ def get_local_image(file_url):
image = Image.open(file_path)
except IOError:
frappe.msgprint("Unable to read file format for {0}".format(file_url))
return
raise
content = None
@ -315,9 +318,11 @@ def get_web_image(file_url):
r.raise_for_status()
except requests.exceptions.HTTPError, e:
if "404" in e.args[0]:
frappe.throw(_("File '{0}' not found").format(file_url))
frappe.msgprint(_("File '{0}' not found").format(file_url))
else:
raise ThumbnailError
frappe.msgprint("Unable to read file format for {0}".format(file_url))
raise
image = Image.open(StringIO.StringIO(r.content))

View file

@ -38,13 +38,13 @@ def add(args=None):
and owner=%(assign_to)s""", args):
frappe.msgprint(_("Already in user's To Do list"), raise_exception=True)
return
else:
from frappe.utils import nowdate
if args.get("re_assign"):
remove_from_todo_if_already_assigned(args['doctype'], args['name'])
d = frappe.get_doc({
"doctype":"ToDo",
"owner": args['assign_to'],
@ -56,39 +56,38 @@ def add(args=None):
"date": args.get('date', nowdate()),
"assigned_by": args.get('assigned_by', frappe.session.user),
}).insert(ignore_permissions=True)
# set assigned_to if field exists
if frappe.get_meta(args['doctype']).get_field("assigned_to"):
frappe.db.set_value(args['doctype'], args['name'], "assigned_to", args['assign_to'])
# notify
if not args.get("no_notification"):
notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN',\
description=args.get("description"), notify=args.get('notify'))
notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN',\
description=args.get("description"), notify=args.get('notify'))
if not args.get("bulk_assign"):
return get(args)
else:
return {}
@frappe.whitelist()
def add_multiple(args=None):
import json
if not args:
args = frappe.local.form_dict
docname_list = json.loads(args['name'])
for docname in docname_list:
args.update({"name": docname})
add(args)
def remove_from_todo_if_already_assigned(doctype, docname):
owner = frappe.db.get_value("ToDo", {"reference_type": doctype, "reference_name": docname, "status":"Open"}, "owner")
if owner:
remove(doctype, docname, owner)
@frappe.whitelist()
def remove(doctype, name, assign_to):
"""remove from todo"""
@ -156,5 +155,6 @@ def notify_assignment(assigned_by, owner, doc_type, doc_name, action='CLOSE',
}
arg["parenttype"] = "Assignment"
from frappe.desk.page.messages import messages
messages.post(**arg)

View file

@ -14,6 +14,9 @@ from poplib import error_proto
import re
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta
from frappe.desk.form import assign_to
from frappe.utils.user import get_system_managers
import socket
class SentEmailInInbox(Exception): pass
@ -96,7 +99,7 @@ class EmailAccount(Document):
)
server.sess
def get_pop3(self):
def get_pop3(self, in_receive=False):
"""Returns logged in POP3 connection object."""
args = {
"host": self.pop3_server,
@ -111,18 +114,56 @@ class EmailAccount(Document):
pop3 = POP3Server(frappe._dict(args))
try:
pop3.connect()
except error_proto, e:
frappe.throw(e.message)
if in_receive and e.message=="-ERR authentication failed":
# if called via self.receive and it leads to authentication error, disable incoming
# and send email to system manager
self.handle_incoming_connect_error(
description=_('Authentication failed while receiving emails from Email Account {0}'.format(self.name))
)
return None
else:
frappe.throw(e.message)
except socket.error:
if in_receive:
# timeout while connecting, see receive.py connect method
description = frappe.message_log.pop() if frappe.message_log else "Socket Error"
self.handle_incoming_connect_error(description=description)
return None
else:
raise
return pop3
def handle_incoming_connect_error(self, description):
self.db_set("enable_incoming", 0)
for user in get_system_managers(only_name=True):
assign_to.add({
'assign_to': user,
'doctype': self.doctype,
'name': self.name,
'description': description,
'priority': 'High',
'notify': 1
})
def receive(self, test_mails=None):
"""Called by scheduler to receive emails from this EMail account using POP3."""
if self.enable_incoming:
if frappe.local.flags.in_test:
incoming_mails = test_mails
else:
pop3 = self.get_pop3()
pop3 = self.get_pop3(in_receive=True)
if not pop3:
return
incoming_mails = pop3.get_messages()
exceptions = []

View file

@ -13,6 +13,14 @@ from frappe.email.doctype.email_account.email_account import notify_unreplied
from datetime import datetime, timedelta
class TestEmailAccount(unittest.TestCase):
def setUp(self):
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
email_account.db_set("enable_incoming", 1)
def tearDown(self):
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
email_account.db_set("enable_incoming", 0)
def test_incoming(self):
frappe.db.sql("delete from tabCommunication where sender='test_sender@example.com'")

View file

@ -25,6 +25,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -47,6 +48,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -70,6 +72,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@ -93,6 +96,7 @@
"options": "DocType",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@ -116,6 +120,7 @@
"options": "\nNew\nSave\nSubmit\nCancel\nDays After\nDays Before\nValue Change",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@ -140,6 +145,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -165,6 +171,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -189,6 +196,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -213,6 +221,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -234,6 +243,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -256,6 +266,7 @@
"options": "<p><strong>Condition Examples:</strong></p>\n<pre>doc.status==\"Open\"\ndoc.due_date==nowdate()\ndoc.total > 40000\n</pre>\n<p><strong>Hints:</strong></p>\n<ol>\n<li>To check for an event every day, select \"Date Change\" in Event</li>\n<li>To send an alert if a particular value changes, select \"Value Change\"</li>\n</ol>",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -278,6 +289,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -301,6 +313,7 @@
"options": "Email Alert Recipient",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@ -323,6 +336,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -345,6 +359,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@ -368,6 +383,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -388,9 +404,10 @@
"label": "Message Examples",
"length": 0,
"no_copy": 0,
"options": "<h5>Message Example</h5>\n\n<pre>\n<h3>Order Overdue</h3>\n\n<p>Transaction {{ doc.name }} has exceeded Due Date. Please take necessary action.</p>\n\n<h4>Details</h4>\n\n<ul>\n<li>Customer: {{ doc.customer }}\n<li>Amount: {{ doc.total_amount }}\n</ul>\n</pre>",
"options": "<h5>Message Example</h5>\n\n<pre>\n&lt;h3&gt;Order Overdue&lt;/h3&gt;\n\n&lt;p&gt;Transaction {{ doc.name }} has exceeded Due Date. Please take necessary action.&lt;/p&gt;\n\n&lt;!-- show last comment --&gt;\n{% if comments %}\nLast comment: {{ comments[-1].comment }} by {{ comments[-1].by }}\n{% endif %}\n\n&lt;h4&gt;Details&lt;/h4&gt;\n\n&lt;ul&gt;\n&lt;li&gt;Customer: {{ doc.customer }}\n&lt;li&gt;Amount: {{ doc.total_amount }}\n&lt;/ul&gt;\n</pre>",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -414,6 +431,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@ -425,13 +443,15 @@
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-envelope",
"idx": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2015-11-16 06:29:46.014034",
"menu_index": 0,
"modified": "2015-11-26 02:14:59.637519",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Alert",

View file

@ -3,6 +3,7 @@
from __future__ import unicode_literals
import frappe
import json
from frappe import _
from frappe.model.document import Document
from frappe.utils import validate_email_add, nowdate
@ -95,10 +96,21 @@ def evaluate_alert(doc, alert, event):
return
subject = alert.subject
if event != "Value Change" and not doc.is_new():
# reload the doc for the latest values & comments,
# except for validate type event.
doc = frappe.get_doc(doc.doctype, doc.name)
context = {"doc": doc, "alert": alert, "comments": None}
if doc.get("_comments"):
context["comments"] = json.loads(doc.get("_comments"))
if "{" in subject:
subject = frappe.render_template(alert.subject, {"doc": doc, "alert": alert})
subject = frappe.render_template(alert.subject, context)
frappe.sendmail(recipients=recipients, subject=subject,
message= frappe.render_template(alert.message, {"doc": doc, "alert":alert}),
message= frappe.render_template(alert.message, context),
bulk=True, reference_doctype = doc.doctype, reference_name = doc.name,
attachments = [frappe.attach_print(doc.doctype, doc.name)] if alert.attach_print else None)

View file

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import time
import _socket, poplib
import socket, poplib
import frappe
from frappe import _
from frappe.utils import extract_email_id, convert_utc_to_user_timezone, now, cint, cstr, strip
@ -48,7 +48,7 @@ class POP3Server:
# connection established!
return True
except _socket.error:
except socket.error:
# Invalid mail server -- due to refusing connection
frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.'))
raise

View file

@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd."
app_description = "Full stack web framework with Python, Javascript, MariaDB, Redis, Node"
app_icon = "octicon octicon-circuit-board"
app_version = "6.10.0"
app_version = "6.10.1"
app_color = "orange"
source_link = "https://github.com/frappe/frappe"
app_license = "MIT"

View file

@ -326,10 +326,26 @@ ul.linked-with-list li {
border-bottom: 1px solid #d1d8dd;
}
/* jquery ui */
.ui-datepicker .ui-datepicker-header {
border-radius: 0px !important;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
display: inline;
}
.ui-datepicker select.ui-datepicker-month {
margin-right: 3px;
}
.ui-datepicker .ui-datepicker-title {
line-height: inherit !important;
padding-bottom: 3px;
}
.ui-datepicker-today .ui-state-default {
background-color: #EBEFF2 !important;
}
.ui-state-default {
box-shadow: none !important;
}
.hidden-xs-inline,
.hidden-xs-inline-block {
display: none;

View file

@ -523,10 +523,12 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
datepicker_options: {
altFormat:'yy-mm-dd',
changeYear: true,
changeMonth: true,
yearRange: "-70Y:+10Y",
},
make_input: function() {
this._super();
this.set_t_for_today();
this.set_datepicker();
},
set_datepicker: function() {
@ -534,6 +536,15 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
(frappe.boot.sysdefaults.date_format || 'yyyy-mm-dd').replace("yyyy", "yy")
this.$input.datepicker(this.datepicker_options);
},
set_t_for_today: function() {
var me = this;
this.$input.on("keydown", function(e) {
if(e.which===84) { // 84 === t
me.set_value(frappe.datetime.str_to_user(frappe.datetime.nowdate()));
return false;
}
});
},
parse: function(value) {
if(value) {
value = dateutil.user_to_str(value);
@ -878,7 +889,7 @@ frappe.ui.form.ControlAttachImage = frappe.ui.form.ControlAttach.extend({
this.$wrapper.on("refresh", function() {
me.set_image();
});
this.set_image();
},
set_image: function() {

View file

@ -134,10 +134,30 @@ ul.linked-with-list li {
/* jquery ui */
.ui-datepicker .ui-datepicker-header {
border-radius: 0px !important;
}
.ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year {
display: inline;
}
.ui-datepicker select.ui-datepicker-month {
margin-right: 3px;
}
.ui-datepicker .ui-datepicker-title {
line-height: inherit !important;
padding-bottom: 3px;
}
.ui-datepicker-today .ui-state-default {
background-color: @light-border-color !important;
}
.ui-state-default {
box-shadow: none !important;
}
.hidden-xs-inline, .hidden-xs-inline-block {
display: none;
}

View file

@ -371,12 +371,6 @@ $.extend(frappe, {
// blur
if(!$('#freeze').length) {
var freeze = $('<div id="freeze" class="modal-backdrop fade"></div>')
.on("click", function() {
if (cur_frm && cur_frm.cur_grid) {
cur_frm.cur_grid.toggle_view();
return false;
}
})
.appendTo("body");
freeze.html(repl('<div class="freeze-message-container"><div class="freeze-message">%(msg)s</div></div>',

View file

@ -1,6 +1,6 @@
from setuptools import setup, find_packages
version = "6.10.0"
version = "6.10.1"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()