From a23dc0a749e65fa650b362f22affec083c4ee933 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 9 Aug 2019 22:13:39 +0530
Subject: [PATCH 01/58] feat: google drive initial bringup
---
frappe/boot.py | 6 +-
.../doctype/google_drive/__init__.py | 0
.../doctype/google_drive/google_drive.js | 30 ++++
.../doctype/google_drive/google_drive.json | 94 +++++++++++++
.../doctype/google_drive/google_drive.py | 133 ++++++++++++++++++
.../doctype/google_drive/test_google_drive.py | 10 ++
frappe/public/build.json | 1 +
frappe/public/js/frappe/form/toolbar.js | 9 ++
.../js/frappe/views/google_drive_uploader.js | 52 +++++++
9 files changed, 332 insertions(+), 3 deletions(-)
create mode 100644 frappe/integrations/doctype/google_drive/__init__.py
create mode 100644 frappe/integrations/doctype/google_drive/google_drive.js
create mode 100644 frappe/integrations/doctype/google_drive/google_drive.json
create mode 100644 frappe/integrations/doctype/google_drive/google_drive.py
create mode 100644 frappe/integrations/doctype/google_drive/test_google_drive.py
create mode 100644 frappe/public/js/frappe/views/google_drive_uploader.js
diff --git a/frappe/boot.py b/frappe/boot.py
index 50888fcdd2..3b7e94dc81 100644
--- a/frappe/boot.py
+++ b/frappe/boot.py
@@ -76,7 +76,7 @@ def get_bootinfo():
bootinfo.calendars = sorted(frappe.get_hooks("calendars"))
bootinfo.treeviews = frappe.get_hooks("treeviews") or []
bootinfo.lang_dict = get_lang_dict()
- bootinfo.gsuite_enabled = get_gsuite_status()
+ bootinfo.google_drive_enabled = get_google_drive_status()
bootinfo.success_action = get_success_action()
bootinfo.update(get_email_accounts(user=frappe.session.user))
bootinfo.energy_points_enabled = is_energy_point_enabled()
@@ -258,8 +258,8 @@ def get_unseen_notes():
(select user from `tabNote Seen By` nsb
where nsb.parent=`tabNote`.name)''', (frappe.utils.now(), frappe.session.user), as_dict=True)
-def get_gsuite_status():
- return (frappe.get_value('Gsuite Settings', None, 'enable') == '1')
+ def get_google_drive_status():
+ return True if frappe.db.exists("Google Drive", {"enable": 1}) else False
def get_success_action():
return frappe.get_all("Success Action", fields=["*"])
diff --git a/frappe/integrations/doctype/google_drive/__init__.py b/frappe/integrations/doctype/google_drive/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
new file mode 100644
index 0000000000..9bdd7ca4c5
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, Frappe Technologies and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Google Drive', {
+ refresh: function(frm) {
+ if (frm.is_new()) {
+ frm.dashboard.set_headline(__("To use Google Drive, enable Google Settings."));
+ }
+ },
+ authorize_google_drive_access: function(frm) {
+ let reauthorize = 0;
+ if(frm.doc.authorization_code) {
+ reauthorize = 1;
+ }
+
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.authorize_access",
+ args: {
+ "g_drive": frm.doc.name,
+ "reauthorize": reauthorize
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ frm.save();
+ window.open(r.message.url);
+ }
+ }
+ });
+ }
+});
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
new file mode 100644
index 0000000000..f2eb3a2f38
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -0,0 +1,94 @@
+{
+ "autoname": "format:{folder_name}-{reference_doctype}",
+ "creation": "2019-08-08 13:16:06.783138",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "enable",
+ "sb_00",
+ "user",
+ "folder_name",
+ "authorize_google_drive_access",
+ "authorization_code",
+ "refresh_token"
+ ],
+ "fields": [
+ {
+ "default": "0",
+ "fieldname": "enable",
+ "fieldtype": "Check",
+ "label": "Enable"
+ },
+ {
+ "depends_on": "enable",
+ "fieldname": "sb_00",
+ "fieldtype": "Section Break",
+ "label": "Google Drive"
+ },
+ {
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "User",
+ "options": "User",
+ "reqd": 1
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "authorize_google_drive_access",
+ "fieldtype": "Button",
+ "label": "Authorize Google Drive Access"
+ },
+ {
+ "fieldname": "folder_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Folder Name",
+ "reqd": 1,
+ "set_only_once": 1,
+ "unique": 1
+ },
+ {
+ "fieldname": "authorization_code",
+ "fieldtype": "Password",
+ "label": "Authorization Code"
+ },
+ {
+ "fieldname": "refresh_token",
+ "fieldtype": "Password",
+ "label": "Refresh Token"
+ }
+ ],
+ "modified": "2019-08-09 18:20:58.169056",
+ "modified_by": "Administrator",
+ "module": "Integrations",
+ "name": "Google Drive",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "All",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
new file mode 100644
index 0000000000..92e96e8522
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import requests
+import googleapiclient.discovery
+import google.oauth2.credentials
+
+from frappe import _
+from frappe.model.document import Document
+from frappe.utils import get_request_site_address
+from six.moves.urllib.parse import quote
+from apiclient.http import MediaFileUpload
+
+SCOPES = "https://www.googleapis.com/auth/drive"
+
+class GoogleDrive(Document):
+
+ def get_access_token(self):
+ google_settings = frappe.get_doc("Google Settings")
+
+ if not google_settings.enable:
+ frappe.throw(_("Google Integration is disabled."))
+
+ if not self.refresh_token:
+ button_label = frappe.bold(_("Allow Google Drive Access"))
+ raise frappe.ValidationError(_("Click on {0} to generate Refresh Token.").format(button_label))
+
+ data = {
+ "client_id": google_settings.client_id,
+ "client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
+ "refresh_token": self.get_password(fieldname="refresh_token", raise_exception=False),
+ "grant_type": "refresh_token",
+ "scope": SCOPES
+ }
+
+ try:
+ r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ except requests.exceptions.HTTPError:
+ button_label = frappe.bold(_("Allow Google Drive Access"))
+ frappe.throw(_("Something went wrong during the token generation. Click on {0} to generate a new one.").format(button_label))
+
+ return r.get("access_token")
+
+@frappe.whitelist()
+def authorize_access(g_drive, reauthorize=None):
+ """
+ If no Authorization code get it from Google and then request for Refresh Token.
+ Google Contact Name is set to flags to set_value after Authorization Code is obtained.
+ """
+
+ google_settings = frappe.get_doc("Google Settings")
+ google_drive = frappe.get_doc("Google Drive", g_drive)
+
+ redirect_uri = get_request_site_address(True) + "?cmd=frappe.integrations.doctype.google_drive.google_drive.google_callback"
+
+ if not google_drive.authorization_code or reauthorize:
+ frappe.cache().hset("google_drive", "google_drive", google_drive.name)
+ return get_authentication_url(client_id=google_settings.client_id, redirect_uri=redirect_uri)
+ else:
+ try:
+ data = {
+ "code": google_drive.authorization_code,
+ "client_id": google_settings.client_id,
+ "client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
+ "redirect_uri": redirect_uri,
+ "grant_type": "authorization_code"
+ }
+ r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+
+ if "refresh_token" in r:
+ frappe.db.set_value("Google Drive", google_drive.name, "refresh_token", r.get("refresh_token"))
+ frappe.db.commit()
+
+ frappe.local.response["type"] = "redirect"
+ frappe.local.response["location"] = "/desk#Form/{0}/{1}".format(quote("Google Drive"), quote(google_drive.name))
+
+ frappe.msgprint(_("Google Drive has been configured."))
+ except Exception as e:
+ frappe.throw(e)
+
+def get_authentication_url(client_id, redirect_uri):
+ return {
+ "url": "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&prompt=consent&client_id={}&include_granted_scopes=true&scope={}&redirect_uri={}".format(client_id, SCOPES, redirect_uri)
+ }
+
+@frappe.whitelist()
+def google_callback(code=None):
+ """
+ Authorization code is sent to callback as per the API configuration
+ """
+ google_drive = frappe.cache().hget("google_drive", "google_drive")
+ frappe.db.set_value("Google Drive", google_drive, "authorization_code", code)
+ frappe.db.commit()
+
+ authorize_access(google_drive)
+
+def get_google_drive_object(g_drive):
+ """
+ Returns an object of Google Drive.
+ """
+ google_settings = frappe.get_doc("Google Settings")
+ account = frappe.get_doc("Google Drive", g_drive)
+
+ credentials_dict = {
+ "token": account.get_access_token(),
+ "refresh_token": account.get_password(fieldname="refresh_token", raise_exception=False),
+ "token_uri": "https://www.googleapis.com/oauth2/v4/token",
+ "client_id": google_settings.client_id,
+ "client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
+ "scopes": "https://www.googleapis.com/auth/drive/v3"
+ }
+
+ credentials = google.oauth2.credentials.Credentials(**credentials_dict)
+ google_drive = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
+
+ return google_calendar
+
+@frappe.whitelist()
+def upload_document(doctype, docname, g_drive):
+ from frappe.utils.print_format import download_pdf
+
+ google_drive = get_google_drive_object(g_drive)
+ download_pdf(doctype=doctype, docname=docname, format="pdf")
+ file_metadata = {"name": frappe.local.response.filename}
+ media = MediaFileUpload(frappe.local.response.filename, mimetype="application/pdf")
+
+ file = google_drive.files().create(body=file_metadata, media_body=media, fields='id').execute()
+
+
+ # frappe.local.response.filecontent
diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py
new file mode 100644
index 0000000000..f06e13572c
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/test_google_drive.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestGoogleDrive(unittest.TestCase):
+ pass
diff --git a/frappe/public/build.json b/frappe/public/build.json
index cb41ae7eef..7bec259933 100755
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -205,6 +205,7 @@
"public/js/frappe/ui/toolbar/toolbar.js",
"public/js/frappe/ui/toolbar/notifications.js",
"public/js/frappe/views/communication.js",
+ "public/js/frappe/views/google_drive_uploader.js",
"public/js/frappe/views/translation_manager.js",
"public/js/frappe/ui/sort_selector.html",
diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js
index 43411bd6de..003f4661e2 100644
--- a/frappe/public/js/frappe/form/toolbar.js
+++ b/frappe/public/js/frappe/form/toolbar.js
@@ -125,6 +125,15 @@ frappe.ui.form.Toolbar = Class.extend({
}
}
+ //Google Drive
+ if(frappe.boot.google_drive_enabled){
+ this.page.add_menu_item(__("Google Drive Upload"), function() {
+ new frappe.views.GoogleDriveUploader(me.frm);}, true);
+ this.print_icon = this.page.add_action_icon("fa fa-google", function() {
+ new frappe.views.GoogleDriveUploader(me.frm);
+ });
+ }
+
// email
if(frappe.model.can_email(null, me.frm) && me.frm.doc.docstatus < 2) {
this.page.add_menu_item(__("Email"), function() {
diff --git a/frappe/public/js/frappe/views/google_drive_uploader.js b/frappe/public/js/frappe/views/google_drive_uploader.js
new file mode 100644
index 0000000000..7c943216b7
--- /dev/null
+++ b/frappe/public/js/frappe/views/google_drive_uploader.js
@@ -0,0 +1,52 @@
+frappe.views.GoogleDriveUploader = Class.extend({
+ init: function(opts) {
+ $.extend(this, opts);
+ this.make();
+ },
+ make: function() {
+ let me = this;
+ let uploader = new frappe.ui.Dialog({
+ title: __("Upload File to Google Drive"),
+ fields: [
+ {
+ fieldtype: "Link",
+ fieldname: "google_drive",
+ options: "Google Drive",
+ label: __("Google Drive"),
+ reqd: 1,
+ get_query: function() {
+ return {
+ "filters": {
+ "owner": frappe.session.user,
+ }
+ }
+ }
+ }
+ ],
+ primary_action_label: __("Submit"),
+ primary_action: (d) => {
+ frappe.show_alert({
+ indicator: "red",
+ message: __("Uploading to Google Drive.")
+ });
+ uploader.hide();
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.upload_document",
+ args: {
+ doctype: me.doctype,
+ docname: me.docname,
+ g_drive: d.google_drive,
+ },
+ callback: function(r) {
+ frappe.show_alert({
+ indicator: "green",
+ message: __("Document uploaded to Google Drive.")
+ });
+ uploader.hide();
+ }
+ })
+ }
+ });
+ uploader.show();
+ }
+})
\ No newline at end of file
From 4e52c6ffa2df6d0468d863047101fc6058a63fac Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 9 Aug 2019 22:18:00 +0530
Subject: [PATCH 02/58] fix: indentation
---
frappe/boot.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/boot.py b/frappe/boot.py
index 3b7e94dc81..60c5e17cd4 100644
--- a/frappe/boot.py
+++ b/frappe/boot.py
@@ -258,8 +258,8 @@ def get_unseen_notes():
(select user from `tabNote Seen By` nsb
where nsb.parent=`tabNote`.name)''', (frappe.utils.now(), frappe.session.user), as_dict=True)
- def get_google_drive_status():
- return True if frappe.db.exists("Google Drive", {"enable": 1}) else False
+def get_google_drive_status():
+ return True if frappe.db.exists("Google Drive", {"enable": 1}) else False
def get_success_action():
return frappe.get_all("Success Action", fields=["*"])
From aff1180e7277741ade2bd19324ee5a1c73c8a37e Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 9 Aug 2019 22:46:52 +0530
Subject: [PATCH 03/58] fix: passsword to data
---
frappe/integrations/doctype/google_drive/google_drive.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index f2eb3a2f38..a16a7b271d 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -50,16 +50,16 @@
},
{
"fieldname": "authorization_code",
- "fieldtype": "Password",
+ "fieldtype": "Data",
"label": "Authorization Code"
},
{
"fieldname": "refresh_token",
- "fieldtype": "Password",
+ "fieldtype": "Data",
"label": "Refresh Token"
}
],
- "modified": "2019-08-09 18:20:58.169056",
+ "modified": "2019-08-09 19:16:28.614921",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From c39b102d796146fd56c3c1baff2183c8c670d5db Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 09:07:20 +0530
Subject: [PATCH 04/58] feat: Google Drive doc pdf uploader
---
.../doctype/google_drive/google_drive.json | 16 ++++-
.../doctype/google_drive/google_drive.py | 60 +++++++++++++++----
frappe/public/js/frappe/form/print.js | 52 ++++++++++++++++
.../frappe/form/templates/print_layout.html | 42 ++++++-------
frappe/public/js/frappe/form/toolbar.js | 9 ---
.../js/frappe/views/google_drive_uploader.js | 52 ----------------
6 files changed, 138 insertions(+), 93 deletions(-)
delete mode 100644 frappe/public/js/frappe/views/google_drive_uploader.js
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index a16a7b271d..1ab858ada3 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -7,8 +7,10 @@
"enable",
"sb_00",
"user",
- "folder_name",
"authorize_google_drive_access",
+ "column_break_5",
+ "folder_name",
+ "folder_id",
"authorization_code",
"refresh_token"
],
@@ -57,9 +59,19 @@
"fieldname": "refresh_token",
"fieldtype": "Data",
"label": "Refresh Token"
+ },
+ {
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "folder_id",
+ "fieldtype": "Data",
+ "label": "Folder ID",
+ "read_only": 1
}
],
- "modified": "2019-08-09 19:16:28.614921",
+ "modified": "2019-08-11 05:17:36.862158",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 92e96e8522..f06dc50386 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -9,10 +9,13 @@ import googleapiclient.discovery
import google.oauth2.credentials
from frappe import _
+from googleapiclient.errors import HttpError
from frappe.model.document import Document
from frappe.utils import get_request_site_address
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
+from frappe.utils.file_manager import save_file, get_file_url
+from frappe.utils.print_format import download_pdf
SCOPES = "https://www.googleapis.com/auth/drive"
@@ -114,20 +117,57 @@ def get_google_drive_object(g_drive):
}
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
- google_drive = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
+ google_drive_object = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
- return google_calendar
+ return google_drive_object, account
+
+def create_folder_in_google_drive(google_drive_object, account):
+ """
+ Create a folder on Drive, returns the newely created folders ID
+ """
+ file_metadata = {
+ "name": account.folder_name,
+ "mimeType": "application/vnd.google-apps.folder"
+ }
+ folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
+ frappe.db.set_value("Google Drive", account.name, "folder_id", folder.get("id"))
@frappe.whitelist()
-def upload_document(doctype, docname, g_drive):
- from frappe.utils.print_format import download_pdf
+def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhead):
+ """
+ Uploads Document to Folder specified in Google Drive Doc.
+ """
+ google_drive_object, account = get_google_drive_object(g_drive)
- google_drive = get_google_drive_object(g_drive)
- download_pdf(doctype=doctype, docname=docname, format="pdf")
- file_metadata = {"name": frappe.local.response.filename}
- media = MediaFileUpload(frappe.local.response.filename, mimetype="application/pdf")
+ if not account.folder_id:
+ create_folder_in_google_drive(google_drive_object, account)
+ account.load_from_db()
- file = google_drive.files().create(body=file_metadata, media_body=media, fields='id').execute()
+ download_pdf(doctype=doctype, name=docname, format=format, no_letterhead=letterhead)
+ filename = frappe.local.response.filename.replace(".pdf", "-{0}.pdf".format(frappe.generate_hash(length=5)))
+ filecontent = frappe.local.response.filecontent
- # frappe.local.response.filecontent
+ upload_file = save_file(filename, filecontent, doctype, docname)
+
+ if not upload_file:
+ frappe.throw(_("Could not upload pdf to Google Drive"))
+
+ fileurl = upload_file.file_url or upload_file.file_name
+ file_metadata = {
+ "name": filename,
+ "parents": [account.folder_id]
+ }
+
+ media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/pdf")
+
+ try:
+ file = google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ except HttpError as e:
+ frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e.resp.status))
+
+def get_absolute_path(filename):
+ filename = filename.replace("/files/", "")
+ file_path = frappe.utils.get_path("public", "files", filename).replace("./", "")
+
+ return "{0}/sites/{1}".format(frappe.utils.get_bench_path(), file_path)
\ No newline at end of file
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index ec78b30c8a..1c180281a0 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -146,6 +146,8 @@ frappe.ui.form.PrintPreview = Class.extend({
frappe.set_route("print-format-builder");
}, __("New Custom Print Format"), __("Start"));
});
+
+ this.google_drive_upload();
},
setup_keyboard_shortcuts() {
this.wrapper.find('.print-toolbar a.btn-default').each((i, el) => {
@@ -452,6 +454,56 @@ frappe.ui.form.PrintPreview = Class.extend({
frappe.throw(__("No Printer is Available."));
}
});
+ },
+ google_drive_upload: function() {
+ var me = this;
+ this.wrapper.find(".btn-upload-drive").click(function () {
+ let uploader = new frappe.ui.Dialog({
+ title: __("Upload File to Google Drive"),
+ fields: [
+ {
+ fieldtype: "Link",
+ fieldname: "google_drive",
+ options: "Google Drive",
+ label: __("Google Drive"),
+ reqd: 1,
+ get_query: function() {
+ return {
+ "filters": {
+ "owner": frappe.session.user,
+ }
+ }
+ }
+ }
+ ],
+ primary_action_label: __("Submit"),
+ primary_action: (d) => {
+ frappe.show_alert({
+ indicator: "red",
+ message: __("Uploading to Google Drive.")
+ })
+ uploader.hide();
+
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.upload_document_to_google_drive",
+ args: {
+ doctype: me.frm.doc.doctype,
+ docname: me.frm.doc.name,
+ g_drive: d.google_drive,
+ format: me.selected_format(),
+ letterhead: me.with_letterhead() ? "0" : "1"
+ },
+ callback: function(r) {
+ frappe.show_alert({
+ indicator: "green",
+ message: __("Document uploaded to Google Drive.")
+ });
+ }
+ })
+ }
+ });
+ uploader.show();
+ });
}
});
diff --git a/frappe/public/js/frappe/form/templates/print_layout.html b/frappe/public/js/frappe/form/templates/print_layout.html
index 5446ea6425..59f448f27f 100644
--- a/frappe/public/js/frappe/form/templates/print_layout.html
+++ b/frappe/public/js/frappe/form/templates/print_layout.html
@@ -7,33 +7,35 @@
placeholder="{{ __("Language") }}">
+
+
+
diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js
index 003f4661e2..43411bd6de 100644
--- a/frappe/public/js/frappe/form/toolbar.js
+++ b/frappe/public/js/frappe/form/toolbar.js
@@ -125,15 +125,6 @@ frappe.ui.form.Toolbar = Class.extend({
}
}
- //Google Drive
- if(frappe.boot.google_drive_enabled){
- this.page.add_menu_item(__("Google Drive Upload"), function() {
- new frappe.views.GoogleDriveUploader(me.frm);}, true);
- this.print_icon = this.page.add_action_icon("fa fa-google", function() {
- new frappe.views.GoogleDriveUploader(me.frm);
- });
- }
-
// email
if(frappe.model.can_email(null, me.frm) && me.frm.doc.docstatus < 2) {
this.page.add_menu_item(__("Email"), function() {
diff --git a/frappe/public/js/frappe/views/google_drive_uploader.js b/frappe/public/js/frappe/views/google_drive_uploader.js
deleted file mode 100644
index 7c943216b7..0000000000
--- a/frappe/public/js/frappe/views/google_drive_uploader.js
+++ /dev/null
@@ -1,52 +0,0 @@
-frappe.views.GoogleDriveUploader = Class.extend({
- init: function(opts) {
- $.extend(this, opts);
- this.make();
- },
- make: function() {
- let me = this;
- let uploader = new frappe.ui.Dialog({
- title: __("Upload File to Google Drive"),
- fields: [
- {
- fieldtype: "Link",
- fieldname: "google_drive",
- options: "Google Drive",
- label: __("Google Drive"),
- reqd: 1,
- get_query: function() {
- return {
- "filters": {
- "owner": frappe.session.user,
- }
- }
- }
- }
- ],
- primary_action_label: __("Submit"),
- primary_action: (d) => {
- frappe.show_alert({
- indicator: "red",
- message: __("Uploading to Google Drive.")
- });
- uploader.hide();
- frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.upload_document",
- args: {
- doctype: me.doctype,
- docname: me.docname,
- g_drive: d.google_drive,
- },
- callback: function(r) {
- frappe.show_alert({
- indicator: "green",
- message: __("Document uploaded to Google Drive.")
- });
- uploader.hide();
- }
- })
- }
- });
- uploader.show();
- }
-})
\ No newline at end of file
From 50f42ffba5241e70986aea779f049a5ec2a0101b Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 16:20:39 +0530
Subject: [PATCH 05/58] feat: system backup to drive
---
frappe/hooks.py | 6 +-
.../doctype/google_drive/google_drive.json | 46 +-
.../doctype/google_drive/google_drive.py | 106 ++++-
.../doctype/gsuite_settings/__init__.py | 0
.../gsuite_settings/gsuite_settings.js | 42 --
.../gsuite_settings/gsuite_settings.json | 404 ------------------
.../gsuite_settings/gsuite_settings.py | 87 ----
.../doctype/gsuite_templates/__init__.py | 0
.../gsuite_templates/gsuite_templates.js | 41 --
.../gsuite_templates/gsuite_templates.json | 228 ----------
.../gsuite_templates/gsuite_templates.py | 93 ----
.../gsuite_templates/test_gsuite_templates.py | 10 -
frappe/public/js/frappe/form/print.js | 6 +-
13 files changed, 125 insertions(+), 944 deletions(-)
delete mode 100644 frappe/integrations/doctype/gsuite_settings/__init__.py
delete mode 100644 frappe/integrations/doctype/gsuite_settings/gsuite_settings.js
delete mode 100644 frappe/integrations/doctype/gsuite_settings/gsuite_settings.json
delete mode 100644 frappe/integrations/doctype/gsuite_settings/gsuite_settings.py
delete mode 100644 frappe/integrations/doctype/gsuite_templates/__init__.py
delete mode 100644 frappe/integrations/doctype/gsuite_templates/gsuite_templates.js
delete mode 100644 frappe/integrations/doctype/gsuite_templates/gsuite_templates.json
delete mode 100644 frappe/integrations/doctype/gsuite_templates/gsuite_templates.py
delete mode 100644 frappe/integrations/doctype/gsuite_templates/test_gsuite_templates.py
diff --git a/frappe/hooks.py b/frappe/hooks.py
index 0b0e03ff61..c233651e6d 100644
--- a/frappe/hooks.py
+++ b/frappe/hooks.py
@@ -192,7 +192,8 @@ scheduler_events = {
],
"daily_long": [
"frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily",
- "frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_daily"
+ "frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_daily",
+ "frappe.integrations.doctype.google_drive.google_drive.daily_backup"
],
"weekly_long": [
"frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_weekly",
@@ -200,7 +201,8 @@ scheduler_events = {
"frappe.utils.change_log.check_for_update",
"frappe.desk.doctype.route_history.route_history.flush_old_route_records",
"frappe.desk.form.document_follow.send_weekly_updates",
- "frappe.social.doctype.energy_point_log.energy_point_log.send_weekly_summary"
+ "frappe.social.doctype.energy_point_log.energy_point_log.send_weekly_summary",
+ "frappe.integrations.doctype.google_drive.google_drive.weekly_backup"
],
"monthly": [
"frappe.email.doctype.auto_email_report.auto_email_report.send_monthly",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 1ab858ada3..5233fdc9ab 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -7,12 +7,14 @@
"enable",
"sb_00",
"user",
+ "backup_folder_name",
"authorize_google_drive_access",
"column_break_5",
- "folder_name",
- "folder_id",
- "authorization_code",
- "refresh_token"
+ "backup_folder_id",
+ "enable_system_backup",
+ "frequency",
+ "refresh_token",
+ "authorization_code"
],
"fields": [
{
@@ -41,15 +43,6 @@
"fieldtype": "Button",
"label": "Authorize Google Drive Access"
},
- {
- "fieldname": "folder_name",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Folder Name",
- "reqd": 1,
- "set_only_once": 1,
- "unique": 1
- },
{
"fieldname": "authorization_code",
"fieldtype": "Data",
@@ -65,13 +58,34 @@
"fieldtype": "Column Break"
},
{
- "fieldname": "folder_id",
+ "depends_on": "enable_system_backup",
+ "fieldname": "frequency",
+ "fieldtype": "Select",
+ "label": "Frequency",
+ "options": "Daily\nWeekly"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_system_backup",
+ "fieldtype": "Check",
+ "label": "Enable System Backup"
+ },
+ {
+ "fieldname": "backup_folder_name",
"fieldtype": "Data",
- "label": "Folder ID",
+ "in_list_view": 1,
+ "label": "Backup Folder Name",
+ "set_only_once": 1,
+ "unique": 1
+ },
+ {
+ "fieldname": "backup_folder_id",
+ "fieldtype": "Data",
+ "label": "Backup Folder ID",
"read_only": 1
}
],
- "modified": "2019-08-11 05:17:36.862158",
+ "modified": "2019-08-11 12:42:41.738678",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index f06dc50386..0c7c5be70b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -7,6 +7,7 @@ import frappe
import requests
import googleapiclient.discovery
import google.oauth2.credentials
+import os
from frappe import _
from googleapiclient.errors import HttpError
@@ -16,11 +17,20 @@ from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
from frappe.utils.file_manager import save_file, get_file_url
from frappe.utils.print_format import download_pdf
+from frappe.utils import get_backups_path, get_files_path
+from frappe.utils.backups import new_backup
+from frappe.utils import now
SCOPES = "https://www.googleapis.com/auth/drive"
class GoogleDrive(Document):
+ def validate(self):
+ if self.enable_system_backup:
+ system_backup = frappe.db.exists("Google Drive", {"enable_system_backup": 1})
+ if system_backup and not system_backup == self.name:
+ frappe.throw(_("Google Drive System Backup can be enabled only for one account."))
+
def get_access_token(self):
google_settings = frappe.get_doc("Google Settings")
@@ -122,52 +132,108 @@ def get_google_drive_object(g_drive):
return google_drive_object, account
def create_folder_in_google_drive(google_drive_object, account):
- """
- Create a folder on Drive, returns the newely created folders ID
- """
file_metadata = {
- "name": account.folder_name,
+ "name": account.backup_folder_name,
"mimeType": "application/vnd.google-apps.folder"
}
folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
- frappe.db.set_value("Google Drive", account.name, "folder_id", folder.get("id"))
+ frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
+
+def check_for_folder_in_google_drive(google_drive_object, account):
+ """
+ Create a folder on Drive, returns the newely created folders ID
+ """
+ if not account.backup_folder_id:
+ create_folder_in_google_drive(google_drive_object, account)
+ return
+
+ try:
+ folder = google_drive_object.files().get(fileId=account.backup_folder_id, fields="id").execute()
+ except HttpError as e:
+ if e.resp.status == 404:
+ create_folder_in_google_drive(google_drive_object, account)
+ else:
+ frappe.msgprint(_("Google Drive - Could not create folder - Error Code {0}.").format(e))
@frappe.whitelist()
def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhead):
"""
Uploads Document to Folder specified in Google Drive Doc.
"""
+ # Get Google Drive Object
google_drive_object, account = get_google_drive_object(g_drive)
- if not account.folder_id:
- create_folder_in_google_drive(google_drive_object, account)
- account.load_from_db()
+ # Check if folder exists in Google Drive
+ check_for_folder_in_google_drive(google_drive_object, account)
+ account.load_from_db()
+ # Create PDF for doc and append datestring to name
download_pdf(doctype=doctype, name=docname, format=format, no_letterhead=letterhead)
-
- filename = frappe.local.response.filename.replace(".pdf", "-{0}.pdf".format(frappe.generate_hash(length=5)))
+ filename = frappe.local.response.filename.replace(".pdf", "-{0}.pdf".format(now()))
filecontent = frappe.local.response.filecontent
- upload_file = save_file(filename, filecontent, doctype, docname)
+ file_to_upload = save_file(filename, filecontent, doctype, docname)
- if not upload_file:
+ if not file_to_upload:
frappe.throw(_("Could not upload pdf to Google Drive"))
- fileurl = upload_file.file_url or upload_file.file_name
+ fileurl = os.path.basename(file_to_upload.file_name or file_to_upload.file_url)
+
+ # parents: Folder id under which the file is to be uploaded
file_metadata = {
"name": filename,
- "parents": [account.folder_id]
+ "parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/pdf")
+ media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/pdf", resumable=True)
try:
- file = google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
except HttpError as e:
- frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e.resp.status))
+ frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
-def get_absolute_path(filename):
- filename = filename.replace("/files/", "")
- file_path = frappe.utils.get_path("public", "files", filename).replace("./", "")
+@frappe.whitelist()
+def upload_system_backup_to_google_drive(g_drive):
+ """
+ Upload system backup to Google Drive
+ """
+ # Get Google Drive Object
+ google_drive_object, account = get_google_drive_object(g_drive)
+
+ # Check if folder exists in Google Drive
+ check_for_folder_in_google_drive(google_drive_object, account)
+ account.load_from_db()
+
+ backup = new_backup(ignore_files=True)
+
+ fileurl = os.path.basename(backup.backup_path_db)
+
+ file_metadata = {
+ "name": "Instance Backup-{0}".format(frappe.utils.now()),
+ "parents": [account.backup_folder_id]
+ }
+
+ media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
+
+ try:
+ google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ except HttpError as e:
+ frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
+
+def daily_backup():
+ g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
+ if g_drive:
+ upload_system_backup_to_google_drive(g_drive)
+
+def weekly_backup():
+ g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Weekly"})
+ if g_drive:
+ upload_system_backup_to_google_drive(g_drive)
+
+def get_absolute_path(filename, backup=False):
+ file_path = os.path.join(frappe.utils.get_files_path()[2:], filename)
+
+ if backup:
+ file_path = os.path.join(frappe.utils.get_backups_path()[2:], filename)
return "{0}/sites/{1}".format(frappe.utils.get_bench_path(), file_path)
\ No newline at end of file
diff --git a/frappe/integrations/doctype/gsuite_settings/__init__.py b/frappe/integrations/doctype/gsuite_settings/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.js b/frappe/integrations/doctype/gsuite_settings/gsuite_settings.js
deleted file mode 100644
index 71db53c5cc..0000000000
--- a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('GSuite Settings', {
- refresh: function(frm) {
- frm.clear_custom_buttons();
- },
-
- allow_gsuite_access: function(frm) {
- if (frm.doc.client_id && frm.doc.client_secret) {
- frappe.call({
- method: "frappe.integrations.doctype.gsuite_settings.gsuite_settings.gsuite_callback",
- callback: function(r) {
- if(!r.exc) {
- frm.save();
- window.open(r.message.url);
- }
- }
- });
- }
- else {
- frappe.msgprint(__("Please enter values for GSuite Access Key and GSuite Access Secret"))
- }
- },
- run_script_test: function(frm) {
- if (frm.doc.client_id && frm.doc.client_secret) {
- frappe.call({
- method: "frappe.integrations.doctype.gsuite_settings.gsuite_settings.run_script_test",
- callback: function(r) {
- if(!r.exc) {
- if (r.message == 'ping') {
- frappe.msgprint(__('GSuite test executed with success. GSuite integration is correctly configured'),__('GSuite script test'));
- }
- }
- }
- });
- }
- else {
- frappe.msgprint(__("Please enter values for GSuite Access Key and GSuite Access Secret"));
- }
- }
-});
diff --git a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.json b/frappe/integrations/doctype/gsuite_settings/gsuite_settings.json
deleted file mode 100644
index 65ed904c74..0000000000
--- a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.json
+++ /dev/null
@@ -1,404 +0,0 @@
-{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2017-04-21 16:57:30.264478",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "System",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "enable",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Enable",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.enable",
- "fieldname": "google_credentials",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Google Credentials",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "client_id",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Client ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "client_secret",
- "fieldtype": "Password",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Client Secret",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:(doc.client_secret && doc.client_id)",
- "fieldname": "allow_gsuite_access",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow GSuite access",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "depends_on": "eval:doc.enable",
- "fieldname": "google_apps_script",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Google Apps Script",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "https://script.google.com/macros/s/AKfycbxIFOx3301xwtF2IFPJ4pUQGqkNF3hBiBebppWkeKn6fKZRQvk/exec",
- "depends_on": "",
- "description": "If you aren't using own publish Google Apps Script webapp you can use the default https://script.google.com/macros/s/AKfycbxIFOx3301xwtF2IFPJ4pUQGqkNF3hBiBebppWkeKn6fKZRQvk/exec ",
- "fieldname": "script_url",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Script URL",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "description": "Copy and paste this code into and empty Code.gs in your project at script.google.com",
- "fieldname": "script_code",
- "fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Script Code",
- "length": 0,
- "no_copy": 0,
- "options": "// ERPNEXT GSuite integration\n//\n\nfunction doGet(e){\n return ContentService.createTextOutput('ok');\n}\n\nfunction doPost(e) {\n var p = JSON.parse(e.postData.contents);\n\n switch(p.exec){\n case 'new':\n var url = createDoc(p);\n result = { 'url': url };\n break;\n case 'test':\n result = { 'test':'ping' , 'version':'1.0'}\n }\n return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);\n}\n\nfunction replaceVars(body,p){\n for (key in p) {\n if (p.hasOwnProperty(key)) {\n if (p[key] != null) {\n body.replaceText('{{'+key+'}}', p[key]);\n }\n }\n } \n}\n\nfunction createDoc(p) {\n if(p.destination){\n var folder = DriveApp.getFolderById(p.destination);\n } else {\n var folder = DriveApp.getRootFolder();\n }\n var template = DriveApp.getFileById( p.template )\n var newfile = template.makeCopy( p.filename , folder );\n\n switch(newfile.getMimeType()){\n case MimeType.GOOGLE_DOCS:\n var body = DocumentApp.openById(newfile.getId()).getBody();\n replaceVars(body,p.vars);\n break;\n case MimeType.GOOGLE_SHEETS:\n //TBD\n case MimeType.GOOGLE_SLIDES:\n //TBD\n }\n return newfile.getUrl()\n}\n\n",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:(doc.client_id && doc.client_secret && doc.authorization_code && doc.refresh_token && doc.script_url)",
- "fieldname": "run_script_test",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Run Script Test",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "refresh_token",
- "fieldtype": "Password",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "refresh_token",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "authorization_code",
- "fieldtype": "Password",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Authorization Code",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 1,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-10-20 16:11:47.757030",
- "modified_by": "Administrator",
- "module": "Integrations",
- "name": "GSuite Settings",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "quick_entry": 1,
- "read_only": 1,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.py b/frappe/integrations/doctype/gsuite_settings/gsuite_settings.py
deleted file mode 100644
index 4e88ad736c..0000000000
--- a/frappe/integrations/doctype/gsuite_settings/gsuite_settings.py
+++ /dev/null
@@ -1,87 +0,0 @@
- # Copyright (c) 2017, Frappe Technologies and contributors
-# -*- coding: utf-8 -*-
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.utils import get_request_site_address
-import requests
-from json import dumps
-from frappe.utils.response import json_handler
-
-SCOPES = 'https://www.googleapis.com/auth/drive'
-
-class GSuiteSettings(Document):
-
- def get_access_token(self):
- if not self.refresh_token:
- raise frappe.ValidationError(_("Google GSuite is not configured."))
- data = {
- 'client_id': self.client_id,
- 'client_secret': self.get_password(fieldname='client_secret',raise_exception=False),
- 'refresh_token': self.get_password(fieldname='refresh_token',raise_exception=False),
- 'grant_type': "refresh_token",
- 'scope': SCOPES
- }
- try:
- r = requests.post('https://www.googleapis.com/oauth2/v4/token', data=data).json()
- except requests.exceptions.HTTPError:
- frappe.throw(_("Something went wrong during the token generation. Please request again an authorization code."))
- return r.get('access_token')
-
-@frappe.whitelist()
-def gsuite_callback(code=None):
- doc = frappe.get_doc("GSuite Settings")
- if code is None:
- return {
- 'url': 'https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id={}&scope={}&redirect_uri={}?cmd=frappe.integrations.doctype.gsuite_settings.gsuite_settings.gsuite_callback'.format(doc.client_id, SCOPES, get_request_site_address(True))
- }
- else:
- try:
- data = {'code': code,
- 'client_id': doc.client_id,
- 'client_secret': doc.get_password(fieldname='client_secret',raise_exception=False),
- 'redirect_uri': get_request_site_address(True) + '?cmd=frappe.integrations.doctype.gsuite_settings.gsuite_settings.gsuite_callback',
- 'grant_type': 'authorization_code'}
- r = requests.post('https://www.googleapis.com/oauth2/v4/token', data=data).json()
- frappe.db.set_value("Gsuite Settings", None, "authorization_code", code)
- if 'refresh_token' in r:
- frappe.db.set_value("Gsuite Settings", None, "refresh_token", r['refresh_token'])
- frappe.db.commit()
- return
- except Exception as e:
- frappe.throw(e.message)
-
-def run_gsuite_script(option, filename = None, template_id = None, destination_id = None, json_data = None):
- gdoc = frappe.get_doc('GSuite Settings')
- if gdoc.script_url:
- data = {
- 'exec': option,
- 'filename': filename,
- 'template': template_id,
- 'destination': destination_id,
- 'vars' : json_data
- }
- headers = {'Authorization': 'Bearer {}'.format( gdoc.get_access_token() )}
-
- try:
- r = requests.post(gdoc.script_url, headers=headers, data=dumps(data, default=json_handler, separators=(',',':')))
- except Exception as e:
- frappe.throw(e.message)
-
- try:
- r = r.json()
- except:
- # if request doesn't return json show HTML ask permissions or to identify the error on google side
- frappe.throw(r.text)
-
- return r
- else:
- frappe.throw(_('Please set script URL on Gsuite Settings'))
-
-@frappe.whitelist()
-def run_script_test():
- r = run_gsuite_script('test')
- return r['test']
diff --git a/frappe/integrations/doctype/gsuite_templates/__init__.py b/frappe/integrations/doctype/gsuite_templates/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.js b/frappe/integrations/doctype/gsuite_templates/gsuite_templates.js
deleted file mode 100644
index ddaa740afd..0000000000
--- a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('GSuite Templates', {
- refresh: function(frm) {
- if (frm.is_new()) {
- // if doc is new, get all options immediately
- frm.trigger('set_available_docs');
- frm.trigger('set_available_folders');
- }
- },
- set_available_docs: function(frm) {
- frappe.call({
- // get documents from Google Drive
- method: 'frappe.integrations.doctype.gsuite_templates.gsuite_templates.get_gdrive_docs',
- callback: function(res) {
- // set available documents as options
- set_gsuite_template_options(frm, 'template_id', res);
- }
- });
- },
- set_available_folders: function(frm) {
- frappe.call({
- // get folders from Google Drive
- method: 'frappe.integrations.doctype.gsuite_templates.gsuite_templates.get_gdrive_folders',
- callback: function(res) {
- // set available folders as options
- set_gsuite_template_options(frm, 'destination_id', res);
- }
- });
- },
-});
-
-const set_gsuite_template_options = function(frm, field, data) {
- var options = [];
- (data.message || []).forEach(function(row){
- options.push({'value': row.id, 'label': row.name});
- });
- frm.set_df_property(field, 'options', options);
-};
-
diff --git a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.json b/frappe/integrations/doctype/gsuite_templates/gsuite_templates.json
deleted file mode 100644
index e0e047a671..0000000000
--- a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.json
+++ /dev/null
@@ -1,228 +0,0 @@
-{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:template_name",
- "beta": 0,
- "creation": "2017-04-24 09:53:41.813982",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
- "fieldname": "template_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Template Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 1
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
- "fieldname": "related_doctype",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Related DocType",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
- "fieldname": "template_id",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Template ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "New Document for {name} ",
- "fetch_if_empty": 0,
- "fieldname": "document_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Document Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
- "fieldname": "destination_id",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Destination ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- }
- ],
- "has_web_view": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-04-14 00:13:49.999149",
- "modified_by": "Administrator",
- "module": "Integrations",
- "name": "GSuite Templates",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "quick_entry": 0,
- "read_only": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
-}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.py b/frappe/integrations/doctype/gsuite_templates/gsuite_templates.py
deleted file mode 100644
index 66028a13d4..0000000000
--- a/frappe/integrations/doctype/gsuite_templates/gsuite_templates.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import requests
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.integrations.doctype.gsuite_settings.gsuite_settings import run_gsuite_script
-
-class GSuiteTemplates(Document):
- pass
-
-@frappe.whitelist()
-def create_gsuite_doc(doctype, docname, gs_template=None):
- templ = frappe.get_doc('GSuite Templates', gs_template)
- doc = frappe.get_doc(doctype, docname)
-
- if not doc.has_permission("read"):
- raise frappe.PermissionError
-
- json_data = doc.as_dict()
- filename = templ.document_name.format(**json_data)
-
- response = run_gsuite_script('new', filename, templ.template_id, templ.destination_id, json_data)
-
- _file = frappe.get_doc({
- "doctype": "File",
- "file_url": response['url'],
- "file_name": filename,
- "attached_to_doctype": doctype,
- "attached_to_name": docname,
- "attached_to_field": True,
- "folder": "Home/Attachments"})
- _file.save()
-
- comment = frappe.get_doc(doctype, docname).add_comment("Attachment",
- _("added {0}").format("{file_name}{icon}".format(**{
- "icon": ' ' if _file.is_private else "",
- "file_url": _file.file_url.replace("#", "%23") if _file.file_name else _file.file_url,
- "file_name": _file.file_name or _file.file_url
- })))
-
- return {
- "name": _file.name,
- "file_name": _file.file_name,
- "file_url": _file.file_url,
- "is_private": _file.is_private,
- "comment": comment.as_dict() if comment else {}
- }
-
-@frappe.whitelist()
-def get_gdrive_docs():
- """ Return a list of Google Docs files in Google Drive """
- return get_gdrive_files('application/vnd.google-apps.document')
-
-@frappe.whitelist()
-def get_gdrive_folders():
- """ Return a list of folders in Google Drive """
- return get_gdrive_files('application/vnd.google-apps.folder')
-
-def get_gdrive_files(mime_type):
- """ Get a list of files of the specified mime_type from Google Drive
-
- returns [
- {
- "kind": "drive#file",
- "id": "sf_lk-U6lYhVvdgsdf98cvkbj87rl6piFtnLEN9oNsrg",
- "name": "My File Name",
- "mimeType": mime_type
- }
- ]
- """
- settings = frappe.get_single("GSuite Settings")
- token = settings.get_access_token()
- url = 'https://www.googleapis.com/drive/v3/files'
-
- params = {
- "q": "mimeType='{}'".format(mime_type)
- }
-
- headers = {
- 'Authorization': 'Bearer {}'.format(token),
- 'Accept': 'application/json'
- }
-
- try:
- response = requests.get(url, params=params, headers=headers)
- except requests.exceptions.RequestException as err:
- frappe.throw(err)
-
- return response.json().get('files')
diff --git a/frappe/integrations/doctype/gsuite_templates/test_gsuite_templates.py b/frappe/integrations/doctype/gsuite_templates/test_gsuite_templates.py
deleted file mode 100644
index aad8e9fae6..0000000000
--- a/frappe/integrations/doctype/gsuite_templates/test_gsuite_templates.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import frappe
-import unittest
-
-class TestGSuiteTemplates(unittest.TestCase):
- pass
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 1c180281a0..855e851b0f 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -470,6 +470,7 @@ frappe.ui.form.PrintPreview = Class.extend({
get_query: function() {
return {
"filters": {
+ "enable": 1,
"owner": frappe.session.user,
}
}
@@ -482,7 +483,10 @@ frappe.ui.form.PrintPreview = Class.extend({
indicator: "red",
message: __("Uploading to Google Drive.")
})
+
uploader.hide();
+ uploader.disable_primary_action();
+ uploader.clear();
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.upload_document_to_google_drive",
@@ -493,7 +497,7 @@ frappe.ui.form.PrintPreview = Class.extend({
format: me.selected_format(),
letterhead: me.with_letterhead() ? "0" : "1"
},
- callback: function(r) {
+ callback: function() {
frappe.show_alert({
indicator: "green",
message: __("Document uploaded to Google Drive.")
From 47450d5a43329ad7201b6924eb1d9d26b64d4dce Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:04:14 +0530
Subject: [PATCH 06/58] fix: add take backup button
---
.../doctype/google_drive/google_drive.js | 18 ++++++++++++++++++
.../doctype/google_drive/google_drive.py | 2 ++
2 files changed, 20 insertions(+)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 9bdd7ca4c5..248a616394 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -6,6 +6,24 @@ frappe.ui.form.on('Google Drive', {
if (frm.is_new()) {
frm.dashboard.set_headline(__("To use Google Drive, enable Google Settings."));
}
+
+ if (frm.doc.enable_system_backup) {
+ let sync_button = frm.add_custom_button(__("Take Backup"), function () {
+ frappe.show_alert({
+ indicator: "green",
+ message: __("Backing up to Google Drive.")
+ });
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive",
+ args: {
+ "g_drive": frm.doc.name
+ },
+ btn: sync_button
+ }).then((r) => {
+ frappe.msgprint(r.message);
+ });
+ });
+ }
},
authorize_google_drive_access: function(frm) {
let reauthorize = 0;
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 0c7c5be70b..d2f78ddb04 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -220,6 +220,8 @@ def upload_system_backup_to_google_drive(g_drive):
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
+ return "Google Drive Backup Successful."
+
def daily_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
if g_drive:
From 1791cbf0cc95b6019cb1662dd12ce8729a348f5f Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:08:37 +0530
Subject: [PATCH 07/58] fix: hide password fields
---
frappe/config/integrations.py | 15 +++++----------
.../doctype/google_drive/google_drive.json | 8 +++++---
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/frappe/config/integrations.py b/frappe/config/integrations.py
index bbe3966b29..bfed056546 100644
--- a/frappe/config/integrations.py
+++ b/frappe/config/integrations.py
@@ -92,16 +92,6 @@ def get_data():
"name": "Google Settings",
"description": _("Google API Settings."),
},
- {
- "type": "doctype",
- "name": "GSuite Settings",
- "description": _("Enter keys to enable integration with Google GSuite"),
- },
- {
- "type": "doctype",
- "name": "GSuite Templates",
- "description": _("Google GSuite Templates to integration with DocTypes"),
- },
{
"type": "doctype",
"name": "Google Contacts",
@@ -111,6 +101,11 @@ def get_data():
"type": "doctype",
"name": "Google Calendar",
"description": _("Google Calendar Integration."),
+ },
+ {
+ "type": "doctype",
+ "name": "Google Drive",
+ "description": _("Google Drive Integration."),
}
]
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 5233fdc9ab..612ded6fab 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -45,12 +45,14 @@
},
{
"fieldname": "authorization_code",
- "fieldtype": "Data",
+ "fieldtype": "Password",
+ "hidden": 1,
"label": "Authorization Code"
},
{
"fieldname": "refresh_token",
- "fieldtype": "Data",
+ "fieldtype": "Password",
+ "hidden": 1,
"label": "Refresh Token"
},
{
@@ -85,7 +87,7 @@
"read_only": 1
}
],
- "modified": "2019-08-11 12:42:41.738678",
+ "modified": "2019-08-11 15:37:45.346890",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From ae1f362d34a1d0d375dd769569f27fb001d3c00e Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:30:48 +0530
Subject: [PATCH 08/58] fix: naming
---
frappe/integrations/doctype/google_drive/google_drive.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 612ded6fab..2f25381173 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -1,5 +1,5 @@
{
- "autoname": "format:{folder_name}-{reference_doctype}",
+ "autoname": "field:backup_folder_name",
"creation": "2019-08-08 13:16:06.783138",
"doctype": "DocType",
"engine": "InnoDB",
@@ -87,7 +87,7 @@
"read_only": 1
}
],
- "modified": "2019-08-11 15:37:45.346890",
+ "modified": "2019-08-11 16:00:39.521237",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From 4ae9624787282c9bba22827ba654472ced0ef142 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:43:22 +0530
Subject: [PATCH 09/58] fix: sync folder name
---
.../doctype/google_drive/google_drive.js | 17 +++++++++++++++++
.../doctype/google_drive/google_drive.py | 8 +++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 248a616394..d37ac23a48 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -24,6 +24,23 @@ frappe.ui.form.on('Google Drive', {
});
});
}
+ if (!frm.doc.backup_folder_id) {
+ let sync_button = frm.add_custom_button(__("Create Folder in Google Drive"), function () {
+ frappe.show_alert({
+ indicator: "green",
+ message: __("Creating folder in Google Drive.")
+ });
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
+ args: {
+ "g_drive": frm.doc.name
+ },
+ btn: sync_button
+ }).then((r) => {
+ frappe.msgprint(r.message);
+ });
+ });
+ }
},
authorize_google_drive_access: function(frm) {
let reauthorize = 0;
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index d2f78ddb04..b424362bfc 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -131,7 +131,11 @@ def get_google_drive_object(g_drive):
return google_drive_object, account
-def create_folder_in_google_drive(google_drive_object, account):
+@frappe.whitelist()
+def create_folder_in_google_drive(google_drive_object=None, account=None, g_drive=None):
+ if g_drive:
+ google_drive_object, account = get_google_drive_object(g_drive)
+
file_metadata = {
"name": account.backup_folder_name,
"mimeType": "application/vnd.google-apps.folder"
@@ -139,6 +143,8 @@ def create_folder_in_google_drive(google_drive_object, account):
folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
+ return "Folder created successfully in Google Drive."
+
def check_for_folder_in_google_drive(google_drive_object, account):
"""
Create a folder on Drive, returns the newely created folders ID
From 6fecd28df04bfa09e6be52ce3edd7c0a9b10a584 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:48:16 +0530
Subject: [PATCH 10/58] fix: show drive id
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 ++
frappe/integrations/doctype/google_drive/google_drive.json | 5 ++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index d37ac23a48..b8bf2f9f3d 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -40,6 +40,8 @@ frappe.ui.form.on('Google Drive', {
frappe.msgprint(r.message);
});
});
+ } else {
+ frm.set_df_property("backup_folder_id", "read_only", 1);
}
},
authorize_google_drive_access: function(frm) {
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 2f25381173..d10e86bab1 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -83,11 +83,10 @@
{
"fieldname": "backup_folder_id",
"fieldtype": "Data",
- "label": "Backup Folder ID",
- "read_only": 1
+ "label": "Backup Folder ID"
}
],
- "modified": "2019-08-11 16:00:39.521237",
+ "modified": "2019-08-11 16:17:26.314299",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From cd732c36b7b49e0b17780d26a4301804f9bfaecc Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 19:52:22 +0530
Subject: [PATCH 11/58] fix: refresh page
---
frappe/integrations/doctype/google_drive/google_drive.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index b8bf2f9f3d..42e46281e1 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -24,7 +24,7 @@ frappe.ui.form.on('Google Drive', {
});
});
}
- if (!frm.doc.backup_folder_id) {
+ if (!frm.doc.backup_folder_id && frm.doc.refresh_token) {
let sync_button = frm.add_custom_button(__("Create Folder in Google Drive"), function () {
frappe.show_alert({
indicator: "green",
@@ -37,6 +37,7 @@ frappe.ui.form.on('Google Drive', {
},
btn: sync_button
}).then((r) => {
+ frm.refresh();
frappe.msgprint(r.message);
});
});
From b4bff26f3f937079971f4dab660813a28409380e Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 20:00:03 +0530
Subject: [PATCH 12/58] fix: show proper feedback
---
frappe/integrations/doctype/google_drive/google_drive.py | 4 +++-
frappe/public/js/frappe/form/print.js | 7 ++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index b424362bfc..673d279384 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -198,6 +198,8 @@ def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhea
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
+ return _("{0} {1} uploaded to Google Drive successfully.").format(doctype, docname)
+
@frappe.whitelist()
def upload_system_backup_to_google_drive(g_drive):
"""
@@ -226,7 +228,7 @@ def upload_system_backup_to_google_drive(g_drive):
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
- return "Google Drive Backup Successful."
+ return _("Google Drive Backup Successful.")
def daily_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 855e851b0f..89556e1d62 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -497,11 +497,8 @@ frappe.ui.form.PrintPreview = Class.extend({
format: me.selected_format(),
letterhead: me.with_letterhead() ? "0" : "1"
},
- callback: function() {
- frappe.show_alert({
- indicator: "green",
- message: __("Document uploaded to Google Drive.")
- });
+ callback: function(r) {
+ frappe.msgprint(r.message);
}
})
}
From ed994eaf9195857511557df8e0dd5b8a37488c6c Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 23:24:00 +0530
Subject: [PATCH 13/58] fix: frappe throw if folder not synced
---
frappe/integrations/doctype/google_drive/google_drive.js | 3 ++-
frappe/integrations/doctype/google_drive/google_drive.py | 3 +++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 42e46281e1..9e4c8e3009 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -24,6 +24,7 @@ frappe.ui.form.on('Google Drive', {
});
});
}
+
if (!frm.doc.backup_folder_id && frm.doc.refresh_token) {
let sync_button = frm.add_custom_button(__("Create Folder in Google Drive"), function () {
frappe.show_alert({
@@ -37,7 +38,7 @@ frappe.ui.form.on('Google Drive', {
},
btn: sync_button
}).then((r) => {
- frm.refresh();
+ refresh_field("backup_folder_id");
frappe.msgprint(r.message);
});
});
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 673d279384..09ea54feab 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -117,6 +117,9 @@ def get_google_drive_object(g_drive):
google_settings = frappe.get_doc("Google Settings")
account = frappe.get_doc("Google Drive", g_drive)
+ if not account.backup_folder_id:
+ frappe.throw(_("Folder {0} not created in Google Drive.").format(account.backup_folder_name))
+
credentials_dict = {
"token": account.get_access_token(),
"refresh_token": account.get_password(fieldname="refresh_token", raise_exception=False),
From 184ee4ed5aa7839108f98b7c22dd4aff3337cb51 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Sun, 11 Aug 2019 23:41:23 +0530
Subject: [PATCH 14/58] fix: msgrint
---
.../integrations/doctype/google_drive/google_drive.json | 6 +++---
frappe/public/js/frappe/form/print.js | 9 +++++----
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index d10e86bab1..398b96f817 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -45,13 +45,13 @@
},
{
"fieldname": "authorization_code",
- "fieldtype": "Password",
+ "fieldtype": "Data",
"hidden": 1,
"label": "Authorization Code"
},
{
"fieldname": "refresh_token",
- "fieldtype": "Password",
+ "fieldtype": "Data",
"hidden": 1,
"label": "Refresh Token"
},
@@ -86,7 +86,7 @@
"label": "Backup Folder ID"
}
],
- "modified": "2019-08-11 16:17:26.314299",
+ "modified": "2019-08-11 20:08:45.407321",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 89556e1d62..5e4e3e5816 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -479,15 +479,15 @@ frappe.ui.form.PrintPreview = Class.extend({
],
primary_action_label: __("Submit"),
primary_action: (d) => {
+ uploader.hide();
+ uploader.disable_primary_action();
+ uploader.clear();
+
frappe.show_alert({
indicator: "red",
message: __("Uploading to Google Drive.")
})
- uploader.hide();
- uploader.disable_primary_action();
- uploader.clear();
-
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.upload_document_to_google_drive",
args: {
@@ -499,6 +499,7 @@ frappe.ui.form.PrintPreview = Class.extend({
},
callback: function(r) {
frappe.msgprint(r.message);
+ uploader.enable_primary_action();
}
})
}
From 097a366f2851c630e1a89473d00acefef074eb8a Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 12 Aug 2019 09:05:34 +0530
Subject: [PATCH 15/58] fix: show alerts while uploading
---
.../doctype/google_drive/google_drive.py | 6 +++++-
frappe/public/js/frappe/form/print.js | 13 ++++++++++---
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 09ea54feab..c87be2317a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -197,11 +197,12 @@ def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhea
media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/pdf", resumable=True)
try:
+ display_upload_status("orange", _("Uploading file to Google Drive."))
google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
- return _("{0} {1} uploaded to Google Drive successfully.").format(doctype, docname)
+ display_upload_status("green", _("File Uploaded to Google Drive."))
@frappe.whitelist()
def upload_system_backup_to_google_drive(g_drive):
@@ -233,6 +234,9 @@ def upload_system_backup_to_google_drive(g_drive):
return _("Google Drive Backup Successful.")
+def display_upload_status(indicator, message):
+ frappe.publish_realtime("upload_google_drive", dict(indicator=indicator, message=message), user=frappe.session.user)
+
def daily_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
if g_drive:
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 5e4e3e5816..6a650971ca 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -457,6 +457,14 @@ frappe.ui.form.PrintPreview = Class.extend({
},
google_drive_upload: function() {
var me = this;
+
+ frappe.realtime.on("upload_google_drive", (data) => {
+ frappe.show_alert({
+ indicator: data.indicator,
+ message: data.message
+ });
+ });
+
this.wrapper.find(".btn-upload-drive").click(function () {
let uploader = new frappe.ui.Dialog({
title: __("Upload File to Google Drive"),
@@ -485,8 +493,8 @@ frappe.ui.form.PrintPreview = Class.extend({
frappe.show_alert({
indicator: "red",
- message: __("Uploading to Google Drive.")
- })
+ message: __("Preparing file to upload.")
+ });
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.upload_document_to_google_drive",
@@ -498,7 +506,6 @@ frappe.ui.form.PrintPreview = Class.extend({
letterhead: me.with_letterhead() ? "0" : "1"
},
callback: function(r) {
- frappe.msgprint(r.message);
uploader.enable_primary_action();
}
})
From db3656afb7b9e734a117a0f41701632a2571b8e9 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 12 Aug 2019 09:46:51 +0530
Subject: [PATCH 16/58] fix: codacy fixes
---
frappe/boot.py | 4 ----
.../doctype/google_drive/google_drive.js | 4 ++--
.../doctype/google_drive/google_drive.py | 16 ++++++++--------
frappe/public/build.json | 2 --
frappe/public/js/frappe/form/print.js | 3 ++-
frappe/public/js/integrations/gsuite.js | 15 ---------------
6 files changed, 12 insertions(+), 32 deletions(-)
delete mode 100644 frappe/public/js/integrations/gsuite.js
diff --git a/frappe/boot.py b/frappe/boot.py
index 60c5e17cd4..d0fa0f2c71 100644
--- a/frappe/boot.py
+++ b/frappe/boot.py
@@ -76,7 +76,6 @@ def get_bootinfo():
bootinfo.calendars = sorted(frappe.get_hooks("calendars"))
bootinfo.treeviews = frappe.get_hooks("treeviews") or []
bootinfo.lang_dict = get_lang_dict()
- bootinfo.google_drive_enabled = get_google_drive_status()
bootinfo.success_action = get_success_action()
bootinfo.update(get_email_accounts(user=frappe.session.user))
bootinfo.energy_points_enabled = is_energy_point_enabled()
@@ -258,9 +257,6 @@ def get_unseen_notes():
(select user from `tabNote Seen By` nsb
where nsb.parent=`tabNote`.name)''', (frappe.utils.now(), frappe.session.user), as_dict=True)
-def get_google_drive_status():
- return True if frappe.db.exists("Google Drive", {"enable": 1}) else False
-
def get_success_action():
return frappe.get_all("Success Action", fields=["*"])
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 9e4c8e3009..879c6eed89 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -48,7 +48,7 @@ frappe.ui.form.on('Google Drive', {
},
authorize_google_drive_access: function(frm) {
let reauthorize = 0;
- if(frm.doc.authorization_code) {
+ if (frm.doc.authorization_code) {
reauthorize = 1;
}
@@ -59,7 +59,7 @@ frappe.ui.form.on('Google Drive', {
"reauthorize": reauthorize
},
callback: function(r) {
- if(!r.exc) {
+ if (!r.exc) {
frm.save();
window.open(r.message.url);
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index c87be2317a..62d3d507b8 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -15,7 +15,7 @@ from frappe.model.document import Document
from frappe.utils import get_request_site_address
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
-from frappe.utils.file_manager import save_file, get_file_url
+from frappe.utils.file_manager import save_file
from frappe.utils.print_format import download_pdf
from frappe.utils import get_backups_path, get_files_path
from frappe.utils.backups import new_backup
@@ -143,8 +143,11 @@ def create_folder_in_google_drive(google_drive_object=None, account=None, g_driv
"name": account.backup_folder_name,
"mimeType": "application/vnd.google-apps.folder"
}
- folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
- frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
+ try:
+ folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
+ frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
+ except HttpError as e
+ frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
return "Folder created successfully in Google Drive."
@@ -157,12 +160,9 @@ def check_for_folder_in_google_drive(google_drive_object, account):
return
try:
- folder = google_drive_object.files().get(fileId=account.backup_folder_id, fields="id").execute()
+ google_drive_object.files().get(fileId=account.backup_folder_id, fields="id").execute()
except HttpError as e:
- if e.resp.status == 404:
- create_folder_in_google_drive(google_drive_object, account)
- else:
- frappe.msgprint(_("Google Drive - Could not create folder - Error Code {0}.").format(e))
+ frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
@frappe.whitelist()
def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhead):
diff --git a/frappe/public/build.json b/frappe/public/build.json
index 7bec259933..5e55e3e1f8 100755
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -187,7 +187,6 @@
"public/js/frappe/ui/upload.html",
"public/js/frappe/upload.js",
- "public/js/integrations/gsuite.js",
"public/js/frappe/ui/tree.js",
"public/js/frappe/views/container.js",
@@ -205,7 +204,6 @@
"public/js/frappe/ui/toolbar/toolbar.js",
"public/js/frappe/ui/toolbar/notifications.js",
"public/js/frappe/views/communication.js",
- "public/js/frappe/views/google_drive_uploader.js",
"public/js/frappe/views/translation_manager.js",
"public/js/frappe/ui/sort_selector.html",
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 6a650971ca..6030219412 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -506,9 +506,10 @@ frappe.ui.form.PrintPreview = Class.extend({
letterhead: me.with_letterhead() ? "0" : "1"
},
callback: function(r) {
+ frappe.msgprint(r.message);
uploader.enable_primary_action();
}
- })
+ });
}
});
uploader.show();
diff --git a/frappe/public/js/integrations/gsuite.js b/frappe/public/js/integrations/gsuite.js
deleted file mode 100644
index 53248a8f32..0000000000
--- a/frappe/public/js/integrations/gsuite.js
+++ /dev/null
@@ -1,15 +0,0 @@
-frappe.provide("frappe.integration_service");
-
-frappe.integration_service.gsuite = {
- create_gsuite_file: function(args, opts) {
- return frappe.call({
- type:'POST',
- method: 'frappe.integrations.doctype.gsuite_templates.gsuite_templates.create_gsuite_doc',
- args: args,
- callback: function(r) {
- var attachment = r.message;
- opts.callback && opts.callback(attachment, r);
- }
- });
- }
-};
From d9103614738de7c3604fd2719cfe5e9eb4bda88d Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 12 Aug 2019 10:25:21 +0530
Subject: [PATCH 17/58] fix: get auth url from google settings
---
.../doctype/google_calendar/google_calendar.py | 7 ++++---
.../doctype/google_contacts/google_contacts.py | 5 +++--
.../doctype/google_drive/google_drive.py | 13 +++++++------
.../doctype/google_settings/google_settings.py | 5 ++++-
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/frappe/integrations/doctype/google_calendar/google_calendar.py b/frappe/integrations/doctype/google_calendar/google_calendar.py
index cc503db9f7..d6ba82ed5a 100644
--- a/frappe/integrations/doctype/google_calendar/google_calendar.py
+++ b/frappe/integrations/doctype/google_calendar/google_calendar.py
@@ -16,6 +16,7 @@ from frappe.utils import add_days, get_datetime, get_weekdays, now_datetime, add
from dateutil import parser
from datetime import datetime, timedelta
from six.moves.urllib.parse import quote
+from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
SCOPES = "https://www.googleapis.com/auth/calendar"
@@ -81,7 +82,7 @@ class GoogleCalendar(Document):
}
try:
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
except requests.exceptions.HTTPError:
button_label = frappe.bold(_("Allow Google Calendar Access"))
frappe.throw(_("Something went wrong during the token generation. Click on {0} to generate a new one.").format(button_label))
@@ -111,7 +112,7 @@ def authorize_access(g_calendar, reauthorize=None):
"redirect_uri": redirect_uri,
"grant_type": "authorization_code"
}
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
if "refresh_token" in r:
frappe.db.set_value("Google Calendar", google_calendar.name, "refresh_token", r.get("refresh_token"))
@@ -162,7 +163,7 @@ def get_google_calendar_object(g_calendar):
credentials_dict = {
"token": account.get_access_token(),
"refresh_token": account.get_password(fieldname="refresh_token", raise_exception=False),
- "token_uri": "https://www.googleapis.com/oauth2/v4/token",
+ "token_uri": get_auth_url(),
"client_id": google_settings.client_id,
"client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
"scopes": "https://www.googleapis.com/auth/calendar/v3"
diff --git a/frappe/integrations/doctype/google_contacts/google_contacts.py b/frappe/integrations/doctype/google_contacts/google_contacts.py
index 6610173e3e..e7eaf928d1 100644
--- a/frappe/integrations/doctype/google_contacts/google_contacts.py
+++ b/frappe/integrations/doctype/google_contacts/google_contacts.py
@@ -8,6 +8,7 @@ import requests
from frappe.model.document import Document
from frappe import _
from frappe.utils import get_request_site_address
+from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
SCOPES = "https://www.googleapis.com/auth/contacts"
REQUEST = "https://people.googleapis.com/v1/people/me/connections"
@@ -38,7 +39,7 @@ class GoogleContacts(Document):
}
try:
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
except requests.exceptions.HTTPError:
button_label = frappe.bold(_('Allow Google Contacts Access'))
frappe.throw(_("Something went wrong during the token generation. Click on {0} to generate a new one.").format(button_label))
@@ -69,7 +70,7 @@ def authorize_access(g_contact, reauthorize=None):
"redirect_uri": redirect_uri,
"grant_type": "authorization_code"
}
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
if "refresh_token" in r:
frappe.db.set_value("Google Contacts", google_contact.name, "refresh_token", r.get("refresh_token"))
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 62d3d507b8..ca4b00abf6 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -20,8 +20,9 @@ from frappe.utils.print_format import download_pdf
from frappe.utils import get_backups_path, get_files_path
from frappe.utils.backups import new_backup
from frappe.utils import now
+from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
-SCOPES = "https://www.googleapis.com/auth/drive"
+SCOPES = "https://www.googleapis.com/auth/drive/v3"
class GoogleDrive(Document):
@@ -50,7 +51,7 @@ class GoogleDrive(Document):
}
try:
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
except requests.exceptions.HTTPError:
button_label = frappe.bold(_("Allow Google Drive Access"))
frappe.throw(_("Something went wrong during the token generation. Click on {0} to generate a new one.").format(button_label))
@@ -81,7 +82,7 @@ def authorize_access(g_drive, reauthorize=None):
"redirect_uri": redirect_uri,
"grant_type": "authorization_code"
}
- r = requests.post("https://www.googleapis.com/oauth2/v4/token", data=data).json()
+ r = requests.post(get_auth_url(), data=data).json()
if "refresh_token" in r:
frappe.db.set_value("Google Drive", google_drive.name, "refresh_token", r.get("refresh_token"))
@@ -123,10 +124,10 @@ def get_google_drive_object(g_drive):
credentials_dict = {
"token": account.get_access_token(),
"refresh_token": account.get_password(fieldname="refresh_token", raise_exception=False),
- "token_uri": "https://www.googleapis.com/oauth2/v4/token",
+ "token_uri": get_auth_url(),
"client_id": google_settings.client_id,
"client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
- "scopes": "https://www.googleapis.com/auth/drive/v3"
+ "scopes": SCOPES
}
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
@@ -146,7 +147,7 @@ def create_folder_in_google_drive(google_drive_object=None, account=None, g_driv
try:
folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
- except HttpError as e
+ except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
return "Folder created successfully in Google Drive."
diff --git a/frappe/integrations/doctype/google_settings/google_settings.py b/frappe/integrations/doctype/google_settings/google_settings.py
index 50713f187c..ecc975235a 100644
--- a/frappe/integrations/doctype/google_settings/google_settings.py
+++ b/frappe/integrations/doctype/google_settings/google_settings.py
@@ -7,4 +7,7 @@ from __future__ import unicode_literals
from frappe.model.document import Document
class GoogleSettings(Document):
- pass
\ No newline at end of file
+ pass
+
+def get_auth_url():
+ return "https://www.googleapis.com/oauth2/v4/token"
\ No newline at end of file
From 468735adf93c02f2090e35952a8a4a8dc9d0aefb Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 12 Aug 2019 11:04:23 +0530
Subject: [PATCH 18/58] chore: codacy fixes
---
.../doctype/google_drive/google_drive.py | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index ca4b00abf6..0a055ab47e 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -17,7 +17,7 @@ from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
from frappe.utils.file_manager import save_file
from frappe.utils.print_format import download_pdf
-from frappe.utils import get_backups_path, get_files_path
+from frappe.utils import get_backups_path, get_files_path, get_bench_path
from frappe.utils.backups import new_backup
from frappe.utils import now
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
@@ -131,37 +131,37 @@ def get_google_drive_object(g_drive):
}
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
- google_drive_object = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
+ google_drive = googleapiclient.discovery.build("drive", "v3", credentials=credentials)
- return google_drive_object, account
+ return google_drive, account
@frappe.whitelist()
-def create_folder_in_google_drive(google_drive_object=None, account=None, g_drive=None):
+def create_folder_in_google_drive(google_drive=None, account=None, g_drive=None):
if g_drive:
- google_drive_object, account = get_google_drive_object(g_drive)
+ google_drive, account = get_google_drive_object(g_drive)
file_metadata = {
"name": account.backup_folder_name,
"mimeType": "application/vnd.google-apps.folder"
}
try:
- folder = google_drive_object.files().create(body=file_metadata, fields="id").execute()
+ folder = google_drive.files().create(body=file_metadata, fields="id").execute()
frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
return "Folder created successfully in Google Drive."
-def check_for_folder_in_google_drive(google_drive_object, account):
+def check_for_folder_in_google_drive(google_drive, account):
"""
Create a folder on Drive, returns the newely created folders ID
"""
if not account.backup_folder_id:
- create_folder_in_google_drive(google_drive_object, account)
+ create_folder_in_google_drive(google_drive, account)
return
try:
- google_drive_object.files().get(fileId=account.backup_folder_id, fields="id").execute()
+ google_drive.files().get(fileId=account.backup_folder_id, fields="id").execute()
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
@@ -171,10 +171,10 @@ def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhea
Uploads Document to Folder specified in Google Drive Doc.
"""
# Get Google Drive Object
- google_drive_object, account = get_google_drive_object(g_drive)
+ google_drive, account = get_google_drive_object(g_drive)
# Check if folder exists in Google Drive
- check_for_folder_in_google_drive(google_drive_object, account)
+ check_for_folder_in_google_drive(google_drive, account)
account.load_from_db()
# Create PDF for doc and append datestring to name
@@ -199,7 +199,7 @@ def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhea
try:
display_upload_status("orange", _("Uploading file to Google Drive."))
- google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
@@ -211,10 +211,10 @@ def upload_system_backup_to_google_drive(g_drive):
Upload system backup to Google Drive
"""
# Get Google Drive Object
- google_drive_object, account = get_google_drive_object(g_drive)
+ google_drive, account = get_google_drive_object(g_drive)
# Check if folder exists in Google Drive
- check_for_folder_in_google_drive(google_drive_object, account)
+ check_for_folder_in_google_drive(google_drive, account)
account.load_from_db()
backup = new_backup(ignore_files=True)
@@ -229,7 +229,7 @@ def upload_system_backup_to_google_drive(g_drive):
media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
try:
- google_drive_object.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
@@ -249,9 +249,9 @@ def weekly_backup():
upload_system_backup_to_google_drive(g_drive)
def get_absolute_path(filename, backup=False):
- file_path = os.path.join(frappe.utils.get_files_path()[2:], filename)
+ file_path = os.path.join(get_files_path()[2:], filename)
if backup:
- file_path = os.path.join(frappe.utils.get_backups_path()[2:], filename)
+ file_path = os.path.join(get_backups_path()[2:], filename)
- return "{0}/sites/{1}".format(frappe.utils.get_bench_path(), file_path)
\ No newline at end of file
+ return "{0}/sites/{1}".format(get_bench_path(), file_path)
\ No newline at end of file
From c4d65de32aca91d3bab26f67f8efc4775cddc49e Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 12 Aug 2019 17:26:40 +0530
Subject: [PATCH 19/58] chore: rename to avoid same name as builtin
---
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
frappe/public/js/frappe/form/print.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 0a055ab47e..64f43e9fc5 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -166,7 +166,7 @@ def check_for_folder_in_google_drive(google_drive, account):
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
@frappe.whitelist()
-def upload_document_to_google_drive(doctype, docname, g_drive, format, letterhead):
+def upload_doc_to_google_drive(doctype, docname, g_drive, format, letterhead):
"""
Uploads Document to Folder specified in Google Drive Doc.
"""
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 6030219412..891ea3ada5 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -497,7 +497,7 @@ frappe.ui.form.PrintPreview = Class.extend({
});
frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.upload_document_to_google_drive",
+ method: "frappe.integrations.doctype.google_drive.google_drive.upload_doc_to_google_drive",
args: {
doctype: me.frm.doc.doctype,
docname: me.frm.doc.name,
From a4fe2b6b7c4facfff5d7f29e26243ec3843779f7 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 13 Aug 2019 17:50:54 +0530
Subject: [PATCH 20/58] fix: remove pdf upload functionality
---
.../doctype/google_drive/google_drive.json | 61 +++++++++---------
.../doctype/google_drive/google_drive.py | 54 ++--------------
frappe/public/js/frappe/form/print.js | 62 -------------------
.../frappe/form/templates/print_layout.html | 2 -
4 files changed, 38 insertions(+), 141 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 398b96f817..8b778f9b90 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -1,6 +1,6 @@
{
"autoname": "field:backup_folder_name",
- "creation": "2019-08-08 13:16:06.783138",
+ "creation": "2019-08-13 17:24:05.470876",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
@@ -9,6 +9,7 @@
"user",
"backup_folder_name",
"authorize_google_drive_access",
+ "last_backup_on",
"column_break_5",
"backup_folder_id",
"enable_system_backup",
@@ -37,28 +38,34 @@
"options": "User",
"reqd": 1
},
+ {
+ "fieldname": "backup_folder_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Backup Folder Name",
+ "set_only_once": 1
+ },
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "authorize_google_drive_access",
"fieldtype": "Button",
"label": "Authorize Google Drive Access"
},
- {
- "fieldname": "authorization_code",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Authorization Code"
- },
- {
- "fieldname": "refresh_token",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Refresh Token"
- },
{
"fieldname": "column_break_5",
"fieldtype": "Column Break"
},
+ {
+ "fieldname": "backup_folder_id",
+ "fieldtype": "Data",
+ "label": "Backup Folder ID"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_system_backup",
+ "fieldtype": "Check",
+ "label": "Enable System Backup"
+ },
{
"depends_on": "enable_system_backup",
"fieldname": "frequency",
@@ -67,26 +74,26 @@
"options": "Daily\nWeekly"
},
{
- "default": "0",
- "fieldname": "enable_system_backup",
- "fieldtype": "Check",
- "label": "Enable System Backup"
+ "fieldname": "refresh_token",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Refresh Token"
},
{
- "fieldname": "backup_folder_name",
+ "fieldname": "authorization_code",
"fieldtype": "Data",
- "in_list_view": 1,
- "label": "Backup Folder Name",
- "set_only_once": 1,
- "unique": 1
+ "hidden": 1,
+ "label": "Authorization Code"
},
{
- "fieldname": "backup_folder_id",
- "fieldtype": "Data",
- "label": "Backup Folder ID"
+ "fieldname": "last_backup_on",
+ "fieldtype": "Datetime",
+ "label": "Last Backup On",
+ "read_only": 1
}
],
- "modified": "2019-08-11 20:08:45.407321",
+ "issingle": 1,
+ "modified": "2019-08-13 17:36:13.014410",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
@@ -106,10 +113,8 @@
"create": 1,
"delete": 1,
"email": 1,
- "export": 1,
"print": 1,
"read": 1,
- "report": 1,
"role": "All",
"share": 1,
"write": 1
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 64f43e9fc5..83d69c6645 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -66,12 +66,11 @@ def authorize_access(g_drive, reauthorize=None):
"""
google_settings = frappe.get_doc("Google Settings")
- google_drive = frappe.get_doc("Google Drive", g_drive)
+ google_drive = frappe.get_doc("Google Drive")
redirect_uri = get_request_site_address(True) + "?cmd=frappe.integrations.doctype.google_drive.google_drive.google_callback"
if not google_drive.authorization_code or reauthorize:
- frappe.cache().hset("google_drive", "google_drive", google_drive.name)
return get_authentication_url(client_id=google_settings.client_id, redirect_uri=redirect_uri)
else:
try:
@@ -89,7 +88,7 @@ def authorize_access(g_drive, reauthorize=None):
frappe.db.commit()
frappe.local.response["type"] = "redirect"
- frappe.local.response["location"] = "/desk#Form/{0}/{1}".format(quote("Google Drive"), quote(google_drive.name))
+ frappe.local.response["location"] = "/desk#Form/{0}".format(quote("Google Drive"))
frappe.msgprint(_("Google Drive has been configured."))
except Exception as e:
@@ -105,8 +104,7 @@ def google_callback(code=None):
"""
Authorization code is sent to callback as per the API configuration
"""
- google_drive = frappe.cache().hget("google_drive", "google_drive")
- frappe.db.set_value("Google Drive", google_drive, "authorization_code", code)
+ frappe.db.set_value("Google Drive", None, "authorization_code", code)
frappe.db.commit()
authorize_access(google_drive)
@@ -146,7 +144,7 @@ def create_folder_in_google_drive(google_drive=None, account=None, g_drive=None)
}
try:
folder = google_drive.files().create(body=file_metadata, fields="id").execute()
- frappe.db.set_value("Google Drive", account.name, "backup_folder_id", folder.get("id"))
+ frappe.db.set_value("Google Drive", None, "backup_folder_id", folder.get("id"))
except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
@@ -165,46 +163,6 @@ def check_for_folder_in_google_drive(google_drive, account):
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
-@frappe.whitelist()
-def upload_doc_to_google_drive(doctype, docname, g_drive, format, letterhead):
- """
- Uploads Document to Folder specified in Google Drive Doc.
- """
- # Get Google Drive Object
- google_drive, account = get_google_drive_object(g_drive)
-
- # Check if folder exists in Google Drive
- check_for_folder_in_google_drive(google_drive, account)
- account.load_from_db()
-
- # Create PDF for doc and append datestring to name
- download_pdf(doctype=doctype, name=docname, format=format, no_letterhead=letterhead)
- filename = frappe.local.response.filename.replace(".pdf", "-{0}.pdf".format(now()))
- filecontent = frappe.local.response.filecontent
-
- file_to_upload = save_file(filename, filecontent, doctype, docname)
-
- if not file_to_upload:
- frappe.throw(_("Could not upload pdf to Google Drive"))
-
- fileurl = os.path.basename(file_to_upload.file_name or file_to_upload.file_url)
-
- # parents: Folder id under which the file is to be uploaded
- file_metadata = {
- "name": filename,
- "parents": [account.backup_folder_id]
- }
-
- media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/pdf", resumable=True)
-
- try:
- display_upload_status("orange", _("Uploading file to Google Drive."))
- google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
- except HttpError as e:
- frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
-
- display_upload_status("green", _("File Uploaded to Google Drive."))
-
@frappe.whitelist()
def upload_system_backup_to_google_drive(g_drive):
"""
@@ -230,14 +188,12 @@ def upload_system_backup_to_google_drive(g_drive):
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
return _("Google Drive Backup Successful.")
-def display_upload_status(indicator, message):
- frappe.publish_realtime("upload_google_drive", dict(indicator=indicator, message=message), user=frappe.session.user)
-
def daily_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
if g_drive:
diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js
index 891ea3ada5..ec78b30c8a 100644
--- a/frappe/public/js/frappe/form/print.js
+++ b/frappe/public/js/frappe/form/print.js
@@ -146,8 +146,6 @@ frappe.ui.form.PrintPreview = Class.extend({
frappe.set_route("print-format-builder");
}, __("New Custom Print Format"), __("Start"));
});
-
- this.google_drive_upload();
},
setup_keyboard_shortcuts() {
this.wrapper.find('.print-toolbar a.btn-default').each((i, el) => {
@@ -454,66 +452,6 @@ frappe.ui.form.PrintPreview = Class.extend({
frappe.throw(__("No Printer is Available."));
}
});
- },
- google_drive_upload: function() {
- var me = this;
-
- frappe.realtime.on("upload_google_drive", (data) => {
- frappe.show_alert({
- indicator: data.indicator,
- message: data.message
- });
- });
-
- this.wrapper.find(".btn-upload-drive").click(function () {
- let uploader = new frappe.ui.Dialog({
- title: __("Upload File to Google Drive"),
- fields: [
- {
- fieldtype: "Link",
- fieldname: "google_drive",
- options: "Google Drive",
- label: __("Google Drive"),
- reqd: 1,
- get_query: function() {
- return {
- "filters": {
- "enable": 1,
- "owner": frappe.session.user,
- }
- }
- }
- }
- ],
- primary_action_label: __("Submit"),
- primary_action: (d) => {
- uploader.hide();
- uploader.disable_primary_action();
- uploader.clear();
-
- frappe.show_alert({
- indicator: "red",
- message: __("Preparing file to upload.")
- });
-
- frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.upload_doc_to_google_drive",
- args: {
- doctype: me.frm.doc.doctype,
- docname: me.frm.doc.name,
- g_drive: d.google_drive,
- format: me.selected_format(),
- letterhead: me.with_letterhead() ? "0" : "1"
- },
- callback: function(r) {
- frappe.msgprint(r.message);
- uploader.enable_primary_action();
- }
- });
- }
- });
- uploader.show();
- });
}
});
diff --git a/frappe/public/js/frappe/form/templates/print_layout.html b/frappe/public/js/frappe/form/templates/print_layout.html
index 59f448f27f..9bdba0d99d 100644
--- a/frappe/public/js/frappe/form/templates/print_layout.html
+++ b/frappe/public/js/frappe/form/templates/print_layout.html
@@ -27,8 +27,6 @@
{%= __("Full Page") %}
{%= __("PDF") %}
-
- Drive
From 2b11be32c222bc91c126850499dbf55a5c1fe31b Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 13 Aug 2019 18:13:20 +0530
Subject: [PATCH 21/58] fix: codacy
---
.../doctype/google_drive/google_drive.js | 21 -------------------
.../doctype/google_drive/google_drive.py | 21 +++++++------------
2 files changed, 8 insertions(+), 34 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 879c6eed89..dd36bce026 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -24,27 +24,6 @@ frappe.ui.form.on('Google Drive', {
});
});
}
-
- if (!frm.doc.backup_folder_id && frm.doc.refresh_token) {
- let sync_button = frm.add_custom_button(__("Create Folder in Google Drive"), function () {
- frappe.show_alert({
- indicator: "green",
- message: __("Creating folder in Google Drive.")
- });
- frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
- args: {
- "g_drive": frm.doc.name
- },
- btn: sync_button
- }).then((r) => {
- refresh_field("backup_folder_id");
- frappe.msgprint(r.message);
- });
- });
- } else {
- frm.set_df_property("backup_folder_id", "read_only", 1);
- }
},
authorize_google_drive_access: function(frm) {
let reauthorize = 0;
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 83d69c6645..8e62462b52 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -15,11 +15,8 @@ from frappe.model.document import Document
from frappe.utils import get_request_site_address
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
-from frappe.utils.file_manager import save_file
-from frappe.utils.print_format import download_pdf
from frappe.utils import get_backups_path, get_files_path, get_bench_path
from frappe.utils.backups import new_backup
-from frappe.utils import now
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
SCOPES = "https://www.googleapis.com/auth/drive/v3"
@@ -109,12 +106,12 @@ def google_callback(code=None):
authorize_access(google_drive)
-def get_google_drive_object(g_drive):
+def get_google_drive_object():
"""
Returns an object of Google Drive.
"""
google_settings = frappe.get_doc("Google Settings")
- account = frappe.get_doc("Google Drive", g_drive)
+ account = frappe.get_doc("Google Drive")
if not account.backup_folder_id:
frappe.throw(_("Folder {0} not created in Google Drive.").format(account.backup_folder_name))
@@ -133,10 +130,8 @@ def get_google_drive_object(g_drive):
return google_drive, account
-@frappe.whitelist()
-def create_folder_in_google_drive(google_drive=None, account=None, g_drive=None):
- if g_drive:
- google_drive, account = get_google_drive_object(g_drive)
+def create_folder_in_google_drive(google_drive, account):
+ google_drive, account = get_google_drive_object()
file_metadata = {
"name": account.backup_folder_name,
@@ -164,12 +159,12 @@ def check_for_folder_in_google_drive(google_drive, account):
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
@frappe.whitelist()
-def upload_system_backup_to_google_drive(g_drive):
+def upload_system_backup_to_google_drive():
"""
Upload system backup to Google Drive
"""
# Get Google Drive Object
- google_drive, account = get_google_drive_object(g_drive)
+ google_drive, account = get_google_drive_object()
# Check if folder exists in Google Drive
check_for_folder_in_google_drive(google_drive, account)
@@ -197,12 +192,12 @@ def upload_system_backup_to_google_drive(g_drive):
def daily_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
if g_drive:
- upload_system_backup_to_google_drive(g_drive)
+ upload_system_backup_to_google_drive()
def weekly_backup():
g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Weekly"})
if g_drive:
- upload_system_backup_to_google_drive(g_drive)
+ upload_system_backup_to_google_drive()
def get_absolute_path(filename, backup=False):
file_path = os.path.join(get_files_path()[2:], filename)
From 6b944cadefac160d024b65ccbbefcb90f6716df3 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Thu, 15 Aug 2019 22:22:55 +0530
Subject: [PATCH 22/58] chore: code cleanup
---
.../doctype/google_drive/google_drive.js | 3 ---
.../doctype/google_drive/google_drive.json | 19 +++++-----------
.../doctype/google_drive/google_drive.py | 22 +++++--------------
3 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index dd36bce026..2185f9bb69 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -15,9 +15,6 @@ frappe.ui.form.on('Google Drive', {
});
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive",
- args: {
- "g_drive": frm.doc.name
- },
btn: sync_button
}).then((r) => {
frappe.msgprint(r.message);
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 8b778f9b90..2da4e6669d 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -8,12 +8,11 @@
"sb_00",
"user",
"backup_folder_name",
- "authorize_google_drive_access",
- "last_backup_on",
- "column_break_5",
"backup_folder_id",
- "enable_system_backup",
+ "authorize_google_drive_access",
+ "column_break_5",
"frequency",
+ "last_backup_on",
"refresh_token",
"authorization_code"
],
@@ -58,16 +57,10 @@
{
"fieldname": "backup_folder_id",
"fieldtype": "Data",
- "label": "Backup Folder ID"
+ "label": "Backup Folder ID",
+ "read_only": 1
},
{
- "default": "0",
- "fieldname": "enable_system_backup",
- "fieldtype": "Check",
- "label": "Enable System Backup"
- },
- {
- "depends_on": "enable_system_backup",
"fieldname": "frequency",
"fieldtype": "Select",
"label": "Frequency",
@@ -93,7 +86,7 @@
}
],
"issingle": 1,
- "modified": "2019-08-13 17:36:13.014410",
+ "modified": "2019-08-15 22:13:14.637569",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 8e62462b52..a5c6b53f3f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -23,12 +23,6 @@ SCOPES = "https://www.googleapis.com/auth/drive/v3"
class GoogleDrive(Document):
- def validate(self):
- if self.enable_system_backup:
- system_backup = frappe.db.exists("Google Drive", {"enable_system_backup": 1})
- if system_backup and not system_backup == self.name:
- frappe.throw(_("Google Drive System Backup can be enabled only for one account."))
-
def get_access_token(self):
google_settings = frappe.get_doc("Google Settings")
@@ -179,7 +173,7 @@ def upload_system_backup_to_google_drive():
"parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
+ media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/gzip", resumable=True)
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
@@ -190,19 +184,13 @@ def upload_system_backup_to_google_drive():
return _("Google Drive Backup Successful.")
def daily_backup():
- g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Daily"})
- if g_drive:
+ if frappe.db.get_single_value("Google Drive", "frequency") == "Daily":
upload_system_backup_to_google_drive()
def weekly_backup():
- g_drive = frappe.db.exists("Google Drive", {"enable": 1, "enable_system_backup": 1, "frequency": "Weekly"})
- if g_drive:
+ if frappe.db.get_single_value("Google Drive", "frequency") == "Weekly":
upload_system_backup_to_google_drive()
-def get_absolute_path(filename, backup=False):
- file_path = os.path.join(get_files_path()[2:], filename)
-
- if backup:
- file_path = os.path.join(get_backups_path()[2:], filename)
-
+def get_absolute_path(filename):
+ file_path = os.path.join(get_backups_path()[2:], filename)
return "{0}/sites/{1}".format(get_bench_path(), file_path)
\ No newline at end of file
From 344ce94c374aa6c6d30dfcfed35323d444a56f68 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 10:49:58 +0530
Subject: [PATCH 23/58] fix: better progress status
---
.../doctype/google_drive/google_drive.js | 12 +++++++++++-
.../doctype/google_drive/google_drive.json | 8 ++++----
.../doctype/google_drive/google_drive.py | 14 ++++++++------
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 2185f9bb69..e642866bdb 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -7,7 +7,17 @@ frappe.ui.form.on('Google Drive', {
frm.dashboard.set_headline(__("To use Google Drive, enable Google Settings."));
}
- if (frm.doc.enable_system_backup) {
+ frappe.realtime.on("upload_to_google_drive", (data) => {
+ if (data.progress) {
+ frm.dashboard.show_progress("Uploading to Google Drive", data.progress / data.total * 100,
+ __("{0}", [data.message]));
+ if (data.progress === data.total) {
+ frm.dashboard.hide_progress("Uploading to Google Drive");
+ }
+ }
+ });
+
+ if (frm.doc.refresh_token) {
let sync_button = frm.add_custom_button(__("Take Backup"), function () {
frappe.show_alert({
indicator: "green",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 2da4e6669d..34d968d50f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -1,5 +1,4 @@
{
- "autoname": "field:backup_folder_name",
"creation": "2019-08-13 17:24:05.470876",
"doctype": "DocType",
"engine": "InnoDB",
@@ -8,10 +7,10 @@
"sb_00",
"user",
"backup_folder_name",
- "backup_folder_id",
+ "frequency",
"authorize_google_drive_access",
"column_break_5",
- "frequency",
+ "backup_folder_id",
"last_backup_on",
"refresh_token",
"authorization_code"
@@ -42,6 +41,7 @@
"fieldtype": "Data",
"in_list_view": 1,
"label": "Backup Folder Name",
+ "reqd": 1,
"set_only_once": 1
},
{
@@ -86,7 +86,7 @@
}
],
"issingle": 1,
- "modified": "2019-08-15 22:13:14.637569",
+ "modified": "2019-08-16 10:47:24.799056",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index a5c6b53f3f..4d9975fd87 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -107,9 +107,6 @@ def get_google_drive_object():
google_settings = frappe.get_doc("Google Settings")
account = frappe.get_doc("Google Drive")
- if not account.backup_folder_id:
- frappe.throw(_("Folder {0} not created in Google Drive.").format(account.backup_folder_name))
-
credentials_dict = {
"token": account.get_access_token(),
"refresh_token": account.get_password(fieldname="refresh_token", raise_exception=False),
@@ -163,21 +160,23 @@ def upload_system_backup_to_google_drive():
# Check if folder exists in Google Drive
check_for_folder_in_google_drive(google_drive, account)
account.load_from_db()
-
+ progress(1, "Backing up Data.")
backup = new_backup(ignore_files=True)
fileurl = os.path.basename(backup.backup_path_db)
file_metadata = {
- "name": "Instance Backup-{0}".format(frappe.utils.now()),
+ "name": fileurl,
"parents": [account.backup_folder_id]
}
media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/gzip", resumable=True)
try:
+ progress(2, "Uploading backup to Google Drive.")
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
+ progress(3, "Uploading successful.")
except HttpError as e:
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
@@ -193,4 +192,7 @@ def weekly_backup():
def get_absolute_path(filename):
file_path = os.path.join(get_backups_path()[2:], filename)
- return "{0}/sites/{1}".format(get_bench_path(), file_path)
\ No newline at end of file
+ return "{0}/sites/{1}".format(get_bench_path(), file_path)
+
+def progress(progress, message):
+ frappe.publish_realtime("upload_to_google_drive", dict(progress=progress, total=3, message=message), user=frappe.session.user)
\ No newline at end of file
From ba00fb749b3b9cc7f08c8cdf69a54768f35098b8 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 10:53:32 +0530
Subject: [PATCH 24/58] chore: code cleanup
---
frappe/integrations/doctype/google_drive/google_drive.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 34d968d50f..04ea90e96b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -64,7 +64,7 @@
"fieldname": "frequency",
"fieldtype": "Select",
"label": "Frequency",
- "options": "Daily\nWeekly"
+ "options": "\nDaily\nWeekly"
},
{
"fieldname": "refresh_token",
@@ -86,7 +86,7 @@
}
],
"issingle": 1,
- "modified": "2019-08-16 10:47:24.799056",
+ "modified": "2019-08-16 10:53:10.165267",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From a708dd932622f8a30838f65efc0d9096dafcbd78 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 11:10:28 +0530
Subject: [PATCH 25/58] chore: remove unused imports
---
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 4d9975fd87..e3a2d2a13f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -15,7 +15,7 @@ from frappe.model.document import Document
from frappe.utils import get_request_site_address
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
-from frappe.utils import get_backups_path, get_files_path, get_bench_path
+from frappe.utils import get_backups_path, get_bench_path
from frappe.utils.backups import new_backup
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
From ac5fdff6011054d04638b4c424ad5e630ec20c91 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 11:44:06 +0530
Subject: [PATCH 26/58] patch: delete gsuite template and settings
---
frappe/patches/v12_0/delete_gsuite_if_exists.py | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 frappe/patches/v12_0/delete_gsuite_if_exists.py
diff --git a/frappe/patches/v12_0/delete_gsuite_if_exists.py b/frappe/patches/v12_0/delete_gsuite_if_exists.py
new file mode 100644
index 0000000000..7379ac9cdf
--- /dev/null
+++ b/frappe/patches/v12_0/delete_gsuite_if_exists.py
@@ -0,0 +1,8 @@
+import frappe
+
+def execute():
+ '''
+ Remove GSuite Template and GSuite Settings
+ '''
+ frappe.delete_doc_if_exists("DocType", "GSuite Settings")
+ frappe.delete_doc_if_exists("DocType", "GSuite Templates")
\ No newline at end of file
From c9fb2d5a5172f062db20053564976481bd1c0b4d Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 16:53:47 +0530
Subject: [PATCH 27/58] feat: upload files to google_drive
---
frappe/core/doctype/file/file.json | 952 ++++--------------
.../doctype/google_drive/google_drive.json | 35 +-
.../doctype/google_drive/google_drive.py | 68 +-
3 files changed, 281 insertions(+), 774 deletions(-)
diff --git a/frappe/core/doctype/file/file.json b/frappe/core/doctype/file/file.json
index 81606ad0f6..9bf7d03512 100644
--- a/frappe/core/doctype/file/file.json
+++ b/frappe/core/doctype/file/file.json
@@ -1,792 +1,226 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "",
- "beta": 0,
- "creation": "2012-12-12 11:19:22",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "editable_grid": 0,
+ "allow_import": 1,
+ "creation": "2012-12-12 11:19:22",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "file_name",
+ "is_private",
+ "preview",
+ "preview_html",
+ "section_break_5",
+ "is_home_folder",
+ "is_attachments_folder",
+ "file_size",
+ "column_break_5",
+ "file_url",
+ "thumbnail_url",
+ "folder",
+ "is_folder",
+ "section_break_8",
+ "attached_to_doctype",
+ "column_break_10",
+ "attached_to_name",
+ "attached_to_field",
+ "lft",
+ "rgt",
+ "old_parent",
+ "content_hash",
+ "uploaded_to_dropbox",
+ "uploaded_to_google_drive"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "file_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "File Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "file_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "file_name",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "label": "File Name",
+ "oldfieldname": "file_name",
+ "oldfieldtype": "Data",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.is_folder",
- "fieldname": "is_private",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Private",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "depends_on": "eval:!doc.is_folder",
+ "fieldname": "is_private",
+ "fieldtype": "Check",
+ "label": "Is Private"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "preview",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Preview",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "preview",
+ "fieldtype": "Section Break",
+ "label": "Preview"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "preview_html",
- "fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Preview HTML",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "preview_html",
+ "fieldtype": "HTML",
+ "label": "Preview HTML"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_5",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "is_home_folder",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Home Folder",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "is_home_folder",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Is Home Folder"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_attachments_folder",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Attachments Folder",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "is_attachments_folder",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Is Attachments Folder"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "file_size",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "File Size",
- "length": 20,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "file_size",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "File Size",
+ "length": 20,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.is_folder",
- "fieldname": "file_url",
- "fieldtype": "Code",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "File URL",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval:!doc.is_folder",
+ "fieldname": "file_url",
+ "fieldtype": "Code",
+ "label": "File URL",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "thumbnail_url",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Thumbnail URL",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "thumbnail_url",
+ "fieldtype": "Small Text",
+ "label": "Thumbnail URL",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "folder",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Folder",
- "length": 0,
- "no_copy": 0,
- "options": "File",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "folder",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Folder",
+ "options": "File",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_folder",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Folder",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "is_folder",
+ "fieldtype": "Check",
+ "label": "Is Folder",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.is_folder",
- "fieldname": "section_break_8",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval:!doc.is_folder",
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "attached_to_doctype",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Attached To DocType",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "attached_to_doctype",
+ "fieldtype": "Link",
+ "in_standard_filter": 1,
+ "label": "Attached To DocType",
+ "options": "DocType",
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "attached_to_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Attached To Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "attached_to_name",
+ "fieldtype": "Data",
+ "label": "Attached To Name",
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "attached_to_field",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Attached To Field",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "attached_to_field",
+ "fieldtype": "Data",
+ "label": "Attached To Field",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lft",
- "fieldtype": "Int",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "lft",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lft",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "label": "lft"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "rgt",
- "fieldtype": "Int",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "rgt",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "rgt",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "label": "rgt"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "old_parent",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "old_parent",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "old_parent",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "old_parent"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "content_hash",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Content Hash",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "content_hash",
+ "fieldtype": "Data",
+ "label": "Content Hash",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uploaded_to_dropbox",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Uploaded To Dropbox",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "uploaded_to_dropbox",
+ "fieldtype": "Check",
+ "label": "Uploaded To Dropbox",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "uploaded_to_google_drive",
+ "fieldtype": "Check",
+ "label": "Uploaded To Google Drive",
+ "read_only": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-file",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "menu_index": 0,
- "modified": "2018-10-01 05:22:50.819899",
- "modified_by": "Administrator",
- "module": "Core",
- "name": "File",
- "owner": "Administrator",
+ ],
+ "icon": "fa fa-file",
+ "idx": 1,
+ "modified": "2019-08-16 16:41:03.086023",
+ "modified_by": "Administrator",
+ "module": "Core",
+ "name": "File",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "import": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 1,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "All",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "All",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_order": "ASC",
- "title_field": "file_name",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "title_field": "file_name",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 04ea90e96b..f605831f32 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -5,7 +5,9 @@
"field_order": [
"enable",
"sb_00",
- "user",
+ "email",
+ "send_email_for_successful_backup",
+ "file_backup",
"backup_folder_name",
"frequency",
"authorize_google_drive_access",
@@ -28,14 +30,6 @@
"fieldtype": "Section Break",
"label": "Google Drive"
},
- {
- "fieldname": "user",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "User",
- "options": "User",
- "reqd": 1
- },
{
"fieldname": "backup_folder_name",
"fieldtype": "Data",
@@ -83,10 +77,31 @@
"fieldtype": "Datetime",
"label": "Last Backup On",
"read_only": 1
+ },
+ {
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Email",
+ "options": "Email",
+ "reqd": 1
+ },
+ {
+ "default": "0",
+ "description": "Note: By default emails for failed backups are sent.",
+ "fieldname": "send_email_for_successful_backup",
+ "fieldtype": "Check",
+ "label": "Send Email for Successful backup"
+ },
+ {
+ "default": "0",
+ "fieldname": "file_backup",
+ "fieldtype": "Check",
+ "label": "File Backup"
}
],
"issingle": 1,
- "modified": "2019-08-16 10:53:10.165267",
+ "modified": "2019-08-16 16:23:36.686391",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index e3a2d2a13f..05f1a8c303 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -15,7 +15,7 @@ from frappe.model.document import Document
from frappe.utils import get_request_site_address
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
-from frappe.utils import get_backups_path, get_bench_path
+from frappe.utils import get_backups_path, get_files_path, get_bench_path
from frappe.utils.backups import new_backup
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
@@ -170,18 +170,48 @@ def upload_system_backup_to_google_drive():
"parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(fileurl), mimetype="application/gzip", resumable=True)
+ media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
try:
progress(2, "Uploading backup to Google Drive.")
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ if account.file_backup:
+ progress(2, "Uploading files to Google Drive.")
+ upload_files(google_drive, account)
+
frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
progress(3, "Uploading successful.")
+ send_email(success=True)
except HttpError as e:
+ send_email(success=False, error=e)
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
return _("Google Drive Backup Successful.")
+def upload_files(google_drive, account):
+ for f in frappe.get_list("File", filters={"is_folder": 0, "uploaded_to_google_drive": 0},
+ fields=["name", "file_url", "file_name", "is_private"]):
+
+ upload_file_to_google_drive(google_drive, account, f.file_name or f.file_url, f.is_private)
+ frappe.db.set_value("File", f.name, "uploaded_to_google_drive", 1)
+
+def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
+ """
+ Uploads File to Folder specified in Google Drive Doc.
+ """
+ # parents: Folder id under which the file is to be uploaded
+ file_metadata = {
+ "name": filename,
+ "parents": [account.backup_folder_id]
+ }
+
+ media = MediaFileUpload(get_absolute_path(fileurl, is_private), mimetype="application/pdf", resumable=True)
+
+ try:
+ google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ except HttpError as e:
+ frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
+
def daily_backup():
if frappe.db.get_single_value("Google Drive", "frequency") == "Daily":
upload_system_backup_to_google_drive()
@@ -190,9 +220,37 @@ def weekly_backup():
if frappe.db.get_single_value("Google Drive", "frequency") == "Weekly":
upload_system_backup_to_google_drive()
-def get_absolute_path(filename):
- file_path = os.path.join(get_backups_path()[2:], filename)
+def get_absolute_path(filename, is_private=False):
+ file_path = os.path.join(get_files_path()[2:], filename)
+
+ if is_private:
+ file_path = os.path.join(get_backups_path()[2:], filename)
return "{0}/sites/{1}".format(get_bench_path(), file_path)
def progress(progress, message):
- frappe.publish_realtime("upload_to_google_drive", dict(progress=progress, total=3, message=message), user=frappe.session.user)
\ No newline at end of file
+ frappe.publish_realtime("upload_to_google_drive", dict(progress=progress, total=3, message=message), user=frappe.session.user)
+
+def send_email(success, error=None):
+ if success:
+ if not frappe.db.get_single_value("Google Drive", None, "send_email_for_successful_backup"):
+ return
+
+ subject = "Backup Upload Successful"
+ message = """Backup Uploaded Successfully
Hi there, this is just to inform you
+ that your backup was successfully uploaded to Google Drive.
+ """
+ else:
+ subject = "[Warning] Backup Upload Failed"
+ message = """Backup Upload Failed
Oops, your automated backup to Google Drive
+ failed.
+ Error message:
+
%s
+
+ Please contact your system manager for more information.
+ """.format(error)
+
+ frappe.sendmail(
+ recipients=frappe.db.get_single_value("Google Drive", "email"),
+ subject=subject,
+ message=message
+ )
\ No newline at end of file
From f7b729f35ff03c991be50319302efe4b6bd3d7c2 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 16:57:23 +0530
Subject: [PATCH 28/58] fix: show folder_name
---
frappe/integrations/doctype/google_drive/google_drive.json | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index f605831f32..ff9f5578ad 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -35,8 +35,7 @@
"fieldtype": "Data",
"in_list_view": 1,
"label": "Backup Folder Name",
- "reqd": 1,
- "set_only_once": 1
+ "reqd": 1
},
{
"depends_on": "eval:!doc.__islocal",
@@ -101,7 +100,7 @@
}
],
"issingle": 1,
- "modified": "2019-08-16 16:23:36.686391",
+ "modified": "2019-08-16 16:57:11.475982",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
From 6d2a072b9ac61dd13033ddf6cef5c4593d06bccb Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 17:03:03 +0530
Subject: [PATCH 29/58] fix: scopes
---
frappe/integrations/doctype/google_drive/google_drive.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 05f1a8c303..d5b92b094a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -19,7 +19,7 @@ from frappe.utils import get_backups_path, get_files_path, get_bench_path
from frappe.utils.backups import new_backup
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
-SCOPES = "https://www.googleapis.com/auth/drive/v3"
+SCOPES = "https://www.googleapis.com/auth/drive"
class GoogleDrive(Document):
@@ -113,7 +113,7 @@ def get_google_drive_object():
"token_uri": get_auth_url(),
"client_id": google_settings.client_id,
"client_secret": google_settings.get_password(fieldname="client_secret", raise_exception=False),
- "scopes": SCOPES
+ "scopes": "https://www.googleapis.com/auth/drive/v3"
}
credentials = google.oauth2.credentials.Credentials(**credentials_dict)
From a709d9bcb120ad4c0ca4fb1b9ad6695b0a67d6bd Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 17:07:45 +0530
Subject: [PATCH 30/58] fix: redirect
---
frappe/integrations/doctype/google_drive/google_drive.js | 1 -
frappe/integrations/doctype/google_drive/google_drive.py | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index e642866bdb..6f9a83c715 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -41,7 +41,6 @@ frappe.ui.form.on('Google Drive', {
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.authorize_access",
args: {
- "g_drive": frm.doc.name,
"reauthorize": reauthorize
},
callback: function(r) {
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index d5b92b094a..551ef0f53a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -50,7 +50,7 @@ class GoogleDrive(Document):
return r.get("access_token")
@frappe.whitelist()
-def authorize_access(g_drive, reauthorize=None):
+def authorize_access(reauthorize=None):
"""
If no Authorization code get it from Google and then request for Refresh Token.
Google Contact Name is set to flags to set_value after Authorization Code is obtained.
@@ -98,7 +98,7 @@ def google_callback(code=None):
frappe.db.set_value("Google Drive", None, "authorization_code", code)
frappe.db.commit()
- authorize_access(google_drive)
+ authorize_access()
def get_google_drive_object():
"""
From cee21f1a70beb3d4bf20b43520f7eefbbfa6928b Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 17:14:21 +0530
Subject: [PATCH 31/58] fix: file name
---
frappe/integrations/doctype/google_drive/google_drive.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 551ef0f53a..f99d34434b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -192,7 +192,7 @@ def upload_files(google_drive, account):
for f in frappe.get_list("File", filters={"is_folder": 0, "uploaded_to_google_drive": 0},
fields=["name", "file_url", "file_name", "is_private"]):
- upload_file_to_google_drive(google_drive, account, f.file_name or f.file_url, f.is_private)
+ upload_file_to_google_drive(google_drive, account, f.file_url or f.file_name, f.is_private)
frappe.db.set_value("File", f.name, "uploaded_to_google_drive", 1)
def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
@@ -200,12 +200,14 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
Uploads File to Folder specified in Google Drive Doc.
"""
# parents: Folder id under which the file is to be uploaded
+ filename = os.path.basename(fileurl)
+
file_metadata = {
"name": filename,
"parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(fileurl, is_private), mimetype="application/pdf", resumable=True)
+ media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
From e2e76055d8b7539c26b95d7c6f27a9e9e4eb67a9 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 20:25:01 +0530
Subject: [PATCH 32/58] fix: handle ioerror
---
.../integrations/doctype/google_drive/google_drive.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index f99d34434b..1099244256 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -170,7 +170,10 @@ def upload_system_backup_to_google_drive():
"parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
+ try:
+ media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
+ except IOError as e:
+ frappe.throw(_("Google Drive - Could not locate locate - {0}").format(os.path.basename(e)))
try:
progress(2, "Uploading backup to Google Drive.")
@@ -207,7 +210,10 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
"parents": [account.backup_folder_id]
}
- media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
+ try:
+ media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
+ except IOError as e:
+ frappe.msgprint(_("Google Drive - Could not locate file - {0}").format(os.path.basename(e)))
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
From babefc73802f86989a2d8d3ddf102ce3e7f187ff Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 20:27:06 +0530
Subject: [PATCH 33/58] chore: code cleanup
---
frappe/integrations/doctype/google_drive/google_drive.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 1099244256..98959af25f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -173,7 +173,7 @@ def upload_system_backup_to_google_drive():
try:
media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
except IOError as e:
- frappe.throw(_("Google Drive - Could not locate locate - {0}").format(os.path.basename(e)))
+ frappe.throw(_("Google Drive - Could not locate locate - {0}").format(e))
try:
progress(2, "Uploading backup to Google Drive.")
@@ -213,7 +213,7 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
try:
media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
except IOError as e:
- frappe.msgprint(_("Google Drive - Could not locate file - {0}").format(os.path.basename(e)))
+ frappe.msgprint(_("Google Drive - Could not locate file - {0}").format(e))
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
From b4bb801f5940c086c3fcd7557308e31e559e0be2 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 20:29:55 +0530
Subject: [PATCH 34/58] fix: return if file not found
---
frappe/integrations/doctype/google_drive/google_drive.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 98959af25f..b5e808797b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -214,6 +214,7 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
except IOError as e:
frappe.msgprint(_("Google Drive - Could not locate file - {0}").format(e))
+ return
try:
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
From 1480cb328586aad4369a2eaa303ffbbe0ac40fef Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Fri, 16 Aug 2019 20:36:16 +0530
Subject: [PATCH 35/58] fix: show dashboard if gdrive is disabled
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 +-
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 6f9a83c715..1b1eeec631 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -3,7 +3,7 @@
frappe.ui.form.on('Google Drive', {
refresh: function(frm) {
- if (frm.is_new()) {
+ if (!frm.doc.enable) {
frm.dashboard.set_headline(__("To use Google Drive, enable Google Settings."));
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index b5e808797b..5627f22ca7 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -213,7 +213,7 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
try:
media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
except IOError as e:
- frappe.msgprint(_("Google Drive - Could not locate file - {0}").format(e))
+ frappe.msgprint(_("Google Drive - File not found - {0}").format(e))
return
try:
From c7a40c7b392db2cb09dab3a737abd046382de889 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 11:59:15 +0530
Subject: [PATCH 36/58] chore: codacy
---
.../doctype/google_drive/google_drive.json | 16 ++++++++--------
.../doctype/google_drive/google_drive.py | 2 +-
.../doctype/google_drive/test_google_drive.py | 10 ----------
3 files changed, 9 insertions(+), 19 deletions(-)
delete mode 100644 frappe/integrations/doctype/google_drive/test_google_drive.py
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index ff9f5578ad..5d5d23db81 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -4,7 +4,7 @@
"engine": "InnoDB",
"field_order": [
"enable",
- "sb_00",
+ "google_drive_section",
"email",
"send_email_for_successful_backup",
"file_backup",
@@ -24,12 +24,6 @@
"fieldtype": "Check",
"label": "Enable"
},
- {
- "depends_on": "enable",
- "fieldname": "sb_00",
- "fieldtype": "Section Break",
- "label": "Google Drive"
- },
{
"fieldname": "backup_folder_name",
"fieldtype": "Data",
@@ -97,10 +91,16 @@
"fieldname": "file_backup",
"fieldtype": "Check",
"label": "File Backup"
+ },
+ {
+ "depends_on": "enable",
+ "fieldname": "google_drive_section",
+ "fieldtype": "Section Break",
+ "label": "Google Drive"
}
],
"issingle": 1,
- "modified": "2019-08-16 16:57:11.475982",
+ "modified": "2019-08-19 11:56:31.447432",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 5627f22ca7..7eae941946 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -253,7 +253,7 @@ def send_email(success, error=None):
message = """Backup Upload Failed
Oops, your automated backup to Google Drive
failed.
Error message:
-
%s
+ {0}
Please contact your system manager for more information.
""".format(error)
diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py
deleted file mode 100644
index f06e13572c..0000000000
--- a/frappe/integrations/doctype/google_drive/test_google_drive.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-# import frappe
-import unittest
-
-class TestGoogleDrive(unittest.TestCase):
- pass
From f3bc7b0e30673406ec727e6c51ccf76bbe1178ba Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 17:52:35 +0530
Subject: [PATCH 37/58] fix: single value
---
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 7eae941946..0297308bbc 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -241,7 +241,7 @@ def progress(progress, message):
def send_email(success, error=None):
if success:
- if not frappe.db.get_single_value("Google Drive", None, "send_email_for_successful_backup"):
+ if not frappe.db.get_single_value("Google Drive", "send_email_for_successful_backup"):
return
subject = "Backup Upload Successful"
From f56e0fa5abdb36201db31383a5b15b11941db588 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 18:14:59 +0530
Subject: [PATCH 38/58] fix: folder creation
---
.../doctype/google_drive/google_drive.js | 18 +++++++++++++++++-
.../doctype/google_drive/google_drive.py | 1 +
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 1b1eeec631..59f6d40ab6 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -17,7 +17,23 @@ frappe.ui.form.on('Google Drive', {
}
});
- if (frm.doc.refresh_token) {
+ if (!frm.doc.backup_folder_id) {
+ let create_button = frm.add_custom_button(__("Create Folder"), function () {
+ frappe.show_alert({
+ indicator: "green",
+ message: __("Creating folder in Google Drive.")
+ });
+ frappe.call({
+ method: "frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive",
+ btn: create_button
+ }).then((r) => {
+ refresh_field(frm.doc.backup_folder_id);
+ frappe.msgprint(r.message);
+ });
+ });
+ }
+
+ if (frm.doc.refresh_token && frm.doc.backup_folder_id) {
let sync_button = frm.add_custom_button(__("Take Backup"), function () {
frappe.show_alert({
indicator: "green",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 0297308bbc..b4121c5b22 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -121,6 +121,7 @@ def get_google_drive_object():
return google_drive, account
+@frappe.whitelist()
def create_folder_in_google_drive(google_drive, account):
google_drive, account = get_google_drive_object()
From 1b7880035186bc96209e9f530179697cf0c7b526 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 18:34:32 +0530
Subject: [PATCH 39/58] fix: create folder
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 +-
frappe/integrations/doctype/google_drive/google_drive.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 59f6d40ab6..93ed29cad8 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -24,7 +24,7 @@ frappe.ui.form.on('Google Drive', {
message: __("Creating folder in Google Drive.")
});
frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive",
+ method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
btn: create_button
}).then((r) => {
refresh_field(frm.doc.backup_folder_id);
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index b4121c5b22..e322791cbe 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -122,7 +122,7 @@ def get_google_drive_object():
return google_drive, account
@frappe.whitelist()
-def create_folder_in_google_drive(google_drive, account):
+def create_folder_in_google_drive():
google_drive, account = get_google_drive_object()
file_metadata = {
@@ -142,7 +142,7 @@ def check_for_folder_in_google_drive(google_drive, account):
Create a folder on Drive, returns the newely created folders ID
"""
if not account.backup_folder_id:
- create_folder_in_google_drive(google_drive, account)
+ create_folder_in_google_drive()
return
try:
From 7a5b0a757520116cc4ab5c28aeef8c5279c60fe5 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 18:55:45 +0530
Subject: [PATCH 40/58] fix: folder creation
---
frappe/integrations/doctype/google_drive/google_drive.js | 5 ++---
frappe/integrations/doctype/google_drive/google_drive.py | 2 --
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 93ed29cad8..cde72f5759 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -26,9 +26,8 @@ frappe.ui.form.on('Google Drive', {
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
btn: create_button
- }).then((r) => {
- refresh_field(frm.doc.backup_folder_id);
- frappe.msgprint(r.message);
+ }).then(() => {
+ frm.refresh();
});
});
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index e322791cbe..d3e5e802fe 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -135,8 +135,6 @@ def create_folder_in_google_drive():
except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
- return "Folder created successfully in Google Drive."
-
def check_for_folder_in_google_drive(google_drive, account):
"""
Create a folder on Drive, returns the newely created folders ID
From 612a7336e83644500ea060fb9cd3d9a7a204b780 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Mon, 19 Aug 2019 19:29:43 +0530
Subject: [PATCH 41/58] fix: folder creation
---
frappe/integrations/doctype/google_drive/google_drive.js | 5 +++--
frappe/integrations/doctype/google_drive/google_drive.py | 2 ++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index cde72f5759..a9335e9034 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -26,8 +26,9 @@ frappe.ui.form.on('Google Drive', {
frappe.call({
method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
btn: create_button
- }).then(() => {
- frm.refresh();
+ }).then((r) => {
+ frappe.msgprint(r.message);
+ frm.refresh_field("backup_folder_id");
});
});
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index d3e5e802fe..609b77d32a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -135,6 +135,8 @@ def create_folder_in_google_drive():
except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
+ return _("Folder Created in Google Drive.")
+
def check_for_folder_in_google_drive(google_drive, account):
"""
Create a folder on Drive, returns the newely created folders ID
From 3f6ced434fa05db6b766ec2f0998515b6abbb1ce Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 20 Aug 2019 19:49:39 +0530
Subject: [PATCH 42/58] fix: private files path
---
.../integrations/doctype/google_drive/google_drive.js | 10 +++++++++-
.../doctype/google_drive/google_drive.json | 11 ++++++-----
.../integrations/doctype/google_drive/google_drive.py | 8 ++++----
.../doctype/google_drive/test_google_drive.py | 10 ++++++++++
4 files changed, 29 insertions(+), 10 deletions(-)
create mode 100644 frappe/integrations/doctype/google_drive/test_google_drive.py
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index a9335e9034..b9294bed81 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -17,7 +17,7 @@ frappe.ui.form.on('Google Drive', {
}
});
- if (!frm.doc.backup_folder_id) {
+ if (frm.doc.refresh_token && !frm.doc.backup_folder_id) {
let create_button = frm.add_custom_button(__("Create Folder"), function () {
frappe.show_alert({
indicator: "green",
@@ -47,6 +47,14 @@ frappe.ui.form.on('Google Drive', {
});
});
}
+
+ if (frm.doc.enable && frm.doc.backup_folder_name) {
+ frm.dashboard.set_headline(__("Enable Google Drive Access."));
+ }
+
+ if (frm.doc.refresh_token && frm.doc.authorization_code && frm.doc.enable) {
+ frm.page.set_indicator("Authorized", "green");
+ }
},
authorize_google_drive_access: function(frm) {
let reauthorize = 0;
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 5d5d23db81..819791ed0a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -6,10 +6,10 @@
"enable",
"google_drive_section",
"email",
- "send_email_for_successful_backup",
- "file_backup",
"backup_folder_name",
"frequency",
+ "send_email_for_successful_backup",
+ "file_backup",
"authorize_google_drive_access",
"column_break_5",
"backup_folder_id",
@@ -51,7 +51,8 @@
"fieldname": "frequency",
"fieldtype": "Select",
"label": "Frequency",
- "options": "\nDaily\nWeekly"
+ "options": "\nDaily\nWeekly",
+ "reqd": 1
},
{
"fieldname": "refresh_token",
@@ -100,8 +101,8 @@
}
],
"issingle": 1,
- "modified": "2019-08-19 11:56:31.447432",
- "modified_by": "Administrator",
+ "modified": "2019-08-20 14:25:24.504705",
+ "modified_by": "qwe@qwe.com",
"module": "Integrations",
"name": "Google Drive",
"owner": "Administrator",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 609b77d32a..1e40d30b94 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -172,7 +172,7 @@ def upload_system_backup_to_google_drive():
}
try:
- media = MediaFileUpload(get_absolute_path(fileurl, True), mimetype="application/gzip", resumable=True)
+ media = MediaFileUpload(get_absolute_path(filename=fileurl, backup=True), mimetype="application/gzip", resumable=True)
except IOError as e:
frappe.throw(_("Google Drive - Could not locate locate - {0}").format(e))
@@ -212,7 +212,7 @@ def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
}
try:
- media = MediaFileUpload(get_absolute_path(filename, is_private), mimetype="application/pdf", resumable=True)
+ media = MediaFileUpload(get_absolute_path(filename=filename, is_private=is_private), mimetype="application/pdf", resumable=True)
except IOError as e:
frappe.msgprint(_("Google Drive - File not found - {0}").format(e))
return
@@ -230,8 +230,8 @@ def weekly_backup():
if frappe.db.get_single_value("Google Drive", "frequency") == "Weekly":
upload_system_backup_to_google_drive()
-def get_absolute_path(filename, is_private=False):
- file_path = os.path.join(get_files_path()[2:], filename)
+def get_absolute_path(filename, is_private=False, backup=False):
+ file_path = os.path.join(get_files_path(is_private=is_private)[2:], filename)
if is_private:
file_path = os.path.join(get_backups_path()[2:], filename)
diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py
new file mode 100644
index 0000000000..f06e13572c
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/test_google_drive.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestGoogleDrive(unittest.TestCase):
+ pass
From 34d729a468d913fd1934b847046898f7fd72293f Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 20 Aug 2019 19:54:03 +0530
Subject: [PATCH 43/58] fix: backup path
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 +-
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index b9294bed81..54ebe14c87 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -48,7 +48,7 @@ frappe.ui.form.on('Google Drive', {
});
}
- if (frm.doc.enable && frm.doc.backup_folder_name) {
+ if (frm.doc.enable && frm.doc.backup_folder_name && !frm.doc.backup_folder_id) {
frm.dashboard.set_headline(__("Enable Google Drive Access."));
}
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 1e40d30b94..0d1462fabb 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -233,7 +233,7 @@ def weekly_backup():
def get_absolute_path(filename, is_private=False, backup=False):
file_path = os.path.join(get_files_path(is_private=is_private)[2:], filename)
- if is_private:
+ if backup:
file_path = os.path.join(get_backups_path()[2:], filename)
return "{0}/sites/{1}".format(get_bench_path(), file_path)
From cab10700f432ae31dcd57e3a288de154edccda9b Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 20 Aug 2019 20:20:59 +0530
Subject: [PATCH 44/58] fix: show headline when no refresh token
---
frappe/integrations/doctype/google_drive/google_drive.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 54ebe14c87..fc828ef0c6 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -48,11 +48,11 @@ frappe.ui.form.on('Google Drive', {
});
}
- if (frm.doc.enable && frm.doc.backup_folder_name && !frm.doc.backup_folder_id) {
+ if (frm.doc.enable && frm.doc.backup_folder_name && !frm.doc.refresh_token) {
frm.dashboard.set_headline(__("Enable Google Drive Access."));
}
- if (frm.doc.refresh_token && frm.doc.authorization_code && frm.doc.enable) {
+ if (frm.doc.enable && frm.doc.refresh_token && frm.doc.authorization_code) {
frm.page.set_indicator("Authorized", "green");
}
},
From 6a9d995a2b39997abe206bc39be0a1b2901a26cd Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Tue, 20 Aug 2019 20:25:54 +0530
Subject: [PATCH 45/58] chore: remove test files
---
.../doctype/google_calendar/test_google_calendar.py | 10 ----------
.../doctype/google_drive/test_google_drive.py | 10 ----------
2 files changed, 20 deletions(-)
delete mode 100644 frappe/integrations/doctype/google_calendar/test_google_calendar.py
delete mode 100644 frappe/integrations/doctype/google_drive/test_google_drive.py
diff --git a/frappe/integrations/doctype/google_calendar/test_google_calendar.py b/frappe/integrations/doctype/google_calendar/test_google_calendar.py
deleted file mode 100644
index 0fad81d7f5..0000000000
--- a/frappe/integrations/doctype/google_calendar/test_google_calendar.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-# import frappe
-import unittest
-
-class TestGoogleCalendar(unittest.TestCase):
- pass
diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py
deleted file mode 100644
index f06e13572c..0000000000
--- a/frappe/integrations/doctype/google_drive/test_google_drive.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-# import frappe
-import unittest
-
-class TestGoogleDrive(unittest.TestCase):
- pass
From 917b4106323f2f54c13b89f0009f324b2d737c61 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 11:06:00 +0530
Subject: [PATCH 46/58] fix: refresh form after creating folder
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index fc828ef0c6..e72a603d4a 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -28,7 +28,7 @@ frappe.ui.form.on('Google Drive', {
btn: create_button
}).then((r) => {
frappe.msgprint(r.message);
- frm.refresh_field("backup_folder_id");
+ frm.refresh();
});
});
}
From bb1c1c150c1d64f6252d3e759660e4c5e7068685 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 16:44:43 +0530
Subject: [PATCH 47/58] fix: reset auth refresh token when email change
---
frappe/integrations/doctype/google_drive/google_drive.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 0d1462fabb..a61e076b19 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -23,6 +23,12 @@ SCOPES = "https://www.googleapis.com/auth/drive"
class GoogleDrive(Document):
+ def validate(self):
+ if not self.email == frappe.db.get_single_value("Google Drive", "email"):
+ self.authorization_code = ""
+ self.refresh_token = ""
+ self.backup_folder_id = ""
+
def get_access_token(self):
google_settings = frappe.get_doc("Google Settings")
From 951cb5459b8449e13ab873aa380a3d51d83c9a39 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 16:54:17 +0530
Subject: [PATCH 48/58] fix: dashboard headline
---
frappe/integrations/doctype/google_drive/google_drive.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index e72a603d4a..2e4d83a880 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -49,7 +49,7 @@ frappe.ui.form.on('Google Drive', {
}
if (frm.doc.enable && frm.doc.backup_folder_name && !frm.doc.refresh_token) {
- frm.dashboard.set_headline(__("Enable Google Drive Access."));
+ frm.dashboard.set_headline(__("Click on Authorize Google Drive Access to authorize Google Drive Access."));
}
if (frm.doc.enable && frm.doc.refresh_token && frm.doc.authorization_code) {
From 7aa975a98f5f4428d71760eed1fe7123cf332ca5 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 17:23:09 +0530
Subject: [PATCH 49/58] fix: upload gz files
---
frappe/config/integrations.py | 5 ++
.../doctype/google_drive/google_drive.json | 11 +--
.../doctype/google_drive/google_drive.py | 87 +++++--------------
.../doctype/google_drive/test_google_drive.py | 10 +++
4 files changed, 40 insertions(+), 73 deletions(-)
create mode 100644 frappe/integrations/doctype/google_drive/test_google_drive.py
diff --git a/frappe/config/integrations.py b/frappe/config/integrations.py
index bfed056546..f41adc9ea4 100644
--- a/frappe/config/integrations.py
+++ b/frappe/config/integrations.py
@@ -42,6 +42,11 @@ def get_data():
"name": "S3 Backup Settings",
"description": _("S3 Backup Settings"),
},
+ {
+ "type": "doctype",
+ "name": "Google Drive",
+ "description": _("Google Drive Backup."),
+ }
]
},
{
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index 819791ed0a..cc129ff77b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -5,7 +5,6 @@
"field_order": [
"enable",
"google_drive_section",
- "email",
"backup_folder_name",
"frequency",
"send_email_for_successful_backup",
@@ -72,14 +71,6 @@
"label": "Last Backup On",
"read_only": 1
},
- {
- "fieldname": "email",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Email",
- "options": "Email",
- "reqd": 1
- },
{
"default": "0",
"description": "Note: By default emails for failed backups are sent.",
@@ -101,7 +92,7 @@
}
],
"issingle": 1,
- "modified": "2019-08-20 14:25:24.504705",
+ "modified": "2019-08-21 17:07:21.773252",
"modified_by": "qwe@qwe.com",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index a61e076b19..759facd518 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -23,12 +23,6 @@ SCOPES = "https://www.googleapis.com/auth/drive"
class GoogleDrive(Document):
- def validate(self):
- if not self.email == frappe.db.get_single_value("Google Drive", "email"):
- self.authorization_code = ""
- self.refresh_token = ""
- self.backup_folder_id = ""
-
def get_access_token(self):
google_settings = frappe.get_doc("Google Settings")
@@ -168,66 +162,36 @@ def upload_system_backup_to_google_drive():
check_for_folder_in_google_drive(google_drive, account)
account.load_from_db()
progress(1, "Backing up Data.")
- backup = new_backup(ignore_files=True)
+ backup = new_backup()
- fileurl = os.path.basename(backup.backup_path_db)
+ fileurl_backup = os.path.basename(backup.backup_path_db)
+ fileurl_public_files = os.path.basename(backup.backup_path_files)
+ fileurl_private_files = os.path.basename(backup.backup_path_private_files)
- file_metadata = {
- "name": fileurl,
- "parents": [account.backup_folder_id]
- }
- try:
- media = MediaFileUpload(get_absolute_path(filename=fileurl, backup=True), mimetype="application/gzip", resumable=True)
- except IOError as e:
- frappe.throw(_("Google Drive - Could not locate locate - {0}").format(e))
+ for file_url in [fileurl_backup, fileurl_public_files, fileurl_private_files]:
+ file_metadata = {
+ "name": fileurl,
+ "parents": [account.backup_folder_id]
+ }
- try:
- progress(2, "Uploading backup to Google Drive.")
- google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
- if account.file_backup:
- progress(2, "Uploading files to Google Drive.")
- upload_files(google_drive, account)
+ try:
+ media = MediaFileUpload(get_absolute_path(filename=fileurl), mimetype="application/gzip", resumable=True)
+ except IOError as e:
+ frappe.throw(_("Google Drive - Could not locate locate - {0}").format(e))
- frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
- progress(3, "Uploading successful.")
- send_email(success=True)
- except HttpError as e:
- send_email(success=False, error=e)
- frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
+ try:
+ progress(2, "Uploading backup to Google Drive.")
+ google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
+ except HttpError as e:
+ send_email(success=False, error=e)
+ frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
+ progress(3, "Uploading successful.")
+ frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
+ send_email(success=True)
return _("Google Drive Backup Successful.")
-def upload_files(google_drive, account):
- for f in frappe.get_list("File", filters={"is_folder": 0, "uploaded_to_google_drive": 0},
- fields=["name", "file_url", "file_name", "is_private"]):
-
- upload_file_to_google_drive(google_drive, account, f.file_url or f.file_name, f.is_private)
- frappe.db.set_value("File", f.name, "uploaded_to_google_drive", 1)
-
-def upload_file_to_google_drive(google_drive, account, fileurl, is_private):
- """
- Uploads File to Folder specified in Google Drive Doc.
- """
- # parents: Folder id under which the file is to be uploaded
- filename = os.path.basename(fileurl)
-
- file_metadata = {
- "name": filename,
- "parents": [account.backup_folder_id]
- }
-
- try:
- media = MediaFileUpload(get_absolute_path(filename=filename, is_private=is_private), mimetype="application/pdf", resumable=True)
- except IOError as e:
- frappe.msgprint(_("Google Drive - File not found - {0}").format(e))
- return
-
- try:
- google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
- except HttpError as e:
- frappe.msgprint(_("Google Drive - Could not upload file - Error Code {0}").format(e))
-
def daily_backup():
if frappe.db.get_single_value("Google Drive", "frequency") == "Daily":
upload_system_backup_to_google_drive()
@@ -236,11 +200,8 @@ def weekly_backup():
if frappe.db.get_single_value("Google Drive", "frequency") == "Weekly":
upload_system_backup_to_google_drive()
-def get_absolute_path(filename, is_private=False, backup=False):
- file_path = os.path.join(get_files_path(is_private=is_private)[2:], filename)
-
- if backup:
- file_path = os.path.join(get_backups_path()[2:], filename)
+def get_absolute_path(filename):
+ file_path = os.path.join(get_backups_path()[2:], filename)
return "{0}/sites/{1}".format(get_bench_path(), file_path)
def progress(progress, message):
diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py
new file mode 100644
index 0000000000..f06e13572c
--- /dev/null
+++ b/frappe/integrations/doctype/google_drive/test_google_drive.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestGoogleDrive(unittest.TestCase):
+ pass
From 9b70c01e872930a3abfd5c3dbc3accef6bad4501 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 17:37:48 +0530
Subject: [PATCH 50/58] fix: queue google drive backup
---
.../integrations/doctype/google_drive/google_drive.js | 4 ++--
.../doctype/google_drive/google_drive.json | 10 +++++++++-
.../integrations/doctype/google_drive/google_drive.py | 7 ++++++-
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 2e4d83a880..034b18d2a8 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -27,8 +27,8 @@ frappe.ui.form.on('Google Drive', {
method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
btn: create_button
}).then((r) => {
- frappe.msgprint(r.message);
frm.refresh();
+ frappe.msgprint(r.message);
});
});
}
@@ -40,7 +40,7 @@ frappe.ui.form.on('Google Drive', {
message: __("Backing up to Google Drive.")
});
frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive",
+ method: "frappe.integrations.doctype.google_drive.google_drive.take_backup",
btn: sync_button
}).then((r) => {
frappe.msgprint(r.message);
diff --git a/frappe/integrations/doctype/google_drive/google_drive.json b/frappe/integrations/doctype/google_drive/google_drive.json
index cc129ff77b..7ea26dadc8 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.json
+++ b/frappe/integrations/doctype/google_drive/google_drive.json
@@ -7,6 +7,7 @@
"google_drive_section",
"backup_folder_name",
"frequency",
+ "email",
"send_email_for_successful_backup",
"file_backup",
"authorize_google_drive_access",
@@ -89,10 +90,17 @@
"fieldname": "google_drive_section",
"fieldtype": "Section Break",
"label": "Google Drive"
+ },
+ {
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "label": "Send Notification To",
+ "options": "Email",
+ "reqd": 1
}
],
"issingle": 1,
- "modified": "2019-08-21 17:07:21.773252",
+ "modified": "2019-08-21 17:33:28.516614",
"modified_by": "qwe@qwe.com",
"module": "Integrations",
"name": "Google Drive",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 759facd518..a3cd5602b5 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -151,6 +151,11 @@ def check_for_folder_in_google_drive(google_drive, account):
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
@frappe.whitelist()
+def take_backup():
+ """Enqueue longjob for taking backup to Google Drive"""
+ enqueue("frappe.integrations.doctype.google_drive.google_drive.upload_system_backup_to_google_drive", queue='long', timeout=1500)
+ frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour."))
+
def upload_system_backup_to_google_drive():
"""
Upload system backup to Google Drive
@@ -169,7 +174,7 @@ def upload_system_backup_to_google_drive():
fileurl_private_files = os.path.basename(backup.backup_path_private_files)
- for file_url in [fileurl_backup, fileurl_public_files, fileurl_private_files]:
+ for fileurl in [fileurl_backup, fileurl_public_files, fileurl_private_files]:
file_metadata = {
"name": fileurl,
"parents": [account.backup_folder_id]
From 1abf318b49e089b38c89e3fac296acb49e684ee5 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 17:40:38 +0530
Subject: [PATCH 51/58] fix: import enqueue
---
frappe/integrations/doctype/google_drive/google_drive.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index a3cd5602b5..0da6f8cd1f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -13,6 +13,7 @@ from frappe import _
from googleapiclient.errors import HttpError
from frappe.model.document import Document
from frappe.utils import get_request_site_address
+from frappe.utils.background_jobs import enqueue
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
from frappe.utils import get_backups_path, get_files_path, get_bench_path
From c33317ccf8b58565c3c97213d7f6a2652f58da3d Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 17:45:54 +0530
Subject: [PATCH 52/58] fix: reset folder id on reauthorize
---
frappe/integrations/doctype/google_drive/google_drive.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 0da6f8cd1f..8a9caa7654 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -63,6 +63,8 @@ def authorize_access(reauthorize=None):
redirect_uri = get_request_site_address(True) + "?cmd=frappe.integrations.doctype.google_drive.google_drive.google_callback"
if not google_drive.authorization_code or reauthorize:
+ if reauthorize:
+ frappe.db.set_value("Google Drive", None, "backup_folder_id", "")
return get_authentication_url(client_id=google_settings.client_id, redirect_uri=redirect_uri)
else:
try:
From 38e2fad23aa4f1e5c1d4466ae67c38ccc649ceb3 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 17:57:12 +0530
Subject: [PATCH 53/58] fix: do not show take backup if not enable
---
frappe/integrations/doctype/google_drive/google_drive.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index 034b18d2a8..bcdb3fbc77 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -17,7 +17,7 @@ frappe.ui.form.on('Google Drive', {
}
});
- if (frm.doc.refresh_token && !frm.doc.backup_folder_id) {
+ if (frm.doc.enable && frm.doc.refresh_token && !frm.doc.backup_folder_id) {
let create_button = frm.add_custom_button(__("Create Folder"), function () {
frappe.show_alert({
indicator: "green",
@@ -33,7 +33,7 @@ frappe.ui.form.on('Google Drive', {
});
}
- if (frm.doc.refresh_token && frm.doc.backup_folder_id) {
+ if (frm.doc.enable && frm.doc.refresh_token && frm.doc.backup_folder_id) {
let sync_button = frm.add_custom_button(__("Take Backup"), function () {
frappe.show_alert({
indicator: "green",
From 8e578d3b0f0727727f7af1e0e4f56ee33456f3b7 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 18:22:29 +0530
Subject: [PATCH 54/58] fix: find folder if already exists
---
.../doctype/google_drive/google_drive.py | 34 ++++++++++++++-----
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 8a9caa7654..f0220227a2 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -126,17 +126,35 @@ def get_google_drive_object():
@frappe.whitelist()
def create_folder_in_google_drive():
- google_drive, account = get_google_drive_object()
+ def _create_folder_in_google_drive(google_drive, account):
+ file_metadata = {
+ "name": account.backup_folder_name,
+ "mimeType": "application/vnd.google-apps.folder"
+ }
+
+ try:
+ folder = google_drive.files().create(body=file_metadata, fields="id").execute()
+ frappe.db.set_value("Google Drive", None, "backup_folder_id", folder.get("id"))
+ except HttpError as e:
+ frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
+
+ google_drive, account = get_google_drive_object()
+ backup_folder_exists = False
- file_metadata = {
- "name": account.backup_folder_name,
- "mimeType": "application/vnd.google-apps.folder"
- }
try:
- folder = google_drive.files().create(body=file_metadata, fields="id").execute()
- frappe.db.set_value("Google Drive", None, "backup_folder_id", folder.get("id"))
+ folder_exists = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute().get("files", [])
except HttpError as e:
- frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
+ frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}").format(e))
+
+ if folder_exists:
+ for f in folder_exists:
+ if f.get("name") == account.backup_folder_name:
+ frappe.db.set_value("Google Drive", None, "backup_folder_id", f.get("id"))
+ backup_folder_exists = True
+ break
+
+ if not backup_folder_exists:
+ _create_folder_in_google_drive(google_drive, account)
return _("Folder Created in Google Drive.")
From b4084de9ab64dab4128f93c3e3f1442c9e33f553 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 19:04:38 +0530
Subject: [PATCH 55/58] fix: create folder if not exists
---
.../doctype/google_drive/google_drive.js | 18 +--------
.../doctype/google_drive/google_drive.py | 39 +++++++++----------
2 files changed, 19 insertions(+), 38 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.js b/frappe/integrations/doctype/google_drive/google_drive.js
index bcdb3fbc77..ec3323f89b 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.js
+++ b/frappe/integrations/doctype/google_drive/google_drive.js
@@ -17,23 +17,7 @@ frappe.ui.form.on('Google Drive', {
}
});
- if (frm.doc.enable && frm.doc.refresh_token && !frm.doc.backup_folder_id) {
- let create_button = frm.add_custom_button(__("Create Folder"), function () {
- frappe.show_alert({
- indicator: "green",
- message: __("Creating folder in Google Drive.")
- });
- frappe.call({
- method: "frappe.integrations.doctype.google_drive.google_drive.create_folder_in_google_drive",
- btn: create_button
- }).then((r) => {
- frm.refresh();
- frappe.msgprint(r.message);
- });
- });
- }
-
- if (frm.doc.enable && frm.doc.refresh_token && frm.doc.backup_folder_id) {
+ if (frm.doc.enable && frm.doc.refresh_token) {
let sync_button = frm.add_custom_button(__("Take Backup"), function () {
frappe.show_alert({
indicator: "green",
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index f0220227a2..c83165d87f 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -24,6 +24,11 @@ SCOPES = "https://www.googleapis.com/auth/drive"
class GoogleDrive(Document):
+ def validate(self):
+ doc_before_save = self.get_doc_before_save()
+ if doc_before_save and doc_before_save.backup_folder_name != self.backup_folder_name:
+ self.backup_folder_id = ''
+
def get_access_token(self):
google_settings = frappe.get_doc("Google Settings")
@@ -124,8 +129,8 @@ def get_google_drive_object():
return google_drive, account
-@frappe.whitelist()
-def create_folder_in_google_drive():
+def check_for_folder_in_google_drive():
+ """Checks if folder exists in Google Drive else create it."""
def _create_folder_in_google_drive(google_drive, account):
file_metadata = {
"name": account.backup_folder_name,
@@ -135,42 +140,33 @@ def create_folder_in_google_drive():
try:
folder = google_drive.files().create(body=file_metadata, fields="id").execute()
frappe.db.set_value("Google Drive", None, "backup_folder_id", folder.get("id"))
+ frappe.db.commit()
except HttpError as e:
frappe.throw(_("Google Drive - Could not create folder in Google Drive - Error Code {0}").format(e))
google_drive, account = get_google_drive_object()
+
+ if account.backup_folder_id:
+ return
+
backup_folder_exists = False
try:
- folder_exists = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute().get("files", [])
+ google_drive_folders = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute().get("files", [])
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}").format(e))
- if folder_exists:
- for f in folder_exists:
+ if google_drive_folders:
+ for f in google_drive_folders:
if f.get("name") == account.backup_folder_name:
frappe.db.set_value("Google Drive", None, "backup_folder_id", f.get("id"))
+ frappe.db.commit()
backup_folder_exists = True
break
if not backup_folder_exists:
_create_folder_in_google_drive(google_drive, account)
- return _("Folder Created in Google Drive.")
-
-def check_for_folder_in_google_drive(google_drive, account):
- """
- Create a folder on Drive, returns the newely created folders ID
- """
- if not account.backup_folder_id:
- create_folder_in_google_drive()
- return
-
- try:
- google_drive.files().get(fileId=account.backup_folder_id, fields="id").execute()
- except HttpError as e:
- frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}.").format(e))
-
@frappe.whitelist()
def take_backup():
"""Enqueue longjob for taking backup to Google Drive"""
@@ -185,8 +181,9 @@ def upload_system_backup_to_google_drive():
google_drive, account = get_google_drive_object()
# Check if folder exists in Google Drive
- check_for_folder_in_google_drive(google_drive, account)
+ check_for_folder_in_google_drive()
account.load_from_db()
+
progress(1, "Backing up Data.")
backup = new_backup()
From 2373014e11b4718ba888c8fb151491dd18b93fac Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 21:32:16 +0530
Subject: [PATCH 56/58] fix: codacy
---
frappe/integrations/doctype/google_drive/google_drive.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index c83165d87f..84e8f98407 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -16,7 +16,7 @@ from frappe.utils import get_request_site_address
from frappe.utils.background_jobs import enqueue
from six.moves.urllib.parse import quote
from apiclient.http import MediaFileUpload
-from frappe.utils import get_backups_path, get_files_path, get_bench_path
+from frappe.utils import get_backups_path, get_bench_path
from frappe.utils.backups import new_backup
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
@@ -152,12 +152,12 @@ def check_for_folder_in_google_drive():
backup_folder_exists = False
try:
- google_drive_folders = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute().get("files", [])
+ google_drive_folders = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute()
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}").format(e))
- if google_drive_folders:
- for f in google_drive_folders:
+ if google_drive_folders.get("files"):
+ for f in google_drive_folders.get("files"):
if f.get("name") == account.backup_folder_name:
frappe.db.set_value("Google Drive", None, "backup_folder_id", f.get("id"))
frappe.db.commit()
From 6ae434c937b5dc5e08100f5781f84c52281dcdb6 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 21:50:40 +0530
Subject: [PATCH 57/58] fix: codacy
---
frappe/integrations/doctype/google_drive/google_drive.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 84e8f98407..9a80a64ed4 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -152,7 +152,7 @@ def check_for_folder_in_google_drive():
backup_folder_exists = False
try:
- google_drive_folders = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'".format(account.backup_folder_name)).execute()
+ google_drive_folders = google_drive.files().list(q="mimeType='application/vnd.google-apps.folder'").execute()
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}").format(e))
From 2ba5f6e0ac21daee7ac3662594a22ceef2e1d1c8 Mon Sep 17 00:00:00 2001
From: Himanshu Warekar
Date: Wed, 21 Aug 2019 23:20:40 +0530
Subject: [PATCH 58/58] fix: remove unnecessary check
---
.../doctype/google_drive/google_drive.py | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py
index 9a80a64ed4..8078c702c0 100644
--- a/frappe/integrations/doctype/google_drive/google_drive.py
+++ b/frappe/integrations/doctype/google_drive/google_drive.py
@@ -156,13 +156,12 @@ def check_for_folder_in_google_drive():
except HttpError as e:
frappe.throw(_("Google Drive - Could not find folder in Google Drive - Error Code {0}").format(e))
- if google_drive_folders.get("files"):
- for f in google_drive_folders.get("files"):
- if f.get("name") == account.backup_folder_name:
- frappe.db.set_value("Google Drive", None, "backup_folder_id", f.get("id"))
- frappe.db.commit()
- backup_folder_exists = True
- break
+ for f in google_drive_folders.get("files"):
+ if f.get("name") == account.backup_folder_name:
+ frappe.db.set_value("Google Drive", None, "backup_folder_id", f.get("id"))
+ frappe.db.commit()
+ backup_folder_exists = True
+ break
if not backup_folder_exists:
_create_folder_in_google_drive(google_drive, account)