Procházet zdrojové kódy

[merge] 5.3.1

version-14
Rushabh Mehta před 10 roky
rodič
revize
a7bd640b24
69 změnil soubory, kde provedl 25083 přidání a 13026 odebrání
  1. +40
    -0
      frappe/change_log/v5/v5_3_0.md
  2. +1
    -1
      frappe/commands.py
  3. +29
    -1
      frappe/core/doctype/communication/communication.py
  4. +2
    -2
      frappe/core/doctype/doctype/doctype.py
  5. +1
    -1
      frappe/core/page/permission_manager/permission_manager.js
  6. +10
    -2
      frappe/data/languages.txt
  7. +3
    -1
      frappe/desk/form/save.py
  8. +3
    -1
      frappe/desk/form/utils.py
  9. +18
    -5
      frappe/email/bulk.py
  10. +5
    -3
      frappe/email/doctype/email_account/email_account.py
  11. +7
    -2
      frappe/email/receive.py
  12. +1
    -0
      frappe/exceptions.py
  13. +29
    -18
      frappe/model/base_document.py
  14. +1
    -0
      frappe/patches.txt
  15. +0
    -0
      frappe/patches/v5_3/__init__.py
  16. +18
    -0
      frappe/patches/v5_3/rename_chinese_languages.py
  17. +6
    -4
      frappe/permissions.py
  18. +1
    -1
      frappe/public/js/frappe/form/formatters.js
  19. +16
    -1
      frappe/public/js/frappe/form/save.js
  20. +1
    -1
      frappe/public/js/frappe/ui/toolbar/about.js
  21. +1
    -1
      frappe/public/js/frappe/ui/toolbar/navbar.html
  22. +1
    -1
      frappe/public/js/frappe/ui/toolbar/offcanvas_left_sidebar.html
  23. +9
    -0
      frappe/share.py
  24. +33
    -1
      frappe/tasks.py
  25. +393
    -353
      frappe/translations/ar.csv
  26. +392
    -349
      frappe/translations/bg.csv
  27. +0
    -0
      frappe/translations/bo.csv
  28. +392
    -352
      frappe/translations/bs.csv
  29. +392
    -352
      frappe/translations/ca.csv
  30. +392
    -352
      frappe/translations/cs.csv
  31. +392
    -349
      frappe/translations/da.csv
  32. +397
    -357
      frappe/translations/de.csv
  33. +392
    -349
      frappe/translations/el.csv
  34. +392
    -352
      frappe/translations/es.csv
  35. +393
    -350
      frappe/translations/fa.csv
  36. +1509
    -0
      frappe/translations/fi.csv
  37. +394
    -354
      frappe/translations/fr.csv
  38. +379
    -339
      frappe/translations/he.csv
  39. +392
    -352
      frappe/translations/hi.csv
  40. +392
    -352
      frappe/translations/hr.csv
  41. +392
    -349
      frappe/translations/hu.csv
  42. +400
    -360
      frappe/translations/id.csv
  43. +392
    -352
      frappe/translations/it.csv
  44. +397
    -359
      frappe/translations/ja.csv
  45. +1356
    -0
      frappe/translations/km.csv
  46. +392
    -352
      frappe/translations/kn.csv
  47. +408
    -368
      frappe/translations/ko.csv
  48. +392
    -349
      frappe/translations/lv.csv
  49. +1509
    -0
      frappe/translations/mk.csv
  50. +392
    -349
      frappe/translations/mr.csv
  51. +1509
    -0
      frappe/translations/my.csv
  52. +393
    -353
      frappe/translations/nl.csv
  53. +1509
    -0
      frappe/translations/no.csv
  54. +642
    -602
      frappe/translations/pl.csv
  55. +392
    -352
      frappe/translations/pt-BR.csv
  56. +392
    -352
      frappe/translations/pt.csv
  57. +392
    -352
      frappe/translations/ro.csv
  58. +392
    -352
      frappe/translations/ru.csv
  59. +0
    -0
      frappe/translations/se.csv
  60. +392
    -352
      frappe/translations/sk.csv
  61. +1509
    -0
      frappe/translations/sq.csv
  62. +392
    -352
      frappe/translations/sr.csv
  63. +1509
    -0
      frappe/translations/sv.csv
  64. +392
    -352
      frappe/translations/ta.csv
  65. +392
    -352
      frappe/translations/th.csv
  66. +396
    -356
      frappe/translations/tr.csv
  67. +392
    -352
      frappe/translations/vi.csv
  68. +392
    -352
      frappe/translations/zh-cn.csv
  69. +437
    -398
      frappe/translations/zh-tw.csv

+ 40
- 0
frappe/change_log/v5/v5_3_0.md Zobrazit soubor

@@ -0,0 +1,40 @@
- Added Language Support for Following languages

<table class="table table-bordered">
<tr>
<td style="width: 30%">bo*</td>
<td>ལྷ་སའི་སྐད་</td>
</tr>
<tr>
<td>fi</td>
<td>suomalainen</td>
</tr>
<tr>
<td>km</td>
<td>ភាសាខ្មែរ</td>
</tr>
<tr>
<td>mk</td>
<td>македонски</td>
</tr>
<tr>
<td>my</td>
<td>Melayu</td>
</tr>
<tr>
<td>no</td>
<td>norsk</td>
</tr>
<tr>
<td>sv</td>
<td>Svenska</td>
</tr>
<tr>
<td>sq</td>
<td>shqiptar</td>
</tr>
</table>

* Unable to find translations for Tibetian via Google

- To contribute to translations, please login to [https://translate.erpnext.com](https://translate.erpnext.com)

+ 1
- 1
frappe/commands.py Zobrazit soubor

@@ -103,7 +103,7 @@ def _is_scheduler_enabled():
enable_scheduler = False
try:
frappe.connect()
enable_scheduler = cint(frappe.db.get_default("enable_scheduler"))
enable_scheduler = cint(frappe.db.get_single_value("System Settings", "enable_scheduler")) and True or False
except:
pass
finally:


+ 29
- 1
frappe/core/doctype/communication/communication.py Zobrazit soubor

@@ -72,6 +72,26 @@ class Communication(Document):
["email_id", "always_use_account_email_id_as_sender"], as_dict=True) or frappe._dict()

def notify(self, print_html=None, print_format=None, attachments=None, recipients=None, except_recipient=False):
"""Calls a delayed celery task 'sendmail' that enqueus email in Bulk Email queue

:param print_html: Send given value as HTML attachment
:param print_format: Attach print format of parent document
:param attachments: A list of filenames that should be attached when sending this email
:param recipients: Email recipients
:param except_recipient: True when pulling email, the notification shouldn't go to the main recipient

"""
if frappe.flags.in_test:
# for test cases, run synchronously
self._notify(print_html=print_html, print_format=print_format, attachments=attachments,
recipients=recipients, except_recipient=except_recipient)
else:
from frappe.tasks import sendmail
sendmail.delay(frappe.local.site, self.name,
print_html=print_html, print_format=print_format, attachments=attachments,
recipients=recipients, except_recipient=except_recipient)

def _notify(self, print_html=None, print_format=None, attachments=None, recipients=None, except_recipient=False):
self.prepare_to_notify(print_html, print_format, attachments)
if not recipients:
recipients = self.get_recipients(except_recipient=except_recipient)
@@ -143,6 +163,7 @@ class Communication(Document):
sender = parseaddr(self.sender)[1]

filtered = []
email_addresses = []
for e in list(set(recipients)):
if (e=="Administrator") or ((e==self.sender) and (e not in original_recipients)) or \
(e in unsubscribed) or (e in email_accounts):
@@ -160,8 +181,11 @@ class Communication(Document):
# while pulling email, don't send email to current recipient
continue

if e not in filtered and email_id not in filtered:
# make sure of case-insensitive uniqueness of email address
if email_id.lower() not in email_addresses:
# append the full email i.e. "Human <human@example.com>"
filtered.append(e)
email_addresses.append(email_id.lower())

if getattr(self, "send_me_a_copy", False):
filtered.append(self.sender)
@@ -252,6 +276,10 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
})
comm.insert(ignore_permissions=True)

# needed for communication.notify which uses celery delay
# if not committed, delayed task doesn't find the communication
frappe.db.commit()

recipients = None
if send_email:
comm.send_me_a_copy = send_me_a_copy


+ 2
- 2
frappe/core/doctype/doctype/doctype.py Zobrazit soubor

@@ -262,8 +262,8 @@ def validate_fields(meta):
def check_dynamic_link_options(d):
if d.fieldtype=="Dynamic Link":
doctype_pointer = filter(lambda df: df.fieldname==d.options, fields)
if not doctype_pointer or (doctype_pointer[0].fieldtype!="Link") \
or (doctype_pointer[0].options!="DocType"):
if not doctype_pointer or (doctype_pointer[0].fieldtype not in ("Link", "Select")) \
or (doctype_pointer[0].fieldtype=="Link" and doctype_pointer[0].options!="DocType"):
frappe.throw(_("Options 'Dynamic Link' type of field must point to another Link Field with options as 'DocType'"))

def check_illegal_default(d):


+ 1
- 1
frappe/core/page/permission_manager/permission_manager.js Zobrazit soubor

@@ -277,7 +277,7 @@ frappe.PermissionEngine = Class.extend({
},

rights: ["read", "write", "create", "delete", "submit", "cancel", "amend",
"print", "email", "report", "import", "export", "set_user_permissions"],
"print", "email", "report", "import", "export", "set_user_permissions", "share"],

set_show_users: function(cell, role) {
cell.html("<a class='grey' href='#'>"+__(role)+"</a>")


+ 10
- 2
frappe/data/languages.txt Zobrazit soubor

@@ -1,5 +1,6 @@
ar العربية
bg bǎlgarski
bo ལྷ་སའི་སྐད་
bs bosanski
ca català
cs česky
@@ -9,6 +10,7 @@ el ελληνικά
es español
en english
fa پارسی
fi suomalainen
fr français
he עברית
hi हिंदी
@@ -17,21 +19,27 @@ hu magyar
id Indonesia
it italiano
ja 日本語
km ភាសាខ្មែរ
kn ಕನ್ನಡ
ko 한국의
lv latviešu valoda
mr मराठी
mk македонски
my Melayu
nl nederlands
no norsk
pl polski
pt português
pt-BR português brasileiro
ro român
ru русский
sv svenska
sk slovenčina
sq shqiptar
sr српски
ta தமிழ்
th ไทย
tr Türk
vi việt
zh-cn 中国(简体)
zh-tw 中國(繁體)
zh-cn 簡體中文
zh-tw 正體中文

+ 3
- 1
frappe/desk/form/save.py Zobrazit soubor

@@ -32,10 +32,12 @@ def savedocs():
raise

@frappe.whitelist()
def cancel(doctype=None, name=None):
def cancel(doctype=None, name=None, workflow_state_fieldname=None, workflow_state=None):
"""cancel a doclist"""
try:
doc = frappe.get_doc(doctype, name)
if workflow_state_fieldname and workflow_state:
doc.set(workflow_state_fieldname, workflow_state)
doc.cancel()
send_updated_docs(doc)



+ 3
- 1
frappe/desk/form/utils.py Zobrazit soubor

@@ -144,7 +144,9 @@ def get_linked_docs(doctype, name, metadata_loaded=None, no_metadata=False):
filters=[[dt, link.get("fieldname"), '=', name]])

except frappe.PermissionError:
frappe.local.message_log.pop()
if frappe.local.message_log:
frappe.local.message_log.pop()

continue

if ret:


+ 18
- 5
frappe/email/bulk.py Zobrazit soubor

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
import HTMLParser
import smtplib
from frappe import msgprint, throw, _
from frappe.email.smtp import SMTPServer, get_outgoing_email_account
from frappe.email.email_body import get_email, get_formatted_html
@@ -107,14 +108,18 @@ def add(email, sender, subject, formatted, text_content=None,
e.insert(ignore_permissions=True)

def check_bulk_limit(recipients):
# get count of mails sent this month
this_month = frappe.db.sql("""select count(*) from `tabBulk Email` where
MONTH(creation)=MONTH(CURDATE())""")[0][0]
status='Sent' and MONTH(creation)=MONTH(CURDATE())""")[0][0]

# if using settings from site_config.json, check bulk limit
# No limit for own email settings
smtp_server = SMTPServer()

if smtp_server.email_account and getattr(smtp_server.email_account,
"from_site_config", False) or frappe.flags.in_test:
if (smtp_server.email_account
and getattr(smtp_server.email_account, "from_site_config", False)
or frappe.flags.in_test):

monthly_bulk_mail_limit = frappe.conf.get('monthly_bulk_mail_limit') or 500

if (this_month + len(recipients)) > monthly_bulk_mail_limit:
@@ -174,6 +179,9 @@ def flush(from_test=False):

auto_commit = not from_test

# additional check
check_bulk_limit([])

if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False:
msgprint(_("Emails are muted"))
from_test = True
@@ -200,11 +208,16 @@ def flush(from_test=False):
frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""",
(email["name"],), auto_commit=auto_commit)

except smtplib.SMTPException:
# bad connection, retry later
frappe.db.sql("""update `tabBulk Email` set status='Not Sent' where name=%s""",
(email["name"],), auto_commit=auto_commit)

except Exception, e:
frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s
where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)

def clear_outbox():
"""remove mails older than 30 days in Outbox"""
"""Remove mails older than 31 days in Outbox. Called daily via scheduler."""
frappe.db.sql("""delete from `tabBulk Email` where
datediff(now(), creation) > 30""")
datediff(now(), creation) > 31""")

+ 5
- 3
frappe/email/doctype/email_account/email_account.py Zobrazit soubor

@@ -124,7 +124,7 @@ class EmailAccount(Document):
exceptions = []
for raw in incoming_mails:
try:
self.insert_communication(raw)
communication = self.insert_communication(raw)

except Exception:
frappe.db.rollback()
@@ -132,6 +132,7 @@ class EmailAccount(Document):

else:
frappe.db.commit()
communication.notify(attachments=communication._attachments, except_recipient=True)

if exceptions:
raise Exception, frappe.as_json(exceptions)
@@ -156,7 +157,7 @@ class EmailAccount(Document):
communication.insert(ignore_permissions = 1)

# save attachments
email.save_attachments_in_doc(communication)
communication._attachments = email.save_attachments_in_doc(communication)

if self.enable_auto_reply and getattr(communication, "is_first", False):
self.send_auto_reply(communication, email)
@@ -164,7 +165,8 @@ class EmailAccount(Document):
# notify all participants of this thread
# convert content to HTML - by default text parts of replies are used.
communication.content = markdown2.markdown(communication.content)
communication.notify(attachments=email.attachments, except_recipient = True)

return communication

def set_thread(self, communication, email):
"""Appends communication to parent based on thread ID. Will extract


+ 7
- 2
frappe/email/receive.py Zobrazit soubor

@@ -153,7 +153,7 @@ class POP3Server:
"Connection timed out",
)
for message in messages:
if message in strip(cstr(e.message)):
if message in strip(cstr(e.message)) or message in strip(cstr(getattr(e, 'strerror', ''))):
return True
return False

@@ -296,10 +296,13 @@ class Email:
def save_attachments_in_doc(self, doc):
"""Save email attachments in given document."""
from frappe.utils.file_manager import save_file, MaxFileSizeReachedError
saved_attachments = []

for attachment in self.attachments:
try:
save_file(attachment['fname'], attachment['fcontent'],
file_data = save_file(attachment['fname'], attachment['fcontent'],
doc.doctype, doc.name)
saved_attachments.append(file_data.file_name)
except MaxFileSizeReachedError:
# WARNING: bypass max file size exception
pass
@@ -307,6 +310,8 @@ class Email:
# same file attached twice??
pass

return saved_attachments

def get_thread_id(self):
"""Extract thread ID from `[]`"""
import re


+ 1
- 0
frappe/exceptions.py Zobrazit soubor

@@ -53,3 +53,4 @@ class EmptyTableError(ValidationError): pass
class LinkExistsError(ValidationError): pass
class InvalidEmailAddressError(ValidationError): pass
class TemplateNotFoundError(ValidationError): pass
class UniqueValidationError(ValidationError): pass

+ 29
- 18
frappe/model/base_document.py Zobrazit soubor

@@ -161,7 +161,7 @@ class BaseDocument(object):
value.parenttype = self.doctype
value.parentfield = key

if value.docstatus==None:
if value.docstatus is None:
value.docstatus = 0

if not getattr(value, "idx", None):
@@ -185,9 +185,8 @@ class BaseDocument(object):
elif df.fieldtype in ("Datetime", "Date") and d[fieldname]=="":
d[fieldname] = None

if d[fieldname]=="":
df = self.meta.get_field(fieldname)
if df and df.fieldtype in ("Datetime", "Date"):
elif df.get("unique") and cstr(d[fieldname]).strip()=="":
# unique empty field should be set to None
d[fieldname] = None

return d
@@ -264,15 +263,23 @@ class BaseDocument(object):
values = ", ".join(["%s"] * len(columns))
), d.values())
except Exception, e:
if e.args[0]==1062 and "PRIMARY" in cstr(e.args[1]):
if self.meta.autoname=="hash":
# hash collision? try again
self.name = None
self.db_insert()
return
type, value, traceback = sys.exc_info()
frappe.msgprint(_("Duplicate name {0} {1}").format(self.doctype, self.name))
raise frappe.DuplicateEntryError, (self.doctype, self.name, e), traceback
if e.args[0]==1062:
if "PRIMARY" in cstr(e.args[1]):
if self.meta.autoname=="hash":
# hash collision? try again
self.name = None
self.db_insert()
return

type, value, traceback = sys.exc_info()
frappe.msgprint(_("Duplicate name {0} {1}").format(self.doctype, self.name))
raise frappe.DuplicateEntryError, (self.doctype, self.name, e), traceback

elif "Duplicate" in cstr(e.args[1]):
# unique constraint
self.show_unique_validation_message(e)
else:
raise
else:
raise

@@ -292,14 +299,18 @@ class BaseDocument(object):
values = ", ".join(["`"+c+"`=%s" for c in columns])
), d.values() + [d.get("name")])
except Exception, e:
if e.args[0]==1062:
type, value, traceback = sys.exc_info()
fieldname = str(e).split("'")[-2]
frappe.msgprint(_("{0} must be unique".format(self.meta.get_label(fieldname))))
raise frappe.ValidationError, (self.doctype, self.name, e), traceback
if e.args[0]==1062 and "Duplicate" in cstr(e.args[1]):
self.show_unique_validation_message(e)
else:
raise

def show_unique_validation_message(self, e):
type, value, traceback = sys.exc_info()
fieldname = str(e).split("'")[-2]
label = fieldname if fieldname.startswith("unique_") else self.meta.get_label(fieldname)
frappe.msgprint(_("{0} must be unique".format(label)))
raise frappe.UniqueValidationError, (self.doctype, self.name, e), traceback

def db_set(self, fieldname, value, update_modified=True):
self.set(fieldname, value)
self.set("modified", now())


+ 1
- 0
frappe/patches.txt Zobrazit soubor

@@ -84,6 +84,7 @@ frappe.patches.v5_0.expire_old_scheduler_logs
execute:frappe.permissions.reset_perms("DocType")
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` = 'idx'")
frappe.patches.v5_2.change_checks_to_not_null
frappe.patches.v5_3.rename_chinese_languages

frappe.patches.v6_0.make_task_log_folder
frappe.patches.v6_0.document_type_rename

frappe/translations/en.csv → frappe/patches/v5_3/__init__.py Zobrazit soubor


+ 18
- 0
frappe/patches/v5_3/rename_chinese_languages.py Zobrazit soubor

@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import frappe

def execute():
language_map = {
"中国(简体)": "簡體中文",
"中國(繁體)": "正體中文"
}

language_in_system_settings = frappe.db.get_single_value("System Settings", "language")
if language_in_system_settings in language_map:
new_language_name = language_map[language_in_system_settings]
frappe.db.set_value("System Settings", "System Settings", "language", new_language_name)

for old_name, new_name in language_map.items():
frappe.db.sql("""update `tabUser` set language=%(new_name)s where language=%(old_name)s""",
{ "old_name": old_name, "new_name": new_name })

+ 6
- 4
frappe/permissions.py Zobrazit soubor

@@ -44,17 +44,19 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):

def false_if_not_shared():
if ptype in ("read", "write", "share", "email", "print"):
shared = frappe.share.get_shared(doctype, user,
["read" if ptype in ("email", "print") else ptype])

if doc:
doc_name = doc if isinstance(doc, basestring) else doc.name
shared = frappe.share.get_shared(doctype, user,
["read" if ptype in ("email", "print") else ptype])

if doc_name in shared:
if verbose: print "Shared"
if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype):
return True

else:
elif shared:
# if atleast one shared doc of that type, then return True
# this is used in db_query to check if permission on DocType
if verbose: print "Has a shared document"
return True



+ 1
- 1
frappe/public/js/frappe/form/formatters.js Zobrazit soubor

@@ -92,7 +92,7 @@ frappe.form.formatters = {
},
Text: function(value) {
if(value) {
var tags = ["<p", "<div", "<br"];
var tags = ["<p", "<div", "<br", "<table"];
var match = false;

for(var i=0; i<tags.length; i++) {


+ 16
- 1
frappe/public/js/frappe/form/save.js Zobrazit soubor

@@ -38,9 +38,24 @@ frappe.ui.form.save = function(frm, action, callback, btn) {
};

var cancel = function() {
var args = {
doctype: frm.doc.doctype,
name: frm.doc.name
};
// update workflow state value if workflow exists
var workflow_state_fieldname = frappe.workflow.get_state_fieldname(frm.doctype);
if(workflow_state_fieldname) {
$.extend(args, {
workflow_state_fieldname: workflow_state_fieldname,
workflow_state: frm.doc[workflow_state_fieldname]
});
}
_call({
method: "frappe.desk.form.save.cancel",
args: { doctype: frm.doc.doctype, name: frm.doc.name },
args: args,
callback: function(r) {
$(document).trigger("save", [frm.doc]);
callback(r);


+ 1
- 1
frappe/public/js/frappe/ui/toolbar/about.js Zobrazit soubor

@@ -13,7 +13,7 @@ frappe.ui.misc.about = function() {
<h4>Installed Apps</h4>\
<div id='about-app-versions'>Loading versions...</div>\
<hr>\
<p class='text-muted'>&copy; 2014 Frappe Technologies Pvt. Ltd and contributors </p> \
<p class='text-muted'>&copy; 2015 Frappe Technologies Pvt. Ltd and contributors </p> \
</div>", frappe.app));

frappe.ui.misc.about_dialog = d;


+ 1
- 1
frappe/public/js/frappe/ui/toolbar/navbar.html Zobrazit soubor

@@ -35,7 +35,7 @@
{%= __("About") %}</a></li>
<li><a href="https://frappe.io" target="_blank" data-link="docs">
{%= __("Documentation") %}</a></li>
<li><a href="https://discuss.frappe.io" target="_blank">
<li><a href="https://discuss.erpnext.com" target="_blank">
{%= __("Forums") %}</a></li>
<li><a href="https://github.com/frappe/erpnext/issues" target="_blank">
{%= __("Report an Issue") %}</a></li>


+ 1
- 1
frappe/public/js/frappe/ui/toolbar/offcanvas_left_sidebar.html Zobrazit soubor

@@ -25,7 +25,7 @@
{%= __("About") %}</a></li>
<li><a href="https://frappe.io" target="_blank" data-link="docs">
{%= __("Documentation") %}</a></li>
<li><a href="https://discuss.frappe.io" target="_blank">
<li><a href="https://discuss.erpnext.com" target="_blank">
{%= __("Forums") %}</a></li>
<li><a href="https://github.com/frappe/erpnext/issues" target="_blank">
{%= __("Report an Issue") %}</a></li>


+ 9
- 0
frappe/share.py Zobrazit soubor

@@ -3,6 +3,7 @@

from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint

@frappe.whitelist()
@@ -11,6 +12,8 @@ def add(doctype, name, user=None, read=1, write=0, share=0, everyone=0, flags=No
if not user:
user = frappe.session.user

check_share_permission(doctype, name)

share_name = get_share_name(doctype, name, user, everyone)

if share_name:
@@ -48,6 +51,8 @@ def remove(doctype, name, user, flags=None):
@frappe.whitelist()
def set_permission(doctype, name, user, permission_to, value=1, everyone=0):
"""Set share permission."""
check_share_permission(doctype, name)

share_name = get_share_name(doctype, name, user, everyone)
value = int(value)

@@ -124,3 +129,7 @@ def get_share_name(doctype, name, user, everyone):

return share_name

def check_share_permission(doctype, name):
"""Check if the user can share with other users"""
if not frappe.has_permission(doctype, ptype="share", doc=name):
frappe.throw(_("No permission to {0} {1} {2}".format("share", doctype, name)), frappe.PermissionError)

+ 33
- 1
frappe/tasks.py Zobrazit soubor

@@ -11,6 +11,8 @@ from frappe.handler import execute_cmd
from frappe.async import set_task_status, END_LINE, get_std_streams
import frappe.utils.response
import sys
import time
import MySQLdb

@celery_task()
def sync_queues():
@@ -134,7 +136,6 @@ def pull_from_email_account(site, email_account):
finally:
frappe.destroy()


@celery_task(bind=True)
def run_async_task(self, site, user, cmd, form_dict):
ret = {}
@@ -177,3 +178,34 @@ def run_async_task(self, site, user, cmd, form_dict):
sys.stderr.close()
sys.stdout, sys.stderr = 1, 0
return ret


@celery_task()
def sendmail(site, communication_name, print_html=None, print_format=None, attachments=None, recipients=None, except_recipient=False):
try:
frappe.connect(site=site)

# upto 3 retries
for i in xrange(3):
try:
communication = frappe.get_doc("Communication", communication_name)
communication._notify(print_html=print_html, print_format=print_format, attachments=attachments, recipients=recipients, except_recipient=except_recipient)
except MySQLdb.OperationalError, e:
# deadlock, try again
if e.args[0]==1213:
frappe.db.rollback()
time.sleep(1)
continue
else:
raise
else:
break

except:
frappe.db.rollback()

else:
frappe.db.commit()

finally:
frappe.destroy()

+ 393
- 353
frappe/translations/ar.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/bg.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 0
- 0
frappe/translations/bo.csv Zobrazit soubor


+ 392
- 352
frappe/translations/bs.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/ca.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/cs.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/da.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 397
- 357
frappe/translations/de.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/el.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/es.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 393
- 350
frappe/translations/fa.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/fi.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 394
- 354
frappe/translations/fr.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 379
- 339
frappe/translations/he.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/hi.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/hr.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/hu.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 400
- 360
frappe/translations/id.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/it.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 397
- 359
frappe/translations/ja.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1356
- 0
frappe/translations/km.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/kn.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 408
- 368
frappe/translations/ko.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/lv.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/mk.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 349
frappe/translations/mr.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/my.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 393
- 353
frappe/translations/nl.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/no.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 642
- 602
frappe/translations/pl.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/pt-BR.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/pt.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/ro.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/ru.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 0
- 0
frappe/translations/se.csv Zobrazit soubor


+ 392
- 352
frappe/translations/sk.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/sq.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/sr.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1509
- 0
frappe/translations/sv.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/ta.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/th.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 396
- 356
frappe/translations/tr.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/vi.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 392
- 352
frappe/translations/zh-cn.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 437
- 398
frappe/translations/zh-tw.csv
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


Načítá se…
Zrušit
Uložit