@@ -1,7 +1,7 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"allow_rename": 1, | |||
"autoname": "hash", | |||
"creation": "2012-12-12 11:19:22", | |||
"custom": 0, | |||
@@ -345,7 +345,7 @@ | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"modified": "2015-09-03 05:17:44.827959", | |||
"modified": "2015-09-08 15:57:09.103049", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "File", | |||
@@ -12,7 +12,8 @@ import frappe, frappe.utils | |||
from frappe.utils.file_manager import delete_file_data_content | |||
from frappe import _ | |||
from frappe.utils.nestedset import NestedSet | |||
from frappe.utils.nestedset import NestedSet, get_successor_of | |||
import json | |||
class File(NestedSet): | |||
nsm_parent_field = 'folder'; | |||
@@ -23,13 +24,16 @@ class File(NestedSet): | |||
self.set_folder_name() | |||
self.set_name() | |||
def get_name_based_on_parent_folder(self): | |||
path = get_breadcrumbs(self.folder) | |||
folder_name = frappe.get_value("File", self.folder, "file_name") | |||
return "/".join([d.file_name for d in path] + [folder_name, self.file_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]) | |||
self.name = self.get_name_based_on_parent_folder() | |||
else: | |||
# home | |||
self.name = self.file_name | |||
@@ -38,7 +42,14 @@ class File(NestedSet): | |||
def after_insert(self): | |||
self.update_parent_folder_size() | |||
def after_rename(self, olddn, newdn, merge=False): | |||
for successor in self.get_successor(): | |||
setup_folder_path(successor, self.name) | |||
def get_successor(self): | |||
return frappe.db.sql_list("select name from tabFile where folder='%s'"%self.name) or [] | |||
def validate(self): | |||
self.validate_duplicate_entry() | |||
self.validate_folder() | |||
@@ -56,8 +67,10 @@ class File(NestedSet): | |||
"""Returns folder size for current folder""" | |||
if not folder: | |||
folder = self.name | |||
return frappe.db.sql("""select sum(ifnull(file_size,0)) | |||
from tabFile where folder=%s""", folder)[0][0] | |||
file_size = frappe.db.sql("""select sum(ifnull(file_size,0)) | |||
from tabFile where folder=%s """, (folder))[0][0] | |||
return file_size | |||
def update_parent_folder_size(self): | |||
"""Update size of parent folder""" | |||
@@ -192,3 +205,22 @@ def create_new_folder(file_name, folder): | |||
file.is_folder = 1 | |||
file.folder = folder | |||
file.insert() | |||
@frappe.whitelist() | |||
def move_file(file_list, new_parent, old_parent): | |||
for file_obj in json.loads(file_list): | |||
setup_folder_path(file_obj.get("name"), new_parent) | |||
# recalculate sizes | |||
frappe.get_doc("File", old_parent).save() | |||
frappe.get_doc("File", new_parent).save() | |||
return "File(s) has been moved successfully!!" | |||
def setup_folder_path(filename, new_parent): | |||
file = frappe.get_doc("File", filename) | |||
file.folder = new_parent | |||
file.save() | |||
if file.is_folder: | |||
frappe.rename_doc("File", file.name, file.get_name_based_on_parent_folder()) |
@@ -68,6 +68,39 @@ frappe.listview_settings['File'] = { | |||
}, {}); | |||
}); | |||
}, | |||
add_menu_item_copy: function(doclist){ | |||
if (!doclist.copy) { | |||
var copy_menu = doclist.page.add_menu_item(__("Copy"), function() { | |||
if(doclist.$page.find(".list-delete:checked").length){ | |||
doclist.selected_files = doclist.get_checked_items(); | |||
doclist.old_parent = doclist.current_folder; | |||
doclist.listview.settings.add_menu_item_paste(doclist); | |||
} | |||
else{ | |||
frappe.throw("Please select file to copy"); | |||
} | |||
}) | |||
doclist.copy = true; | |||
} | |||
}, | |||
add_menu_item_paste:function(doclist){ | |||
var paste_menu = doclist.page.add_menu_item(__("Paste"), function(){ | |||
frappe.call({ | |||
method:"frappe.core.doctype.file.file.move_file", | |||
args: { | |||
"file_list": doclist.selected_files, | |||
"new_parent": doclist.current_folder, | |||
"old_parent": doclist.old_parent | |||
}, | |||
callback:function(r){ | |||
doclist.paste = false; | |||
frappe.msgprint(__(r.message)); | |||
doclist.selected_files = []; | |||
$(paste_menu).remove(); | |||
} | |||
}) | |||
}) | |||
}, | |||
before_run: function(doclist) { | |||
var name_filter = doclist.filter_list.get_filter("file_name"); | |||
if(name_filter) { | |||
@@ -5,8 +5,85 @@ from __future__ import unicode_literals | |||
import frappe | |||
import unittest | |||
from frappe.utils.file_manager import save_file, get_file, get_files_path | |||
from frappe import _ | |||
from frappe.core.doctype.file.file import move_file | |||
import json | |||
# test_records = frappe.get_test_records('File') | |||
class TestFile(unittest.TestCase): | |||
pass | |||
def setUp(self): | |||
self.delete_exist_folder() | |||
self.upload_file() | |||
def test_file_upload(self): | |||
self.execute_tests_after_upload() | |||
self.execute_test_copy_doc() | |||
self.execute_test_non_parent_folder() | |||
def delete_exist_folder(self): | |||
file_name = frappe.db.get_value("File", {"file_url":"/files/hello.txt"}, "name") | |||
if file_name: | |||
file = frappe.get_doc("File", file_name) | |||
ancestors = file.get_ancestors() | |||
file.delete() | |||
self.delete_ancestors(ancestors) | |||
self.execute_tests_after_trash() | |||
def delete_ancestors(self, ancestors): | |||
for folder in ancestors: | |||
if folder != "Home": | |||
folder = frappe.get_doc("File", folder) | |||
folder.delete() | |||
def execute_tests_after_trash(self): | |||
if frappe.db.get_value("File", _("Home/Test_Folder_Copy"), "folder"): | |||
file_size = frappe.db.get_value("File", _("Home/Test_Folder_Copy"), "file_size") | |||
self.assertEqual(file_size, 0) | |||
def upload_file(self): | |||
self.attached_to_doctype, self.attached_to_docname = self.create_event() | |||
self.saved_file = save_file('hello.txt', "hello world", \ | |||
self.attached_to_doctype, self.attached_to_docname) | |||
self.saved_filename = get_files_path(self.saved_file.file_name) | |||
def create_event(self): | |||
event = frappe.get_doc({ | |||
"doctype": "Event", | |||
"subject":"File Upload Event", | |||
"starts_on": "2014-01-01", | |||
"event_type": "Public" | |||
}).insert() | |||
return event.doctype, event.name | |||
def execute_tests_after_upload(self): | |||
self.assertTrue(frappe.db.get_value("File", | |||
"Home/Desk/Event/%s"%self.attached_to_docname, "is_folder")) | |||
self.assertEqual("Home/Desk/Event/%s"%self.attached_to_docname, \ | |||
frappe.db.get_value("File", {"file_url":"/files/hello.txt"}, "folder")) | |||
def execute_test_copy_doc(self): | |||
folder = frappe.get_doc({ | |||
"doctype": "File", | |||
"file_name": _("Test_Folder_Copy"), | |||
"is_folder": 1, | |||
"folder": _("Home") | |||
}).insert() | |||
file = frappe.get_doc("File", "/files/hello.txt") | |||
file_dict = [{"name": file.name}] | |||
move_file(json.dumps(file_dict), folder.name, file.folder) | |||
file = frappe.get_doc("File", "/files/hello.txt") | |||
self.assertEqual(_("Home/Test_Folder_Copy"), file.folder) | |||
def execute_test_non_parent_folder(self): | |||
d = frappe.get_doc({ | |||
"doctype": "File", | |||
"file_name": _("Test_Folder"), | |||
"is_folder": 1 | |||
}) | |||
self.assertRaises(frappe.ValidationError, d.save) |