@@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json | |||||
from .exceptions import * | from .exceptions import * | ||||
from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | ||||
__version__ = '10.0.9' | |||||
__version__ = '10.0.10' | |||||
__title__ = "Frappe Framework" | __title__ = "Frappe Framework" | ||||
local = Local() | local = Local() | ||||
@@ -520,6 +520,36 @@ | |||||
"set_only_once": 0, | "set_only_once": 0, | ||||
"unique": 0 | "unique": 0 | ||||
}, | }, | ||||
{ | |||||
"allow_bulk_edit": 0, | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "attached_to_field", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_global_search": 0, | |||||
"in_list_view": 0, | |||||
"in_standard_filter": 0, | |||||
"label": "Attached To Field", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 1, | |||||
"remember_last_selected_value": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | { | ||||
"allow_bulk_edit": 0, | "allow_bulk_edit": 0, | ||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
@@ -653,7 +683,7 @@ | |||||
"istable": 0, | "istable": 0, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"menu_index": 0, | "menu_index": 0, | ||||
"modified": "2017-10-27 13:27:43.882914", | |||||
"modified": "2018-01-15 03:41:23.876072", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "File", | "name": "File", | ||||
@@ -75,8 +75,8 @@ class File(NestedSet): | |||||
self.set_folder_size() | self.set_folder_size() | ||||
if frappe.db.exists('File', {'name': self.name, 'is_folder': 0}): | if frappe.db.exists('File', {'name': self.name, 'is_folder': 0}): | ||||
old_file_url = self.file_url | |||||
if not self.is_folder and (self.is_private != self.db_get('is_private')): | if not self.is_folder and (self.is_private != self.db_get('is_private')): | ||||
old_file_url = self.file_url | |||||
private_files = frappe.get_site_path('private', 'files') | private_files = frappe.get_site_path('private', 'files') | ||||
public_files = frappe.get_site_path('public', 'files') | public_files = frappe.get_site_path('public', 'files') | ||||
@@ -92,10 +92,20 @@ class File(NestedSet): | |||||
self.file_url = "/private/files/{0}".format(self.file_name) | self.file_url = "/private/files/{0}".format(self.file_name) | ||||
# update documents image url with new file url | # update documents image url with new file url | ||||
if self.attached_to_doctype and self.attached_to_name and \ | |||||
frappe.db.get_value(self.attached_to_doctype, self.attached_to_name, "image") == old_file_url: | |||||
frappe.db.set_value(self.attached_to_doctype, self.attached_to_name, "image", self.file_url) | |||||
if self.attached_to_doctype and self.attached_to_name: | |||||
if not self.attached_to_field: | |||||
field_name = None | |||||
reference_dict = frappe.get_doc(self.attached_to_doctype, self.attached_to_name).as_dict() | |||||
for key, value in reference_dict.items(): | |||||
if value == old_file_url: | |||||
field_name = key | |||||
break | |||||
self.attached_to_field = field_name | |||||
if self.attached_to_field: | |||||
frappe.db.set_value(self.attached_to_doctype, self.attached_to_name, self.attached_to_field, self.file_url) | |||||
def set_folder_size(self): | def set_folder_size(self): | ||||
"""Set folder size if folder""" | """Set folder size if folder""" | ||||
@@ -247,12 +247,27 @@ frappe.ui.Page = Class.extend({ | |||||
//-- Generic --// | //-- Generic --// | ||||
/* | |||||
* Add label to given drop down menu. If label, is already contained in the drop | |||||
* down menu, it will be ignored. | |||||
* @param {string} label - Text for the drop down menu | |||||
* @param {function} click - function to be called when `label` is clicked | |||||
* @param {Boolean} standard | |||||
* @param {object} parent - DOM object representing the parent of the drop down item lists | |||||
*/ | |||||
add_dropdown_item: function(label, click, standard, parent) { | add_dropdown_item: function(label, click, standard, parent) { | ||||
const is_already_added = () => { | |||||
let found_lists = $(parent).find('li > a.grey-link:contains(' + label + ')'); | |||||
return found_lists.length > 0; | |||||
} | |||||
parent.parent().removeClass("hide"); | parent.parent().removeClass("hide"); | ||||
var $li = $('<li><a class="grey-link">'+ label +'</a><li>'), | var $li = $('<li><a class="grey-link">'+ label +'</a><li>'), | ||||
$link = $li.find("a").on("click", click); | $link = $li.find("a").on("click", click); | ||||
if (is_already_added()) return; | |||||
if(standard===true) { | if(standard===true) { | ||||
$li.appendTo(parent); | $li.appendTo(parent); | ||||
} else { | } else { | ||||
@@ -24,6 +24,7 @@ def upload(): | |||||
# get record details | # get record details | ||||
dt = frappe.form_dict.doctype | dt = frappe.form_dict.doctype | ||||
dn = frappe.form_dict.docname | dn = frappe.form_dict.docname | ||||
df = frappe.form_dict.docfield | |||||
file_url = frappe.form_dict.file_url | file_url = frappe.form_dict.file_url | ||||
filename = frappe.form_dict.filename | filename = frappe.form_dict.filename | ||||
frappe.form_dict.is_private = cint(frappe.form_dict.is_private) | frappe.form_dict.is_private = cint(frappe.form_dict.is_private) | ||||
@@ -53,30 +54,31 @@ def upload(): | |||||
"comment": comment.as_dict() if comment else {} | "comment": comment.as_dict() if comment else {} | ||||
} | } | ||||
def get_file_doc(dt=None, dn=None, folder=None, is_private=None): | |||||
def get_file_doc(dt=None, dn=None, folder=None, is_private=None, df=None): | |||||
'''returns File object (Document) from given parameters or form_dict''' | '''returns File object (Document) from given parameters or form_dict''' | ||||
r = frappe.form_dict | r = frappe.form_dict | ||||
if dt is None: dt = r.doctype | if dt is None: dt = r.doctype | ||||
if dn is None: dn = r.docname | if dn is None: dn = r.docname | ||||
if df is None: df = r.docfield | |||||
if folder is None: folder = r.folder | if folder is None: folder = r.folder | ||||
if is_private is None: is_private = r.is_private | if is_private is None: is_private = r.is_private | ||||
if r.filedata: | if r.filedata: | ||||
file_doc = save_uploaded(dt, dn, folder, is_private) | |||||
file_doc = save_uploaded(dt, dn, folder, is_private, df) | |||||
elif r.file_url: | elif r.file_url: | ||||
file_doc = save_url(r.file_url, r.filename, dt, dn, folder, is_private) | |||||
file_doc = save_url(r.file_url, r.filename, dt, dn, folder, is_private, df) | |||||
return file_doc | return file_doc | ||||
def save_uploaded(dt, dn, folder, is_private): | |||||
def save_uploaded(dt, dn, folder, is_private, df=None): | |||||
fname, content = get_uploaded_content() | fname, content = get_uploaded_content() | ||||
if content: | if content: | ||||
return save_file(fname, content, dt, dn, folder, is_private=is_private); | |||||
return save_file(fname, content, dt, dn, folder, is_private=is_private, df=df); | |||||
else: | else: | ||||
raise Exception | raise Exception | ||||
def save_url(file_url, filename, dt, dn, folder, is_private): | |||||
def save_url(file_url, filename, dt, dn, folder, is_private, df=None): | |||||
# if not (file_url.startswith("http://") or file_url.startswith("https://")): | # if not (file_url.startswith("http://") or file_url.startswith("https://")): | ||||
# frappe.msgprint("URL must start with 'http://' or 'https://'") | # frappe.msgprint("URL must start with 'http://' or 'https://'") | ||||
# return None, None | # return None, None | ||||
@@ -89,6 +91,7 @@ def save_url(file_url, filename, dt, dn, folder, is_private): | |||||
"file_name": filename, | "file_name": filename, | ||||
"attached_to_doctype": dt, | "attached_to_doctype": dt, | ||||
"attached_to_name": dn, | "attached_to_name": dn, | ||||
"attached_to_field": df, | |||||
"folder": folder, | "folder": folder, | ||||
"is_private": is_private | "is_private": is_private | ||||
}) | }) | ||||
@@ -111,7 +114,7 @@ def get_uploaded_content(): | |||||
frappe.msgprint(_('No file attached')) | frappe.msgprint(_('No file attached')) | ||||
return None, None | return None, None | ||||
def save_file(fname, content, dt, dn, folder=None, decode=False, is_private=0): | |||||
def save_file(fname, content, dt, dn, folder=None, decode=False, is_private=0, df=None): | |||||
if decode: | if decode: | ||||
if isinstance(content, text_type): | if isinstance(content, text_type): | ||||
content = content.encode("utf-8") | content = content.encode("utf-8") | ||||
@@ -136,6 +139,7 @@ def save_file(fname, content, dt, dn, folder=None, decode=False, is_private=0): | |||||
"doctype": "File", | "doctype": "File", | ||||
"attached_to_doctype": dt, | "attached_to_doctype": dt, | ||||
"attached_to_name": dn, | "attached_to_name": dn, | ||||
"attached_to_field": df, | |||||
"folder": folder, | "folder": folder, | ||||
"file_size": file_size, | "file_size": file_size, | ||||
"content_hash": content_hash, | "content_hash": content_hash, | ||||