FEAT: Python permanece rodando em loop sem a necessidade de um cron job

This commit is contained in:
Rafael Alves Lopes 2025-10-30 07:04:21 -03:00
parent ae303e58fe
commit ee168f5d5a
3 changed files with 92 additions and 455 deletions

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
psycopg2-binary
mysql-connector-python
python-dotenv
pandas

View File

@ -1,370 +0,0 @@
[
{
"sys_id": "00ed542efbd4fe1023e5f8d65eefdc9b",
"sys_created_on": "2025-10-02 23:52:10",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "NOVO\n\nTESTE\n\nPARA \n\nVERIFICAR\n\nHTML\n\nNO \n\nCOMENTARIO\n\nTestando parágrafo\n\n**Testando negrito (B)**\n\n***Testando Italico (I)***\n\n> \r\n***Testando Blockquote***\n\nTestando DIV\n\nTestando alinhamento",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "05d54e5afb1cbe1023e5f8d65eefdc94",
"sys_created_on": "2025-10-02 12:47:52",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Vai ter como sim, podemos ver</p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "068c5caafbd4fe1023e5f8d65eefdccf",
"sys_created_on": "2025-10-02 23:46:18",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Testando a inserção de imagens</p>\r\n<p><a href=\"/front/document.send.php?docid=82186&itemtype=Ticket&items_id=33776\" target=\"_blank\" ><img alt=\"cb4c1e7e-ba446868-68df0a7d462e59.15008476\" width=\"1197\" src=\"/front/document.send.php?docid=82186&itemtype=Ticket&items_id=33776\" /></a></p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "16954a5afb1cbe1023e5f8d65eefdcdf",
"sys_created_on": "2025-10-02 12:46:51",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "1b1dd182fbd8fe50ef1ffe316eefdc5f",
"sys_created_on": "2025-10-01 15:11:30",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "2a5d15c2fb187e1023e5f8d65eefdce3",
"sys_created_on": "2025-10-01 15:12:31",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "2bdd542efbd4fe1023e5f8d65eefdc1f",
"sys_created_on": "2025-10-02 23:52:08",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "Mais um teste para remoção de html no comentario. \n\nTestando parágrafo\n\n**Testando negrito (B)**\n\n***Testando Italico (I)***\n\n> \r\n***Testando Blockquote***\n\nTestando DIV\n\nTestando alinhamento",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "35954a96fb107290ef1ffe316eefdc85",
"sys_created_on": "2025-10-02 12:46:50",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "3d68102afbd87290ef1ffe316eefdc69",
"sys_created_on": "2025-10-02 23:28:15",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47141, content=&#60;p&#62;Testando a inserção de imagens&#60;/p&#62;\r\n&#60;p&#62;&#60;a href=\"/front/document.send.php?docid=82186&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68df0a7d462e59.15008476\" width=\"1197\" src=\"/front/document.send.php?docid=82186&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;, date=2025-10-02T23:27:59.000Z, date_creation=2025-10-02T23:27:59.000Z, date_mod=2025-10-02T23:27:59.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "3e8c9caafbd4fe1023e5f8d65eefdca1",
"sys_created_on": "2025-10-02 23:46:21",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Teste Comentario Limpo</p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "41d58e96fb107290ef1ffe316eefdc6a",
"sys_created_on": "2025-10-02 12:47:53",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "4a3b14eafbd87290ef1ffe316eefdcc1",
"sys_created_on": "2025-10-02 23:40:35",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47145, content=&#60;p&#62;NOVO&#60;/p&#62;\r\n&#60;p&#62;&#60;br&#62;&#60;br&#62;TESTE&#60;br&#62;&#60;br&#62;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;PARA&#38;nbsp;&#60;br&#62;&#60;br&#62;&#60;br&#62;&#60;br&#62;&#60;br&#62;VERIFICAR&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;HTML&#60;br&#62;&#60;br&#62;&#60;br&#62;NO&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;COMENTARIO&#60;br&#62;&#60;br&#62;&#60;br&#62;&#60;/p&#62;\r\n&#60;p&#62;Testando&#38;nbsp; parágrafo&#60;/p&#62;\r\n&#60;p&#62;&#60;strong&#62;Testando negrito (B)&#60;/strong&#62;&#60;/p&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Italico (I)&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;blockquote&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Blockquote&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;div&#62;Testando DIV&#60;/div&#62;\r\n&#60;div&#62;&#38;nbsp;&#60;/div&#62;\r\n&#60;div style=\"text-align: justify;\"&#62;Testando alinhamento&#60;/div&#62;\r\n&#60;/blockquote&#62;\r\n&#60;p&#62;&#60;br&#62;&#60;br&#62;&#60;br&#62;&#60;/p&#62;, date=2025-10-02T23:40:13.000Z, date_creation=2025-10-02T23:40:13.000Z, date_mod=2025-10-02T23:40:13.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "4b71142efb94fe1023e5f8d65eefdca6",
"sys_created_on": "2025-10-02 22:58:01",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47139, content=&#60;p&#62;Comentário teste, para validar funcionamento do Midware&#60;/p&#62;, date=2025-10-02T22:44:22.000Z, date_creation=2025-10-02T22:44:22.000Z, date_mod=2025-10-02T22:44:22.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "5070ca12fb107290ef1ffe316eefdc28",
"sys_created_on": "2025-10-02 12:24:19",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "Teste fora do código",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "598c5caafbd4fe1023e5f8d65eefdc43",
"sys_created_on": "2025-10-02 23:46:15",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Vai ter como sim, podemos ver</p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "5cb8e9cefb187e1023e5f8d65eefdcb0",
"sys_created_on": "2025-10-01 16:02:05",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "5f16ce5afb1cbe1023e5f8d65eefdcea",
"sys_created_on": "2025-10-02 12:49:07",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "6716829afb1cbe1023e5f8d65eefdc5e",
"sys_created_on": "2025-10-02 12:49:08",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "724825cefb187e1023e5f8d65eefdcd3",
"sys_created_on": "2025-10-01 16:00:20",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "75e3d242fbdcfe50ef1ffe316eefdc6c",
"sys_created_on": "2025-10-01 19:10:53",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "798c1c2efbd87290ef1ffe316eefdc3b",
"sys_created_on": "2025-10-02 23:46:17",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Mais um teste para remoção de html no comentario.&nbsp;</p>\r\n<p>Testando&nbsp; parágrafo</p>\r\n<p><strong>Testando negrito (B)</strong></p>\r\n<p><em><strong>Testando Italico (I)</strong></em></p>\r\n<blockquote>\r\n<p><em><strong>Testando Blockquote</strong></em></p>\r\n<p>&nbsp;</p>\r\n<div>Testando DIV</div>\r\n<div>&nbsp;</div>\r\n<div style=\"text-align: justify;\">Testando alinhamento</div>\r\n</blockquote>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "7bdd542efbd4fe1023e5f8d65eefdc5d",
"sys_created_on": "2025-10-02 23:52:09",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "Comentatradic\n\nzcx\n\nadsgvsdbf\n\nteste\n\nv\n\nszxc\n\na\n\na\n\na\n\na\n\na\n\na\n\na\n\na\n\nTestando parágrafo\n\n**Testando negrito (B)**\n\n***Testando Italico (I)***\n\n> \r\n***Testando Blockquote***\n\nTestando DIV\n\nTestando alinhamento",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "8568ad8efbd8fe50ef1ffe316eefdc7b",
"sys_created_on": "2025-10-01 16:00:46",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "952e98aefbd87290ef1ffe316eefdc69",
"sys_created_on": "2025-10-02 23:53:22",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "COMENTARIO TESTE\n\nTESTE\n\nCOMENTARIO TESTE\n\nTESTE COM IMAGEM:\n\nTestando a inserção de imagens\n\nTestando parágrafo\n\n**Testando negrito (B)**\n\n***Testando Italico (I)***\n\n> \r\n***Testando Blockquote***\n\nTestando DIV\n\nTestando alinhamento",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "9599546afbd87290ef1ffe316eefdcf8",
"sys_created_on": "2025-10-02 23:33:25",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47142, content=&#60;div class=\"rich_text_container\"&#62;\r\n&#60;p&#62;Mais um teste para remoção de html no comentario.&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;Testando&#38;nbsp; parágrafo&#60;/p&#62;\r\n&#60;p&#62;&#60;strong&#62;Testando negrito (B)&#60;/strong&#62;&#60;/p&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Italico (I)&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;blockquote&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Blockquote&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;div&#62;Testando DIV&#60;/div&#62;\r\n&#60;div&#62;&#38;nbsp;&#60;/div&#62;\r\n&#60;div style=\"text-align: justify;\"&#62;Testando alinhamento&#60;/div&#62;\r\n&#60;/blockquote&#62;\r\n&#60;/div&#62;, date=2025-10-02T23:33:11.000Z, date_creation=2025-10-02T23:33:11.000Z, date_mod=2025-10-02T23:33:11.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "9b4786dafb1cbe1023e5f8d65eefdc04",
"sys_created_on": "2025-10-02 12:54:19",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "02/10/2025 09:54:18 - SOTHIS CAOA (Comentários adicionais)\n02/10/2025 09:54:18 - SOTHIS CAOA (Comentários adicionais)\n&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;\n\n\n\n",
"sys_created_by": "admin.caoa",
"element": "comments"
},
{
"sys_id": "9f4786dafb1cbe1023e5f8d65eefdca2",
"sys_created_on": "2025-10-02 12:54:18",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "a25dd582fbd8fe50ef1ffe316eefdce8",
"sys_created_on": "2025-10-01 15:12:33",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "a98c1c2efbd87290ef1ffe316eefdc11",
"sys_created_on": "2025-10-02 23:46:17",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Comentário teste, para validar funcionamento do Midware</p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "ab47c25afb107290ef1ffe316eefdcc3",
"sys_created_on": "2025-10-02 12:54:19",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "ad2c3146fb987e1023e5f8d65eefdc72",
"sys_created_on": "2025-10-01 17:27:05",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "ad8c5caafbd4fe1023e5f8d65eefdc62",
"sys_created_on": "2025-10-02 23:46:16",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>fiz tudo, olha a prova ai:<br><br><a href=\"/front/document.send.php?docid=82185&itemtype=Ticket&items_id=33776\" target=\"_blank\" ><img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&itemtype=Ticket&items_id=33776\" /></a></p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "c027e54efbd8fe50ef1ffe316eefdc47",
"sys_created_on": "2025-10-01 15:55:14",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "c168ad8efbd8fe50ef1ffe316eefdca2",
"sys_created_on": "2025-10-01 16:00:47",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "c28c1c2efbd87290ef1ffe316eefdcb1",
"sys_created_on": "2025-10-02 23:46:19",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<div class=\"rich_text_container\">\r\n<p>Mais um teste para remoção de html no comentario.&nbsp;</p>\r\n<p>Testando&nbsp; parágrafo</p>\r\n<p><strong>Testando negrito (B)</strong></p>\r\n<p><em><strong>Testando Italico (I)</strong></em></p>\r\n<blockquote>\r\n<p><em><strong>Testando Blockquote</strong></em></p>\r\n<p>&nbsp;</p>\r\n<div>Testando DIV</div>\r\n<div>&nbsp;</div>\r\n<div style=\"text-align: justify;\">Testando alinhamento</div>\r\n</blockquote>\r\n</div>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "cbf32d8afb187e1023e5f8d65eefdc64",
"sys_created_on": "2025-10-01 15:41:32",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "cfe25202fbdcfe50ef1ffe316eefdc58",
"sys_created_on": "2025-10-01 19:06:36",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "d18ad4aafbd87290ef1ffe316eefdccc",
"sys_created_on": "2025-10-02 23:37:31",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47144, content=&#60;p&#62;Comentatradic&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;zcx&#60;/p&#62;\r\n&#60;p&#62;adsgvsdbf&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;teste&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;v&#60;/p&#62;\r\n&#60;p&#62;szxc&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;a&#60;/p&#62;\r\n&#60;p&#62;Testando&#38;nbsp; parágrafo&#60;/p&#62;\r\n&#60;p&#62;&#60;strong&#62;Testando negrito (B)&#60;/strong&#62;&#60;/p&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Italico (I)&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;blockquote&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Blockquote&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;div&#62;Testando DIV&#60;/div&#62;\r\n&#60;div&#62;&#38;nbsp;&#60;/div&#62;\r\n&#60;div style=\"text-align: justify;\"&#62;Testando alinhamento&#60;/div&#62;\r\n&#60;/blockquote&#62;, date=2025-10-02T23:37:16.000Z, date_creation=2025-10-02T23:37:16.000Z, date_mod=2025-10-02T23:37:16.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "d8b8e9cefb187e1023e5f8d65eefdca0",
"sys_created_on": "2025-10-01 16:02:05",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "d968d866fbd4fe1023e5f8d65eefdc46",
"sys_created_on": "2025-10-02 23:28:14",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "{id=47140, content=&#60;p&#62;Mais um teste para remoção de html no comentario.&#38;nbsp;&#60;/p&#62;\r\n&#60;p&#62;Testando&#38;nbsp; parágrafo&#60;/p&#62;\r\n&#60;p&#62;&#60;strong&#62;Testando negrito (B)&#60;/strong&#62;&#60;/p&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Italico (I)&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;blockquote&#62;\r\n&#60;p&#62;&#60;em&#62;&#60;strong&#62;Testando Blockquote&#60;/strong&#62;&#60;/em&#62;&#60;/p&#62;\r\n&#60;p&#62;&#38;nbsp;&#60;/p&#62;\r\n&#60;div&#62;Testando DIV&#60;/div&#62;\r\n&#60;div&#62;&#38;nbsp;&#60;/div&#62;\r\n&#60;div style=\"text-align: justify;\"&#62;Testando alinhamento&#60;/div&#62;\r\n&#60;/blockquote&#62;, date=2025-10-02T23:26:44.000Z, date_creation=2025-10-02T23:26:44.000Z, date_mod=2025-10-02T23:26:44.000Z}",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "e31dd182fbd8fe50ef1ffe316eefdc96",
"sys_created_on": "2025-10-01 15:11:31",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;fiz tudo, olha a prova ai:&#60;br&#62;&#60;br&#62;&#60;a href=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" target=\"_blank\" &#62;&#60;img alt=\"cb4c1e7e-ba446868-68d4315d901ec4.10948457\" width=\"1092\" src=\"/front/document.send.php?docid=82185&#38;itemtype=Ticket&#38;items_id=33776\" /&#62;&#60;/a&#62;&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "eaecfd46fb987e1023e5f8d65eefdcab",
"sys_created_on": "2025-10-01 17:30:27",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "ee8c5c2efbd87290ef1ffe316eefdc01",
"sys_created_on": "2025-10-02 23:46:20",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>NOVO</p>\r\n<p><br><br>TESTE<br><br></p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>PARA&nbsp;<br><br><br><br><br>VERIFICAR</p>\r\n<p>&nbsp;</p>\r\n<p>HTML<br><br><br>NO&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>COMENTARIO<br><br><br></p>\r\n<p>Testando&nbsp; parágrafo</p>\r\n<p><strong>Testando negrito (B)</strong></p>\r\n<p><em><strong>Testando Italico (I)</strong></em></p>\r\n<blockquote>\r\n<p><em><strong>Testando Blockquote</strong></em></p>\r\n<p>&nbsp;</p>\r\n<div>Testando DIV</div>\r\n<div>&nbsp;</div>\r\n<div style=\"text-align: justify;\">Testando alinhamento</div>\r\n</blockquote>\r\n<p><br><br><br></p>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "ee8c9caafbd4fe1023e5f8d65eefdc31",
"sys_created_on": "2025-10-02 23:46:19",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "<p>Comentatradic</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>zcx</p>\r\n<p>adsgvsdbf</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>teste</p>\r\n<p>&nbsp;</p>\r\n<p>v</p>\r\n<p>szxc</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>a</p>\r\n<p>Testando&nbsp; parágrafo</p>\r\n<p><strong>Testando negrito (B)</strong></p>\r\n<p><em><strong>Testando Italico (I)</strong></em></p>\r\n<blockquote>\r\n<p><em><strong>Testando Blockquote</strong></em></p>\r\n<p>&nbsp;</p>\r\n<div>Testando DIV</div>\r\n<div>&nbsp;</div>\r\n<div style=\"text-align: justify;\">Testando alinhamento</div>\r\n</blockquote>",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "fae25202fbdcfe50ef1ffe316eefdc2c",
"sys_created_on": "2025-10-01 19:06:34",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
},
{
"sys_id": "fde3decefbd87e1023e5f8d65eefdcc8",
"sys_created_on": "2025-10-01 19:10:51",
"element_id": "493386721b2c9a90c5e163923b4bcb4a",
"value": "&#60;p&#62;Vai ter como sim, podemos ver&#60;/p&#62;",
"sys_created_by": "SOTHIS.CAOA",
"element": "comments"
}
]

View File

@ -1,38 +1,53 @@
# scripts/update_location_mapping.py #!/usr/bin/env python3
import csv import os
import time
import logging
import psycopg2 import psycopg2
import mysql.connector import mysql.connector
from mysql.connector import Error from mysql.connector import Error
import logging
from datetime import datetime
import os
from dotenv import load_dotenv
import pandas as pd import pandas as pd
from datetime import timedelta from datetime import datetime, timedelta
from dotenv import load_dotenv
# Carrega as variáveis do .env
from pathlib import Path from pathlib import Path
# Detecta ambiente # ===========================
env = os.getenv('NODE_ENV', 'development') # 🔧 Configuração do Ambiente
env_file = f".env.{env}" # ===========================
# Caminho absoluto (mesma pasta do script ou raiz do projeto) env = os.getenv('NODE_ENV', 'production')
env_path = Path(__file__).resolve().parent.parent / env_file env_file = f".env.{env}"
env_path = Path(__file__).resolve().parents[2] / env_file
load_dotenv(dotenv_path=env_path) load_dotenv(dotenv_path=env_path)
print(f"🌎 Ambiente carregado: {env}") print(f"🌎 Ambiente carregado: {env} ({env_path})")
# Configuração de logging
# ===========================
# 🪵 Configuração de Logs
# ===========================
LOG_DIR = Path(__file__).resolve().parents[3] / "logs" / "location"
ERROR_DIR = Path(__file__).resolve().parents[3] / "logs" / "error"
LOG_DIR.mkdir(parents=True, exist_ok=True)
ERROR_DIR.mkdir(parents=True, exist_ok=True)
log_file = LOG_DIR / f"location_{datetime.now().strftime('%Y-%m-%d')}.log"
error_file = ERROR_DIR / f"location_error_{datetime.now().strftime('%Y-%m-%d')}.log"
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s', format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[ handlers=[
logging.FileHandler('location_mapping.log'), logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler() logging.StreamHandler(),
logging.FileHandler(error_file, encoding="utf-8")
] ]
) )
# Configurações de banco de dados a partir do .env # ===========================
# 💾 Configurações dos Bancos
# ===========================
SNGLPI_DB_CONFIG = { SNGLPI_DB_CONFIG = {
'host': os.getenv('SNGLPI_DB_HOST'), 'host': os.getenv('SNGLPI_DB_HOST'),
'port': os.getenv('SNGLPI_DB_PORT'), 'port': os.getenv('SNGLPI_DB_PORT'),
@ -50,44 +65,43 @@ GLPI_DB_CONFIG = {
'charset': os.getenv('GLPI_DB_CHARSET', 'utf8mb4') 'charset': os.getenv('GLPI_DB_CHARSET', 'utf8mb4')
} }
# Caminho para o arquivo CSV
CSV_PATH = os.getenv('LOCATION_MAPPING_CSV_PATH') CSV_PATH = os.getenv('LOCATION_MAPPING_CSV_PATH')
# Função para verificar se o CSV foi modificado recentemente # ===========================
# 🔍 Funções auxiliares
# ===========================
def csv_recently_modified(minutes=2): def csv_recently_modified(minutes=2):
"""Verifica se o CSV foi alterado recentemente."""
if not os.path.exists(CSV_PATH): if not os.path.exists(CSV_PATH):
logging.error(f"Arquivo CSV não encontrado: {CSV_PATH}") logging.error(f"Arquivo CSV não encontrado: {CSV_PATH}")
return False return False
last_mod_time = datetime.fromtimestamp(os.path.getmtime(CSV_PATH)) last_mod_time = datetime.fromtimestamp(os.path.getmtime(CSV_PATH))
if datetime.now() - last_mod_time <= timedelta(minutes=minutes): if datetime.now() - last_mod_time <= timedelta(minutes=minutes):
logging.info(f"CSV modificado recentemente ({last_mod_time}), rodando atualização.") logging.info(f"CSV modificado recentemente ({last_mod_time})")
return True return True
else: else:
logging.info(f"CSV não foi modificado nos últimos {minutes} minutos (última modificação: {last_mod_time}).") logging.debug(f"CSV não foi modificado nos últimos {minutes} minutos.")
return False return False
# Função para conectar ao banco SNGLPI
def get_snglpi_connection(): def get_snglpi_connection():
try: try:
conn = psycopg2.connect(**SNGLPI_DB_CONFIG) return psycopg2.connect(**SNGLPI_DB_CONFIG)
return conn
except Exception as e: except Exception as e:
logging.error(f"Erro ao conectar ao banco SNGLPI: {e}") logging.error(f"Erro ao conectar ao banco SNGLPI: {e}")
return None return None
# Função para conectar ao banco GLPI
def get_glpi_connection(): def get_glpi_connection():
try: try:
conn = mysql.connector.connect(**GLPI_DB_CONFIG) return mysql.connector.connect(**GLPI_DB_CONFIG)
return conn
except Error as e: except Error as e:
logging.error(f"Erro ao conectar ao banco GLPI: {e}") logging.error(f"Erro ao conectar ao banco GLPI: {e}")
return None return None
# Função para buscar location_id no SNGLPI
def find_sn_location_id(location_name, cursor): def find_sn_location_id(location_name, cursor):
try: try:
query = """ query = """
@ -100,10 +114,10 @@ def find_sn_location_id(location_name, cursor):
result = cursor.fetchone() result = cursor.fetchone()
return result[0] if result else None return result[0] if result else None
except Exception as e: except Exception as e:
logging.error(f"Erro ao buscar location_id para {location_name}: {e}") logging.error(f"Erro ao buscar location_id ({location_name}): {e}")
return None return None
# Função para buscar entity_id no GLPI
def find_glpi_entity_id(entity_name, cursor): def find_glpi_entity_id(entity_name, cursor):
try: try:
query = """ query = """
@ -116,18 +130,17 @@ def find_glpi_entity_id(entity_name, cursor):
result = cursor.fetchone() result = cursor.fetchone()
return result[0] if result else None return result[0] if result else None
except Exception as e: except Exception as e:
logging.error(f"Erro ao buscar entity_id para {entity_name}: {e}") logging.error(f"Erro ao buscar entity_id ({entity_name}): {e}")
return None return None
# Função principal para atualizar a tabela de mapeamento
def update_mapping_table(): def update_mapping_table():
"""Atualiza a tabela de mapeamento a partir do CSV."""
try: try:
# Verificar se o arquivo CSV existe
if not os.path.exists(CSV_PATH): if not os.path.exists(CSV_PATH):
logging.error(f"Arquivo CSV não encontrado: {CSV_PATH}") logging.error(f"Arquivo CSV não encontrado: {CSV_PATH}")
return False return False
# Conectar aos bancos
snglpi_conn = get_snglpi_connection() snglpi_conn = get_snglpi_connection()
glpi_conn = get_glpi_connection() glpi_conn = get_glpi_connection()
@ -137,43 +150,25 @@ def update_mapping_table():
snglpi_cur = snglpi_conn.cursor() snglpi_cur = snglpi_conn.cursor()
glpi_cur = glpi_conn.cursor() glpi_cur = glpi_conn.cursor()
# Ler CSV
df = pd.read_csv(CSV_PATH, encoding='latin-1', sep=';') df = pd.read_csv(CSV_PATH, encoding='latin-1', sep=';')
print(df.head())
print(df.columns)
print(df)
# Adicionar colunas para IDs
df['sn_location_id'] = None df['sn_location_id'] = None
df['glpi_entity_id'] = None df['glpi_entity_id'] = None
# Processar cada linha do CSV
mappings = [] mappings = []
for index, row in df.iterrows(): for _, row in df.iterrows():
sn_location_name = row['sn_location_name'] sn_name = row['sn_location_name']
glpi_entity_name = row['glpi_entity_name'] glpi_name = row['glpi_entity_name']
# Buscar IDs sn_id = find_sn_location_id(sn_name, snglpi_cur)
sn_id = find_sn_location_id(sn_location_name, snglpi_cur) glpi_id = find_glpi_entity_id(glpi_name, glpi_cur)
glpi_id = find_glpi_entity_id(glpi_entity_name, glpi_cur)
# Preencher o DataFrame
df.loc[index, 'sn_location_id'] = sn_id
df.loc[index, 'glpi_entity_id'] = glpi_id
if glpi_id: if glpi_id:
# Se o glpi_entity_id for encontrado, adiciona para inserção mappings.append((sn_id, sn_name, glpi_id, glpi_name))
mappings.append((sn_id, sn_location_name, glpi_id, glpi_entity_name))
logging.debug(f"Mapeamento: {sn_location_name} -> {glpi_entity_name} (ID: {glpi_id})")
else: else:
logging.warning(f"Não foi possível encontrar entity_id para: {glpi_entity_name}") logging.warning(f"Entity não encontrada: {glpi_name}")
# Atualizar tabela de mapeamento
if mappings: if mappings:
# Limpar tabela existente
snglpi_cur.execute("DELETE FROM location_mapping") snglpi_cur.execute("DELETE FROM location_mapping")
# Inserir novos mapeamentos
insert_query = """ insert_query = """
INSERT INTO location_mapping INSERT INTO location_mapping
(sn_location_id, sn_location_name, glpi_entity_id, glpi_entity_name) (sn_location_id, sn_location_name, glpi_entity_id, glpi_entity_name)
@ -181,12 +176,10 @@ def update_mapping_table():
""" """
snglpi_cur.executemany(insert_query, mappings) snglpi_cur.executemany(insert_query, mappings)
snglpi_conn.commit() snglpi_conn.commit()
logging.info(f"Tabela atualizada com {len(mappings)} registros.")
logging.info(f"Tabela atualizada com {len(mappings)} mapeamentos")
else: else:
logging.warning("Nenhum mapeamento válido encontrado para atualização") logging.warning("Nenhum mapeamento válido encontrado.")
# Fechar conexões
snglpi_cur.close() snglpi_cur.close()
glpi_cur.close() glpi_cur.close()
snglpi_conn.close() snglpi_conn.close()
@ -196,16 +189,26 @@ def update_mapping_table():
except Exception as e: except Exception as e:
logging.error(f"Erro no processo de atualização: {e}") logging.error(f"Erro no processo de atualização: {e}")
# Rollback em caso de erro
if 'snglpi_conn' in locals(): if 'snglpi_conn' in locals():
snglpi_conn.rollback() snglpi_conn.rollback()
return False return False
# ===========================
# 🔁 Loop Contínuo
# ===========================
if __name__ == "__main__": if __name__ == "__main__":
logging.info("Iniciando atualização de mapeamento de localizações") logging.info("🚀 Iniciando monitoramento contínuo do Location Mapping")
if csv_recently_modified(minutes=2): while True:
success = update_mapping_table() try:
if success: if csv_recently_modified(minutes=2):
logging.info("Atualização concluída com sucesso") success = update_mapping_table()
else: if success:
logging.error("Falha na atualização") logging.info("✅ Atualização concluída com sucesso.")
else:
logging.error("❌ Falha na atualização.")
time.sleep(60)
except Exception as e:
logging.error(f"Erro inesperado no loop principal: {e}")
time.sleep(60)