-
Notifications
You must be signed in to change notification settings - Fork 11
fix: robust bug fixes and storage verification tools #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: version-15
Are you sure you want to change the base?
Changes from all commits
a8bf1d4
733f2ed
11f72e7
ea37c4e
1c41786
4fead3d
8da0e40
cd6b128
9a2281e
dd6e931
0834d25
609b96a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
|
|
||
| import frappe | ||
| import os | ||
| from cloud_storage.cloud_storage.overrides.file import get_cloud_storage_client, get_cloud_storage_config | ||
| from botocore.exceptions import ClientError | ||
|
|
||
| def execute(): | ||
| print(f"\n{'='*50}") | ||
| print(f"Storage Verification for Site: {frappe.local.site}") | ||
| print(f"{'='*50}") | ||
|
|
||
| # 1. Get All Files from DB | ||
| files = frappe.get_all( | ||
| "File", | ||
| fields=["name", "file_name", "file_url", "is_private", "s3_key", "is_folder"], | ||
| filters={"is_folder": 0} | ||
| ) | ||
| total_db_files = len(files) | ||
| print(f"Total Files in DB: {total_db_files}") | ||
|
|
||
| config = get_cloud_storage_config() | ||
| if not config: | ||
| print("Cloud Storage not configured for this site.") | ||
| return | ||
|
|
||
| try: | ||
| client = get_cloud_storage_client() | ||
| bucket = client.bucket | ||
| except Exception as e: | ||
| print(f"Failed to initialize MinIO client: {e}") | ||
| return | ||
|
|
||
| local_count = 0 | ||
| minio_count = 0 | ||
| synced_count = 0 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| missing_local = [] | ||
| missing_minio = [] | ||
|
|
||
| print("\nScanning files...") | ||
|
|
||
| for f in files: | ||
| # Check Local | ||
| if f.is_private: | ||
| local_path = frappe.get_site_path("private", "files", f.file_name) | ||
| else: | ||
| local_path = frappe.get_site_path("public", "files", f.file_name) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This assumes all public files are in Should we use something like: local_path = frappe.get_site_path("public", f.file_url.lstrip("/")) |
||
|
|
||
| if os.path.exists(local_path): | ||
| local_count += 1 | ||
| else: | ||
| missing_local.append(f.file_name) | ||
|
|
||
| # Check MinIO | ||
| in_minio = False | ||
| if f.s3_key: | ||
| try: | ||
| client.head_object(Bucket=bucket, Key=f.s3_key) | ||
| in_minio = True | ||
| minio_count += 1 | ||
| synced_count += 1 | ||
| except ClientError: | ||
| missing_minio.append(f.file_name) | ||
| else: | ||
| # Not marked as migrated (s3_key is empty/null) | ||
| pass | ||
|
|
||
| print(f"\n{'='*50}") | ||
| print(f"Verification Summary for {frappe.local.site}") | ||
| print(f"{'='*50}") | ||
| print(f"Total Records in DB: {total_db_files}") | ||
| print(f"Found Locally: {local_count}") | ||
| print(f"Found in MinIO (Verified): {minio_count}") | ||
| print(f"Marked as Migrated (DB): {len([f for f in files if f.s3_key])}") | ||
| print(f"{'='*50}") | ||
|
|
||
| if missing_local: | ||
| print(f"\n[WARNING] Missing Local Files ({len(missing_local)}):") | ||
| print(", ".join(missing_local[:10]) + ("..." if len(missing_local) > 10 else "")) | ||
|
|
||
| if missing_minio: | ||
| print(f"\n[ERROR] Missing in MinIO (DB claims migrated) ({len(missing_minio)}):") | ||
| print(", ".join(missing_minio[:10]) + ("..." if len(missing_minio) > 10 else "")) | ||
|
|
||
| # Verification of count | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comparing
A better logic would be: marked_as_migrated = len([f for f in files if f.s3_key])
if marked_as_migrated != minio_count:
print(f"[ERROR] Sync Issue: DB claims {marked_as_migrated} files migrated, but only {minio_count} found in cloud!")This catches the critical case where DB thinks files are migrated but they're missing from cloud storage. |
||
| if local_count != minio_count: | ||
| print(f"\n[INFO] Count Mismatch: Local ({local_count}) vs MinIO ({minio_count})") | ||
| print("Note: This is expected if partial migration or if 'remove_local' was used.") | ||
| else: | ||
| print("\n[SUCCESS] Local and MinIO counts match (for migrated files).") | ||
|
|
||
| print(f"{'='*50}\n") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,8 @@ | |
| "dependencies": { | ||
| "docx-preview": "^0.3.0", | ||
| "jszip": "^3.10.1", | ||
| "madr": "^3.0.0" | ||
| "madr": "^3.0.0", | ||
| "vue": "^3.3.4" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the PR body you wrote: "Vue Dependency: Added Vue to package.json to resolve bench build failures on v15." Frappe v15 already includes Vue 3 in core, so it shouldn't throw an error. Adding Vue here might cause version conflicts or bundle duplication. |
||
| }, | ||
| "release": { | ||
| "branches": [ | ||
|
|
@@ -19,4 +20,4 @@ | |
| "access": "restricted" | ||
| }, | ||
| "private": true | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,7 @@ authors = [ | |
|
|
||
| [tool.poetry] | ||
| name = "cloud_storage" | ||
| version = "15.9.1" | ||
| version = "1.1.1" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The version change from |
||
| description = "Frappe App for integrating with cloud storage applications" | ||
| authors = ["AgriTheory <support@agritheory.dev>"] | ||
| readme = "README.md" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project supports S3, DigitalOcean Spaces, Backblaze, etc. Consider using generic messaging like: