def send_offline_remind_sms(self): logging.info("[CELERY] checkertask send offline remind sms started.") try: currenttime = int(time.time()) terminals = self.db.query("SELECT tid, alias, mobile, owner_mobile, offline_time" " FROM T_TERMINAL_INFO" " WHERE login = 0" " AND service_status = 1" " AND offline_time < %s", (currenttime - 24*60*60)) for terminal in terminals: sms_option = QueryHelper.get_sms_option_by_uid(terminal.owner_mobile, 'heartbeat_lost', self.db) if sms_option == UWEB.SMS_OPTION.SEND: ctime = get_terminal_time(currenttime) ctime = safe_unicode(ctime) alias = terminal['alias'] if terminal['alias'] else terminal['mobile'] sms = SMSCode.SMS_HEARTBEAT_LOST % (alias, ctime) SMSHelper.send(terminal.owner_mobile, sms) logging.info("[CELERY] Send offline remind sms to user:%s, tid:%s", terminal.owner_mobile, terminal.tid) logging.info("[CELERY] checkertask send offline remind sms finished.") except Exception as e: logging.exception("[CELERY] Check terminal poweroff timeout exception.")
def get(self, hash_): """Download the records and save it as excel. """ mem_key = self.get_memcache_key(hash_) r = self.redis.getvalue(mem_key) if r: results, interval = r[0], r[1] else: self.render("errors/download.html") return wb = xlwt.Workbook() ws = wb.add_sheet(OFFLINE_SHEET) start_line = 0 for i, head in enumerate(OFFLINE_HEADER): ws.write(0, i, head) ws.col(1).width = 4000 * 4 ws.col(2).width = 4000 ws.col(3).width = 4000 ws.col(4).width = 4000 ws.col(6).width = 4000 * 2 ws.col(7).width = 4000 * 2 ws.col(8).width = 4000 * 2 ws.col(10).width = 4000 * 4 start_line += 1 for i, result in zip(range(start_line, len(results) + start_line), results): ws.write(i, 0, u'个人用户' if result['user_type'] == UWEB.USER_TYPE.PERSON else u'集团用户') ws.write(i, 1, result['corp_name']) ws.write(i, 2, result['umobile']) ws.write(i, 3, result['tmobile']) ws.write(i, 4, result['tid']) ws.write(i, 5, result['softversion']) ws.write(i, 6, result['alias']) ws.write(i, 7, str(result['pbat'])+'%') ws.write(i, 8, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time']))) ws.write(i, 9, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['login_time']))) ws.write(i, 10, seconds_to_label(result['offline_period'])) ws.write(i, 11, 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.write(i, 12, safe_unicode(terminal_offline['remark'])) _tmp_file = StringIO() wb.save(_tmp_file) filename = self.generate_file_name(OFFLINE_FILE_NAME) self.set_header('Content-Type', 'application/force-download') self.set_header('Content-Disposition', 'attachment; filename=%s.xls' % (filename,)) # move the the begging. _tmp_file.seek(0, SEEK_SET) self.write(_tmp_file.read()) _tmp_file.close()
def get(self, privilegegroupname): """ check whether the privilegegroupname already exists. """ r = self.db.query("SELECT id FROM T_PRIVILEGE_GROUP" " WHERE name = %s",safe_unicode(privilegegroupname)) ret = dict(success=True if r else False) self.set_header(*self.JSON_HEADER) self.write(json_encode(ret))
def get(self, hash_): """Download the records and save it as excel. """ mem_key = self.get_memcache_key(hash_) results = self.redis.getvalue(mem_key) if not results: self.render("errors/download.html") return filename = BUSINESS_FILE_NAME 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;') wb = xlwt.Workbook() ws = wb.add_sheet(BUSINESS_SHEET) start_line = 0 for i, head in enumerate(BUSINESS_HEADER): ws.write(0, i, head) start_line += 1 for i, result in zip(range(start_line, len(results) + start_line), results): ws.write(i, 0, i) ws.write(i, 1, safe_unicode(result['ecname']) if result['ecname'] else u'') ws.write(i, 2, result['cmobile']) ws.write(i, 3, result['umobile']) ws.write(i, 4, result['tmobile']) ws.write(i, 5, result['tid']) ws.write(i, 6, result['softversion']) ws.write(i, 7, result['alias']) ws.write(i, 8, u'移动卫士' if int(result['biz_type']) == 0 else u'移动外勤') if int(result['login']) == 0: ws.write(i, 9, u'离线', offline_style) else: ws.write(i, 9, u'在线', online_style) ws.write(i, 10, '%s%%' % result['pbat']) ws.write(i, 11, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['begintime']))) ws.write(i, 12, result['bt_name']) ws.write(i, 13, result['bt_mac']) _tmp_file = StringIO() wb.save(_tmp_file) filename = self.generate_file_name(filename) self.set_header('Content-Type', 'application/force-download') self.set_header('Content-Disposition', 'attachment; filename=%s.xls' % (filename,)) # move the the begging. _tmp_file.seek(0, SEEK_SET) self.write(_tmp_file.read()) _tmp_file.close()
def put(self): """Modify profile of current user. """ status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) tid = data.get('tid',None) # check tid whether exist in request and update current_user self.check_tid(tid) logging.info("[UWEB] User profile request: %s, uid: %s, tid: %s", data, self.current_user.uid, self.current_user.tid) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT self.write_ret(status) return try: if data.has_key('name') and not check_name(data.name): status = ErrorCode.ILLEGAL_NAME self.write_ret(status) return name = data.get('name', None) if name is not None: sql_cmd = "UPDATE T_USER SET name = %s WHERE uid = %s" self.db.execute(sql_cmd, name, self.current_user.uid) cnum = data.get('cnum', None) if cnum is not None: self.db.execute("UPDATE T_CAR" " SET cnum = %s" " WHERE tid = %s", safe_unicode(cnum), self.current_user.tid) terminal_info_key = get_terminal_info_key(self.current_user.tid) terminal_info = self.redis.getvalue(terminal_info_key) if terminal_info: terminal_info['alias'] = cnum if cnum else self.current_user.sim self.redis.setvalue(terminal_info_key, terminal_info) self.write_ret(status) except Exception as e: logging.exception("[UWEB] Update profile failed. uid:%s, tid:%s, Exception: %s", self.current_user.uid, self.current_user.tid, e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)
def notify_report_by_push(self, report, mobile): flag = self.check_timestamp(int(report['timestamp'])) if not flag: return name = QueryHelper.get_alias_by_tid(report.dev_id, self.redis, self.db) report.comment = '' region_id = None if report.rName == EVENTER.RNAME.POWERLOW: if report.terminal_type == "1": if int(report.pbat) == 100: report.comment = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_FULL] elif int(report.pbat) <= 5: report.comment = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_OFF] else: if int(report.pbat) <= 20: report.comment = (ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_LOW]) % report.pbat else: report.comment = ErrorCode.ERROR_MESSAGE[ErrorCode.FOB_POWER_LOW] % report.fobid elif report.rName in (EVENTER.RNAME.REGION_ENTER, EVENTER.RNAME.REGION_OUT): region = report['region'] region_id = region.region_id if region.get('region_name', None): region.comment = u"围栏名:%s" % safe_unicode(region.region_name) # push if report.rName == EVENTER.RNAME.STOP: logging.info("[EVENTER] %s altert needn't to push to user. Terminal: %s", report.rName, report.dev_id) else: self.notify_to_parents(name, report, mobile, region_id) if report.rName in [EVENTER.RNAME.ILLEGALMOVE, EVENTER.RNAME.ILLEGALSHAKE]: _date = datetime.datetime.fromtimestamp(int(report['timestamp'])) _seconds = _date.hour * 60 * 60 + _date.minute * 60 + _date.second if _seconds < 7 * 60 * 60 or _seconds > 19 * 60 * 60: _resend_alarm = functools.partial(self.notify_to_parents, name, report, mobile, region_id) # 30 seconds later, send sms 1 time. task = RepeatedTimer(30, _resend_alarm, 1) task.start() self.push_to_client(report)
def post(self): """Insert new items.""" status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) mobile = data.get('mobile', '') logging.info("[UWEB] feedback request: %s", data) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT self.write_ret(status) return try: #if data.has_key('contact') and not check_sql_injection(data.contact): # status = ErrorCode.ILLEGAL_NAME # logging.info("[UWEB] feedback failed, Message: %s", ErrorCode.ERROR_MESSAGE[status]) # self.write_ret(status) # return #if data.has_key('email') and not check_sql_injection(data.email): # status = ErrorCode.ILLEGAL_EMAIL # logging.info("[UWEB] feedback failed, Message: %s", ErrorCode.ERROR_MESSAGE[status]) # self.write_ret(status) # return self.db.execute("INSERT INTO T_FEEDBACK(contact, mobile," " email, content, timestamp, category)" " VALUES(%s, %s, %s, %s, %s, %s)", data.contact, mobile, data.email, safe_unicode(data.content), int(time.time()), data.category) self.write_ret(status) except Exception as e: status = ErrorCode.FEEDBACK_FAILED logging.exception("[UWEB] add feedback failed, Exception: %s, content:\n%s", e.args, data.content) self.write_ret(status)
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 prepare_data(self, hash_): """Associated with the post method. workflow: if get value according the hash: return value else: retrieve the db and return the result. """ mem_key = self.get_memcache_key(hash_) data = self.redis.getvalue(mem_key) if data: if isinstance(data, str): data = eval(data) return data[0], data[1] start_time = int(self.get_argument('start_time', 0)) end_time = int(self.get_argument('end_time', 0)) res_ = self.db.query("SELECT id, tid, softversion," " owner_mobile AS umobile," " mobile AS tmobile, begintime, offline_time," " login_time, pbat, remark, group_id" " FROM T_TERMINAL_INFO" " WHERE service_status = 1 AND login =0" " AND mobile like '14778%%'" " ORDER BY offline_time DESC, pbat") for item in res_: item['alias'] = QueryHelper.get_alias_by_tid( item['tid'], self.redis, self.db) item['corp_name'] = u'' if item['group_id'] == -1: item['user_type'] = UWEB.USER_TYPE.PERSON #item['user_type'] = u'个人账户' else: item['user_type'] = UWEB.USER_TYPE.CORP corp = QueryHelper.get_corp_by_groupid(item['group_id'], self.db) item['corp_name'] = corp.get('name', '') #item['user_type'] = u'集团账户' offline_period = int(time.time()) - item['offline_time'] item['offline_period'] = offline_period if offline_period > 0 else 0 item['offline_cause'] = 2 if item['pbat'] < 5 else 1 item['remark'] = safe_unicode(item['remark']) res = res_[:] user_type = self.get_argument('user_type', '') if user_type: # has no user_type for item in res_: if item['user_type'] != user_type: res.remove(item) offline_cause = self.get_argument('offline_cause', None) if (offline_cause is not None) and (offline_cause != ''): for item in res_: if item['offline_cause'] != int(offline_cause): if item in res: res.remove(item) offline_period = self.get_argument('offline_period', None) if offline_period is not None: for item in res_: if offline_period == '1': if item['offline_period'] >60*60*24: if item in res: res.remove(item) elif offline_period == '2': if item['offline_period'] <60*60*24*1: if item in res: res.remove(item) elif offline_period == '3': if item['offline_period'] <60*60*24*2: if item in res: res.remove(item) elif offline_period == '4': if item['offline_period'] <60*60*24*3: if item in res: res.remove(item) self.redis.setvalue(mem_key,(res, [start_time, end_time]), time=self.MEMCACHE_EXPIRY) return res, [start_time, end_time]
def check_region_event(self, ori_location, region): """Check enter or out region workflow: get old_region_status accordinding to region and tid get old_region_time accordinding to region and tid check region_status according distance, then keep region_status in redis if not old_region_status: skip if old_region_time and location's gps_time <= old_region_time: skip check region event according to region_status and old_region_staus if region event: keep region_status, region_time in redis """ if not (ori_location and region): logging.info("[EVENTER] query data is invalid, ori_location: %s, region: %s, no check", ori_location, region) return None if not (ori_location['cLat'] and ori_location['cLon']): logging.info("[EVENTER] location is invalid, ori_location: %s, no check", ori_location) return None # BIG NOTE: python grammar, shallow copy will change origen data. location = copy.deepcopy(dict(ori_location)) location = DotDict(location) old_region_status_key = get_region_status_key(location['dev_id'], region.region_id) old_region_status = self.redis.getvalue(old_region_status_key) old_region_time_key = get_region_time_key(location['dev_id'], region.region_id) old_region_time = self.redis.getvalue(old_region_time_key) if region.region_shape == UWEB.REGION_SHAPE.CIRCLE: # get distance beteween now location and the centre of the region distance = lbmphelper.get_distance(region.region_longitude, region.region_latitude, location.cLon, location.cLat) if distance >= region.region_radius: region_status = EVENTER.CATEGORY.REGION_OUT rname = EVENTER.RNAME.REGION_OUT else: region_status = EVENTER.CATEGORY.REGION_ENTER rname = EVENTER.RNAME.REGION_ENTER elif region.region_shape == UWEB.REGION_SHAPE.POLYGON: polygon = {'name':'', 'points':[]} points = region.points point_lst = points.split(':') for point in point_lst: latlon = point.split(',') dct = {'lat':float(latlon[0])/3600000, 'lon':float(latlon[1])/3600000} polygon['points'].append(dct) polygon['name'] = region.region_name if PtInPolygon(location, polygon): region_status = EVENTER.CATEGORY.REGION_ENTER rname = EVENTER.RNAME.REGION_ENTER else: region_status = EVENTER.CATEGORY.REGION_OUT rname = EVENTER.RNAME.REGION_OUT else: #NOTE: here should never occur. logging.error("[EVENTER] unknow region_shape: %s, region: %s, skip it", region.region_shape, region) if old_region_time: if int(location['gps_time']) <= int(old_region_time): logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_region_time: %s, skip it", location['gps_time'], old_region_time) return location # keep region status self.redis.setvalue(old_region_status_key, region_status) logging.info("rname:%s, old status:%s, current status:%s, tid:%s", safe_unicode(region.region_name), old_region_status, region_status, location['dev_id']) if not old_region_status: logging.info("[EVENTER] old_region_status: %s is invalid, skip it", old_region_status) # skip the first region event return location # check region event if region_status != old_region_status: self.redis.setvalue(old_region_status_key, region_status) self.redis.setvalue(old_region_time_key, location['gps_time']) # 2: complete the location location['category'] = region_status location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need location['rName'] = rname location['region'] = region location['region_id'] = region.region_id return location
def notify_report_by_sms(self, report, mobile): flag = self.check_timestamp(int(report['timestamp'])) if not flag: return name = QueryHelper.get_alias_by_tid(report.dev_id, self.redis, self.db) terminal_time = get_terminal_time(int(report['timestamp'])) terminal_time = safe_unicode(terminal_time) report_name = report.name if not report_name: if report.cLon and report.cLat: report_name = ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE] else: report_name = ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED] sms = '' sms_white = '' if isinstance(report_name, str): report_name = report_name.decode('utf-8') report_name = unicode(report_name) if report.rName == EVENTER.RNAME.POWERLOW: if report.terminal_type == "1": # type: terminal if int(report.pbat) == 100: pbat_message_key = get_pbat_message_key(report.dev_id) if self.redis.exists(pbat_message_key) is False: self.redis.setvalue(pbat_message_key, 1, time=24*60*60) else: logging.info("[EVENTER] Don't send duplicate power full message to terminal:%s in 24 hours", report.dev_id) return elif int(report.pbat) > 20 and int(report.pbat) < 100: logging.info("[EVENTER] Terminal:%s reported power low pbat:%s between 20% and 100%, so skip it", report.dev_id, report.pbat) return sms = self.handle_power_status(report, name, report_name, terminal_time) else: # type: fob sms = SMSCode.SMS_FOB_POWERLOW % (report.fobid, terminal_time) elif report.rName == EVENTER.RNAME.ILLEGALMOVE: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_ILLEGALMOVE_NOLOC % (name, terminal_time) else: sms = SMSCode.SMS_ILLEGALMOVE % (name, report_name, terminal_time) _date = datetime.datetime.fromtimestamp(int(report['timestamp'])) _seconds = _date.hour * 60 * 60 + _date.minute * 60 + _date.second if _seconds < 7 * 60 * 60 or _seconds > 19 * 60 * 60: _resend_alarm = functools.partial(self.sms_to_user, report.dev_id, sms+u"重复提醒,如已收到,请忽略。", mobile) #NOTE: re-notify # 30 seconds later, send sms 1 time. task = RepeatedTimer(30, _resend_alarm, 1) task.start() elif report.rName == EVENTER.RNAME.ILLEGALSHAKE: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_ILLEGALSHAKE_NOLOC % (name, terminal_time) else: sms = SMSCode.SMS_ILLEGALSHAKE % (name, report_name, terminal_time) #NOTE: re-notify _date = datetime.datetime.fromtimestamp(int(report['timestamp'])) _seconds = _date.hour * 60 * 60 + _date.minute * 60 + _date.second if _seconds < 7 * 60 * 60 or _seconds > 19 * 60 * 60: _resend_alarm = functools.partial(self.sms_to_user, report.dev_id, sms+u"此条短信为重复提醒,请注意您的车辆状态。", mobile) # 30 seconds later, send sms 1 time. task = RepeatedTimer(30, _resend_alarm, 1) task.start() elif report.rName == EVENTER.RNAME.EMERGENCY: whitelist = QueryHelper.get_white_list_by_tid(report.dev_id, self.db) if whitelist: white_str = ','.join(white['mobile'] for white in whitelist) if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_SOS_OWNER_NOLOC % (name, white_str, terminal_time) sms_white = SMSCode.SMS_SOS_WHITE_NOLOC % (name, terminal_time) else: sms = SMSCode.SMS_SOS_OWNER % (name, white_str, report_name, terminal_time) sms_white = SMSCode.SMS_SOS_WHITE % (name, report_name, terminal_time) else: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_SOS_NOLOC % (name, terminal_time) else: sms = SMSCode.SMS_SOS % (name, report_name, terminal_time) elif report.rName == EVENTER.RNAME.POWERDOWN: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_POWERDOWN_NOLOC % (name, terminal_time) else: sms = SMSCode.SMS_POWERDOWN % (name, report_name, terminal_time) elif report.rName == EVENTER.RNAME.REGION_OUT: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_REGION_OUT_NOLOC % (name, safe_unicode(report['region']['region_name']), terminal_time) else: sms = SMSCode.SMS_REGION_OUT % (name, safe_unicode(report['region']['region_name']), report_name, terminal_time) elif report.rName == EVENTER.RNAME.REGION_ENTER: if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_REGION_ENTER_NOLOC % (name, safe_unicode(report['region']['region_name']), terminal_time) else: sms = SMSCode.SMS_REGION_ENTER % (name, safe_unicode(report['region']['region_name']), report_name, terminal_time) elif report.rName == EVENTER.RNAME.SPEED_LIMIT: sms_dct = dict(name=name, report_name=report_name, speed=int(report.get('speed',0)), terminal_time=terminal_time) if report_name in [ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_NAME_NONE], ErrorCode.ERROR_MESSAGE[ErrorCode.LOCATION_FAILED]]: sms = SMSCode.SMS_SPEED_LIMIT_NOLOC % sms_dct else: sms = SMSCode.SMS_SPEED_LIMIT % sms_dct else: pass #wap_url = 'http://api.map.baidu.com/staticimage?center=%s,%s%26width=800%26height=800%26zoom=17%26markers=%s,%s' #wap_url = wap_url % (report.lon/3600000.0, report.lat/3600000.0, report.lon/3600000.0, report.lat/3600000.0) #wap_url = 'http://api.map.baidu.com/staticimage?center=' +\ # str(report.cLon/3600000.0) + ',' + str(report.cLat/3600000.0) +\ # '&width=320&height=480&zoom=17&markers=' +\ # str(report.cLon/3600000.0) + ',' + str(report.cLat/3600000.0) if report.cLon and report.cLat: clon = '%0.3f' % (report.cLon/3600000.0) clat = '%0.3f' % (report.cLat/3600000.0) url = ConfHelper.UWEB_CONF.url_out + '/wapimg?clon=' + clon + '&clat=' + clat tiny_id = URLHelper.get_tinyid(url) if tiny_id: base_url = ConfHelper.UWEB_CONF.url_out + UWebHelper.URLS.TINYURL tiny_url = base_url + '/' + tiny_id logging.info("[EVENTER] get tiny url successfully. tiny_url:%s", tiny_url) self.redis.setvalue(tiny_id, url, time=EVENTER.TINYURL_EXPIRY) sms += u"点击" + tiny_url + u" 查看定位器位置。" if sms_white: sms_white += u"点击" + tiny_url + u" 查看定位器位置。" self.sms_to_whitelist(sms_white, whitelist) else: logging.info("[EVENTER] get tiny url failed.") else: logging.info("[EVENTER] location failed.") self.sms_to_user(report.dev_id, sms, mobile)
def check_single_event(self, ori_location, single): """Check enter or out single workflow: get old_single_status accordinding to single and tid get old_single_time accordinding to single and tid check single_status according distance, then keep single_status in redis if not old_single_status: skip if old_single_time and location's gps_time <= old_region_time: skip check single event according to single_status and old_single_staus if single event: keep single_status, single_time in redis """ if not (ori_location and single): logging.info("[EVENTER] query data is invalid, ori_location: %s, single: %s, do not check.", ori_location, single) return None if not (ori_location['cLat'] and ori_location['cLon']): logging.info("[EVENTER] location is invalid, ori_location: %s, do not check.", ori_location) return None # BIG NOTE: python grammar, shallow copy will change origen data. location = copy.deepcopy(dict(ori_location)) location = DotDict(location) old_single_status_key = get_single_status_key(location['dev_id'], single.single_id) old_single_status = self.redis.getvalue(old_single_status_key) old_single_time_key = get_single_time_key(location['dev_id'], single.single_id) old_single_time = self.redis.getvalue(old_single_time_key) if single.single_shape == UWEB.SINGLE_SHAPE.CIRCLE: # get distance beteween now location and the centre of the region distance = lbmphelper.get_distance(single.single_longitude, single.single_latitude, location.cLon, location.cLat) if distance >= single.single_radius: single_status = EVENTER.CATEGORY.SINGLE_OUT rname = EVENTER.RNAME.SINGLE_OUT else: single_status = EVENTER.CATEGORY.SINGLE_ENTER rname = EVENTER.RNAME.SINGLE_ENTER elif single.single_shape == UWEB.SINGLE_SHAPE.POLYGON: polygon = {'name':'', 'points':[]} points = single.points point_lst = points.split(':') for point in point_lst: latlon = point.split(',') dct = {'lat':float(latlon[0])/3600000, 'lon':float(latlon[1])/3600000} polygon['points'].append(dct) polygon['name'] = single.single_name if PtInPolygon(location, polygon): single_status = EVENTER.CATEGORY.SINGLE_ENTER rname = EVENTER.RNAME.SINGLE_ENTER else: single_status = EVENTER.CATEGORY.SINGLE_OUT rname = EVENTER.RNAME.SINGLE_OUT else: #NOTE: here should never occur. logging.error("[EVENTER] unknow single_shape: %s, single: %s, skip it", single.single_shape, single) #NOTE: skip the time if old_single_time: if int(location['gps_time']) <= int(old_single_time): logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_single_time: %s, skip it", location['gps_time'], old_single_time) return location logging.info('old_single_status_key: %s, single_status: %s', old_single_status_key, single_status) # keep region status self.redis.setvalue(old_single_status_key, single_status) logging.info("rname:%s, old status:%s, current status:%s, tid:%s", safe_unicode(single.single_name), old_single_status, single_status, location['dev_id']) if not old_single_status: logging.info("[EVENTER] old_single_status: %s is invalid, skip it", old_single_status) # skip the first region event return location # check single event if single_status != old_single_status: self.redis.setvalue(old_single_status_key, single_status) self.redis.setvalue(old_single_time_key, location['gps_time']) # 2: complete the location location['category'] = single_status location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need location['rName'] = rname location['single'] = single location['single_id'] = single.single_id # 3. keep it in db # out first, then enter if single_status == EVENTER.CATEGORY.SINGLE_ENTER: single_event = self.db.get("SELECT id as seid, tid, sid, start_time, end_time" " FROM T_SINGLE_EVENT" " WHERE tid = %s " " AND sid = %s" " AND start_time !=0" " AND end_time = 0 " " ORDER BY id DESC LIMIT 1", location['dev_id'], location['single_id']) if not single_event: pass else: self.db.execute("UPDATE T_SINGLE_EVENT" " SET end_time = %s" " WHERE id = %s", location['gps_time'], single_event['seid']) elif single_status == EVENTER.CATEGORY.SINGLE_OUT: last_pvt_key = get_last_pvt_key(location['dev_id']) last_pvt = self.redis.getvalue(last_pvt_key) if last_pvt: gps_time = last_pvt['gps_time'] else: gps_time = location['gps_time'] self.db.execute("INSERT INTO T_SINGLE_EVENT(tid, sid, start_time)" " VALUES(%s, %s, %s)", location['dev_id'], location['single_id'], gps_time) return location
def post(self): """Retrive various event. """ status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) tid = data.get('tid', None) tids = data.get('tids', None) tids = str_to_list(tids) if not tids: tids = [tid, ] if tid else [] tids = [str(t) for t in tids] if not tid: tid = tids[0] if len(tids) > 0 else '' # check tid whether exist in request and update current_user self.check_tid(tid) logging.info("[UWEB] Event request: %s, uid: %s, tid: %s, tids: %s", data, self.current_user.uid, self.current_user.tid, tids) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT logging.exception("[UWEB] Invalid data format. body: %s, Exception: %s", self.request.body, e.args) self.write_ret(status) return try: terminal = QueryHelper.get_available_terminal(self.current_user.tid, self.db) if not terminal: status = ErrorCode.LOGIN_AGAIN logging.error( "[UWEB] The terminal with tid: %s does not exist, redirect to login.html", self.current_user.tid) self.write_ret(status) return page_size = int(data.get('pagesize', UWEB.LIMIT.PAGE_SIZE)) category = data.get('category', None) categories = data.get('categories', None) page_number = int(data.pagenum) page_count = int(data.pagecnt) start_time = data.start_time end_time = data.end_time # NOTE: all catgories all_categories = [2, # powerlow 3, # illegalshake 4, # illegalmove 5, # sos 6, # hearbeat lost 7, # region enter 8, # retion out 9, # power off 10, # stop 11, # speed_limit ] if category is not None: if int(category) == -1: categories = all_categories else: categories = [int(category), ] elif categories: if int(categories[0]) == -1: categories = all_categories else: categories = [int(c) for c in categories] # NOTE: for individual: the interval between start_time and end_time is one week; # for enterprise: no need to check time interval if self.current_user.cid != UWEB.DUMMY_CID: hide_lst = [5] # enterprise: no sos else: # individual: no stop hide_lst = [5, 10, 11] if (int(end_time) - int(start_time)) > UWEB.QUERY_INTERVAL: self.write_ret(ErrorCode.QUERY_INTERVAL_EXCESS) return # we need return the event count to GUI at first time query if page_count == -1: sql = ("SELECT COUNT(*) as count FROM V_EVENT" " WHERE tid IN %s " + " AND category IN %s" + " AND (timestamp BETWEEN %s AND %s)")\ % (tuple(tids + DUMMY_IDS_STR), tuple(list(set(categories) - set(hide_lst)) + DUMMY_IDS), start_time, end_time) res = self.db.get(sql) event_count = res.count d, m = divmod(event_count, page_size) page_count = (d + 1) if m else d sql = ("SELECT tid, latitude, longitude, clatitude, clongitude," " timestamp, name, type, speed, degree," " category, pbat, terminal_type, fobid, rid, locate_error" " FROM V_EVENT" " WHERE tid IN %s" " AND (timestamp BETWEEN %s AND %s)" " AND category IN %s" " ORDER BY timestamp DESC" " LIMIT %s, %s") %\ (tuple(tids + DUMMY_IDS_STR), start_time, end_time, tuple(list(set(categories) - set(hide_lst)) + DUMMY_IDS), page_number * page_size, page_size) events = self.db.query(sql) alias_dict = {} for tid in tids: terminal_info_key = get_terminal_info_key(tid) terminal_info = self.redis.getvalue(terminal_info_key) alias_dict[tid] = terminal_info['alias'] if terminal_info[ 'alias'] else terminal_info['mobile'] # Adjust the fields in events. for event in events: event['alias'] = alias_dict[event['tid']] event['pbat'] = event['pbat'] if event[ 'pbat'] is not None else 0 event['fobid'] = event['fobid'] if event[ 'fobid'] is not None else u'' event['name'] = event['name'] if event[ 'name'] is not None else u'' event['degree'] = float(event['degree']) event['speed'] = float(event['speed']) event['comment'] = '' if event['category'] == EVENTER.CATEGORY.POWERLOW: if event['terminal_type'] == '1': if int(event['pbat']) == 100: event['comment'] = ErrorCode.ERROR_MESSAGE[ ErrorCode.TRACKER_POWER_FULL] elif int(event['pbat']) <= 5: event['comment'] = ErrorCode.ERROR_MESSAGE[ ErrorCode.TRACKER_POWER_OFF] else: event['comment'] = ( ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_LOW]) % event['pbat'] else: event['comment'] = ErrorCode.ERROR_MESSAGE[ ErrorCode.FOB_POWER_LOW] % event['fobid'] if event['category'] in [EVENTER.CATEGORY.REGION_ENTER, EVENTER.CATEGORY.REGION_OUT]: region = self.db.get("SELECT name AS region_name" " FROM T_REGION" " WHERE id = %s", event.rid) region_name = safe_unicode( region.region_name) if region else u'' event['comment'] = u'围栏名:' + region_name self.write_ret(status, dict_=DotDict(events=events, pagecnt=page_count)) except Exception as e: logging.exception("[UWEB] uid:%s, tid:%s get alarm info failed. Exception: %s", self.current_user.uid, self.current_user.tid, e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)
def handle_locationdesc(info, address, connection, channel, exchange, gw_binding, db, redis): """ S10 locationdesc packet 0: success, then return locationdesc to terminal and record new terminal's address 1: invalid SessionID """ try: head = info.head body = info.body dev_id = head.dev_id if len(body) == 6: body.append(20) logging.info("[GW] old version is compatible, append locate_error") resend_key, resend_flag = get_resend_flag(redis, dev_id, head.timestamp, head.command) go_ahead = False args = DotDict(success=GATEWAY.RESPONSE_STATUS.SUCCESS, locationdesc="", ew="E", lon=0.0, ns="N", lat=0.0) sessionID = QueryHelper.get_terminal_sessionID(dev_id, redis) if sessionID != head.sessionID: args.success = GATEWAY.RESPONSE_STATUS.INVALID_SESSIONID logging.error("[GW] Invalid sessionID, terminal: %s", head.dev_id) else: if resend_flag: logging.warn("[GW] Recv resend packet, head: %s, body: %s and drop it!", info.head, info.body) else: go_ahead = True #NOTE: Check ydcw or ajt ajt = QueryHelper.get_ajt_whitelist_by_mobile(head.dev_id, db) if ajt: url_out = ConfHelper.UWEB_CONF.ajt_url_out else: url_out = ConfHelper.UWEB_CONF.url_out if go_ahead: redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) ldp = LocationDescParser(body, head) location = ldp.ret logging.info("[GW] T10 packet parsered:%s", location) if not location.has_key('gps_time'): location['gps_time'] = int(time.time()) logging.info("[GW] what's up? location:%s hasn't gps_time.", location) location['t'] = EVENTER.INFO_TYPE.POSITION if location['valid'] != GATEWAY.LOCATION_STATUS.SUCCESS: cellid = True else: cellid = False location = lbmphelper.handle_location(location, redis, cellid=cellid, db=db) location.name = location.get('name') if location.get('name') else "" location.name = safe_unicode(location.name) user = QueryHelper.get_user_by_tid(head.dev_id, db) tname = QueryHelper.get_alias_by_tid(head.dev_id, redis, db) dw_method = u'GPS' if not cellid else u'基站' if location.cLat and location.cLon: if user: current_time = get_terminal_time(int(time.time())) sms = SMSCode.SMS_DW_SUCCESS % (tname, dw_method, location.name, safe_unicode(current_time)) url = url_out + '/wapimg?clon=' +\ str(location.cLon/3600000.0) + '&clat=' + str(location.cLat/3600000.0) tiny_id = URLHelper.get_tinyid(url) if tiny_id: base_url = url_out + UWebHelper.URLS.TINYURL tiny_url = base_url + '/' + tiny_id logging.info("[GW] get tiny url successfully. tiny_url:%s", tiny_url) redis.setvalue(tiny_id, url, time=EVENTER.TINYURL_EXPIRY) sms += u"点击 " + tiny_url + u" 查看定位器位置。" else: logging.info("[GW] get tiny url failed.") SMSHelper.send(user.owner_mobile, sms) else: if user: sms = SMSCode.SMS_DW_FAILED % (tname, dw_method) SMSHelper.send(user.owner_mobile, sms) if not (location.lat and location.lon): args.success = GATEWAY.RESPONSE_STATUS.CELLID_FAILED else: insert_location(location, db, redis) lc = LocationDescRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=dev_id) update_terminal_status(redis, head.dev_id, address) append_gw_request(request, connection, channel, exchange, gw_binding) except: logging.exception("[GW] Handle locationdesc exception.") GWException().notify()
def day_notify(self): logging.info("[CELERY] checkertask day_notify started.") try: #NOTE: avoid sms is sent when the server is restart. _date = datetime.datetime.fromtimestamp(int(time.time())) if _date.hour not in (9,10): return #NOTE: get all terminals which may be notified, record them into T_MILEAGE_NOTIFICATION. terminals = self.db.query("SELECT tid, day_notification, notify_count, left_days" " FROM T_DAY_NOTIFICATION" " WHERE day_notification != 0" " AND notify_count < 3") for terminal in terminals: if int(time.time()) < terminal['day_notification']: # it's not time to notify continue terminal_info = QueryHelper.get_terminal_by_tid(terminal.tid, self.db) tid = terminal['tid'] owner_mobile = terminal_info['owner_mobile'] assist_mobile = terminal_info['assist_mobile'] t = self.db.get("SELECT distance_current FROM T_TERMINAL_INFO WHERE tid = %s", terminal.tid) #distance_current = terminal_info['distance_current'] distance_current = t['distance_current'] mobile = terminal_info['mobile'] notify_count = terminal['notify_count'] left_days = terminal['left_days'] day_notification= terminal['day_notification'] if left_days == 1: # it should be notified this day logging.info("[CELERY] Send day notification." " tid: %s, mobile: %s, owner_mobile: %s, assist_mobile: %s," " day_notification: %s" " notify_count: %s, left_days: %s.", tid, mobile, owner_mobile, assist_mobile, day_notification, notify_count, left_days) self.db.execute("UPDATE T_DAY_NOTIFICATION" " SET notify_count = %s," " left_days = %s," " notify_time = %s" " WHERE tid = %s", notify_count+1, 3, int(time.time()), tid) if owner_mobile: sms = SMSCode.SMS_NOTIFY_DAY % (terminal_info['alias']) SMSHelper.send(owner_mobile, sms) if assist_mobile: user = QueryHelper.get_user_by_mobile(owner_mobile, self.db) name = safe_unicode(user['name']) sms = SMSCode.SMS_NOTIFY_ASSIST_DAY % (mobile, owner_mobile, name) SMSHelper.send(assist_mobile, sms) elif left_days in (2, 3): # do not notify, just postpone one day logging.info("[CELERY] Do not send day notification this day," " just modify the left_days." " tid: %s, mobile: %s, owner_mobile: %s, assist_mobile: %s," " day_notification: %s" " notify_count: %s, left_days: %s.", tid, mobile, owner_mobile, assist_mobile, day_notification, notify_count, left_days) self.db.execute("UPDATE T_DAY_NOTIFICATION" " SET left_days = %s" " WHERE tid = %s", left_days-1, tid) else: #NOTE: It should never occur. logging.info("[CELERY] Invalid left_days: %s, mobile: %s.", left_days, mobile) except Exception as e: logging.exception("[CELERY] Day notification failed. Exception: %s.", e.args)
def post(self): """Get event info. """ status = WXErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) logging.info("[WEIXIN] event request body: %s", self.request.body) tid = data.tid openid = data.get('openid') start_time = data.start_time end_time = data.end_time except Exception as e: status = WXErrorCode.ILLEGAL_DATA_FORMAT logging.exception("[WEIXIN] Invalid data format. Exception: %s", e.args) self.render('error.html', status=status, message=WXErrorCode.ERROR_MESSAGE[status]) return try: checksql = "SELECT uid FROM T_USER WHERE openid = '%s'" % openid user = self.db.query(checksql) if not user: status = WXErrorCode.USER_BIND message = WXErrorCode.ERROR_MESSAGE[status] self.render('error.html', status=status, message=message) return sql = ("SELECT tid, latitude, longitude, clatitude, clongitude," " timestamp, name, type, speed, degree," " category, pbat, terminal_type, fobid, rid, locate_error" " FROM V_EVENT" " WHERE tid ='%s'" " AND (timestamp BETWEEN %s AND %s)" " ORDER BY timestamp DESC") %\ (tid, start_time, end_time) #sql = ("SELECT tid, latitude, longitude, clatitude, clongitude," # " timestamp, name, type, speed, degree," # " category, pbat, terminal_type, fobid, rid, locate_error" # " FROM V_EVENT" # " where timestamp BETWEEN %s AND %s" # " ORDER BY timestamp DESC limit 21 ") %\ # (start_time, end_time) events = self.db.query(sql) alias_dict = {} terminal_info_key = get_terminal_info_key(tid) terminal_info = self.redis.getvalue(terminal_info_key) alias_dict[tid] = terminal_info['alias'] if terminal_info['alias'] else terminal_info['mobile'] # change the type form decimal to float. for event in events: event['alias'] = '' # alias_dict[event['tid']] event['pbat'] = event['pbat'] if event['pbat'] is not None else 0 event['fobid'] = event['fobid'] if event['fobid'] is not None else u'' event['name'] = event['name'] if event['name'] is not None else u'' event['degree'] = float(event['degree']) event['speed'] = float(event['speed']) event['comment'] = '' if event['category'] == EVENTER.CATEGORY.POWERLOW: if event['terminal_type'] == '1': if int(event['pbat']) == 100: event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_FULL] elif int(event['pbat']) <= 5: event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_OFF] else: event['comment'] = (ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_LOW]) % event['pbat'] else: event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.FOB_POWER_LOW] % event['fobid'] if event['category'] in [EVENTER.CATEGORY.REGION_ENTER, EVENTER.CATEGORY.REGION_OUT]: region = self.db.get("SELECT name AS region_name" " FROM T_REGION" " WHERE id = %s", event.rid) region_name = safe_unicode(region.region_name) if region else u'' event['comment'] = u'围栏名:'+ region_name r = events * 2 + events[0:6] self.write_ret(status, dict_=DotDict(res=r)) print "jjjjjj res:",r except Exception as e: logging.exception("[WEIXIN] search event failed POST(), Execption:%s", e.args) status=WXErrorCode.FAILED message=WXErrorCode.ERROR_MESSAGE[status] self.render('error.html', status=status, message=message)