ContagemLigacoes/Program.cs

185 lines
6.6 KiB
C#

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("");
}
}