def handle(self, *args, **options): if not BOT['SLACK']['MSG_BDAY']: return t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) try: msg_handles, ids, names = [], [], [] today_str = datetime.date.today().strftime('%m/%d') member = Member.objects.filter(is_alumni=0, bday=today_str) for ppl in member: (who, _) = find_slack_id(ppl.first_name) if who: send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who msg_handles.append( (send_to, '', [{"fallback": 'BDay', "mrkdwn_in": ["text"], "color": "ff912e", "text": '*Happy Birthday*, _%s_!' % ppl.first_name}]) ) ids.append(who) names.append(ppl.first_name) if ids and (not DEBUG): msg_handles.append( ('#general', '', [{"fallback": 'BDay', "mrkdwn_in": ["text"], "color": "ff912e", "text": '*Happy Birthday* to _%s_! %s' % (' and '.join(names), ', '.join( ['<@' + id + '>' for id in ids] ))}]) ) except Exception: send_error_slack(traceback.format_exc(), 'Birthday Wishes', ' '.join(sys.argv), 'log_cron_bday.log') self.stdout.write("Finished with \033[41mERROR\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: for h in msg_handles: send_notify_slack(*h) if '@' in h[0]: self.stdout.write('\033[92mSUCCESS\033[0m: PM\'ed birthday wish to \033[94m%s\033[0m in Slack.' % h[0]) if (not DEBUG) and msg_handles: send_notify_slack(SLACK['ADMIN_NAME'], '', [{"fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled *Birthday Wishes* sent to `%s` @ _%s_\n' % (' '.join(ids), time.ctime())}]) self.stdout.write("Finished with \033[92mSUCCESS\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) if options['item']: is_apache = 'apache' in options['item'] is_config = 'config' in options['item'] is_mysql = 'mysql' in options['item'] is_static = 'static' in options['item'] else: is_apache, is_config, is_mysql, is_static = True, True, True, True d = time.strftime( '%Y%m%d') # datetime.datetime.now().strftime('%Y%m%d') gdrive_dir = 'echo' if DEBUG else 'cd %s' % APACHE_ROOT prefix = '_DEBUG' if DEBUG else '' flag = False if is_mysql: t = time.time() self.stdout.write("#1: Uploading MySQL database...") try: subprocess.check_call( '%s && drive upload -f %s/backup/backup_mysql.tgz -t %s_%s_mysql%s.tgz' % (gdrive_dir, MEDIA_ROOT, env('SERVER_NAME'), d, prefix), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: send_error_slack(traceback.format_exc(), 'Upload MySQL Database', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mMySQL\033[0m database uploaded." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_static: t = time.time() self.stdout.write("#2: Uploading static files...") try: subprocess.check_call( '%s && drive upload -f %s/backup/backup_static.tgz -t %s_%s_static%s.tgz' % (gdrive_dir, MEDIA_ROOT, env('SERVER_NAME'), d, prefix), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: send_error_slack(traceback.format_exc(), 'Upload Static Files', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mstatic\033[0m files uploaded." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_apache: t = time.time() self.stdout.write("#3: Uploading apache2 settings...") try: subprocess.check_call( '%s && drive upload -f %s/backup/backup_apache.tgz -t %s_%s_apache%s.tgz' % (gdrive_dir, MEDIA_ROOT, env('SERVER_NAME'), d, prefix), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: send_error_slack(traceback.format_exc(), 'Upload Apache2 Settings', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mapache2\033[0m settings uploaded." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_config: t = time.time() self.stdout.write("#4: Uploading config settings...") try: subprocess.check_call( '%s && drive upload -f %s/backup/backup_config.tgz -t %s_%s_config%s.tgz' % (gdrive_dir, MEDIA_ROOT, env('SERVER_NAME'), d, prefix), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: send_error_slack(traceback.format_exc(), 'Upload Config Settings', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mconfig\033[0m settings uploaded." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) t = time.time() self.stdout.write("#5: Removing obsolete backups...") try: old = (datetime.date.today() - datetime.timedelta(days=KEEP_BACKUP) ).strftime('%Y-%m-%dT00:00:00') list_mysql = subprocess.Popen( "%s && drive list -q \"title contains '%s_' and (title contains '_mysql.tgz' or title contains '_mysql_DEBUG.tgz') and modifiedDate <= '%s'\"| awk '{printf $1\" \"}'" % (gdrive_dir, env('SERVER_NAME'), old), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split()[1:] list_static = subprocess.Popen( "%s && drive list -q \"title contains '%s_' and (title contains '_static.tgz' or title contains '_static_DEBUG.tgz') and modifiedDate <= '%s'\"| awk '{ printf $1\" \"}'" % (gdrive_dir, env('SERVER_NAME'), old), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split()[1:] list_apache = subprocess.Popen( "%s && drive list -q \"title contains '%s_' and (title contains '_apache.tgz' or title contains '_apache_DEBUG.tgz') and modifiedDate <= '%s'\"| awk '{ printf $1\" \"}'" % (gdrive_dir, env('SERVER_NAME'), old), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split()[1:] list_config = subprocess.Popen( "%s && drive list -q \"title contains '%s_' and (title contains '_config.tgz' or title contains '_config_DEBUG.tgz') and modifiedDate <= '%s'\"| awk '{ printf $1\" \"}'" % (gdrive_dir, env('SERVER_NAME'), old), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split()[1:] list_all = list_mysql + list_static + list_apache + list_config except Exception: send_error_slack(traceback.format_exc(), 'Check Obsolete Backup Files', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True for id in list_all: try: subprocess.check_call('%s && drive info -i %s' % (gdrive_dir, id), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) subprocess.check_call('%s && drive delete -i %s' % (gdrive_dir, id), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: send_error_slack(traceback.format_exc(), 'Remove Obsolete Backup Files', ' '.join(sys.argv), 'log_cron_gdrive.log') flag = True if not flag: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94m%s\033[0m obsolete backup files removed." % len(list_all)) self.stdout.write("Time elapsed: %.1f s.\n" % (time.time() - t)) if flag: self.stdout.write("Finished with errors!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: if DEBUG: self.stdout.write("\033[94m Uploaded to Google Drive. \033[0m") else: (t_cron, d_cron, t_now) = get_date_time('gdrive') gdrive_list = subprocess.Popen( "%s && drive list -q \"title contains '%s_' and title contains '.tgz'\"" % (gdrive_dir, env('SERVER_NAME')), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split( )[4:] html = 'File\t\t\t\tTime\t\t\t\tSize\n\n' for i in xrange(0, len(gdrive_list), 6): html += '%s\t\t%s %s\t\t%s %s\n' % ( gdrive_list[i + 1], gdrive_list[i + 4], gdrive_list[i + 5], gdrive_list[i + 2], gdrive_list[i + 3]) if IS_SLACK: if (not DEBUG) and BOT['SLACK']['ADMIN']['MSG_GDRIVE']: send_notify_slack(SLACK['ADMIN_NAME'], '', [{ "fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled weekly *Gdrive Sync* finished @ _%s_\n' % time.ctime() }]) # send_notify_slack(SLACK['ADMIN_NAME'], '>```%s```\n' % html, '') else: send_notify_emails( '{%s} SYSTEM: Weekly Sync Notice' % env('SERVER_NAME'), 'This is an automatic email notification for the success of scheduled weekly sync of the %s Website backup contents to Google Drive account.\n\nThe crontab job is scheduled at %s (UTC) on every %sday.\n\nThe last system backup was performed at %s (PDT).\n\n%s\n\n%s Website Admin\n' % (env('SERVER_NAME'), t_cron, d_cron, t_now, html, env('SERVER_NAME'))) get_backup_stat() self.stdout.write("Admin Backup Statistics refreshed.") self.stdout.write("All done successfully!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) if options['interval']: if options['interval'][0].endswith('ly'): flag = options['interval'][0] else: flag = options['interval'][0] + 'ly' else: self.stdout.write( '\033[41mERROR\033[0m: \033[94minterval\033[0m not found.') self.stdout.write("Finished with \033[41mERROR\033[0m!") sys.exit(1) if flag in ['monthly', 'quarterly']: if datetime.utcnow().date().day > 7: return try: result = dash_duty(0) ppls = result['ppls'] result = dash_schedule(0) if flag == 'weekly': day_1 = ( result['weekday'] - int(BOT['SLACK']['REMINDER']['DAY_BEFORE_REMINDER_1'])) day_2 = ( result['weekday'] - int(BOT['SLACK']['REMINDER']['DAY_BEFORE_REMINDER_2'])) if day_1 < 0: day_1 += 7 if day_2 < 0: day_2 += 7 if datetime.utcnow().date().isoweekday() == day_1: if result['this']['type'] != 'N/A': if BOT['SLACK']['DUTY']['MONTH']['MSG_BREAKFAST']: self.compose_msg(ppls[flag]['breakfast'], 'Breakfast', flag, ' to _Group Meeting_ tomorrow') if result['this']['type'] == 'ES': if BOT['SLACK']['DUTY']['ETERNA']['MSG_MIC']: self.compose_msg( ppls['monthly']['eterna'], 'Eterna Microphone Setup', flag, ' for the upcoming _Eterna Open Group Meeting_. Please arrive *30 min* early. The instructions are <https://docs.google.com/document/d/1bh5CYBklIdZl65LJDsBffC8m8J_3jKf4FY1qiYjRIw8/edit|here>' ) elif datetime.utcnow().date().isoweekday() == day_2: offset = int( BOT['SLACK']['REMINDER']['DAY_BEFORE_REMINDER_2']) year = (datetime.utcnow() + timedelta(days=offset)).date().year date = datetime.strptime( "%s %s" % (dash_schedule(0)['this']['date'], year), '%b %d %Y') if (datetime.utcnow() + timedelta(days=offset)).date() != date.date(): (who_id, _) = find_slack_id( ppls['weekly']['group meeting']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id send_notify_slack(send_to, '', [{ "fallback": 'ERROR', "mrkdwn_in": ["text"], "color": "warning", "text": 'Mismatch in Schedule Spreadsheet date. It seems to be not up-to-date. Please fix the Spreadsheet immediately!' }]) if result['this']['type'] == 'ES': who = result['this']['who'] (who_id, _) = find_slack_id(who) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id if BOT['SLACK']['REMINDER']['ES']['REMINDER_2']: (who_id2, _) = find_slack_id( ppls['monthly']['eterna']['main']) self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "c28fdd", "text": '*LAB DUTY*: Just a reminder for sending a description of your upcoming _Eterna Open Group Meeting_ to <%s> and <@%s> for releasing news on both DasLab Website and EteRNA broadcast.' % (SLACK['ADMIN_NAME'], who_id2) }])) if BOT['SLACK']['DUTY']['ETERNA']['MSG_BROADCAST']: self.compose_msg( ppls['monthly']['eterna'], 'Eterna Broadcast Posting', flag, ' for _Eterna Open Group Meeting_. If _%s_ <@%s> hasn\'t send out descriptions, please ask him/her!' % (who, who_id)) if BOT['SLACK']['DUTY']['ETERNA']['MSG_NEWS']: (who_id, _) = find_slack_id( ppls['monthly']['website']['main']) send_to = SLACK[ 'ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "c28fdd", "text": '*LAB DUTY*: Just a reminder for posting news on lab website about the upcoming _Eterna Open Group Meeing_ on *%s* by _%s_ <@%s>.' % (result['this']['date'], who, who_id) }])) elif result['this']['type'] == 'JC': if BOT['SLACK']['REMINDER']['JC']['REMINDER_2']: who = result['this']['who'] (who_id, _) = find_slack_id(who) send_to = SLACK[ 'ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "c28fdd", "text": '*LAB DUTY*: Just a reminder for posting your paper of choice for the upcoming _Journal Club_ to `#general`.' }])) else: return elif datetime.utcnow().date().isoweekday( ) == result['weekday']: if BOT['SLACK']['DUTY']['MONTH']['MSG_SCHEDULE']: self.compose_msg( ppls[flag]['group meeting'], 'Meeting Scheduling', flag, ' (move current down to bottom, and move next up top)' ) else: return elif flag == 'monthly': if BOT['SLACK']['DUTY']['MONTH']['MSG_AWS']: self.compose_msg(ppls[flag]['amazon'], 'Amazon Web Services', flag, '') if BOT['SLACK']['DUTY']['MONTH']['MSG_WEBSITE']: self.compose_msg(ppls[flag]['website'], 'Website', flag, '') if BOT['SLACK']['DUTY']['MONTH']['MSG_BDAY']: self.compose_msg(ppls[flag]['birthday'], 'Birthday Celebrations', flag, '') day = datetime.utcnow().date() fields = [] for ppl in Member.objects.filter(is_alumni=0).exclude( bday__isnull=True).order_by('bday'): temp = datetime.strptime( '%s/%s' % (day.year, ppl.bday), '%Y/%m/%d') is_upcoming = (temp <= datetime.utcnow() + timedelta( days=60)) and (temp >= datetime.utcnow()) if day.month >= 10: temp = datetime.strptime( '%s/%s' % (day.year + 1, ppl.bday), '%Y/%m/%d') is_upcoming = is_upcoming or ( (temp <= datetime.utcnow() + timedelta(days=60)) and (temp >= datetime.utcnow())) if is_upcoming: fields.append({ 'title': ppl.full_name(), 'value': ppl.bday, 'short': True }) if not fields: fields.append({ 'title': 'Nobody', 'value': '_within next 60 days_', 'short': True }) birthday = ppls[flag]['birthday'] (who_main, _) = find_slack_id(birthday['main']) (who_bkup, _) = find_slack_id(birthday['backup']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_main self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "ff912e", "text": '_Upcoming Birthdays_:', "fields": fields }])) if datetime.utcnow().date().month == 11: (who_id, _) = find_slack_id(ppls['quarterly']['github']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "3ed4e7", "text": '*REMINDER*: Renewal of `Dropbox` membership _annually_. Please renew and check the payment status.' }])) self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "3ed4e7", "text": '*REMINDER*: Renewal of `GitHub` membership _annually_. Please renew and check the payment status.' }])) elif datetime.utcnow().date().month == 8: (who_id, _) = find_slack_id(ppls[flag]['amazon']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append((send_to, '', [{ "fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "3ed4e7", "text": '*REMINDER*: Renewal of `AWS` reserved instances [all upfront] _annually_. Please renew and check the payment status.' }])) elif flag == 'quarterly': if BOT['SLACK']['DUTY']['QUARTER']['MSG_TRIP']: self.compose_msg(ppls[flag]['lab trips'], 'Lab Outing / Trips', flag, '') if BOT['SLACK']['DUTY']['QUARTER']['MSG_GIT']: self.compose_msg(ppls[flag]['github'], 'Mailing / Slack / GitHub', flag, '') except Exception: print traceback.format_exc() send_error_slack(traceback.format_exc(), 'Send Duty Reminders', ' '.join(sys.argv), 'log_cron_duty.log') self.stdout.write("Finished with \033[41mERROR\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: for h in self.msg_handles: send_notify_slack(*h) if '@' in h[0]: self.stdout.write( '\033[92mSUCCESS\033[0m: PM\'ed duty reminder to \033[94m%s\033[0m in Slack.' % h[0]) if (not DEBUG) and len(self.msg_handles): send_notify_slack(SLACK['ADMIN_NAME'], '', [{ "fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled %s *Duty Reminder* finished @ _%s_\n' % (flag, time.ctime()) }]) self.stdout.write("Finished with \033[92mSUCCESS\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): if not BOT['SLACK']['IS_FLASH_SETUP']: return t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) flag_mismatch = False try: result = dash_duty(0) ppls = result['ppls'] result = dash_schedule(0) offset_1 = int(BOT['SLACK']['REMINDER']['DAY_BEFORE_REMINDER_1']) offset_2 = int(BOT['SLACK']['REMINDER']['DAY_BEFORE_REMINDER_2']) day_1 = (result['weekday'] - offset_1) if day_1 < 0: day_1 += 7 if datetime.utcnow().date().isoweekday() != day_1: return types = {'ES': 'EteRNA Special', 'GM': 'Group Meeting', 'JC': 'Journal Club', 'FS': 'Flash Slides'} year = (datetime.utcnow() + timedelta(days=offset_1)).date().year date = datetime.strptime("%s %s" % (result['this']['date'], year), '%b %d %Y') if result['this']['type'] == 'N/A': msg_this = 'Hi all,\n\nThis is a reminder that there will be *`NO Meeting`* this week' if result['this']['note']: msg_this += ' due to: _%s_.' % result['this']['note'] else: msg_this += '.' send_to = SLACK['ADMIN_NAME'] if DEBUG else "#general" self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text"], "color": "good", "title": 'Group Meeting Reminder', "text": msg_this, "thumb_url": 'https://daslab.stanford.edu/site_media/images/group/logo_bot.jpg'}]) ) self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation skipped (N/A for this week: \033[94m%s\033[0m).' % datetime.strftime(date, '%b %d %Y')) else: type_this = types[result['this']['type']] if (datetime.utcnow() + timedelta(days=offset_1)).date() != date.date(): (who_id, _) = find_slack_id(ppls['weekly']['group meeting']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id send_notify_slack(send_to, '', [{"fallback": 'ERROR', "mrkdwn_in": ["text"], "color": "warning", "text": 'Mismatch in Schedule Spreadsheet date. It seems to be not up-to-date.\nFlash Slide has *`NOT`* been setup yet for this week! Please investigate and fix the setup immediately.'}]) flag_mismatch = True sys.exit(1) title = 'Flash Slides: %s' % datetime.strftime(date, '%b %d %Y') access_token = requests.post('https://www.googleapis.com/oauth2/v3/token?refresh_token=%s&client_id=%s&client_secret=%s&grant_type=refresh_token' % (DRIVE['REFRESH_TOKEN'], DRIVE['CLIENT_ID'], DRIVE['CLIENT_SECRET'])).json()['access_token'] temp = requests.post('https://www.googleapis.com/drive/v2/files/%s/copy?access_token=%s' % (DRIVE['TEMPLATE_PRESENTATION_ID'], access_token), json={"title": "%s" % title}) ppt_id = temp.json()['id'] temp = requests.post('https://www.googleapis.com/drive/v2/files/%s/permissions?sendNotificationEmails=false&access_token=%s' % (ppt_id, access_token), json={"role": "writer", "type": "group", "value": "*****@*****.**"}) if temp.status_code != 200: self.stdout.write('\033[41mERROR\033[0m: Google Presentation (\033[94m%s\033[0m) created but NOT shared.' % ppt_id) if IS_SLACK: (who_id, _) = find_slack_id(ppls['weekly']['flash slide']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id send_notify_slack(send_to, '', [{"fallback": 'ERROR', "mrkdwn_in": ["text"], "color": "warning", "text": 'FlashSlide was created but failed on sharing to the group.\nFlash Slide setup is *`NOT`* complete! Please investigate and fix the setup immediately.'}]) send_error_slack(temp.json(), 'Group Meeting Setup', ' '.join(sys.argv), 'log_cron_cache.log') else: self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation (\033[94m%s\033[0m) created and shared.' % ppt_id) flash_slides = FlashSlide(date=date, link='https://docs.google.com/presentation/d/%s/edit#slide=id.p' % ppt_id) flash_slides.save() self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation (\033[94m%s\033[0m) saved in MySQL.' % ppt_id) flag = result['this']['note'].lower().replace(' ', '') name = result['this']['who'] ids = [] if '/' in name or '&' in name: names = name.replace('/', '*|*').replace('&', '*|*').replace(' ', '').split('*|*') elif name.strip() and name != '-': names = [name] else: names = [] if name: for name in names: (who_id, sunet_id) = find_slack_id(name) if flag == 'endofrotationtalk' and BOT['SLACK']['REMINDER']['ROT']['REMINDER_1']: if GROUP.find_type(sunet_id) == 'roton': msg_who = 'Just a reminder: Please send your presentation to %s (site admin) for `archiving` *after* your presentation this _%s_.' % (SLACK['ADMIN_NAME'], datetime.strftime(date, '%A')) ids.append('_' + name + '_ <@' + who_id + '>') send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text"], "color": "good", "text": msg_who}])) else: if sunet_id == 'none': self.stdout.write('\033[41mERROR\033[0m: rotation student (\033[94m%s\033[0m) not found.' % name) elif sunet_id == 'ambiguous': self.stdout.write('\033[41mERROR\033[0m: rotation student (\033[94m%s\033[0m) is ambiguate (more than 1 match).' % name) else: self.stdout.write('\033[41mERROR\033[0m: rotation student (\033[94m%s\033[0m) not available in database.' % name) elif GROUP.find_type(sunet_id) in ['admin', 'group', 'alumni', 'other']: ids.append('_' + name + '_ <@' + who_id + '>') else: ids.append('_%s_' % name) else: ids = ['_(None)_'] (who_id, _) = find_slack_id(ppls['monthly']['website']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id if flag == 'endofrotationtalk' and BOT['SLACK']['REMINDER']['ROT']['REMINDER_ADMIN']: self.msg_handles.append( (send_to, '', [{"fallback": 'REMINDER', "mrkdwn_in": ["text"], "color": "warning", "text": '*REMINDER*: Add *RotationStudent* entry for _%s_.' % datetime.strftime(date, '%b %d %Y (%a)')}]) ) if result['this']['type'] == 'JC' and BOT['SLACK']['REMINDER']['JC']['REMINDER_ADMIN']: self.msg_handles.append( (send_to, '', [{"fallback": 'REMINDER', "mrkdwn_in": ["text"], "color": "warning", "text": '*REMINDER*: Add *JournalClub* entry for _%s_.' % datetime.strftime(date, '%b %d %Y (%a)')}]) ) elif result['this']['type'] == 'ES' and BOT['SLACK']['REMINDER']['ES']['REMINDER_ADMIN']: self.msg_handles.append( (send_to, '', [{"fallback": 'REMINDER', "mrkdwn_in": ["text"], "color": "warning", "text": '*REMINDER*: Add *EternaYoutube* entry for _%s_.' % datetime.strftime(date, '%b %d %Y (%a)')}]) ) send_to = SLACK['ADMIN_NAME'] if DEBUG else "#general" super_prefix = '*Extended/Super* ' if result['this']['type'] == 'FS' else '' self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "good", "title": 'Group Meeting Reminder', "text": 'Hi all,\n\nThis is a reminder that group meeting will be %s*`%s`* for this week.\n' % (super_prefix, type_this), "thumb_url": 'https://daslab.stanford.edu/site_media/images/group/logo_bot.jpg', "fields": [{'title': 'Date', 'value': '_%s_' % datetime.strftime(date, '%b %d %Y (%a)'), 'short': True}, {'title': 'Time & Place', 'value': '_%s @ %s_' % (result['time']['start'], result['place']), 'short': True}, {'title': 'Type', 'value': '`%s`' % type_this, 'short': True}, {'title': 'Presenter', 'value': '%s' % ', \n'.join(ids), 'short': True}] }]) ) self.msg_handles.append( (send_to, '', [{"fallback": '%s' % title, "mrkdwn_in": ["text"], "color": "warning", "title": '%s' % title, "text": '*<https://docs.google.com/presentation/d/%s/edit#slide=id.p>*\nA <https://daslab.stanford.edu/group/flash_slide/|full list> of Flash Slide links is available on the DasLab Website.' % ppt_id}]) ) if result['last']['note'].lower().replace(' ', '') == 'endofrotationtalk' and BOT['SLACK']['REMINDER']['ROT']['REMINDER_2']: (who_id, _) = find_slack_id(ppls['quarterly']['github']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append( (send_to, '', [{"fallback": 'REMINDER', "mrkdwn_in": ["text"], "color": "warning", "text": '*REMINDER*: Revoke permissions (_Group Website_ and _Slack Membership_) of recent finished *RotationStudent*.'}]) ) if result['next']['type'] == 'N/A': msg_next = 'For next week, there will be *`NO Meeting`*' if result['next']['note']: msg_next += ' due to: _%s_.' % result['next']['note'] else: msg_next += '.' send_to = SLACK['ADMIN_NAME'] if DEBUG else "#general" self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text"], "color": "439fe0", "text": msg_next}]) ) else: type_next = types[result['next']['type']] year = (datetime.utcnow() + timedelta(days=(offset_1 + 7))).date().year date = datetime.strptime("%s %s" % (result['next']['date'], year), '%b %d %Y') msg_who = 'Just a reminder that you are up for `%s` *next* _%s_ (*%s*).\n' % (type_next, datetime.strftime(date, '%A'), datetime.strftime(date, '%b %d')) if result['next']['type'] == 'JC' and BOT['SLACK']['REMINDER']['JC']['REMINDER_1']: date = (datetime.utcnow() + timedelta(days=(offset_1 + 7 - offset_2))).date() msg_who += ' Please post your paper of choice to the group `#general` channel by *next* _%s_ (*%s*).\n' % (datetime.strftime(date, '%A'), datetime.strftime(date, '%b %d')) elif result['next']['type'] == 'ES' and BOT['SLACK']['REMINDER']['ES']['REMINDER_1']: date = (datetime.utcnow() + timedelta(days=(offset_1 + 7 - offset_2))).date() msg_who += ' Please post a brief description of the topic to the group `#general` channel by *next* _%s_ (*%s*) to allow time for releasing news on both DasLab Website and EteRNA broadcast.\n' % (datetime.strftime(date, '%A'), datetime.strftime(date, '%b %d')) name = result['next']['who'] ids = [] if '/' in name or '&' in name: names = name.replace('/', '*|*').replace('&', '*|*').replace(' ', '').split('*|*') elif name.strip() and name != '-': names = [name] else: names = [] if name: for name in names: (who_id, sunet_id) = find_slack_id(name) if GROUP.find_type(sunet_id) != 'unknown': ids.append('_' + name + '_ <@' + who_id + '>') if (result['next']['type'] == 'JC' and BOT['SLACK']['REMINDER']['JC']['REMINDER_1']) or (result['next']['type'] == 'ES' and BOT['SLACK']['REMINDER']['ES']['REMINDER_1']) or (result['next']['type'] == 'GM' and (BOT['SLACK']['REMINDER']['JC']['REMINDER_1'] or BOT['SLACK']['REMINDER']['ES']['REMINDER_1'] or BOT['SLACK']['REMINDER']['ROT']['REMINDER_1'])): send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id self.msg_handles.append( (send_to, '', [{"fallback":'Reminder', "mrkdwn_in": ["text"], "color":"good", "text":msg_who}])) else: if sunet_id == 'none': self.stdout.write('\033[41mERROR\033[0m: member (\033[94m%s\033[0m) not found.' % name) elif sunet_id == 'ambiguous': self.stdout.write('\033[41mERROR\033[0m: member (\033[94m%s\033[0m) is ambiguate (more than 1 match).' % name) else: self.stdout.write('\033[41mERROR\033[0m: member (\033[94m%s\033[0m) not available in database.' % name) else: ids.append('_%s_' % name) else: ids = ['_(None)_'] send_to = SLACK['ADMIN_NAME'] if DEBUG else "#general" date = datetime.strptime("%s %s" % (result['next']['date'], year), '%b %d %Y') self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text", "fields"], "color": "439fe0", "text": 'For next week: \n', "thumb_url": 'https: //daslab.stanford.edu/site_media/images/group/logo_bot.jpg', "fields": [{'title': 'Date', 'value': '_%s_' % datetime.strftime(date, '%b %d %Y (%a)'), 'short': True}, {'title': 'Time & Place', 'value': '_%s @ %s_' % (result['time']['start'], result['place']), 'short': True}, {'title': 'Type', 'value': '`%s`' % type_next, 'short': True}, {'title': 'Presenter', 'value': '%s' % ', \n'.join(ids), 'short': True}] }]) ) (who_id, _) = find_slack_id(ppls['weekly']['group meeting']['main']) self.msg_handles.append( (send_to, '', [{"fallback": 'Reminder', "mrkdwn_in": ["text"], "color": "danger", "text": 'The <https://daslab.stanford.edu/group/schedule/|full schedule> is available on the DasLab Website. For questions regarding the schedule, please contact <@%s>. Thanks for your attention.\n\nSite Admin: <%s>' % (who_id, SLACK['ADMIN_NAME'])}]) ) except Exception: if flag_mismatch: return send_error_slack(traceback.format_exc(), 'Group Meeting Setup', ' '.join(sys.argv), 'log_cron_meeting.log') if result['this']['type'] != 'N/A': year = (datetime.utcnow() + timedelta(days=offset_1)).date().year date = datetime.strptime("%s %s" % (result['this']['date'], year), '%b %d %Y') FlashSlide.objects.get(date=date).delete() requests.delete('https://www.googleapis.com/drive/v2/files/%s/?access_token=%s' % (ppt_id, access_token)) self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation (\033[94m%s\033[0m) deleted.' % ppt_id) self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation (\033[94m%s\033[0m) removed in MySQL.' % ppt_id) if IS_SLACK: (who_id, _) = find_slack_id(ppls['weekly']['flash slide']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id send_notify_slack(send_to, '', [{"fallback": 'ERROR', "mrkdwn_in": ["text"], "color": "warning", "text": 'FlashSlide table in MySQL database, presentation in Google Drive, and posted messages in Slack are rolled back.\nFlash Slide has *`NOT`* been setup yet for this week! Please investigate and fix the setup immediately.'}]) else: send_notify_emails('{%s} ERROR: Weekly Meeting Setup' % env('SERVER_NAME'), 'This is an automatic email notification for the failure of scheduled weekly flash slides setup. The following error occurred:\n\n%s\n\n%s\n\nFlashSlide table in MySQL database, presentation in Google Drive, and posted messages in Slack are rolled back.\n\n** Flash Slide has NOT been setup yet for this week! Please investigate and fix the setup immediately.\n\n%s Website Admin' % (ts, err, env('SERVER_NAME'))) self.stdout.write("Finished with \033[41mERROR\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: for h in self.msg_handles: send_notify_slack(*h) if '@' in h[0]: self.stdout.write('\033[92mSUCCESS\033[0m: PM\'ed reminder to \033[94m%s\033[0m in Slack.' % h[0]) self.stdout.write('\033[92mSUCCESS\033[0m: Google Presentation posted in Slack.') self.stdout.write('\033[92mSUCCESS\033[0m: Meeting Reminder posted in Slack.') if (not DEBUG): (who_id, _) = find_slack_id(ppls['weekly']['flash slide']['main']) send_to = SLACK['ADMIN_NAME'] if DEBUG else '@' + who_id send_notify_slack(send_to, '', [{"fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled weekly *Flash Slides Setup* finished @ _%s_. Please also paste the link in the Schedule Spreadsheet.\n' % time.ctime()}]) self.stdout.write("Finished with \033[92mSUCCESS\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) if options['item']: is_apache = 'apache' in options['item'] is_config = 'config' in options['item'] is_mysql = 'mysql' in options['item'] is_static = 'static' in options['item'] else: is_apache, is_config, is_mysql, is_static = True, True, True, True flag = False if is_mysql: t = time.time() self.stdout.write("#1: Restoring MySQL database...") try: tarfile.open('%s/backup/backup_mysql.tgz' % MEDIA_ROOT, 'r:gz').extractall() subprocess.check_call( 'cat %s/backup/backup_mysql | mysql -u %s -p%s %s' % (MEDIA_ROOT, env.db()['USER'], env.db()['PASSWORD'], env.db()['NAME']), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) os.remove('%s/backup/backup_mysql' % MEDIA_ROOT) except Exception: send_error_slack(traceback.format_exc(), 'Restore MySQL Database', ' '.join(sys.argv), 'log_cron_restore.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mMySQL\033[0m database overwritten." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_static: t = time.time() self.stdout.write("#2: Restoring static files...") try: shutil.rmtree('%s/backup/data' % MEDIA_ROOT) tarfile.open('%s/backup/backup_static.tgz' % MEDIA_ROOT, 'r:gz').extractall() shutil.rmtree('%s/data' % MEDIA_ROOT) shutil.move('%s/backup/data' % MEDIA_ROOT, '%s' % MEDIA_ROOT) shutil.rmtree('%s/backup/data' % MEDIA_ROOT) if (not DEBUG): subprocess.check_call('%s/util_chmod.sh' % MEDIA_ROOT, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception: send_error_slack(traceback.format_exc(), 'Restore Static Files', ' '.join(sys.argv), 'log_cron_restore.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mstatic\033[0m files overwritten." ) self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_apache: t = time.time() self.stdout.write("#3: Restoring apache2 settings...") try: shutil.rmtree('%s/backup/apache2' % MEDIA_ROOT) tarfile.open('%s/backup/backup_apache.tgz' % MEDIA_ROOT, 'r:gz').extractall() shutil.rmtree('/etc/apache2') shutil.move('%s/backup/apache2' % MEDIA_ROOT, '/etc/apache2') shutil.rmtree('%s/backup/apache2' % MEDIA_ROOT) if (not DEBUG): subprocess.check_call('apache2ctl restart', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception: send_error_slack(traceback.format_exc(), 'Restore Apache2 Settings', ' '.join(sys.argv), 'log_cron_restore.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mapache2\033[0m settings overwritten." ) self.stdout.write("Time elapsed: %.1f s.\n" % (time.time() - t)) if is_config: t = time.time() self.stdout.write("#4: Restoring config settings...") try: shutil.rmtree('%s/backup/config' % MEDIA_ROOT) tarfile.open('%s/backup/backup_config.tgz' % MEDIA_ROOT, 'r:gz').extractall() shutil.rmtree('%s/config' % MEDIA_ROOT) shutil.move('%s/backup/config' % MEDIA_ROOT, '%s/config' % MEDIA_ROOT) shutil.rmtree('%s/backup/config' % MEDIA_ROOT) if (not DEBUG): subprocess.check_call('apache2ctl restart', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception: send_error_slack(traceback.format_exc(), 'Restore Config Settings', ' '.join(sys.argv), 'log_cron_restore.log') flag = True else: self.stdout.write( " \033[92mSUCCESS\033[0m: \033[94mconfig\033[0m settings overwritten." ) self.stdout.write("Time elapsed: %.1f s.\n" % (time.time() - t)) if flag: self.stdout.write("Finished with errors!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: self.stdout.write("All done successfully!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): flag = (options['force'] == 1) if options['force'] else False if not (BOT['SLACK']['IS_VERSION'] or flag): return t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) d = time.strftime( '%Y%m%d') # datetime.datetime.now().strftime('%Y%m%d') t = time.time() (ver, syst) = ({}, {}) self.stdout.write("Checking system versions...") try: cpu = subprocess.Popen( "uptime | sed 's/.*: //g' | sed 's/,/ \//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['linux'] = subprocess.Popen( "uname -r | sed 's/[a-z\-]//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['python'] = '%s.%s.%s' % (sys.version_info.major, sys.version_info.minor, sys.version_info.micro) ver['django'] = subprocess.Popen( 'python -c "import django; print django.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show django-crontab', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['django_crontab'] = subprocess.Popen( "head -2 %s | tail -1 | sed 's/.*: //g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show django-environ', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['django_environ'] = subprocess.Popen( "head -2 %s | tail -1 | sed 's/.*: //g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['mysql'] = subprocess.Popen( "mysql --version | sed 's/,.*//g' | sed 's/.*Distrib //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['apache'] = subprocess.Popen( "apachectl -v | head -1 | sed 's/.*\///g' | sed 's/[a-zA-Z \(\)]//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: ver['mod_wsgi'] = 'N/A' else: ver['mod_wsgi'] = subprocess.Popen( "apt-cache show libapache2-mod-wsgi | grep Version | head -1 | sed 's/.*: //g' | sed 's/-.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: ver['mod_webauth'] = 'N/A' else: ver['mod_webauth'] = subprocess.Popen( "apt-cache show libapache2-webauth | grep Version | head -1 | sed 's/.*: //g' | sed 's/-.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['openssl'] = subprocess.Popen( "openssl version | sed 's/.*OpenSSL //g' | sed 's/[a-z].*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: ver['wallet'] = 'N/A' else: ver['wallet'] = subprocess.Popen( 'wallet -v | sed %s' % "'s/.*wallet //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver_jquery = open( os.path.join(MEDIA_ROOT, 'media/js/jquery.min.js'), 'r').readline() ver['jquery'] = ver_jquery[ver_jquery.find('v') + 1:ver_jquery.find('|')].strip() ver_bootstrap = open( os.path.join(MEDIA_ROOT, 'media/js/bootstrap.min.js'), 'r').readlines() ver_bootstrap = ver_bootstrap[1] ver['bootstrap'] = ver_bootstrap[ver_bootstrap.find('v') + 1:ver_bootstrap.find('(')].strip( ) ver['django_suit'] = subprocess.Popen( 'python -c "import suit; print suit.VERSION"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['django_adminplus'] = subprocess.Popen( 'python -c "import adminplus; print adminplus.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: ver['django_filemanager'] = '0.0.2' else: open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show django-filemanager', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['django_filemanager'] = subprocess.Popen( "head -2 %s | tail -1 | sed 's/.*: //g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver_head = open( os.path.join(MEDIA_ROOT, 'media/js/head.load.min.js'), 'r').readline() ver['head'] = ver_head[ver_head.find('v') + 1:ver_head.rfind('*')].strip() ver_fullcall = open( os.path.join(MEDIA_ROOT, 'media/js/fullcalendar.min.js'), 'r').readlines() ver_fullcall = ver_fullcall[1] ver['fullcal'] = ver_fullcall[ver_fullcall.find('v') + 1:].strip() ver_moment = open( os.path.join(MEDIA_ROOT, 'media/js/moment.min.js'), 'r').readlines() ver_moment = ver_moment[1] ver['moment'] = ver_moment[ver_moment.find(':') + 2:].strip() # f = open(os.path.join(MEDIA_ROOT, 'media/js/dropzone.min.js'), 'r') # ver_dropz = ''.join(f.readlines()) # ver_dropz = ver_dropz[ver_dropz.find('.version="') + 10 : ver_dropz.find('.version="') + 18] # ver += ver_dropz[:ver_dropz.find('"')] + '\t' # f.close() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show icalendar', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['icalendar'] = subprocess.Popen( 'head -2 %s | tail -1 | sed %s' % (os.path.join(MEDIA_ROOT, 'data/temp.txt'), "'s/.*: //g'"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['gviz_api'] = '1.8.2' open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'ssh -V', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['ssh'] = subprocess.Popen( "sed 's/^OpenSSH\_//g' %s | sed 's/U.*//' | sed 's/,.*//g' | sed 's/[a-z]/./g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['git'] = subprocess.Popen( "git --version | sed 's/.*version //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['nano'] = subprocess.Popen( "nano --version | head -1 | sed 's/.*version //g' | sed 's/(.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['gdrive'] = subprocess.Popen( "drive -v | sed 's/.*v//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: ver['pandoc'] = subprocess.Popen( "pandoc --version | head -1 | sed 's/.*pandoc //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() else: ver['pandoc'] = subprocess.Popen( "dpkg -l pandoc | tail -1 | sed 's/[a-z ]//g' | sed 's/-.*//g' | sed 's/~.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['curl'] = subprocess.Popen( "curl --version | head -1 | sed 's/.*curl //g' | sed 's/ (.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['boto'] = subprocess.Popen( 'python -c "import boto; print boto.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show pygithub', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['pygithub'] = subprocess.Popen( "head -2 %s | tail -1 | sed 's/.*: //g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'pip show slacker', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['slacker'] = subprocess.Popen( 'head -2 %s | tail -1 | sed %s' % (os.path.join(MEDIA_ROOT, 'data/temp.txt'), "'s/.*: //g'"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['dropbox'] = subprocess.Popen( 'python -c "import dropbox; print dropbox.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['requests'] = subprocess.Popen( 'python -c "import requests; print requests.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['simplejson'] = subprocess.Popen( 'python -c "import simplejson; print simplejson.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['virtualenv'] = subprocess.Popen( 'python -c "import virtualenv; print virtualenv.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['pip'] = subprocess.Popen( 'python -c "import pip; print pip.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['yuicompressor'] = subprocess.Popen( "java -jar %s/../yuicompressor.jar -V" % MEDIA_ROOT, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() disk_sp = subprocess.Popen( 'df -h | grep "/dev/"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].split() syst['disk'] = [disk_sp[3][:-1] + ' G', disk_sp[2][:-1] + ' G'] if DEBUG: mem_str = subprocess.Popen( 'top -l 1 | head -n 10 | grep PhysMem', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() mem_avail = mem_str[mem_str.find(',') + 1:mem_str.find('unused')].strip() if 'M' in mem_avail: mem_avail = '%.1f G' % (int(mem_avail[:-1]) / 1024.) else: mem_avail = mem_avail[:-1] + ' ' + mem_avail[-1] mem_used = mem_str[mem_str.find(':') + 1:mem_str.find('used')].strip() if 'M' in mem_used: mem_used = '%.1f G' % (int(mem_used[:-1]) / 1024.) else: mem_used = mem_used[:-1] + ' ' + mem_used[-1] else: mem_str = subprocess.Popen( 'free -h', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split( '\n') mem_str = [x for x in mem_str[2].split(' ') if x] mem_avail = mem_str[-1] if mem_avail.endswith('G'): mem_avail = str(float(mem_avail[:-1]) * 1024) + ' M' else: mem_avail = mem_avail[:-1] + ' M' mem_used = mem_str[-2] if mem_used.endswith('G'): mem_used = str(float(mem_used[:-1]) * 1024) + ' M' else: mem_used = mem_used[:-1] + ' M' syst['memory'] = [mem_avail, mem_used] syst['cpu'] = cpu.replace(' ', '').split('/') syst['path'] = { 'root': MEDIA_ROOT, 'data': MEDIA_ROOT + '/data', 'media': MEDIA_ROOT + '/media' } gdrive_dir = 'echo' if DEBUG else 'cd %s' % APACHE_ROOT syst['drive'] = subprocess.Popen( "%s && drive quota | awk '{ printf $2 \" G\t\"}'" % gdrive_dir, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split('\t') syst['ssl_cert'] = dash_ssl() if not DEBUG: ver['ubuntu'] = subprocess.Popen( "lsb_release -a | head -3 | tail -1 | sed 's/.*Ubuntu //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['htop'] = subprocess.Popen( "htop --version | head -1 | sed 's/.*htop //g' | sed 's/ \-.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'aws --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['aws_cli'] = subprocess.Popen( "sed 's/ Python.*//g' %s | sed 's/.*\///g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['screen'] = subprocess.Popen( "screen --version | sed 's/.*version//g' | sed 's/(.*//g' | sed 's/[a-z ]//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['bash'] = subprocess.Popen( "bash --version | head -1 | sed 's/.*version//g' | sed 's/-release.*//g' | sed 's/[ ()]//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['gcc'] = subprocess.Popen( "gcc --version | head -1 | sed 's/.*) //g' | sed 's/ .*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['make'] = subprocess.Popen( "make --version | head -1 | sed 's/.*Make//g' | sed 's/ //g' | head -1", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split( '\n')[0] ver['cmake'] = subprocess.Popen( "cmake --version | head -1 | sed 's/.*version//g' | sed 's/ //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['ninja'] = subprocess.Popen( "ninja --version", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'javac -version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['java'] = subprocess.Popen( "sed 's/.*javac//g' %s | sed 's/_/./g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() if DEBUG: open(os.path.join(MEDIA_ROOT, 'data/temp.txt'), 'w').write( subprocess.Popen( 'perl -version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip()) ver['perl'] = subprocess.Popen( "head -2 %s | tail -1 | sed 's/).*//g' | sed 's/.*(//g' | sed 's/[a-z]//g'" % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() else: ver['perl'] = subprocess.Popen( "dpkg -l perl | tail -1 | sed 's/[a-z ]//g' | sed 's/-.*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['ruby'] = subprocess.Popen( "ruby --version | sed 's/.*ruby //g' | sed 's/ (.*//g' | sed 's/[a-z]/./g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['go'] = subprocess.Popen( "go version | sed 's/.*version go//g' | sed 's/ .*//g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['coreutils'] = subprocess.Popen( "tty --version | head -1 | sed 's/.*) //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['wget'] = subprocess.Popen( "wget --version | head -1 | sed 's/.*Wget//g' | sed 's/built.*//g' | sed 's/ //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['tar'] = subprocess.Popen( "tar --version | head -1 | sed 's/.*)//g' | sed 's/-.*//g' | sed 's/ //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['setuptools'] = subprocess.Popen( 'python -c "import setuptools; print setuptools.__version__"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['tkinter'] = subprocess.Popen( 'python -c "import Tkinter; print Tkinter.Tcl().eval(\'info patchlevel\')"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['imagemagick'] = subprocess.Popen( "mogrify -version | head -1 | sed 's/\-.*//g' | sed 's/.*ImageMagick //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() ver['kerberos'] = subprocess.Popen( "klist -V | sed 's/.*version //g'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() simplejson.dump(ver, open( os.path.join(MEDIA_ROOT, 'cache/stat_ver.json'), 'w'), indent=' ' * 4, sort_keys=True) simplejson.dump(syst, open( os.path.join(MEDIA_ROOT, 'cache/stat_sys.json'), 'w'), indent=' ' * 4, sort_keys=True) subprocess.Popen('rm %s' % os.path.join(MEDIA_ROOT, 'data/temp.txt'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) get_backup_stat() if not DEBUG: ver_txt = "$(tput setab 1) ubuntu %s | linux %s | screen %s | bash %s | ssh %s $(tput sgr 0)\n$(tput setab 172) gcc %s | make %s | cmake %s | ninja %s |$(tput sgr 0)$(tput setab 15)$(tput setaf 16) mysql %s | django %s $(tput sgr 0)\n$(tput setab 11)$(tput setaf 16) python %s | java %s | perl %s | ruby %s | go %s $(tput sgr 0)\n$(tput setab 2) coreutils %s | wget %s | tar %s | curl %s | gdrive %s | pandoc %s $(tput sgr 0)\n$(tput setab 22) tkinter %s | virtualenv %s | setuptools %s | requests %s | simplejson %s $(tput sgr 0)\n$(tput setab 39) jquery %s | bootstrap %s | headload %s | moment %s | fullcalendar %s $(tput sgr 0)\n$(tput setab 20) crontab %s | environ %s | suit %s | adminplus %s | filemanager %s $(tput sgr 0)\n$(tput setab 55) boto %s | pygithub %s | slacker %s | dropbox %s | icalendar %s | gviz %s $(tput sgr 0)\n$(tput setab 171) apache %s | wsgi %s | webauth %s | openssl %s | wallet %s | kerberos %s $(tput sgr 0)\n$(tput setab 8) git %s | pip %s | nano %s | imagemagick %s | htop %s | awscli %s $(tput sgr 0)\n\n\n$(tput setab 15)$(tput setaf 16) Das Lab Website Server $(tput sgr 0)\n$(tput setab 15)$(tput setaf 16) daslab.stanford.edu / $(tput setaf 1)52$(tput setaf 16).$(tput setaf 2)25$(tput setaf 16).$(tput setaf 172)214$(tput setaf 16).$(tput setaf 4)40 $(tput sgr 0)\n" % ( ver['ubuntu'], ver['linux'], ver['screen'], ver['bash'], ver['ssh'], ver['gcc'], ver['make'], ver['cmake'], ver['ninja'], ver['mysql'], ver['django'], ver['python'], ver['java'], ver['perl'], ver['ruby'], ver['go'], ver['coreutils'], ver['wget'], ver['tar'], ver['curl'], ver['gdrive'], ver['pandoc'], ver['tkinter'], ver['virtualenv'], ver['setuptools'], ver['requests'], ver['simplejson'], ver['jquery'], ver['bootstrap'], ver['head'], ver['moment'], ver['fullcal'], ver['django_crontab'], ver['django_environ'], ver['django_suit'], ver['django_adminplus'], ver['django_filemanager'], ver['boto'], ver['pygithub'], ver['slacker'], ver['dropbox'], ver['icalendar'], ver['gviz_api'], ver['apache'], ver['mod_wsgi'], ver['mod_webauth'], ver['openssl'], ver['wallet'], ver['kerberos'], ver['git'], ver['pip'], ver['nano'], ver['imagemagick'], ver['htop'], ver['aws_cli']) subprocess.check_call('echo "%s" > %s/cache/sys_ver.txt' % (ver_txt, MEDIA_ROOT), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception: send_error_slack(traceback.format_exc(), 'Update System Versions', ' '.join(sys.argv), 'log_cron_version.log') self.stdout.write("Finished with \033[41mERROR\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) if (not DEBUG) and BOT['SLACK']['ADMIN']['MSG_VERSION']: send_notify_slack(SLACK['ADMIN_NAME'], '', [{ "fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled weekly *Version* finished @ _%s_\n' % time.ctime() }]) self.stdout.write("Time elapsed: %.1f s.\n" % (time.time() - t)) self.stdout.write( "\033[92mSUCCESS\033[0m: \033[94mVersions\033[0m recorded in cache/stat_sys.json and cache/stat_ver.json." ) self.stdout.write("All done successfully!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) if options['item']: is_apache = 'apache' in options['item'] is_config = 'config' in options['item'] is_mysql = 'mysql' in options['item'] is_static = 'static' in options['item'] else: is_apache, is_config, is_mysql, is_static = True, True, True, True flag = False if is_mysql: t = time.time() self.stdout.write("#1: Backing up MySQL database...") try: subprocess.check_call('mysqldump --quick %s -u %s -p%s > %s/backup/backup_mysql' % (env.db()['NAME'], env.db()['USER'], env.db()['PASSWORD'], MEDIA_ROOT), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) tarfile.open('%s/backup/backup_mysql.tgz' % MEDIA_ROOT, 'w:gz').add('%s/backup/backup_mysql' % MEDIA_ROOT, arcname='backup_mysql') os.remove('%s/backup/backup_mysql' % MEDIA_ROOT) except Exception: send_error_slack(traceback.format_exc(), 'Backup MySQL Database', ' '.join(sys.argv), 'log_cron_backup.log') flag = True else: self.stdout.write(" \033[92mSUCCESS\033[0m: \033[94mMySQL\033[0m database dumped.") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_static: t = time.time() self.stdout.write("#2: Backing up static files...") try: tarfile.open('%s/backup/backup_static.tgz' % MEDIA_ROOT, 'w:gz').add('%s/data' % MEDIA_ROOT, arcname='data') except Exception: send_error_slack(traceback.format_exc(), 'Backup Static Files', ' '.join(sys.argv), 'log_cron_backup.log') flag = True else: self.stdout.write(" \033[92mSUCCESS\033[0m: \033[94mstatic\033[0m files synced.") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_apache: t = time.time() self.stdout.write("#3: Backing up apache2 settings...") try: pass # tarfile.open('%s/backup/backup_apache2.tgz' % MEDIA_ROOT, 'w:gz').add('/etc/apache2', arcname='apache2') except Exception: send_error_slack(traceback.format_exc(), 'Backup Apache2 Settings', ' '.join(sys.argv), 'log_cron_backup.log') flag = True else: self.stdout.write(" \033[92mSUCCESS\033[0m: \033[94mapache2\033[0m settings saved.") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t)) if is_config: t = time.time() self.stdout.write("#4: Backing up config settings...") try: tarfile.open('%s/backup/backup_config.tgz' % MEDIA_ROOT, 'w:gz').add('%s/config' % MEDIA_ROOT, arcname='config') except Exception: send_error_slack(traceback.format_exc(), 'Backup Config Settings', ' '.join(sys.argv), 'log_cron_backup.log') flag = True else: self.stdout.write(" \033[92mSUCCESS\033[0m: \033[94mconfig\033[0m settings saved.") self.stdout.write("Time elapsed: %.1f s.\n" % (time.time() - t)) if flag: self.stdout.write("Finished with errors!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) else: if DEBUG: self.stdout.write("\033[94m Backed up locally. \033[0m") else: (t_cron, d_cron, t_now) = get_date_time('backup') local_list = subprocess.Popen('ls -gh %s/backup/*.*gz' % MEDIA_ROOT, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip().split() html = 'File\t\t\t\tTime\t\t\t\tSize\n\n' for i in xrange(0, len(local_list), 8): html += '%s\t\t%s %s, %s\t\t%s\n' % (local_list[i + 7], local_list[i + 4], local_list[i + 5], local_list[i + 6], local_list[i + 3]) if IS_SLACK: if (not DEBUG) and BOT['SLACK']['ADMIN']['MSG_BACKUP']: send_notify_slack(SLACK['ADMIN_NAME'], '', [{"fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled weekly *Backup* finished @ _%s_\n' % time.ctime()}]) # send_notify_slack(SLACK['ADMIN_NAME'], '>```%s```\n' % html, '') else: send_notify_emails('{%s} SYSTEM: Weekly Backup Notice' % env('SERVER_NAME'), 'This is an automatic email notification for the success of scheduled weekly backup of the %s Website database and static contents.\n\nThe crontab job is scheduled at %s (UTC) on every %sday.\n\nThe last system backup was performed at %s (PDT).\n\n%s\n\n%s Website Admin\n' % (env('SERVER_NAME'), t_cron, d_cron, t_now, html, env('SERVER_NAME'))) self.stdout.write("Admin email (Weekly Backup Notice) sent.") get_backup_stat() self.stdout.write("Admin Backup Statistics refreshed.") self.stdout.write("All done successfully!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))
def handle(self, *args, **options): if not BOT['SLACK']['IS_REPORT']: return t0 = time.time() self.stdout.write('%s:\t%s' % (time.ctime(), ' '.join(sys.argv))) try: if os.path.exists('%s/cache/log_alert_admin.log' % MEDIA_ROOT): lines = open('%s/cache/log_alert_admin.log' % MEDIA_ROOT, 'r').readlines() lines = ''.join(lines) if (not IS_SLACK): send_notify_emails( '{%s} SYSTEM: Weekly Error Report' % env('SERVER_NAME'), 'This is an automatic email notification for the aggregated weekly error report. The following error occurred:\n\n\n%s\n\n%s Website Admin' % (lines, env('SERVER_NAME'))) open('%s/cache/log_alert_admin.log' % MEDIA_ROOT, 'w').write('') self.stdout.write( "\033[92mSUCCESS\033[0m: All errors were sent to \033[94mEmail\033[0m. Log cleared." ) else: self.stdout.write( "\033[92mSUCCESS\033[0m: All errors were reported to \033[94mSlack\033[0m already, nothing to do." ) if os.path.exists('%s/cache/log_cron.log' % MEDIA_ROOT): subprocess.check_call('gzip -f %s/cache/log_cron.log' % MEDIA_ROOT, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) self.stdout.write( "\033[92mSUCCESS\033[0m: \033[94mlog_cron.log\033[0m gzipped." ) else: self.stdout.write( "\033[92mSUCCESS\033[0m: \033[94mlog_cron.log\033[0m not exist, nothing to do." ) msgs = SlackMessage.objects.filter( date__lte=(datetime.utcnow() - timedelta(days=15)).date()) for msg in msgs: msg.delete() except Exception: send_error_slack(traceback.format_exc(), 'Weekly Error Report', ' '.join(sys.argv), 'log_cron_report.log') self.stdout.write("Finished with \033[41mERROR\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0)) sys.exit(1) if (not DEBUG) and BOT['SLACK']['ADMIN']['MSG_REPORT']: send_notify_slack(SLACK['ADMIN_NAME'], '', [{ "fallback": 'SUCCESS', "mrkdwn_in": ["text"], "color": "good", "text": '*SUCCESS*: Scheduled weekly *Report* finished @ _%s_\n' % time.ctime() }]) self.stdout.write("Finished with \033[92mSUCCESS\033[0m!") self.stdout.write("Time elapsed: %.1f s." % (time.time() - t0))