{"id":353985,"date":"2024-05-20T22:39:18","date_gmt":"2024-05-20T22:39:18","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=353985"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=353985","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e\u0444\u0430\u0439\u043b\u043e\u0432<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u043b\u0438\u0441\u0442\u0430 \u0438\u043b\u0438 \u0438\u0437 \u0430\u0443\u0434\u0438\u043e\u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2013 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0430\u044f\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432 \u043e\u0444\u0438\u0441\u0430\u0445 \u0438\u043b\u0438 \u0443\u0447\u0451\u0431\u044b. \u0414\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0438 \u0430\u0443\u0434\u0438\u043e \u0432 \u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b, \u043a\u0430\u043a \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0435 \u0437\u0440\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0447\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439.     <\/p>\n<p>\u0414\u0435\u0442\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 (\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435) \u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 [1]. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0445 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u044f\u0447\u0435\u0435\u043a \u0434\u043e\u043b\u0433\u043e\u0439 \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 LSTM [2]. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438, \u044d\u0442\u0430\u043f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.    <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043b\u0438\u0441\u0442\u0430 \u0438\u043b\u0438 \u0430\u0443\u0434\u0438\u043e-\u0444\u0430\u0439\u043b\u0430.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0441\u0442\u0435\u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439<\/h2>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/051\/d53\/753\/051d53753b9b21c9eb803ba1a488cf07.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1 \u2013 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   \" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1 \u2013 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   \" width=\"1032\" height=\"645\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/051\/d53\/753\/051d53753b9b21c9eb803ba1a488cf07.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1 \u2013 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   <\/figcaption><\/div>\n<\/figure>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440, \u0432 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 MVC (Model-View-Controller). \u0412\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0442\u0440\u0451\u0445 \u0432\u0438\u0434\u043e\u0432: \u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u0422\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u0438, \u0437\u0430 \u0441\u0447\u0451\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.   <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u043e\u0434 \u043c\u043e\u0434\u0443\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 Java Script, \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Google Chrome. \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432\u0445\u043e\u0434\u044f\u0442: \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u043b\u0430\u0441\u044c \u043d\u0430 Windows.    <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f Java Servlet.   <\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d \u0432\u0435\u0431 \u0441\u0435\u0440\u0432\u0435\u0440 Apache Tomcat, \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e, \u0433\u0438\u0431\u043a\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, Apache Tomcat \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u0430\u0442\u0440\u0430\u0442 \u043d\u0430 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 http (\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0430 \u041f\u041a).   <\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e-\u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438 \u0438\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b\u044b (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0444\u0430\u0439\u043b\u044b *.docx). \u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Python \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 OpenCV \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 TensorFlow. <\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0421\u0423\u0411\u0414) PostgreSQL. \u041f\u043b\u044e\u0441\u0430\u043c\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0431\u044b\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (IDE) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438. \u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u043d\u0430 Python \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f PyCharm, \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b &#8212; IntelliJ IDEA; \u043e\u0431\u0435 IDE \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439 JetBrains, \u043f\u043e\u0445\u043e\u0436\u0438 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c\u0438. <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/vadimpechenin\/RecognizingTextFromImageApp.git\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>, \u0434\u0430\u043b\u0435\u0435 \u0440\u0430\u0441\u043a\u0440\u043e\u044e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0438 \u0430\u0443\u0434\u0438\u043e \u0444\u0430\u0439\u043b\u043e\u0432   <\/h2>\n<p>\u0414\u043b\u044f\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f OCR\u00a0\u2014 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043d\u0430\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u00a0\u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u044c. \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0442\u0435\u043a\u0441\u0442, \u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0432\u00a0\u043d\u0435\u043c. \u041f\u043e\u0441\u043b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0438\u043c\u0432\u043e\u043b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0\u043c\u0430\u0448\u0438\u043d\u043d\u043e\u2011\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. <\/p>\n<p>\u0414\u043b\u044f\u00a0\u0446\u0435\u043b\u0435\u0439 OCR \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043f\u0430\u043a\u0435\u0442 <em>PyTesseract<\/em>, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043e\u0431\u043e\u043b\u043e\u0447\u043d\u043e\u0439 \u0434\u043b\u044f\u00a0Google Tesseract\u2011OCR Engine. Tesseract \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438 \u0438 \u0434\u0432\u0443\u0445\u0441\u0442\u0443\u043f\u0435\u043d\u0447\u0430\u0442\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a\u00a0\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044e. \u0412\u00a0\u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u041d\u0430\u00a0\u0432\u0442\u043e\u0440\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043b\u044e\u0431\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043d\u0438\u0437\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438 \u043f\u043e\u00a0\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443. \u042d\u0442\u0430\u043f\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u00a0\u0431\u0430\u0437\u0435 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0439 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 LSTM, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0434\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u041f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u0444\u043e\u0440\u043c\u0430\u0442\u0435 PDF \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u0437\u00a0\u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u00a0\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043f\u0430\u043c\u044f\u0442\u044c \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>fitz<\/em>. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f\u00a0\u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"python\">import fitz  @staticmethod def __getPDF(dictOfProject, parameters):     for imageFromList in dictOfProject['InputDocument']:         byteImage = bytes.fromhex(imageFromList)         fileName = str(parameters.imagesFolder.joinpath('example.pdf').resolve())         file = open(fileName, 'wb')         file.write(byteImage)         file.close()         pdfDocument = fitz.open(fileName)      return pdfDocument<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 PNG, \u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>pytesseract<\/em> \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f\u0441\u044c \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>docx<\/em>. <\/p>\n<p>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f OCR:<\/p>\n<pre><code class=\"python\">import os import docx import cv2  @staticmethod def __recognitionText(pdfDocument, parameters):     mydoc = docx.Document()     for current_page in range(len(pdfDocument)):         for image in pdfDocument.get_page_images(current_page):             xref = image[0]             fileName = str(parameters.imagesFolder.joinpath(\"page%s-%s.png\" % (current_page, xref)).resolve())             # \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenCV             ConvertPdfToTextCalculator.__takeImage(parameters.pytesseract, mydoc,fileName)     pdfDocument.close()     return mydoc  @staticmethod def __takeImage(pytesseract, mydoc,fileName):     image = cv2.imread(fileName)     # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443     pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'     string = pytesseract.image_to_string(image, lang='rus')     # \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442     mydoc.add_paragraph(string)<\/code><\/pre>\n<p>\u0414\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0430\u0443\u0434\u0438\u043e\u00a0\u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Speech Recognition (\u0432 \u043a\u043e\u0434\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043a\u0430\u043a <em>sr<\/em>), \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043a\u0440\u044b\u0442\u043e\u0439 \u043c\u0430\u0440\u043a\u043e\u0432\u0441\u043a\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 [3] \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f\u00a0\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0440\u0435\u0447\u0435\u0432\u044b\u0445 API (\u043c\u043d\u043e\u0439\u00a0\u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d Google Speech). \u0414\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0437\u0432\u0443\u043a\u043e\u043c \u043a\u0430\u043a\u00a0\u0441\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0438 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0438 \u0435\u0433\u043e \u043d\u0430\u00a0\u043e\u0442\u0440\u0435\u0437\u043a\u0438 \u043f\u043e\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443 \u0442\u0438\u0448\u0438\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <em>pydub<\/em>, \u0430\u00a0\u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043b\u0430\u0441\u0441 <em>AudioSegment<\/em> \u0438 \u043c\u0435\u0442\u043e\u0434 <em>split_on_silence<\/em>. <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <em>AudioSegment:<\/em><\/p>\n<pre><code class=\"python\">@staticmethod def __getWav(dictOfProject, parameters):     for imageFromList in dictOfProject['InputDocument']:         byteFile = bytes.fromhex(imageFromList)         fileName = str(parameters.imagesFolder.joinpath('example.wav').resolve())         file = open(fileName, 'wb')         file.write(byteFile)         file.close()         sound = parameters.AudioSegment.from_wav(fileName)      return sound<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0430 \u0437\u0432\u0443\u043a\u0438, \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u0448\u0438\u043d\u043e\u0439:<\/p>\n<pre><code class=\"python\">@staticmethod def __getSounds(soundDocument, parameters):     chunks = parameters.split_on_silence(soundDocument,                                                              min_silence_len=500,                                                              silence_thresh=soundDocument.dBFS - 15,                                                              keep_silence=500,                               )     return chunks<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"python\">def __recognitionSound(chunks, parameters):     mydoc = docx.Document()     r = parameters.sr.Recognizer()          for i, audio_chunk in enumerate(chunks, start=1):                  chunk_filename = os.path.join(parameters.imagesFolder, f\"chunk{i}.wav\")         audio_chunk.export(chunk_filename, format=\"wav\")         start_time = datetime.now()         print(datetime.now() - start_time)                  with parameters.sr.AudioFile(chunk_filename) as source:             audio_listened = r.record(source)                          try:                 text = r.recognize_google(audio_listened, language=parameters.language)             except parameters.sr.UnknownValueError as e:                 print(\"Error:\", str(e))             else:                 text = f\"{text.capitalize()}. \"                 print(\" -- :\", text)                 mydoc.add_paragraph(text)         print(\"\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: \")         print(datetime.now() - start_time)     return mydoc<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b\u044b *.pdf \u0438\u043b\u0438 *.wav \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0441\u043e\u043a\u0435\u0442\u043e\u0432. \u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>NetworkServer<\/em>. <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0437\u0430\u043f\u0443\u0441\u043a\u0430 cvserver.py \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">import keyboard from core.clientServer.networkServer import NetworkServer  if __name__ == '__main__':     server = NetworkServer()     port = 10000     server.init(port)     server.start()     print(\"\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430!\")     print(\"\u0414\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 q\")     keyboard.wait(\"q\")     server.stop()     server.done()     print(\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430\")<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 NetworkServer:<\/p>\n<pre><code class=\"python\">import socket from threading import Thread  from core.clientsManager import ClientsManager from core.clientServer.clientHandler import ClientHandler from core.requests.requestFactory import RequestFactory   class NetworkServer(object):     def __init__(self):         self._socket = None         self._continueWork = False         self._thread = None         self._clientsManager = ClientsManager()         self._requestFactory = RequestFactory()      def init(self, portNumber):         self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)         self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)         self._socket.settimeout(0.1)         self._socket.bind((\"127.0.0.1\", portNumber))         self._socket.listen(0)      def done(self):         self.stop()         if not (self._socket is None):             self._socket.close()             self._socket = None      def start(self):         if not (self._thread is None):             self.stop()         self._continueWork = True         self._thread = Thread(target=self.__work)         self._thread.start()      def stop(self):         if self._thread is None:             return         self._continueWork = False         self._thread.join()         self._thread = None      def __work(self):         while self._continueWork:             try:                 clientSocket, clientAddress = self._socket.accept()                 client = ClientHandler(self, clientSocket)                 self.getClientsManager().Add(client)                 client.run()             except socket.timeout:                 pass             except Exception as e:                 print(\"Exception occur: \" + e.__str__())                 raise      def getClientsManager(self):         return self._clientsManager      def getRequestFactory(self):         return self._requestFactory<\/code><\/pre>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <em>Thread()<\/em>. \u0414\u043b\u044f \u0432\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>ClientsManager<\/em>.  <\/p>\n<pre><code class=\"python\">from threading import Lock   class ClientsManager(object):     def __init__(self):         self._clientsLock = Lock()         self._clients = []      def Add(self, client):         self._clientsLock.acquire()         if not (client in self._clients):             self._clients.append(client)         self._clientsLock.release()      def Remove(self, client):         self._clientsLock.acquire()         if client in self._clients:             self._clients.remove(client)         self._clientsLock.release()<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0438 \u043e\u0442\u0441\u044b\u043b\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u00a0 <em>ClientHandler<\/em>. <\/p>\n<pre><code class=\"python\">from threading import Thread  from core.requests.requestResponseBuilder import RequestResponseBuilder   class ClientHandler(object):     RECEIVE_TIMEOUT = 30      def __init__(self, parent, clientSocket):         self._parent = parent         self._socket = clientSocket         self._thread = None      def run(self):         self._thread = Thread(target=self.__work)         self._thread.start()      def __work(self):         self._socket.settimeout(self.RECEIVE_TIMEOUT)          requestCode, requestBody = RequestResponseBuilder.readRequest(self._socket)         responseBody = self._parent.getRequestFactory().handle(requestCode, requestBody)         RequestResponseBuilder.writeResponse(self._socket, responseBody)          self._socket.close()         self._parent.getClientsManager().Remove(self)<\/code><\/pre>\n<p>\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>RequestFactory<\/em> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u043a\u043b\u0430\u0441\u0441\u0430\u043c-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c<em> (RecognitionTextHandler<\/em> \u0438 <em>RecognitionSpeechHandler<\/em>), \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u0434\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <\/p>\n<p>\u041a\u043e\u0434 <em>RequestFactory<\/em>: <\/p>\n<pre><code class=\"python\">from typing import Optional  from core.requests.recognitionTextHandler import RecognitionTextHandler from core.requests.recognitionSpeechHandler import RecognitionSpeechHandler from core.requests.requestCodes import RequestCodes   class RequestFactory(object):      def __init__(self) -> None:         self._handlers = {             RequestCodes.RecognitionText: RecognitionTextHandler(),             RequestCodes.RecognitionSpeech: RecognitionSpeechHandler()         }      def handle(self, requestCode: int, requestBody: bytearray) -> Optional[bytes]:         if requestCode in self._handlers:             response = self._handlers[requestCode].handle(requestBody)         else:             response = None         return response<\/code><\/pre>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441 <em>RequestResponseBuilder<\/em> \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043b\u044f \u00ab\u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0438\u00bb \u0438 \u00ab\u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438\u00bb \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0431\u0430\u0439\u0442.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 <em>RequestFactory<\/em> \u043a\u043b\u0430\u0441\u0441\u044b-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e \u0441\u0443\u0442\u0438 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u043a\u043b\u0430\u0441\u0441\u044b-\u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e, \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0430.<\/p>\n<p>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 \u2013 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430:<\/p>\n<pre><code class=\"python\">import json from typing import Optional  import pytesseract  from core.calculators.convertPdfToTextCalculator import ConvertPdfToTextCalculator from core.optParameters import OptParameters from core.commonUtils import CommonUtils   class RecognitionTextHandler(object):     def __init__(self):         self.pytesseract = pytesseract         self.pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'      def handle(self, packedParameters: bytearray) -> Optional[bytes]:         if packedParameters is None or len(packedParameters) == 0:             return None          parametersStr = packedParameters.decode(\"utf8\")          parameters = json.loads(parametersStr)          optParameters = OptParameters()         optParameters.pytesseract = self.pytesseract         optParameters.imagesFolder = CommonUtils.getSolutionFolder().joinpath(\"CVServer\").joinpath(\"main\").joinpath(\"data\")         result = ConvertPdfToTextCalculator.calculate(parameters, optParameters)         try:             response = json.dumps(result).encode(\"utf8\")         except:             print('Error')          return response<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 \u2013 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0447\u0438:<\/p>\n<pre><code class=\"python\">import json from typing import Optional  import speech_recognition as sr   from core.calculators.convertWavToTextCalculator import ConvertWavToTextCalculator  from core.optParameters import OptParameters from core.commonUtils import CommonUtils  from pydub import AudioSegment from pydub.silence import split_on_silence   class RecognitionSpeechHandler(object):     def __init__(self):         self.sr = sr         self.AudioSegment = AudioSegment         self.split_on_silence = split_on_silence      def handle(self, packedParameters: bytearray) -> Optional[bytes]:         if packedParameters is None or len(packedParameters) == 0:             return None          parametersStr = packedParameters.decode(\"utf8\")          parameters = json.loads(parametersStr)          optParameters = OptParameters()         optParameters.AudioSegment = self.AudioSegment         optParameters.split_on_silence = self.split_on_silence         optParameters.sr = self.sr         optParameters.imagesFolder = CommonUtils.getSolutionFolder().joinpath(\"CVServer\").joinpath(\"main\").joinpath(\"data\").joinpath(\"sound\")          result = ConvertWavToTextCalculator.calculate(parameters, optParameters)         try:             response = json.dumps(result).encode(\"utf8\")         except:             print('Error')          return response<\/code><\/pre>\n<p>\u041e\u0442\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u044f \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439    {&#8216;result&#8217;: True\/False, &#8216;value&#8217;: itemshex}, \u00a0\u0433\u0434\u0435 <em>itemhex<\/em> \u2013 \u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>hex()<\/em>. <\/p>\n<p>   \u041e\u043f\u0438\u0448\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445   <\/h2>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0432 \u0445\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 2 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 ER \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 (\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c-\u0441\u0432\u044f\u0437\u044c) \u0441\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445.   <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd8\/ad8\/9ab\/dd8ad89abd27b6379c6ad63cabeeffa2.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2 \u2013 ER \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u044b   \" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2 \u2013 ER \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u044b   \" width=\"588\" height=\"351\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dd8\/ad8\/9ab\/dd8ad89abd27b6379c6ad63cabeeffa2.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2 \u2013 ER \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u044b   <\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u0430\u044f \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 2, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 4 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u2013 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0438\u043c\u0435\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 ID, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u0443\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 UUID.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439: 1) \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043f\u0440\u0430\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439; 2) \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u044b\u043c \u0444\u0430\u0439\u043b\u0430\u043c.<\/p>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0435 \u0437\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0438 \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c <em>Users<\/em> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e \u043b\u0438\u0447\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: <em>Name<\/em> (\u0438\u043c\u044f), <em>Surname<\/em> (\u0444\u0430\u043c\u0438\u043b\u0438\u044f), <em>Email<\/em> (\u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0447\u0442\u044b), <em>Username<\/em> (\u043b\u043e\u0433\u0438\u043d), <em>Password<\/em> (\u043f\u0430\u0440\u043e\u043b\u044c).<\/p>\n<p>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c <em>Roles<\/em> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u043e\u043b\u044f\u0445, \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0435 <em>Role<\/em>, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: user \u0438 admin.<\/p>\n<p>\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 <em>Users<\/em> \u0438 <em>Roles<\/em> \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b <em>UserRoles<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b <em>UserID<\/em> \u0438 <em>RoleID<\/em>.<\/p>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c <em>Documents<\/em>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u043f\u043e\u043b\u044f <em>UserID<\/em> (\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 Users), \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <em>Title<\/em> \u0438 \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e <em>FilePDF<\/em> \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0435\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442 <em>FileTXT<\/em>. <em>FilePDF<\/em> &#8212; \u044d\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 *.pdf \u0438\u043b\u0438 *.wav \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442, <em>FileTXT<\/em> &#8212; \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 *.docx \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u043e\u0434 \u043d\u0430 Python \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c SQLAlchemy, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 PostgreSQL. \u041a\u043e\u0434 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 <em>Tools\/ DBGenerate <\/em>\u043f\u0440\u043e\u0435\u043a\u0442\u0430<br \/> \u043d\u0430 Github.<\/p>\n<h2>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439   <\/h2>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0435\u0439, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 3.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4b3\/217\/a93\/4b3217a93d5e5d42712e0dcc7b443396.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0435\u0439   \" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0435\u0439   \" width=\"1612\" height=\"879\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4b3\/217\/a93\/4b3217a93d5e5d42712e0dcc7b443396.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0435\u0439   <\/figcaption><\/div>\n<\/figure>\n<p>\u042f\u0434\u0440\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 <em>MainServlet<\/em>, \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>HttpServlet<\/em>. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 <em>HandlerInfo<\/em> \u0432\u00a0\u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u00ab\u0441\u043b\u043e\u0432\u0430\u0440\u044c\u00bb <em>handlers<\/em>, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0445 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u0441\u043f\u043e\u0441\u043e\u0431 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0443. \u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 MainServlet:<\/p>\n<pre><code class=\"java\">import classes.RequestCode; import core.interaction.*; import handlers.DocumentsHandler; import handlers.SessionHandler; import handlers.UsersInfoHandler; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.MultipartConfig; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse;  import java.io.IOException; import java.util.HashMap; import java.util.Map;   \/**  * \u041a\u043b\u0430\u0441\u0441 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435.  *  *\/ @WebServlet(name = \"MainServlet\", urlPatterns = \"\/handler\") @MultipartConfig(         fileSizeThreshold = 1024 * 1024 * 8,         maxFileSize = 1024 * 1024 * 8,         maxRequestSize = 1024 * 1024 * 9 ) public class MainServlet extends HttpServlet {       private static class HandlerInfo {         RequestHandler requestHandler;         RequestExtractor requestExtractor;         ResponsePacker responsePacker;          public HandlerInfo(RequestHandler handler, RequestExtractor requestExtractor, ResponsePacker responsePacker) {             this.requestHandler = handler;             this.requestExtractor = requestExtractor;             this.responsePacker = responsePacker;         }     }      private volatile Boolean isInitialized;     private final Object isInitializedLock = new Object();     private final Map&lt;String, HandlerInfo> handlers;     private MainServletEnvironment environment;      public MainServlet() {         handlers = new HashMap&lt;>();     }       @Override     public void init(ServletConfig config) throws ServletException {         super.init(config);         \/\/\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0441\u0441\u0438\u0438         if(isInitialized == null) {             synchronized(isInitializedLock) {                 if(isInitialized == null) {                     isInitialized = initializeImpl();                 }             }         }         log(\"Method init =)\");     }      @Override     protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException, IOException {         String command = null;         try {             if (isInitialized) {                 command = httpServletRequest.getParameter(\"cmd\");                 HandlerInfo handlerInfo = handlers.get(command);                 if (handlerInfo != null) {                     Request request = handlerInfo.requestExtractor.extract(httpServletRequest);                     InnerResponseRecipient responseRecipient = new InnerResponseRecipient();                     handlerInfo.requestHandler.executeRequest(responseRecipient, request);                     handlerInfo.responsePacker.pack(request, responseRecipient.response, httpServletRequest, httpServletResponse);                 } else {                     handleError(httpServletResponse, \"templates\/CommandNotSupported.html\");                 }             } else {                 handleError(httpServletResponse, \"templates\/InitializationFailed.html\");             }         } catch (Exception e) {             System.out.printf(\"\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0434 %s\", command);             handleError(httpServletResponse, \"templates\/ExceptionOccur.html\");             e.printStackTrace();         }         log(\"Method service =)\");     }      private void handleError(HttpServletResponse httpServletResponse, String errorTemplate) throws IOException {         String pageText = environment.resourceManager.getResource(errorTemplate);         HttpServletResponseBuilder.onStringResponse(httpServletResponse, HttpServletResponse.SC_BAD_REQUEST, HttpServletResponseBuilder.HTMLContentType, pageText);     }      @Override     public void destroy() {         super.destroy();         log(\"Method desctoy =)\");     }      private boolean initializeImpl() {         boolean result;         try {             environment = MainServletEnvironment.create();             result = environment != null;              if (result) {                 RequestHandler sessionHandler = new SessionHandler(environment.sessionManager, environment.securityManager);                 register(RequestCode.SESSION_OPEN, sessionHandler, environment.editContentRequestExtractor, environment.sessionOpenResponsePacker);                 register(RequestCode.SESSION_CLOSE, sessionHandler, environment.baseRequestExtractor, environment.sessionCloseResponsePacker);                  RequestHandler usersInfoHandler = new UsersInfoHandler(environment.sessionManager, environment.securityManager, environment.documentManager);                 register(RequestCode.USERS_INFO, usersInfoHandler, environment.editContentRequestExtractor, environment.objectResponsePacker);                 register(RequestCode.CURRENT_USER_INFO, usersInfoHandler, environment.baseRequestExtractor, environment.objectResponsePacker);                 register(RequestCode.REGISTRATION_USER_INFO, usersInfoHandler, environment.entityWithViolationsRequestExtractor, environment.sessionOpenResponsePacker);                 register(RequestCode.GET_DOCUMENTS_HISTORY, usersInfoHandler, environment.baseRequestExtractor, environment.objectResponsePacker);                 register(RequestCode.GET_DOCUMENT_BY_ID, usersInfoHandler, environment.editContentRequestExtractor, environment.objectResponsePacker);                  RequestHandler documentsHandler = new DocumentsHandler(environment.sessionManager, environment.documentManager);                 register(RequestCode.RECOGNIZE_DOCUMENT, documentsHandler, environment.requestWithAttachmentsExtractor, environment.objectResponsePacker);                 register(RequestCode.RECOGNIZE_AUDIO_DOCUMENT, documentsHandler, environment.requestWithAttachmentsExtractor, environment.objectResponsePacker);                 register(RequestCode.SAVE_DOCUMENT, documentsHandler, environment.requestWithAttachmentsExtractor, environment.baseResponsePacker);             }         } catch (Exception e) {             e.printStackTrace();             result = false;         }          return result;     }      private void register(RequestCode code, RequestHandler handler, RequestExtractor requestExtractor, ResponsePacker responsePacker) {         handlers.put(code.toString(), new HandlerInfo(handler, requestExtractor, responsePacker));     }  }<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, <em>MainServlet<\/em> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 <em>MainServlet Environment<\/em>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u2011\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u0432 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438\u2011\u043e\u0442\u0432\u0435\u0442\u0430\u043c\u0438 \u0438 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445. <em>MainServlet<\/em> \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b: <em>initialize()<\/em>\u00a0\u2014 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437 \u0437\u0430\u043f\u0443\u0441\u043a \u043c\u0435\u0442\u043e\u0434\u0430 <em>initializeImpl()<\/em>; <em>initializeImpl()<\/em>\u00a0\u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <em>create()<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 <em>MainServlet Environment<\/em>, \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c <em>handlers<\/em> \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 <em>register()<\/em>; \u043c\u0435\u0442\u043e\u0434 <em>service()<\/em> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u044b; \u043c\u0435\u0442\u043e\u0434 <em>handleError()<\/em> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0432\u00a0\u0441\u043b\u043e\u0432\u0430\u0440\u0435 <em>handlers<\/em>.\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <em>WebHandlerEnvironment<\/em>:<\/p>\n<pre><code class=\"java\">import core.ResourceManager; import core.SessionManager; import core.documentManager.DocumentManager; import core.interaction.RequestExtractor; import core.interaction.ResponsePacker; import core.interaction.requestExtractors.BaseRequestExtractor; import core.interaction.requestExtractors.EditContentRequestExtractor; import core.interaction.requestExtractors.RequestWithAttachmentsExtractor; import core.interaction.requestExtractors.entityRequestExtractor.EntityRequestExtractor; import core.interaction.requestExtractors.entityRequestExtractor.EntityWithViolationsRequestExtractor; import core.interaction.responsePackers.BaseResponsePacker; import core.interaction.responsePackers.ObjectResponsePacker; import core.interaction.responsePackers.SessionCloseResponsePacker; import core.interaction.responsePackers.SessionOpenResponsePacker; import db.HibernateSessionFactory; import org.hibernate.SessionFactory; import core.securityManager.SecurityManager;  public class MainServletEnvironment {     final public SessionFactory hibernateSessionFactory;     final public SessionManager sessionManager;     final public SecurityManager securityManager;     final public DocumentManager documentManager;     final public ResourceManager resourceManager;     final public RequestExtractor baseRequestExtractor;     final public RequestExtractor editContentRequestExtractor;     final public RequestWithAttachmentsExtractor requestWithAttachmentsExtractor;     final public EntityRequestExtractor entityRequestExtractor;     final public EntityWithViolationsRequestExtractor entityWithViolationsRequestExtractor;     final public ResponsePacker sessionOpenResponsePacker;     final public ResponsePacker sessionCloseResponsePacker;     final public BaseResponsePacker baseResponsePacker;     final public ObjectResponsePacker objectResponsePacker;      private MainServletEnvironment(SessionFactory hibernateSessionFactory, SessionManager sessionManager,                                   SecurityManager securityManager,DocumentManager documentManager) {         this.hibernateSessionFactory = hibernateSessionFactory;         this.sessionManager = sessionManager;         this.securityManager = securityManager;         this.resourceManager = new ResourceManager();         this.documentManager = documentManager;          this.baseRequestExtractor = new BaseRequestExtractor();         this.editContentRequestExtractor = new EditContentRequestExtractor();         this.entityRequestExtractor = new EntityRequestExtractor();         this.entityWithViolationsRequestExtractor = new EntityWithViolationsRequestExtractor();         this.requestWithAttachmentsExtractor = new RequestWithAttachmentsExtractor();          this.baseResponsePacker = new BaseResponsePacker();         this.objectResponsePacker = new ObjectResponsePacker(resourceManager);         this.sessionCloseResponsePacker = new SessionCloseResponsePacker(resourceManager);         this.sessionOpenResponsePacker = new SessionOpenResponsePacker(resourceManager);      }      public static MainServletEnvironment create() {         boolean result;         SessionFactory hibernateSessionFactory = null;         SessionManager sessionManager = null;         SecurityManager securityManager = null;         DocumentManager documentManager = null;         try {             hibernateSessionFactory = HibernateSessionFactory.getSessionFactory();             sessionManager = new SessionManager();             securityManager = new SecurityManager(hibernateSessionFactory, sessionManager);             documentManager = new DocumentManager(hibernateSessionFactory, sessionManager);             result = securityManager.init();             } catch (Exception e) {                 e.printStackTrace();                 result = false;             }             return result ? new MainServletEnvironment(hibernateSessionFactory, sessionManager, securityManager, documentManager): null;         } }<\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Apache Tomcat. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 <em>handlers<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 <em>core<\/em>. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 <em>dbclasses<\/em> \u0438 <em>db<\/em>, \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/722\/be5\/bd6\/722be5bd66797c3f758979addb422496.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" width=\"1042\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/722\/be5\/bd6\/722be5bd66797c3f758979addb422496.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4 \u2013 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e (<em>CVServer <\/em>\u043d\u0430 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0430 4) \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u0430\u0441\u0441 <em>RecognizeTextClient <\/em>\u043f\u0430\u043a\u0435\u0442\u0430 <em>core<\/em>. \u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u043e\u0442\u0432\u0435\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 http. \u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <em>RecognizeTextClient<\/em>:<\/p>\n<pre><code class=\"java\">import classes.RecognitionDocument; import core.recognitionClient.handlers.TextRecognitionHandler;  import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects;  \/**  * \u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 pdf \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430  *\/ public class RecognizeTextClient {     private static final String SERVER_IP = \"127.0.0.1\";     private static final int SERVER_PORT = 10000;     private static final int RequestCodeLength = 3;     private static final int RequestBodyLength = 8;     private static final int ResponseHeaderLength = 10;     private final String requestHeaderMask;     private final TextRecognitionHandler textRecognitionHandler;     private Socket clientSocket;     private InputStream in;     private OutputStream out;      public RecognizeTextClient(){         requestHeaderMask = String.format(\"%%0%dd%%0%dd\", RequestCodeLength, RequestBodyLength);         textRecognitionHandler = new TextRecognitionHandler();     }      private boolean connect() {         try {             clientSocket = new Socket(SERVER_IP, SERVER_PORT);             in = clientSocket.getInputStream();             out = clientSocket.getOutputStream();         } catch (IOException ignored) {             clientSocket = null;         }         return clientSocket != null;     }     private void disconnect() {         if(clientSocket != null) {             try{                 in.close();                 out.close();                 clientSocket.close();             } catch (IOException ignored) {             }         }         clientSocket = null;     }     private String writeRequestReadResponse(int requestCode, String request) throws IOException {         byte[] requestBody = request.getBytes(StandardCharsets.UTF_8);         String requestHeaderStr = String.format(requestHeaderMask, requestCode, requestBody.length);         byte[] requestHeader = requestHeaderStr.getBytes(StandardCharsets.UTF_8);         byte[] responseHeader = new byte[ResponseHeaderLength];         byte[] responseBody;         String response;          out.write(requestHeader);         out.write(requestBody);         out.flush();          readNBytes(responseHeader, ResponseHeaderLength);         String responseHeaderStr = new String(responseHeader, StandardCharsets.UTF_8);         int responseBodyLength = Integer.parseInt(responseHeaderStr);         if(responseBodyLength != 0 ) {             responseBody = new byte[responseBodyLength];             readNBytes(responseBody, responseBodyLength);             response = new String(responseBody, StandardCharsets.UTF_8);         }else {             response = \"\";         }          return response;     }     private void readNBytes(byte[] b, int len) throws IOException {         Objects.requireNonNull(b);         if (len &lt; 0 || len > b.length)             throw new IndexOutOfBoundsException();         int n = 0;         while (n &lt; len) {             int count = in.read(b, n, len - n);             if (count &lt; 0)                 break;             n += count;         }     }     private String executeOperation(int operationCode, String operationParameters) {         String response = null;         if(connect()) {             try{                 response = writeRequestReadResponse(operationCode, operationParameters);             } catch (IOException ignored) {             }         }         disconnect();         return response;     }      public boolean recognitionText(List&lt;byte[]> inputDocument, RecognitionDocument calculateResult) {         String parameters = textRecognitionHandler.getRequestParameters(inputDocument);         String response = executeOperation(CalculateServerRequestCode.RECOGNIZE_TEXT, parameters);         if(!textRecognitionHandler.parseResponse(response)) return false;         calculateResult.setValue(textRecognitionHandler.getInfos());         return textRecognitionHandler.getResult();     }      public boolean recognitionAudio(List&lt;byte[]> inputDocument, RecognitionDocument calculateResult) {         String parameters = textRecognitionHandler.getRequestParameters(inputDocument);         String response = executeOperation(CalculateServerRequestCode.RECOGNIZE_AUDIO, parameters);         if(!textRecognitionHandler.parseResponse(response)) return false;         calculateResult.setValue(textRecognitionHandler.getInfos());         return textRecognitionHandler.getResult();     } }<\/code><\/pre>\n<p>\u0412 \u043f\u0430\u043a\u0435\u0442\u0435 validators \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 \u0444\u043e\u0440\u043c\u044b \u043f\u0440\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a \u043e\u0442\u043c\u0435\u0447\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Hibernate. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d \u043a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <em>SessionFactory<\/em>\u00a0(\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445). \u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <em>HibernateSessionFactory<\/em>:<\/p>\n<pre><code class=\"java\">package db;  import dbclasses.*; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration;  \/**  * \u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f SessionFactory.  *\/ public class HibernateSessionFactory {      private static volatile SessionFactory sessionFactory; \/\/\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0441\u0435\u0441\u0441\u0438\u044f\u043c\u0438 (\u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0441\u0435\u0441\u0441\u0438\u0439)      private static final Object sessionFactoryLock = new Object();      public static SessionFactory getSessionFactory() {         if (sessionFactory == null)         {             synchronized(sessionFactoryLock)             {                 if (sessionFactory == null)                 {                     try                     {                         Configuration configuration = new Configuration().configure();                          configuration.addAnnotatedClass(User.class);                         configuration.addAnnotatedClass(Role.class);                         configuration.addAnnotatedClass(UserRole.class);                         configuration.addAnnotatedClass(Document.class);                          StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());                         sessionFactory = configuration.buildSessionFactory(builder.build());                     }                     catch (Exception e)                     {                         System.out.println(\"\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435!\" + e);                     }                 }             }         }         return sessionFactory;     } }<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043a\u043b\u0430\u0441\u0441\u0435 <em>HibernateSessionFactory<\/em> \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u044b-\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e <em>Document<\/em>. \u041a\u043b\u0430\u0441\u0441-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 <em>MainServlet <\/em>(\u0440\u0438\u0441\u0443\u043d\u043e\u043a 4), \u043d\u043e\u0441\u0438\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <em>DocumentsHandler:<\/em><\/p>\n<pre><code class=\"java\">package handlers;  import classes.*; import core.SessionManager; import core.documentManager.DocumentManager; import core.interaction.Request; import core.interaction.RequestHandlerContainer; import core.interaction.Response; import core.interaction.ResponseRecipient; import core.interaction.requests.RequestWithAttachments; import core.interaction.responses.ObjectResponse; import core.recognitionClient.RecognizeTextClient; import dbclasses.Document;  import java.nio.charset.StandardCharsets; import java.time.Clock; import java.util.List; import java.util.Objects;  public class DocumentsHandler extends RequestHandlerContainer {     private final SessionManager sessionManager;     private final DocumentManager documentManager;      public DocumentsHandler(SessionManager sessionManager, DocumentManager documentManager) {         super();         this.sessionManager = sessionManager;         this.documentManager = documentManager;         register(RequestCode.RECOGNIZE_DOCUMENT.toString(), this::DocumentRecognize);         register(RequestCode.RECOGNIZE_AUDIO_DOCUMENT.toString(), this::AudioDocumentRecognize);         register(RequestCode.SAVE_DOCUMENT.toString(), this::DocumentSave);     }      private boolean DocumentRecognize(ResponseRecipient responseRecipient, Request requestBase) {         RequestWithAttachments request = (RequestWithAttachments) requestBase;         boolean result;          Session session = sessionManager.getSession(request.sessionID);         session.lastActivityTime = Clock.systemDefaultZone().instant();          RecognizeTextClient recognizeTextClient = new RecognizeTextClient();         RecognitionDocument calculateResult = new RecognitionDocument();          result = recognizeTextClient.recognitionText(request.attachments, calculateResult);         Response response = new ObjectResponse(request.code, request.sessionID, result, calculateResult);          if (responseRecipient != null) {             responseRecipient.ReceiveResponse(response);         }         return result;     }      private boolean AudioDocumentRecognize(ResponseRecipient responseRecipient, Request requestBase) {         RequestWithAttachments request = (RequestWithAttachments) requestBase;         boolean result;          Session session = sessionManager.getSession(request.sessionID);         session.lastActivityTime = Clock.systemDefaultZone().instant();          RecognizeTextClient recognizeTextClient = new RecognizeTextClient();         RecognitionDocument calculateResult = new RecognitionDocument();          result = recognizeTextClient.recognitionAudio(request.attachments, calculateResult);         Response response = new ObjectResponse(request.code, request.sessionID, result, calculateResult);          if (responseRecipient != null) {             responseRecipient.ReceiveResponse(response);         }         return result;     }      private boolean DocumentSave(ResponseRecipient responseRecipient, Request requestBase) {         RequestWithAttachments request = (RequestWithAttachments) requestBase;         boolean result = false;          Session session = sessionManager.getSession(request.sessionID);         session.lastActivityTime = Clock.systemDefaultZone().instant();          byte[] filepdf = request.attachments.get(0);         byte[] filetext = request.attachments.get(1);         String titleOfDocument = new String(request.attachments.get(2), StandardCharsets.UTF_8);          String[] userIDs = new String[] {session.currentUserID};          Document document = new Document();         if(session != null) {             for (String userID : userIDs) {                 if (Objects.equals(userID, session.currentUserID)) {                     document.setUserID(userID);                     document.setTitle(titleOfDocument);                     document.setFilepdf(filepdf);                     document.setFiletext(filetext);                     result = saveDocument(document, result);                 }             }         }         Response response = new Response(request.code, request.sessionID, result);          if (responseRecipient != null) {             responseRecipient.ReceiveResponse(response);         }          return result;     }      private boolean saveDocument(Document entity, boolean result) {         if (entity!=null){             try{                 documentManager.save(entity);                 result = true;             }             catch(Exception e) {                 e.printStackTrace();                 result = false;             }         }         return result;     }      private boolean DocumentInfoID(ResponseRecipient responseRecipient, Request request, String sessionID, String[] userIDs, String ID) {         boolean result;         List&lt;Document>  documents = documentManager.getDocumentByID(sessionID, userIDs, ID);         DocumentsInfo view = new DocumentsInfo(documents);         result = documents.size() != 0;          ObjectResponse response = new ObjectResponse(request.code, request.sessionID, result, view);          if (responseRecipient != null) {             responseRecipient.ReceiveResponse(response);         }         return true;     } }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0441\u0441-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (RECOGNIZE_DOCUMENT, RECOGNIZE_AUDIO_DOCUMENT, SAVE_DOCUMENT), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043a\u043b\u0430\u0441\u0441 <em>RecognizeTextClient<\/em> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0442\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 <em>DocumentManager <\/em>\u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 core (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 4):<\/p>\n<pre><code class=\"java\">package core.documentManager;  import classes.Session; import core.CommonUtils; import core.SessionManager; import db.DocumentManagerService; import dbclasses.Document;  import java.util.*;  \/**  * \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e Document  *\/ public class DocumentManager {     private final DocumentManagerService service;     private final SessionManager sessionManager;     private final DocumentManagerData data;      public DocumentManager(org.hibernate.SessionFactory hibernateSessionFactory, SessionManager sessionManager) {         this.sessionManager = sessionManager;         this.service = new DocumentManagerService(hibernateSessionFactory);         this.data = new DocumentManagerData();     }      public boolean init() {         boolean result = true;          service.getData(data);         if (data==null){             result = false;         }         return result;     }       public List&lt;Document> getDocuments(String currentSessionID, String[] ids) {         List&lt;Document> result = new ArrayList&lt;>();         Session session = sessionManager.getSession(currentSessionID);         List&lt;String> userIDs = new ArrayList&lt;>();         if(ids == null || ids.length == 0) {             userIDs.add(session.currentUserID);         } else {             Collections.addAll(userIDs, ids);         }         if(session != null) {             for(String userID : userIDs) {                 if(Objects.equals(userID, session.currentUserID)) {                     service.getDataByUserID(data,userID);                     result.addAll(data.documents);                 }             }         }         return result;     }      public List&lt;Document> getDocumentByID(String currentSessionID, String[] ids, String id) {         List&lt;Document> result = new ArrayList&lt;>();         Session session = sessionManager.getSession(currentSessionID);         List&lt;String> userIDs = new ArrayList&lt;>();         if(ids == null || ids.length == 0) {             userIDs.add(session.currentUserID);         } else {             Collections.addAll(userIDs, ids);         }         if(session != null) {             for(String userID : userIDs) {                 if(Objects.equals(userID, session.currentUserID)) {                     service.getDataByID(data,id);                     result.addAll(data.documents);                 }             }         }         return result;     }       public void save(Document document) {         document.setId(CommonUtils.createID());          service.createDocument(document);     } } <\/code><\/pre>\n<p><em>DocumentManager <\/em>\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430 Document, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043b\u0430\u0441\u0441 <em>DocumentManagerData:<\/em><\/p>\n<pre><code class=\"java\">package core.documentManager;  import dbclasses.Document;   import java.util.ArrayList; import java.util.List;   \/**  * \u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432  *\/ public class DocumentManagerData {     public final List&lt;Document> documents;      public DocumentManagerData() {         documents = new ArrayList&lt;>();     }      public void clear() {         documents.clear();     } }<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 <em>DocumentManager <\/em>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441-\u0441\u0435\u0440\u0432\u0438\u0441 <em>DocumentManagerService<\/em> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439.   <\/p>\n<pre><code class=\"java\">package db;  import core.documentManager.DocumentManagerData; import dbclasses.Document; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.query.Query;  import java.util.List;  public class DocumentManagerService {     private final SessionFactory sessionFactory;      public DocumentManagerService(SessionFactory sessionFactory) {         this.sessionFactory = sessionFactory;     }      public void getData(DocumentManagerData data) {         data.clear();         Session session = sessionFactory.openSession();         Transaction transaction = session.beginTransaction();         try {             data.documents.addAll(session.createQuery(\"SELECT row FROM Document row\", Document.class).list());             transaction.commit();         } catch (Exception e) {             transaction.rollback();             throw e;         } finally {             session.close();         }     }      public void getDataByUserID(DocumentManagerData data, String id) {         data.clear();         Session session = sessionFactory.openSession();         Transaction transaction = session.beginTransaction();         try {             data.documents.addAll(session.createQuery(\"SELECT row FROM Document row WHERE row.userID= : userID\", Document.class).                 setParameter(\"userID\", id).                 list());             transaction.commit();         } catch (Exception e) {             transaction.rollback();             throw e;         } finally {             session.close();         }     }      public void getDataByID(DocumentManagerData data, String id) {         data.clear();         Session session = sessionFactory.openSession();         Transaction transaction = session.beginTransaction();         try {             data.documents.addAll(session.createQuery(\"SELECT row FROM Document row WHERE row.id= : id\", Document.class).                     setParameter(\"id\", id).                     list());             transaction.commit();         } catch (Exception e) {             transaction.rollback();             throw e;         } finally {             session.close();         }     }      public void createDocument(Document document) {         Session session = sessionFactory.openSession();         Transaction transaction = session.beginTransaction();         try {             session.persist(document);             transaction.commit();         } catch (Exception e) {             transaction.rollback();             throw e;         } finally {             session.close();         }     } }<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430-\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 Document:<\/p>\n<pre><code class=\"java\">package dbclasses;  import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Table;  @Entity @Table(name = \"Documents\") public class Document extends ObjectWithID {      @Column(name = \"userid\")     private String userID;      @Column(name = \"title\")     private String title;      @Column(name = \"filepdf\")     private byte[] filepdf;      @Column(name = \"filetext\")     private byte[] filetext;      public String getUserID() {         return userID;     }      public void setUserID(String userID) {         this.userID = userID;     }      public String getTitle() {         return title;     }      public void setTitle(String title) {         this.title = title;     }      public byte[] getFilepdf() {         return filepdf;     }      public void setFilepdf(byte[] filepdf) {         this.filepdf = filepdf;     }      public byte[] getFiletext() {         return filetext;     }      public void setFiletext(byte[] filetxt) {         this.filetext = filetxt;     } }<\/code><\/pre>\n<p>\u0412\u0435\u0441\u044c \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 web (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 3) \u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043f\u044f\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 HTML, \u0437\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0432\u0438\u0434 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c\u0438 \u0444\u0430\u0439\u043b\u044b CSS, \u0437\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0444\u0430\u0439\u043b\u044b \u043d\u0430 JavaScript. \u041e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 AJAX, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432 \u0431\u0443\u0444\u0435\u0440\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 NetworkClient, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 (\u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 NetworkClient \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b). <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 NetworkClient \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">export default class NetworkClient {      constructor(parent) {         this._parent = parent;         this._serverUrl = 'handler';         this._defaultTimeout = 30000; \/\/\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a     } #executeCommand(commandName, commandParameters, onSuccess, onError) {     let query = {         method: 'POST',         url: this._serverUrl,         timeout: this._defaultTimeout,         context: this._parent,         success: onSuccess,         error: onError     };      let parameters = commandParameters;     if (parameters instanceof FormData) {         parameters.append(\"cmd\", commandName);         query.data = parameters;         query.processData = false;         query.contentType = false;     } else {         parameters.cmd = commandName;         query.data = parameters;     }      $.ajax(query); } commandLogin(username, password, onSuccess, onError) {     let command = \"SESSION_OPEN\";     let commandParameters = {\"id\": username.trim(), \"string\": md5(password.trim())};     this.#executeCommand(command, commandParameters, onSuccess, onError); }<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <em>commandLogin<\/em> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043b\u043e\u0433\u0438\u043d \u0438 \u043f\u0430\u0440\u043e\u043b\u044c), \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u00abSESSION_OPEN\u00bb \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434 <em>executeCommand<\/em> (\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b). \u0412 <em>executeCommand<\/em> \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f POST \u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c AJAX \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0434\u0430\u043b\u0435\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0445\u043e\u0434\u044f\u0442 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434, \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<h2>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0442\u043e\u0433\u0430 &#8212; \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   <\/h2>\n<p>\u041f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043a\u0440\u0430\u0442\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0435\u0435\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, <em>startform.html<\/em> (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 5). \u041a\u0440\u043e\u043c\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 Python &#8212; \u0444\u0430\u0439\u043b <em>cvserver.py<\/em>.   <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/924\/256\/37d\/92425637db4b2b19721451639efc47d0.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5 \u2013 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5 \u2013 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" width=\"1920\" height=\"1061\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/924\/256\/37d\/92425637db4b2b19721451639efc47d0.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5 \u2013 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u043e \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043b\u0438\u0431\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043b\u0438\u0431\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 6).    <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e8c\/bbd\/513\/e8cbbd5130a61c887360d7a67e98ba9c.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6 \u2013 \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6 \u2013 \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438\" width=\"1399\" height=\"767\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e8c\/bbd\/513\/e8cbbd5130a61c887360d7a67e98ba9c.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6 \u2013 \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430 (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 7), \u0433\u0434\u0435 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0444\u043e\u0440\u043c\u0430\u0442\u0430 *.pdf \u0438\u043b\u0438 *.wav. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/968\/277\/0d6\/9682770d6f68cc494eb8da03b57a6414.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7 \u2013 \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7 \u2013 \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430\" width=\"1725\" height=\"962\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/968\/277\/0d6\/9682770d6f68cc494eb8da03b57a6414.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7 \u2013 \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f, \u043e\u043d\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435, \u043b\u0438\u0431\u043e \u0432 \u0432\u0438\u0434\u0435 PDF (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 8), \u043b\u0438\u0431\u043e \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044f \u0437\u0432\u0443\u043a\u0430 (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 9).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b46\/6df\/c0a\/b466dfc0a563d78c98632142c73e2d95.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 pdf \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 pdf \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435\" width=\"1725\" height=\"962\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b46\/6df\/c0a\/b466dfc0a563d78c98632142c73e2d95.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 pdf \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u0435\u043d\u044e \u00ab\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c\u00bb \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 8). \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0441 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u0434\u0430\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/314\/973\/052\/314973052fbc3ca0da22c4eda36beb25.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u0430\u0443\u0434\u0438\u043e \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u0430\u0443\u0434\u0438\u043e \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f\" width=\"1725\" height=\"962\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/314\/973\/052\/314973052fbc3ca0da22c4eda36beb25.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9 \u2013 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u0430\u0443\u0434\u0438\u043e \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u00ab\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439\u00bb \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f (\u0440\u0438\u0441\u0443\u043d\u043e\u043a 10).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8a8\/04f\/af9\/8a804faf9c6dee35d056ff68bb4ae388.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10 \u2013 \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10 \u2013 \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" width=\"1573\" height=\"962\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8a8\/04f\/af9\/8a804faf9c6dee35d056ff68bb4ae388.png\"\/><\/p>\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10 \u2013 \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043b\u0438\u0447\u043d\u043e \u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0435\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c. <\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ol>\n<li>\n<p>LeCun, Y. Gradient-based learning applied to document recognition \/ Y. LeCun, L. Bottou, Y. Bengio, P. Haffner \/\/ Proceedings of the IEEE. \u2013 1998. \u2013 Vol. 86, Issue 11. \u2013 P. 2278-2323.<\/p>\n<\/li>\n<li>\n<p>. Rabiner, L.R. A tutorial on hidden Markov models and selected applications in speech recognition \/ L.R. Rabiner \/\/ Proceedings of the IEEE. \u2013 1989. \u2013 Vol. 77, issue 2. \u2013 P. 257 &#8212; 286.<\/p>\n<\/li>\n<li>\n<p>Hochreiter S. Long Short-term Memory \/ S. Hochreiter, J. Schmidhuber \/\/ Neural Computation. \u2013 1997. \u2013 Vol. 9, no. 8. \u2013 P. 1735-80.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/758882\/\"> https:\/\/habr.com\/ru\/articles\/758882\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u043b\u0438\u0441\u0442\u0430 \u0438\u043b\u0438 \u0438\u0437 \u0430\u0443\u0434\u0438\u043e\u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2013 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0430\u044f\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432 \u043e\u0444\u0438\u0441\u0430\u0445 \u0438\u043b\u0438 \u0443\u0447\u0451\u0431\u044b. \u0414\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0438 \u0430\u0443\u0434\u0438\u043e \u0432 \u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b, \u043a\u0430\u043a \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0435 \u0437\u0440\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0447\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439.     <\/p>\n<p>\u0414\u0435\u0442\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 (\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435) \u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 [1]. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0445 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u044b\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u044f\u0447\u0435\u0435\u043a \u0434\u043e\u043b\u0433\u043e\u0439 \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 LSTM [2]. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438, \u044d\u0442\u0430\u043f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.    <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043b\u0438\u0441\u0442\u0430 \u0438\u043b\u0438 \u0430\u0443\u0434\u0438\u043e-\u0444\u0430\u0439\u043b\u0430.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0441\u0442\u0435\u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439<\/h2>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1 \u2013 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   <\/figcaption><\/div>\n<\/figure>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440, \u0432 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 MVC (Model-View-Controller). \u0412\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0442\u0440\u0451\u0445 \u0432\u0438\u0434\u043e\u0432: \u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u0422\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u0438, \u0437\u0430 \u0441\u0447\u0451\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.   <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u043e\u0434 \u043c\u043e\u0434\u0443\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 Java Script, \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Google Chrome. \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432\u0445\u043e\u0434\u044f\u0442: \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u043b\u0430\u0441\u044c \u043d\u0430 Windows.    <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f Java Servlet.   <\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d \u0432\u0435\u0431 \u0441\u0435\u0440\u0432\u0435\u0440 Apache Tomcat, \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e, \u0433\u0438\u0431\u043a\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, Apache Tomcat \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u0430\u0442\u0440\u0430\u0442 \u043d\u0430 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 http (\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0430 \u041f\u041a).   <\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0430\u0443\u0434\u0438\u043e-\u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438 \u0438\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b\u044b (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0444\u0430\u0439\u043b\u044b *.docx). \u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Python \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 OpenCV \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 TensorFlow. <\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0421\u0423\u0411\u0414) PostgreSQL. \u041f\u043b\u044e\u0441\u0430\u043c\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0431\u044b\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (IDE) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438. \u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u043d\u0430 Python \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f PyCharm, \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b &#8212; IntelliJ IDEA; \u043e\u0431\u0435 IDE \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439 JetBrains, \u043f\u043e\u0445\u043e\u0436\u0438 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c\u0438. <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/vadimpechenin\/RecognizingTextFromImageApp.git\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>, \u0434\u0430\u043b\u0435\u0435 \u0440\u0430\u0441\u043a\u0440\u043e\u044e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0438 \u0430\u0443\u0434\u0438\u043e \u0444\u0430\u0439\u043b\u043e\u0432   <\/h2>\n<p>\u0414\u043b\u044f\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f OCR\u00a0\u2014 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043d\u0430\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u00a0\u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u044c. \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0442\u0435\u043a\u0441\u0442, \u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0432\u00a0\u043d\u0435\u043c. \u041f\u043e\u0441\u043b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0438\u043c\u0432\u043e\u043b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0\u043c\u0430\u0448\u0438\u043d\u043d\u043e\u2011\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. <\/p>\n<p>\u0414\u043b\u044f\u00a0\u0446\u0435\u043b\u0435\u0439 OCR \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043f\u0430\u043a\u0435\u0442 <em>PyTesseract<\/em>, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043e\u0431\u043e\u043b\u043e\u0447\u043d\u043e\u0439 \u0434\u043b\u044f\u00a0Google Tesseract\u2011OCR Engine. Tesseract \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438 \u0438 \u0434\u0432\u0443\u0445\u0441\u0442\u0443\u043f\u0435\u043d\u0447\u0430\u0442\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a\u00a0\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044e. \u0412\u00a0\u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u041d\u0430\u00a0\u0432\u0442\u043e\u0440\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043b\u044e\u0431\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043d\u0438\u0437\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438 \u043f\u043e\u00a0\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443. \u042d\u0442\u0430\u043f\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u00a0\u0431\u0430\u0437\u0435 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0439 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 LSTM, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0434\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u041f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u0444\u043e\u0440\u043c\u0430\u0442\u0435 PDF \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u0437\u00a0\u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u00a0\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043f\u0430\u043c\u044f\u0442\u044c \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>fitz<\/em>. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f\u00a0\u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"python\">import fitz  @staticmethod def __getPDF(dictOfProject, parameters):     for imageFromList in dictOfProject['InputDocument']:         byteImage = bytes.fromhex(imageFromList)         fileName = str(parameters.imagesFolder.joinpath('example.pdf').resolve())         file = open(fileName, 'wb')         file.write(byteImage)         file.close()         pdfDocument = fitz.open(fileName)      return pdfDocument<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 PNG, \u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>pytesseract<\/em> \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f\u0441\u044c \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>docx<\/em>. <\/p>\n<p>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f OCR:<\/p>\n<pre><code class=\"python\">import os import docx import cv2  @staticmethod def __recognitionText(pdfDocument, parameters):     mydoc = docx.Document()     for current_page in range(len(pdfDocument)):         for image in pdfDocument.get_page_images(current_page):             xref = image[0]             fileName = str(parameters.imagesFolder.joinpath(\"page%s-%s.png\" % (current_page, xref)).resolve())             # \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenCV             ConvertPdfToTextCalculator.__takeImage(parameters.pytesseract, mydoc,fileName)     pdfDocument.close()     return mydoc  @staticmethod def __takeImage(pytesseract, mydoc,fileName):     image = cv2.imread(fileName)     # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443     pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'     string = pytesseract.image_to_string(image, lang='rus')     # \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442     mydoc.add_paragraph(string)<\/code><\/pre>\n<p>\u0414\u043b\u044f\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0430\u0443\u0434\u0438\u043e\u00a0\u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Speech Recognition (\u0432 \u043a\u043e\u0434\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043a\u0430\u043a <em>sr<\/em>), \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043a\u0440\u044b\u0442\u043e\u0439 \u043c\u0430\u0440\u043a\u043e\u0432\u0441\u043a\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 [3] \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f\u00a0\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0440\u0435\u0447\u0435\u0432\u044b\u0445 API (\u043c\u043d\u043e\u0439\u00a0\u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d Google Speech). \u0414\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0437\u0432\u0443\u043a\u043e\u043c \u043a\u0430\u043a\u00a0\u0441\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0438 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0438 \u0435\u0433\u043e \u043d\u0430\u00a0\u043e\u0442\u0440\u0435\u0437\u043a\u0438 \u043f\u043e\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443 \u0442\u0438\u0448\u0438\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <em>pydub<\/em>, \u0430\u00a0\u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043b\u0430\u0441\u0441 <em>AudioSegment<\/em> \u0438 \u043c\u0435\u0442\u043e\u0434 <em>split_on_silence<\/em>. <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <em>AudioSegment:<\/em><\/p>\n<pre><code class=\"python\">@staticmethod def __getWav(dictOfProject, parameters):     for imageFromList in dictOfProject['InputDocument']:         byteFile = bytes.fromhex(imageFromList)         fileName = str(parameters.imagesFolder.joinpath('example.wav').resolve())         file = open(fileName, 'wb')         file.write(byteFile)         file.close()         sound = parameters.AudioSegment.from_wav(fileName)      return sound<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0430 \u0437\u0432\u0443\u043a\u0438, \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u0448\u0438\u043d\u043e\u0439:<\/p>\n<pre><code class=\"python\">@staticmethod def __getSounds(soundDocument, parameters):     chunks = parameters.split_on_silence(soundDocument,                                                              min_silence_len=500,                                                              silence_thresh=soundDocument.dBFS - 15,                                                              keep_silence=500,                               )     return chunks<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"python\">def __recognitionSound(chunks, parameters):     mydoc = docx.Document()     r = parameters.sr.Recognizer()          for i, audio_chunk in enumerate(chunks, start=1):                  chunk_filename = os.path.join(parameters.imagesFolder, f\"chunk{i}.wav\")         audio_chunk.export(chunk_filename, format=\"wav\")         start_time = datetime.now()         print(datetime.now() - start_time)                  with parameters.sr.AudioFile(chunk_filename) as source:             audio_listened = r.record(source)                          try:                 text = r.recognize_google(audio_listened, language=parameters.language)             except parameters.sr.UnknownValueError as e:                 print(\"Error:\", str(e))             else:                 text = f\"{text.capitalize()}. \"                 print(\" -- :\", text)                 mydoc.add_paragraph(text)         print(\"\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: \")         print(datetime.now() - start_time)     return mydoc<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b\u044b *.pdf \u0438\u043b\u0438 *.wav \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0441\u043e\u043a\u0435\u0442\u043e\u0432. \u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <em>NetworkServer<\/em>. <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0437\u0430\u043f\u0443\u0441\u043a\u0430 cvserver.py \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">import keyboard from core.clientServer.networkServer import NetworkServer  if __name__ == '__main__':     server = NetworkServer()     port = 10000     server.init(port)     server.start()     print(\"\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430!\")     print(\"\u0414\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 q\")     keyboard.wait(\"q\")     server.stop()     server.done()     print(\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430\")<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 NetworkServer:<\/p>\n<pre><code class=\"python\">import socket from threading import Thread  from core.clientsManager import ClientsManager from core.clientServer.clientHandler import ClientHandler from core.requests.requestFactory import RequestFactory   class NetworkServer(object):     def __init__(self):         self._socket = None         self._continueWork = False         self._thread = None         self._clientsManager = ClientsManager()         self._requestFactory =<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-353985","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/353985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=353985"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/353985\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=353985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=353985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=353985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}