From 202508410c4a01d432f07a6dcfec1dd3a85e27d2 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 7 Mar 2013 12:25:21 +0530 Subject: [PATCH] completed dropbox backup in backup manager --- .../doctype/backup_manager/backup_dropbox.py | 115 ++++++++++++++++++ .../doctype/backup_manager/backup_manager.js | 12 +- .../doctype/backup_manager/backup_manager.py | 73 ++++++----- .../doctype/backup_manager/backup_manager.txt | 35 +++++- setup/page/setup/setup.js | 26 ++-- startup/schedule_handlers.py | 7 +- 6 files changed, 209 insertions(+), 59 deletions(-) create mode 100644 setup/doctype/backup_manager/backup_dropbox.py diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py new file mode 100644 index 0000000000..3b0857fdd9 --- /dev/null +++ b/setup/doctype/backup_manager/backup_dropbox.py @@ -0,0 +1,115 @@ +import os +import webnotes +from webnotes.utils import get_request_site_address + +@webnotes.whitelist() +def get_dropbox_authorize_url(): + sess = get_dropbox_session() + request_token = sess.obtain_request_token() + return_address = get_request_site_address(True) \ + + "?cmd=setup.doctype.backup_manager.backup_dropbox.dropbox_callback" + + url = sess.build_authorize_url(request_token, return_address) + + return { + "url": url, + "key": request_token.key, + "secret": request_token.secret, + } + +@webnotes.whitelist(allow_guest=True) +def dropbox_callback(oauth_token=None, not_approved=False): + if not not_approved: + if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token: + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1) + message = "Dropbox access allowed." + + sess = get_dropbox_session() + sess.set_request_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"), + webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret")) + access_token = sess.obtain_access_token() + + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", + access_token.key) + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", + access_token.secret) + + else: + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) + message = "Illegal Access Token Please try again." + else: + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) + message = "Dropbox Access not approved." + + webnotes.message_title = "Dropbox Approval" + webnotes.message = "

%s

Please close this window.

" % message + + webnotes.conn.commit() + webnotes.response['type'] = 'page' + webnotes.response['page_name'] = 'message.html' + +def backup_to_dropbox(): + from dropbox import client, session + from conf import dropbox_access_key, dropbox_secret_key + from webnotes.utils.backups import new_backup + if not webnotes.conn: + webnotes.connect() + + + sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder") + + sess.set_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"), + webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret")) + + dropbox_client = client.DropboxClient(sess) + + # upload database + backup = new_backup() + filename = backup.backup_path_db + upload_file_to_dropbox(filename, "database", dropbox_client) + + # upload files + response = dropbox_client.metadata("files") + + + # add missing files + for filename in os.listdir(os.path.join("public", "files")): + found = False + for file_metadata in response["contents"]: + if filename==os.path.basename(file_metadata["path"]): + if os.stat(os.path.join("public", "files", filename)).st_size==file_metadata["bytes"]: + found=True + + if not found: + upload_file_to_dropbox(os.path.join("public", "files", filename), "files", dropbox_client) + + +def get_dropbox_session(): + from dropbox import session + try: + from conf import dropbox_access_key, dropbox_secret_key + except ImportError, e: + webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py", + raise_exception=True) + + sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder") + return sess + +def upload_file_to_dropbox(filename, folder, dropbox_client): + if __name__=="__main__": + print "Uploading " + filename + size = os.stat(filename).st_size + f = open(filename,'r') + + if size > 4194304: + uploader = dropbox_client.get_chunked_uploader(f, size) + while uploader.offset < size: + try: + uploader.upload_chunked() + except rest.ErrorResponse, e: + pass + else: + response = dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) + +if __name__=="__main__": + backup_to_dropbox() \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.js b/setup/doctype/backup_manager/backup_manager.js index a0f7f71dcc..154c72ec0e 100644 --- a/setup/doctype/backup_manager/backup_manager.js +++ b/setup/doctype/backup_manager/backup_manager.js @@ -1,6 +1,6 @@ cur_frm.cscript.allow_dropbox_access = function(doc) { wn.call({ - method: "setup.doctype.backup_manager.backup_manager.get_dropbox_authorize_url", + method: "setup.doctype.backup_manager.backup_dropbox.get_dropbox_authorize_url", callback: function(r) { if(!r.exc) { cur_frm.set_value("dropbox_access_secret", r.message.secret); @@ -11,4 +11,14 @@ cur_frm.cscript.allow_dropbox_access = function(doc) { } } }) +} + +cur_frm.cscript.backup_right_now = function(doc) { + msgprint("Backing up and uploading. This may take a few minutes.") + wn.call({ + method: "setup.doctype.backup_manager.backup_manager.take_backups", + callback: function(r) { + msgprint("Backups taken. Please check your email for the response.") + } + }) } \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.py b/setup/doctype/backup_manager/backup_manager.py index fc41654985..48d48e817c 100644 --- a/setup/doctype/backup_manager/backup_manager.py +++ b/setup/doctype/backup_manager/backup_manager.py @@ -3,51 +3,46 @@ from __future__ import unicode_literals import webnotes from webnotes import _ -from webnotes.utils import get_request_site_address class DocType: def __init__(self, d, dl): self.doc, self.doclist = d, dl -@webnotes.whitelist() -def get_dropbox_authorize_url(): - from dropbox import session +def take_backups_daily(): + take_backups_if("Daily") +def take_backups_weekly(): + take_backups_if("Weekly") + +def take_backups_if(freq): + if webnotes.conn.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq: + take_backups() + +@webnotes.whitelist() +def take_backups(): try: - from conf import dropbox_access_key, dropbox_secret_key - except ImportError, e: - webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py", - raise_exception=True) - - sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder") - request_token = sess.obtain_request_token() - return_address = get_request_site_address(True) \ - + "?cmd=setup.doctype.backup_manager.backup_manager.dropbox_callback" - - url = sess.build_authorize_url(request_token, return_address) - - return { - "url": url, - "key": request_token.key, - "secret": request_token.secret, - } - -@webnotes.whitelist(allow_guest=True) -def dropbox_callback(oauth_token=None, not_approved=False): - if not not_approved: - if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1) - message = "Dropbox access allowed." - else: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) - message = "Illegal Access Token Please try again." + from setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox + backup_to_dropbox() + send_email(True, "Dropbox") + except Exception, e: + send_email(False, "Dropbox", e) + +def send_email(success, service_name, error_status=None): + if success: + subject = "Backup Upload Successful" + message ="""

Backup Uploaded Successfully

Hi there, this is just to inform you + that your backup was successfully uploaded to your %s account. So relax!

+ """ % service_name + else: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) - message = "Dropbox Access not approved." + subject = "[Warning] Backup Upload Failed" + message ="""

Backup Upload Failed

Oops, your automated backup to %s + failed.

+

Error message: %s

+

Please contact your system manager for more information.

+ """ % (service_name, error_status) - webnotes.message_title = "Dropbox Approval" - webnotes.message = "

%s

Please close this window.

" % message - - webnotes.conn.commit() - webnotes.response['type'] = 'page' - webnotes.response['page_name'] = 'message.html' + # email system managers + from webnotes.utils.email_lib import sendmail + sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","), + subject=subject, msg=message) diff --git a/setup/doctype/backup_manager/backup_manager.txt b/setup/doctype/backup_manager/backup_manager.txt index bf5d6867f4..a994e7da53 100644 --- a/setup/doctype/backup_manager/backup_manager.txt +++ b/setup/doctype/backup_manager/backup_manager.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-05 16:35:50", "docstatus": 0, - "modified": "2013-03-05 18:05:05", + "modified": "2013-03-07 12:18:07", "modified_by": "Administrator", "owner": "Administrator" }, @@ -39,6 +39,27 @@ "name": "Backup Manager" }, { + "doctype": "DocField", + "fieldname": "setup", + "fieldtype": "Section Break", + "label": "Setup" + }, + { + "description": "Email ids separated by commas.", + "doctype": "DocField", + "fieldname": "send_notifications_to", + "fieldtype": "Data", + "label": "Send Notifications To", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "backup_right_now", + "fieldtype": "Button", + "label": "Backup Right Now" + }, + { + "description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.", "doctype": "DocField", "fieldname": "sync_with_dropbox", "fieldtype": "Section Break", @@ -47,27 +68,31 @@ { "doctype": "DocField", "fieldname": "upload_backups_to_dropbox", - "fieldtype": "Check", - "label": "Upload Backups to Dropbox" + "fieldtype": "Select", + "label": "Upload Backups to Dropbox", + "options": "Never\nWeekly\nDaily" }, { "doctype": "DocField", "fieldname": "dropbox_access_key", "fieldtype": "Data", "hidden": 1, - "label": "Dropbox Access Key" + "label": "Dropbox Access Key", + "read_only": 1 }, { "doctype": "DocField", "fieldname": "dropbox_access_secret", "fieldtype": "Data", "hidden": 1, - "label": "Dropbox Access Secret" + "label": "Dropbox Access Secret", + "read_only": 1 }, { "doctype": "DocField", "fieldname": "dropbox_access_allowed", "fieldtype": "Check", + "hidden": 1, "label": "Dropbox Access Allowed", "read_only": 1 }, diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js index 1d8a5ba822..e970a60c24 100644 --- a/setup/page/setup/setup.js +++ b/setup/page/setup/setup.js @@ -186,19 +186,19 @@ wn.module_page["Setup"] = [ }, ] }, - // { - // title: wn._("Backups"), - // icon: "icon-cloud-upload", - // right: true, - // items: [ - // { - // "route":"Form/Backup Manager", - // doctype:"Backup Manager", - // label: wn._("Backup Manager"), - // "description":wn._("Sync backups with remote tools like Dropbox etc.") - // }, - // ] - // }, + { + title: wn._("Backups"), + icon: "icon-cloud-upload", + right: true, + items: [ + { + "route":"Form/Backup Manager", + doctype:"Backup Manager", + label: wn._("Backup Manager"), + "description":wn._("Sync backups with remote tools like Dropbox etc.") + }, + ] + }, ] pscript['onload_Setup'] = function(wrapper) { diff --git a/startup/schedule_handlers.py b/startup/schedule_handlers.py index c710c54086..2a066af331 100644 --- a/startup/schedule_handlers.py +++ b/startup/schedule_handlers.py @@ -51,8 +51,13 @@ def execute_daily(): from webnotes.utils.email_lib.bulk import clear_outbox run_fn(clear_outbox) + # daily backup + from setup.doctype.backup_manager.backup_manager + take_backups_daily() + def execute_weekly(): - pass + from setup.doctype.backup_manager.backup_manager + take_backups_weekly() def execute_monthly(): pass