Просмотр исходного кода

Merge branch 'develop' of gitadmin/tuoheng_airport_stream into release

pull/2/head
chenyukun 1 год назад
Родитель
Сommit
42920614fa
100 измененных файлов: 1151 добавлений и 116 удалений
  1. +115
    -116
      .gitignore
  2. +8
    -0
      .idea/.gitignore
  3. +6
    -0
      .idea/misc.xml
  4. +8
    -0
      .idea/modules.xml
  5. +9
    -0
      .idea/tuoheng_airport_stream.iml
  6. +6
    -0
      .idea/vcs.xml
  7. +39
    -0
      airportStream.py
  8. +30
    -0
      bean/Feedback.py
  9. +24
    -0
      bean/Result.py
  10. +20
    -0
      bean/Stream.py
  11. +0
    -0
      bean/__init__.py
  12. Двоичные данные
      bean/__pycache__/Feedback.cpython-38.pyc
  13. Двоичные данные
      bean/__pycache__/Result.cpython-38.pyc
  14. Двоичные данные
      bean/__pycache__/Stream.cpython-38.pyc
  15. Двоичные данные
      bean/__pycache__/__init__.cpython-38.pyc
  16. +17
    -0
      common/Constant.py
  17. +0
    -0
      common/__init__.py
  18. Двоичные данные
      common/__pycache__/Constant.cpython-38.pyc
  19. Двоичные данные
      common/__pycache__/__init__.cpython-38.pyc
  20. +0
    -0
      concurrency/__init__.py
  21. Двоичные данные
      concurrency/__pycache__/__init__.cpython-38.pyc
  22. +62
    -0
      concurrency/http/HttpFeedbackThread.py
  23. +124
    -0
      concurrency/http/HttpPushStreamProcess.py
  24. +93
    -0
      concurrency/http/HttpServiceImpl.py
  25. +0
    -0
      concurrency/http/__init__.py
  26. Двоичные данные
      concurrency/http/__pycache__/HttpFeedbackThread.cpython-38.pyc
  27. Двоичные данные
      concurrency/http/__pycache__/HttpPushStreamProcess.cpython-38.pyc
  28. Двоичные данные
      concurrency/http/__pycache__/HttpServiceImpl.cpython-38.pyc
  29. Двоичные данные
      concurrency/http/__pycache__/__init__.cpython-38.pyc
  30. +35
    -0
      concurrency/mqtt/MqttFeedbackThread.py
  31. +204
    -0
      concurrency/mqtt/MqttPushStreamProcess.py
  32. +0
    -0
      concurrency/mqtt/__init__.py
  33. Двоичные данные
      concurrency/mqtt/__pycache__/MqttFeedbackThread.cpython-38.pyc
  34. Двоичные данные
      concurrency/mqtt/__pycache__/MqttPushStreamProcess.cpython-38.pyc
  35. Двоичные данные
      concurrency/mqtt/__pycache__/__init__.cpython-38.pyc
  36. +20
    -0
      config/logger.yml
  37. +20
    -0
      config/mqtt.yml
  38. +11
    -0
      config/service.yml
  39. +66
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/AUTHORS
  40. +1
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/INSTALLER
  41. +15
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/LICENSE
  42. +164
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/METADATA
  43. +48
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/RECORD
  44. +0
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/REQUESTED
  45. +5
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/WHEEL
  46. +1
    -0
      dist/airportStream/Cerberus-1.3.4.dist-info/top_level.txt
  47. Двоичные данные
      dist/airportStream/MSVCP140.dll
  48. Двоичные данные
      dist/airportStream/VCRUNTIME140.dll
  49. Двоичные данные
      dist/airportStream/VCRUNTIME140_1.dll
  50. Двоичные данные
      dist/airportStream/_asyncio.pyd
  51. Двоичные данные
      dist/airportStream/_bz2.pyd
  52. Двоичные данные
      dist/airportStream/_cffi_backend.cp38-win_amd64.pyd
  53. Двоичные данные
      dist/airportStream/_ctypes.pyd
  54. Двоичные данные
      dist/airportStream/_decimal.pyd
  55. Двоичные данные
      dist/airportStream/_hashlib.pyd
  56. Двоичные данные
      dist/airportStream/_lzma.pyd
  57. Двоичные данные
      dist/airportStream/_multiprocessing.pyd
  58. Двоичные данные
      dist/airportStream/_overlapped.pyd
  59. Двоичные данные
      dist/airportStream/_queue.pyd
  60. Двоичные данные
      dist/airportStream/_ruamel_yaml.cp38-win_amd64.pyd
  61. Двоичные данные
      dist/airportStream/_socket.pyd
  62. Двоичные данные
      dist/airportStream/_ssl.pyd
  63. Двоичные данные
      dist/airportStream/airportStream.exe
  64. Двоичные данные
      dist/airportStream/api-ms-win-core-console-l1-1-0.dll
  65. Двоичные данные
      dist/airportStream/api-ms-win-core-datetime-l1-1-0.dll
  66. Двоичные данные
      dist/airportStream/api-ms-win-core-debug-l1-1-0.dll
  67. Двоичные данные
      dist/airportStream/api-ms-win-core-errorhandling-l1-1-0.dll
  68. Двоичные данные
      dist/airportStream/api-ms-win-core-file-l1-1-0.dll
  69. Двоичные данные
      dist/airportStream/api-ms-win-core-file-l1-2-0.dll
  70. Двоичные данные
      dist/airportStream/api-ms-win-core-file-l2-1-0.dll
  71. Двоичные данные
      dist/airportStream/api-ms-win-core-handle-l1-1-0.dll
  72. Двоичные данные
      dist/airportStream/api-ms-win-core-heap-l1-1-0.dll
  73. Двоичные данные
      dist/airportStream/api-ms-win-core-interlocked-l1-1-0.dll
  74. Двоичные данные
      dist/airportStream/api-ms-win-core-libraryloader-l1-1-0.dll
  75. Двоичные данные
      dist/airportStream/api-ms-win-core-localization-l1-2-0.dll
  76. Двоичные данные
      dist/airportStream/api-ms-win-core-memory-l1-1-0.dll
  77. Двоичные данные
      dist/airportStream/api-ms-win-core-namedpipe-l1-1-0.dll
  78. Двоичные данные
      dist/airportStream/api-ms-win-core-processenvironment-l1-1-0.dll
  79. Двоичные данные
      dist/airportStream/api-ms-win-core-processthreads-l1-1-0.dll
  80. Двоичные данные
      dist/airportStream/api-ms-win-core-processthreads-l1-1-1.dll
  81. Двоичные данные
      dist/airportStream/api-ms-win-core-profile-l1-1-0.dll
  82. Двоичные данные
      dist/airportStream/api-ms-win-core-rtlsupport-l1-1-0.dll
  83. Двоичные данные
      dist/airportStream/api-ms-win-core-string-l1-1-0.dll
  84. Двоичные данные
      dist/airportStream/api-ms-win-core-synch-l1-1-0.dll
  85. Двоичные данные
      dist/airportStream/api-ms-win-core-synch-l1-2-0.dll
  86. Двоичные данные
      dist/airportStream/api-ms-win-core-sysinfo-l1-1-0.dll
  87. Двоичные данные
      dist/airportStream/api-ms-win-core-timezone-l1-1-0.dll
  88. Двоичные данные
      dist/airportStream/api-ms-win-core-util-l1-1-0.dll
  89. Двоичные данные
      dist/airportStream/api-ms-win-crt-conio-l1-1-0.dll
  90. Двоичные данные
      dist/airportStream/api-ms-win-crt-convert-l1-1-0.dll
  91. Двоичные данные
      dist/airportStream/api-ms-win-crt-environment-l1-1-0.dll
  92. Двоичные данные
      dist/airportStream/api-ms-win-crt-filesystem-l1-1-0.dll
  93. Двоичные данные
      dist/airportStream/api-ms-win-crt-heap-l1-1-0.dll
  94. Двоичные данные
      dist/airportStream/api-ms-win-crt-locale-l1-1-0.dll
  95. Двоичные данные
      dist/airportStream/api-ms-win-crt-math-l1-1-0.dll
  96. Двоичные данные
      dist/airportStream/api-ms-win-crt-process-l1-1-0.dll
  97. Двоичные данные
      dist/airportStream/api-ms-win-crt-runtime-l1-1-0.dll
  98. Двоичные данные
      dist/airportStream/api-ms-win-crt-stdio-l1-1-0.dll
  99. Двоичные данные
      dist/airportStream/api-ms-win-crt-string-l1-1-0.dll
  100. +0
    -0
      dist/airportStream/api-ms-win-crt-time-l1-1-0.dll

+ 115
- 116
.gitignore Просмотреть файл

@@ -1,116 +1,115 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

## ---> Python
## Byte-compiled / optimized / DLL files
#__pycache__/
#*.py[cod]
#*$py.class
#
## C extensions
#*.so
#
## Distribution / packaging
#.Python
#build/
#develop-eggs/
#downloads/
#eggs/
#.eggs/
#lib/
#lib64/
#parts/
#sdist/
#var/
#wheels/
#*.egg-info/
#.installed.cfg
#*.egg
#MANIFEST
#
## PyInstaller
## Usually these files are written by a python script from a template
## before PyInstaller builds the exe, so as to inject date/other infos into it.
#*.manifest
#*.spec
#
## Installer logs
#pip-log.txt
#pip-delete-this-directory.txt
#
## Unit test / coverage reports
#htmlcov/
#.tox/
#.nox/
#.coverage
#.coverage.*
#.cache
#nosetests.xml
#coverage.xml
#*.cover
#.hypothesis/
#.pytest_cache/
#
## Translations
#*.mo
#*.pot
#
## Django stuff:
#*.log
#local_settings.py
#db.sqlite3
#
## Flask stuff:
#instance/
#.webassets-cache
#
## Scrapy stuff:
#.scrapy
#
## Sphinx documentation
#docs/_build/
#
## PyBuilder
#target/
#
## Jupyter Notebook
#.ipynb_checkpoints
#
## IPython
#profile_default/
#ipython_config.py
#
## pyenv
#.python-version
#
## celery beat schedule file
#celerybeat-schedule
#
## SageMath parsed files
#*.sage.py
#
## Environments
#.env
#.venv
#env/
#venv/
#ENV/
#env.bak/
#venv.bak/
#
## Spyder project settings
#.spyderproject
#.spyproject
#
## Rope project settings
#.ropeproject
#
## mkdocs documentation
#/site
#
## mypy
#.mypy_cache/
#.dmypy.json
#dmypy.json
#
## Pyre type checker
#.pyre/
#

+ 8
- 0
.idea/.gitignore Просмотреть файл

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

+ 6
- 0
.idea/misc.xml Просмотреть файл

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" project-jdk-name="Python 3.8 (test)" project-jdk-type="Python SDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

+ 8
- 0
.idea/modules.xml Просмотреть файл

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tuoheng_airport_stream.iml" filepath="$PROJECT_DIR$/.idea/tuoheng_airport_stream.iml" />
</modules>
</component>
</project>

+ 9
- 0
.idea/tuoheng_airport_stream.iml Просмотреть файл

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 6
- 0
.idea/vcs.xml Просмотреть файл

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

+ 39
- 0
airportStream.py Просмотреть файл

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from multiprocessing import freeze_support
from os.path import dirname, realpath, join
from loguru import logger

from service.MqttDisService import MqttDispatcherService
from service.HttpDisService import HttpDispatcherService
from util.LogUtils import init_log
from util.RWUtils import getConfigs

'''
主程序入口
'''

if __name__ == '__main__':
freeze_support()
base_dir = dirname(realpath(__file__))
init_log(base_dir)
logger.info("(♥◠‿◠)ノ゙ 【机场推流服务】开始启动 ლ(´ڡ`ლ)゙")
print("(♥◠‿◠)ノ゙ 【机场推流服务】开始启动 ლ(´ڡ`ლ)゙")
print("############################################################")
print("配置文件路径: ", join(base_dir, "config"))
print("服务配置文件: service.yml")
print("mqtt配置文件: mqtt.yml")
print("日志配置文件: logger.yml")
print("日志文件路径: ", join(base_dir, "logs"))
print("############################################################")
# mqtt交互
service_config = getConfigs(base_dir, "config/service.yml")
service_config['base_dir'] = base_dir
if 1 == service_config['docking_method']:
print("当前使用的交互模式是mqtt交互!!")
print("############################################################")
MqttDispatcherService(service_config)
elif 2 == service_config['docking_method']:
print("当前使用的交互模式是接口交互!!")
print("############################################################")
HttpDispatcherService(service_config)


+ 30
- 0
bean/Feedback.py Просмотреть файл

@@ -0,0 +1,30 @@
# -*-coding:utf-8 -*-
from enums.StatusEnum import StatusType
from util.QueUtil import put_queue
from util.TimeUtils import now_date_to_str


def push_result(fb_queue, errorCode="", errorMsg="", status=StatusType.RUNNING.value[0]):
put_queue(fb_queue, ('stream',
{
"errorCode": errorCode,
"errorMsg": errorMsg,
"status": status,
"currentTime": now_date_to_str()
}),
timeout=2)


def push_http_result(fb_queue, callback_url=None, errorCode="", errorMsg="", status=StatusType.RUNNING.value[0]):
if callback_url is not None:
put_queue(fb_queue, ('stream',
{
"callback_url": callback_url,
"data": {
"errorCode": errorCode,
"errorMsg": errorMsg,
"status": status,
"currentTime": now_date_to_str()
}
}),
timeout=2)

+ 24
- 0
bean/Result.py Просмотреть файл

@@ -0,0 +1,24 @@
# -*-coding:utf-8 -*-
from pydantic import BaseModel


class JsonResult(BaseModel):
code: int
msg: str
data: None

@staticmethod
def success(code=0, msg="操作成功!", data=None):
return {
"code": code,
"msg": msg,
"data": data
}

@staticmethod
def error(code=-1, msg="操作失败!", data=None):
return {
"code": code,
"msg": msg,
"data": data
}

+ 20
- 0
bean/Stream.py Просмотреть файл

@@ -0,0 +1,20 @@
# -*-coding:utf-8 -*-
from typing import Union

from pydantic import BaseModel, Field, HttpUrl
from fastapi._compat import Required


class PushStreamRequest(BaseModel):
pullUrl: Union[str, None] = Field(default=None, title="拉流地址",
pattern="(^(https|http|rtsp|rtmp|artc|webrtc|ws)://[\\w\\d\\.\\-/:_?=&!~*'()+$@,;\"%\\[\\]]+$)?")
pushUrl: Union[str, None] = Field(default=None, title="推流地址",
pattern="(^(https|http|rtsp|rtmp|artc|webrtc|ws)://[\\w\\d\\.\\-/:_?=&!~*'()+$@,;\"%\\[\\]]+$)?")
callbackUrl: HttpUrl = Field(default=Required, title="回调地址")


class CallbackRequest(BaseModel):
errorCode: Union[str, None]
errorMsg: Union[str, None]
status: Union[int, None]
currentTime: Union[str, None]

+ 0
- 0
bean/__init__.py Просмотреть файл


Двоичные данные
bean/__pycache__/Feedback.cpython-38.pyc Просмотреть файл


Двоичные данные
bean/__pycache__/Result.cpython-38.pyc Просмотреть файл


Двоичные данные
bean/__pycache__/Stream.cpython-38.pyc Просмотреть файл


Двоичные данные
bean/__pycache__/__init__.cpython-38.pyc Просмотреть файл


+ 17
- 0
common/Constant.py Просмотреть файл

@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from multiprocessing import Queue

SHARE_QUEUE = Queue()


def get_share_queue():
return SHARE_QUEUE


TASK_RECORD = {
"stream": None
}


def get_task_record():
return TASK_RECORD

+ 0
- 0
common/__init__.py Просмотреть файл


Двоичные данные
common/__pycache__/Constant.cpython-38.pyc Просмотреть файл


Двоичные данные
common/__pycache__/__init__.cpython-38.pyc Просмотреть файл


+ 0
- 0
concurrency/__init__.py Просмотреть файл


Двоичные данные
concurrency/__pycache__/__init__.cpython-38.pyc Просмотреть файл


+ 62
- 0
concurrency/http/HttpFeedbackThread.py Просмотреть файл

@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
import time
from json import loads
from threading import Thread
from traceback import format_exc

from loguru import logger

from util.QueUtil import get_block_queue
from util.RequestUtil import HttpRequests


class HttpFeedbackThread(Thread):
__slots__ = '__fb_queue'

def __init__(self, fb_queue):
super().__init__()
self.__fb_queue = fb_queue

def run(self):
logger.info("启动反馈线程")
fb_queue = self.__fb_queue
request = HttpRequests()
try:
headers = {'content-type': "application/json"}
while True:
try:
fb = get_block_queue(fb_queue)
if fb is not None and len(fb) > 0:
if fb[0] == "stream":
stream_req(request, fb[1], headers)
del fb
else:
time.sleep(1)
except Exception:
logger.error("反馈异常:{}", format_exc())
if request:
request.close_session()
request = HttpRequests()
finally:
request.close_session()
logger.info("反馈线程执行完成")


def stream_req(request, stream, headers):
logger.info("开始发送推流回调请求, 回调地址: {}", stream['callback_url'])
logger.info("开始发送推流回调请求, 回调请求体: {}", stream['data'])
try:
response = request.send_request('POST', stream['callback_url'], data=stream['data'],
headers=headers, timeout=3)
if response.status_code != 200:
logger.error("推流回调请求失败! 状态码: {}, {}", response.status_code, response.__dict__)
else:
content = response.content.decode('utf-8')
if content is not None and len(content) > 0:
content = loads(content)
code = content.get('code')
if code is not None and code != 0:
logger.error("推流回调请求失败! 失败描述: {}", content.get('msg'))
except Exception:
logger.error("回调请求失败, 请求体: {}, 回调地址: {}, 异常信息: {}", stream['data'], stream['callback_url'],
format_exc())

+ 124
- 0
concurrency/http/HttpPushStreamProcess.py Просмотреть файл

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
import time
from multiprocessing import Process, Queue
from threading import Thread
from traceback import format_exc

from loguru import logger

from bean.Feedback import push_http_result
from enums.ExceptionEnum import StreamStrExceptionType
from enums.StatusEnum import StatusType
from exception.CustomerException import ServiceException
from util.LogUtils import init_log
from util.PushStreamUtils import PushStreamUtil
from util.QueUtil import put_queue, get_no_block_queue


class PushStreamProcess(Process):
__slots__ = ('__fbQueue', '__event', '__service_config', '__push_stream_tool', '__callback_url')

def __init__(self, fb_queue, service_config, callback_url, pull_url, push_url):
super().__init__()
self.__fb_queue = fb_queue
self.__event = Queue()
self.__service_config = service_config
self.__callback_url = callback_url
self.__push_stream_tool = PushStreamUtil(service_config["stream"]["pullUrl"],
service_config["stream"]["pushUrl"])
self.__push_stream_tool.set_url(pull_url, push_url)

def send_event(self, result):
put_queue(self.__event, result, timeout=2, is_throw_ex=True)

def push_stream(self, push_queue, push_stream_tool):
logger.info("开始启动推流线程!")
while True:
try:
push_stream_tool.start_push_stream()
out, err = push_stream_tool.push_stream_sp.communicate()
if push_stream_tool.status:
logger.warning("推流异常,请检测拉流地址和推流地址是否正常!")
if push_stream_tool.push_stream_sp.returncode != 0:
logger.error("推流异常:{}", err.decode('utf-8'))
put_queue(push_queue, (2, StatusType.RETRYING.value[0]), timeout=2, is_throw_ex=True)
push_stream_tool.close_push_stream_p()
time.sleep(3)
if not push_stream_tool.status:
push_stream_tool.close_push_stream_p()
put_queue(push_queue, (0,), timeout=2, is_throw_ex=True)
break
except ServiceException as s:
logger.error("{}", s.msg)
push_stream_tool.close_push_stream_p()
# push_stream_tool.status = False
put_queue(push_queue, (1, s), timeout=2, is_throw_ex=True)
break
except Exception as e:
logger.error("异常:{}", format_exc())
push_stream_tool.close_push_stream_p()
# push_stream_tool.status = False
put_queue(push_queue, (1, e), timeout=2, is_throw_ex=True)
break
logger.info("推流线程运行结束!")

def run(self):
fb_queue, event_queue, callback_url = self.__fb_queue, self.__event, self.__callback_url
service_config = self.__service_config
hb_status = StatusType.WAITTING.value[0]
push_stream_tool = self.__push_stream_tool
# 初始化日志
init_log(service_config["base_dir"])
logger.info("开始启动推流进程")
push_queue = Queue()
push = Thread(target=self.push_stream, args=(push_queue, push_stream_tool))
push.setDaemon(True)
push.start()
count, start_time, ex = 0, time.time(), None
try:
while True:
if push_stream_tool.status and not push.is_alive():
logger.error("检测到推流线程异常停止!")
raise Exception("检测到推流线程异常停止!")
ph_result = get_no_block_queue(push_queue)
event_result = get_no_block_queue(event_queue)
if event_result is not None:
command = event_result.get("command")
if "stop" == command:
hb_status = StatusType.STOPPING.value[0]
push_stream_tool.status = False
push_stream_tool.close_push_stream_p()
if ph_result is not None and ph_result[0] == 0:
logger.info("推流任务停止中")
push.join(timeout=60)
push_http_result(fb_queue, callback_url, status=StatusType.SUCCESS.value[0])
break
if ph_result is not None and ph_result[0] == 1:
logger.info("推流任务异常停止中")
push.join(timeout=60)
raise ph_result[1]
if ph_result is not None and ph_result[0] == 2:
if StatusType.RETRYING.value[0] == ph_result[1]:
hb_status = StatusType.RETRYING.value[0]
start_time = time.time()
if time.time() - start_time > 10:
hb_status = StatusType.RUNNING.value[0]
count += 1
if count % 15 == 0:
push_http_result(fb_queue, callback_url, status=hb_status)
count = 0
time.sleep(1)
except ServiceException as s:
logger.error("推流异常, code: {}, msg: {}", s.code, s.msg)
ex = s.code, s.msg
except Exception:
logger.error("推流异常:{}", format_exc())
ex = StreamStrExceptionType.SERVICE_INNER_EXCEPTION.value[0], StreamStrExceptionType.SERVICE_INNER_EXCEPTION.value[1]
finally:
push_stream_tool.status = False
push_stream_tool.close_push_stream_p()
push.join(timeout=60)
if ex:
code, msg = ex
push_http_result(fb_queue, callback_url, code, msg, status=StatusType.FAILED.value[0])
logger.info("推流检测线程执行完成")

+ 93
- 0
concurrency/http/HttpServiceImpl.py Просмотреть файл

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
import sys
from multiprocessing import Queue
from threading import Thread
from time import sleep
from traceback import format_exc

from loguru import logger

from bean.Feedback import push_http_result
from common.Constant import get_task_record, get_share_queue
from concurrency.http.HttpFeedbackThread import HttpFeedbackThread
from concurrency.http.HttpPushStreamProcess import PushStreamProcess
from enums.ExceptionEnum import StreamStrExceptionType
from enums.StatusEnum import StatusType
from exception.CustomerException import ServiceException
from util.QueUtil import get_no_block_queue


class HttpServiceImpl:
__slots__ = ()

def __init__(self, service_config):
service_thread = Thread(target=self.start_service, args=(service_config,))
service_thread.setDaemon(True)
service_thread.start()

@staticmethod
def start_service(service_config):
fb_queue = Queue()
task, msg_queue = get_task_record(), get_share_queue()
handle_method = {
"stream": lambda x, y, z, h: handle_stream(x, y, z, h)
}
feedbackThread = None
while True:
try:
if task["stream"] is not None and not task["stream"].is_alive():
task["stream"] = None
feedbackThread = start_feedback_thread(feedbackThread, fb_queue)
message = get_no_block_queue(msg_queue)
if message is not None and isinstance(message, tuple) and len(message) == 2:
if handle_method.get(message[0]) is not None:
handle_method[message[0]](message[1], service_config, task, fb_queue)
else:
sleep(1)
except Exception:
logger.error("服务异常: {}", format_exc())


def handle_stream(msg, service_config, task, fb_queue):
try:
command = msg["command"]
if 'start' == command:
if task["stream"] is not None:
logger.error("推流任务已存在!!!")
push_http_result(fb_queue, msg["callback_url"],
StreamStrExceptionType.PUSH_STREAM_TASK_IS_AREADLY.value[0],
StreamStrExceptionType.PUSH_STREAM_TASK_IS_AREADLY.value[1],
StatusType.FAILED.value[0])
return
push_http_result(fb_queue, msg["callback_url"], status=StatusType.WAITTING.value[0])
pp = PushStreamProcess(fb_queue, service_config, msg["callback_url"], msg["pull_url"], msg["push_url"])
pp.start()
task["stream"] = pp
elif 'stop' == command:
if task["stream"] is None:
logger.error("推流任务不存在, 任务无法停止!")
return
task["stream"].send_event({"command": "stop"})
except ServiceException as s:
logger.error("消息处理异常: {}", s.msg)
push_http_result(fb_queue, msg["callback_url"], s.code, s.msg, StatusType.FAILED.value[0])
except Exception:
logger.error("消息处理异常: {}", format_exc())
push_http_result(fb_queue, msg["callback_url"],
StreamStrExceptionType.SERVICE_INNER_EXCEPTION.value[0],
StreamStrExceptionType.SERVICE_INNER_EXCEPTION.value[1],
StatusType.FAILED.value[0])
finally:
del msg


def start_feedback_thread(feedbackThread, fb_queue):
if feedbackThread is None:
feedbackThread = HttpFeedbackThread(fb_queue)
feedbackThread.setDaemon(True)
feedbackThread.start()
else:
if not feedbackThread.is_alive():
logger.error("反馈线程异常停止! 开始终止程序!")
sys.exit()
return feedbackThread

+ 0
- 0
concurrency/http/__init__.py Просмотреть файл


Двоичные данные
concurrency/http/__pycache__/HttpFeedbackThread.cpython-38.pyc Просмотреть файл


Двоичные данные
concurrency/http/__pycache__/HttpPushStreamProcess.cpython-38.pyc Просмотреть файл


Двоичные данные
concurrency/http/__pycache__/HttpServiceImpl.cpython-38.pyc Просмотреть файл


Двоичные данные
concurrency/http/__pycache__/__init__.cpython-38.pyc Просмотреть файл


+ 35
- 0
concurrency/mqtt/MqttFeedbackThread.py Просмотреть файл

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
import time
from threading import Thread
from traceback import format_exc

from loguru import logger

from util.QueUtil import get_block_queue

'''
问题反馈线程
'''


class FeedbackThread(Thread):
__slots__ = ('__fb_queue', '__mq')

def __init__(self, fb_queue, mq):
super().__init__()
self.__fb_queue = fb_queue
self.__mq = mq

def run(self):
logger.info("启动反馈线程")
fb_queue, mq = self.__fb_queue, self.__mq
while True:
try:
fb = get_block_queue(fb_queue)
if fb is not None and len(fb) > 0:
mq.publish(fb)
else:
time.sleep(1)
except Exception:
logger.error("反馈异常:{}", format_exc())
logger.info("反馈线程执行完成")

+ 204
- 0
concurrency/mqtt/MqttPushStreamProcess.py Просмотреть файл

@@ -0,0 +1,204 @@
# -*- coding: utf-8 -*-
import time
from multiprocessing import Queue, Process
from threading import Thread
from traceback import format_exc

from loguru import logger

from bean.Feedback import push_result
from enums.ExceptionEnum import ExceptionType
from enums.StatusEnum import StatusType
from exception.CustomerException import ServiceException
from util.LogUtils import init_log
from util.PushStreamUtils import PushStreamUtil
from util.QueUtil import put_queue, get_no_block_queue


class PushStreamProcess(Process):
__slots__ = ('__fb_queue', '__service_config', '__event', '__pullUrl', '__pushUrl')

def __init__(self, fb_queue, service_config, pullUrl, pushUrl):
super().__init__()
self.__fb_queue = fb_queue
self.__service_config = service_config
self.__event = Queue()
self.__pullUrl = pullUrl
self.__pushUrl = pushUrl
push_result(fb_queue, status=StatusType.WAITTING.value[0])

def send_event(self, result):
put_queue(self.__event, result, timeout=2, is_throw_ex=True)

@staticmethod
def push_stream(push_queue, push_stream_tool):
logger.info("开始启动推流线程!")
while True:
try:
push_stream_tool.start_push_stream()
out, err = push_stream_tool.push_stream_sp.communicate()
if push_stream_tool.status:
logger.warning("推流异常,请检测拉流地址和推流地址是否正常!")
if push_stream_tool.push_stream_sp.returncode != 0:
logger.error("推流异常:{}", err.decode("utf-8"))
put_queue(push_queue, (2, StatusType.RETRYING.value[0]), timeout=2, is_throw_ex=True)
push_stream_tool.close_push_stream_p()
time.sleep(1)
if not push_stream_tool.status:
push_stream_tool.close_push_stream_p()
put_queue(push_queue, (0,), timeout=2, is_throw_ex=True)
break
except ServiceException as s:
logger.error("异常: {}", s.msg)
push_stream_tool.close_push_stream_p()
# push_stream_tool.status = False
put_queue(push_queue, (1, s), timeout=2, is_throw_ex=True)
break
except Exception as e:
logger.error("异常: {}", format_exc())
push_stream_tool.close_push_stream_p()
# push_stream_tool.status = False
put_queue(push_queue, (1, e), timeout=2, is_throw_ex=True)
break
logger.info("推流线程运行结束!")

def run(self):
service_config, pullUrl, pushUrl = self.__service_config, self.__pullUrl, self.__pushUrl
fb_queue, event_queue, push_queue = self.__fb_queue, self.__event, Queue()
hb_status = StatusType.WAITTING.value[0]
push_stream_tool = PushStreamUtil(service_config["stream"]["pullUrl"], service_config["stream"]["pushUrl"])
push_stream_tool.set_url(pullUrl, pushUrl)
push = None
count, start_time, ex = 0, time.time(), None
try:
init_log(service_config["base_dir"])
logger.info("开始启动推流进程!")
push = Thread(target=self.push_stream, args=(push_queue, push_stream_tool))
push.setDaemon(True)
push.start()
while True:
if push_stream_tool.status and not push.is_alive():
logger.error("检测到推流线程异常停止!")
raise Exception("检测到推流线程异常停止!")
ph_result = get_no_block_queue(push_queue)
event_result = get_no_block_queue(event_queue)
if event_result is not None:
command = event_result.get("command")
if "stop" == command:
hb_status = StatusType.STOPPING.value[0]
push_stream_tool.status = False
push_stream_tool.close_push_stream_p()
if ph_result is not None and ph_result[0] == 0:
logger.info("推流任务停止中")
push.join(timeout=60)
push_result(fb_queue, status=StatusType.SUCCESS.value[0])
break
if ph_result is not None and ph_result[0] == 1:
logger.info("推流任务异常停止中")
push.join(timeout=60)
raise ph_result[1]
if ph_result is not None and ph_result[0] == 2:
if StatusType.RETRYING.value[0] == ph_result[1]:
hb_status = StatusType.RETRYING.value[0]
start_time = time.time()
if time.time() - start_time > 20:
hb_status = StatusType.RUNNING.value[0]
count += 1
if count % 15 == 0:
push_result(fb_queue, status=hb_status)
count = 0
time.sleep(1)
except ServiceException as s:
logger.error("推流异常, code: {}, msg: {}", s.code, s.msg)
ex = s.code, s.msg
except Exception:
logger.error("推流异常:{}", format_exc())
ex = ExceptionType.SERVICE_INNER_EXCEPTION.value[0], ExceptionType.SERVICE_INNER_EXCEPTION.value[1]
finally:
push_stream_tool.status = False
push_stream_tool.close_push_stream_p()
if push:
push.join(timeout=60)
if ex:
code, msg = ex
push_result(fb_queue, code, msg, status=StatusType.FAILED.value[0])
logger.info("推流检测线程执行完成")

# """
# 版本二
# """
# class PushStreamThread(Thread):
# __slots__ = ('__fbQueue', '__event', '__push_stream_tool', '__hb_status')
#
# def __init__(self, fbQueue, push_stream_tool):
# super().__init__()
# self.__fb_queue = fbQueue
# self.__event = Queue()
# self.__push_stream_tool = push_stream_tool
# self.__hb_status = StatusType.WAITTING.value[0]
# put_queue(self.__fb_queue, {
# "errorCode": "",
# "errorMsg": "",
# "status": StatusType.WAITTING.value[0],
# "current_time": now_date_to_str()}, is_throw_ex=False)
#
# def send_event(self, result):
# put_queue(self.__event, result, is_throw_ex=False)
#
# def run(self):
# logger.info("启动推流线程")
# self.__push_stream_tool.start_push_stream()
# count = 0
# start_time = time.time()
# while True:
# try:
# event_result = get_no_block_queue(self.__event)
# if event_result is not None:
# command = event_result.get("command")
# if "stop" == command:
# self.__push_stream_tool.close_push_stream_p(send=True)
# put_queue(self.__fb_queue, {
# "errorCode": "",
# "errorMsg": "",
# "status": StatusType.SUCCESS.value[0],
# "current_time": now_date_to_str()}, is_throw_ex=False)
# break
# if self.__push_stream_tool.push_stream_sp and self.__push_stream_tool.push_stream_sp.poll() is not None:
# logger.error("推流异常,请检查推流地址和拉流地址是否正常!!!!!")
# # if self.__push_stream_tool.push_stream_sp.returncode != 0:
# # out, err = self.__push_stream_tool.push_stream_sp.communicate(timeout=120)
# # logger.error("推流异常:{}", err.decode())
# self.__push_stream_tool.close_push_stream_p(send=True)
# self.__push_stream_tool.start_push_stream()
# self.__hb_status = StatusType.RETRYING.value[0]
# start_time = time.time()
# if time.time() - start_time > 20:
# self.__hb_status = StatusType.RUNNING.value[0]
# count += 1
# if count % 10 == 0:
# put_queue(self.__fb_queue, {
# "errorCode": "",
# "errorMsg": "",
# "status": self.__hb_status,
# "current_time": now_date_to_str()}, is_throw_ex=False)
# count = 0
# time.sleep(1)
# except ServiceException as s:
# logger.error("推流异常, code: {}, msg: {}", s.code, s.msg)
# put_queue(self.__fb_queue, {
# "errorCode": s.code,
# "errorMsg": s.msg,
# "status": StatusType.FAILED.value[0],
# "current_time": now_date_to_str()}, is_throw_ex=False)
# self.__push_stream_tool.close_push_stream_p(send=True)
# break
# except Exception:
# logger.error("推流异常:{}", format_exc())
# put_queue(self.__fb_queue, {
# "errorCode": ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
# "errorMsg": ExceptionType.SERVICE_INNER_EXCEPTION.value[1],
# "status": StatusType.FAILED.value[0],
# "current_time": now_date_to_str()}, is_throw_ex=False)
# self.__push_stream_tool.close_push_stream_p(send=True)
# break
# logger.info("推流检测线程执行完成")

+ 0
- 0
concurrency/mqtt/__init__.py Просмотреть файл


Двоичные данные
concurrency/mqtt/__pycache__/MqttFeedbackThread.cpython-38.pyc Просмотреть файл


Двоичные данные
concurrency/mqtt/__pycache__/MqttPushStreamProcess.cpython-38.pyc Просмотреть файл


Двоичные данные
concurrency/mqtt/__pycache__/__init__.cpython-38.pyc Просмотреть файл


+ 20
- 0
config/logger.yml Просмотреть файл

@@ -0,0 +1,20 @@
# 是否启动日志文件记录日志
enable_file_log: true
# 是否启动控制台打印日志
enable_stderr: true
# 日志相对于根路径下的相对路径
base_path: "logs"
# 日志文件名称
log_name: "airport_media.log"
# 日志打印格式
log_fmt: "{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}][{process.name}-{process.id}-{thread.name}-{thread.id}][{line}] {module}-{function} - {message}"
# 日志打印级别
level: "INFO"
# 日志绕接时间
rotation: "00:00"
# 日志保存时间
retention: "7 days"
# 日志编码格式
encoding: "utf8"



+ 20
- 0
config/mqtt.yml Просмотреть файл

@@ -0,0 +1,20 @@
mqtt:
# mqtt客户端id对应每个机场平台的编码
client_id: "THOBS@0000THJSQ232003"
# mqtt用户(根据对接环境修改)
username: "admin"
# mqtt密码(根据对接环境修改)
password: "admin##123"
# mqtt连接地址(根据对接环境修改)
host: "mqtt.t-aaron.com"
# mqtt端口号(根据对接环境修改)
port: 10883
# 长链接时间
keepalive: 60
topic:
stream:
# 推流订阅topic(不修改)
sub_topic: "/v1/%s/stream/push"
# 推流响应topic(不修改)
res_topic: "/v1/%s/stream/result"


+ 11
- 0
config/service.yml Просмотреть файл

@@ -0,0 +1,11 @@
# 1: mqtt消息队列方式对接
# 2: http接口方式对接
docking_method: 2
# 推拉流功能配置
stream:
# 拉流地址
pullUrl: "rtmp://live.play.t-aaron.com/live/1111"
# 推流地址
pushUrl: "rtmp://live.push.t-aaron.com/live/2222"



+ 66
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/AUTHORS Просмотреть файл

@@ -0,0 +1,66 @@
Cerberus is developed and maintained by the Cerberus community. It was created
by Nicola Iarocci.

Core maintainers
~~~~~~~~~~~~~~~~

- Nicola Iarocci (nicolaiarocci)
- Frank Sachsenheim (funkyfuture)

Contributors
~~~~~~~~~~~~

- Antoine Lubineau
- Arsh Singh
- Audric Schiltknecht
- Brandon Aubie
- Brett
- Bruno Oliveira
- Bryan W. Weber
- C.D. Clark III
- Christian Hogan
- Connor Zapfel
- Damián Nohales
- Danielle Pizzolli
- Davis Kirkendall
- Denis Carriere
- Dominik Kellner
- Eelke Hermens
- Evgeny Odegov
- Florian Rathgeber
- Gabriel Wainer
- Harro van der Klauw
- Jaroslav Semančík
- Jonathan Huot
- Kaleb Pomeroy
- Kirill Pavlov
- Kornelijus Survila
- Lujeni
- Luke Bechtel
- Luo Peng
- Martijn Vermaat
- Martin Ortbauer
- Matthew Ellison
- Michael Klich
- Nik Haldimann
- Nikita Melentev
- Nikita Vlaznev
- Paul Weaver
- Peter Demin
- Riccardo
- Roman Redkovich
- Scott Crunkleton
- Sebastian Heid
- Sebastian Rajo
- Sergey Leshchenko
- Tobias Betz
- Trong Hieu HA
- Vipul Gupta
- Waldir Pimenta
- Yauhen Shulitski
- calve
- gilbsgilbs

A full, up-to-date list of contributors is available from git with:

git shortlog -sne

+ 1
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/INSTALLER Просмотреть файл

@@ -0,0 +1 @@
pip

+ 15
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/LICENSE Просмотреть файл

@@ -0,0 +1,15 @@
ISC License

Copyright (c) 2012-2016 Nicola Iarocci.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

+ 164
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/METADATA Просмотреть файл

@@ -0,0 +1,164 @@
Metadata-Version: 2.1
Name: Cerberus
Version: 1.3.4
Summary: Lightweight, extensible schema and data validation tool for Python dictionaries.
Home-page: http://docs.python-cerberus.org
Author: Nicola Iarocci
Author-email: nicola@nicolaiarocci.com
Maintainer: Frank Sachsenheim
Maintainer-email: funkyfuture@riseup.net
License: ISC
Project-URL: Documentation, http://python-cerberus.org
Project-URL: Code, https://github.com/pyeve/cerberus
Project-URL: Issue tracker, https://github.com/pyeve/cerberus/issues
Keywords: validation,schema,dictionaries,documents,normalization
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: ISC License (ISCL)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=2.7
License-File: LICENSE
License-File: AUTHORS
Requires-Dist: setuptools

Cerberus |latest-version|
=========================
|build-status| |python-support| |black|

Cerberus is a lightweight and extensible data validation library for Python.

.. code-block:: python

>>> v = Validator({'name': {'type': 'string'}})
>>> v.validate({'name': 'john doe'})
True


Features
--------

Cerberus provides type checking and other base functionality out of the box and
is designed to be non-blocking and easily and widely extensible, allowing for
custom validation. It has no dependencies, but has the potential to become
yours.


Versioning & Interpreter support
--------------------------------

The Cerberus `1.x` versions can be used with Python 2 while version `2.0` and
later rely on Python 3 features.

Starting with Cerberus 1.2, it is maintained according to
`semantic versioning`_. So, a major release sheds off the old and defines a
space for the new, minor releases ship further new features and improvements
(you now the drill, new bugs are inevitable too), and micro releases polish a
definite amount of features to glory.

We intend to test Cerberus against all CPython interpreters at least until half
a year after their `end of life`_ and against the most recent PyPy interpreter
as a requirement for a release. If you still need to use it with a potential
security hole in your setup, it should most probably work with the latest
minor version branch from the time when the interpreter was still tested.
Subsequent minor versions have good chances as well. In any case, you are
advised to run the contributed test suite on your target system.


Funding
-------

Cerberus is an open source, collaboratively funded project. If you run a
business and are using Cerberus in a revenue-generating product, it would
make business sense to sponsor its development: it ensures the project that
your product relies on stays healthy and actively maintained. Individual users
are also welcome to make a recurring pledge or a one time donation if Cerberus
has helped you in your work or personal projects.

Every single sign-up makes a significant impact towards making Eve possible. To
learn more, check out our `funding page`_.


Documentation
-------------

Complete documentation is available at http://docs.python-cerberus.org


Installation
------------

Cerberus is on PyPI_, so all you need to do is:

.. code-block:: console

$ pip install cerberus


Testing
-------

Just run:

.. code-block:: console

$ python setup.py test

Or you can use tox to run the tests under all supported Python versions. Make
sure the required python versions are installed and run:

.. code-block:: console

$ pip install tox # first time only
$ tox


Contributing
------------

Please see the `Contribution Guidelines`_.


Copyright
---------

Cerberus is an open source project by `Nicola Iarocci`_. See the license_ file
for more information.


.. _Contribution Guidelines: https://github.com/pyeve/cerberus/blob/master/CONTRIBUTING.rst
.. _end of life: https://devguide.python.org/#status-of-python-branches
.. _funding page: http://docs.python-cerberus.org/en/latest/funding.html
.. _license: https://github.com/pyeve/cerberus/blob/master/LICENSE
.. _Nicola Iarocci: https://nicolaiarocci.com/
.. _PyPI: https://pypi.python.org/
.. _semantic versioning: https://semver.org/

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:alt: Black code style
:target: https://black.readthedocs.io/
.. |build-status| image:: https://travis-ci.org/pyeve/cerberus.svg?branch=master
:alt: Build status
:target: https://travis-ci.org/pyeve/cerberus
.. |latest-version| image:: https://img.shields.io/pypi/v/cerberus.svg
:alt: Latest version on PyPI
:target: https://pypi.org/project/cerberus
.. |license| image:: https://img.shields.io/pypi/l/cerberus.svg
:alt: Software license
:target: https://github.com/pyeve/cerberus/blob/master/LICENSE
.. |python-support| image:: https://img.shields.io/pypi/pyversions/cerberus.svg
:target: https://pypi.python.org/pypi/cerberus
:alt: Python versions

+ 48
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/RECORD Просмотреть файл

@@ -0,0 +1,48 @@
Cerberus-1.3.4.dist-info/AUTHORS,sha256=Wa5cbyooET3QnA5rDV6trSRxay3If8IuT0HEeEPHSSo,1145
Cerberus-1.3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Cerberus-1.3.4.dist-info/LICENSE,sha256=OXJkvLKH9kPVx7jBhG566vGRH4I2svi9759-bxzy__k,751
Cerberus-1.3.4.dist-info/METADATA,sha256=eDm6XwMWX8T1L3bOIgc2f5hg5YZ4OW120hznkjgXqTk,5799
Cerberus-1.3.4.dist-info/RECORD,,
Cerberus-1.3.4.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Cerberus-1.3.4.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
Cerberus-1.3.4.dist-info/top_level.txt,sha256=ZwdViFmandWj-jK09wLSDM63moDFYE46vDo7tRb-1HE,9
cerberus/__init__.py,sha256=Zj2rLhMbfDS9h_0UuNBf0DfNucUv7ae-RCn51tTiRB4,796
cerberus/__pycache__/__init__.cpython-38.pyc,,
cerberus/__pycache__/errors.cpython-38.pyc,,
cerberus/__pycache__/platform.cpython-38.pyc,,
cerberus/__pycache__/schema.cpython-38.pyc,,
cerberus/__pycache__/utils.cpython-38.pyc,,
cerberus/__pycache__/validator.cpython-38.pyc,,
cerberus/benchmarks/__init__.py,sha256=tIrl4N414oddAmhtfZm5u5tmpSKCaaSvyg780Y7_F5M,80
cerberus/benchmarks/__pycache__/__init__.cpython-38.pyc,,
cerberus/benchmarks/__pycache__/test_overall_performance_1.cpython-38.pyc,,
cerberus/benchmarks/__pycache__/test_overall_performance_2.cpython-38.pyc,,
cerberus/benchmarks/test_overall_performance_1.py,sha256=7iNmNttRTC7ZyZ7q3rmGQfutfkV-Dp6eaolW-ZlHA3Q,6052
cerberus/benchmarks/test_overall_performance_2.py,sha256=Z41GN5ZlWRcuNbFsXPLDfLqAAdTffOGGwm695LPsi4g,1610
cerberus/errors.py,sha256=xxuSnQmY1wGHr3nLob0xwMjf8pXCwrn7cBxT0IRrHOc,21252
cerberus/platform.py,sha256=7eEKOaKSTjn2AiYrqymRrMTSbX2iB7RNstIbPQVr6bE,856
cerberus/schema.py,sha256=57M65CjNq1TV9dTwnntDT567K8gC_9f16oMUxCqqSvU,18337
cerberus/tests/__init__.py,sha256=-4-nTnmGWSRzRFGkF_lSHt8c_6b3ZdSaT8woqerrUp0,4687
cerberus/tests/__pycache__/__init__.cpython-38.pyc,,
cerberus/tests/__pycache__/conftest.cpython-38.pyc,,
cerberus/tests/__pycache__/test_assorted.cpython-38.pyc,,
cerberus/tests/__pycache__/test_customization.cpython-38.pyc,,
cerberus/tests/__pycache__/test_errors.cpython-38.pyc,,
cerberus/tests/__pycache__/test_legacy.cpython-38.pyc,,
cerberus/tests/__pycache__/test_normalization.cpython-38.pyc,,
cerberus/tests/__pycache__/test_registries.cpython-38.pyc,,
cerberus/tests/__pycache__/test_schema.cpython-38.pyc,,
cerberus/tests/__pycache__/test_utils.cpython-38.pyc,,
cerberus/tests/__pycache__/test_validation.cpython-38.pyc,,
cerberus/tests/conftest.py,sha256=CVw_J0T2rw89KTYL7OKQyKwv8yE0kCa18Vvv-NfP3ls,2517
cerberus/tests/test_assorted.py,sha256=DifsOU-Y16Zp4utQ4SyJtTGjgL4fPwkVWXiKQnCmbcM,3169
cerberus/tests/test_customization.py,sha256=M8_39XtpLOkKpsJX6O6E4danmNy6HW_VbnfO-39SHMw,3383
cerberus/tests/test_errors.py,sha256=dFB8HpAq0vJwJxh3oDA4bhr8e2O1V9gVnu4B_0Flc_w,11862
cerberus/tests/test_legacy.py,sha256=37wjVkGfwPX9kZE_TDds3Q9R5b-CQzlvQiOJVG9Y9NI,30
cerberus/tests/test_normalization.py,sha256=zcsNVbEF4SNQj0UI1O1bBwbvIn5QFWEYStxalS0P5KU,17212
cerberus/tests/test_registries.py,sha256=dD2BGXcG2f-Z0qBAYqNgfCKJK7ve-pdK93LaNrJrML0,2841
cerberus/tests/test_schema.py,sha256=OQi7qevtQe1ZfG-xeUToQ6p9zlhBENq3bHHZZR_RXOM,5080
cerberus/tests/test_utils.py,sha256=YhkRkqKmeARPXJIfG6o9TvgXpk45gucN5LToZgnDLvw,290
cerberus/tests/test_validation.py,sha256=OIHxLnJdUOBjxtsOSsiLQ4YrpucQ8wo9Zv6z5Q6wmuw,59155
cerberus/utils.py,sha256=IbWRFyNtBLz38pJsT2ogcaBzjHHyr59j2nqDyMH5czM,3875
cerberus/validator.py,sha256=rcS-H26EqX41y1CZzwpA2G7DitQav_bk4sqUWkuhdng,64960

+ 0
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/REQUESTED Просмотреть файл


+ 5
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/WHEEL Просмотреть файл

@@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.40.0)
Root-Is-Purelib: true
Tag: py3-none-any


+ 1
- 0
dist/airportStream/Cerberus-1.3.4.dist-info/top_level.txt Просмотреть файл

@@ -0,0 +1 @@
cerberus

Двоичные данные
dist/airportStream/MSVCP140.dll Просмотреть файл


Двоичные данные
dist/airportStream/VCRUNTIME140.dll Просмотреть файл


Двоичные данные
dist/airportStream/VCRUNTIME140_1.dll Просмотреть файл


Двоичные данные
dist/airportStream/_asyncio.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_bz2.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_cffi_backend.cp38-win_amd64.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_ctypes.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_decimal.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_hashlib.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_lzma.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_multiprocessing.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_overlapped.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_queue.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_ruamel_yaml.cp38-win_amd64.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_socket.pyd Просмотреть файл


Двоичные данные
dist/airportStream/_ssl.pyd Просмотреть файл


Двоичные данные
dist/airportStream/airportStream.exe Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-console-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-datetime-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-debug-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-errorhandling-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-file-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-file-l1-2-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-file-l2-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-handle-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-heap-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-interlocked-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-libraryloader-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-localization-l1-2-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-memory-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-namedpipe-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-processenvironment-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-processthreads-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-processthreads-l1-1-1.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-profile-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-rtlsupport-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-string-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-synch-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-synch-l1-2-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-sysinfo-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-timezone-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-core-util-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-conio-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-convert-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-environment-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-filesystem-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-heap-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-locale-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-math-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-process-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-runtime-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-stdio-l1-1-0.dll Просмотреть файл


Двоичные данные
dist/airportStream/api-ms-win-crt-string-l1-1-0.dll Просмотреть файл


+ 0
- 0
dist/airportStream/api-ms-win-crt-time-l1-1-0.dll Просмотреть файл


Некоторые файлы не были показаны из-за большого количества измененных файлов

Загрузка…
Отмена
Сохранить