def notify_maintainer(db, redis, content, category): """Notify alarm info to maintainers. :arg category: int, e.g. 1: gateway 2: eventer """ mobiles = [] emails = [] alarm_key = 'maintainer_alarm:%s' % category alarm_interval = 60 * 5 # 5 minutes alarm_flag = redis.getvalue(alarm_key) if not alarm_flag: maintainers = db.query( "SELECT mid, mobile, email FROM T_MAINTAINER WHERE valid = 1") for item in maintainers: mobiles.append(item['mobile']) emails.append(item['email']) for mobile in mobiles: SMSHelper.send(mobile, content) for email in emails: EmailHelper.send(email, content) redis.setvalue(alarm_key, True, alarm_interval) logging.info("[PUBLIC] Notify alarm to maintainers. content: %s, category: %s.", content, category) else: logging.info("[PUBLIC] Notify alarm is ignored in 5 minutes. content: %s, category: %s.", content, category)
def notify(self): content = SMSCode.SMS_GW_ERROR_REPORT % ConfHelper.UWEB_CONF.url_out for mobile in self.mobiles: SMSHelper.send(mobile, content) for email in self.emails: EmailHelper.send(email, content)
def check_service(self): try: base_id = self.get_lid_by_tid(self.tid) while True: time.sleep(600) # 10 minutes new_lid = self.get_lid_by_tid(self.tid) logging.info("[CK] simulator terminal location base_id:%s, new_lid:%s", base_id, new_lid) if new_lid > base_id: base_id = new_lid else: for mobile in self.mobiles: sms = SMSCode.SMS_SERVICE_EXCEPTION_REPORT % ConfHelper.UWEB_CONF.url_out SMSHelper.send(mobile, sms) logging.info("[CK] Notify Administrator:%s By SMS, service exception!", mobile) for email in self.emails: content = SMSCode.SMS_SERVICE_EXCEPTION_REPORT % ConfHelper.UWEB_CONF.url_out EmailHelper.send(email, content) logging.info("[CK] Notify Administrator:%s By EMAIL, service exception!", email) except KeyboardInterrupt: logging.error("Ctrl-C is pressed.") except Exception as e: logging.exception("[CK] Check service failed. Exception: %s", e.args)
def check_push(self): """ """ res = self.db_push.get( "SELECT count(id) as count FROM T_PUSH where status = 1") if res and res['count'] >= self.alarm_size: content = SMSCode.SMS_PUSH_REPORT % ConfHelper.UWEB_CONF.url_out for mobile in self.mobiles: SMSHelper.send(mobile, content) for email in self.emails: EmailHelper.send(email, content) logging.info("[CK] Notify push queue exception to administrator!")
def check_sms(self): """Notify administrators when sms to be send is more than alarm_size; """ res = self.db.get( "SELECT count(id) as count FROM T_SMS where send_status = -1") if res and res['count'] >= self.alarm_size: content = SMSCode.SMS_SMS_REPORT % ConfHelper.UWEB_CONF.url_out for mobile in self.mobiles: SMSHelper.send(mobile, content) for email in self.emails: EmailHelper.send(email, content) logging.info("[CK] Notify sms queue exception to administrator!")
def alarm(self): """ #NOTE: Send alarm message if need. """ send_flag = self.redis.getvalue(self.alarm_key) if (not send_flag): content = SMSCode.SMS_GW_DELAY_REPORT % ConfHelper.UWEB_CONF.url_out for mobile in self.mobiles: SMSHelper.send(mobile, content) for email in self.emails: EmailHelper.send(email, content) logging.info("[CK] Notify S packet delay to administrator!") self.redis.setvalue(self.alarm_key, True, self.alarm_interval)
def put(self): status = ErrorCode.SUCCESS try: data = json_decode(self.request.body) logging.info("data: %s", data) id = data.get("id", -1) reply = data.get("reply","") email = data.get("email", "") except Exception as e: logging.info("[LOG] Feedback illegal data format. Exception: %s", e.args) status = ErrorCode.ILLEGAL_DATA_FORMAT self.write_ret(status) try: reply_time = int(time.time()) self.acbdb.execute("UPDATE T_FEEDBACK" " SET reply = %s," " reply_time = %s" " WHERE id = %s", reply, reply_time, id) # if email is not null, send email to user if email: self.acbdb.execute("UPDATE T_FEEDBACK" " SET isreplied = 1" " WHERE id = %s", id) body = u"尊敬的客户:\n\t首先感谢您对【移动卫士】的支持与关心,对您的意见反馈表示衷心感谢。\n\t针对您的反馈内容,工作人员做了如下回复:\n\t%s\n\n\t【移动卫士】" % reply EmailHelper.send(email, body, [], []) self.write_ret(status, dict_=DotDict(reply_time=reply_time)) except Exception as e: logging.exception("[LOG] Feedback query failed. Exception: %s", e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)
from models import * from flask import jsonify from flask_socketio import emit from helpers.utilities import merge_two_dicts from helpers.emailhelper import EmailHelper from collections import defaultdict from settings import API_BOUND_HOST, API_PORT, BASE_URL_FOR_EMAIL email_helper = EmailHelper() def create_folder(user_id, params): folder_name = params.get('name', None) if not folder_name: return jsonify({'errors': "Folder name required"}), 400 name_conflict_user = db_session_users.query(UserFolder).filter_by( user_id=user_id, name=folder_name).first() if name_conflict_user: return jsonify({ 'errors': "Folder name: " + folder_name + " is already being used" }), 409 new_folder = UserFolder(user_id=user_id, name=folder_name) db_session_users.add(new_folder) db_session_users.commit() db_session_users.refresh(new_folder)
def statistic_offline_terminal(self, epoch_time): """Export data into excel file. """ start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) logging.info("[CELERY] %s statistic_offline_terminal started.", start_time) current_day = time.localtime(epoch_time) day_start_time, day_end_time = start_end_of_day(current_day.tm_year, current_day.tm_mon, current_day.tm_mday) month_start_time, month_end_time = start_end_of_month(current_day.tm_year, current_day.tm_mon) year_start_time, year_end_time = start_end_of_year(current_day.tm_year) logging.info("[CELERY] day_start_time: %s, day_end_time: %s, month_start_time: %s, month_end_time: %s, year_start_time: %s, year_end_time: %s.", day_start_time, day_end_time, month_start_time, month_end_time, year_start_time, year_end_time) import xlwt import xlrd BASE_PATH = '/var/ydcws/reports/' # NOTE: chinese filename cannot download successfully, so here use # english filename. wish one day chinese words can work well OFFLINE_FILE_NAME = u"terminals_offline" #OFFLINE_FILE_NAME = u"离线用户统计表" cur_path = time.strftime("%Y%m%d",time.localtime(epoch_time) ) pre_path = time.strftime("%Y%m%d",time.localtime(epoch_time-60*60*24)) PRE_PATH = BASE_PATH + OFFLINE_FILE_NAME + '-' + pre_path + '.xls' CUR_PATH = BASE_PATH + OFFLINE_FILE_NAME + '-' + cur_path + '.xls' OFFLINE_HEADER = (u"车主号", u"终端号", u"电量", u"离线时间", u"累计离线时间", u"离线原因", u"唤醒指令下发频次", u"今日新增", u"当前状态", u"基站定位结果", u"备注") OFFLINE_DETAIL_HEADER = (u"用户类型", u"车主号", u"终端号", u"电量", u"离线时间", u"累计离线时间", u"离线原因", u"备注") # offline-terminals of this day cur_sql_cmd = ("SELECT id, owner_mobile as umobile, mobile as tmobile," " begintime, offline_time, pbat, remark" " FROM T_TERMINAL_INFO" " WHERE service_status = 1 AND login =0 " " AND (mobile LIKE '14778%%' OR mobile LIKE '1847644%%') " " AND (offline_time BETWEEN %s AND %s) ORDER BY pbat") # offline-terminals till now #terminals_offline_cmd = ("SELECT id, owner_mobile as umobile, mobile as tmobile," # " begintime, offline_time, pbat, remark, group_id" # " FROM T_TERMINAL_INFO" # " WHERE service_status = 1 AND login =0 " # " AND (mobile LIKE '14778%%' OR mobile LIKE '1847644%%') " # " ORDER BY group_id, pbat") terminals_offline_cmd = ("SELECT id, owner_mobile as umobile, mobile as tmobile," " begintime, offline_time, pbat, remark, group_id" " FROM T_TERMINAL_INFO" " WHERE service_status=1 AND login=0 " " ORDER BY group_id, pbat") terminal_sql_cmd = "SELECT login, remark, offline_time FROM T_TERMINAL_INFO WHERE mobile = %s LIMIT 1" cur_res = self.db.query(cur_sql_cmd, day_start_time, epoch_time) terminals_ofline = self.db.query(terminals_offline_cmd) tmobile_lst = [] for item in cur_res: tmobile_lst.append(item['tmobile']) item['offline_period'] = int(time.time()) - item['offline_time'] item['offline_cause'] = 2 if item['pbat'] < 5 else 1 item['sim_status'] = u'失败' if item['offline_cause'] == 1: # heart beat # check the sim status terminal_log = self.db.get("SELECT sim_status FROM T_BIND_LOG" " WHERE tmobile = %s LIMIT 1", item['tmobile']) if terminal_log.sim_status == 1: item['sim_status'] = u'成功' item['remark'] = safe_unicode(item['remark']) logging.info('[CELERY] the currentrecords to be dealed with, counts: %s, cur_res: %s', len(cur_res), cur_res) # NOTE: get last day's data pre_res = [] if not os.path.isfile(PRE_PATH): logging.info("[CELERY] pre_path: %s cannot be found.", PRE_PATH) else: wb=xlrd.open_workbook(PRE_PATH) sh=wb.sheet_by_name(u'离线汇总分析') for rownum in range(1,sh.nrows): # get records from the second row row = sh.row_values(rownum) if row[1] in tmobile_lst: continue if row[8] == u'在线': continue tmobile = row[1] terminal = self.db.get(terminal_sql_cmd, tmobile) current_status = u'离线' if not terminal: current_status = u'已解绑' row[8] = current_status else: if terminal['login'] !=0: current_status = u'在线' row[8] = current_status offline_period = int(time.time()) - terminal['offline_time'] row[4] = seconds_to_label(offline_period) d,m = divmod(offline_period,60*60) count = d+1 if m else d row[6] = count row[10] = safe_unicode(terminal['remark']) pre_res.append(row) logging.info('[CELERY] the previous records to be dealed with, count: %s, pre_res: %s', len(pre_res), pre_res) # some styles #date_style = xlwt.easyxf(num_format_str='YYYY-MM-DD HH:mm:ss') title_style = xlwt.easyxf('pattern: pattern solid, fore_colour ocean_blue; font: bold off; align: wrap on, vert centre, horiz center;' "borders: top double, bottom double, left double, right double;") abnormal_style = xlwt.easyxf('font: colour_index red, bold off; align: wrap on, vert centre, horiz center;') add_style = xlwt.easyxf('font: colour_index blue, bold off; align: wrap on, vert centre, horiz center;') powerlow_style = xlwt.easyxf('font: colour_index dark_yellow, bold off; align: wrap on, vert centre, horiz center;') online_style = xlwt.easyxf('font: colour_index green, bold off; align: wrap on, vert centre, horiz center;') offline_style = xlwt.easyxf('font: colour_index brown, bold off; align: wrap on, vert centre, horiz center;') center_style = xlwt.easyxf('align: wrap on, vert centre, horiz center;') wb = xlwt.Workbook() ws = wb.add_sheet(u'离线汇总分析') ws_detail = wb.add_sheet(u'离线明细') # sheet 1: 离线汇总分析 start_line = 0 for i, head in enumerate(OFFLINE_HEADER): ws.write(0, i, head, title_style) ws.col(0).width = 4000 # umobile ws.col(1).width = 4000 # tmobile ws.col(3).width = 4000 * 2 # offline_time ws.col(4).width = 4000 * 2 # offline_period ws.col(6).width = 4000 # lq count ws.col(9).width = 4000 # sim_status ws.col(10).width = 4000 * 4 # remark start_line += 1 results = cur_res for i, result in zip(range(start_line, len(results) + start_line), results): ws.write(i, 0, result['umobile'], center_style) ws.write(i, 1, result['tmobile'], center_style) ws.write(i, 2, str(result['pbat'])+'%', center_style) ws.write(i, 3, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time'])), center_style) ws.write(i, 4, seconds_to_label(result['offline_period']), center_style) if result['offline_cause'] == 2: offline_cause = u'低电关机' ws.write(i, 5, offline_cause, powerlow_style) else: offline_cause = u'通讯异常' ws.write(i, 5, offline_cause, abnormal_style) if result['sim_status'] == u'成功': ws.write(i, 9, safe_unicode(result['sim_status']), online_style) else: ws.write(i, 9, safe_unicode(result['sim_status']), abnormal_style) d,m = divmod(result['offline_period'],60*60) count = d+1 if m else d ws.write(i, 6, count) terminal = self.db.get("SELECT remark FROM T_TERMINAL_INFO where id = %s", result['id']) ws.write(i, 7, u'新增', add_style) ws.write(i, 10, safe_unicode(terminal['remark']), center_style) start_line += 1 logging.info('[CELERY] current offline records, count: %s, tmobile_lst: %s', len(tmobile_lst), tmobile_lst) results = pre_res for i, result in zip(range(start_line, len(results) + start_line), results): #for j in range(len(OFFLINE_HEADER)): # ws.write(i, j, result[j]) #if result[1] in tmobile_lst: # continue ws.write(i, 0, result[0], center_style) ws.write(i, 1, result[1], center_style) ws.write(i, 2, result[2], center_style) ws.write(i, 3, result[3], center_style) ws.write(i, 4, result[4], center_style) if result[5] == u'低电关机': ws.write(i, 5, u'低电关机', powerlow_style) else: ws.write(i, 5, u'通讯异常', abnormal_style) ws.write(i, 6, result[6]) if result[8] == u'在线': ws.write(i, 8, u'在线', online_style) elif result[8] == u'已解绑': ws.write(i, 8, u'已解绑') else: pass #ws.write(i, 9, result[9], center_style) ws.write(i, 10, result[10], center_style) # sheet 2: 离线明细 start_line = 0 for i, head in enumerate(OFFLINE_DETAIL_HEADER): ws_detail.write(0, i, head, title_style) ws_detail.col(1).width = 4000 ws_detail.col(2).width = 4000 ws_detail.col(4).width = 4000 * 2 ws_detail.col(5).width = 4000 * 2 ws_detail.col(7).width = 4000 * 4 start_line += 1 results = terminals_ofline for i, result in zip(range(start_line, len(results) + start_line), results): # some modification if result['group_id'] == -1: result['user_type'] = UWEB.USER_TYPE.PERSON else: result['user_type'] = UWEB.USER_TYPE.CORP offline_period = int(time.time()) - result['offline_time'] result['offline_period'] = offline_period if offline_period > 0 else 0 result['offline_cause'] = 2 if result['pbat'] < 5 else 1 ws_detail.write(i, 0, u'个人用户' if result['user_type'] == UWEB.USER_TYPE.PERSON else u'集团用户') ws_detail.write(i, 1, result['umobile'], center_style) ws_detail.write(i, 2, result['tmobile'], center_style) ws_detail.write(i, 3, str(result['pbat'])+'%', center_style) ws_detail.write(i, 4, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time'])), center_style) ws_detail.write(i, 5, seconds_to_label(result['offline_period'])) if result['offline_cause'] == 2: offline_cause = u'低电关机' ws_detail.write(i, 6, offline_cause, powerlow_style) else: offline_cause = u'通讯异常' ws_detail.write(i, 6, offline_cause, abnormal_style) #ws_detail.write(i, 6, u'低电关机' if result['offline_cause'] == 2 else u'通讯异常') terminal_offline = self.db.get("SELECT remark FROM T_TERMINAL_INFO where id = %s", result['id']) ws_detail.write(i, 7, safe_unicode(terminal_offline['remark'])) start_line += 1 wb.save(CUR_PATH) content = u'附件是 %s 的离线报表统计,请查收! 详情请看:%s ' % (cur_path,ConfHelper.ADMIN_CONF.url) subject = u'移动车卫士离线分析报告' + cur_path EmailHelper.send(self.to_emails, content, self.cc_emails, files=[CUR_PATH], subject=subject) logging.info("[CELERY] statistic_offline_terminal finished, cur_path: %s", CUR_PATH)
def invite_user(params, user_id): email = params.get('email') resend = params.get('resend', False) def error_response(msg, code=400): response = jsonify({ 'error': msg, }) response.status_code = code return response current_user = db_session_users.query(User).filter_by(id=user_id).first() if not 'admin' in current_user.roles: return error_response('Only admin users can send invitations', code=403) if email is None: return error_response('Email must be specified') else: email = email.lower() if not EmailHelper.validate_email(email): return error_response('Domain is not allowed') user = db_session_users.query(User).filter_by(email=email).scalar() if user is None: user = User({ 'email': email, 'enabled': False, 'properties': {'invited_by': current_user.email}, }) # mark internal users with the internal user flag so we can differentiate user types when # calculating various stats if email.endswith("@jurispect.com") or email.endswith("@compliance.ai"): user.is_internal_user = True user.gen_reset_token() elif resend is True and user is not None: # Add resent email time to user properties to surface in the FE user.properties = merge_two_dicts(user.properties, { 'resent_invite_time': datetime.datetime.utcnow().isoformat() }) elif resend is False: return error_response('User already exists') user.gen_reset_token() try: _send_activation_email('invite', user) except SMTPException: db_session_users.rollback() return error_response('Could not send email', code=500) response = jsonify({ 'success': True, }) db_session_users.add(user) try: db_session_users.commit() except IntegrityError: return error_response('User already exists') return response
"--debug", dest="debug", action="store_true", help="Add debug data to email") optparser.add_option("-l", "--limit", dest="limit", type="int", help="Limit number of emails to send") optparser.add_option("-b", "--base-url", dest="base_url", help="Override default base URL") (opts, _) = optparser.parse_args() email_helper = EmailHelper() num_of_emails_attempted = 0 # helper method to get the minimum date, handles for cases when one of the two dates = None def get_min_date(date1, date2): if date1 and not date2: return date1 elif date2 and not date1: return date2 else: return min(date1, date2) # default the user's job interval to weekly if not set (weekly/daily/none) def get_user_job_interval_preference(user):
import sys this_folder = os.path.dirname(os.path.realpath(__file__)) sys.path.append(this_folder + '/../') from helpers.emailhelper import EmailHelper import urllib """ Generate a sample invite email for layout testing python bin/maketestemail.py > test.eml """ email_helper = EmailHelper() template = 'invite-inline' subject = 'Welcome to Compliance.ai!' base_url = 'http://example.com' email = '*****@*****.**' activate_url = '%s/activate?email=%s&token=%s' % ( base_url, urllib.quote_plus(email), urllib.quote_plus( '$2b$10$.gjXMdl8WgLBUgRahn8GJO5RlVF18ivb75jEoGB8p9LrJrl0ERW2G')) template_vars = { 'url': activate_url, 'email': email, }