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()
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()
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()
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()
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
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()
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()
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)
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
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()