diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 592d152e2f..b1cc85bd95 100644 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -9,7 +9,7 @@ naming for same name files: file.gif, file-1.gif, file-2.gif etc """ import frappe, frappe.utils -from frappe.utils.file_manager import delete_file_data_content +from frappe.utils.file_manager import delete_file_data_content, get_content_hash from frappe import _ from frappe.utils.nestedset import NestedSet @@ -67,7 +67,11 @@ class File(NestedSet): if self.is_new(): self.validate_duplicate_entry() self.validate_folder() - self.validate_file() + + if not self.flags.ignore_file_validate: + self.validate_file() + self.generate_content_hash() + self.set_folder_size() def set_folder_size(self): @@ -108,7 +112,7 @@ class File(NestedSet): if not self.file_name: self.file_name = self.file_url.split("/files/")[-1] - if not os.path.exists(get_files_path(self.file_name)): + if not os.path.exists(get_files_path(self.file_name.lstrip("/"))): frappe.throw(_("File {0} does not exist").format(self.file_url), IOError) def validate_duplicate_entry(self): @@ -126,6 +130,18 @@ class File(NestedSet): self.duplicate_entry = n_records[0][0] frappe.throw(frappe._("Same file has already been attached to the record"), frappe.DuplicateEntryError) + def generate_content_hash(self): + if self.content_hash or not self.file_url: + return + + if self.file_url.startswith("/files/"): + try: + with open(get_files_path(self.file_name.lstrip("/")), "r") as f: + self.content_hash = get_content_hash(f.read()) + except IOError: + frappe.msgprint(_("File {0} does not exist").format(self.file_url)) + raise + def on_trash(self): if self.is_home_folder or self.is_attachments_folder: frappe.throw(_("Cannot delete Home and Attachments folders")) diff --git a/frappe/patches.txt b/frappe/patches.txt index fd006e9ced..89a508485b 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -11,10 +11,12 @@ execute:frappe.reload_doc('core', 'doctype', 'version') #2014-02-21 execute:frappe.reload_doc('email', 'doctype', 'email_alert') #2014-07-15 execute:frappe.reload_doc('desk', 'doctype', 'todo') #2014-12-31-1 execute:frappe.reload_doc('custom', 'doctype', 'property_setter') #2014-12-31-1 +execute:frappe.reload_doc('core', 'doctype', 'patch_log') #2016-10-31 execute:frappe.reload_doctype("File") # 2015-10-19 execute:frappe.db.sql("alter table `tabSessions` modify `user` varchar(255), engine=InnoDB") execute:frappe.db.sql("delete from `tabDocField` where parent='0'") frappe.patches.v4_0.change_varchar_length +frappe.patches.v6_4.reduce_varchar_length frappe.patches.v5_0.v4_to_v5 frappe.patches.v5_0.remove_shopping_cart_app @@ -96,9 +98,9 @@ frappe.patches.v6_2.ignore_user_permissions_if_missing execute:frappe.db.sql("delete from tabSessions where user is null") frappe.patches.v6_2.rename_backup_manager execute:frappe.delete_doc("DocType", "Backup Manager") -frappe.patches.v6_4.reduce_varchar_length frappe.patches.v6_4.rename_bengali_language execute:frappe.db.sql("""update `tabCommunication` set parenttype=null, parent=null, parentfield=null""") #2015-10-22 execute:frappe.permissions.reset_perms("Web Page") frappe.patches.v6_6.user_last_active frappe.patches.v6_6.rename_slovak_language +frappe.patches.v6_6.fix_file_url diff --git a/frappe/patches/v4_0/fix_attach_field_file_url.py b/frappe/patches/v4_0/fix_attach_field_file_url.py index 58a2e4391d..c29e5763f1 100644 --- a/frappe/patches/v4_0/fix_attach_field_file_url.py +++ b/frappe/patches/v4_0/fix_attach_field_file_url.py @@ -5,8 +5,8 @@ from __future__ import unicode_literals import frappe def execute(): - attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype='Attach'""") + - frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype='Attach'""")) + attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""") + + frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""")) for doctype, fieldname in attach_fields: frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) diff --git a/frappe/patches/v6_1/rename_file_data.py b/frappe/patches/v6_1/rename_file_data.py index 64af2e1411..f077896dd4 100644 --- a/frappe/patches/v6_1/rename_file_data.py +++ b/frappe/patches/v6_1/rename_file_data.py @@ -14,10 +14,15 @@ def execute(): for file in frappe.get_all("File", filters={"is_folder": 0}): file = frappe.get_doc("File", file.name) file.flags.ignore_folder_validate = True + file.flags.ignore_file_validate = True file.flags.ignore_duplicate_entry_error = True file.flags.ignore_links = True file.set_folder_name() - file.save() + try: + file.save() + except: + print frappe.get_traceback() + raise from frappe.utils.nestedset import rebuild_tree rebuild_tree("File", "folder") diff --git a/frappe/patches/v6_6/fix_file_url.py b/frappe/patches/v6_6/fix_file_url.py new file mode 100644 index 0000000000..1313bb013a --- /dev/null +++ b/frappe/patches/v6_6/fix_file_url.py @@ -0,0 +1,32 @@ +from __future__ import unicode_literals +import frappe +from frappe.model.meta import is_single + +def execute(): + """Fix old style file urls that start with files/""" + fix_file_urls() + fix_attach_field_urls() + +def fix_file_urls(): + for file in frappe.db.sql_list("""select name from `tabFile` where file_url like 'files/%'"""): + file = frappe.get_doc("File", file) + file.db_set("file_url", "/" + file.file_url, update_modified=False) + file.validate_file() + file.db_set("file_name", file.file_name, update_modified=False) + if not file.content_hash: + file.generate_content_hash() + file.db_set("content_hash", file.content_hash, update_modified=False) + +def fix_attach_field_urls(): + # taken from an old patch + attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""") + + frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""")) + + for doctype, fieldname in attach_fields: + if is_single(doctype): + frappe.db.sql("""update `tabSingles` set value=concat("/", `value`) + where doctype=%(doctype)s and field=%(fieldname)s + and value like 'files/%%'""", {"doctype": doctype, "fieldname": fieldname}) + else: + frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) + where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname))