Files
2020-01-22 19:43:23 +01:00

699 lines
19 KiB
C#

using MapoSDK;
using NLog;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace IOB_UT
{
/// <summary>
/// Override metodo WebClient con gesitone TimeOut corto
/// </summary>
public class WebClientWT : WebClient
{
/// <summary>
/// timeout da conf
/// </summary>
protected int urlCallTOut
{
get
{
int answ = 5000;
answ = baseUtils.CRI("urlCallTOut");
if (answ < 0 || answ > 10000)
{
answ = 3000;
}
return answ;
}
}
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest wr = base.GetWebRequest(address);
wr.Timeout = urlCallTOut; // timeout in milliseconds (ms)
return wr;
}
}
public class baseUtils
{
/// <summary>
/// Oggetto connessione REDIS
/// </summary>
public static RedisIobCache redisMan = new RedisIobCache();
/// <summary>
/// Indicazione VETO PING a server sino alla data-ora indicata
/// </summary>
public static DateTime dtVetoPing = DateTime.Now;
#if false
{
get
{
return redisMan.servStatus.dtVetoPing;
}
set
{
var currData = redisMan.servStatus;
currData.dtVetoPing = value;
redisMan.servStatus = currData;
}
}
#endif
/// <summary>
/// Indicazione VETO invio a server sino alla data-ora indicata
/// </summary>
public static DateTime dtVetoSend = DateTime.Now;
/// <summary>
/// Status MP_IO
/// </summary>
public static bool MPIO_Online = false;
/// <summary>
/// Status IOB
/// </summary>
public static bool IOB_Online = false;
/// <summary>
/// Calcola una pausa con errore casuale x il prossimo send programmato verso SERVER
/// </summary>
public static int nextPauseSendMSec
{
get
{
// parto dal dato std di veto per pauseSendMSec
int answ = CRI("pauseSendMSec");
// aggiungo NOISE... +/- 33%
Random rnd = new Random();
int noise = rnd.Next(1, answ / 3);
answ += noise - (answ / 6);
return answ;
}
}
/// <summary>
/// Classe logger
/// </summary>
public static Logger lg = LogManager.GetCurrentClassLogger();
/// <summary>
/// Fattore di riduzione dei log
/// </summary>
public static int logReduxFactor = 10;
/// <summary>
/// Conteggio valori true in un array di boolean
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static int CountTrue(params bool[] args)
{
return args.Count(t => t);
}
/// <summary>
/// legge conf in formato char
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static char CRC(string key)
{
char answ = '-';
try
{
answ = ConfigurationManager.AppSettings[key].ToCharArray()[0];
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato stringa
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string CRS(string key)
{
string answ = "";
try
{
answ = ConfigurationManager.AppSettings[key].ToString();
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato INT
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static Int32 CRI(string key)
{
int answ = 0;
try
{
answ = Convert.ToInt32(CRS(key));
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato BOOLean
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool CRB(string key)
{
bool answ = false;
try
{
answ = Convert.ToBoolean(CRS(key));
}
catch
{ }
return answ;
}
/// <summary>
/// verifica se un dato bit sia alzato (come flag di strobe)
/// </summary>
/// <param name="value">valore da testare</param>
/// <param name="flag">valore cercato, può essere un singolo valore o un insieme in modalità AND</param>
/// <returns></returns>
public static bool IsSetAll(StFlag32 value, StFlag32 flag)
{
return ((value & flag) == flag);
}
/// <summary>
/// verifica se un dato bit sia alzato (come flag di strobe)
/// </summary>
/// <param name="value">valore da testare</param>
/// <param name="flag">valore cercato, può essere un singolo valore o un insieme in modalità OR</param>
/// <returns></returns>
public static bool IsSetAny(StFlag32 value, StFlag32 flag)
{
return ((value & flag) != 0);
}
/// <summary>
/// formatta un numero in forma binaria 0/1
/// </summary>
/// <param name="valore"></param>
/// <returns></returns>
public static string binaryForm(int valore)
{
string answ = "";
try
{
answ = string.Format(new BinaryFormatter(), "{0:B}", valore);
}
catch
{ }
return answ;
}
/// <summary>
/// Method to convert an integer to a string containing the number in binary. A negative
/// number will be formatted as a 32-character binary number in two's compliment.
/// </summary>
/// <param name="theNumber">self-explanatory</param>
/// <param name="minimumDigits">if binary number contains fewer characters leading zeros are added</param>
/// <returns>string as described above</returns>
public static string IntToBinStr(int theNumber, int minimumDigits)
{
return Convert.ToString(theNumber, 2).PadLeft(minimumDigits, '0');
}
/// <summary>
/// Effettua reverse della stringa
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string reverseStr(string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
/// <summary>
/// imposta un bit al valore richiesto duplicando il valore IN come OUT
/// </summary>
/// <param name="original">valore originale da aggiornare</param>
/// <param name="bitBool">valore richiesto x il bit (0/1)</param>
/// <param name="bitIndex">indice bit, 0 based (es: 0..31 per 32bit)</param>
/// <returns></returns>
public static byte[] setBitOnStFlag(byte[] original, bool bitBool, int bitIndex)
{
int bitVal = 0;
if (bitBool)
{
bitVal = 1;
}
// risposta è identica ad originale...
byte[] answ = original;
// verifico se il bit è 0/1b
if (bitVal <= 1 && bitVal >= 0)
{
// verifico se si possa aggiornare il bit richiesto (<= al totale dei bit...)
if (bitIndex <= original.Length * 8 - 1)
{
// calcolo byte
int byteIndex = bitIndex / 8;
// bit nel byte
int bitInByteIndex = bitIndex % 8;
// bit richiesto
byte mask = (byte)(bitVal << bitInByteIndex);
// imposto!
answ[byteIndex] |= mask;
}
}
return answ;
}
/// <summary>
/// Converte un bitarray a byte[]
/// </summary>
/// <param name="bits"></param>
/// <returns></returns>
public static byte[] ToByteArray(BitArray bits)
{
int numBytes = bits.Count / 8;
if (bits.Count % 8 != 0)
{
numBytes++;
}
byte[] bytes = new byte[numBytes];
int byteIndex = 0, bitIndex = 0;
for (int i = 0; i < bits.Count; i++)
{
if (bits[i])
{
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
}
bitIndex++;
if (bitIndex == 8)
{
bitIndex = 0;
byteIndex++;
}
}
return bytes;
}
/// <summary>
/// Scrittura dictionary su file
/// </summary>
/// <param name="dictionary"></param>
/// <param name="file"></param>
public static void WriteBin(Dictionary<string, string> dictionary, string file)
{
using (FileStream fs = File.OpenWrite(file))
using (BinaryWriter writer = new BinaryWriter(fs))
{
// Put count.
writer.Write(dictionary.Count);
// Write pairs.
foreach (var pair in dictionary)
{
writer.Write(pair.Key);
writer.Write(pair.Value);
}
}
}
/// <summary>
/// Lettura dictionary da file
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static Dictionary<string, string> ReadBin(string file)
{
var result = new Dictionary<string, string>();
// verifico file esista...
if (!File.Exists(file))
{
FileStream fs = File.Create(file);
fs.Close();
}
using (FileStream fs = File.OpenRead(file))
using (BinaryReader reader = new BinaryReader(fs))
{
// Get count.
int count = 0;
try
{
count = reader.ReadInt32();
}
catch
{ }
// Read in all pairs.
for (int i = 0; i < count; i++)
{
string key = reader.ReadString();
string value = reader.ReadString();
result[key] = value;
}
}
return result;
}
/// <summary>
/// Scrittura dictionary su file
/// </summary>
/// <param name="dictionary"></param>
/// <param name="file"></param>
public static void WritePlain(Dictionary<string, string> dictionary, string file)
{
string dirPath = file.Substring(0, file.LastIndexOf('\\'));
// verifico directory
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray();
try
{
File.WriteAllLines(file, lines);
}
catch (Exception exc)
{
lg.Info(exc, string.Format("Errore in scrittura file {0}", file));
}
}
/// <summary>
/// Lettura dictionary da file
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static Dictionary<string, string> ReadPlain(string file)
{
// inizializzo num righe lette...
int numRow = 0;
var result = new Dictionary<string, string>();
// verifico file esista...
if (!File.Exists(file))
{
FileStream fs = File.Create(file);
fs.Close();
}
try
{
string[] lines = File.ReadAllLines(file);
result = lines.Select(l => l.Split(':')).ToDictionary(a => a[0], a => a[1]);
numRow = result.Count;
}
catch
{ }
// se leggesse un valore NON coerente (senza righe) restituisce un file vuoto...
if (numRow == 0)
{
result = new Dictionary<string, string>();
}
return result;
}
/// <summary>
/// Test ping x indirizzo indicato
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public static bool pingAddress(IPAddress address)
{
bool answ = false;
try
{
Ping pingSender = new Ping();
PingReply reply = pingSender.Send(address, 100);
// se passa il ping do OK...
if (reply.Status == IPStatus.Success)
{
answ = true;
}
}
catch (Exception exc)
{
lg.Error(exc);
}
return answ;
}
/// <summary>
/// IP della macchina
/// </summary>
/// <returns></returns>
public static string GetIP()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sIpAddr = string.Empty;
try
{
foreach (NetworkInterface adapter in nics)
{
if (sIpAddr == String.Empty)// only return IP Address from first card
{
IPInterfaceProperties properties = adapter.GetIPProperties();
foreach (var item in properties.UnicastAddresses)
{
if (item.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
sIpAddr = item.Address.ToString();
}
}
}
}
}
catch (Exception exc)
{
lg.Error(exc);
}
return sIpAddr;
}
/// <summary>
/// Macaddress della macchina
/// </summary>
/// <returns></returns>
public static string GetMACAddress()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sMacAddress = string.Empty;
foreach (NetworkInterface adapter in nics)
{
if (sMacAddress == String.Empty)// only return MAC Address from first card
{
IPInterfaceProperties properties = adapter.GetIPProperties();
//sMacAddress = adapter.GetPhysicalAddress().ToString();
sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
}
}
return sMacAddress;
}
/// <summary>
/// Oggetto WebClient BASE da riutilizzare
/// </summary>
protected static WebClientWT client { get; set; }
/// <summary>
/// Oggetto WebClient con PAYLOAD da riutilizzare
/// </summary>
protected static WebClientWT clientPayload { get; set; }
public static void resetWebClients()
{
// resetto i webclients...
client = new WebClientWT();
clientPayload = new WebClientWT();
}
/// <summary>
/// Effettua chiamata URL IMMEDIATAMENTE e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string callUrlNow(string URL)
{
string answ = "";
if (client == null)
{
client = new WebClientWT();
}
client.Headers.Add("user-agent", $"{CRS("appName")}");
#if false
WebClientWT client = new WebClientWT();
client.Headers.Add("user-agent", CRS("appName"));
#endif
try
{
answ = client.DownloadString(URL);
}
catch (Exception exc)
{
// imposto veto
int pauseSendMSec = nextPauseSendMSec;
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
// log ogni
lg.Info($"Errore in callURL verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata");
logReduxFactor--;
if (logReduxFactor <= 0)
{
lg.Error($"Eccezione in esecuzione callURL: {URL}{Environment.NewLine}{exc}");
logReduxFactor = 10;
}
}
// restituisco valore!
return answ;
}
/// <summary>
/// Effettua chiamata IMMEDIATAMENTE URL e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <returns></returns>
public static string callUrlNow(string URL, string payload)
{
string answ = "";
if (clientPayload == null)
{
clientPayload = new WebClientWT();
}
clientPayload.Headers.Add("user-agent", $"{CRS("appName")}-PAYLOAD");
#if false
WebClientWT clientPayload = new WebClientWT();
clientPayload.Headers.Add("user-agent", CRS("appName"));
#endif
try
{
answ = clientPayload.UploadString(URL, payload);
}
catch (Exception exc)
{
// imposto veto
int pauseSendMSec = nextPauseSendMSec;
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
// log ogni
lg.Info($"Errore in callURL con PAYLOAD verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata");
logReduxFactor--;
if (logReduxFactor <= 0)
{
lg.Error($"Eccezione in esecuzione callURL: {URL}{Environment.NewLine}con payload: {payload}{Environment.NewLine}{exc}");
logReduxFactor = 10;
}
}
// restituisco valore!
return answ;
}
/// <summary>
/// Effettua chiamata URL e restituisce risultato, SE NON E' in veto send (x mmitigare chiamate...)
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string callUrl(string URL)
{
string answ = "";
// controllo se ho un VETO all'invio...
if (dtVetoSend < DateTime.Now)
{
answ = callUrlNow(URL);
}
return answ;
}
/// <summary>
/// Effettua chiamata URL e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <returns></returns>
public static string callUrl(string URL, string payload)
{
string answ = "";
// controllo se ho un VETO all'invio...
if (dtVetoSend < DateTime.Now)
{
callUrlNow(URL, payload);
}
// restituisco valore!
return answ;
}
/// <summary>
/// Versione async della chiamata ad URL
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string callUrlAsync(string URL)
{
// Chiamo in modalità task...
var resp = TaskEx.Run(() => callUrl(URL));
return resp.Result;
}
/// <summary>
/// Versione async della chiamata ad URL
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <returns></returns>
public static string callUrlAsync(string URL, string payload)
{
// Chiamo in modalità task...
var resp = TaskEx.Run(() => callUrl(URL, payload));
return resp.Result;
}
/// <summary>
/// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare a dim inferiori a _logMaxMb
/// </summary>
public static void shrinkDir(string dirPath)
{
// obj filemover...
fileMover.obj.setDirectory(dirPath);
float dirSizeMb = fileMover.obj.totalMb();
lg.Info("Inizio shrinkDir LOG folder: {0} Mb", dirSizeMb);
// ottengo elenco files *.txt
FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.log");
int numDdMax = 2;
try
{
numDdMax = CRI("zipLogOldDay");
}
catch
{ }
foreach (FileInfo _file in _fis)
{
if (_file.LastWriteTime < DateTime.Now.AddDays(-1)) // zippo files + vecchi di 2 gg...
{
fileMover.obj.zippaSingoloFile(_file);
// cancello l'originale...
fileMover.obj.eliminaFile(_file);
}
}
// ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal + vecchio...
dirSizeMb = fileMover.obj.totalMb();
int maxLogDirSize = CRI("maxLogDirSize");
int maxTry = 100;
// controllo se serva eliminare...
if (dirSizeMb > maxLogDirSize)
{
lg.Info("Continuo shrinkDir LOG folder: {0} Mb --> ELIMINAZIONE FILES", dirSizeMb);
while (dirSizeMb > maxLogDirSize)
{
fileMover.obj.deleteOldest();
maxTry--;
if (maxTry > 0)
{
dirSizeMb = fileMover.obj.totalMb();
}
else
{
// per uscire fingo di aver ridotto...
dirSizeMb = maxLogDirSize - 1;
}
}
dirSizeMb = fileMover.obj.totalMb();
lg.Info("Completata shrinkDir LOG folder: {0} Mb", dirSizeMb);
}
}
}
}