def get(self): """Jump to attendance.html, provide alias """ mobile = self.get_argument('mobile', None) terminal = self.db.get("SELECT id, tid FROM T_TERMINAL_INFO" " WHERE mobile = %s" " AND service_status = %s", mobile, UWEB.SERVICE_STATUS.ON) if not terminal: logging.error("The terminal with mobile: %s does not exist, redirect to login.html", self.current_user.tid) self.render("login.html", map_type=ConfHelper.LBMP_CONF.map_type, alias='') return alias = QueryHelper.get_alias_by_tid(terminal['tid'], self.redis, self.db) self.render("attendance.html", map_type=ConfHelper.LBMP_CONF.map_type, alias=alias)
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): """Retrive various attendance. """ status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) mobile = data.get('mobile', None) mobiles = str_to_list(mobile) if not mobiles: terminals = self.db.query("SELECT tmobile FROM V_TERMINAL" " where cid = %s", self.current_user.cid) mobiles = [str(terminal['tmobile']) for terminal in terminals] logging.info("[UWEB] attendance request: %s, cid: %s", data, self.current_user.cid) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT logging.exception("[UWEB] Invalid data format. Exception: %s", e.args) self.write_ret(status) return try: page_size = int(data.get('pagesize', UWEB.LIMIT.PAGE_SIZE)) page_number = int(data.pagenum) page_count = int(data.pagecnt) start_time = data.start_time end_time = data.end_time # we need return the event count to GUI at first time query if page_count == -1: sql = ("SELECT COUNT(*) as count FROM V_ATTENDANCE" " WHERE mobile IN %s " " AND (timestamp BETWEEN %s AND %s)") sql = sql % (tuple(mobiles + DUMMY_IDS_STR), 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 mobile as tid, mobile, clatitude, clongitude," " timestamp, name, type, speed, degree," " locate_error" " FROM V_ATTENDANCE" " WHERE mobile IN %s" " AND (timestamp BETWEEN %s AND %s)" " ORDER BY timestamp DESC" " LIMIT %s, %s") sql = sql % (tuple(mobiles + DUMMY_IDS_STR), start_time, end_time, page_number * page_size, page_size) res = self.db.query(sql) # change the type form decimal to float. for r in res: r['alias'] = QueryHelper.get_alias_by_tid(r['tid'], self.redis, self.db) r['name'] = r['name'] if r['name'] is not None else u'' r['degree'] = float(r['degree']) r['speed'] = float(r['speed']) r['comment'] = '' self.write_ret(status, dict_=DotDict(res=res, pagecnt=page_count)) except Exception as e: status = ErrorCode.SERVER_BUSY logging.exception("[UWEB] cid:%s get attendance info failed. Exception: %s", self.current_user.cid, e.args) self.write_ret(status)
def post(self): try: line_id = int(self.get_argument('line_id')) logging.info("[CLIENT] map request line_id : %s", line_id) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT self.write_ret(status) return try: cars_info = [] status = ErrorCode.SUCCESS terminals = self.db.query("SELECT tid " " FROM T_CAR_LINE, T_LINE_PASSENGER" " WHERE T_CAR_LINE.line_id = T_LINE_PASSENGER.line_id" " AND T_CAR_LINE.line_id = %s", line_id) tids = [terminal.tid for terminal in terminals] # 1 inquery data for tid in tids: # 1: get terminal info terminal_info_key = get_terminal_info_key(tid) terminal = self.redis.getvalue(terminal_info_key) if not terminal: terminal = self.db.get("SELECT mannual_status, defend_status," " fob_status, mobile, login, gps, gsm," " pbat, keys_num" " FROM T_TERMINAL_INFO" " WHERE tid = %s", tid) terminal = DotDict(terminal) terminal['alias'] = QueryHelper.get_alias_by_tid(tid, self.redis, self.db) fobs = self.db.query("SELECT fobid FROM T_FOB" " WHERE tid = %s", tid) terminal['fob_list'] = [fob.fobid for fob in fobs] self.redis.setvalue(terminal_info_key, DotDict(terminal)) if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP: terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE # 2: get location location_key = get_location_key(str(tid)) location = self.redis.getvalue(location_key) if not location: location = self.db.get("SELECT id, speed, timestamp, category, name," " degree, type, latitude, longitude, clatitude, clongitude, timestamp" " FROM T_LOCATION" " WHERE tid = %s" " AND NOT (clatitude = 0 AND clongitude = 0)" " ORDER BY timestamp DESC" " LIMIT 1", tid) if location: mem_location = DotDict({'id':location.id, 'latitude':location.latitude, 'longitude':location.longitude, 'type':location.type, 'clatitude':location.clatitude, 'clongitude':location.clongitude, 'timestamp':location.timestamp, 'name':location.name, 'degree':float(location.degree), 'speed':float(location.speed)}) self.redis.setvalue(location_key, mem_location, EVENTER.LOCATION_EXPIRY) if location and location['name'] is None: location['name'] = '' car_info=dict(defend_status=terminal['defend_status'] if terminal['defend_status'] is not None else 1, mannual_status=terminal['mannual_status'] if terminal['mannual_status'] is not None else 1, fob_status=terminal['fob_status'] if terminal['fob_status'] is not None else 0, timestamp=location['timestamp'] if location else 0, speed=location.speed if location else 0, # NOTE: degree's type is Decimal, float() it before json_encode degree=float(location.degree) if location else 0.00, name=location.name if location else '', type=location.type if location else 1, latitude=location['latitude'] if location else 0, longitude=location['longitude'] if location else 0, clatitude=location['clatitude'] if location else 0, clongitude=location['clongitude'] if location else 0, login=terminal['login'] if terminal['login'] is not None else 0, gps=terminal['gps'] if terminal['gps'] is not None else 0, gsm=terminal['gsm'] if terminal['gsm'] is not None else 0, pbat=terminal['pbat'] if terminal['pbat'] is not None else 0, mobile=terminal['mobile'], alias=terminal['alias'], #keys_num=terminal['keys_num'] if terminal['keys_num'] is not None else 0, keys_num=0, fob_list=terminal['fob_list'] if terminal['fob_list'] else []) cars_info.append(car_info) self.write_ret(status, dict_=DotDict(cars_info=cars_info)) except Exception as e: logging.exception("[CLIENT] map show tids lastinfo failed, line_id : %s. Exception: %s", line_id, e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)
def post(self): """Provide some statistics about terminals. """ status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) logging.info("[UWEB] event statistic 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: res = [] page_size = UWEB.LIMIT.PAGE_SIZE page_number = int(data.pagenum) page_count = int(data.pagecnt) start_time = data.start_time end_time = data.end_time tids = str_to_list(data.tids) # the interval between start_time and end_time is one week if self.current_user.cid != UWEB.DUMMY_CID: # no checks for enterprise pass elif (int(end_time) - int(start_time)) > UWEB.QUERY_INTERVAL: self.write_ret(ErrorCode.QUERY_INTERVAL_EXCESS) return CATEGORY_DCT = DotDict(illegalmove=EVENTER.CATEGORY.ILLEGALMOVE, illegashake=EVENTER.CATEGORY.ILLEGALSHAKE, #sos=EVENTER.CATEGORY.EMERGENCY, heartbeat_lost=EVENTER.CATEGORY.HEARTBEAT_LOST, powerlow=EVENTER.CATEGORY.POWERLOW) if page_count == -1: count = len(tids) d, m = divmod(count, page_size) page_count = (d + 1) if m else d for tid in tids: res_item = {} res_item['alias'] = QueryHelper.get_alias_by_tid(tid, self.redis, self.db) for key, category in CATEGORY_DCT.iteritems(): item = self.db.get("SELECT COUNT(*) as count FROM V_EVENT" " WHERE tid = %s" " AND (timestamp BETWEEN %s AND %s)" " AND category = %s", tid, start_time, end_time, category) res_item[key] = item.count res.append(res_item) # store resutl in redis m = hashlib.md5() m.update(self.request.body) hash_ = m.hexdigest() mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_) self.redis.setvalue(mem_key, res, time=UWEB.STATISTIC_INTERVAL) res = res[(page_number * page_size):((page_number+1) * page_size)] self.write_ret(status, dict_=DotDict(res=res, pagecnt=page_count, hash_=hash_)) except Exception as e: logging.exception("[UWEB] event statistic, uid:%s, tid:%s failed. Exception: %s", self.current_user.uid, self.current_user.tid, e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)
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 post(self): """We store cid, oid, uid,tid and sim in the cookie to authenticate the user. """ username_ = self.get_argument("username", "") username = base64.b64decode(username_)[128:] if len(username_) > 128 else username_ password_ = self.get_argument("password", "") password = base64.b64decode(password_)[128:] if len(password_) > 128 else password_ captcha_ = self.get_argument("captcha", "") captcha = base64.b64decode(captcha_)[128:] if len(captcha_) > 128 else captcha_ user_type = self.get_argument("user_type", UWEB.USER_TYPE.PERSON) # NOTE: Get captchahash from cookie captchahash = self.get_secure_cookie("captchahash") logging.info("[UWEB] Browser login request, username: %s, password: %s, " " user_type: %s, catpcha: %s, captchahash: %s", username, password, user_type, captcha, captchahash) # must check username and password avoid sql injection. if not (username.isalnum() and password.isalnum()): self.render("login.html", username='', password='', user_type=user_type, message_captcha=None, message=ErrorCode.ERROR_MESSAGE[ErrorCode.ILLEGAL_LABEL]) return m = hashlib.md5() m.update(captcha.lower()) m.update(UWEB.HASH_SALT) hash_ = m.hexdigest() if hash_.lower() != captchahash.lower(): self.render("login.html", username=username, password=password, user_type=user_type, message=None, message_captcha=ErrorCode.ERROR_MESSAGE[ErrorCode.WRONG_CAPTCHA]) return # check the user, return uid, tid, sim and status cid, oid, uid, terminals, _user_type, status = self.login_passwd_auth( username, password, user_type) if status == ErrorCode.SUCCESS: # role: 0: person; 1: operator; 2: enterprise # method 0: web; 1: android; 2: ios role = None user_id = None if _user_type == UWEB.USER_TYPE.PERSON: role = 0 user_id = uid elif _user_type == UWEB.USER_TYPE.OPERATOR: role = 1 user_id = oid elif _user_type == UWEB.USER_TYPE.CORP: role = 2 user_id = cid else: logging.error("[UWEB] invalid user_type: %s", _user_type) pass if (role is not None) and (user_id is not None): # NOTE: keep the login log login_info = dict(uid=user_id, role=role, method=0) record_login_user(login_info, self.db) # keep current_user in cookie self.bookkeep(dict(cid=cid, oid=oid, uid=uid if uid else cid, tid=terminals[0].tid, sim=terminals[0].sim)) # keep client_id in cookie self.set_client_id(username) user_info = QueryHelper.get_user_by_uid(uid, self.db) if user_info: # NOTE: if alias is null, provide cnum or sim instead for terminal in terminals: terminal['alias'] = QueryHelper.get_alias_by_tid( terminal.tid, self.redis, self.db) self.login_sms_remind( uid, user_info.mobile, terminals, login="******") else: # corp maybe has no user pass #NOTE:clear cookies self.clear_cookie('captchahash') self.clear_cookie('captchahash_sms') self.clear_cookie('bdshare_firstime') self.clear_cookie('USERCURRENTROLE') self.redirect(self.get_argument("next", "/index")) else: logging.info("[UWEB] username: %s login failed, message: %s", username, ErrorCode.ERROR_MESSAGE[status]) self.render("login.html", username=username, password=password, user_type=user_type, message_captcha=None, message=ErrorCode.ERROR_MESSAGE[status])
def _on_finish(db): self.db = db page_count = int(data.pagecnt) if statistic_mode == 'all': # all if page_count == -1: count = len(tids) d, m = divmod(count, page_size) page_count = (d + 1) if m else d reports = [] for item, tid in enumerate(tids): seq=item+1 dis_sum = Decimal() start_date = get_date_from_utc(start_time) end_date = get_date_from_utc(end_time) start_day = datetime.datetime.fromtimestamp(start_time) end_day = datetime.datetime.fromtimestamp(end_time) # get how many days the end_time and start_time cover days = abs(end_day-start_day).days+1 for item in range(days): distance = Decimal() timestamp = start_time+1*60*60*24*(item) date = get_date_from_utc(timestamp) year, month, day = date.year, date.month, date.day start_time_, end_time_ = start_end_of_day(year=year, month=month, day=day) points = self.db.query("SELECT longitude, latitude FROM T_LOCATION" " WHERE tid = %s" " AND (timestamp BETWEEN %s AND %s)" " AND type = 0" " ORDER BY timestamp asc", tid, start_time_+start_period_, start_time_+end_period_) for i in range(len(points)-1): if points[i].longitude and points[i].latitude and \ points[i+1].longitude and points[i+1].latitude: dis = get_distance(points[i].longitude, points[i].latitude, points[i+1].longitude, points[i+1].latitude) distance += Decimal(str(dis)) # meter --> km distance = '%0.1f' % (distance/1000,) dis_sum += Decimal(distance) alias = QueryHelper.get_alias_by_tid(tid, self.redis, self.db) dct = dict(seq=seq, alias=alias, distance=float(dis_sum)) reports.append(dct) # orgnize and store the data to be downloaded m = hashlib.md5() m.update(self.request.body) hash_ = m.hexdigest() mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_) self.redis.setvalue(mem_key, (statistic_mode, reports, 0), time=UWEB.STATISTIC_INTERVAL) reports= reports[(page_number * page_size):((page_number+1) * page_size)] self.write_ret(status, dict_=DotDict(res=reports, pagecnt=page_count, hash_=hash_)) else: # single tid = tids[0] delta = end_time - start_time # end_time must bigger than start_time d, m = divmod(delta, 60*60*24) start_date = get_date_from_utc(start_time) end_date = get_date_from_utc(end_time) start_day = datetime.datetime.fromtimestamp(start_time) end_day = datetime.datetime.fromtimestamp(end_time) # get how many days the end_time and start_time cover days = abs(end_day-start_day).days+1 #if days == 0: # if start_date.day == end_date.day: # days = 1 # else: # days = 2 #else: # days = days+1 if m else days # if end_day.hour*60*60 + end_day.minute*60 + end_day.second < start_day.hour*60*60 + start_day.minute*60 + start_day.second: # days = days+1 res = [] graphics = [] counts = [] dis_sum = Decimal() current_time = int(time.time()) sql_cmd = ("SELECT longitude, latitude FROM T_LOCATION" " WHERE tid = %s" " AND (timestamp BETWEEN %s AND %s)" " AND type = 0" " ORDER BY timestamp asc") #last_cmd = ("SELECT timestamp FROM T_LOCATION" # " WHERE tid = %s" # " AND (timestamp BETWEEN %s AND %s)" # " AND type = 0" # " ORDER BY timestamp desc limit 1") #next_cmd = ("SELECT timestamp FROM T_LOCATION" # " WHERE tid = %s" # " AND (timestamp BETWEEN %s AND %s)" # " AND type = 0" # " ORDER BY timestamp asc limit 1") if days == 1: # start_time, end_time in the same day timestamp = start_time date = get_date_from_utc(timestamp) re = {} re['alias'] = '-'.join([str(date.year),str(date.month),str(date.day)]) distance = Decimal() points = self.db.query(sql_cmd, tid, start_time+start_period_, start_time+end_period_) for i in range(len(points)-1): if points[i].longitude and points[i].latitude and \ points[i+1].longitude and points[i+1].latitude: dis = get_distance(points[i].longitude, points[i].latitude, points[i+1].longitude, points[i+1].latitude) distance += Decimal(str(dis)) # meter --> km distance = '%0.1f' % (distance/1000,) graphics.append(float(distance)) dis_sum += Decimal(distance) re['distance'] = distance re['seq'] = 1 res.append(re) else: # start_time, end_time in different days for item in range(days): timestamp = start_time+1*60*60*24*(item) date = get_date_from_utc(timestamp) year, month, day = date.year, date.month, date.day start_time_, end_time_ = start_end_of_day(year=year, month=month, day=day) ## handle the first day and last day #if item == 0: # start_time_ = start_time #if item == days: # end_time_ = end_time #last_point = self.db.get(last_cmd, tid, start_time_-60*60*24, start_time_,) #next_point = self.db.get(next_cmd, tid, end_time_, end_time_+60*60*24) #start_time_ = last_point['timestamp'] if last_point else start_time_ #end_time_ = next_point['timestamp'] if next_point else end_time_ re = {} re['alias'] = '-'.join([str(year),str(month),str(day)]) distance = Decimal() points = self.db.query(sql_cmd, tid, start_time_+start_period_, start_time_+end_period_) for i in range(len(points)-1): if points[i].longitude and points[i].latitude and \ points[i+1].longitude and points[i+1].latitude: dis = get_distance(points[i].longitude, points[i].latitude, points[i+1].longitude, points[i+1].latitude) distance += Decimal(str(dis)) # meter --> km distance = '%0.1f' % (distance/1000,) graphics.append(float(distance)) dis_sum += Decimal(distance) re['distance'] = distance re['seq'] = item+1 res.append(re) counts = [float(dis_sum),] if page_count == -1: items_count = len(res) d, m = divmod(items_count, page_size) page_count = (d + 1) if m else d # store resutl in redis m = hashlib.md5() m.update(self.request.body) hash_ = m.hexdigest() mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_) self.redis.setvalue(mem_key, (statistic_mode, res, counts,), time=UWEB.STATISTIC_INTERVAL) res= res[page_number*page_size:(page_number+1)*page_size] self.write_ret(status, dict_=dict(res=res, counts=counts, graphics=graphics, pagecnt=page_count, hash_=hash_)) self.finish()
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 post(self): username = self.get_argument("username") password = self.get_argument("password") user_type = self.get_argument("user_type", UWEB.USER_TYPE.PERSON) biz_type = self.get_argument("biz_type", UWEB.BIZ_TYPE.YDWS) devid = self.get_argument("devid", "") versionname = self.get_argument("versionname", "") version_type = int(self.get_argument("version_type", 0)) logging.info("[UWEB] Android login request, username: %s, password: %s, user_type: %s, devid: %s", username, password, user_type, devid) # must check username and password avoid sql injection. if not (username.isalnum() and password.isalnum()): status = ErrorCode.ILLEGAL_LABEL self.write_ret(status) return # check the user, return uid, tid, sim and status cid, oid, uid, terminals, user_type, status = self.login_passwd_auth(username, password, user_type) logging.info( "[UWEB] Login auth, cid:%s, oid:%s, uid:%s, user_type:%s", cid, oid, uid, user_type) if status == ErrorCode.SUCCESS: # role: 0: person; 1: operator; 2: enterprise # method 0: web; 1: android; 2: ios # NOTE: keep the login log login_info = dict(uid=uid, role=0, method=1, versionname=versionname) record_login_user(login_info, self.db) self.bookkeep(dict(cid=cid, oid=oid, uid=uid, tid=terminals[0].tid, sim=terminals[0].sim)) user_info = QueryHelper.get_user_by_uid(uid, self.db) # NOTE: add cars_info, it's same as lastinfo cars_info = {} if user_type == UWEB.USER_TYPE.PERSON: terminals = QueryHelper.get_terminals_by_uid(uid, biz_type, self.db) elif user_type == UWEB.USER_TYPE.OPERATOR: terminals = QueryHelper.get_terminals_by_oid(oid, biz_type, self.db) elif user_type == UWEB.USER_TYPE.CORP: terminals = QueryHelper.get_terminals_by_cid(cid, biz_type, self.db) else: logging.error("[UWEB] Invalid user_type: %s", user_type) for terminal in terminals: # 1: get terminal tid = terminal.tid group_info = get_group_info_by_tid(self.db, tid) terminal_info_key = get_terminal_info_key(tid) terminal_cache = self.redis.getvalue(terminal_info_key) if terminal_cache: terminal['gps'] = terminal_cache['gps'] terminal['gsm'] = terminal_cache['gsm'] terminal['pbat'] = terminal_cache['pbat'] mobile = terminal['mobile'] terminal['keys_num'] = 0 if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP: terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE # NOTE: if alias is null, provide cnum or sim instead terminal['alias'] = QueryHelper.get_alias_by_tid( tid, self.redis, self.db) fobs = self.db.query("SELECT fobid FROM T_FOB" " WHERE tid = %s", tid) terminal['fob_list'] = [fob.fobid for fob in fobs] terminal['sim'] = terminal['mobile'] # 2: get location location = QueryHelper.get_location_info(tid, self.db, self.redis) if location and not (location.clatitude or location.clongitude): location_key = get_location_key(str(tid)) locations = [location, ] locations = get_locations_with_clatlon(locations, self.db) location = locations[0] self.redis.setvalue(location_key, location, EVENTER.LOCATION_EXPIRY) if location and location['name'] is None: location['name'] = '' avatar_name, avatar_path, avatar_full_path, avatar_time = self.get_avatar_info(mobile) service_status = QueryHelper.get_service_status_by_tmobile( self.db, mobile) car_dct = {} if location and location['type'] == 1: # cellid location['locate_error'] = 500 # mile car_info = dict(defend_status=terminal['defend_status'] if terminal['defend_status'] is not None else 1, service_status=service_status, mannual_status=terminal['mannual_status'] if terminal['mannual_status'] is not None else 1, fob_status=terminal['fob_status'] if terminal['fob_status'] is not None else 0, timestamp=location['timestamp'] if location else 0, speed=location.speed if location else 0, # NOTE: degree's type is Decimal, float() it before json_encode degree=float(location.degree) if location else 0.00, locate_error=location.get('locate_error', 20) if location else 20, bt_name=terminal['bt_name'] if terminal.get('bt_name', None) is not None else '', bt_mac=terminal['bt_mac'] if terminal.get('bt_mac', None) is not None else '', dev_type=terminal['dev_type'] if terminal.get('dev_type', None) is not None else 'A', name=location.name if location else '', type=location.type if location else 1, latitude=location['latitude'] if location else 0, longitude=location['longitude'] if location else 0, clatitude=location['clatitude'] if location else 0, clongitude=location['clongitude'] if location else 0, login=terminal['login'] if terminal['login'] is not None else 0, gps=terminal['gps'] if terminal['gps'] is not None else 0, gsm=terminal['gsm'] if terminal['gsm'] is not None else 0, pbat=terminal['pbat'] if terminal['pbat'] is not None else 0, mobile=terminal['mobile'], owner_mobile=terminal['owner_mobile'], alias=terminal['alias'], #keys_num=terminal['keys_num'] if terminal['keys_num'] is not None else 0, keys_num=0, group_id=group_info['group_id'], group_name=group_info['group_name'], icon_type=terminal['icon_type'], avatar_path=avatar_path, avatar_time=avatar_time, fob_list=terminal['fob_list'] if terminal['fob_list'] else []) car_dct[tid] = car_info cars_info.update(car_dct) #push_info = NotifyHelper.get_push_info() push_id = devid if devid else uid push_key = NotifyHelper.get_push_key(push_id, self.redis) lastinfo_time_key = get_lastinfo_time_key(uid) lastinfo_time = self.redis.getvalue(lastinfo_time_key) # uid --> android_push_list # check push_id whether exists in a old android_push_list old_android_push_list_key = self.redis.get(push_id) if old_android_push_list_key: old_android_push_list = self.redis.getvalue( old_android_push_list_key) if not isinstance(old_android_push_list, list): self.redis.delete(old_android_push_list_key) old_android_push_list = [] if old_android_push_list and (push_id in old_android_push_list): logging.info("[UWEB] push_id:%s has existed in a old_android_push_list: %s, so remove push_id from the list.", push_id, old_android_push_list) old_android_push_list.remove(push_id) self.redis.set(old_android_push_list_key, old_android_push_list) android_push_list_key = get_android_push_list_key(uid) android_push_list = self.redis.getvalue(android_push_list_key) android_push_list = android_push_list if android_push_list else [] if push_id not in android_push_list: android_push_list.append(push_id) self.redis.set(android_push_list_key, android_push_list) self.redis.set(push_id, android_push_list_key) logging.info("[UWEB] uid: %s, android_push_lst: %s", username, android_push_list) if user_info: self.login_sms_remind(uid, user_info.mobile, terminals, login="******") else: pass # corp maybe no user_info push = dict(id='', key='') json_data = WSPushHelper.register_wspush(uid, self.redis) data = json_data['data'] if data: id = data.get('push_id', '') key = data.get('psd', '') push['id'] = id push['key'] = key if version_type >= 1: terminals = [] for k, v in cars_info.iteritems(): v.update({'tid': k}) terminals.append(v) self.write_ret(status, dict_=DotDict(wspush=push, push_id=push_id, push_key=push_key, name=user_info.name if user_info else username, user_type=user_type, terminals=terminals, lastinfo_time=lastinfo_time,)) else: self.write_ret(status, dict_=DotDict(wspush=push, push_id=push_id, # app_key=push_info.app_key, push_key=push_key, name=user_info.name if user_info else username, user_type=user_type, cars_info=cars_info, lastinfo_time=lastinfo_time, cars=terminals)) else: logging.info("[UWEB] username: %s login failed, message: %s", username, ErrorCode.ERROR_MESSAGE[status]) self.write_ret(status)
def handle_defend(info, address, connection, channel, exchange, gw_binding, db, redis): """ S18 defend status report packet 0: success, then record new terminal's address 1: invalid SessionID """ try: head = info.head body = info.body dev_id = head.dev_id resend_key, resend_flag = get_resend_flag(redis, dev_id, head.timestamp, head.command) # old version is compatible if len(body) == 1: body.append('0') logging.info("[GW] old version is compatible, append mannual status 0") args = DotDict(success=GATEWAY.RESPONSE_STATUS.SUCCESS, command=head.command) sessionID = QueryHelper.get_terminal_sessionID(dev_id, redis) if sessionID != head.sessionID: args.success = GATEWAY.RESPONSE_STATUS.INVALID_SESSIONID else: if resend_flag: logging.warn("[GW] Recv resend packet, head: %s, body: %s and drop it!", info.head, info.body) else: redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) hp = AsyncParser(body, head) defend_info = hp.ret defend_info['mannual_status'] = defend_info['defend_status'] if defend_info['defend_source'] != 0: # come from sms or web if defend_info['defend_source'] == "1": _status = u"设防" if defend_info['defend_status'] == "1" else u"撤防" tname = QueryHelper.get_alias_by_tid(head.dev_id, redis, db) sms = SMSCode.SMS_DEFEND_SUCCESS % (tname, _status) user = QueryHelper.get_user_by_tid(head.dev_id, db) if user: SMSHelper.send(user.owner_mobile, sms) del defend_info['defend_status'] del defend_info['defend_source'] update_mannual_status(db, redis, head.dev_id, defend_info['mannual_status']) update_terminal_status(redis, head.dev_id, address) if args['success'] == GATEWAY.RESPONSE_STATUS.SUCCESS: acc_status_info_key = get_acc_status_info_key(dev_id) acc_status_info = redis.getvalue(acc_status_info_key) if acc_status_info and (not acc_status_info['t2_status']): # T2(query) is need args['success'] = 3 # acc_status is changed logging.info("[GW] ACC_status is changed, dev_id: %s, acc_status_info: %s", dev_id, acc_status_info) hc = AsyncRespComposer(args) request = DotDict(packet=hc.buf, address=address, dev_id=dev_id) append_gw_request(request, connection, channel, exchange, gw_binding) except: logging.exception("[GW] Handle defend status report exception.") GWException().notify()
def handle_old_login(t_info, address, connection, channel, exchange, gw_binding, db, redis): """ S1 Login response packet: 0 - success, then get a sessionID for terminal and record terminal's address 1 - illegal format of sim 2 - expired, service stop or endtime < now 3 - illegal sim, a mismatch between imsi and sim 4 - psd wrong. HK 5 - dev_id is empty 6 - not whitelist """ sms = None args = DotDict(success=GATEWAY.LOGIN_STATUS.SUCCESS, sessionID='') dev_id = t_info['dev_id'] resend_key, resend_flag = get_resend_flag(redis, dev_id, t_info.timestamp, t_info.command) logging.info("[GW] Checking terminal mobile: %s and owner mobile: %s, Terminal: %s", t_info['t_msisdn'], t_info['u_msisdn'], t_info['dev_id']) if not (check_phone(t_info['u_msisdn']) and check_phone(t_info['t_msisdn'])): args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.error("[GW] Login failed! Invalid terminal mobile: %s or owner_mobile: %s, dev_id: %s", t_info['t_msisdn'], t_info['u_msisdn'], t_info['dev_id']) return t_status = db.get("SELECT service_status" " FROM T_TERMINAL_INFO" " WHERE mobile = %s", t_info['t_msisdn']) if t_status and t_status.service_status == GATEWAY.SERVICE_STATUS.OFF: args.success = GATEWAY.LOGIN_STATUS.EXPIRED lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.error("[GW] Login failed! terminal service expired! mobile: %s, dev_id: %s", t_info['t_msisdn'], t_info['dev_id']) return logging.info("[GW] Checking imsi: %s and mobile: %s, Terminal: %s", t_info['imsi'], t_info['t_msisdn'], t_info['dev_id']) tmobile = db.get("SELECT imsi FROM T_TERMINAL_INFO" " WHERE mobile = %s", t_info['t_msisdn']) if tmobile and tmobile.imsi and tmobile.imsi != t_info['imsi']: # check terminal and give a appropriate HK notification terminal = db.get("SELECT id FROM T_TERMINAL_INFO WHERE tid=%s", t_info['dev_id']) if terminal: alias = QueryHelper.get_alias_by_tid(t_info['dev_id'], redis, db) else: alias = t_info['t_msisdn'] args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM sms = SMSCode.SMS_TERMINAL_HK % alias SMSHelper.send(t_info['u_msisdn'], sms) lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.error("[GW] Login failed! Illegal SIM: %s for Terminal: %s", t_info['t_msisdn'], t_info['dev_id']) return terminal = db.get("SELECT id, mobile, owner_mobile, service_status" " FROM T_TERMINAL_INFO" " WHERE tid = %s", t_info['dev_id']) if terminal: if terminal.mobile != t_info['t_msisdn']: logging.info("[GW] Terminal: %s changed mobile, old mobile: %s, new mobile: %s", t_info['dev_id'], terminal.mobile, t_info['t_msisdn']) if (terminal.owner_mobile == t_info['u_msisdn'] or terminal.service_status == UWEB.SERVICE_STATUS.TO_BE_UNBIND): # delete old terminal! logging.info("[GW] Delete old tid bind relation. tid: %s, owner_mobile: %s, service_status: %s", t_info['dev_id'], t_info['u_msisdn'], terminal.service_status) delete_terminal_new(t_info['dev_id'], db, redis, del_user=False) exist = db.get("SELECT tid, owner_mobile, service_status FROM T_TERMINAL_INFO" " WHERE mobile = %s LIMIT 1", t_info['t_msisdn']) if exist: # cannot send unbind packet to dev_id t_status = None logging.info("[GW] Delete old tmobile bind relation. tid: %s, mobile: %s", exist.tid, t_info['t_msisdn']) delete_terminal_new(exist.tid, db, redis, del_user=False) if exist.service_status == UWEB.SERVICE_STATUS.TO_BE_UNBIND: logging.info("[GW] Terminal: %s of %s is to_be_unbind, delete it.", exist.tid, t_info['t_msisdn']) elif exist.owner_mobile != t_info['u_msisdn']: sms = SMSCode.SMS_DELETE_TERMINAL % t_info['t_msisdn'] SMSHelper.send(exist.owner_mobile, sms) terminal = None else: args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM sms = SMSCode.SMS_TID_EXIST % t_info['dev_id'] SMSHelper.send(t_info['u_msisdn'], sms) lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.error("[GW] Login failed! Terminal: %s already bound by %s, new mobile: %s", t_info['dev_id'], terminal.mobile, t_info['t_msisdn']) return #NOTE: Check ydcw or ajt ajt = QueryHelper.get_ajt_whitelist_by_mobile(t_info['t_msisdn'], db) if ajt: url_out = ConfHelper.UWEB_CONF.ajt_url_out else: url_out = ConfHelper.UWEB_CONF.url_out logging.info("[GW] Terminal: %s, login url is: %s", t_info['t_msisdn'], url_out) if t_info['psd']: flag = 0 # check terminal exist or not when HK if not terminal: args.success = GATEWAY.LOGIN_STATUS.UNREGISTER sms = SMSCode.SMS_TID_NOT_EXIST SMSHelper.send(t_info['u_msisdn'], sms) lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.error("[GW] Login failed! Terminal %s execute HK, but tid is not exist", t_info['dev_id']) return # HK, change terminal mobile or owner mobile logging.info("[GW] Checking password. Terminal: %s", t_info['dev_id']) owner = db.get("SELECT id FROM T_USER" " WHERE mobile = %s" " AND password = password(%s)", terminal.owner_mobile, t_info['psd']) if not owner: # psd wrong sms = SMSCode.SMS_PSD_WRONG args.success = GATEWAY.LOGIN_STATUS.PSD_WRONG logging.error("[GW] Login failed! Password invalid. Terminal: %s", t_info['dev_id']) else: if terminal: if terminal.mobile != t_info['t_msisdn']: # terminal HK logging.info("[GW] Terminal: %s HK started.", t_info['dev_id']) # unbind old tmobile old_bind = db.get("SELECT id, tid FROM T_TERMINAL_INFO" " WHERE mobile = %s" " AND id != %s", t_info['t_msisdn'], terminal.id) if old_bind: # clear db db.execute("DELETE FROM T_TERMINAL_INFO" " WHERE id = %s", old_bind.id) # clear redis sessionID_key = get_terminal_sessionID_key(old_bind.tid) address_key = get_terminal_address_key(old_bind.tid) info_key = get_terminal_info_key(old_bind.tid) lq_sms_key = get_lq_sms_key(old_bind.tid) lq_interval_key = get_lq_interval_key(old_bind.tid) keys = [sessionID_key, address_key, info_key, lq_sms_key, lq_interval_key] redis.delete(*keys) logging.info("[GW] Delete old bind Terminal: %s, SIM: %s", t_info['dev_id'], t_info['t_msisdn']) # update new tmobile db.execute("UPDATE T_TERMINAL_INFO" " SET mobile = %s," " imsi = %s" " WHERE id = %s", t_info['t_msisdn'], t_info['imsi'], terminal.id) # clear redis sessionID_key = get_terminal_sessionID_key(t_info['dev_id']) address_key = get_terminal_address_key(t_info['dev_id']) info_key = get_terminal_info_key(t_info['dev_id']) lq_sms_key = get_lq_sms_key(t_info['dev_id']) lq_interval_key = get_lq_interval_key(t_info['dev_id']) keys = [sessionID_key, address_key, info_key, lq_sms_key, lq_interval_key] redis.delete(*keys) # HK sms sms = SMSCode.SMS_TERMINAL_HK_SUCCESS % (terminal.mobile, t_info['t_msisdn']) # subscription LE for new sim thread.start_new_thread(subscription_lbmp, (t_info,)) logging.info("[GW] Terminal: %s HK success!", t_info['dev_id']) if terminal.owner_mobile != t_info['u_msisdn']: logging.info("[GW] Owner HK started. Terminal: %s", t_info['dev_id']) # owner HK user = db.get("SELECT id FROM T_USER" " WHERE mobile = %s", t_info['u_msisdn']) if user: logging.info("[GW] Owner already existed. Terminal: %s", t_info['dev_id']) sms = SMSCode.SMS_USER_ADD_TERMINAL % (t_info['t_msisdn'], url_out) else: logging.info("[GW] Create new owner started. Terminal: %s", t_info['dev_id']) psd = get_psd() user_info = dict(umobile=t_info['u_msisdn'], password=psd) add_user(user_info, db, redis) sms = SMSCode.SMS_USER_HK_SUCCESS % (t_info['u_msisdn'], url_out, t_info['u_msisdn'], psd) db.execute("UPDATE T_TERMINAL_INFO" " SET owner_mobile = %s" " WHERE id = %s", t_info['u_msisdn'], terminal.id) logging.info("[GW] Owner of %s HK success!", t_info['dev_id']) else: logging.error("[GW] What happened? Cannot find old terminal by dev_id: %s", t_info['dev_id']) else: flag = 1 # login or JH if terminal: # login logging.info("[GW] Terminal: %s Normal login started!", t_info['dev_id']) else: # SMS JH or admin JH or change new dev JH logging.info("[GW] Terminal: %s, mobile: %s JH started.", t_info['dev_id'], t_info['t_msisdn']) exist = db.get("SELECT id FROM T_USER" " WHERE mobile = %s", t_info['u_msisdn']) if exist: logging.info("[GW] Owner already existed. Terminal: %s", t_info['dev_id']) sms = SMSCode.SMS_USER_ADD_TERMINAL % (t_info['t_msisdn'], url_out) else: # get a new psd for new user logging.info("[GW] Create new owner started. Terminal: %s", t_info['dev_id']) psd = get_psd() user_info = dict(umobile=t_info['u_msisdn'], password=psd, uname=t_info['u_msisdn']) add_user(user_info, db, redis) sms = SMSCode.SMS_JH_SUCCESS % (t_info['t_msisdn'], url_out, t_info['u_msisdn'], psd) admin_terminal = db.get("SELECT id, tid FROM T_TERMINAL_INFO" " WHERE tid = %s", t_info['t_msisdn']) if admin_terminal: # admin JH db.execute("UPDATE T_TERMINAL_INFO" " SET tid = %s," " dev_type = %s," " owner_mobile = %s," " imsi = %s," " imei = %s," " factory_name = %s," " keys_num = %s," " softversion = %s" " WHERE id = %s", t_info['dev_id'], t_info['dev_type'], t_info['u_msisdn'], t_info['imsi'], t_info['imei'], t_info['factory_name'], t_info['keys_num'], t_info['softversion'], admin_terminal.id) db.execute("UPDATE T_CAR SET tid = %s" " WHERE tid = %s", t_info['dev_id'], t_info['t_msisdn']) logging.info("[GW] Terminal %s by ADMIN JH success!", t_info['dev_id']) else: exist_terminal = db.get("SELECT id, tid FROM T_TERMINAL_INFO" " WHERE mobile = %s", t_info['t_msisdn']) if exist_terminal: # unbind old tmobile db.execute("DELETE FROM T_TERMINAL_INFO" " WHERE id = %s", exist_terminal.id) # clear redis sessionID_key = get_terminal_sessionID_key(exist_terminal.tid) address_key = get_terminal_address_key(exist_terminal.tid) info_key = get_terminal_info_key(exist_terminal.tid) lq_sms_key = get_lq_sms_key(exist_terminal.tid) lq_interval_key = get_lq_interval_key(exist_terminal.tid) keys = [sessionID_key, address_key, info_key, lq_sms_key, lq_interval_key] redis.delete(*keys) logging.info("[GW] Terminal %s change dev, old dev: %s!", t_info['dev_id'], exist_terminal.tid) # send JH sms to terminal. default active time # is one year. begintime = datetime.datetime.now() endtime = begintime + relativedelta(years=1) terminal_info = dict(tid=t_info['dev_id'], dev_type=t_info['dev_type'], tmobile=t_info['t_msisdn'], owner_mobile=t_info['u_msisdn'], imsi=t_info['imsi'], imei=t_info['imei'], factory_name=t_info['factory_name'], softversion=t_info['softversion'], keys_num=t_info['keys_num'], login=GATEWAY.TERMINAL_LOGIN.ONLINE, service_status=UWEB.SERVICE_STATUS.ON, group_id=-1, mannual_status=UWEB.DEFEND_STATUS.YES, begintime=int(time.mktime(begintime.timetuple())), endtime=4733481600, offline_time=int(time.mktime(begintime.timetuple())), biz_type=UWEB.BIZ_TYPE.YDWS) add_terminal(terminal_info, db, redis) # record the add action, enterprise or individual bind_info = dict(tid=t_info['dev_id'], tmobile=t_info['t_msisdn'], umobile=t_info['u_msisdn'], group_id=-1, cid='', add_time=int(time.time())) record_add_action(bind_info, db) logging.info("[GW] Terminal %s by SMS JH success!", t_info['dev_id']) # subscription LE for new sim thread.start_new_thread(subscription_lbmp, (t_info,)) if args.success == GATEWAY.LOGIN_STATUS.SUCCESS: # get SessionID if resend_flag: args.sessionID = QueryHelper.get_terminal_sessionID(t_info['dev_id'], redis) logging.warn("[GW] Recv resend login packet: %s and use old sessionID: %s!", t_info, args.sessionID) if not args.sessionID: args.sessionID = get_sessionID() else: args.sessionID = get_sessionID() terminal_sessionID_key = get_terminal_sessionID_key(t_info['dev_id']) redis.setvalue(terminal_sessionID_key, args.sessionID) redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) # record terminal address update_terminal_status(redis, t_info["dev_id"], address) # set login info = DotDict(login=GATEWAY.TERMINAL_LOGIN.ONLINE, mobile=t_info['t_msisdn'], keys_num=t_info['keys_num'], login_time=int(time.time()), dev_id=t_info["dev_id"]) update_terminal_info(db, redis, info) logging.info("[GW] Terminal %s login success! SIM: %s", t_info['dev_id'], t_info['t_msisdn']) #NOTE: wspush to cient if flag != "1": # normal login WSPushHelper.pushS4(t_info["dev_id"], db, redis) else: # JH pass lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) if sms and t_info['u_msisdn']: SMSHelper.send(t_info['u_msisdn'], sms) # unbind terminal of to_be_unbind if t_status and t_status.service_status == UWEB.SERVICE_STATUS.TO_BE_UNBIND: logging.info("[GW] Terminal: %s is unbinded, send unbind packet.", t_info["dev_id"]) seq = str(int(time.time()*1000))[-4:] args = DotDict(seq=seq, tid=t_info["dev_id"]) ubc = UNBindComposer(args) request = DotDict(packet=ubc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding)
def handle_new_login(t_info, address, connection, channel, exchange, gw_binding, db, redis): """Handle the login packet with version bigger than 2.2.0 S1 t_info:{'dev_id' // tid 't_msisdn' // tmobile 'u_msisdn' // umobile 'imei' // sim's id 'imsi' // track's id 'dev_type' 'softversion' // version of terminal, like 2.3.0 'timestamp' 'psd' 'keys_num' 'sessionID' 'command' 'factory_name' } flag(t_info['psd']): 0 - boot_normally 1 - active_terminal 2 - assert_reboot 3 - network_uncovered 4 - server_no_response 5 - config_changed 6 - session_expired 7 - terminal_unactived 8 - package_send_fail 9 - simcard_error 10 - gprs_error 11 - mcu_timeout 12 - reboot_by_sms 100 - script_reload workflow: if normal login: if sn and imsi exist, but msisdn and msisdn are empty: send register sms again normal login, check [SN,PHONE,IMSI,USER] is matching or not. else: #JH delete old bind relation of tid, and send message to old user. update new bind relation of tmobile, and send message to new user. login response packet: 0 - success, then get a sessionID for terminal and record terminal's address 1 - unregister, terminal login first. 3 - illegal sim, a mismatch between [SN,PHONE,IMSI,USER] 6 - not whitelist """ args = DotDict(success=GATEWAY.LOGIN_STATUS.SUCCESS, sessionID='') tid = t_info.dev_id resend_key, resend_flag = get_resend_flag(redis, tid, t_info.timestamp, t_info.command) sms = '' t_status = None #NOTE: new softversion, new meaning, 1: active; othter: normal login flag = t_info['psd'] terminal = db.get("SELECT tid, group_id, mobile, imsi, owner_mobile, service_status," " defend_status, mannual_status, icon_type, login_permit, " " alias, vibl, use_scene, push_status, speed_limit, stop_interval," " distance_current" " FROM T_TERMINAL_INFO" " WHERE mobile = %s LIMIT 1", t_info['t_msisdn']) cnum = QueryHelper.get_cnum_by_terminal(tid, t_info['t_msisdn'], redis, db) #NOTE: normal login if flag != "1": # normal login #NOTE: no tmobile and ower_mobile if (not t_info['t_msisdn']) and (not t_info['u_msisdn']): t = db.get("SELECT tid, group_id, mobile, imsi, owner_mobile, service_status" " FROM T_TERMINAL_INFO" " WHERE service_status=1" " AND tid = %s " " AND imsi = %s LIMIT 1", t_info['dev_id'], t_info['imsi']) if t: args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM t_info['t_msisdn'] = t.mobile t_info['u_msisdn'] = t.owner_mobile register_sms = SMSCode.SMS_REGISTER % (t.owner_mobile, t.mobile) SMSHelper.send_to_terminal(t.mobile, register_sms) logging.info("[GW] A crash terminal tid:%s, imei:%s has no tmobile: %s, umobile:%s in login packet, so send %s again.", t_info['dev_id'], t_info['imei'], t_info['t_msisdn'], t_info['u_msisdn'], register_sms) else: args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM logging.info("[GW] A crash terminal:%s login without umobile and tmobile, and there is no record in db.", t_info['dev_id']) else: #NOTE: no tmobile if not t_info['t_msisdn']: # login first. tid_terminal = db.get("SELECT tid, mobile, owner_mobile, service_status" " FROM T_TERMINAL_INFO" " WHERE tid = %s LIMIT 1", t_info['dev_id']) args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM if tid_terminal: #NOTE: mobile is not not JH, send caution to owner sms_ = SMSCode.SMS_NOT_JH % tid_terminal.mobile SMSHelper.send(tid_terminal.owner_mobile, sms_) logging.warn("[GW] terminal: %s login at first time.", t_info['dev_id']) #NOTE: tmobile is exist elif terminal: alias = QueryHelper.get_alias_by_tid(terminal['tid'], redis, db) if terminal['tid'] != t_info['dev_id']: args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM sms = SMSCode.SMS_TERMINAL_HK % alias logging.warn("[GW] Terminal changed dev, mobile: %s, old_tid: %s, new_tid: %s", t_info['t_msisdn'], terminal['tid'], t_info['dev_id']) elif terminal['imsi'] != t_info['imsi']: args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM sms = SMSCode.SMS_TERMINAL_HK % alias logging.warn("[GW] Terminal imsi is wrong, tid: %s, mobile: %s, old_imsi: %s, new_imsi: %s", t_info['dev_id'], t_info['t_msisdn'], terminal['imsi'], t_info['imsi']) elif terminal['owner_mobile'] != t_info['u_msisdn']: register_sms = SMSCode.SMS_REGISTER % (terminal['owner_mobile'], terminal['mobile']) SMSHelper.send_to_terminal(terminal['mobile'], register_sms) logging.warn("[GW] Terminal owner_mobile is wrong, tid: %s, old_owner_mobile: %s, new_owner_mobile: %s, send the regist sms: %s again", t_info['dev_id'], terminal['owner_mobile'], t_info['u_msisdn'], register_sms) elif terminal['service_status'] == UWEB.SERVICE_STATUS.TO_BE_UNBIND: t_status = UWEB.SERVICE_STATUS.TO_BE_UNBIND logging.warn("[GW] Terminal is unbinded. tid: %s, mobile: %s", t_info["dev_id"], t_info['t_msisdn']) else: logging.info("[GW] Terminal normal login successfully. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) else: args.success = GATEWAY.LOGIN_STATUS.UNREGISTER logging.error("[GW] Terminal login failed, unregister. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) #NOTE: JH else: # JH logging.info("[GW] Terminal JH started. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) # 0. Initialize the valus keeps same as the default value in database. group_id = -1 login_permit = 1 mannual_status = UWEB.DEFEND_STATUS.YES defend_status = UWEB.DEFEND_STATUS.YES icon_type = 0 alias = '' push_status = 1 vibl = 1 use_scene = 3 speed_limit = 120 stop_interval = 0 distance_current = 0 # send JH sms to terminal. default active time is one year. begintime = datetime.datetime.now() endtime = begintime + relativedelta(years=1) # 1. check data validation logging.info("[GW] Checking terminal mobile: %s and owner mobile: %s, Terminal: %s", t_info['t_msisdn'], t_info['u_msisdn'], t_info['dev_id']) if not (check_phone(t_info['u_msisdn']) and check_phone(t_info['t_msisdn'])): args.success = GATEWAY.LOGIN_STATUS.ILLEGAL_SIM lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info['dev_id']) if t_info['u_msisdn']: # send JH failed caution to owner sms = SMSCode.SMS_JH_FAILED SMSHelper.send(t_info['u_msisdn'], sms) logging.error("[GW] Login failed! Invalid terminal mobile: %s or owner_mobile: %s, tid: %s", t_info['t_msisdn'], t_info['u_msisdn'], t_info['dev_id']) append_gw_request(request, connection, channel, exchange, gw_binding) # 2. delete to_be_unbind terminal if terminal and terminal.service_status == UWEB.SERVICE_STATUS.TO_BE_UNBIND: logging.info("[GW] Delete terminal which is to_be_unbind. tid: %s, mobile: %s", terminal['tid'], terminal['mobile']) delete_terminal_new(terminal['tid'], db, redis) terminal = None # 3. add user info exist = db.get("SELECT id FROM T_USER" " WHERE mobile = %s", t_info['u_msisdn']) #NOTE: Check ydcw or ajt ajt = QueryHelper.get_ajt_whitelist_by_mobile(t_info['t_msisdn'], db) if ajt: url_out = ConfHelper.UWEB_CONF.ajt_url_out else: url_out = ConfHelper.UWEB_CONF.url_out logging.info("[GW] Login url is: %s, tid: %s, mobile: %s ", url_out, t_info['dev_id'], t_info['t_msisdn']) if exist: logging.info("[GW] Owner already existed. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) sms = SMSCode.SMS_USER_ADD_TERMINAL % (t_info['t_msisdn'], url_out) else: # get a new psd for new user logging.info("[GW] Create new owner started. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) psd = get_psd() user_info = dict(umobile=t_info['u_msisdn'], password=psd, uname=t_info['u_msisdn']) add_user(user_info, db, redis) sms = SMSCode.SMS_JH_SUCCESS % (t_info['t_msisdn'], url_out, t_info['u_msisdn'], psd) # 4. JH existed tmobile is_refurbishment = False if terminal: if (terminal['tid'] == t_info['dev_id']) and \ (terminal['imsi'] == t_info['imsi']) and \ (terminal['owner_mobile'] == t_info['u_msisdn']): # 4.1 SCN: Refurbishment, the terminal-info has existed in platform. JH it again. is_refurbishment = True # check the login packet whether is send again if resend_flag: sms = '' logging.info("[GW] Recv resend packet, do not send sms. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) else: sms = SMSCode.SMS_USER_ADD_TERMINAL % (t_info['t_msisdn'], url_out) logging.info("[GW] Terminal is refurbishment. tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) else: # 4.2 existed tmobile changed dev or corp terminal login first, get the old info(group_id, login_permit and so on) before change group_id = terminal.group_id login_permit = terminal.login_permit mannual_status = terminal.mannual_status defend_status = terminal.defend_status icon_type = terminal.icon_type alias = terminal.alias vibl = terminal.vibl use_scene = terminal.use_scene push_status = terminal.push_status speed_limit = terminal.speed_limit stop_interval = terminal.stop_interval distance_current = terminal.distance_current if terminal.tid == terminal.mobile: # corp terminal login first, keep corp info db.execute("UPDATE T_REGION_TERMINAL" " SET tid = %s" " WHERE tid = %s", t_info['dev_id'], t_info['t_msisdn']) logging.info("[GW] Corp terminal login first, tid: %s, mobile: %s.", t_info['dev_id'], t_info['t_msisdn']) elif terminal.tid != t_info['dev_id']: logging.info("[GW] Terminal changed dev, mobile: %s, new_tid: %s, delete old_tid: %s.", t_info['t_msisdn'], t_info['dev_id'], terminal.tid) else: # Refurbishment, change user logging.info("[GW] Terminal change user, tid: %s, mobile: %s, new_owner_mobile: %s, old_owner_mobile: %s", t_info['dev_id'], t_info['t_msisdn'], t_info['u_msisdn'], terminal.owner_mobile) #NOTE: If terminal has exist, firt remove the terminal logging.info("[GW] Terminal is deleted, tid: %s, mobile: %s.", terminal['tid'], terminal['mobile']) del_user = True if terminal.owner_mobile != t_info['u_msisdn']: # send message to old user of dev_id sms_ = SMSCode.SMS_DELETE_TERMINAL % terminal.mobile SMSHelper.send(terminal.owner_mobile, sms_) if terminal.tid == t_info['dev_id']: # clear data belongs to the terminal clear_data(terminal.tid, db, redis) logging.info("[GW] Send delete terminal message: %s to user: %s", sms_, terminal.owner_mobile) else: del_user = False delete_terminal_new(terminal.tid, db, redis, del_user=del_user) #NOTE: Normal JH. if not is_refurbishment: # 5. delete existed tid tid_terminal = db.get("SELECT tid, mobile, owner_mobile, service_status" " FROM T_TERMINAL_INFO" " WHERE tid = %s LIMIT 1", t_info['dev_id']) if tid_terminal: logging.info("[GW] Terminal is deleted, tid: %s, mobile: %s.", tid_terminal['tid'], tid_terminal['mobile']) del_user = True if tid_terminal['owner_mobile'] != t_info['u_msisdn']: if tid_terminal['service_status'] == UWEB.SERVICE_STATUS.TO_BE_UNBIND: logging.info("[GW] Terminal is to_be_unbind, tid: %s, mobile: %s, delete it.", tid_terminal['tid'], tid_terminal['mobile']) else: # send message to old user of dev_id sms_ = SMSCode.SMS_DELETE_TERMINAL % tid_terminal['mobile'] SMSHelper.send(tid_terminal['owner_mobile'], sms_) logging.info("[GW] Send delete terminal message: %s to user: %s", sms_, tid_terminal['owner_mobile']) # user changed, must clear history data of dev_id clear_data(tid_terminal['tid'], db, redis) else: del_user = False delete_terminal_new(tid_terminal['tid'], db, redis, del_user=del_user) # 6 add terminal info # check use sence ttype = get_terminal_type_by_tid(t_info['dev_id']) logging.info("[GW] Terminal's type is %s. tid: %s, mobile: %s", ttype, t_info['dev_id'], t_info['t_msisdn']) terminal_info = dict(tid=t_info['dev_id'], group_id=group_id, dev_type=t_info['dev_type'], tmobile=t_info['t_msisdn'], owner_mobile=t_info['u_msisdn'], imsi=t_info['imsi'], imei=t_info['imei'], factory_name=t_info['factory_name'], softversion=t_info['softversion'], keys_num=t_info['keys_num'], login=GATEWAY.TERMINAL_LOGIN.ONLINE, service_status=UWEB.SERVICE_STATUS.ON, mannual_status=mannual_status, push_status=push_status, icon_type=icon_type, begintime=int(time.mktime(begintime.timetuple())), endtime=4733481600, offline_time=int(time.mktime(begintime.timetuple())), cnum=cnum, login_permit=login_permit, bt_mac=t_info['bt_mac'], bt_name=t_info['bt_name'], vibl=vibl, use_scene=use_scene, biz_type=UWEB.BIZ_TYPE.YDWS, alias=alias, speed_limit=speed_limit, stop_interval=stop_interval, distance_current=distance_current) add_terminal(terminal_info, db, redis) # record the add action, enterprise or individual corp = QueryHelper.get_corp_by_gid(group_id, db) bind_info = dict(tid=t_info['dev_id'], tmobile=t_info['t_msisdn'], umobile=t_info['u_msisdn'], group_id=group_id, cid=corp.get('cid', '') if corp else '', add_time=int(time.time())) record_add_action(bind_info, db) logging.info("[GW] Terminal JH success! tid: %s, mobile: %s.", t_info['dev_id'], t_info['t_msisdn']) # subscription LE for new sim thread.start_new_thread(subscription_lbmp, (t_info,)) if args.success == GATEWAY.LOGIN_STATUS.SUCCESS: # get SessionID if resend_flag: logging.warn("[GW] Recv resend login packet and use old sessionID! packet: %s, tid: %s, mobile: %s.", t_info, t_info['dev_id'], t_info['t_msisdn']) args.sessionID = QueryHelper.get_terminal_sessionID(t_info['dev_id'], redis) if not args.sessionID: args.sessionID = get_sessionID() else: #NOTE: generate a sessionid and keep it in redis. args.sessionID = get_sessionID() terminal_sessionID_key = get_terminal_sessionID_key(t_info['dev_id']) redis.setvalue(terminal_sessionID_key, args.sessionID) redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) # record terminal address update_terminal_status(redis, t_info["dev_id"], address) #NOTE: When termianl is normal login, update some properties to platform. info = DotDict(login=GATEWAY.TERMINAL_LOGIN.ONLINE, mobile=t_info['t_msisdn'], keys_num=t_info['keys_num'], softversion=t_info['softversion'], login_time=int(time.time()), dev_id=t_info["dev_id"], bt_mac=t_info['bt_mac'], bt_name=t_info['bt_name'], dev_type=t_info['dev_type']) update_terminal_info(db, redis, info) logging.info("[GW] Terminal login success! tid: %s, mobile: %s", t_info['dev_id'], t_info['t_msisdn']) #NOTE: wspush to cient if flag != "1": # normal login WSPushHelper.pushS4(t_info["dev_id"], db, redis) else: # JH pass lc = LoginRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) if sms and t_info['u_msisdn']: logging.info("[GW] Send sms to owner. mobile: %s, content: %s", t_info['u_msisdn'], sms) SMSHelper.send(t_info['u_msisdn'], sms) if t_status == UWEB.SERVICE_STATUS.TO_BE_UNBIND: seq = str(int(time.time()*1000))[-4:] args_ = DotDict(seq=seq, tid=t_info["dev_id"]) ubc = UNBindComposer(args_) request = DotDict(packet=ubc.buf, address=address, dev_id=t_info["dev_id"]) append_gw_request(request, connection, channel, exchange, gw_binding) logging.warn("[GW] Terminal is unbinded, tid: %s, send unbind packet.", t_info["dev_id"])
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 post(self): logging.info("[UWEB] Android login test") status = ErrorCode.SUCCESS cid = UWEB.DUMMY_CID oid = UWEB.DUMMY_OID uid = ConfHelper.UWEB_CONF.test_uid tid = ConfHelper.UWEB_CONF.test_tid sim = ConfHelper.UWEB_CONF.test_sim version_type = int(self.get_argument("version_type", 0)) biz_type = UWEB.BIZ_TYPE.YDWS self.bookkeep(dict(cid=cid, oid=oid, uid=uid, tid=tid, sim=sim)) user_info = QueryHelper.get_user_by_uid(uid, self.db) # NOTE: add cars_info, it's same as lastinfo cars_info = {} terminals = QueryHelper.get_terminals_by_uid(uid, biz_type, self.db) for terminal in terminals: # 1: get terminal tid = terminal.tid group_info = get_group_info_by_tid(self.db, tid) terminal_info_key = get_terminal_info_key(tid) terminal_cache = self.redis.getvalue(terminal_info_key) if terminal_cache: terminal['gps'] = terminal_cache['gps'] terminal['gsm'] = terminal_cache['gsm'] terminal['pbat'] = terminal_cache['pbat'] mobile = terminal['mobile'] terminal['keys_num'] = 0 if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP: terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE # NOTE: if alias is null, provide cnum or sim instead terminal['alias'] = QueryHelper.get_alias_by_tid( tid, self.redis, self.db) fobs = self.db.query("SELECT fobid FROM T_FOB" " WHERE tid = %s", tid) terminal['fob_list'] = [fob.fobid for fob in fobs] terminal['sim'] = terminal['mobile'] # 2: get location location = QueryHelper.get_location_info(tid, self.db, self.redis) if location and not (location.clatitude or location.clongitude): location_key = get_location_key(str(tid)) locations = [location, ] locations = get_locations_with_clatlon(locations, self.db) location = locations[0] self.redis.setvalue( location_key, location, EVENTER.LOCATION_EXPIRY) if location and location['name'] is None: location['name'] = '' avatar_name, avatar_path, avatar_full_path, avatar_time = self.get_avatar_info( mobile) service_status = QueryHelper.get_service_status_by_tmobile( self.db, mobile) car_dct = {} if location and location['type'] == 1: # cellid location['locate_error'] = 500 # mile car_info = dict(defend_status=terminal['defend_status'] if terminal['defend_status'] is not None else 1, service_status=service_status, mannual_status=terminal['mannual_status'] if terminal['mannual_status'] is not None else 1, fob_status=terminal['fob_status'] if terminal['fob_status'] is not None else 0, timestamp=location['timestamp'] if location else 0, speed=location.speed if location else 0, # NOTE: degree's type is Decimal, float() it before json_encode degree=float(location.degree) if location else 0.00, locate_error=location.get('locate_error', 20) if location else 20, bt_name=terminal['bt_name'] if terminal.get('bt_name', None) is not None else '', bt_mac=terminal['bt_mac'] if terminal.get('bt_mac', None) is not None else '', dev_type=terminal['dev_type'] if terminal.get('dev_type', None) is not None else 'A', name=location.name if location else '', type=location.type if location else 1, latitude=location['latitude'] if location else 0, longitude=location['longitude'] if location else 0, clatitude=location['clatitude'] if location else 0, clongitude=location['clongitude'] if location else 0, login=terminal['login'] if terminal['login'] is not None else 0, gps=terminal['gps'] if terminal['gps'] is not None else 0, gsm=terminal['gsm'] if terminal['gsm'] is not None else 0, pbat=terminal['pbat'] if terminal['pbat'] is not None else 0, mobile=terminal['mobile'], owner_mobile=terminal['owner_mobile'], alias=terminal['alias'], #keys_num=terminal['keys_num'] if terminal['keys_num'] is not None else 0, keys_num=0, group_id=group_info['group_id'], group_name=group_info['group_name'], icon_type=terminal['icon_type'], avatar_path=avatar_path, avatar_time=avatar_time, fob_list=terminal['fob_list'] if terminal['fob_list'] else []) car_dct[tid] = car_info cars_info.update(car_dct) #push_info = NotifyHelper.get_push_info() push_id = uid push_key = NotifyHelper.get_push_key(push_id, self.redis) lastinfo_time_key = get_lastinfo_time_key(uid) lastinfo_time = self.redis.getvalue(lastinfo_time_key) push = dict(id='', key='') t = int(time.time()) * 1000 push_key = get_push_key(uid, t) json_data = WSPushHelper.register_wspush(uid, self.redis) data = json_data['data'] if data: id = data.get('push_id', '') key = data.get('psd', '') push['id'] = id push['key'] = key if version_type >= 1: terminals = [] for k, v in cars_info.iteritems(): v.update({'tid': k}) terminals.append(v) self.write_ret(status, dict_=DotDict(wspush=push, push_id=push_id, push_key=push_key, name=user_info.name if user_info else uid, user_type=UWEB.USER_TYPE.PERSON, lastinfo_time=lastinfo_time, terminals=terminals)) else: self.write_ret(status, dict_=DotDict(wspush=push, push_id=push_id, # app_key=push_info.app_key, push_key=push_key, name=user_info.name if user_info else uid, user_type=UWEB.USER_TYPE.PERSON, cars_info=cars_info, lastinfo_time=lastinfo_time, cars=terminals,))
def _on_finish(db): self.db = db page_count = int(data.pagecnt) if statistic_mode == 'all': # all if page_count == -1: count = len(tids) d, m = divmod(count, page_size) page_count = (d + 1) if m else d reports = [] dis_count = Decimal() for item, tid in enumerate(tids): seq = item + 1 # NOTE: It's amazing: In database, distance's type is long. sum(distance)'s type is Decimal mileage_log = self.db.get("SELECT SUM(distance) AS distance" " FROM T_MILEAGE_LOG" " WHERE tid = %s" " AND (timestamp BETWEEN %s AND %s)", tid, start_time, end_time + 60 * 60 * 24) if mileage_log and mileage_log['distance']: dis_sum = '%0.1f' % (mileage_log['distance'] / 1000,) else: dis_sum = 0 alias = QueryHelper.get_alias_by_tid( tid, self.redis, self.db) dct = dict(seq=seq, alias=alias, distance=float(dis_sum)) reports.append(dct) dis_count += Decimal(dis_sum) counts = [float(dis_count), ] # orgnize and store the data to be downloaded m = hashlib.md5() m.update(self.request.body) hash_ = m.hexdigest() mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_) self.redis.setvalue( mem_key, (statistic_mode, reports, counts), time=UWEB.STATISTIC_INTERVAL) reports = reports[ (page_number * page_size):((page_number + 1) * page_size)] self.write_ret(status, dict_=DotDict(res=reports, pagecnt=page_count, hash_=hash_)) else: # single tid = tids[0] # end_time must be bigger than start_time delta = end_time - start_time d, m = divmod(delta, 60 * 60 * 24) start_date = get_date_from_utc(start_time) end_date = get_date_from_utc(end_time) start_day = datetime.datetime.fromtimestamp(start_time) end_day = datetime.datetime.fromtimestamp(end_time) # get how many days the end_time and start_time cover days = abs(end_day - start_day).days + 1 res = [] graphics = [] counts = [] dis_sum = Decimal() current_time = int(time.time()) for item in range(days): timestamp = start_time + 1 * 60 * 60 * 24 * (item) date = get_date_from_utc(timestamp) year, month, day = date.year, date.month, date.day start_time_, end_time_ = start_end_of_day( year=year, month=month, day=day) re = {} re['alias'] = '-'.join([str(year), str(month), str(day)]) mileage_log = self.db.get("SELECT distance FROM T_MILEAGE_LOG" " WHERE tid = %s" " AND timestamp = %s", tid, end_time_) distance = mileage_log['distance'] if mileage_log else 0 # meter --> km distance = '%0.1f' % (Decimal(distance) / 1000,) if float(distance) == 0: distance = 0 graphics.append(float(distance)) dis_sum += Decimal(distance) re['distance'] = distance re['seq'] = item + 1 res.append(re) counts = [float(dis_sum), ] if page_count == -1: items_count = len(res) d, m = divmod(items_count, page_size) page_count = (d + 1) if m else d # store resutl in redis m = hashlib.md5() m.update(self.request.body) hash_ = m.hexdigest() mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_) self.redis.setvalue( mem_key, (statistic_mode, res, counts,), time=UWEB.STATISTIC_INTERVAL) res = res[ page_number * page_size:(page_number + 1) * page_size] self.write_ret(status, dict_=dict(res=res, counts=counts, graphics=graphics, pagecnt=page_count, hash_=hash_)) self.finish()
def handle_runtime(info, address, connection, channel, exchange, gw_binding, db, redis): """ S23 runtime status packet: {login [0:unlogin | 1:login], defend_status [0:undefend | 1:defend], gps:gsm:pbat [0-100:0-9:0-100]} 0: success, then record new terminal's address 1: invalid SessionID """ try: head = info.head body = info.body dev_id = head.dev_id resend_key, resend_flag = get_resend_flag(redis, dev_id, head.timestamp, head.command) if len(body) == 3: body.append('-1') body.append('0') logging.info("[GW] old version is compatible, append fob_pbat, is_send") if len(body) == 4: body.append('0') logging.info("[GW] old version is compatible, append is_send") args = DotDict(success=GATEWAY.RESPONSE_STATUS.SUCCESS, command=head.command, mannual_status='') sessionID = QueryHelper.get_terminal_sessionID(dev_id, redis) if sessionID != head.sessionID: args.success = GATEWAY.RESPONSE_STATUS.INVALID_SESSIONID else: if resend_flag: logging.warn("[GW] Recv resend packet, head: %s, body: %s and drop it!", info.head, info.body) terminal_info = QueryHelper.get_terminal_info(head.dev_id, db, redis) args.mannual_status = terminal_info['mannual_status'] else: redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) hp = AsyncParser(body, head) runtime_info = hp.ret update_terminal_status(redis, head.dev_id, address) terminal_info = update_terminal_info(db, redis, runtime_info) args.mannual_status = terminal_info['mannual_status'] db.execute("INSERT INTO T_RUNTIME_STATUS" " VALUES(NULL, %s, %s, %s, %s, %s, %s, %s, %s)", head.dev_id, runtime_info['login'], runtime_info['defend_status'], runtime_info['gps'], runtime_info['gsm'], runtime_info['pbat'], runtime_info['fob_pbat'], head.timestamp) is_send = int(runtime_info['is_send']) if is_send: terminal_info = QueryHelper.get_terminal_info(head.dev_id, db, redis) alias = QueryHelper.get_alias_by_tid(head.dev_id, redis, db) communication_staus = u'正常' communication_mode = u'撤防' gsm_strength = u'强' gps_strength = u'强' if int(terminal_info['login']) == GATEWAY.TERMINAL_LOGIN.ONLINE: communication_staus = u'正常' else: communication_staus = u'异常' if int(terminal_info['mannual_status']) == UWEB.DEFEND_STATUS.YES: communication_mode = u'强力设防' elif int(terminal_info['mannual_status']) == UWEB.DEFEND_STATUS.SMART: communication_mode = u'智能设防' else: communication_mode= u'撤防' pbat = int(terminal_info.get('pbat', 0)) gsm = int(terminal_info.get('gsm', 0)) if gsm < 3: gsm_strength = u'弱' elif gsm < 6: gsm_strength = u'较弱' gps = int(terminal_info.get('gps', 0)) if gps < 10: gps_strength = u'弱' elif gps < 20: gps_strength = u'较弱' elif gps < 30: gps_strength = u'较强' runtime_sms = SMSCode.SMS_RUNTIME_STATUS % (alias, communication_staus, communication_mode, int(pbat), gsm_strength, gps_strength) SMSHelper.send(terminal_info.owner_mobile, runtime_sms) logging.info("[GW] Send runtime_status sms to user: %s, tid: %s", terminal_info.owner_mobile, head.dev_id) update_terminal_status(redis, head.dev_id, address) if args['success'] == GATEWAY.RESPONSE_STATUS.SUCCESS: acc_status_info_key = get_acc_status_info_key(dev_id) acc_status_info = redis.getvalue(acc_status_info_key) if acc_status_info and (not acc_status_info['t2_status']): # T2(query) is need args['success'] = 3 # acc_status is changed logging.info("[GW] ACC_status is changed, dev_id: %s, acc_status_info: %s", dev_id, acc_status_info) rc = RuntimeRespComposer(args) request = DotDict(packet=rc.buf, address=address, dev_id=dev_id) append_gw_request(request, connection, channel, exchange, gw_binding) except: logging.exception("[GW] Handle runtime status report exception.") GWException().notify()