diff --git a/commit/commit/code_analysis/apis.py b/commit/commit/code_analysis/apis.py index 483995b..c26ee1a 100644 --- a/commit/commit/code_analysis/apis.py +++ b/commit/commit/code_analysis/apis.py @@ -31,7 +31,8 @@ def find_all_occurrences_of_whitelist(path: str, app_name: str): ## Comment out later # if file.endswith('party.py'): - indexes,line_nos = find_indexes_of_whitelist(file_content, no_of_occurrences) + indexes,line_nos,no_of_occurrences = find_indexes_of_whitelist(file_content, no_of_occurrences) + api_count += no_of_occurrences apis = get_api_details(file, file_content, indexes,line_nos, path) api_details.extend(apis) @@ -43,17 +44,70 @@ def find_all_occurrences_of_whitelist(path: str, app_name: str): def find_indexes_of_whitelist(file_content: str, count: int): ''' - Find indexes of @frappe.whitelist in the file content + Find indexes of @frappe.whitelist in the file content, + ensuring it's not commented out or inside a string. ''' + def is_in_string_or_comment(file_content, index): + # State variables + in_single_quote = False + in_double_quote = False + in_comment = False + in_triple_single_quote = False + in_triple_double_quote = False + + i = 0 + while i < index: + char = file_content[i] + + # Handle triple single-quoted strings + if file_content[i:i+3] == "'''" and not in_double_quote: + if in_triple_single_quote: + in_triple_single_quote = False + i += 2 + else: + in_triple_single_quote = True + i += 2 + # Handle triple double-quoted strings + elif file_content[i:i+3] == '"""' and not in_single_quote: + if in_triple_double_quote: + in_triple_double_quote = False + i += 2 + else: + in_triple_double_quote = True + i += 2 + # Handle single-quoted strings + elif char == "'" and not in_double_quote and not in_triple_single_quote and not in_triple_double_quote: + in_single_quote = not in_single_quote + # Handle double-quoted strings + elif char == '"' and not in_single_quote and not in_triple_single_quote and not in_triple_double_quote: + in_double_quote = not in_double_quote + # Handle single-line comments + elif char == '#' and not in_single_quote and not in_double_quote and not in_triple_single_quote and not in_triple_double_quote: + in_comment = True + # Handle end of line for single-line comments + elif char == '\n': + in_comment = False + + i += 1 + + return in_single_quote or in_double_quote or in_comment or in_triple_single_quote or in_triple_double_quote + indexes = [] line_nos = [] - for i in range(count): - index = file_content.find('@frappe.whitelist', indexes[i - 1] + len('@frappe.whitelist') if i > 0 else 0) - indexes.append(index) - line_nos.append((file_content.count('\n', 0, index)+1)) - + actual_count = count - return indexes, line_nos + start = 0 + while actual_count > 0: + index = file_content.find('@frappe.whitelist', start) + if index == -1: + break + if not is_in_string_or_comment(file_content, index): + indexes.append(index) + line_nos.append(file_content.count('\n', 0, index) + 1) + actual_count -= 1 + start = index + len('@frappe.whitelist') + + return indexes, line_nos, actual_count def get_api_details(file, file_content: str, indexes: list,line_nos:list, path: str): ''' @@ -98,7 +152,10 @@ def get_whitelist_details(file_content: str, index: int): ''' whitelist_end_index = file_content.find(')', index) whitelisted_content = file_content[index:whitelist_end_index + 1] - args = whitelisted_content.split("(")[1].split(")")[0].split(",") + if "(" in whitelisted_content and ")" in whitelisted_content: + args = whitelisted_content.split("(")[1].split(")")[0].split(",") + else: + args = [] request_types = [] xss_safe = False allow_guest = False @@ -159,7 +216,10 @@ def extract_arguments_from_def(api_def: str): ''' Extract arguments from def ''' - arguments_with_types_defaults = api_def.split("(")[1].split(")")[0].split(",") + if "(" not in api_def or ")" not in api_def: + arguments_with_types_defaults = [] + else: + arguments_with_types_defaults = api_def.split("(")[1].split(")")[0].split(",") arguments = [] for arg in arguments_with_types_defaults: @@ -202,7 +262,28 @@ def find_function_end_lines(source_code: str,function_name:str): for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): - end_line = node.end_lineno - function_end_lines[node.name] = end_line + decorators = get_decorators(node) + if 'whitelist' in decorators: + end_line = node.end_lineno + function_end_lines[node.name] = end_line + + return function_end_lines.get(function_name,0) - return function_end_lines.get(function_name,0) \ No newline at end of file +def get_decorator_name(node): + if isinstance(node, ast.Call): + if isinstance(node.func, ast.Name): + return node.func.id + elif isinstance(node.func, ast.Attribute): + return node.func.attr + elif isinstance(node, ast.Attribute): + return node.attr + else: + return None + +def get_decorators(node): + decorators = [] + for decorator in node.decorator_list: + decorator_name = get_decorator_name(decorator) + if decorator_name is not None: + decorators.append(decorator_name) + return decorators \ No newline at end of file diff --git a/commit/commit/doctype/commit_project_branch/commit_project_branch.py b/commit/commit/doctype/commit_project_branch/commit_project_branch.py index c35af44..d78db59 100644 --- a/commit/commit/doctype/commit_project_branch/commit_project_branch.py +++ b/commit/commit/doctype/commit_project_branch/commit_project_branch.py @@ -17,9 +17,16 @@ class CommitProjectBranch(Document): def before_insert(self): self.path_to_folder = self.get_path_to_folder() self.create_branch_folder() - self.clone_repo() - self.get_modules() - self.find_all_apis() + + def after_insert(self): + frappe.enqueue( + method = background_fetch_process, + is_async = True, + job_name="Fetch Project Branch", + enqueue_after_commit = True, + at_front = True, + project_branch = self.name + ) def create_branch_folder(self): if not os.path.exists(self.path_to_folder): @@ -44,7 +51,6 @@ def clone_repo(self): # print("Cloned repo") self.last_fetched = frappe.utils.now_datetime() self.commit_hash = repo.head.object.hexsha - pass def fetch_repo(self): repo = git.Repo(self.path_to_folder) @@ -107,10 +113,58 @@ def get_doctypes_in_module(self, module): def on_trash(self): # Delete the folder - if os.path.exists(self.path_to_folder): + if self.path_to_folder and os.path.exists(self.path_to_folder): shutil.rmtree(self.path_to_folder) - pass +def background_fetch_process(project_branch): + try: + doc = frappe.get_doc("Commit Project Branch", project_branch) + frappe.publish_realtime('commit_branch_clone_repo', + { + 'branch_name': doc.branch_name, + 'project': doc.project, + 'text': "Cloning repository...", + 'is_completed': False + }, user=frappe.session.user) + + + doc.clone_repo() + frappe.publish_realtime('commit_branch_get_modules', + { + 'branch_name': doc.branch_name, + 'project': doc.project, + 'text': "Getting all modules for your app...", + 'is_completed': False + }, user=frappe.session.user) + + doc.get_modules() + + frappe.publish_realtime('commit_branch_find_apis', + { + 'branch_name': doc.branch_name, + 'project': doc.project, + 'text': "Finding all APIs...", + 'is_completed': False + }, user=frappe.session.user) + + doc.find_all_apis() + doc.save() + + frappe.publish_realtime("commit_project_branch_created", { + 'name': doc.name, + 'branch_name': doc.branch_name, + 'project': doc.project, + 'text': "Branch created successfully.", + 'is_completed': True + }, user=frappe.session.user) + + + + except frappe.DoesNotExistError: + # throw the error and delete the document + frappe.throw("Project Branch not found") + frappe.delete_doc("Commit Project Branch", project_branch) + @frappe.whitelist(allow_guest=True) def fetch_repo(doc): diff --git a/commit/commit/github_connect/connected_app.py b/commit/commit/github_connect/connected_app.py deleted file mode 100644 index 78bfa88..0000000 --- a/commit/commit/github_connect/connected_app.py +++ /dev/null @@ -1,7 +0,0 @@ -import frappe - -@frappe.whitelist(allow_guest=True) -def trial(): - connected_app = frappe.get_doc("Connected App", "fa306fb623") - return connected_app.initiate_web_application_flow() - \ No newline at end of file diff --git a/dashboard/index.html b/dashboard/index.html index 250ced6..2eaa979 100644 --- a/dashboard/index.html +++ b/dashboard/index.html @@ -17,6 +17,10 @@
+ diff --git a/dashboard/package.json b/dashboard/package.json index 84eaafd..d713012 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -40,7 +40,7 @@ "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", "cmdk": "^0.2.0", - "frappe-react-sdk": "^1.2.8", + "frappe-react-sdk": "^1.7.0", "install": "^0.13.0", "lodash": "^4.17.21", "lodash.isplainobject": "^4.0.6", diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index 5ce8661..c9d2db2 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -8,8 +8,18 @@ import { CreateERD } from './pages/features/erd/meta/CreateERDForMeta' function App() { + const getSiteName = () => { + // @ts-ignore + if (window.frappe?.boot?.versions?.frappe && (window.frappe.boot.versions.frappe.startsWith('15') || window.frappe.boot.versions.frappe.startsWith('16'))) { + // @ts-ignore + return window.frappe?.boot?.sitename ?? import.meta.env.VITE_SITE_NAME + } + return import.meta.env.VITE_SITE_NAME + + } + return ( -