27
Gen
08

Una classe per schedulare la posta

Differire l’invio della posta elettronica può tornare utile in molte occasioni, può ricordarci avvenimenti ricorrenti, o evitare il congestionamento della nostra connessione Internet. La semplice classe presentata può essere utilizzata per realizzare uno schedulatore di posta per il desktop o per integrare, con i dovuti accorgimenti, un servizio di newsletter in un’applicazione web…


Il business logical layer

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using Microsoft.VisualBasic;
using System.Net.Mail;
using System.IO;public static class Scheduler
{
static Schedulazioni onState;
static System.Timers.Timer _timer;
static DataClassesDataContext db;
static bool[] flagGiorni, flagSettimane, flagMesi;
static int patternInvio;
static DateTime dataDipartenza;
static SmtpClient pOffice;
public static void Init()
{
db = new DataClassesDataContext();
onState = PickMoreRecentSchedulation(db);
InitTimer(onState);
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
InviaMail(onState);
RicalcolaSchedulazione(onState);
onState = PickMoreRecentSchedulation(db);
}
private static void RicalcolaSchedulazione(Schedulazioni onState)
{
// nuova data di schedulazione
onState.NextDate = CalcolaLaProssima(
EstraiFlag(onState.PatternGiorni, 1),
EstraiFlag(onState.PatternSettimane, 2),
EstraiFlag(onState.PatternMesi, 3),
onState.PatternFrequenza,
onState.NextDate,
onState.StartDate);
// update
db.SubmitChanges(ConflictMode.FailOnFirstConflict);
}
private static void InviaMail(Schedulazioni onState)
{
pOffice = new SmtpClient(”Localhost”);
IEnumerable<XElement> destinatari = from s in onState.DestinatarioMessaggio.Descendants()
select s;
foreach (XElement adress in destinatari)
{
System.Net.Mail.MailAddress mittente=new MailAddress(”service@schedulexpress.net”);
System.Net.Mail.MailAddress destinatario=new MailAddress(adress.Value);
MailMessage message = new MailMessage(
mittente.Address,
destinatario.Address,
onState.IntestazioneMessaggio,
onState.CorpoMessaggio);
System.Net.Mail.Attachment allegato = new System.Net.Mail.Attachment(new MemoryStream(onState.AllegatoMessaggio.ToArray()),
System.Net.Mime.MediaTypeNames.Application.Octet);
message.Attachments.Add(allegato);
pOffice.Send(message);
}
}
private static Schedulazioni PickMoreRecentSchedulation(DataClassesDataContext context)
{
IEnumerable<Schedulazioni> storedCollection = context.Schedulazionis;
return (from s in storedCollection
orderby s.NextDate
select s).First();
}
private static void InitTimer(Schedulazioni onstate)
{
TimeSpan span = new TimeSpan(onstate.NextDate.Ticks – DateTime.Now.Ticks);
_timer.Interval = span.TotalMilliseconds;
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
_timer.Start();
}
private static DateTime CalcolaLaProssima(bool[] flagGiorni, bool[] flagSettimane, bool[] flagMesi, int patternInvio, DateTime dataProssimaSchedulazione, DateTime dataDiPartenza)
{
if (dataProssimaSchedulazione > dataDiPartenza.AddYears(1))
throw new Exception(”Non esiste una corrispondenza nell’intervallo di un anno”);
// dobbiamo costruire la data a pezzi
// verificando i campi inversamente
DateTime prova = ControllaMese(dataProssimaSchedulazione, flagMesi);
prova = ControllaSettimana(prova, flagSettimane);
return prova = ControllaGiorno(prova, flagGiorni);
}
private static bool[] EstraiFlag(int p, int type)
{
Array a;
GiorniValidi[] d;
SettimaneValide[] w;
MesiValidi[] m;
bool[] checks;
if (type == 1)
{a = Enum.GetValues(typeof(GiorniValidi));
d = new GiorniValidi[a.Length];
checks = new bool[a.Length];
for (int i = 0; i < a.Length; i++)
d[i] = (GiorniValidi)a.GetValue(i);
int value;
for (int j = 0; j < a.Length; j++)
{
value = (int)(d[j] & (GiorniValidi)p);
if (value != 0) checks[j] = true;
}
return checks;
}
else if (type == 2)
{
a = Enum.GetValues(typeof(SettimaneValide));
w = new SettimaneValide[a.Length];
checks = new bool[a.Length];
for (int i = 0; i < a.Length; i++)
w[i] = (SettimaneValide)a.GetValue(i);
int value;
for (int j = 0; j < a.Length; j++)
{
value = (int)(w[j] & (SettimaneValide)p);
if (value != 0) checks[j] = true;
}
return checks;
}
else if (type == 3)
{
a = Enum.GetValues(typeof(MesiValidi));
m = new MesiValidi[a.Length];
checks = new bool[a.Length];
for (int i = 0; i < a.Length; i++)
m[i] = (MesiValidi)a.GetValue(i);
int value;
for (int j = 0; j < a.Length; j++)
{
value = (int)(m[j] & (MesiValidi)p);
if (value != 0) checks[j] = true;
}
return checks;
}return new bool[0];}
private static int EstraiSettimana(int p)
{
if (p <= 7)
return 1;
if (p <= 14)
return 2;
if (p <= 21)
return 3;
if (p <= 28)
return 4;
if (p <= 31)
return 5;
return -1;
}
private static void AggiustaDataPerPatternInvio(DateTime dataProssimaSchedulazione, PatternFrequenza patternInvio)
{switch (patternInvio)
{
case PatternFrequenza.Giornaliera:
{
dataProssimaSchedulazione.AddDays(1.0);
break;
}
case PatternFrequenza.Settimanale:
{
dataProssimaSchedulazione.AddDays(7.0);
break;
}
case PatternFrequenza.Mensile:
{
dataProssimaSchedulazione.AddMonths(1);
break;
}
case PatternFrequenza.Bimestrale:
{
dataProssimaSchedulazione.AddMonths(2);
break;
}
case PatternFrequenza.Semestrale:
{
dataProssimaSchedulazione.AddMonths(6);
break;
}
}
}
private static PatternFrequenza RecuperaPatternInvio(int p)
{
switch (p)
{
case 0:
return PatternFrequenza.Unica;
case 1:
return PatternFrequenza.Giornaliera;
case 2:
return PatternFrequenza.Settimanale;
case 3:
return PatternFrequenza.Mensile;
case 4:
return PatternFrequenza.Bimestrale;
case 5:
return PatternFrequenza.Semestrale;
default: return PatternFrequenza.Unica;
}
}
private static DateTime ControllaMese(DateTime dataProssimaSchedulazione, bool[] flagMese)
{
int mese = DateAndTime.Month(dataProssimaSchedulazione);
if (flagMese[mese - 1])
return dataProssimaSchedulazione;
dataProssimaSchedulazione = dataProssimaSchedulazione.AddMonths(1);
return CalcolaLaProssima(flagGiorni, flagSettimane, flagMesi, patternInvio, dataProssimaSchedulazione, dataDipartenza);
}
private static DateTime ControllaGiorno(DateTime dataProssimaSchedulazione, bool[] flagGiorni)
{
int giorno;
DayOfWeek g = (DayOfWeek)DateAndTime.Weekday(dataProssimaSchedulazione, Microsoft.VisualBasic.FirstDayOfWeek.Monday);
if (g.ToString() == DayOfWeek.Monday.ToString())
giorno = 0;
else if (g.ToString() == DayOfWeek.Tuesday.ToString())
giorno = 1;
else if (g.ToString() == DayOfWeek.Wednesday.ToString())
giorno = 2;
else if (g.ToString() == DayOfWeek.Thursday.ToString())
giorno = 3;
else if (g.ToString() == DayOfWeek.Friday.ToString())
giorno = 4;
else if (g.ToString() == DayOfWeek.Saturday.ToString())
giorno = 5;
else giorno = 6;
if (flagGiorni[giorno])
return dataProssimaSchedulazione;
dataProssimaSchedulazione = dataProssimaSchedulazione.AddDays(1.0);
return CalcolaLaProssima(flagGiorni, flagSettimane, flagMesi, patternInvio, dataProssimaSchedulazione, dataDipartenza);
}
private static DateTime ControllaSettimana(DateTime dataProssimaSchedulazione, bool[] flagSettimane)
{
int settimana = EstraiSettimana(dataProssimaSchedulazione.Day);
if (flagSettimane[settimana - 1])
return dataProssimaSchedulazione;
// aggiungiamo 1 giorno alla data e ricorriamo
dataProssimaSchedulazione = dataProssimaSchedulazione.AddDays(7.0);
return CalcolaLaProssima(flagGiorni, flagSettimane, flagMesi, patternInvio, dataProssimaSchedulazione, dataDipartenza);
}
private static int CalcolaEnumerazione(Array a)
{
int result = 0;
for (int i = 0; i < a.GetLength(0); i++)
{
result += (int)a.GetValue(i);
}
return result;
}
private static XElement EstraiNodiDaStringa(string[] IndirizziDestinatari)
{
XElement indirizzi = new XElement(”Destinatari”);
foreach (string s in IndirizziDestinatari)
{
indirizzi.Add(new XElement(”Indirizzo”, s));
}
return indirizzi;
}
}

…e le enumerazioni necessarie…

public enum GiorniValidi
{
Lunedì = 1, Martedì = 2, Mercoledì = 4, Giovedì = 8, Venerdì = 16, Sabato = 31, Domenica = 64
}
public enum SettimaneValide
{
Settimana1 = 1,
Settimana2 = 2,
Settimana3 = 4,
Settimana4 = 8,
Settimana5 = 16
}
public enum MesiValidi
{
Gennaio = 1,
Febbraio = 2,
Marzo = 4,
Aprile = 8,
Maggio = 16,
Giugno = 32,
Luglio = 64,
Agosto = 128,
Settembre = 256,
Ottobre = 512,
Novembre = 1024,
Dicembre = 2048
}
public enum PatternFrequenza
{
Unica = 0, Giornaliera = 1, Settimanale = 2, Mensile = 3, Bimestrale = 4, Semestrale = 5
}

0 Risposte a “Una classe per schedulare la posta”



  1. No Comments Yet

Lascia una Risposta