Skip to content

Commit

Permalink
Merge branch 'develop' into customize_form
Browse files Browse the repository at this point in the history
  • Loading branch information
sagarvora committed May 2, 2023
2 parents 53e0a20 + 26512c4 commit 5ef66f3
Show file tree
Hide file tree
Showing 94 changed files with 737 additions and 416 deletions.
14 changes: 9 additions & 5 deletions cypress/integration/folder_navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ context("Folder Navigation", () => {

it("Adding Folders", () => {
//Adding filter to go into the home folder
cy.get(".filter-selector > .btn").findByText("1 filter").click();
cy.findByRole("button", { name: "Clear Filters" }).click();
cy.get(".filter-x-button").click();
cy.click_filter_button();
cy.get(".filter-action-buttons > .text-muted").findByText("+ Add a Filter").click();
cy.get(".fieldname-select-area > .awesomplete > .form-control:last").type("Fol{enter}");
cy.get(
Expand Down Expand Up @@ -47,9 +47,13 @@ context("Folder Navigation", () => {
//Adding a file inside the Test Folder
cy.findByRole("button", { name: "Add File" }).eq(0).click({ force: true });
cy.get(".file-uploader").findByText("Link").click();
cy.get(".input-group > .form-control").type(
"https://wallpaperplay.com/walls/full/8/2/b/72402.jpg"
);
cy.get(".input-group > input.form-control:visible").as("upload_input");
cy.get("@upload_input").type("https://wallpaperplay.com/walls/full/8/2/b/72402.jpg", {
waitForAnimations: false,
parseSpecialCharSequences: false,
force: true,
delay: 100,
});
cy.click_modal_primary_button("Upload");

//To check if the added file is present in the Test Folder
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/list_paging.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ context("List Paging", () => {

it("test load more with count selection buttons", () => {
cy.visit("/app/todo/view/report");
cy.clear_filters();
cy.get(".filter-x-button").click();

cy.get(".list-paging-area .list-count").should("contain.text", "20 of");
cy.get(".list-paging-area .btn-more").click();
Expand Down
1 change: 1 addition & 0 deletions cypress/integration/list_view_drag_select.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ context("List View", () => {
});

it("List view check rows on drag", () => {
cy.get(".filter-x-button").click();
cy.get(".list-row-checkbox").then(($checkbox) => {
cy.wrap($checkbox).first().trigger("mousedown");
cy.get(".level.list-row").each(($ele) => {
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ context("Sidebar", () => {
);

//To check if there is no filter added to the listview
cy.get(".filter-selector > .btn").should("contain", "Filter");
cy.get(".filter-button").should("contain", "Filter");

//To add a filter to display data into the listview
cy.get(".group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item").click();
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ Cypress.Commands.add("click_listview_row_item_with_text", (text) => {
});

Cypress.Commands.add("click_filter_button", () => {
cy.get(".filter-selector > .btn").click();
cy.get(".filter-button").click();
});

Cypress.Commands.add("click_listview_primary_button", (btn_name) => {
Expand Down
6 changes: 3 additions & 3 deletions frappe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ def set_user_lang(user: str, user_language: str | None = None) -> None:
# end: static analysis hack


def init(site: str, sites_path: str = ".", new_site: bool = False) -> None:
def init(site: str, sites_path: str = ".", new_site: bool = False, force=False) -> None:
"""Initialize frappe for the current site. Reset thread locals `frappe.local`"""
if getattr(local, "initialised", None):
if getattr(local, "initialised", None) and not force:
return

local.error_log = []
Expand Down Expand Up @@ -845,7 +845,7 @@ def only_for(roles: list[str] | tuple[str] | str, message=False):
if isinstance(roles, str):
roles = (roles,)

if not set(roles).intersection(get_roles()):
if set(roles).isdisjoint(get_roles()):
if not message:
raise PermissionError

Expand Down
22 changes: 18 additions & 4 deletions frappe/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,18 @@ def application(request: Request):
rollback = sync_database(rollback)

finally:
# Important note:
# this function *must* always return a response, hence any exception thrown outside of
# try..catch block like this finally block needs to be handled appropriately.

if request.method in UNSAFE_HTTP_METHODS and frappe.db and rollback:
frappe.db.rollback()

if getattr(frappe.local, "initialised", False):
for after_request_task in frappe.get_hooks("after_request"):
frappe.call(after_request_task, response=response, request=request)
try:
run_after_request_hooks(request, response)
except Exception as e:
# We can not handle exceptions safely here.
frappe.logger().error("Failed to run after request hook", exc_info=True)

log_request(request, response)
process_response(response)
Expand All @@ -89,12 +95,20 @@ def application(request: Request):
return response


def run_after_request_hooks(request, response):
if not getattr(frappe.local, "initialised", False):
return

for after_request_task in frappe.get_hooks("after_request"):
frappe.call(after_request_task, response=response, request=request)


def init_request(request):
frappe.local.request = request
frappe.local.is_ajax = frappe.get_request_header("X-Requested-With") == "XMLHttpRequest"

site = _site or request.headers.get("X-Frappe-Site-Name") or get_site_name(request.host)
frappe.init(site=site, sites_path=_sites_path)
frappe.init(site=site, sites_path=_sites_path, force=True)

if not (frappe.local.conf and frappe.local.conf.db_name):
# site does not exist
Expand Down
24 changes: 16 additions & 8 deletions frappe/contacts/address_and_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,26 @@ def get_permitted_and_not_permitted_links(doctype):
return {"permitted_links": permitted_links, "not_permitted_links": not_permitted_links}


def delete_contact_and_address(doctype, docname):
def delete_contact_and_address(doctype: str, docname: str) -> None:
for parenttype in ("Contact", "Address"):
items = frappe.db.sql_list(
"""select parent from `tabDynamic Link`
where parenttype=%s and link_doctype=%s and link_name=%s""",
(parenttype, doctype, docname),
)

for name in items:
for name in frappe.get_all(
"Dynamic Link",
filters={
"parenttype": parenttype,
"link_doctype": doctype,
"link_name": docname,
},
pluck="parent",
):
doc = frappe.get_doc(parenttype, name)
if len(doc.links) == 1:
doc.delete()
else:
for link in doc.links:
if link.link_doctype == doctype and link.link_name == docname:
doc.remove(link)
doc.save()
break


@frappe.whitelist()
Expand Down
6 changes: 4 additions & 2 deletions frappe/core/doctype/data_import/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,11 @@ def add_header(self):
for df in self.fields:
is_parent = not df.is_child_table_field
if is_parent:
label = _(df.label)
label = _(df.label or df.fieldname)
else:
label = f"{_(df.label)} ({_(df.child_table_df.label)})"
label = (
f"{_(df.label or df.fieldname)} ({_(df.child_table_df.label or df.child_table_df.fieldname)})"
)

if label in header:
# this label is already in the header,
Expand Down
1 change: 1 addition & 0 deletions frappe/core/doctype/doctype/doctype.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ def scrub_field_names(self):
"name",
"parent",
"creation",
"owner",
"modified",
"modified_by",
"parentfield",
Expand Down
60 changes: 18 additions & 42 deletions frappe/core/doctype/document_naming_rule/document_naming_rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@
frappe.ui.form.on("Document Naming Rule", {
refresh: function (frm) {
frm.trigger("document_type");
if (!frm.doc.__islocal) frm.trigger("add_update_counter_button");
frm.last_counter_value = frm.doc.counter;
frm.skip_before_save = false;
},
before_save: function (frm) {
if (frm.is_new() || frm.skip_before_save || frm.last_counter_value === frm.doc.counter)
return;

frappe.validated = false;
frappe.warn(
__("Are you sure?"),
__("Updating counter may lead to document name conflicts if not done properly"),
() => {
frm.skip_before_save = true;
frm.save();
},
__("Proceed"),
false
);
},
document_type: (frm) => {
// update the select field options with fieldnames
Expand All @@ -26,45 +43,4 @@ frappe.ui.form.on("Document Naming Rule", {
});
}
},
add_update_counter_button: (frm) => {
frm.add_custom_button(__("Update Counter"), function () {
const fields = [
{
fieldtype: "Data",
fieldname: "new_counter",
label: __("New Counter"),
default: frm.doc.counter,
reqd: 1,
description: __(
"Warning: Updating counter may lead to document name conflicts if not done properly"
),
},
];

let primary_action_label = __("Save");

let primary_action = (fields) => {
frappe.call({
method: "frappe.core.doctype.document_naming_rule.document_naming_rule.update_current",
args: {
name: frm.doc.name,
new_counter: fields.new_counter,
},
callback: function () {
frm.set_value("counter", fields.new_counter);
dialog.hide();
},
});
};

const dialog = new frappe.ui.Dialog({
title: __("Update Counter Value for Prefix: {0}", [frm.doc.prefix]),
fields,
primary_action_label,
primary_action,
});

dialog.show();
});
},
});
20 changes: 14 additions & 6 deletions frappe/core/doctype/document_naming_rule/document_naming_rule.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
"conditions",
"naming_section",
"prefix",
"prefix_digits",
"counter"
"counter",
"column_break_xfqa",
"prefix_digits"
],
"fields": [
{
Expand All @@ -22,7 +23,8 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Document Type",
"options": "DocType"
"options": "DocType",
"reqd": 1
},
{
"default": "0",
Expand All @@ -38,11 +40,12 @@
"reqd": 1
},
{
"default": "0",
"description": "Warning: Updating counter may lead to document name conflicts if not done properly",
"fieldname": "counter",
"fieldtype": "Int",
"label": "Counter",
"no_copy": 1,
"read_only": 1
"no_copy": 1
},
{
"default": "5",
Expand Down Expand Up @@ -76,11 +79,15 @@
"fieldname": "priority",
"fieldtype": "Int",
"label": "Priority"
},
{
"fieldname": "column_break_xfqa",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-09-13 20:07:47.617615",
"modified": "2023-04-24 15:14:32.054272",
"modified_by": "Administrator",
"module": "Core",
"name": "Document Naming Rule",
Expand All @@ -102,6 +109,7 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "document_type",
"track_changes": 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,3 @@ def apply(self, doc):

doc.name = naming_series + ("%0" + str(self.prefix_digits) + "d") % (counter + 1)
frappe.db.set_value(self.doctype, self.name, "counter", counter + 1)


@frappe.whitelist()
def update_current(name, new_counter):
frappe.only_for("System Manager")
frappe.db.set_value("Document Naming Rule", name, "counter", new_counter)
10 changes: 9 additions & 1 deletion frappe/core/doctype/file/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
move_file,
unzip_file,
)
from frappe.core.doctype.file.utils import get_extension
from frappe.exceptions import ValidationError
from frappe.tests.utils import FrappeTestCase
from frappe.utils import get_files_path
Expand Down Expand Up @@ -461,7 +462,7 @@ def test_make_thumbnail(self):
).insert(ignore_permissions=True)

test_file.make_thumbnail()
self.assertTrue(test_file.thumbnail_url.endswith("_small.jpeg"))
self.assertTrue(test_file.thumbnail_url.endswith("_small.jpg"))

# test local image
test_file.db_set("thumbnail_url", None)
Expand Down Expand Up @@ -739,3 +740,10 @@ def test_revert_optimized_file_on_rollback(self):
size_after_rollback = os.stat(image_path).st_size

self.assertEqual(size_before_optimization, size_after_rollback)

def test_image_header_guessing(self):
file_path = frappe.get_app_path("frappe", "tests/data/sample_image_for_optimization.jpg")
with open(file_path, "rb") as f:
file_content = f.read()

self.assertEqual(get_extension("", None, file_content), "jpg")
10 changes: 6 additions & 4 deletions frappe/core/doctype/file/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import hashlib
import imghdr
import mimetypes
import os
import re
from io import BytesIO
from typing import TYPE_CHECKING, Optional
from urllib.parse import unquote

import filetype
import requests
import requests.exceptions
from PIL import Image
Expand Down Expand Up @@ -76,9 +76,11 @@ def get_extension(

mimetype = mimetypes.guess_type(filename + "." + extn)[0]

if mimetype is None or not mimetype.startswith("image/") and content:
# detect file extension by reading image header properties
extn = imghdr.what(filename + "." + (extn or ""), h=content)
if mimetype is None and extn is None and content:
# detect file extension by using filetype matchers
_type_info = filetype.match(content)
if _type_info:
extn = _type_info.extension

return extn

Expand Down

0 comments on commit 5ef66f3

Please sign in to comment.