Оборудование отправляет файлы по FTP. Сервер на pyftpdlib. в 2% случаев файл приходит битым в первой строке.
ЁА°Ш?Л° " : [
{
"ManNumDetection" : [
{
Должно быть так:
{
"NumberStat" : [
{
"ManNumDetection" : [
Куда копать?
Server FTP
def ftp_server_local():
print("Starting FTP")
# экземпляр фиктивного средства авторизации
# для управления "виртуальными" пользователями
authorizer = DummyAuthorizer()
ftp_path = config.FTP_DIR
login_ftp = config.LOGIN_FTP
pass_ftp = config.PASS_FTP
if not os.path.isdir(f'{ftp_path}'):
os.mkdir(f'{ftp_path}')
if not os.path.isdir(f'{ftp_path}/logs'):
os.mkdir(f'{ftp_path}/logs')
# authorizer.add_user(login_ftp, pass_ftp, ftp_path, perm='elamwMT')
authorizer.add_user(login_ftp, pass_ftp, ftp_path, perm='elradfmwMT')
# authorizer.add_anonymous(os.getcwd())
# экземпляр класса обработчика FTP
handler = FTPHandler
handler.authorizer = authorizer
# настраиваемый баннер (строка, возвращаемая при подключении клиента)
handler.banner = "qqqqqq"
# masquerade-адрес и диапазон портов, которые будут использоваться
# для пассивных подключений. Строки ниже нужно раскомментировать
# если вы находитесь за NAT (masquerade_address укажите свой).
handler.masquerade_address = config.EXTERNAL_IP
handler.passive_ports = range(60000, 60200)
# экземпляр класса FTP-сервера, который слушает `0.0.0.0:2121`
# address = ('0.0.0.0', config.PORT_FTP)
address = ('', config.PORT_FTP)
server = FTPServer(address, handler)
# лимиты на соединения
server.max_cons = 500
server.max_cons_per_ip = 50
# запись логов в файл
logging.basicConfig(filename=f'{ftp_path}/logs/pyftpd.log', level=logging.ERROR)
server.serve_forever()
if __name__ == '__main__':
ftp_server_local()