Пример #1
0
    def getResource(self, sid, rid, name):
        if cherrypy.session.get("permission", -1) not in [0, 1, 2]:
            raise cherrypy.HTTPError(401, "权限不足")

        sess = Session()
        try:
            record = sess.query(Record).filter(Record.st_id == sid,
                                               Record.id == rid).one()

            if name == "image1":
                url, _type = record.img_plate_path, "image/jpeg"
            elif name == "image2":
                url, _type = record.img_smoke_path, "image/jpeg"
            elif name == "video":
                url, _type = record.video_path, "video/mp4"
            else:
                raise NoResultFound()
            if not path.isfile(url):
                raise NoResultFound()
            return cherrypy.lib.static.serve_file(url, _type)
        except NoResultFound:
            raise cherrypy.HTTPError(404)
        except:
            server._warning("查询记录时发生错误", exc_info=True)
            raise cherrypy.HTTPError(500, "发生未知错误")
        finally:
            sess.close()
Пример #2
0
    def index(self, sid=None, rid=None):
        if sid is None:
            return True, server.config_manager.getConfigIdList()
        if not hasConfigId(sid):
            return False, NOT_EXISTS_ID_ERROR

        if rid is None:
            return self.getRecordInfo(sid, cherrypy.session["permission"])

        sess = Session()
        try:
            record: Record = sess.query(Record).filter(Record.st_id == sid,
                                                       Record.id == rid).one()

            return True, {
                "st_id":
                record.st_id,
                "st_name":
                record.st_name,
                "Ringelmann":
                record.Ringelmann,
                "plate":
                record.plate,
                "plate_color":
                record.plate_color,
                "plate_type":
                record.plate_type,
                "vehicle_type":
                record.car_type,
                "vehicle_color":
                record.car_color,
                "lane":
                record.car_lane,
                "timestamp":
                record.timestamp,
                "image1":
                "{}{}image1".format(cherrypy.request.script_name,
                                    cherrypy.request.path_info),
                "image2":
                "{}{}image2".format(cherrypy.request.script_name,
                                    cherrypy.request.path_info),
                "video":
                "{}{}video".format(cherrypy.request.script_name,
                                   cherrypy.request.path_info)
            }
        except NoResultFound:
            return False, "记录ID不存在"
        except:
            server._warning("查询记录时发生错误", exc_info=True)
            return False, "发生未知错误"
        finally:
            sess.close()
Пример #3
0
 def login(self):
     data = cherrypy.request.json
     sess = Session()
     try:
         perm = sess.query(User.permission).filter(
             User.username == data.get("user", ""),
             User.password == data.get("password", "")).one()[0]
         cherrypy.session["permission"] = perm
         return True, perm
     except NoResultFound:
         return False, "用户名或密码错误"
     except:
         server._warning("用户登录时发生错误", exc_info=True)
         return False, "发生未知错误"
     finally:
         sess.close()
Пример #4
0
    def upload(self, sid, rid):
        if not hasConfigId(sid):
            return False, NOT_EXISTS_ID_ERROR

        # 数据验证
        data = cherrypy.request.json
        if not (isinstance(data.get("Ringelmann", None), int)
                and 0 <= data["Ringelmann"] <= 5):
            return False, "林格曼黑度值必须在0~5之间"
        if data.get("plate_color", None) not in PLATE_COLOR:
            return False, "车牌颜色取值错误"
        if data.get("plate_type", None) not in PLATE_TYPE:
            return False, "车牌类型取值错误"
        if data.get("vehicle_type", None) not in VEHICLE_TYPE:
            return False, "车辆类型取值错误"
        if data.get("vehicle_color", None) not in VEHICLE_COLOR:
            return False, "车辆颜色取值错误"
        if isinstance(data.get("lane", None),
                      int) is False or data["lane"] < 1:
            return False, "车道号必须为大于0的整数"

        sess = Session()
        try:
            record: Record = sess.query(Record).filter(Record.st_id == sid,
                                                       Record.id == rid).one()
            # 修改记录数据
            record.Ringelmann = data["Ringelmann"]
            record.plate_color = data["plate_color"]
            record.plate_type = data["plate_type"]
            record.car_type = data["vehicle_type"]
            record.car_color = data["vehicle_color"]
            record.car_lane = data["lane"]
            record.plate = data.get("plate", None) or "无车牌"

            # 修改确认状态、上传状态
            record.status = True
            if record.upload_status == "0":
                record.upload_status = "1"
            sess.commit()
            return True, None
        except NoResultFound:
            return False, "记录ID不存在"
        except:
            sess.rollback()
            server._warning("查询记录时发生错误", exc_info=True)
            return False, "未知错误"
        finally:
            sess.close()
Пример #5
0
    def getRecordInfo(self, sid, perm) -> typing.List[typing.Dict]:
        upload_status = {"0": "未上传", "1": "等待上传", "2": "已上传"}

        sess = Session()
        result = []

        try:
            query = sess.query(Record.id, Record.status, Record.upload_status,
                               Record.timestamp).order_by(
                                   desc(Record.timestamp))
            if perm == 2:
                records = query.filter(
                    Record.st_id == sid,
                    or_(Record.status == False,
                        Record.upload_status != "0")).all()
            elif perm == 1:
                records = query.filter(Record.st_id == sid,
                                       Record.status == False).all()
            else:
                records = query.filter(Record.st_id == sid,
                                       Record.upload_status != "0").all()

            for _id, status, upload, timestamp in records:
                result.append({
                    "id":
                    _id,
                    "name":
                    datetime.fromtimestamp(
                        timestamp /
                        1000).strftime("%Y/%m/%d %H:%M:%S.%f")[:-3],
                    "status":
                    status,
                    "upload":
                    upload_status[upload]
                })
        except:
            server._warning("查询记录时发生错误", exc_info=True)
            return False, "发生未知错误"
        finally:
            sess.close()

        return True, result
Пример #6
0
    def status(self, sid, rid):
        if not hasConfigId(sid):
            return False, NOT_EXISTS_ID_ERROR

        sess = Session()
        try:
            record: Record = sess.query(Record).filter(Record.st_id == sid,
                                                       Record.id == rid).one()
            record.status = True
            sess.commit()
            return True, None
        except NoResultFound:
            return False, "记录ID不存在"
        except:
            sess.rollback()
            server._warning("查询记录时发生错误", exc_info=True)
            return False, "未知错误"
        finally:
            sess.close()
Пример #7
0
 def upload(self):
     """ 执行一次上传操作 """
     sess = Session()
     for info in self.upload_dict.values():
         try:
             records = sess.query(Record).filter(
                 Record.upload_status == "1",
                 Record.st_id.in_(info.stations)).all()
             for record in records:
                 if info.func(record):
                     record.upload_status = "2"
                     sess.commit()
                     self._info("[{}]上传成功".format(info.name))
                 else:
                     self._warning("[{}]上传失败".format(info.name),
                                   exc_info=True)
         except:
             sess.rollback()
             self._warning("[{}]上传失败".format(info.name), exc_info=True)
     sess.close()
Пример #8
0
    def cleanRecord(self, days1: int = 30, days2: int = 90):
        """ 清除指定天数以前的黑烟记录
        - days1 int[30]: 已确认未上传记录最长保留时间
        - days2 int[90]: 未确认记录最长保留时间
        """
        sess = Session()
        timestamp1 = int(
            (datetime.now() - timedelta(days=days1)).timestamp() * 1000)
        timestamp2 = int(
            (datetime.now() - timedelta(days=days2)).timestamp() * 1000)
        try:
            # 查询过期记录
            records = sess.query(Record.id, Record.save_dir).filter(
                or_(
                    and_(Record.timestamp < timestamp1, Record.status == True,
                         Record.upload_status == "0"),
                    and_(
                        Record.timestamp < timestamp2,
                        Record.status == False,
                    ))).all()
            # 尝试删除记录文件夹
            delete_list = []
            for _id, _dir in records:
                if path.isdir(_dir) is False:
                    delete_list.append(_id)
                else:
                    try:
                        shutil.rmtree(_dir)
                        delete_list.append(_id)
                    except:
                        pass

            # 删除记录
            count = 0
            if delete_list:
                count = sess.query(Record).filter(
                    Record.id.in_(delete_list)).delete(False)
                sess.commit()
            self._info("[CLEAN]共找到符合条件记录{}条, 删除{}条".format(
                len(records), count))
        except:
            sess.rollback()
            self._warning("[CLEAN]记录删除失败", exc_info=True)
Пример #9
0
def main(dir_name: str):
    f = "record.json"
    for dn in os.listdir(dir_name):
        records = []
        for p, _, fl in os.walk(path.join(dir_name, dn)):
            if f in fl:
                with open(path.join(p, f), encoding="utf-8") as fp:
                    data = json.load(fp)
                record = Record()
                record.timestamp = data["timestamp"]
                record.st_id = data["st_id"]
                record.st_name = data["st_name"]
                record.Ringelmann = data["Ringelmann"]
                record.RingelmannLimit = data["RingelmannLimit"]
                record.plate = data["plate"]
                record.plate_color = data["plate_color"]
                record.plate_type = "其他"
                record.car_color = data["car_color"]
                record.car_type = data["car_type"]
                record.car_lane = data["car_lane"]
                record.save_dir = path.abspath(p)
                record.status = path.isfile(path.join(p, "status"))
                if path.isfile(path.join(p, "2")):
                    record.upload_status = "2"
                elif path.isfile(path.join(p, "1")):
                    record.upload_status = "1"
                else:
                    record.upload_status = "0"
                records.append(record)

        print(dn, "total", len(records))
        if records:
            try:
                sess = Session()
                sess.add_all(records)
                sess.commit()
            except:
                import traceback
                traceback.print_exc()
                sess.rollback()
                raise
Пример #10
0
    def __saveRecord(self, track, frames):
        """ 保存黑烟记录 """
        savepath = path.join(
            self.__record_dir,
            datetime.fromtimestamp(
                track.timestamp).strftime("%Y%m%d%H%M%S.%f"))
        # 创建保存目录
        while True:
            if path.exists(savepath):
                # 检查记录是否已保存过
                record = Record.fromJSON(savepath)
                if record.id == track.id:
                    del frames
                    return
                savepath += "_"
            else:
                break
        os.makedirs(savepath, exist_ok=True)

        # 保存图片
        try:
            for i, img in enumerate([track.plate_image, track.smoke_image]):
                p = path.join(savepath, '{}.jpg'.format(i))
                cv2.imwrite(p, img)
        except:
            self.__log.error('保存记录图片时出现错误', exc_info=True)
            shutil.rmtree(savepath)
            return

        # 保存视频
        sub = None
        try:
            p = path.join(savepath, 'video.mp4')
            cmd = "ffmpeg -f rawvideo -pix_fmt bgr24 -an -s {width}*{height} -i - -r {fps} -b:v 4096k -bufsize 4096k -c:a avc -c:v h264 {file}".format(
                fps=self.__fps,
                file=p,
                width=self.__size[0],
                height=self.__size[1])
            sub = Popen(cmd,
                        stdin=PIPE,
                        stdout=PIPE,
                        stderr=STDOUT,
                        shell=True)
            while frames:
                sub.stdin.write(frames.pop(0))
            sub.stdin.close()
            sub.wait()

        except:
            self.__log.error('保存记录视频时出错', exc_info=True)
            if isinstance(sub, Popen):
                if sub.stdout.readable():
                    self.__log.error("stdout/stderr:{}".format(
                        sub.stdout.read()))
            shutil.rmtree(savepath)
            return
        finally:
            del frames

        # 转换格式 更新数据
        record = Record.fromTrackObject(track, self.__cfg.id, self.__cfg.name,
                                        self.__cfg.Ringelmann, savepath)

        # 保存记录
        sess = Session()
        try:
            sess.add(record)
            sess.commit()
            self.__log.info('记录保存成功')
        except:
            sess.rollback()
            self.__log.error('保存黑烟信息时出错', exc_info=True)
            shutil.rmtree(savepath)
        finally:
            sess.close()