Exemple #1
0
 def update_location(self, location):
     self.db.execute("UPDATE T_LOCATION"
                     "  SET name = %s,"
                     "      latitude = %s,"
                     "      longitude = %s,"
                     "      clatitude = %s,"
                     "      clongitude = %s,"
                     "      type = %s,"
                     "      timestamp = %s"
                     "  WHERE id = %s",	
                     location.name, location.lat, location.lon,
                     location.cLat, location.cLon, location.type,
                     location.gps_time, location.id)
     is_alived = self.redis.getvalue('is_alived')
     if (is_alived == ALIVED and location.cLat and location.cLon):
         mem_location = DotDict({'id':location.id,
                                 'latitude':location.lat,
                                 'longitude':location.lon,
                                 'type':location.type,
                                 'clatitude':location.cLat,
                                 'clongitude':location.cLon,
                                 'timestamp':location.gps_time,
                                 'name':location.name,
                                 'degree':float(location.degree),
                                 'speed':location.speed})
         location_key = get_location_key(str(location.dev_id))
         self.redis.setvalue(location_key, mem_location, EVENTER.LOCATION_EXPIRY)
Exemple #2
0
def handle_latlon_from_cellid(lat, lon, tid, redis, db):
    """Check the laton from cellid whether varied widely from the latlon from gps. 
       If the distance between them is less than a constant, modify the
       latlon of cellid to the latlon of last credible latlon of gps

       @params: lat, degree * 3600000
                lon, degree * 3600000
       @return: lat, degree * 3600000
                lon, degree * 3600000
    """
    distance = 0

    clats, clons = get_clocation_from_ge([lat,], [lon,])
    clat, clon = clats[0], clons[0]
    location_key = get_location_key(tid)
    location = redis.getvalue(location_key)
    if location and location.get('type',None) == UWEB.LOCATE_FLAG.GPS: 
        distance = get_distance(int(clon), int(clat), int(location.clongitude), int(location.clatitude))
    else: 
        location = db.get("SELECT latitude, longitude, clatitude, clongitude FROM T_LOCATION"
                          "  WHERE tid = %s AND type = %s"
                          "    AND NOT (clatitude = 0 AND clongitude = 0)" 
                          " ORDER BY timestamp DESC" 
                          " LIMIT 1",
                          tid, UWEB.LOCATE_FLAG.GPS)
        if location: 
            distance = get_distance(int(clon), int(clat), int(location.clongitude), int(location.clatitude))

    logging.info("[LBMPHELPER] The distance :%s, tid:%s", distance, tid)
    if 0 < distance < 2000: 
        lon, lat = location.longitude, location.latitude
        logging.info("[LBMPHELPER] The distance: %s beteen cellid-latlon(%s, %s) and gps-latlon(%s, %s) is "
                     "lesser than %s, so change the cellid-latlon to gps-latlon",
                     distance, lat, lon, location.longitude, location.latitude, UWEB.CELLID_MAX_OFFSET)
    return lat, lon 
Exemple #3
0
def get_last_degree(location, redis, db):
    # if the car is still(speed < min_speed) or location is cellid, the degree is suspect.
    # use degree of last usable location
    is_alived = redis.getvalue('is_alived')
    if is_alived == ALIVED:
        location_key = get_location_key(location.dev_id)
        last_location = redis.getvalue(location_key)
    else:
        last_location = db.get("SELECT degree FROM T_LOCATION"
                               "  WHERE tid = %s"
                               "    AND type = 0"
                               "    AND (%s BETWEEN timestamp - %s"
                               "                AND timestamp + %s)"
                               "  ORDER BY timestamp DESC"
                               "  LIMIT 1",
                               location.dev_id, location.timestamp,
                               EVENTER.LOCATION_EXPIRY * 1000,
                               EVENTER.LOCATION_EXPIRY * 1000)
    if last_location:
        location.degree = last_location.degree

    return float(location.degree)
Exemple #4
0
def filter_location(location, redis):
    """
    workflow:
    if old_location:
        if distance <= MIN_DISTANCE:
            just a little migration cause by lbmp
        else:
            if distance > MAX_DISTANCE or speed > MAX_SPEED:
                odd location 
            elif old_location.speed:
                if (speed > HIGH_SPEED and ratio > MAX_RATIO):
                    odd location
            else:
                pass 
    else:
        first location, save it!
    """
    MIN_DISTANCE = 50  # m
    MAX_DISTANCE = 10000 # m
    HIGH_SPEED = 60 # km/h
    MAX_SPEED = 320 # km/h
    MAX_RATIO = 50 # ratio of two speed

    odd_flag = False
    speed = 0
    ratio = 0
    distance = 0

    location_key = get_location_key(location.dev_id)
    old_location = redis.getvalue(location_key)
    if old_location:
        # not first location, need to check distance and speed
        interval = location.timestamp - old_location.timestamp
        distance = get_distance(location.lon, 
                                location.lat, 
                                old_location.longitude,
                                old_location.latitude)
        if distance <= MIN_DISTANCE:
            # a little migration between two points cause by lbmp, not to filter
            speed = old_location.speed if old_location.speed else 0
        else:
            if interval != 0:
                speed = float(distance / interval) * 3600 #km/h

            if distance > MAX_DISTANCE or speed > MAX_SPEED:
                odd_flag = True
            elif old_location.speed:
                ratio = float(speed / float(old_location.speed))
                if speed > HIGH_SPEED and ratio > MAX_RATIO:
                    # speed change too fast, check it!
                    odd_flag = True
            else:
                pass

        if odd_flag:
            logging.warn("[EVENTER] Receive odd location: %s, distance: %sm, speed: %skm/h,"
                         " ratio: %s, and drop it!  The last location: %s",
                         location, distance, speed, ratio, old_location)
            return None

    location['speed'] = speed
    return location
Exemple #5
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)
Exemple #6
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,))
Exemple #7
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)
Exemple #8
0
    def post(self):
        try:
            data = DotDict(json_decode(self.request.body))
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            logging.info("[UWEB] lastfinfo failed, message: %s, request: \n%s", 
                         ErrorCode.ERROR_MESSAGE[status], self.request.body)
            self.write_ret(status)
            return 

        try:
            cars_info = OrderedDict() 
            usable = 0 # nothing is modified, the cars_info is no use, use the data last time
            status = ErrorCode.SUCCESS
            
            terminals = self.db.query("SELECT tid FROM T_TERMINAL_INFO"
                                      "  WHERE service_status = %s"
                                      "    AND owner_mobile = %s"
                                      "    AND login_permit = 1"
                                      "    ORDER BY LOGIN DESC",
                                      UWEB.SERVICE_STATUS.ON, self.current_user.uid)
            tids = [terminal.tid for terminal in terminals]

            # 1 inquery data     
            for tid in tids:
                # 1: get terminal info 
                terminal = QueryHelper.get_terminal_info(tid, self.db, self.redis) 
                if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP:
                    terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE

                # 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'] = ''

                if location and location['type'] == 1: # cellid 
                    location['locate_error'] = 500  # mile

                car_dct = {}
                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,
                              locate_error=location.get('locate_error', 20) if location else 20,
                              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,
                              bt_name=terminal.get('bt_name', '') if terminal else '',
                              bt_mac=terminal.get('bt_mac', '') if terminal else '',
                              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,
                              fob_list=terminal['fob_list'] if terminal['fob_list'] else [])

                car_dct[tid]=car_info
                cars_info.update(car_dct)
            
            lastinfo_key = get_lastinfo_key(self.current_user.uid)

            # BIG NOTE: here, compare lastinfo and cars_info as str
            lastinfo = self.redis.get(lastinfo_key)

            lastinfo_time_key = get_lastinfo_time_key(self.current_user.uid)
            lastinfo_time = self.redis.getvalue(lastinfo_time_key)

            if lastinfo == str(cars_info):  
                pass
            else:
                lastinfo_time = int(time.time())
                self.redis.setvalue(lastinfo_key, cars_info) 
                self.redis.setvalue(lastinfo_time_key, lastinfo_time)

            track_tid = data.get('track_tid', None)  # use cache
            track_info = []
            query_time = data.get('time', None) 
            track_time = data.get('track_time', query_time) 
            
            # 2 check whether provide usable data   
            if data.get('cache', None):  # use cache
                if query_time is not None: # use time
                    if int(query_time) < lastinfo_time:
                        usable = 1
                        if track_tid:
                            if track_tid not in tids:
                                logging.error("The terminal with tid: %s does not exist", track_tid)
                            else:
                                track_key = get_track_key(track_tid)
                                self.redis.setvalue(track_key, 1, UWEB.TRACK_INTERVAL)
                                if int(query_time) == -1:
                                    pass
                                elif lastinfo_time - query_time > 1: # every 30 second, ternimal generate a location 
                                    car_info = cars_info[track_tid]
                                    endtime = int(car_info['timestamp'])-1 if car_info['timestamp'] else int(lastinfo_time)-1 
                                    track  = self.db.query("SELECT id, latitude, longitude," 
                                                           "    clatitude, clongitude"
                                                           "  FROM T_LOCATION"
                                                           "  WHERE tid = %s"
                                                           "    AND NOT (latitude = 0 OR longitude = 0)"
                                                           "    AND (timestamp BETWEEN %s AND %s)"
                                                           "    AND type = 0"
                                                           "    ORDER BY timestamp",
                                                           track_tid, int(track_time)+1, endtime)
                                    track = get_locations_with_clatlon(track, self.db)
                                    for item in track:
                                        if item['clatitude'] and item['clongitude']:
                                            track_info.append(item['clatitude'])
                                            track_info.append(item['clongitude'])
                    else: 
                        cars_info = {}
                        usable = 0
                else: # no time
                    if lastinfo == cars_info: 
                        cars_info = {}
                        usable = 0
                    else: 
                        usable = 1
            else: 
                usable = 1

            self.write_ret(status, 
                           dict_=DotDict(cars_info=cars_info,
                                         track_info=track_info,
                                         usable=usable,
                                         lastinfo_time=lastinfo_time)) 
        except Exception as e:
            logging.exception("[UWEB] uid: %s, data: %s get lastinfo failed. Exception: %s", 
                              self.current_user.uid, data, e.args) 
            status = ErrorCode.SERVER_BUSY
            self.write_ret(status)
Exemple #9
0
    def post(self):
        try:
            data = DotDict(json_decode(self.request.body))
            track_lst = data.get('track_lst', [])
            current_time = int(time.time()) 
            lastinfo_time = data.get('lastinfo_time') 
            #NOTE: first time, lastinfo_time = -1, set the lsstinfo_time as current_time 
            if lastinfo_time == -1:
                lastinfo_time = current_time 
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            logging.info("[UWEB] lastfinfo for corp failed, message: %s, Exception: %s, request: \n%s", 
                         ErrorCode.ERROR_MESSAGE[status], e.args, self.request.body)
            self.write_ret(status)
            return 

        try:
            status = ErrorCode.SUCCESS
            corp = self.db.get("SELECT cid, name, mobile FROM T_CORP WHERE cid = %s", self.current_user.cid)
            if self.current_user.oid == UWEB.DUMMY_OID:
                groups = self.db.query("SELECT id gid, name FROM T_GROUP WHERE corp_id = %s", self.current_user.cid)
            else:
                groups = self.db.query("SELECT group_id FROM T_GROUP_OPERATOR WHERE oper_id = %s", self.current_user.oid)
                gids = [g.group_id for g in groups]
                groups = self.db.query("SELECT id gid, name FROM T_GROUP WHERE id IN %s", tuple(DUMMY_IDS + gids))
 
            res = DotDict(name=corp.name if corp else '',
                          cid=corp.cid if corp else '',
                          online=0,
                          offline=0,
                          groups=[],
                          lastinfo_time=current_time)
            for group in groups:
                group['trackers'] = {} 
                terminals = self.db.query("SELECT tid FROM T_TERMINAL_INFO"
                                          "  WHERE group_id = %s"
                                          "    AND (service_status = %s"
                                          "         OR service_status = %s)",
                                          group.gid, UWEB.SERVICE_STATUS.ON, 
                                          UWEB.SERVICE_STATUS.TO_BE_ACTIVATED)
                tids = [str(terminal.tid) for terminal in terminals]

                for tid in tids:
                    group['trackers'][tid] = {} 
                    # 1: get terminal info 
                    terminal = QueryHelper.get_terminal_info(tid, self.db, self.redis) 
                    if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP:
                        terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE

                    if terminal['login'] == GATEWAY.TERMINAL_LOGIN.ONLINE:
                        res['online'] +=1
                    else:
                        res['offline'] +=1

                    # 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'] = ''

                    if location and location['type'] == 1: # cellid 
                        location['locate_error'] = 500  # mile
                    #1: build the basic_info
                    basic_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,
                                    locate_error=location.get('locate_error', 20) if location else 20,
                                    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,
                                    bt_name=terminal.get('bt_name', '') if terminal else '',
                                    bt_mac=terminal.get('bt_mac', '') if terminal else '',
                                    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,
                                    icon_type=terminal['icon_type'] if terminal.get('icon_type', None) is not None else 0,
                                    fob_list=terminal['fob_list'] if terminal['fob_list'] else [])

                    #2: build track_info
                    track_info = []
                    for item in track_lst:
                        if tid == item['track_tid']:
                            track_key = get_track_key(tid)
                            self.redis.setvalue(track_key, 1, UWEB.TRACK_INTERVAL)
                            endtime = int(basic_info['timestamp'])-1 if basic_info['timestamp'] else int(current_time)-1
                            points_track = self.db.query("SELECT id, latitude, longitude," 
                                                         "   clatitude, clongitude, type, timestamp"
                                                         "  FROM T_LOCATION"
                                                         "  WHERE tid = %s"
                                                         "    AND NOT (latitude = 0 OR longitude = 0)"
                                                         "    AND (timestamp BETWEEN %s AND %s)"
                                                         "    AND type = 0"
                                                         "    ORDER BY timestamp",
                                                         tid,
                                                         int(item['track_time'])+1, endtime)

                            #points_track = get_locations_with_clatlon(points_track, self.db)
                            for point in points_track: 
                                if point['clatitude'] and point['clongitude']:
                                    t = dict(latitude=point['latitude'],
                                             longitude=point['longitude'],
                                             clatitude=point['clatitude'],
                                             clongitude=point['clongitude'],
                                             type=point['type'],
                                             timestamp=point['timestamp'])
                                    track_info.append(t)
                            break

                    #3: build trace_info
                    trace_info = []
                    points_trace = self.db.query("SELECT distinct id, latitude, longitude," 
                                                 "    clatitude, clongitude"
                                                 "  FROM T_LOCATION"
                                                 "  WHERE tid = %s"
                                                 "    AND NOT (latitude = 0 OR longitude = 0)"
                                                 "    AND (timestamp  between %s and %s)"
                                                 "    AND type = 0"
                                                 "    ORDER BY timestamp",
                                                 tid, int(current_time)-60*5, basic_info['timestamp'])

                    #points_trace = get_locations_with_clatlon(points_trace, self.db)
                    points_trace = points_trace[:5] 
                    len_trace = 0
                    if points_trace:
                        for point in points_trace:
                            if len_trace >= 5:
                                break
                            if point['clatitude'] and point['clongitude']:
                                trace_info.append(point['clatitude'])
                                trace_info.append(point['clongitude'])
                                len_trace += 1
                            else:
                                continue

                    #4: build alert_info
                    alarm_info_key = get_alarm_info_key(tid)
                    alarm_info_all = self.redis.getvalue(alarm_info_key)
                    alarm_info_all  = alarm_info_all if alarm_info_all else []
                    alarm_info = []
                    
                    if alarm_info_all:
                        for alarm in alarm_info_all:
                            #NOTE: here, check alarm's keeptime when kept in reids, not timestamp alarm occurs
                            if alarm.get('keeptime', None) is None: 
                                alarm['keeptime'] = alarm['timestamp']
                            if alarm['keeptime'] >= lastinfo_time/1000:
                               alarm_info.append(alarm)
                        
                    if alarm_info:
                        # NOTE: here, do not remove alarm_info, it will automagically disappear after 1 day 
                        #self.redis.delete(alarm_info_key)
                        #logging.info("[UWEB] lastinfo_time: %s, alarm_info_key: %s, alarm_info: %s", lastinfo_time,  alarm_info_key, alarm_info)
                        pass

                    for alarm in alarm_info:
                        alarm['alias'] = terminal['alias']

                    group['trackers'][tid]['basic_info'] = basic_info
                    group['trackers'][tid]['track_info'] = track_info 
                    group['trackers'][tid]['trace_info'] = trace_info
                    group['trackers'][tid]['alarm_info'] = alarm_info
                res.groups.append(group)
            self.write_ret(status, 
                           dict_=DotDict(res=res,
                                         res_type=3))
        except Exception as e:
            logging.exception("[UWEB] cid: %s get corp lastinfo failed. Exception: %s", 
                              self.current_user.cid, e.args) 
            status = ErrorCode.SERVER_BUSY
            self.write_ret(status)
Exemple #10
0
        def _on_finish(db):
            self.db = db
            try:
                data = DotDict(json_decode(self.request.body))
                biz_type = data.get("biz_type", UWEB.BIZ_TYPE.YDWS)
                track_list = data.get("track_list", [])
                version_type = int(data.get("version_type", 0))
                logging.info("[UWEB] Lastposition request: %s", 
                             data)
            except Exception as e:
                self.write_ret(ErrorCode.ILLEGAL_DATA_FORMAT) 
                self.finish()
                return

            try:
                res = OrderedDict() 
                usable = 1
                status = ErrorCode.SUCCESS
                if data.get('tids', None):
                    terminals = []
                    for tid in data.tids:
                        terminal = QueryHelper.get_terminal_info(tid, self.db, self.redis) 
                        if terminal:
                            terminals.append(DotDict(tid=tid))
                        else:
                            logging.exception("[UWEB] tid: %s can not be found.", 
                                              tid)
                else:
                    if self.current_user.oid != UWEB.DUMMY_OID: # operator,Note: operator also has cid, so we check oid firstly.
                        groups = self.db.query("SELECT group_id "
                                               "  FROM T_GROUP_OPERATOR"
                                               "  WHERE oper_id = %s", 
                                               self.current_user.oid)
                        gids = [g.group_id for g in groups]
                        terminals = self.db.query("SELECT tid FROM T_TERMINAL_INFO"
                                                  "  WHERE (service_status = %s"
                                                  "         OR service_status = %s)"
                                                  "    AND biz_type = %s"
                                                  "    AND group_id IN %s"
                                                  "    ORDER BY LOGIN DESC",
                                                  UWEB.SERVICE_STATUS.ON, 
                                                  UWEB.SERVICE_STATUS.TO_BE_ACTIVATED, 
                                                  biz_type,
                                                  tuple(DUMMY_IDS + gids))
                    elif self.current_user.cid != UWEB.DUMMY_CID: # Corp 
                        groups = self.db.query("SELECT id gid, name "
                                               "  FROM T_GROUP"
                                               "  WHERE corp_id = %s", 
                                               self.current_user.cid)
                        gids = [g.gid for g in groups]
                        terminals = self.db.query("SELECT tid FROM T_TERMINAL_INFO"
                                                  "  WHERE (service_status = %s"
                                                  "         OR service_status = %s)"
                                                  "    AND biz_type = %s"
                                                  "    AND group_id IN %s"
                                                  "    ORDER BY LOGIN DESC",
                                                  UWEB.SERVICE_STATUS.ON, 
                                                  UWEB.SERVICE_STATUS.TO_BE_ACTIVATED, 
                                                  biz_type,
                                                  tuple(DUMMY_IDS + gids))
                    else : # individual user
                        #NOTE: only show the terminals with login_permit is 1
                        terminals = self.db.query("SELECT tid FROM T_TERMINAL_INFO"
                                                  "  WHERE (service_status = %s"
                                                  "         OR service_status = %s)"
                                                  "    AND biz_type = %s"
                                                  "    AND owner_mobile = %s"
                                                  "    AND login_permit = 1"
                                                  "    ORDER BY login DESC",
                                                  UWEB.SERVICE_STATUS.ON, 
                                                  UWEB.SERVICE_STATUS.TO_BE_ACTIVATED, 
                                                  biz_type,
                                                  self.current_user.uid)
                _now_time = time.time()
                if (_now_time - _start_time) > 5:
                    logging.info("[UWEB] Lastinfo step1 used time: %s > 5s",
                                _now_time - _start_time)

                tids = [terminal.tid for terminal in terminals]
                for tid in tids:
                    _now_time = time.time()
                    if (_now_time - _start_time) > 5:
                        logging.info("[UWEB] Lastinfo step2 used time: %s > 5s",
                                    _now_time - _start_time)

                    res[tid] = {'car_info':{},
                                'track_info':[]}

                    # 0: get group info
                    group_info = get_group_info_by_tid(self.db, tid)

                    # 1: get terminal info 
                    terminal = QueryHelper.get_terminal_info(tid, self.db, self.redis) 
                    mobile = terminal['mobile']
                    if terminal['login'] == GATEWAY.TERMINAL_LOGIN.SLEEP:
                        terminal['login'] = GATEWAY.TERMINAL_LOGIN.ONLINE

                    # 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]
                        if location.clatitude and location.clongitude:
                            self.redis.setvalue(location_key, location, EVENTER.LOCATION_EXPIRY)

                    if location and location['name'] is None:
                        location['name'] = location['name'] if location['name'] else ''


                    if location and location['type'] == 1: # cellid
                        location['locate_error'] = 500  # mile

                    avatar_full_path, avatar_path, avatar_name, avatar_time = self.get_avatar_info(mobile)
                    service_status = QueryHelper.get_service_status_by_tmobile(self.db, mobile)

                    acc_status_info = QueryHelper.get_acc_status_info_by_tid(self.client_id, tid, self.db, self.redis)
                    acc_message = acc_status_info['acc_message']

                    car_info=dict(defend_status=terminal['defend_status'] if terminal.get('defend_status', None) is not None else 1,
                                  service_status=service_status,
                                  mannual_status=terminal['mannual_status'] if terminal.get('mannual_status', None) is not None else 1,
                                  acc_message=acc_message,
                                  fob_status=terminal['fob_status'] if terminal.get('fob_status', None) 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,
                                  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,
                                  bt_name=terminal.get('bt_name', '') if terminal else '',
                                  bt_mac=terminal.get('bt_mac', '') if terminal else '',
                                  dev_type=terminal['dev_type'] if terminal.get('dev_type', None) is not None else 'A',
                                  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'] if terminal['alias'] else terminal['mobile'],
                                  #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'],
                                  fob_list=terminal['fob_list'] if terminal['fob_list'] else [],
                                  avatar_path=avatar_path,
                                  avatar_time=avatar_time)

                    res[tid]['car_info'] = car_info
                
                lastposition_key = get_lastposition_key(self.current_user.uid)
                lastposition = self.redis.get(lastposition_key)

                lastposition_time_key = get_lastposition_time_key(self.current_user.uid)
                lastposition_time = self.redis.getvalue(lastposition_time_key)

                if lastposition == str(res):  
                    pass
                else:
                    lastposition_time = int(time.time())
                    self.redis.setvalue(lastposition_key, res) 
                    self.redis.setvalue(lastposition_time_key, lastposition_time)

                query_time = data.get('lastposition_time', None)
                # 2 check whether provide usable data   
                if int(data.get('cache', 0)) == 1:  # use cache
                    if int(query_time) == lastposition_time:
                        usable = 0 
                        res = {} 
                    else: 
                        usable = 1
                        for item in track_list:
                            track_tid = item['track_tid']
                            if track_tid not in tids:
                                logging.error("The terminal with tid: %s does not exist", 
                                              track_tid)
                            else:
                                track_time = item['track_time']
                                track_key = get_track_key(track_tid)
                                self.redis.setvalue(track_key, 1, UWEB.TRACK_INTERVAL)
                                car_info = res[track_tid]['car_info']
                                endtime = int(car_info['timestamp'])-1 if car_info['timestamp'] else int(lastposition_time)-1 
                                track_info = self.get_track_info(track_tid, int(track_time)+1, endtime)
                                res[track_tid]['track_info'] = track_info
                else: 
                    usable = 1
                    for item in track_list:
                        track_tid = item['track_tid']
                        if track_tid not in tids:
                            logging.error("The terminal with tid: %s does not exist", track_tid)
                        else:
                            track_time = item['track_time']
                            track_key = get_track_key(track_tid)
                            self.redis.setvalue(track_key, 1, UWEB.TRACK_INTERVAL)
                            car_info = res[track_tid]['car_info']
                            endtime = int(car_info['timestamp'])-1 if car_info['timestamp'] else int(time.time())-1
                            track_info = self.get_track_info(track_tid, int(track_time)+1, endtime) 
                            res[track_tid]['track_info'] = track_info
               
                if int(version_type) >= 1:
                    terminals = []
                    for k, v in res.iteritems():
                        v.update({'tid':k})
                        terminals.append(v)

                    self.write_ret(status, 
                                   dict_=DotDict(terminals=terminals,
                                                 usable=usable,
                                                 lastposition_time=lastposition_time))

                else:
                    self.write_ret(status, 
                                   dict_=DotDict(res=res,
                                                 usable=usable,
                                                 lastposition_time=lastposition_time))
                _now_time = time.time()
                if (_now_time - _start_time) > 5:
                    logging.info("[UWEB] Lastinfo step3 used time: %s > 5s",
                                _now_time - _start_time)
            except Exception as e:
                logging.exception("[UWEB] uid: %s get lastposition failed. Exception: %s", 
                                  self.current_user.uid, e.args) 
                status = ErrorCode.SERVER_BUSY
                self.write_ret(status)
            IOLoop.instance().add_callback(self.finish)
Exemple #11
0
        def _on_finish(db):
            self.db = db
            try:
                data = DotDict(json_decode(self.request.body))
                track_lst = data.get("track_lst", [])
                # NOTE: nearly all timestamp's len is 10, here use 13
                current_time = int(time.time() * 1000)
                lastinfo_time = data.get("lastinfo_time")
            except Exception as e:
                status = ErrorCode.ILLEGAL_DATA_FORMAT
                logging.info(
                    "[UWEB] inlastfinfo for corp failed, message: %s, Exception: %s, request: \n%s",
                    ErrorCode.ERROR_MESSAGE[status],
                    e.args,
                    self.request.body,
                )
                self.write_ret(status)
                IOLoop.instance().add_callback(self.finish)
                return

            try:
                status = ErrorCode.SUCCESS
                REMOVE_GID_TID = []  # [(gid, tid),(gid,tid),]
                res_type = 0
                # NOTE: first time, lastinfo_time = -1, set the lsstinfo_time
                # as current_time
                if lastinfo_time == -1:
                    # logging.info("[UWEB] res_type=2, first time, cid:%s", self.current_user.cid)
                    res_type = 2
                    lastinfo_time = current_time

                corp = self.db.get("SELECT cid, name, mobile FROM T_CORP WHERE cid = %s", self.current_user.cid)
                if self.current_user.oid == UWEB.DUMMY_OID:
                    uid = self.current_user.cid
                    groups = self.db.query("SELECT id gid, name FROM T_GROUP WHERE corp_id = %s" "  ORDER BY id", uid)
                else:
                    uid = self.current_user.oid
                    groups = self.db.query("SELECT group_id FROM T_GROUP_OPERATOR WHERE oper_id = %s", uid)
                    gids = [g.group_id for g in groups]
                    groups = self.db.query(
                        "SELECT id gid, name FROM T_GROUP WHERE id IN %s" "  ORDER BY id", tuple(DUMMY_IDS + gids)
                    )

                corp_info = dict(name=corp["name"] if corp else "", cid=corp["cid"] if corp else "")

                corp_info_key = get_corp_info_key(uid)

                corp_info_tuple = self.redis.getvalue(corp_info_key)
                if corp_info_tuple:
                    corp_info_old, corp_info_time = corp_info_tuple
                else:
                    corp_info_old, corp_info_time = None, None

                if corp_info_old is not None:
                    if corp_info_old != corp_info:
                        # logging.info("[UWEB] res_type=2, corp_info changed, cid:%s", self.current_user.cid)
                        res_type = 2
                        self.redis.setvalue(corp_info_key, (corp_info, current_time))
                    else:
                        if lastinfo_time < corp_info_time:
                            # logging.info("[UWEB] res_type=2, corp_info time changed, lastinfo_time:%s < corp_info_time:%s, cid:%s",
                            # lastinfo_time, corp_info_time,
                            # self.current_user.cid)
                            res_type = 2
                else:
                    self.redis.setvalue(corp_info_key, (corp_info, current_time))

                _now_time = time.time()
                if (_now_time - _start_time) > 5:
                    logging.info(
                        "[UWEB] Inclastinfo step1_corp used time: %s > 5s, cid: %s",
                        _now_time - _start_time,
                        self.current_user.cid,
                    )

                res = DotDict(
                    name=corp_info["name"],
                    cid=corp_info["cid"],
                    online=0,
                    offline=0,
                    groups=[],
                    lastinfo_time=current_time,
                )

                group_info_key = get_group_info_key(uid)
                group_info_tuple = self.redis.getvalue(group_info_key)
                if group_info_tuple:
                    group_info_old, group_info_time = group_info_tuple
                else:
                    group_info_old, group_info_time = None, None
                if group_info_old is not None:
                    if group_info_old != groups:
                        # logging.info("[UWEB] res_type=2, group_info changed, cid:%s", self.current_user.cid)
                        res_type = 2
                        self.redis.setvalue(group_info_key, (groups, current_time))
                    else:
                        if lastinfo_time < group_info_time:
                            # logging.info("[UWEB] res_type=2, group_info time changed, lastinfo_time:%s < group_info_time:%s, cid:%s",
                            # lastinfo_time, group_info_time,
                            # self.current_user.cid)
                            res_type = 2
                else:
                    self.redis.setvalue(group_info_key, (groups, current_time))

                for group in groups:
                    group["trackers"] = {}
                    terminals = QueryHelper.get_terminals_by_group_id(group.gid, db)
                    tids = [str(terminal.tid) for terminal in terminals]
                    _now_time = time.time()
                    if (_now_time - _start_time) > 5:
                        logging.info(
                            "[UWEB] Inclastinfo step1_group_sql used time: %s > 5s, cid: %s, gid: %s",
                            _now_time - _start_time,
                            self.current_user.cid,
                            group.gid,
                        )

                    terminal_info_key = get_group_terminal_info_key(uid, group.gid)
                    terminal_info_tuple = self.redis.getvalue(terminal_info_key)
                    if terminal_info_tuple:
                        terminal_info_old, terminal_info_time = terminal_info_tuple
                    else:
                        terminal_info_old, terminal_info_time = None, None
                    if terminal_info_old is not None:
                        if terminal_info_old != tids:
                            # logging.info("[UWEB] res_type=2, terminal_info changed, cid:%s", self.current_user.cid)
                            res_type = 2
                            self.redis.setvalue(terminal_info_key, (tids, current_time))
                        else:
                            if lastinfo_time < terminal_info_time:
                                # logging.info("[UWEB] res_type=2, terminal_info time changed, lastinfo_time:%s < terminal_info_time:%s, cid:%s",
                                # lastinfo_time, terminal_info_time,
                                # self.current_user.cid)
                                res_type = 2
                    else:
                        self.redis.setvalue(terminal_info_key, (tids, current_time))
                    _now_time = time.time()
                    if (_now_time - _start_time) > 5:
                        logging.info(
                            "[UWEB] Inclastinfo step1_group used time: %s > 5s, cid: %s, gid: %s",
                            _now_time - _start_time,
                            self.current_user.cid,
                            group.gid,
                        )
                    for tid in tids:
                        _now_time = time.time()
                        if (_now_time - _start_time) > 5:
                            logging.info(
                                "[UWEB] Inclastinfo step2 used time: %s > 5s, cid: %s",
                                _now_time - _start_time,
                                self.current_user.cid,
                            )

                        group["trackers"][tid] = {}
                        # 1: get terminal info
                        terminal = QueryHelper.get_terminal_info(tid, self.db, self.redis)
                        if terminal["login"] == GATEWAY.TERMINAL_LOGIN.SLEEP:
                            terminal["login"] = GATEWAY.TERMINAL_LOGIN.ONLINE

                        if terminal["login"] == GATEWAY.TERMINAL_LOGIN.ONLINE:
                            res["online"] += 1
                        else:
                            res["offline"] += 1

                        # 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]
                            # NOTE: offset latlon
                            # 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"] = ""

                        if location and location["type"] == 1:  # cellid
                            location["locate_error"] = 500  # mile

                        acc_status_info = QueryHelper.get_acc_status_info_by_tid(
                            self.client_id, tid, self.db, self.redis
                        )
                        acc_message = acc_status_info["acc_message"]
                        op_status = acc_status_info["op_status"]

                        # 1: build the basic_info
                        basic_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,
                            acc_message=acc_message,
                            op_status=op_status,
                            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,
                            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,
                            bt_name=terminal.get("bt_name", "") if terminal else "",
                            bt_mac=terminal.get("bt_mac", "") if terminal else "",
                            dev_type=terminal["dev_type"] if terminal.get("dev_type", None) is not None else "A",
                            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,
                            icon_type=terminal["icon_type"] if terminal.get("icon_type", None) is not None else 0,
                            fob_list=terminal["fob_list"] if terminal["fob_list"] else [],
                        )

                        _now_time = time.time()
                        if (_now_time - _start_time) > 5:
                            logging.info(
                                "[UWEB] Inclastinfo step2_basic used time: %s > 5s, cid: %s",
                                _now_time - _start_time,
                                self.current_user.cid,
                            )
                        # 2: build track_info
                        track_info = []
                        for item in track_lst:
                            if tid == item["track_tid"]:
                                track_key = get_track_key(tid)
                                self.redis.setvalue(track_key, 1, UWEB.TRACK_INTERVAL)
                                # endtime = int(basic_info['timestamp'])-1 if basic_info['timestamp'] else (current_time/1000)-1
                                endtime = int(basic_info["timestamp"]) - 1
                                points_track = []

                                logging.info(
                                    "[UWEB] tid: %s, track_time, %s, %s", tid, int(item["track_time"]) + 1, endtime
                                )
                                # NOTE: offset latlon
                                # points_track = get_locations_with_clatlon(points_track, self.db)
                                for point in points_track:
                                    if point["clatitude"] and point["clongitude"]:
                                        t = dict(
                                            latitude=point["latitude"],
                                            longitude=point["longitude"],
                                            clatitude=point["clatitude"],
                                            clongitude=point["clongitude"],
                                            type=point["type"],
                                            timestamp=point["timestamp"],
                                        )
                                        track_info.append(t)
                                break

                        _now_time = time.time()
                        if (_now_time - _start_time) > 5:
                            logging.info(
                                "[UWEB] Inclastinfo step2_track used time: %s > 5s, cid: %s",
                                _now_time - _start_time,
                                self.current_user.cid,
                            )
                        # 3: build trace_info
                        trace_info = []
                        points_trace = []
                        points_trace = points_trace[-5:]
                        # points_trace = get_locations_with_clatlon(points_trace, self.db)
                        len_trace = 0
                        if points_trace:
                            for point in points_trace:
                                if len_trace >= 5:
                                    break
                                if point["clatitude"] and point["clongitude"]:
                                    trace_info.append(point["clatitude"])
                                    trace_info.append(point["clongitude"])
                                    len_trace += 1
                                else:
                                    continue

                        _now_time = time.time()
                        if (_now_time - _start_time) > 5:
                            logging.info(
                                "[UWEB] Inclastinfo step2_trace used time: %s > 5s, cid: %s",
                                _now_time - _start_time,
                                self.current_user.cid,
                            )

                        # 4: build alert_info
                        alarm_info_key = get_alarm_info_key(tid)
                        alarm_info_all = self.redis.getvalue(alarm_info_key)
                        alarm_info_all = alarm_info_all if alarm_info_all else []
                        alarm_info = []

                        if alarm_info_all:
                            for alarm in alarm_info_all:
                                # NOTE: here, check alarm's keeptime when kept
                                # in reids, not timestamp alarm occurs
                                if alarm.get("keeptime", None) is None:
                                    alarm["keeptime"] = alarm["timestamp"]
                                if alarm["keeptime"] >= lastinfo_time / 1000:
                                    alarm_info.append(alarm)

                        for alarm in alarm_info:
                            alarm["alias"] = terminal["alias"]

                        _now_time = time.time()
                        if (_now_time - _start_time) > 5:
                            logging.info(
                                "[UWEB] Inclastinfo step2_alarm used time: %s > 5s, cid: %s",
                                _now_time - _start_time,
                                self.current_user.cid,
                            )
                        group["trackers"][tid]["basic_info"] = basic_info
                        group["trackers"][tid]["track_info"] = track_info
                        group["trackers"][tid]["trace_info"] = trace_info
                        group["trackers"][tid]["alarm_info"] = alarm_info

                        terminal_detail_key = get_group_terminal_detail_key(uid, group.gid, tid)
                        terminal_detail_tuple = self.redis.getvalue(terminal_detail_key)
                        if terminal_detail_tuple:
                            terminal_detail_old, terminal_detail_time = terminal_detail_tuple
                        else:
                            terminal_detail_old, terminal_detail_time = None, None

                        if res_type != 2:
                            if terminal_detail_old is not None:
                                if terminal_detail_old != group["trackers"][tid]:
                                    self.redis.setvalue(terminal_detail_key, (group["trackers"][tid], current_time))
                                    # logging.info("[UWEB] res_type=1, terminal detail changed cid:%s", self.current_user.cid)
                                    res_type = 1
                                else:
                                    if lastinfo_time < terminal_detail_time:
                                        # logging.info("[UWEB] res_type=1, terminal detail time changed cid:%s", self.current_user.cid)
                                        res_type = 1
                                    else:
                                        # logging.info("[UWEB] res_type=0, terminal detail no changed cid:%s", self.current_user.cid)
                                        REMOVE_GID_TID.append((group.gid, tid))
                            else:
                                self.redis.setvalue(terminal_detail_key, (group["trackers"][tid], current_time))
                        else:
                            pass
                    res.groups.append(group)

                if res_type == 0:
                    res = DotDict(lastinfo_time=current_time)
                    self.write_ret(status, dict_=DotDict(res=res, res_type=res_type))
                else:
                    if res_type == 1:
                        for gid, tid in REMOVE_GID_TID:
                            # logging.info("[UWEB] res_type=1, gid: %s, tid: %s is tobe removed. cid:%s",
                            #             gid, tid, self.current_user.cid)
                            for index, group in enumerate(res.groups):
                                if gid == group["gid"]:
                                    del res.groups[index]["trackers"][tid]
                                    # logging.info("[UWEB] res_type=1, gid: %s, tid: %s is removed. cid:%s",
                                    # gid, tid, self.current_user.cid)

                        _groups = deepcopy(res.groups)
                        for index, group in enumerate(_groups):
                            if not group["trackers"]:
                                res.groups.remove(group)
                                # logging.info("[UWEB] res_type=1, gid: %s, has no tracker, remove it. cid:%s",
                                #             gid, self.current_user.cid)

                    self.write_ret(status, dict_=DotDict(res=res, res_type=res_type))

                _now_time = time.time()
                if (_now_time - _start_time) > 5:
                    logging.info(
                        "[UWEB] Inclastinfo step3 used time: %s > 5s, cid: %s",
                        _now_time - _start_time,
                        self.current_user.cid,
                    )
            except Exception as e:
                logging.exception(
                    "[UWEB] cid: %s get corp lastinfo failed. Exception: %s", self.current_user.cid, e.args
                )
                status = ErrorCode.SERVER_BUSY
                self.write_ret(status)
            IOLoop.instance().add_callback(self.finish)