Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
    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) 
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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])
Exemplo n.º 8
0
        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()
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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"])            
Exemplo n.º 14
0
    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]
Exemplo n.º 15
0
    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,))
Exemplo n.º 16
0
        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()
Exemplo n.º 17
0
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()