Пример #1
0
    def send_offline_remind_sms(self):
        logging.info("[CELERY] checkertask send offline remind sms started.")
        try:
            currenttime = int(time.time())

            terminals = self.db.query("SELECT tid, alias, mobile, owner_mobile, offline_time"
                                      "  FROM T_TERMINAL_INFO"
                                      "  WHERE login = 0"
                                      "  AND service_status = 1"
                                      "  AND offline_time < %s",
                                      (currenttime - 24*60*60))
            for terminal in terminals:
                sms_option = QueryHelper.get_sms_option_by_uid(terminal.owner_mobile, 'heartbeat_lost', self.db)
                if sms_option == UWEB.SMS_OPTION.SEND:
                    ctime = get_terminal_time(currenttime)
                    ctime = safe_unicode(ctime)

                    alias = terminal['alias'] if terminal['alias'] else terminal['mobile']
                    sms = SMSCode.SMS_HEARTBEAT_LOST % (alias, ctime)
                    SMSHelper.send(terminal.owner_mobile, sms)
                    logging.info("[CELERY] Send offline remind sms to user:%s, tid:%s", terminal.owner_mobile, terminal.tid)
           
            logging.info("[CELERY] checkertask send offline remind sms finished.")
        except Exception as e:
            logging.exception("[CELERY] Check terminal poweroff timeout exception.")
Пример #2
0
    def get(self, hash_):
        """Download the records and save it as excel.
        """
        mem_key = self.get_memcache_key(hash_)

        r = self.redis.getvalue(mem_key)
        if r:
            results, interval = r[0], r[1]
        else:
            self.render("errors/download.html")
            return

        wb = xlwt.Workbook()
        ws = wb.add_sheet(OFFLINE_SHEET)

        start_line = 0
        for i, head in enumerate(OFFLINE_HEADER):
            ws.write(0, i, head)

        ws.col(1).width = 4000 * 4 
        ws.col(2).width = 4000  
        ws.col(3).width = 4000 
        ws.col(4).width = 4000 
        ws.col(6).width = 4000 * 2 
        ws.col(7).width = 4000 * 2
        ws.col(8).width = 4000 * 2
        ws.col(10).width = 4000 * 4

        start_line += 1

        for i, result in zip(range(start_line, len(results) + start_line), results):
            ws.write(i, 0, u'个人用户' if result['user_type'] == UWEB.USER_TYPE.PERSON else u'集团用户')
            ws.write(i, 1, result['corp_name'])
            ws.write(i, 2, result['umobile'])
            ws.write(i, 3, result['tmobile'])
            ws.write(i, 4, result['tid'])
            ws.write(i, 5, result['softversion'])
            ws.write(i, 6, result['alias'])
            ws.write(i, 7, str(result['pbat'])+'%')
            ws.write(i, 8, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time'])))
            ws.write(i, 9, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['login_time'])))
            ws.write(i, 10, seconds_to_label(result['offline_period']))
            ws.write(i, 11, u'低电关机' if result['offline_cause'] == 2 else u'通讯异常')
            terminal_offline = self.db.get("SELECT remark FROM T_TERMINAL_INFO"
                                           "  WHERE id = %s", result['id'])
            ws.write(i, 12, safe_unicode(terminal_offline['remark']))

          
        _tmp_file = StringIO()
        wb.save(_tmp_file)
        filename = self.generate_file_name(OFFLINE_FILE_NAME)

        self.set_header('Content-Type', 'application/force-download')
        self.set_header('Content-Disposition', 'attachment; filename=%s.xls' % (filename,))

        # move the the begging.
        _tmp_file.seek(0, SEEK_SET)
        self.write(_tmp_file.read())
        _tmp_file.close()
Пример #3
0
    def get(self, privilegegroupname):
        """
        check whether the privilegegroupname already exists.
        """

        r = self.db.query("SELECT id FROM T_PRIVILEGE_GROUP"
                          " WHERE name = %s",safe_unicode(privilegegroupname))
        ret = dict(success=True if r else False)
        self.set_header(*self.JSON_HEADER)
        self.write(json_encode(ret))
Пример #4
0
    def get(self, hash_):
        """Download the records and save it as excel.
        """
        mem_key = self.get_memcache_key(hash_)

        results = self.redis.getvalue(mem_key)

        if not results:
            self.render("errors/download.html")
            return

        filename = BUSINESS_FILE_NAME 
        online_style = xlwt.easyxf('font: colour_index green, bold off; align: wrap on, vert centre, horiz center;') 
        offline_style = xlwt.easyxf('font: colour_index brown, bold off; align: wrap on, vert centre, horiz center;')

        wb = xlwt.Workbook()
        ws = wb.add_sheet(BUSINESS_SHEET)

        start_line = 0
        for i, head in enumerate(BUSINESS_HEADER): 
            ws.write(0, i, head)

        start_line += 1
        for i, result in zip(range(start_line, len(results) + start_line), results):
            ws.write(i, 0, i)
            ws.write(i, 1, safe_unicode(result['ecname']) if result['ecname'] else u'')
            ws.write(i, 2, result['cmobile'])
            ws.write(i, 3, result['umobile'])
            ws.write(i, 4, result['tmobile'])
            ws.write(i, 5, result['tid'])
            ws.write(i, 6, result['softversion'])
            ws.write(i, 7, result['alias'])
            ws.write(i, 8, u'移动卫士' if int(result['biz_type']) == 0 else u'移动外勤')
            if int(result['login']) == 0:
                ws.write(i, 9, u'离线', offline_style)
            else:
                ws.write(i, 9, u'在线', online_style)
            ws.write(i, 10, '%s%%' % result['pbat'])
            ws.write(i, 11, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['begintime'])))
            ws.write(i, 12, result['bt_name'])
            ws.write(i, 13, result['bt_mac'])

        _tmp_file = StringIO()
        wb.save(_tmp_file)
        
        filename = self.generate_file_name(filename)

        self.set_header('Content-Type', 'application/force-download')
        self.set_header('Content-Disposition', 'attachment; filename=%s.xls' % (filename,))

        # move the the begging. 
        _tmp_file.seek(0, SEEK_SET)
        self.write(_tmp_file.read())
        _tmp_file.close()
Пример #5
0
    def put(self):
        """Modify profile of current user.
        """
        status = ErrorCode.SUCCESS
        try:
            data = DotDict(json_decode(self.request.body))
            tid = data.get('tid',None) 
            # check tid whether exist in request and update current_user
            self.check_tid(tid)
            logging.info("[UWEB] User profile request: %s, uid: %s, tid: %s", 
                         data, self.current_user.uid, self.current_user.tid)
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            self.write_ret(status)
            return 

        try:
            if data.has_key('name')  and not check_name(data.name):
                status = ErrorCode.ILLEGAL_NAME 
                self.write_ret(status)
                return
     
            name = data.get('name', None)
            if name is not None:
                sql_cmd = "UPDATE T_USER SET name = %s WHERE uid = %s"
                self.db.execute(sql_cmd, 
                                name, self.current_user.uid)

            cnum = data.get('cnum', None)
            if cnum is not None:
                self.db.execute("UPDATE T_CAR"
                                "  SET cnum = %s"
                                "  WHERE tid = %s",
                                safe_unicode(cnum), self.current_user.tid)
                terminal_info_key = get_terminal_info_key(self.current_user.tid)
                terminal_info = self.redis.getvalue(terminal_info_key)
                if terminal_info:
                    terminal_info['alias'] = cnum if cnum else self.current_user.sim 
                    self.redis.setvalue(terminal_info_key, terminal_info)

            self.write_ret(status)
        except Exception as e:
            logging.exception("[UWEB] Update profile failed. uid:%s, tid:%s, Exception: %s", 
                              self.current_user.uid, self.current_user.tid, e.args)
            status = ErrorCode.SERVER_BUSY
            self.write_ret(status)
Пример #6
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) 
Пример #7
0
    def post(self):
        """Insert new items."""
        status = ErrorCode.SUCCESS
        try:
            data = DotDict(json_decode(self.request.body))
            mobile = data.get('mobile', '')
            logging.info("[UWEB] feedback request: %s", data)
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            self.write_ret(status)
            return 

        try:
            #if data.has_key('contact') and not check_sql_injection(data.contact):
            #    status = ErrorCode.ILLEGAL_NAME
            #    logging.info("[UWEB] feedback failed, Message: %s", ErrorCode.ERROR_MESSAGE[status])
            #    self.write_ret(status)
            #    return

            #if data.has_key('email')  and not check_sql_injection(data.email):
            #    status = ErrorCode.ILLEGAL_EMAIL
            #    logging.info("[UWEB] feedback failed, Message: %s", ErrorCode.ERROR_MESSAGE[status])
            #    self.write_ret(status)
            #    return

            self.db.execute("INSERT INTO T_FEEDBACK(contact, mobile,"
                            "  email, content, timestamp, category)"
                            "  VALUES(%s, %s, %s, %s, %s, %s)",
                            data.contact, mobile, data.email, 
                            safe_unicode(data.content),
                            int(time.time()), data.category)
            self.write_ret(status)
        except Exception as e:
            status = ErrorCode.FEEDBACK_FAILED
            logging.exception("[UWEB] add feedback failed, Exception: %s, content:\n%s", 
                              e.args, data.content)
            self.write_ret(status)
Пример #8
0
    def statistic_offline_terminal(self, epoch_time):
        """Export data into excel file.
        """ 
        start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 
        logging.info("[CELERY] %s statistic_offline_terminal started.", start_time)

        current_day = time.localtime(epoch_time)
        day_start_time, day_end_time = start_end_of_day(current_day.tm_year, current_day.tm_mon, current_day.tm_mday)
        month_start_time, month_end_time = start_end_of_month(current_day.tm_year, current_day.tm_mon)
        year_start_time, year_end_time = start_end_of_year(current_day.tm_year)

        logging.info("[CELERY] day_start_time: %s, day_end_time: %s, month_start_time: %s, month_end_time: %s, year_start_time: %s, year_end_time: %s.", 
                    day_start_time, day_end_time, month_start_time, month_end_time, year_start_time, year_end_time)


        import xlwt 
        import xlrd

        BASE_PATH = '/var/ydcws/reports/' 
        # NOTE: chinese filename cannot download successfully, so here use
        # english filename. wish one day chinese words can work well 
        OFFLINE_FILE_NAME = u"terminals_offline"
        #OFFLINE_FILE_NAME = u"离线用户统计表"
        cur_path = time.strftime("%Y%m%d",time.localtime(epoch_time) ) 
        pre_path = time.strftime("%Y%m%d",time.localtime(epoch_time-60*60*24)) 
        PRE_PATH = BASE_PATH + OFFLINE_FILE_NAME + '-' + pre_path + '.xls'
        CUR_PATH = BASE_PATH + OFFLINE_FILE_NAME + '-' + cur_path + '.xls'

        OFFLINE_HEADER = (u"车主号",
                          u"终端号", 
                          u"电量", 
                          u"离线时间", 
                          u"累计离线时间", 
                          u"离线原因", 
                          u"唤醒指令下发频次", 
                          u"今日新增", 
                          u"当前状态", 
                          u"基站定位结果", 
                          u"备注")

        OFFLINE_DETAIL_HEADER = (u"用户类型", 
                                 u"车主号",
                                 u"终端号", 
                                 u"电量", 
                                 u"离线时间", 
                                 u"累计离线时间", 
                                 u"离线原因", 
                                 u"备注")

        # offline-terminals of this day 
        cur_sql_cmd = ("SELECT id, owner_mobile as umobile, mobile as tmobile,"
                       "  begintime, offline_time, pbat, remark"
                       "  FROM T_TERMINAL_INFO"
                       "  WHERE service_status = 1 AND login =0 "
                       "  AND (mobile LIKE '14778%%' OR  mobile LIKE '1847644%%') "
                       "  AND (offline_time BETWEEN %s AND %s) ORDER BY pbat")

        # offline-terminals till now 
        #terminals_offline_cmd  = ("SELECT id, owner_mobile as umobile, mobile as tmobile,"
        #                          "  begintime, offline_time, pbat, remark, group_id"
        #                          "  FROM T_TERMINAL_INFO"
        #                          "  WHERE service_status = 1 AND login =0 "
        #                          "  AND (mobile LIKE '14778%%' OR  mobile LIKE '1847644%%') "
        #                          "  ORDER BY group_id, pbat")

        terminals_offline_cmd  = ("SELECT id, owner_mobile as umobile, mobile as tmobile,"
                                  "  begintime, offline_time, pbat, remark, group_id"
                                  "  FROM T_TERMINAL_INFO"
                                  "  WHERE service_status=1 AND login=0 "
                                  "  ORDER BY group_id, pbat")

        terminal_sql_cmd = "SELECT login, remark, offline_time FROM T_TERMINAL_INFO WHERE mobile = %s LIMIT 1"

        cur_res = self.db.query(cur_sql_cmd, day_start_time, epoch_time)
        terminals_ofline = self.db.query(terminals_offline_cmd)

        tmobile_lst = []
        for item in cur_res:
            tmobile_lst.append(item['tmobile'])
            item['offline_period'] = int(time.time()) - item['offline_time']
            item['offline_cause'] =  2 if item['pbat'] < 5 else 1
            item['sim_status'] = u'失败'
            if item['offline_cause'] == 1: # heart beat
                # check the sim status
                terminal_log = self.db.get("SELECT sim_status FROM T_BIND_LOG"
                                           "  WHERE tmobile = %s LIMIT 1",
                                           item['tmobile'])
                if terminal_log.sim_status == 1:
                    item['sim_status'] = u'成功'
            
            item['remark'] = safe_unicode(item['remark'])
        logging.info('[CELERY] the currentrecords to be dealed with, counts: %s, cur_res: %s', len(cur_res), cur_res)
         
        # NOTE: get last day's data
        pre_res = [] 
        if not os.path.isfile(PRE_PATH):
            logging.info("[CELERY] pre_path: %s cannot be found.", PRE_PATH)
        else:
            wb=xlrd.open_workbook(PRE_PATH)
            sh=wb.sheet_by_name(u'离线汇总分析')
            for rownum in range(1,sh.nrows): # get records from the second row

                row = sh.row_values(rownum)

                if row[1] in tmobile_lst:
                    continue
                if row[8] == u'在线':
                    continue

                tmobile = row[1]

                terminal = self.db.get(terminal_sql_cmd, tmobile) 

                current_status = u'离线'
                if not terminal:
                    current_status = u'已解绑'
                    row[8] = current_status
                else:
                    if terminal['login'] !=0:
                        current_status = u'在线'
                        row[8] = current_status

                    offline_period = int(time.time()) - terminal['offline_time']
                    row[4] = seconds_to_label(offline_period)
                    d,m = divmod(offline_period,60*60)
                    count = d+1 if m else d
                    row[6] = count
                    row[10] = safe_unicode(terminal['remark'])
                pre_res.append(row)
            logging.info('[CELERY] the previous records to be dealed with, count: %s, pre_res: %s', len(pre_res), pre_res)

        # some styles
        #date_style = xlwt.easyxf(num_format_str='YYYY-MM-DD HH:mm:ss')
        title_style = xlwt.easyxf('pattern: pattern solid, fore_colour ocean_blue; font: bold off; align: wrap on, vert centre, horiz center;' "borders: top double, bottom double, left double, right double;")
        abnormal_style = xlwt.easyxf('font: colour_index red, bold off; align: wrap on, vert centre, horiz center;')
        add_style = xlwt.easyxf('font: colour_index blue, bold off; align: wrap on, vert centre, horiz center;')
        powerlow_style = xlwt.easyxf('font: colour_index dark_yellow, bold off; align: wrap on, vert centre, horiz center;') 
        online_style = xlwt.easyxf('font: colour_index green, bold off; align: wrap on, vert centre, horiz center;')
        offline_style = xlwt.easyxf('font: colour_index brown, bold off; align: wrap on, vert centre, horiz center;')
        center_style  = xlwt.easyxf('align: wrap on, vert centre, horiz center;')


        wb = xlwt.Workbook()
        ws = wb.add_sheet(u'离线汇总分析')
        ws_detail = wb.add_sheet(u'离线明细')

        # sheet 1: 离线汇总分析
        start_line = 0
        for i, head in enumerate(OFFLINE_HEADER):
            ws.write(0, i, head, title_style)

        ws.col(0).width = 4000 # umobile 
        ws.col(1).width = 4000 # tmobile 
        ws.col(3).width = 4000 * 2  # offline_time
        ws.col(4).width = 4000 * 2  # offline_period
        ws.col(6).width = 4000      # lq count
        ws.col(9).width = 4000  # sim_status
        ws.col(10).width = 4000 * 4 # remark

        start_line += 1

        results = cur_res
        for i, result in zip(range(start_line, len(results) + start_line), results):
            ws.write(i, 0, result['umobile'], center_style)
            ws.write(i, 1, result['tmobile'], center_style)
            ws.write(i, 2, str(result['pbat'])+'%', center_style)
            ws.write(i, 3, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time'])), center_style)
            ws.write(i, 4, seconds_to_label(result['offline_period']), center_style)

            if result['offline_cause'] == 2: 
                offline_cause =  u'低电关机' 
                ws.write(i, 5, offline_cause, powerlow_style)
            else:
                offline_cause =  u'通讯异常'
                ws.write(i, 5, offline_cause, abnormal_style)
                if result['sim_status'] == u'成功': 
                    ws.write(i, 9, safe_unicode(result['sim_status']), online_style)
                else:
                    ws.write(i, 9, safe_unicode(result['sim_status']), abnormal_style)
            d,m = divmod(result['offline_period'],60*60)
            count = d+1 if m else d
            ws.write(i, 6, count)
            terminal = self.db.get("SELECT remark FROM T_TERMINAL_INFO where id = %s", result['id'])

            ws.write(i, 7, u'新增', add_style)
            ws.write(i, 10, safe_unicode(terminal['remark']), center_style)
            start_line += 1

        logging.info('[CELERY] current offline records, count: %s, tmobile_lst: %s', len(tmobile_lst), tmobile_lst)
        results = pre_res
        for i, result in zip(range(start_line, len(results) + start_line), results):
            #for j in range(len(OFFLINE_HEADER)):
            #    ws.write(i, j, result[j])
            #if result[1] in tmobile_lst:
            #    continue
            ws.write(i, 0, result[0], center_style)
            ws.write(i, 1, result[1], center_style)
            ws.write(i, 2, result[2], center_style)
            ws.write(i, 3, result[3], center_style)
            ws.write(i, 4, result[4], center_style)

            if result[5] == u'低电关机':
                ws.write(i, 5, u'低电关机', powerlow_style)
            else:
                ws.write(i, 5, u'通讯异常', abnormal_style)
            ws.write(i, 6, result[6])
            if result[8] == u'在线':
                ws.write(i, 8, u'在线', online_style)
            elif result[8] == u'已解绑': 
                ws.write(i, 8, u'已解绑')
            else:
                pass
            #ws.write(i, 9, result[9], center_style)
            ws.write(i, 10, result[10], center_style)

        # sheet 2: 离线明细

        start_line = 0
        for i, head in enumerate(OFFLINE_DETAIL_HEADER):
            ws_detail.write(0, i, head, title_style)

        ws_detail.col(1).width = 4000 
        ws_detail.col(2).width = 4000 
        ws_detail.col(4).width = 4000 * 2 
        ws_detail.col(5).width = 4000 * 2 
        ws_detail.col(7).width = 4000 * 4

        start_line += 1
        results = terminals_ofline
        for i, result in zip(range(start_line, len(results) + start_line), results):
            # some modification 
            if result['group_id'] == -1: 
                result['user_type'] = UWEB.USER_TYPE.PERSON 
            else: 
                result['user_type'] = UWEB.USER_TYPE.CORP
            offline_period = int(time.time()) - result['offline_time'] 
            result['offline_period'] = offline_period if offline_period > 0  else  0 
            result['offline_cause'] = 2 if result['pbat'] < 5 else 1

            ws_detail.write(i, 0, u'个人用户' if result['user_type'] == UWEB.USER_TYPE.PERSON else u'集团用户')
            ws_detail.write(i, 1, result['umobile'], center_style)
            ws_detail.write(i, 2, result['tmobile'], center_style)
            ws_detail.write(i, 3, str(result['pbat'])+'%', center_style)
            ws_detail.write(i, 4, time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result['offline_time'])), center_style) 
            ws_detail.write(i, 5, seconds_to_label(result['offline_period']))

            if result['offline_cause'] == 2: 
                offline_cause =  u'低电关机' 
                ws_detail.write(i, 6, offline_cause, powerlow_style)
            else:
                offline_cause =  u'通讯异常'
                ws_detail.write(i, 6, offline_cause, abnormal_style)
            #ws_detail.write(i, 6, u'低电关机' if result['offline_cause'] == 2 else u'通讯异常')
            terminal_offline = self.db.get("SELECT remark FROM T_TERMINAL_INFO where id = %s", result['id']) 
            ws_detail.write(i, 7, safe_unicode(terminal_offline['remark']))

            start_line += 1

        wb.save(CUR_PATH)

        content = u'附件是 %s 的离线报表统计,请查收! 详情请看:%s ' % (cur_path,ConfHelper.ADMIN_CONF.url)
        subject = u'移动车卫士离线分析报告' + cur_path
        EmailHelper.send(self.to_emails, content, self.cc_emails, files=[CUR_PATH], subject=subject) 
        logging.info("[CELERY] statistic_offline_terminal finished, cur_path: %s", CUR_PATH)
Пример #9
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]
Пример #10
0
    def check_region_event(self, ori_location, region): 
        """Check enter or out region 

        workflow:
        get old_region_status accordinding to region and tid
        get old_region_time accordinding to region and tid
        check region_status according distance, then keep region_status in redis
        if not old_region_status:
            skip
        if old_region_time and location's gps_time <= old_region_time:
            skip
        check region event according to region_status and old_region_staus
        if region event:
            keep region_status, region_time in redis
        """
        if not (ori_location and region): 
            logging.info("[EVENTER] query data is invalid, ori_location: %s, region: %s, no check", 
                         ori_location, region)
            return None
        if not (ori_location['cLat'] and ori_location['cLon']):
            logging.info("[EVENTER] location is invalid, ori_location: %s, no check", 
                         ori_location)
            return None

        # BIG NOTE: python grammar, shallow copy will change origen data.
        location = copy.deepcopy(dict(ori_location))
        location = DotDict(location)

        old_region_status_key = get_region_status_key(location['dev_id'], region.region_id)
        old_region_status = self.redis.getvalue(old_region_status_key)

        old_region_time_key = get_region_time_key(location['dev_id'], region.region_id)
        old_region_time = self.redis.getvalue(old_region_time_key)

        if region.region_shape == UWEB.REGION_SHAPE.CIRCLE:
            # get distance beteween now location and the centre of the region 
            distance = lbmphelper.get_distance(region.region_longitude,
                                               region.region_latitude,
                                               location.cLon, 
                                               location.cLat)
            
            if distance >= region.region_radius:
                region_status = EVENTER.CATEGORY.REGION_OUT
                rname = EVENTER.RNAME.REGION_OUT
            else:
                region_status = EVENTER.CATEGORY.REGION_ENTER
                rname = EVENTER.RNAME.REGION_ENTER
        elif region.region_shape == UWEB.REGION_SHAPE.POLYGON:
            polygon = {'name':'',
                       'points':[]}
            points = region.points 
            point_lst = points.split(':') 
            for point in point_lst: 
               latlon = point.split(',') 
               dct = {'lat':float(latlon[0])/3600000, 
                      'lon':float(latlon[1])/3600000} 
               polygon['points'].append(dct)

            polygon['name'] = region.region_name

            if PtInPolygon(location, polygon):
                region_status = EVENTER.CATEGORY.REGION_ENTER
                rname = EVENTER.RNAME.REGION_ENTER
            else:
                region_status = EVENTER.CATEGORY.REGION_OUT
                rname = EVENTER.RNAME.REGION_OUT
        else: #NOTE: here should never occur. 
            logging.error("[EVENTER] unknow region_shape: %s, region: %s, skip it", 
                         region.region_shape, region)

        if old_region_time:
            if int(location['gps_time']) <= int(old_region_time):
                logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_region_time: %s, skip it", 
                             location['gps_time'], old_region_time)
                return location
        
        # keep region status 
        self.redis.setvalue(old_region_status_key, region_status)
        logging.info("rname:%s, old status:%s, current status:%s, tid:%s",
                     safe_unicode(region.region_name), old_region_status, region_status, location['dev_id'])    

        if not old_region_status:
            logging.info("[EVENTER] old_region_status: %s is invalid, skip it", 
                         old_region_status)
            # skip the first region event
            return location

        # check region event
        if region_status != old_region_status:
            self.redis.setvalue(old_region_status_key, region_status)
            self.redis.setvalue(old_region_time_key, location['gps_time'])
            # 2: complete the location
            location['category'] = region_status
            location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need
            location['rName'] = rname
            location['region'] = region 
            location['region_id'] = region.region_id

        return location
Пример #11
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)
Пример #12
0
    def check_single_event(self, ori_location, single): 
        """Check enter or out single 

        workflow:
        get old_single_status accordinding to single and tid
        get old_single_time accordinding to single and tid
        check single_status according distance, then keep single_status in redis
        if not old_single_status:
            skip
        if old_single_time and location's gps_time <= old_region_time:
            skip
        check single event according to single_status and old_single_staus
        if single event:
            keep single_status, single_time in redis
        """
        if not (ori_location and single): 
            logging.info("[EVENTER] query data is invalid, ori_location: %s, single: %s, do not check.", 
                         ori_location, single)
            return None
        if not (ori_location['cLat'] and ori_location['cLon']):
            logging.info("[EVENTER] location is invalid, ori_location: %s, do not check.", 
                         ori_location)
            return None

        # BIG NOTE: python grammar, shallow copy will change origen data.
        location = copy.deepcopy(dict(ori_location))
        location = DotDict(location)

        old_single_status_key = get_single_status_key(location['dev_id'], single.single_id)
        old_single_status = self.redis.getvalue(old_single_status_key)

        old_single_time_key = get_single_time_key(location['dev_id'], single.single_id)
        old_single_time = self.redis.getvalue(old_single_time_key)

        if single.single_shape == UWEB.SINGLE_SHAPE.CIRCLE:
            # get distance beteween now location and the centre of the region 
            distance = lbmphelper.get_distance(single.single_longitude,
                                               single.single_latitude,
                                               location.cLon, 
                                               location.cLat)
            
            if distance >= single.single_radius:
                single_status = EVENTER.CATEGORY.SINGLE_OUT
                rname = EVENTER.RNAME.SINGLE_OUT
            else:
                single_status = EVENTER.CATEGORY.SINGLE_ENTER
                rname = EVENTER.RNAME.SINGLE_ENTER
        elif single.single_shape == UWEB.SINGLE_SHAPE.POLYGON:
            polygon = {'name':'',
                       'points':[]}
            points = single.points 
            point_lst = points.split(':') 
            for point in point_lst: 
               latlon = point.split(',') 
               dct = {'lat':float(latlon[0])/3600000, 
                      'lon':float(latlon[1])/3600000} 
               polygon['points'].append(dct)

            polygon['name'] = single.single_name

            if PtInPolygon(location, polygon):
                single_status = EVENTER.CATEGORY.SINGLE_ENTER
                rname = EVENTER.RNAME.SINGLE_ENTER
            else:
                single_status = EVENTER.CATEGORY.SINGLE_OUT
                rname = EVENTER.RNAME.SINGLE_OUT
        else: #NOTE: here should never occur. 
            logging.error("[EVENTER] unknow single_shape: %s, single: %s, skip it", 
                         single.single_shape, single)

        #NOTE: skip the time
        if old_single_time:
            if int(location['gps_time']) <= int(old_single_time):
                logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_single_time: %s, skip it", 
                             location['gps_time'], old_single_time)
                return location
        
        logging.info('old_single_status_key: %s, single_status: %s', old_single_status_key, single_status)

        # keep region status 
        self.redis.setvalue(old_single_status_key, single_status)
        logging.info("rname:%s, old status:%s, current status:%s, tid:%s",
                     safe_unicode(single.single_name), old_single_status, single_status, location['dev_id'])    

        if not old_single_status:
            logging.info("[EVENTER] old_single_status: %s is invalid, skip it", 
                         old_single_status)
            # skip the first region event
            return location

        # check single event
        if single_status != old_single_status:
            self.redis.setvalue(old_single_status_key, single_status)
            self.redis.setvalue(old_single_time_key, location['gps_time'])

            # 2: complete the location
            location['category'] = single_status
            location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need
            location['rName'] = rname
            location['single'] = single 
            location['single_id'] = single.single_id

            # 3. keep it in db
            # out first, then enter
            if single_status == EVENTER.CATEGORY.SINGLE_ENTER:
                single_event = self.db.get("SELECT id as seid, tid, sid, start_time, end_time" 
                                           "  FROM T_SINGLE_EVENT"
                                           "  WHERE tid = %s "
                                           "  AND sid = %s"
                                           "  AND start_time !=0"
                                           "  AND end_time = 0 "
                                           "  ORDER BY id DESC LIMIT 1",
                                           location['dev_id'],
                                           location['single_id'])

                if not single_event:
                    pass
                else:
                    self.db.execute("UPDATE T_SINGLE_EVENT"
                                    "  SET end_time = %s"
                                    "  WHERE id = %s",
                                    location['gps_time'],
                                    single_event['seid'])
            elif single_status == EVENTER.CATEGORY.SINGLE_OUT:
                last_pvt_key = get_last_pvt_key(location['dev_id'])
                last_pvt = self.redis.getvalue(last_pvt_key)
                if last_pvt:
                    gps_time = last_pvt['gps_time']
                else:
                    gps_time = location['gps_time']
                self.db.execute("INSERT INTO T_SINGLE_EVENT(tid, sid, start_time)" 
                                "  VALUES(%s, %s, %s)",
                                location['dev_id'], 
                                location['single_id'],
                                gps_time)
                
        return location
Пример #13
0
    def post(self):
        """Retrive various event.
        """
        status = ErrorCode.SUCCESS
        try:
            data = DotDict(json_decode(self.request.body))

            tid = data.get('tid', None)

            tids = data.get('tids', None)
            tids = str_to_list(tids)

            if not tids:
                tids = [tid, ] if tid else []
            tids = [str(t) for t in tids]

            if not tid:
                tid = tids[0] if len(tids) > 0 else ''

            # check tid whether exist in request and update current_user
            self.check_tid(tid)
            logging.info("[UWEB] Event request: %s, uid: %s, tid: %s, tids: %s",
                         data, self.current_user.uid, self.current_user.tid, tids)
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            logging.exception("[UWEB] Invalid data format. body: %s, Exception: %s",
                              self.request.body, e.args)
            self.write_ret(status)
            return

        try:
            terminal = QueryHelper.get_available_terminal(self.current_user.tid, self.db)
            if not terminal:
                status = ErrorCode.LOGIN_AGAIN
                logging.error(
                    "[UWEB] The terminal with tid: %s does not exist, redirect to login.html", self.current_user.tid)
                self.write_ret(status)
                return

            page_size = int(data.get('pagesize', UWEB.LIMIT.PAGE_SIZE))
            category = data.get('category', None)
            categories = data.get('categories', None)
            page_number = int(data.pagenum)
            page_count = int(data.pagecnt)
            start_time = data.start_time
            end_time = data.end_time

            # NOTE: all catgories
            all_categories = [2,  # powerlow
                              3,  # illegalshake
                              4,  # illegalmove
                              5,  # sos
                              6,  # hearbeat lost
                              7,  # region enter
                              8,  # retion out
                              9,  # power off
                              10,  # stop
                              11,  # speed_limit
                              ]

            if category is not None:
                if int(category) == -1:
                    categories = all_categories
                else:
                    categories = [int(category), ]
            elif categories:
                if int(categories[0]) == -1:
                    categories = all_categories
                else:
                    categories = [int(c) for c in categories]

            # NOTE: for individual: the interval between start_time and end_time is one week;
            # for enterprise: no need to check time interval
            if self.current_user.cid != UWEB.DUMMY_CID:
                hide_lst = [5]  # enterprise: no sos
            else:  # individual: no stop
                hide_lst = [5, 10, 11]
                if (int(end_time) - int(start_time)) > UWEB.QUERY_INTERVAL:
                    self.write_ret(ErrorCode.QUERY_INTERVAL_EXCESS)
                    return

            # we need return the event count to GUI at first time query
            if page_count == -1:
                sql = ("SELECT COUNT(*) as count FROM V_EVENT"
                       "  WHERE tid IN %s " +
                       "  AND category  IN %s" +
                       "    AND (timestamp BETWEEN %s AND %s)")\
                    % (tuple(tids + DUMMY_IDS_STR), tuple(list(set(categories) - set(hide_lst)) + DUMMY_IDS), start_time, end_time)
                res = self.db.get(sql)
                event_count = res.count
                d, m = divmod(event_count, page_size)
                page_count = (d + 1) if m else d

            sql = ("SELECT tid, latitude, longitude, clatitude, clongitude,"
                   "  timestamp, name, type, speed, degree,"
                   "  category, pbat, terminal_type, fobid, rid, locate_error"
                   "  FROM V_EVENT"
                   "  WHERE tid IN %s"
                   "    AND (timestamp BETWEEN %s AND %s)"
                   "    AND category IN %s"
                   "  ORDER BY timestamp DESC"
                   "  LIMIT %s, %s") %\
                  (tuple(tids + DUMMY_IDS_STR), start_time, end_time,
                   tuple(list(set(categories) - set(hide_lst)) + DUMMY_IDS),  page_number * page_size, page_size)
            events = self.db.query(sql)

            alias_dict = {}
            for tid in tids:
                terminal_info_key = get_terminal_info_key(tid)
                terminal_info = self.redis.getvalue(terminal_info_key)
                alias_dict[tid] = terminal_info['alias'] if terminal_info[
                    'alias'] else terminal_info['mobile']

            # Adjust the fields in events.
            for event in events:
                event['alias'] = alias_dict[event['tid']]
                event['pbat'] = event['pbat'] if event[
                    'pbat'] is not None else 0
                event['fobid'] = event['fobid'] if event[
                    'fobid'] is not None else u''
                event['name'] = event['name'] if event[
                    'name'] is not None else u''
                event['degree'] = float(event['degree'])
                event['speed'] = float(event['speed'])
                event['comment'] = ''
                if event['category'] == EVENTER.CATEGORY.POWERLOW:
                    if event['terminal_type'] == '1':
                        if int(event['pbat']) == 100:
                            event['comment'] = ErrorCode.ERROR_MESSAGE[
                                ErrorCode.TRACKER_POWER_FULL]
                        elif int(event['pbat']) <= 5:
                            event['comment'] = ErrorCode.ERROR_MESSAGE[
                                ErrorCode.TRACKER_POWER_OFF]
                        else:
                            event['comment'] = (
                                ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_LOW]) % event['pbat']
                    else:
                        event['comment'] = ErrorCode.ERROR_MESSAGE[
                            ErrorCode.FOB_POWER_LOW] % event['fobid']

                if event['category'] in [EVENTER.CATEGORY.REGION_ENTER, EVENTER.CATEGORY.REGION_OUT]:
                    region = self.db.get("SELECT name AS region_name"
                                         "  FROM T_REGION"
                                         "  WHERE id = %s",
                                         event.rid)

                    region_name = safe_unicode(
                        region.region_name) if region else u''
                    event['comment'] = u'围栏名:' + region_name

            self.write_ret(status,
                           dict_=DotDict(events=events,
                                         pagecnt=page_count))
        except Exception as e:
            logging.exception("[UWEB] uid:%s, tid:%s get alarm info failed. Exception: %s",
                              self.current_user.uid, self.current_user.tid, e.args)
            status = ErrorCode.SERVER_BUSY
            self.write_ret(status)
Пример #14
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()
Пример #15
0
    def day_notify(self):
        logging.info("[CELERY] checkertask day_notify started.")
        try:
            #NOTE: avoid sms is sent when the server is restart.
            _date = datetime.datetime.fromtimestamp(int(time.time()))
            if _date.hour not in (9,10):
                return
                
            #NOTE: get all terminals which may be notified, record them into T_MILEAGE_NOTIFICATION.
            terminals = self.db.query("SELECT tid, day_notification, notify_count, left_days"
                                      "  FROM T_DAY_NOTIFICATION"
                                      "  WHERE day_notification != 0"
                                      "  AND notify_count < 3")
            for terminal in terminals:
                if int(time.time()) < terminal['day_notification']:
                    # it's not time to notify
                    continue

                terminal_info = QueryHelper.get_terminal_by_tid(terminal.tid, self.db)
                tid = terminal['tid']

                owner_mobile = terminal_info['owner_mobile']
                assist_mobile = terminal_info['assist_mobile']
                
                t = self.db.get("SELECT distance_current FROM T_TERMINAL_INFO WHERE tid = %s", terminal.tid)
                #distance_current = terminal_info['distance_current']
                distance_current = t['distance_current']
                mobile = terminal_info['mobile']

                notify_count = terminal['notify_count']
                left_days = terminal['left_days']
                day_notification= terminal['day_notification']

                if left_days == 1: # it should be notified this day                           
                    logging.info("[CELERY] Send day notification."
                                 "  tid: %s, mobile: %s, owner_mobile: %s, assist_mobile: %s,"
                                 "  day_notification: %s" 
                                 "  notify_count: %s, left_days: %s.", 
                                 tid, mobile, owner_mobile, assist_mobile, day_notification, 
                                 notify_count, left_days)
                    self.db.execute("UPDATE T_DAY_NOTIFICATION"
                                    "  SET notify_count = %s,"
                                    "      left_days = %s,"
                                    "      notify_time = %s"
                                    "  WHERE tid = %s",
                                    notify_count+1, 3, 
                                    int(time.time()), tid)
                    if owner_mobile:
                        sms = SMSCode.SMS_NOTIFY_DAY % (terminal_info['alias'])
                        SMSHelper.send(owner_mobile, sms)
                    if assist_mobile:
                        user = QueryHelper.get_user_by_mobile(owner_mobile, self.db)
                        name = safe_unicode(user['name'])
                        sms = SMSCode.SMS_NOTIFY_ASSIST_DAY % (mobile, owner_mobile, name)
                        SMSHelper.send(assist_mobile, sms)
                elif left_days in (2, 3): # do not notify, just postpone one day
                    logging.info("[CELERY] Do not send day notification this day,"
                                 "  just modify the left_days."
                                 "  tid: %s, mobile: %s, owner_mobile: %s, assist_mobile: %s,"
                                 "  day_notification: %s" 
                                 "  notify_count: %s, left_days: %s.", 
                                 tid, mobile, owner_mobile, assist_mobile, day_notification, 
                                 notify_count, left_days)
                    self.db.execute("UPDATE T_DAY_NOTIFICATION"
                                    "  SET left_days = %s"
                                    "  WHERE tid = %s",
                                    left_days-1,
                                    tid)
                else: #NOTE: It should never occur.
                    logging.info("[CELERY] Invalid left_days: %s, mobile: %s.", 
                                left_days, mobile)
                    
        except Exception as e:
            logging.exception("[CELERY] Day notification failed. Exception: %s.",
                              e.args)
Пример #16
0
    def post(self):
        """Get event info.
        """
        status = WXErrorCode.SUCCESS
        try:
            data = DotDict(json_decode(self.request.body))
            logging.info("[WEIXIN] event request body: %s", self.request.body)
            tid = data.tid
            openid = data.get('openid')
            start_time = data.start_time
            end_time = data.end_time
        except Exception as e:
            status = WXErrorCode.ILLEGAL_DATA_FORMAT
            logging.exception("[WEIXIN] Invalid data format. Exception: %s",
                              e.args)
            self.render('error.html', 
                        status=status,
                        message=WXErrorCode.ERROR_MESSAGE[status])
            return

        try:
            checksql = "SELECT  uid FROM T_USER WHERE openid = '%s'" % openid
            user = self.db.query(checksql)
            if not user:
                status = WXErrorCode.USER_BIND
                message = WXErrorCode.ERROR_MESSAGE[status]
                self.render('error.html',
                            status=status,
                            message=message)
                return

            sql = ("SELECT tid, latitude, longitude, clatitude, clongitude," 
                   "  timestamp, name, type, speed, degree,"
                   "  category, pbat, terminal_type, fobid, rid, locate_error"
                   "  FROM V_EVENT"
                   "  WHERE tid ='%s'"
                   "    AND (timestamp BETWEEN %s AND %s)"
                   "  ORDER BY timestamp DESC") %\
                (tid, start_time, end_time)

            #sql = ("SELECT tid, latitude, longitude, clatitude, clongitude," 
             #      "  timestamp, name, type, speed, degree,"
              #     "  category, pbat, terminal_type, fobid, rid, locate_error"
               #    "  FROM V_EVENT"
                #   "   where timestamp BETWEEN %s AND %s"
                 #  "  ORDER BY timestamp DESC limit 21 ") %\
               # (start_time, end_time)
            events = self.db.query(sql)
                
            alias_dict = {}
            terminal_info_key = get_terminal_info_key(tid)
            terminal_info = self.redis.getvalue(terminal_info_key)
            alias_dict[tid] = terminal_info['alias'] if terminal_info['alias'] else terminal_info['mobile']

            # change the type form decimal to float.
            for event in events:
                event['alias'] = '' # alias_dict[event['tid']] 
                event['pbat'] = event['pbat'] if event['pbat'] is not None else 0
                event['fobid'] = event['fobid'] if event['fobid'] is not None else u''
                event['name'] = event['name'] if event['name'] is not None else u''
                event['degree'] = float(event['degree'])
                event['speed'] = float(event['speed'])
                event['comment'] = ''
                if event['category'] == EVENTER.CATEGORY.POWERLOW:
                    if event['terminal_type'] == '1':
                        if int(event['pbat']) == 100:
                            event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_FULL] 
                        elif int(event['pbat']) <= 5:
                            event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_OFF] 
                        else:
                            event['comment'] = (ErrorCode.ERROR_MESSAGE[ErrorCode.TRACKER_POWER_LOW]) % event['pbat']
                    else:
                        event['comment'] = ErrorCode.ERROR_MESSAGE[ErrorCode.FOB_POWER_LOW] % event['fobid']

                if event['category'] in [EVENTER.CATEGORY.REGION_ENTER, EVENTER.CATEGORY.REGION_OUT]:
                    region = self.db.get("SELECT name AS region_name"
                                         "  FROM T_REGION"
                                         "  WHERE id = %s",
                                         event.rid)
                    
                    region_name = safe_unicode(region.region_name) if region else u''
                    event['comment'] = u'围栏名:'+ region_name
 
            r = events * 2 + events[0:6]
            self.write_ret(status,
                           dict_=DotDict(res=r))

            print "jjjjjj res:",r
        except Exception as e:
            logging.exception("[WEIXIN] search event failed POST(), Execption:%s",
                              e.args)
            status=WXErrorCode.FAILED
            message=WXErrorCode.ERROR_MESSAGE[status]
            self.render('error.html',
                        status=status,
                        message=message)