diff --git a/core/doctype/doctype/doctype.py b/core/doctype/doctype/doctype.py
index 2fe2895b91..9fb4a07a29 100644
--- a/core/doctype/doctype/doctype.py
+++ b/core/doctype/doctype/doctype.py
@@ -226,7 +226,7 @@ def validate_permissions(permissions, for_remove=False):
issubmittable = webnotes.conn.get_value("DocType", doctype, "is_submittable")
def get_txt(d):
- return "For %s (level %s) in %s:" % (d.role, d.permlevel, d.parent)
+ return "For %s (level %s) in %s row %s:" % (d.role, d.permlevel, d.parent, d.idx)
def check_atleast_one_set(d):
if not d.read and not d.write and not d.submit and not d.cancel and not d.create:
@@ -245,7 +245,7 @@ def validate_permissions(permissions, for_remove=False):
raise_exception=True)
def check_level_zero_is_set(d):
- if d.permlevel > 0 and d.role != 'All':
+ if cint(d.permlevel) > 0 and d.role != 'All':
if not permissions.get({"role": d.role, "permlevel": 0}):
webnotes.msgprint(get_txt(d) + " Higher level permissions are meaningless if level 0 permission is not set.",
raise_exception=True)
diff --git a/core/doctype/scheduler_log/__init__.py b/core/doctype/scheduler_log/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core/doctype/scheduler_log/scheduler_log.py b/core/doctype/scheduler_log/scheduler_log.py
new file mode 100644
index 0000000000..928aa9ff9f
--- /dev/null
+++ b/core/doctype/scheduler_log/scheduler_log.py
@@ -0,0 +1,8 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+ def __init__(self, d, dl):
+ self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/core/doctype/scheduler_log/scheduler_log.txt b/core/doctype/scheduler_log/scheduler_log.txt
new file mode 100644
index 0000000000..1ff16c15f5
--- /dev/null
+++ b/core/doctype/scheduler_log/scheduler_log.txt
@@ -0,0 +1,59 @@
+[
+ {
+ "owner": "Administrator",
+ "docstatus": 0,
+ "creation": "2013-01-15 12:42:11",
+ "modified_by": "Administrator",
+ "modified": "2013-01-15 12:49:23"
+ },
+ {
+ "autoname": "SCHLOG.#####",
+ "description": "Log of Scheduler Errors",
+ "doctype": "DocType",
+ "module": "Core",
+ "document_type": "System",
+ "name": "__common__"
+ },
+ {
+ "name": "__common__",
+ "parent": "Scheduler Log",
+ "doctype": "DocField",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "parentfield": "fields"
+ },
+ {
+ "parent": "Scheduler Log",
+ "read": 1,
+ "cancel": 1,
+ "name": "__common__",
+ "create": 1,
+ "doctype": "DocPerm",
+ "submit": 0,
+ "write": 1,
+ "parenttype": "DocType",
+ "role": "System Manager",
+ "report": 1,
+ "permlevel": 0,
+ "parentfield": "permissions"
+ },
+ {
+ "name": "Scheduler Log",
+ "doctype": "DocType"
+ },
+ {
+ "doctype": "DocField",
+ "label": "Method",
+ "fieldname": "method",
+ "fieldtype": "Data"
+ },
+ {
+ "doctype": "DocField",
+ "label": "Error",
+ "fieldname": "error",
+ "fieldtype": "Text"
+ },
+ {
+ "doctype": "DocPerm"
+ }
+]
\ No newline at end of file
diff --git a/public/js/wn/model/create_new.js b/public/js/wn/model/create_new.js
index 3233a0b3f4..e178664140 100644
--- a/public/js/wn/model/create_new.js
+++ b/public/js/wn/model/create_new.js
@@ -59,7 +59,7 @@ $.extend(wn.model, {
if(def_vals[df["default"]])
return def_vals[df["default"]];
- else if(df.fieldtype=="Time" && !df["default"] && df.reqd)
+ else if(df.fieldtype=="Time" && (!df["default"]))
return dateutil.get_cur_time()
else if(df["default"])
return df["default"];
diff --git a/public/js/wn/views/communication.js b/public/js/wn/views/communication.js
index 40a4375747..2dfa40cc45 100644
--- a/public/js/wn/views/communication.js
+++ b/public/js/wn/views/communication.js
@@ -75,7 +75,7 @@ wn.views.CommunicationList = Class.extend({
make_line: function(doc) {
var me = this;
var comm = $(repl('
| \
- '
+ '
+wn._('Show Details')+'\
\
@@ -83,6 +83,10 @@ wn.views.CommunicationList = Class.extend({
padding: 10px; overflow-x: auto; display: none;">\
|
', doc))
.appendTo(this.body);
+
+ if(!doc.name) {
+ comm.find(".show-details").toggle(false);
+ }
comm.find(".comm-header")
.css({"cursor":"pointer"})
diff --git a/webnotes/model/wrapper.py b/webnotes/model/wrapper.py
index 81d79a633a..8011c78444 100644
--- a/webnotes/model/wrapper.py
+++ b/webnotes/model/wrapper.py
@@ -48,6 +48,8 @@ class ModelWrapper:
self.load_from_db(dt, dn)
elif isinstance(dt, list):
self.set_doclist(dt)
+ elif isinstance(dt, dict):
+ self.set_doclist([dt])
def load_from_db(self, dt=None, dn=None, prefix='tab'):
"""
diff --git a/webnotes/utils/__init__.py b/webnotes/utils/__init__.py
index e12f5f9502..0f5bd8f166 100644
--- a/webnotes/utils/__init__.py
+++ b/webnotes/utils/__init__.py
@@ -59,19 +59,7 @@ def get_fullname(profile):
return profile
-# TODO: deprecate it
-def decode_email_header(s):
- import email.header
-
- # replace double quotes with blank
- # double quotes in header prohibit decoding of header
- decoded_header_tuple = email.header.decode_header(s.replace('"', ''))
-
- decoded_list = map(lambda h: unicode(h[0], encoding=h[1] or 'utf-8'), decoded_header_tuple)
-
- return " ".join(decoded_list)
-
-def get_email_id(user):
+def get_formatted_email(user):
"""get email id of user formatted as: John Doe """
if user == "Administrator":
return user
@@ -81,14 +69,15 @@ def get_email_id(user):
def extract_email_id(email):
"""fetch only the email part of the email id"""
- import re
- sender_email = re.findall("<([^>]*)>", email)
- return sender_email and sender_email[0] or ""
+ from email.utils import parseaddr
+ if ',' in email and email.count("@")==1:
+ email = email.split(",")[-1]
+ fullname, email_id = parseaddr(email)
+ return email_id
def validate_email_add(email_str):
"""Validates the email string"""
- from email.utils import parseaddr
- real_name, email = parseaddr(email_str)
+ email = extract_email_id(email_str)
import re
return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", email.lower())
diff --git a/webnotes/utils/email_lib/receive.py b/webnotes/utils/email_lib/receive.py
index 3fbad5f48e..a5f1e1719f 100644
--- a/webnotes/utils/email_lib/receive.py
+++ b/webnotes/utils/email_lib/receive.py
@@ -21,9 +21,7 @@
#
from __future__ import unicode_literals
-"""
- This module contains classes for managing incoming emails
-"""
+from webnotes.utils import extract_email_id
class IncomingMail:
"""
@@ -41,18 +39,21 @@ class IncomingMail:
self.html_content = ''
self.attachments = []
self.parse()
+ self.set_content_and_type()
+ self.from_email = extract_email_id(self.mail["From"])
def parse(self):
- """
- Extracts text, html and attachments from the mail
- """
for part in self.mail.walk():
self.process_part(part)
+ def set_content_and_type(self):
+ self.content, self.content_type = '[Blank Email]', 'text/plain'
+ if self.text_content:
+ self.content, self.content_type = self.text_content, 'text/plain'
+ else:
+ self.content, self.content_type = self.html_content, 'text/html'
+
def process_part(self, part):
- """
- Process a single part of an email
- """
content_type = part.get_content_type()
charset = part.get_content_charset()
if not charset: charset = self.get_charset(part)
@@ -67,15 +68,9 @@ class IncomingMail:
self.get_attachment(part, charset)
def get_text_content(self):
- """
- Returns the text parts of the email. If None, then HTML parts
- """
return self.text_content or self.html_content
def get_charset(self, part):
- """
- Guesses character set
- """
charset = part.get_content_charset()
if not charset:
import chardet
@@ -84,57 +79,48 @@ class IncomingMail:
return charset
def get_payload(self, part, charset):
- """
- get utf-8 encoded part content
- """
try:
return unicode(part.get_payload(decode=True),str(charset),"ignore")
except LookupError, e:
return part.get_payload()
def get_attachment(self, part, charset):
- """
- Extracts an attachment
- """
self.attachments.append({
'content-type': part.get_content_type(),
'filename': part.get_filename(),
'content': part.get_payload(decode=True),
})
-
+
+ def save_attachments_in_doc(self, doc):
+ from webnotes.utils.file_manager import save_file, add_file_list
+ for attachment in self.attachments:
+ fid = save_file(attachment['filename'], attachment['content'])
+ status = add_file_list(doc.doctype, doc.name, fid, fid)
def get_thread_id(self):
- """
- Extracts thread id of the message between first []
- from the subject
- """
import re
subject = self.mail.get('Subject', '')
-
- return re.findall('(?<=\[)[\w/-]+', subject)
+ l= re.findall('(?<=\[)[\w/-]+', subject)
+ return l and l[0] or None
class POP3Mailbox:
- """
- A simple pop3 mailbox, abstracts connection and mail extraction
- To use, subclass it and override method process_message(from, subject, text, thread_id)
- """
+ def __init__(self):
+ self.setup()
+ self.get_messages()
- def __init__(self, settings_doc):
- """
- settings_doc must contain
- use_ssl, host, username, password
- (by name or object)
- """
- if isinstance(settings_doc, basestring):
- from webnotes.model.doc import Document
- self.settings = Document(settings_doc, settings_doc)
- else:
- self.settings = settings_doc
+ def setup(self):
+ # overrride
+ self.settings = webnotes._dict()
+ def check_mails(self):
+ # overrride
+ return True
+
+ def process_message(self, mail):
+ # overrride
+ pass
+
def connect(self):
- """
- Connects to the mailbox
- """
import poplib
if self.settings.use_ssl:
@@ -145,10 +131,6 @@ class POP3Mailbox:
self.pop.pass_(self.settings.password)
def get_messages(self):
- """
- Loads messages from the mailbox and calls
- process_message for each message
- """
import webnotes
if not self.check_mails():
@@ -190,15 +172,3 @@ class POP3Mailbox:
self.pop.quit()
webnotes.conn.begin()
- def check_mails(self):
- """
- To be overridden
- If mailbox is to be scanned, returns true
- """
- return True
-
- def process_message(self, mail):
- """
- To be overriden
- """
- pass
diff --git a/webnotes/utils/scheduler.py b/webnotes/utils/scheduler.py
index 2ddc494cb6..eeeff28d24 100644
--- a/webnotes/utils/scheduler.py
+++ b/webnotes/utils/scheduler.py
@@ -101,8 +101,10 @@ def log(method):
import webnotes.utils
webnotes.conn.begin()
- webnotes.conn.sql("""insert into __SchedulerLog (`timestamp`, method, error)
- values (%s, %s, %s)""", (webnotes.utils.now_datetime(), method, traceback))
+ d = webnotes.doc("Scheduler Log")
+ d.method = method
+ d.error = traceback
+ d.save()
webnotes.conn.commit()
return traceback