Adicionar arquivos de projeto.
This commit is contained in:
parent
87298bf025
commit
3cd0ab1212
16
ContagemLigacoes.csproj
Normal file
16
ContagemLigacoes.csproj
Normal file
@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Npgsql" Version="9.0.3" />
|
||||
<PackageReference Include="Spectre.Console" Version="0.50.1-preview.0.11" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
22
ContagemLigacoes.sln
Normal file
22
ContagemLigacoes.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.12.35527.113 d17.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContagemLigacoes", "ContagemLigacoes.csproj", "{BE025921-A746-4E01-903F-E04A1C91A85A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BE025921-A746-4E01-903F-E04A1C91A85A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BE025921-A746-4E01-903F-E04A1C91A85A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BE025921-A746-4E01-903F-E04A1C91A85A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BE025921-A746-4E01-903F-E04A1C91A85A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
184
Program.cs
Normal file
184
Program.cs
Normal file
@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using Npgsql;
|
||||
using Spectre.Console;
|
||||
|
||||
class Program
|
||||
{
|
||||
static DateTime _endTime;
|
||||
static bool _stop = false;
|
||||
static bool _isAuthenticated = false;
|
||||
static readonly string _connectionString = "Server=192.168.10.248;Port=5432;Database=pipefy_move_cards;User Id=postgres;Password=gds21;";
|
||||
static readonly string _windowsID = Environment.UserName;
|
||||
// Agora guardamos uma lista de tuplas (UserID, Nome)
|
||||
static readonly List<(BigInteger UserId, string Nome)> _pipeUsers = new();
|
||||
|
||||
static void Main()
|
||||
{
|
||||
AnsiConsole.Clear();
|
||||
|
||||
// 1) Autenticação (pode retornar múltiplos usuários)
|
||||
Autenticacao();
|
||||
|
||||
if (!_isAuthenticated)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[bold red]Nenhum usuário encontrado ou erro na autenticação. Saindo...[/]");
|
||||
Console.ReadLine();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Loop principal: atualizar dados e aguardar entrada
|
||||
while (!_stop)
|
||||
{
|
||||
AtualizarDados();
|
||||
AguardarEntrada();
|
||||
}
|
||||
|
||||
AnsiConsole.MarkupLine("[bold yellow]Aplicação encerrada.[/]");
|
||||
}
|
||||
|
||||
static void Autenticacao()
|
||||
{
|
||||
AnsiConsole.Status()
|
||||
.Spinner(Spinner.Known.Dots)
|
||||
.Start("[green]Autenticando usuário...[/]", ctx =>
|
||||
{
|
||||
const string query = @"
|
||||
SELECT ""UserID"", ""Nome""
|
||||
FROM public.""usuarios""
|
||||
WHERE ""windowsID"" = @WindowsID";
|
||||
|
||||
try
|
||||
{
|
||||
using var conn = new NpgsqlConnection(_connectionString);
|
||||
conn.Open();
|
||||
using var cmd = new NpgsqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@WindowsID", _windowsID);
|
||||
|
||||
using var reader = cmd.ExecuteReader();
|
||||
while (reader.Read())
|
||||
{
|
||||
var userId = BigInteger.Parse(reader["UserID"].ToString()!);
|
||||
var nome = reader["Nome"].ToString()!;
|
||||
_pipeUsers.Add((userId, nome));
|
||||
}
|
||||
|
||||
if (_pipeUsers.Count > 0)
|
||||
{
|
||||
_isAuthenticated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.MarkupLine("[bold red]Nenhum usuário encontrado para este WindowsID.[/]");
|
||||
_isAuthenticated = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"\n[red]Erro na autenticação:[/] {ex.Message}");
|
||||
_isAuthenticated = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void AtualizarDados()
|
||||
{
|
||||
AnsiConsole.Clear();
|
||||
|
||||
// Painel de cabeçalho que mostra quantos usuários foram carregados
|
||||
var header = new Panel($"[bold]WindowsID[/]: {_windowsID} • [bold]Usuários encontrados[/]: {_pipeUsers.Count}")
|
||||
.Header("[yellow]Resumo Diário por Usuário[/]")
|
||||
.Expand();
|
||||
AnsiConsole.Write(header);
|
||||
|
||||
// Montamos uma tabela com: Nome do usuário | UserID | Registros Hoje
|
||||
var table = new Table().Border(TableBorder.Rounded);
|
||||
table.AddColumn("[green]Nome[/]");
|
||||
table.AddColumn("[green]UserID[/]");
|
||||
table.AddColumn("[green]Registros Hoje[/]");
|
||||
|
||||
// Para cada usuário, rodar uma query COUNT(*) e adicionar linha na tabela
|
||||
foreach (var (userId, nome) in _pipeUsers)
|
||||
{
|
||||
int count = 0;
|
||||
AnsiConsole.Status()
|
||||
.Spinner(Spinner.Known.Line)
|
||||
.Start($"[blue]Obtendo registros de [yellow]{nome}[/]...[/]", ctx =>
|
||||
{
|
||||
const string query = @"
|
||||
SELECT COUNT(*)
|
||||
FROM public.""ActionsHistory""
|
||||
WHERE ""UserID"" = @pipeUser
|
||||
AND ""MovedAt"" > CURRENT_DATE
|
||||
AND ""FieldID"" IS NOT NULL";
|
||||
try
|
||||
{
|
||||
using var conn = new NpgsqlConnection(_connectionString);
|
||||
conn.Open();
|
||||
using var cmd = new NpgsqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@pipeUser", userId);
|
||||
count = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Em caso de erro, exibimos zero e continuamos
|
||||
count = 0;
|
||||
AnsiConsole.MarkupLine($"\n[red]Erro ao consultar {nome}:[/] {ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
table.AddRow(nome, userId.ToString(), $"[bold yellow]{count}[/]");
|
||||
}
|
||||
|
||||
AnsiConsole.Write(table);
|
||||
|
||||
AnsiConsole.MarkupLine("\n[gray]Pressione [green]ENTER[/] para atualizar agora ou qualquer outra tecla para sair.[/]");
|
||||
}
|
||||
|
||||
static void AguardarEntrada()
|
||||
{
|
||||
// Tempo de espera em segundos (ex.: 10 minutos = 600s)
|
||||
int intervalSeconds = 600;
|
||||
_endTime = DateTime.Now.AddSeconds(intervalSeconds);
|
||||
|
||||
// Escreve uma linha em branco para “reservar” o lugar do contador
|
||||
AnsiConsole.WriteLine("");
|
||||
|
||||
// Começa o loop que vai atualizar a mesma linha a cada segundo
|
||||
while (!_stop)
|
||||
{
|
||||
var remaining = _endTime - DateTime.Now;
|
||||
|
||||
if (remaining.TotalMilliseconds <= 0)
|
||||
{
|
||||
// Quando chegar a zero, exibe a mensagem de atualização automática
|
||||
AnsiConsole.MarkupLine("\r[red]Atualização automática agora![/]");
|
||||
Thread.Sleep(1000);
|
||||
break;
|
||||
}
|
||||
|
||||
// Monta o texto de “Próxima atualização em MM:SS”
|
||||
AnsiConsole.Markup($"\r[blue]Próxima atualização em {remaining.Minutes:00}:{remaining.Seconds:00}[/]");
|
||||
|
||||
// Pequena pausa de 1 segundo
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Se o usuário apertar qualquer tecla…
|
||||
if (Console.KeyAvailable)
|
||||
{
|
||||
var key = Console.ReadKey(true);
|
||||
// …e não for ENTER, sinalizamos para parar o loop e sair
|
||||
if (key.Key != ConsoleKey.Enter)
|
||||
_stop = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Garante que, ao sair do loop, o cursor fique embaixo do texto
|
||||
Console.WriteLine("");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user