diff --git a/frappe/__init__.py b/frappe/__init__.py index 2ab0c18038..dede506209 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -38,8 +38,11 @@ class _dict(dict): def copy(self): return _dict(dict(self).copy()) -def _(msg): +def _(msg, lang=None): """Returns translated string in current lang, if exists.""" + if not lang: + lang = local.lang + if local.lang == "en": return msg @@ -905,6 +908,20 @@ def get_all(doctype, *args, **kwargs): kwargs["limit_page_length"] = 0 return get_list(doctype, *args, **kwargs) +def get_value(*args, **kwargs): + """Returns a document property or list of properties. + + Alias for `frappe.db.get_value` + + :param doctype: DocType name. + :param filters: Filters like `{"x":"y"}` or name of the document. `None` if Single DocType. + :param fieldname: Column name. + :param ignore: Don't raise exception if table, column is missing. + :param as_dict: Return values as dict. + :param debug: Print query in error log. + """ + return db.get_value(*args, **kwargs) + def add_version(doc): """Insert a new **Version** of the given document. A **Version** is a JSON dump of the current document state.""" diff --git a/frappe/core/doctype/file/file.json b/frappe/core/doctype/file/file.json index 9a6c5d0cc8..a8ff6310c9 100644 --- a/frappe/core/doctype/file/file.json +++ b/frappe/core/doctype/file/file.json @@ -8,6 +8,29 @@ "docstatus": 0, "doctype": "DocType", "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "file_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "File Name", + "no_copy": 0, + "oldfieldname": "file_name", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -34,9 +57,10 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "depends_on": "", "fieldname": "is_home_folder", "fieldtype": "Check", - "hidden": 0, + "hidden": 1, "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, @@ -52,6 +76,49 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:!doc.is_folder", + "fieldname": "file_url", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "File URL", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_5", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -79,16 +146,14 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "file_name", - "fieldtype": "Data", + "fieldname": "file_size", + "fieldtype": "Int", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, - "in_list_view": 0, - "label": "File Name", + "in_list_view": 1, + "label": "File Size", "no_copy": 0, - "oldfieldname": "file_name", - "oldfieldtype": "Data", "permlevel": 0, "print_hide": 0, "read_only": 1, @@ -102,17 +167,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "file_url", - "fieldtype": "Data", + "fieldname": "section_break_8", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, - "label": "File URL", "no_copy": 0, "permlevel": 0, + "precision": "", "print_hide": 0, - "read_only": 1, + "read_only": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -145,20 +210,20 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "attached_to_name", - "fieldtype": "Data", + "fieldname": "column_break_10", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, - "label": "Attached To Name", "no_copy": 0, "permlevel": 0, + "precision": "", "print_hide": 0, - "read_only": 1, + "read_only": 0, "report_hide": 0, "reqd": 0, - "search_index": 1, + "search_index": 0, "set_only_once": 0, "unique": 0 }, @@ -166,20 +231,20 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "file_size", - "fieldtype": "Int", + "fieldname": "attached_to_name", + "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, - "in_list_view": 1, - "label": "File Size", + "in_list_view": 0, + "label": "Attached To Name", "no_copy": 0, "permlevel": 0, "print_hide": 0, "read_only": 1, "report_hide": 0, "reqd": 0, - "search_index": 0, + "search_index": 1, "set_only_once": 0, "unique": 0 }, @@ -275,12 +340,12 @@ "hide_toolbar": 0, "icon": "icon-file", "idx": 1, - "in_create": 1, + "in_create": 0, "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-09-02 06:17:57.856863", + "modified": "2015-09-03 05:17:44.827959", "modified_by": "Administrator", "module": "Core", "name": "File", diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index ed775ed621..e234bc8c9d 100644 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -21,6 +21,20 @@ class File(NestedSet): def before_insert(self): frappe.local.rollback_observers.append(self) self.set_folder_name() + self.set_name() + + def set_name(self): + """Set name for folder""" + if self.is_folder: + if self.folder: + path = get_breadcrumbs(self.folder) + folder_name = frappe.get_value("File", self.folder, "file_name") + self.name = "/".join([d.file_name for d in path] + [folder_name, self.file_name]) + else: + # home + self.name = self.file_name + else: + self.name = self.file_url def after_insert(self): self.update_parent_folder_size() @@ -32,7 +46,7 @@ class File(NestedSet): def set_folder_size(self): """Set folder size if folder""" - if self.is_folder: + if self.is_folder and not self.is_new(): self.fize_size = self.get_folder_size() for folder in self.get_ancestors(): @@ -45,33 +59,33 @@ class File(NestedSet): return frappe.db.sql("""select sum(ifnull(file_size,0)) from tabFile where folder=%s""", folder)[0][0] + def update_parent_folder_size(self): + """Update size of parent folder""" + if self.folder and not self.is_folder: # it not home + frappe.get_doc("File", self.folder).save() + def set_folder_name(self): """Make parent folders if not exists based on reference doctype and name""" if self.attached_to_doctype and not self.folder: self.folder = self.get_parent_folder_name() - def update_parent_folder_size(self): - """Update size of parent folder""" - if self.folder: # it not home - frappe.get_doc("File", self.folder).save() - def get_parent_folder_name(self): """Returns parent folder name. If not exists, then make""" + doctype_folder_name = self.get_doctype_folder_name() + parent_folder_name = frappe.db.get_value("File", {"file_name": self.attached_to_name, + "is_folder": 1, "folder": doctype_folder_name}) + + return self.make_folder(parent_folder_name, doctype_folder_name, + self.attached_to_name) + + def get_doctype_folder_name(self): + """Returns doctype folder name. If not exists, then make""" module_folder_name = self.get_module_folder_name() - parent_folder_name = frappe.db.get_value("File", {"file_name": self.attached_to_doctype, + doctype_folder_name = frappe.db.get_value("File", {"file_name": self.attached_to_doctype, "is_folder": 1, "folder": module_folder_name}) - if not parent_folder_name: - # parent folder - parent_folder = frappe.get_doc({ - "doctype": "File", - "is_folder": 1, - "file_name": _(self.attached_to_doctype), - "folder": module_folder_name - }).insert() - - parent_folder_name = parent_folder.name - return parent_folder_name + return self.make_folder(doctype_folder_name, module_folder_name, + _(self.attached_to_doctype, frappe.db.get_default("lang"))) def get_module_folder_name(self): """Returns module folder name. If not exists, then make""" @@ -83,18 +97,22 @@ class File(NestedSet): module_folder_name = frappe.db.get_value("File", {"file_name": module, "is_folder": 1, "folder": home_folder_name}) - if not module_folder_name: - module_folder = frappe.get_doc({ + return self.make_folder(module_folder_name, home_folder_name, _(module, + frappe.db.get_default("lang"))) + + def make_folder(self, name, folder, file_name): + if not name: + # parent folder + file = frappe.get_doc({ "doctype": "File", "is_folder": 1, - "file_name": _(module), - "folder": home_folder_name + "file_name": file_name, + "folder": folder }).insert() - module_folder_name = module_folder.name - - return module_folder_name + name = file.name + return name def validate_folder(self): if not self.is_home_folder and not self.folder and \ diff --git a/frappe/core/doctype/file/file_list.js b/frappe/core/doctype/file/file_list.js index 1fe15e0038..3b75b210de 100644 --- a/frappe/core/doctype/file/file_list.js +++ b/frappe/core/doctype/file/file_list.js @@ -1,14 +1,7 @@ -//TODO - -// show breadcrumbs -// search bar to add search filter -// back button -// new - // if file, attach - // if folder, set name frappe.listview_settings['File'] = { hide_name_column: true, + use_route: true, add_fields: ["is_folder", "file_name"], formatters: { file_size: function(value) { @@ -32,12 +25,23 @@ frappe.listview_settings['File'] = { } }, onload: function(doclist) { - doclist.breadcrumb = $('
') - .insertBefore(doclist.wrapper.find(".show_filters")); + doclist.filter_area = doclist.wrapper.find(".show_filters"); + doclist.breadcrumb = $(' ') + .insertBefore(doclist.filter_area); + }, + before_run: function(doclist) { + var name_filter = doclist.filter_list.get_filter("file_name"); + if(name_filter) { + doclist.filter_area.removeClass("hide"); + doclist.breadcrumb.addClass("hide"); + } else { + doclist.filter_area.addClass("hide"); + doclist.breadcrumb.removeClass("hide"); + } }, refresh: function(doclist) { // set folder before querying - var name_filter = doclist.filter_list.get_filter("name"); + var name_filter = doclist.filter_list.get_filter("file_name"); var folder_filter = doclist.filter_list.get_filter("folder"); if(folder_filter) { @@ -46,6 +50,12 @@ frappe.listview_settings['File'] = { if(name_filter) return; + var route = frappe.get_route(); + if(route[2]) { + doclist.current_folder = route.slice(2).join("/"); + doclist.current_folder_name = route.slice(-1)[0]; + } + if(!doclist.current_folder) { doclist.current_folder = frappe.boot.home_folder; doclist.current_folder_name = __("Home"); @@ -58,14 +68,12 @@ frappe.listview_settings['File'] = { }, post_render_item: function(list, row, data) { if(data.is_folder) { - $(row).find(".list-id").on("click", function() { - list.doclistview.current_folder = data.name; - list.doclistview.current_folder_name = data.file_name; - list.doclistview.refresh(); - return false; - }); + $(row).find(".list-id").attr("href", "#List/File/" + data.name); } }, + set_file_route: function(name) { + frappe.set_route(["List", "File"].concat(decodeURIComponent(name).split("/"))); + }, post_render: function(doclist) { frappe.call({ method: "frappe.core.doctype.file.file.get_breadcrumbs", @@ -76,16 +84,9 @@ frappe.listview_settings['File'] = { doclist.breadcrumb.empty(); if(r.message && r.message.length) { $.each(r.message, function(i, folder) { - $('