From 00eefb1a1ce72308d5c7a357b2d994782949daa7 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 13 Jun 2011 17:42:51 +0530 Subject: [PATCH 01/16] Backup Generator Module: On Tools > Download Backup, backup link is emailed. --- cgi-bin/webnotes/utils/backups.py | 254 +++++++++++++++++++----------- 1 file changed, 164 insertions(+), 90 deletions(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 804750fa29..e46c5c8ef7 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -1,107 +1,181 @@ -import webnotes +""" + This module handles the On Demand Backup utility +""" +#Imports +import os, webnotes +from datetime import datetime -backup_folder = '/backups' -mysql_path = '' -download_folder = 'backups' -def mysqldump(db, folder=''): - global mysql_path - import os - import webnotes.defs - - os.system('%(path)smysqldump %(db)s > %(folder)s%(db)s.sql -u %(db)s -p%(pwd)s --ignore-table=%(db)s.__DocTypeCache' % {'path':mysql_path, 'db':db, 'pwd':webnotes.defs.db_password, 'folder':folder}) +#Global constants +from webnotes.defs import backup_path, backup_link_path, backup_url +verbose = 0 -def backup_db(db, conn, from_all=0): - import os - global backup_folder - - try: - # Check processlist - if from_all or len(conn.sql("show processlist")) == 1: - p = backup_folder - if from_all: p = backup_folder + '/dumps' - - # clear old file - os.system('rm %s/%s.tar.gz' % (p,db)) - - # dump - mysqldump(db, p+'/') - - # zip - os.system('tar czf %s/%s.tar.gz %s/%s.sql' % (p, db, p, db)) - os.system('rm %s/%s.sql' % (p, db)) - else: - print("Another process is running in database. Please try again") - except Exception, e: - #sql('unlock tables') - raise e +class BackupGenerator: + """ + This class contains methods to perform On Demand Backup -def backup_all(): - # backups folder - import os - import webnotes.db - global backup_folder - - conn = webnotes.db.Database(use_default=1) - dblist = conn.sql('select db_name from tabAccount') + To initialize, specify (db_name, user, password, db_file_name=None) + If specifying db_file_name, also append ".sql.gz" + """ + def __init__(self, db_name, user, password, db_file_name=None): + self.db_name = db_name + self.user = user + self.password = password + self.db_file_name = db_file_name and db_file_name \ + or (backup_path + db_name + ".sql.gz") - # backup -all in /backups folder - for d in (('accounts',),) + dblist: - backup_db(d[0], conn, 1) + def take_dump(self): + """ + Dumps a db via mysqldump + """ + os.system("""mysqldump -u %(user)s -p%(password)s %(db_name)s | + gzip -c > %(db_file_name)s""" % self.__dict__) - conn.close() - # dump all in /daily folder - import time, datetime - fname = 'daily-' + time.strftime('%Y-%m-%d') + '.tar.gz' + def copy_to_backup_link(self): + """ + Copies the backup file from backup path to shared link path + It also gives the file a random name, thus hiding the db_name + """ + import random + todays_date = "".join(str(datetime.date(datetime.today())).split("-")) + random_number = str(int(random.random()*99999999)) + + #Generate a random name using today's date and a 8 digit random number + random_name = todays_date + "_" + random_number + ".sql.gz" + + os.system("""cp -f %(src_file)s %(dest_file)s""" % \ + {"src_file":self.db_file_name, + "dest_file":(backup_link_path + random_name)}) + if verbose: print "file copied" + return random_name - # daily dump - os.system('tar czf %s/daily/%s %s/dumps' % (backup_folder, fname, backup_folder)) + + def get_recipients(self): + """ + Get recepient's email address + """ + import webnotes.db + webnotes.conn = webnotes.db.Database(use_default = 1) + recipient_list = webnotes.conn.sql("""SELECT parent FROM tabUserRole + WHERE role='System Manager' + AND parent!='Administrator'""") + return [i[0] for i in recipient_list] + + + def send_email(self, backup_file): + """ + Sends the link to backup file located at erpnext/backups + """ + file_url = backup_url + backup_file + from webnotes.utils.email_lib import sendmail + + recipient_list = self.get_recipients() + msg = """Click here to begin downloading\ + your backup + + This link will be valid for 24 hours. + + Also, a new backup will be available for download (if requested)\ + only after 24 hours.""" % {"file_url":file_url} + + datetime_str = datetime.fromtimestamp(os.stat(self.db_file_name).st_ctime) + + subject = datetime_str.strftime("%d/%m/%Y %H:%M:%S") + """ - Backup ready to be downloaded""" + sendmail(recipients=recipient_list, msg=msg, subject=subject) + + + + def get_backup(self): + """ + Takes a new dump if existing file is old + and sends the link to the file as email + """ + #Check if file exists and is less than a day old + #If not Take Dump + if is_file_old(self.db_file_name): + self.take_dump() + + #Copy file to backup_link_path + #This is a security hole. When the user calls get_backup repeatedly + #a file will be generated each time. + backup_file = self.copy_to_backup_link() - # keep only three files - if len(os.listdir(backup_folder + '/daily')) > 3: - delete_oldest_file(backup_folder + '/daily') - - # if sunday, then copy to weekly - if datetime.datetime.now().weekday()==6: - os.system('cp '+backup_folder+'/daily/'+fname+' '+backup_folder+'/weekly/'+fname) - - # keep only three files - if len(os.listdir(backup_folder + '/weekly')) > 3: - delete_oldest_file(backup_folder + '/weekly') - -def delete_oldest_file(folder): - import os - a = sorted(os.listdir(folder), key=lambda fn: os.stat(folder+'/'+fn).st_mtime, reverse=False) - if a: - os.system('rm %s/%s' % (folder, a[0])) + #Email Link + self.send_email(backup_file) + def get_backup(): - import webnotes - import os, time + """ + This function is executed when the user clicks on + Toos > Download Backup + """ + #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password + odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ + webnotes.defs.db_password) + odb.get_backup() + webnotes.msgprint("""A download link to your backup will be emailed \ + to you shortly.""") - global backup_folder, download_folder - # get the last nightly backup file from the backups folder - os.chdir(download_folder) +def delete_temp_backups(): + """ + Cleans up the backup_link_path directory by deleting files older than 24 hours + """ + file_list = os.listdir(backup_link_path) + for this_file in file_list: + this_file_path = backup_link_path + this_file + if is_file_old(this_file_path, 1): + os.remove(this_file_path) - if webnotes.conn.cur_db_name: - fname = webnotes.conn.cur_db_name + '.tar.gz' - # rename it - from random import choice - lnd='0123456789' - new_name = ''.join(map(lambda x,y=lnd: choice(y), range(8))) + '.sql.gz' - folder = backup_folder + '/dumps/' +def is_file_old(db_file_name, older_than=24): + """ + Checks if file exists and is older than specified hours + Returns -> + True: file does not exist or file is old + False: file is new + """ + if os.path.isfile(db_file_name): + from datetime import timedelta + import time + #Get timestamp of the file + file_datetime = datetime.fromtimestamp\ + (os.stat(db_file_name).st_ctime) + if datetime.today() - file_datetime >= timedelta(hours = older_than): + if verbose: print "File is old" + return True + else: + if verbose: print "File is recent" + return False + else: + if verbose: print "File does not exist" + return True - # get the newest file - if os.path.exists(folder): - os.system('cp '+ folder + webnotes.conn.cur_db_name+'.sql.gz' + ' ./' + new_name) - webnotes.msgprint('Your nightly backup is available for download by clicking here (only for the next few hours)') + + +if __name__ == "__main__": + """ + is_file_old db_name user password + get_backup db_name user password + """ + import sys + cmd = sys.argv[1] + if cmd == "is_file_old": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + is_file_old(odb.db_file_name) - # delete any files older than a day - now = time.time() - for f in os.listdir('.'): - if os.stat(f).st_mtime < (now - 86400): - if os.path.isfile(f): - os.remove(f) + if cmd == "get_backup": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.get_backup() + + if cmd == "take_dump": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.take_dump() + + if cmd == "send_email": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.send_email("abc.sql.gz") + + if cmd == "delete_temp_backups": + delete_temp_backups() From 6be68dd332f93492975d7bd44aa7cc01f536b789 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 13 Jun 2011 19:12:14 +0530 Subject: [PATCH 02/16] removed & and , validation in autoname --- cgi-bin/webnotes/model/doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 cgi-bin/webnotes/model/doc.py diff --git a/cgi-bin/webnotes/model/doc.py b/cgi-bin/webnotes/model/doc.py old mode 100644 new mode 100755 index f6dc31bbca..bb15ebb92f --- a/cgi-bin/webnotes/model/doc.py +++ b/cgi-bin/webnotes/model/doc.py @@ -227,7 +227,7 @@ class Document: self.name = self.name.strip() # no leading and trailing blanks - forbidden = ['%', "'", '"', ',', '#', '*', '?', '&', '`'] + forbidden = ['%', "'", '"', '#', '*', '?', '`'] for f in forbidden: if f in self.name: webnotes.msgprint('%s not allowed in ID (name)' % f, raise_exception =1) From 97a08b58fbcf8f7dc879bc95115a0bcdc04670e6 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 10:30:56 +0530 Subject: [PATCH 03/16] Added function to delete old temporary backup files when user downloads backup. --- cgi-bin/webnotes/utils/backups.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index e46c5c8ef7..388045530f 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -112,8 +112,9 @@ def get_backup(): """ #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ - webnotes.defs.db_password) + webnotes.defs.db_password) odb.get_backup() + delete_temp_backups() webnotes.msgprint("""A download link to your backup will be emailed \ to you shortly.""") From ff966f6c539e5dc8d867540b06febefd6609dd45 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 10:34:38 +0530 Subject: [PATCH 04/16] Added comments --- cgi-bin/webnotes/utils/backups.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 388045530f..01ce9935f0 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -10,6 +10,7 @@ from datetime import datetime from webnotes.defs import backup_path, backup_link_path, backup_url verbose = 0 +#------------------------------------------------------------------------------- class BackupGenerator: """ This class contains methods to perform On Demand Backup @@ -104,7 +105,7 @@ class BackupGenerator: #Email Link self.send_email(backup_file) - +#------------------------------------------------------------------------------- def get_backup(): """ This function is executed when the user clicks on @@ -153,7 +154,7 @@ def is_file_old(db_file_name, older_than=24): if verbose: print "File does not exist" return True - +#------------------------------------------------------------------------------- if __name__ == "__main__": """ From 63b28bcf9dc4082994dedc411911e4cb0d5c0305 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 10:47:23 +0530 Subject: [PATCH 05/16] Added delete function to delete temporary backup files --- cgi-bin/webnotes/utils/backups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 01ce9935f0..75f1b55fff 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -127,7 +127,7 @@ def delete_temp_backups(): file_list = os.listdir(backup_link_path) for this_file in file_list: this_file_path = backup_link_path + this_file - if is_file_old(this_file_path, 1): + if is_file_old(this_file_path): os.remove(this_file_path) From 7344c6a09c37e2d3102c4a9b5b25ea62d2dcc5b2 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 16:06:25 +0530 Subject: [PATCH 06/16] renamed backups.py to backups-temp.py --- cgi-bin/webnotes/utils/backups.py | 183 ------------------------------ 1 file changed, 183 deletions(-) delete mode 100644 cgi-bin/webnotes/utils/backups.py diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py deleted file mode 100644 index 75f1b55fff..0000000000 --- a/cgi-bin/webnotes/utils/backups.py +++ /dev/null @@ -1,183 +0,0 @@ -""" - This module handles the On Demand Backup utility -""" -#Imports -import os, webnotes -from datetime import datetime - - -#Global constants -from webnotes.defs import backup_path, backup_link_path, backup_url -verbose = 0 - -#------------------------------------------------------------------------------- -class BackupGenerator: - """ - This class contains methods to perform On Demand Backup - - To initialize, specify (db_name, user, password, db_file_name=None) - If specifying db_file_name, also append ".sql.gz" - """ - def __init__(self, db_name, user, password, db_file_name=None): - self.db_name = db_name - self.user = user - self.password = password - self.db_file_name = db_file_name and db_file_name \ - or (backup_path + db_name + ".sql.gz") - - def take_dump(self): - """ - Dumps a db via mysqldump - """ - os.system("""mysqldump -u %(user)s -p%(password)s %(db_name)s | - gzip -c > %(db_file_name)s""" % self.__dict__) - - - def copy_to_backup_link(self): - """ - Copies the backup file from backup path to shared link path - It also gives the file a random name, thus hiding the db_name - """ - import random - todays_date = "".join(str(datetime.date(datetime.today())).split("-")) - random_number = str(int(random.random()*99999999)) - - #Generate a random name using today's date and a 8 digit random number - random_name = todays_date + "_" + random_number + ".sql.gz" - - os.system("""cp -f %(src_file)s %(dest_file)s""" % \ - {"src_file":self.db_file_name, - "dest_file":(backup_link_path + random_name)}) - if verbose: print "file copied" - return random_name - - - def get_recipients(self): - """ - Get recepient's email address - """ - import webnotes.db - webnotes.conn = webnotes.db.Database(use_default = 1) - recipient_list = webnotes.conn.sql("""SELECT parent FROM tabUserRole - WHERE role='System Manager' - AND parent!='Administrator'""") - return [i[0] for i in recipient_list] - - - def send_email(self, backup_file): - """ - Sends the link to backup file located at erpnext/backups - """ - file_url = backup_url + backup_file - from webnotes.utils.email_lib import sendmail - - recipient_list = self.get_recipients() - msg = """Click here to begin downloading\ - your backup - - This link will be valid for 24 hours. - - Also, a new backup will be available for download (if requested)\ - only after 24 hours.""" % {"file_url":file_url} - - datetime_str = datetime.fromtimestamp(os.stat(self.db_file_name).st_ctime) - - subject = datetime_str.strftime("%d/%m/%Y %H:%M:%S") + """ - Backup ready to be downloaded""" - sendmail(recipients=recipient_list, msg=msg, subject=subject) - - - - def get_backup(self): - """ - Takes a new dump if existing file is old - and sends the link to the file as email - """ - #Check if file exists and is less than a day old - #If not Take Dump - if is_file_old(self.db_file_name): - self.take_dump() - - #Copy file to backup_link_path - #This is a security hole. When the user calls get_backup repeatedly - #a file will be generated each time. - backup_file = self.copy_to_backup_link() - - #Email Link - self.send_email(backup_file) - -#------------------------------------------------------------------------------- -def get_backup(): - """ - This function is executed when the user clicks on - Toos > Download Backup - """ - #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password - odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ - webnotes.defs.db_password) - odb.get_backup() - delete_temp_backups() - webnotes.msgprint("""A download link to your backup will be emailed \ - to you shortly.""") - - -def delete_temp_backups(): - """ - Cleans up the backup_link_path directory by deleting files older than 24 hours - """ - file_list = os.listdir(backup_link_path) - for this_file in file_list: - this_file_path = backup_link_path + this_file - if is_file_old(this_file_path): - os.remove(this_file_path) - - -def is_file_old(db_file_name, older_than=24): - """ - Checks if file exists and is older than specified hours - Returns -> - True: file does not exist or file is old - False: file is new - """ - if os.path.isfile(db_file_name): - from datetime import timedelta - import time - #Get timestamp of the file - file_datetime = datetime.fromtimestamp\ - (os.stat(db_file_name).st_ctime) - if datetime.today() - file_datetime >= timedelta(hours = older_than): - if verbose: print "File is old" - return True - else: - if verbose: print "File is recent" - return False - else: - if verbose: print "File does not exist" - return True - -#------------------------------------------------------------------------------- - -if __name__ == "__main__": - """ - is_file_old db_name user password - get_backup db_name user password - """ - import sys - cmd = sys.argv[1] - if cmd == "is_file_old": - odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) - is_file_old(odb.db_file_name) - - if cmd == "get_backup": - odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) - odb.get_backup() - - if cmd == "take_dump": - odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) - odb.take_dump() - - if cmd == "send_email": - odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) - odb.send_email("abc.sql.gz") - - if cmd == "delete_temp_backups": - delete_temp_backups() From 4bb7cf07d57d0426b045025282e4c036392978de Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 16:31:34 +0530 Subject: [PATCH 07/16] Redownloaded backups.py --- cgi-bin/webnotes/utils/backups.py | 184 ++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 cgi-bin/webnotes/utils/backups.py diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py new file mode 100644 index 0000000000..145a7e5826 --- /dev/null +++ b/cgi-bin/webnotes/utils/backups.py @@ -0,0 +1,184 @@ +""" + This module handles the On Demand Backup utility +""" +#Imports +import os, webnotes +from datetime import datetime + + +#Global constants +from webnotes.defs import backup_path, backup_link_path, backup_url +verbose = 0 + +#------------------------------------------------------------------------------- +class BackupGenerator: + """ + This class contains methods to perform On Demand Backup + + To initialize, specify (db_name, user, password, db_file_name=None) + If specifying db_file_name, also append ".sql.gz" + """ + def __init__(self, db_name, user, password, db_file_name=None): + self.db_name = db_name + self.user = user + self.password = password + self.db_file_name = db_file_name and db_file_name \ + or (backup_path + db_name + ".sql.gz") + + def take_dump(self): + """ + Dumps a db via mysqldump + """ + os.system("""mysqldump -u %(user)s -p%(password)s %(db_name)s | + gzip -c > %(db_file_name)s""" % self.__dict__) + + + def copy_to_backup_link(self): + """ + Copies the backup file from backup path to shared link path + It also gives the file a random name, thus hiding the db_name + """ + import random + todays_date = "".join(str(datetime.date(datetime.today())).split("-")) + random_number = str(int(random.random()*99999999)) + + #Generate a random name using today's date and a 8 digit random number + random_name = todays_date + "_" + random_number + ".sql.gz" + + os.system("""cp -f %(src_file)s %(dest_file)s""" % \ + {"src_file":self.db_file_name, + "dest_file":(backup_link_path + random_name)}) + if verbose: print "file copied" + return random_name + + + def get_recipients(self): + """ + Get recepient's email address + """ + import webnotes.db + webnotes.conn = webnotes.db.Database(use_default = 1) + recipient_list = webnotes.conn.sql("""SELECT parent FROM tabUserRole + WHERE role='System Manager' + AND parent!='Administrator'""") + return [i[0] for i in recipient_list] + + + def send_email(self, backup_file): + """ + Sends the link to backup file located at erpnext/backups + """ + file_url = backup_url + backup_file + from webnotes.utils.email_lib import sendmail + + recipient_list = self.get_recipients() + msg = """Click here to begin downloading\ + your backup + + This link will be valid for 24 hours. + + Also, a new backup will be available for download (if requested)\ + only after 24 hours.""" % {"file_url":file_url} + + datetime_str = datetime.fromtimestamp(os.stat(self.db_file_name).st_ctime) + + subject = datetime_str.strftime("%d/%m/%Y %H:%M:%S") + """ - Backup ready to be downloaded""" + sendmail(recipients=recipient_list, msg=msg, subject=subject) + + + + def get_backup(self): + """ + Takes a new dump if existing file is old + and sends the link to the file as email + """ + #Check if file exists and is less than a day old + #If not Take Dump + if is_file_old(self.db_file_name): + self.take_dump() + + #Copy file to backup_link_path + #This is a security hole. When the user calls get_backup repeatedly + #a file will be generated each time. + backup_file = self.copy_to_backup_link() + + #Email Link + self.send_email(backup_file) + +#------------------------------------------------------------------------------- +def get_backup(): + """ + This function is executed when the user clicks on + Toos > Download Backup + """ + #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password + odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ + webnotes.defs.db_password) + odb.get_backup() + delete_temp_backups() + webnotes.msgprint("""A download link to your backup will be emailed \ + to you shortly.""") + + +def delete_temp_backups(): + """ + Cleans up the backup_link_path directory by deleting files older than 24 hours + """ + file_list = os.listdir(backup_link_path) + for this_file in file_list: + this_file_path = backup_link_path + this_file + if is_file_old(this_file_path): + os.remove(this_file_path) + + +def is_file_old(db_file_name, older_than=24): + """ + Checks if file exists and is older than specified hours + Returns -> + True: file does not exist or file is old + False: file is new + """ + if os.path.isfile(db_file_name): + from datetime import timedelta + import time + #Get timestamp of the file + file_datetime = datetime.fromtimestamp\ + (os.stat(db_file_name).st_ctime) + if datetime.today() - file_datetime >= timedelta(hours = older_than): + if verbose: print "File is old" + return True + else: + if verbose: print "File is recent" + return False + else: + if verbose: print "File does not exist" + return True + +#------------------------------------------------------------------------------- + +if __name__ == "__main__": + """ + is_file_old db_name user password + get_backup db_name user password + """ + import sys + cmd = sys.argv[1] + if cmd == "is_file_old": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + is_file_old(odb.db_file_name) + + if cmd == "get_backup": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.get_backup() + + if cmd == "take_dump": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.take_dump() + + if cmd == "send_email": + odb = BackupGenerator(sys.argv[2], sys.argv[3], sys.argv[4]) + odb.send_email("abc.sql.gz") + + if cmd == "delete_temp_backups": + delete_temp_backups() + From d28c12be3a877e99183ea729c334bb071a6f4996 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 14 Jun 2011 16:53:48 +0530 Subject: [PATCH 08/16] Added recipient list to the backup download available message so that user can check that email. --- cgi-bin/webnotes/utils/backups.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 145a7e5826..86a6e210ac 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -84,7 +84,7 @@ class BackupGenerator: subject = datetime_str.strftime("%d/%m/%Y %H:%M:%S") + """ - Backup ready to be downloaded""" sendmail(recipients=recipient_list, msg=msg, subject=subject) - + return recipient_list def get_backup(self): @@ -103,7 +103,9 @@ class BackupGenerator: backup_file = self.copy_to_backup_link() #Email Link - self.send_email(backup_file) + recipient_list = self.send_email(backup_file) + + return recipient_list #------------------------------------------------------------------------------- def get_backup(): @@ -114,10 +116,11 @@ def get_backup(): #if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ webnotes.defs.db_password) - odb.get_backup() + recipient_list = odb.get_backup() delete_temp_backups() webnotes.msgprint("""A download link to your backup will be emailed \ - to you shortly.""") + to you shortly on the following email address: + %s""" % (str(recipient_list),)) def delete_temp_backups(): From d5b1c7f9b94b859bddbca03a1b742a9be656817f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 15 Jun 2011 13:05:08 +0530 Subject: [PATCH 09/16] modified the recipient list fetch logic --- cgi-bin/webnotes/utils/backups.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 86a6e210ac..82cc69510a 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -56,11 +56,12 @@ class BackupGenerator: """ Get recepient's email address """ - import webnotes.db - webnotes.conn = webnotes.db.Database(use_default = 1) - recipient_list = webnotes.conn.sql("""SELECT parent FROM tabUserRole - WHERE role='System Manager' - AND parent!='Administrator'""") + recipient_list = webnotes.conn.sql(\ + """SELECT parent FROM tabUserRole + WHERE role='System Manager' + AND parent!='Administrator' + AND parent IN + (SELECT email FROM tabProfile WHERE enabled=1)""") return [i[0] for i in recipient_list] From 19eccd6d5b5c1cc49c023dc3d5ea7d18dc6c632c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 15 Jun 2011 13:15:04 +0530 Subject: [PATCH 10/16] Commented connection function call, as connection is already set up when using download backup functionality. --- cgi-bin/webnotes/utils/backups.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py index 82cc69510a..903683c196 100644 --- a/cgi-bin/webnotes/utils/backups.py +++ b/cgi-bin/webnotes/utils/backups.py @@ -56,6 +56,8 @@ class BackupGenerator: """ Get recepient's email address """ + #import webnotes.db + #webnotes.conn = webnotes.db.Database(use_default=1) recipient_list = webnotes.conn.sql(\ """SELECT parent FROM tabUserRole WHERE role='System Manager' From c0e654fbd6bd85085f4b9fbf041f286c6be71874 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 Jun 2011 09:58:24 +0530 Subject: [PATCH 11/16] Modified install.py - Added condition such that if master sql is used for installation, core modules need not be imported. This will probably solve new company creation issue. --- cgi-bin/webnotes/install_lib/install.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py index 5612f36ce2..2a014b4398 100755 --- a/cgi-bin/webnotes/install_lib/install.py +++ b/cgi-bin/webnotes/install_lib/install.py @@ -95,6 +95,9 @@ class Installer: """ a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes. """ + #Storing passed source path + passed_source_path = source_path + # get the path of the sql file to import if not source_path: @@ -125,7 +128,9 @@ class Installer: self.dbman.restore_database(target, source_path, self.root_password) if verbose: print "Imported from database %s" % source_path - self.import_core_module() + #If source path is passed + #i.e. importing from master sql, dont import core modules + if not passed_source_path: self.import_core_module() # framework cleanups self.framework_cleanups(target) From 40d638b045cb75221b54f5c3e84947789492c65e Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 Jun 2011 13:58:46 +0530 Subject: [PATCH 12/16] Modified send method of FormEmail class: changed method call attach to attach_file --- cgi-bin/webnotes/utils/email_lib/form_email.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cgi-bin/webnotes/utils/email_lib/form_email.py b/cgi-bin/webnotes/utils/email_lib/form_email.py index 5bd3be8007..979f1f8b86 100644 --- a/cgi-bin/webnotes/utils/email_lib/form_email.py +++ b/cgi-bin/webnotes/utils/email_lib/form_email.py @@ -148,9 +148,11 @@ class FormEmail: self.email.add_attachment(self.dn.replace(' ','').replace('/','-') + '.html', self.body) # attachments + # self.with_attachments comes from http form variables + # i.e. with_attachments=1 if cint(self.with_attachments): for a in self.set_attachments(): - a and self.email.attach(a.split(',')[0]) + a and self.email.attach_file(a.split(',')[0]) # cc if self.cc: From e7462499d92972b20fef01f7b266257679e79c42 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 27 Jun 2011 10:58:32 +0530 Subject: [PATCH 13/16] fix to install.py --- cgi-bin/webnotes/install_lib/install.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py index 2a014b4398..e4791b66e9 100755 --- a/cgi-bin/webnotes/install_lib/install.py +++ b/cgi-bin/webnotes/install_lib/install.py @@ -21,6 +21,9 @@ def copy_defs(): # class Installer: def __init__(self, root_login, root_password): + + import webnotes + import webnotes.db self.root_password = root_password from webnotes.model.db_schema import DbManager @@ -35,6 +38,8 @@ class Installer: # run framework related cleanups # def framework_cleanups(self, target): + + import webnotes self.dbman.drop_table('__DocTypeCache') webnotes.conn.sql("create table `__DocTypeCache` (name VARCHAR(120), modified DATETIME, content TEXT, server_code_compiled TEXT)") @@ -48,6 +53,7 @@ class Installer: Imports the "Core" module from .txt file and creates Creates profile Administrator """ + import webnotes from webnotes.modules.import_module import import_module from webnotes.modules.module_manager import reload_doc From 5033f1f36488d13fd4b1fc1c73502454bd4a6e70 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 27 Jun 2011 11:02:52 +0530 Subject: [PATCH 14/16] fixes in install --- cgi-bin/webnotes/install_lib/install.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py index e4791b66e9..dc720bdfa6 100755 --- a/cgi-bin/webnotes/install_lib/install.py +++ b/cgi-bin/webnotes/install_lib/install.py @@ -24,6 +24,7 @@ class Installer: import webnotes import webnotes.db + import webnotes.defs self.root_password = root_password from webnotes.model.db_schema import DbManager @@ -32,7 +33,7 @@ class Installer: webnotes.conn=self.conn webnotes.session= {'user':'Administrator'} self.dbman = DbManager(self.conn) - self.mysql_path = hasattr(defs, 'mysql_path') and webnotes.defs.mysql_path or '' + self.mysql_path = hasattr(webnotes.defs, 'mysql_path') and webnotes.defs.mysql_path or '' # # run framework related cleanups @@ -101,6 +102,7 @@ class Installer: """ a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes. """ + import webnotes.defs #Storing passed source path passed_source_path = source_path @@ -113,7 +115,7 @@ class Installer: self.dbman.delete_user(target) # create user and db - self.dbman.create_user(target,getattr(defs,'db_password',None)) + self.dbman.create_user(target,getattr(webnotes.defs,'db_password',None)) if verbose: print "Created user %s" % target # create a database @@ -159,7 +161,7 @@ def make_scheduler(root_login, root_password, verbose): dbman.delete_user('master_scheduler') # create user and db - dbman.create_user('master_scheduler', getattr(defs,'db_password',None)) + dbman.create_user('master_scheduler', getattr(webnotes.defs,'db_password',None)) if verbose: print "Created user master_scheduler" # create a database @@ -215,14 +217,14 @@ if __name__=='__main__': try: - from webnotes import defs import webnotes import webnotes.db + import webnotes.defs except ImportError: copy_defs() - from webnotes import defs import webnotes import webnotes.db + import webnotes.defs if len(args)==3: From 74720f659f9549e119a82860418df99adb88f088 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 27 Jun 2011 11:23:28 +0530 Subject: [PATCH 15/16] space allowed in db password --- cgi-bin/webnotes/install_lib/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py index dc720bdfa6..b54db527e8 100755 --- a/cgi-bin/webnotes/install_lib/install.py +++ b/cgi-bin/webnotes/install_lib/install.py @@ -133,7 +133,7 @@ class Installer: # import in target if verbose: print "Starting database import..." - self.dbman.restore_database(target, source_path, self.root_password) + self.dbman.restore_database(target, source_path, self.root_password.replace(' ','\ ')) if verbose: print "Imported from database %s" % source_path #If source path is passed From 9fcb4c230fd35936129defa78a53a5e7f96c608f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 27 Jun 2011 12:33:39 +0530 Subject: [PATCH 16/16] bug fix in core/doctype/profile naming --- cgi-bin/core/doctype/profile/profile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cgi-bin/core/doctype/profile/profile.py b/cgi-bin/core/doctype/profile/profile.py index 60388f039f..d4684a7bf3 100644 --- a/cgi-bin/core/doctype/profile/profile.py +++ b/cgi-bin/core/doctype/profile/profile.py @@ -25,7 +25,8 @@ class DocType: if not validate_email_add(self.doc.email): msgprint("%s is not a valid email id" % self.doc.email) raise Exception - self.doc.name = self.doc.email + + self.doc.name = self.doc.email def on_update(self): # owner is always name