Example #1
0
        private static void OnMondayMorning()
        {
            try
            {
                // Detect and log any forex difference exceeding 100 cents.

                FinancialAccounts allAccounts = FinancialAccounts.GetAll(); // across ALL ORGS!

                foreach (FinancialAccount account in allAccounts)
                {
                    // For every account, if it's based on foreign currency, check for forex gains/losses

                    if (account.ForeignCurrency != null)
                    {
                        account.CheckForexProfitLoss();
                    }
                }
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
                if (testMode)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
Example #2
0
        internal static void RemindExpiries(DateTime dateExpiry)
        {
            Organizations orgs = Organizations.GetAll();

            foreach (Organization org in orgs)
            {
                Memberships memberships = Memberships.GetExpiring(org, dateExpiry);

                // Mail each expiring member

                foreach (Membership membership in memberships)
                {
                    try
                    {
                        SendReminderMail(membership);
                        PWLog.Write(PWLogItem.Person, membership.PersonId,
                                    PWLogAction.MembershipRenewReminder,
                                    "Mail was sent to " + membership.Person.Mail +
                                    " reminding to renew membership in " + membership.Organization.Name + ".", string.Empty);
                    }
                    catch (Exception ex)
                    {
                        ExceptionMail.Send(
                            new Exception("Failed to create reminder mail for person " + membership.PersonId, ex));
                    }
                }
            }
        }
Example #3
0
        public static void Run()
        {
            Database      database      = new Database(Globals.DatabaseConnectString);
            ForumDatabase forumDatabase = new ForumDatabase(Globals.ForumDatabaseConnectString);

            Hashtable memberAccounts = new Hashtable();

            Member[] members = database.GetAllMembers();

            foreach (Member member in members)
            {
                try
                {
                    if (member.ForumAccountId != 0)
                    {
                        if (!forumDatabase.IsPartyMember(member.ForumAccountId))
                        {
                            // This guy is not listed as a party member, but should be.

                            forumDatabase.SetPartyMember(member.ForumAccountId);
                        }
                        memberAccounts [member.ForumAccountId] = true;
                    }
                }
                catch (Exception)
                {
                    // The forum account probably doesn't exist. Just remove it from the profile.

                    try
                    {
                        database.SetMemberForumAccountId(member.MemberId, 0);
                    }
                    catch (Exception e2)
                    {
                        ExceptionMail.Send(e2);
                    }
                }
            }

            // Now that we have flagged all member accounts as member accounts, flag the rest as
            // non-party members.

            int[] accountIds = forumDatabase.GetAccountList();

            foreach (int accountId in accountIds)
            {
                if (!memberAccounts.ContainsKey(accountId))
                {
                    if (forumDatabase.IsPartyMember(accountId))
                    {
                        forumDatabase.SetPartyNonmember(accountId);
                    }
                }
            }
        }
Example #4
0
        private static void OnEveryTenSeconds()
        {
            try
            {
                BotLog.Write(0, "MainCycle", "Ten-second entry");

                SystemSettings.HeartbeatBackend = (ulong)DateTime.UtcNow.ToUnix();
                CommsTransmitter.Run();

                BroadcastTimestamp();

                try
                {
                    /*TestTrace("Running EventProcessor.Run()...");
                     * EventProcessor.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running MailResolver.Run()...");
                     * MailResolver.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running MailProcessor.Run()...");
                     * MailProcessor.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                BotLog.Write(0, "MainCycle", "Ten-second exit");
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
            }
        }
Example #5
0
        private static void OnEveryTenSeconds()
        {
            try
            {
                BotLog.Write(0, "MainCycle", "Ten-second entry");

                CommsTransmitter.Run();

                try
                {
                    /*TestTrace("Running EventProcessor.Run()...");
                     * EventProcessor.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running MailResolver.Run()...");
                     * MailResolver.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running MailProcessor.Run()...");
                     * MailProcessor.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                BotLog.Write(0, "MainCycle", "Ten-second exit");
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
            }
        }
Example #6
0
 private static void OnTuesdayMorning()
 {
     try
     {
         //TestTrace("Running ActivityMailer.Run()...");
         // PirateWeb.Utility.BotCode.ActivityMailer.Run();
         //TestTrace(" done.\r\n");
     }
     catch (Exception e)
     {
         ExceptionMail.Send(e, true);
         if (testMode)
         {
             Console.WriteLine(e.ToString());
         }
     }
 }
Example #7
0
        private static void OnMondayMorning()
        {
            try
            {
                Dictionary <int, bool> accountTested = new Dictionary <int, bool>();

                // Check the bitcoin hotwallets for forex profit/loss.

                Organizations allOrganizations = Organizations.GetAll();

                foreach (Organization organization in allOrganizations)
                {
                    FinancialAccount hotWalletAccount = organization.FinancialAccounts.AssetsBitcoinHot;

                    if (hotWalletAccount != null)
                    {
                        BitcoinUtility.CheckHotwalletForexProfitLoss(hotWalletAccount);
                        accountTested[hotWalletAccount.Identity] = true;
                    }
                }

                // Detect and log any forex difference exceeding 100 cents.

                FinancialAccounts allAccounts = FinancialAccounts.GetAll(); // across ALL ORGS!

                foreach (FinancialAccount account in allAccounts)
                {
                    // For every account, if it's based on foreign currency, and not already checked,
                    // then check for forex gains/losses

                    if (account.ForeignCurrency != null && !accountTested.ContainsKey(account.Identity))
                    {
                        account.CheckForexProfitLoss();
                    }
                }
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
                if (testMode)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
Example #8
0
        /// <summary>
        /// Asynchronous callback method. Not in use.
        /// </summary>
        /// <param name="result"></param>
        internal static void MessageSent(IAsyncResult result)
        {
            MailTransmissionDelegate asyncTransmitter = (MailTransmitter.MailTransmissionDelegate)result.AsyncState;

            try
            {
                asyncTransmitter.EndInvoke(result);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.ToString());
                ExceptionMail.Send(e);
            }

            lock (lockObject)
            {
                outstandingTransmissions--;
            }
        }
Example #9
0
        private static void OnMondayMorning()
        {
            try
            {
                // Detect and log any forex difference exceeding 100 cents.

                FinancialAccounts allAccounts = FinancialAccounts.GetAll(); // across ALL ORGS!

                foreach (FinancialAccount account in allAccounts)
                {
                    // For every account, if it's based on foreign currency, check for forex gains/losses

                    if (account.ForeignCurrency != null)
                    {
                        account.CheckForexProfitLoss();
                    }
                }

                // Also check the bitcoin hotwallets for forex profit/loss as a special case of the above.

                Organizations allOrganizations = Organizations.GetAll();

                foreach (Organization organization in allOrganizations)
                {
                    FinancialAccount hotWalletAccount = organization.FinancialAccounts.AssetsBitcoinHot;

                    if (hotWalletAccount != null)
                    {
                        BitcoinUtility.CheckHotwalletForexProfitLoss(hotWalletAccount);
                    }
                }
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
                if (testMode)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
Example #10
0
        private static void OnEveryFiveMinutes()
        {
            try
            {
                BotLog.Write(0, "MainCycle", "Five-minute entry");

                try
                {
                    /*BotLog.Write(1, "FiveMinute", "Starting press release checker");
                     * TestTrace("Running PressReleaseChecker.Run()...");
                     * PressReleaseChecker.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*BotLog.Write(1, "FiveMinute", "Starting newsletter checker");
                     * TestTrace("Running NewsletterChecker.Run()...");
                     * NewsletterChecker.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*BotLog.Write(1, "FiveMinute", "Starting turnaround tracker");
                     * TestTrace("Running TurnaroundTracker.Run()...");
                     * TurnaroundTracker.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    // TestTrace(" done.\r\nRunning UpdateStatsCache.Run()...");
                    // UpdateStatsCache.Run();

                    /*TestTrace(" done.\r\nRunning TranslateUrls()...");
                     * TranslateUrls();*/

                    // Added during election rush 2010: clean up support database every five minutes instead of once a day
                    // SMS notifications for bounces are turned off, so people don't get SMS notifications in the middle of the night
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*BotLog.Write(1, "FiveMinute", "Closing delay warnings");
                     * TestTrace("Running SupportDatabase.CloseDelayWarnings()...");
                     * SupportDatabase.CloseDelayWarnings();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running SupportDatabase.NotifyBouncingEmails()...");
                     * BotLog.Write(1, "FiveMinute", "Notifying bouncing emails");
                     * SupportDatabase.NotifyBouncingEmails();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running SupportMailReview.Run()...");
                     * BotLog.Write(1, "FiveMinute", "Running support mail review");
                     * SupportMailReview.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }


                BotLog.Write(0, "MainCycle", "Five-minute exit");
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
                TestTrace(e.ToString());
            }
        }
Example #11
0
        private static void Main(string[] args)
        {
            testMode = false;

            UnixSignal[] killSignals =
            {
                new UnixSignal(Signum.SIGINT),
                new UnixSignal(Signum.SIGTERM)
            };

            BotLog.Write(0, "MainCycle", string.Empty);
            BotLog.Write(0, "MainCycle", "-----------------------------------------------");
            BotLog.Write(0, "MainCycle", string.Empty);

            if (args.Length > 0)
            {
                if (args[0].ToLower() == "test")
                {
/*
 *                  BotLog.Write(0, "MainCycle", "Running self-tests");
 *                  HeartBeater.Instance.Beat(heartbeatFile);  // Otherwise Heartbeater.Beat() will fail in various places
 *
 *                  testMode = true;
 *                  Console.WriteLine("Testing All Maintenance Processes (except membership-changing ones).");
 *                  PWLog.Write(PWLogItem.None, 0, PWLogAction.SystemTest, string.Empty, string.Empty);
 *
 *                  Console.WriteLine("\r\n10-second intervals:");
 *                  OnEveryTenSeconds();
 *                  Console.WriteLine("\r\nEvery minute:");
 *                  OnEveryMinute();
 *                  Console.WriteLine("\r\nEvery five minutes:");
 *                  OnEveryFiveMinutes();
 *                  Console.WriteLine("\r\nEvery hour:");
 *                  OnEveryHour();
 *                  Console.WriteLine("\r\nNoon:");
 *                  OnNoon();
 *                  Console.WriteLine("\r\nMidnight:");
 *                  OnMidnight();
 */

                    Console.WriteLine("Testing database access...");

                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).Name);
                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).PasswordHash);

                    Console.WriteLine("Creating OutboundComm...");

                    OutboundComm.CreateNotification(null, NotificationResource.System_Startup);

                    Console.WriteLine("Transmitting...");

                    OutboundComms comms = OutboundComms.GetOpen();

                    Console.WriteLine("{0} open items in outbound comms.", comms.Count);

                    foreach (OutboundComm comm in comms)
                    {
                        if (comm.TransmitterClass != "Swarmops.Utility.Communications.CommsTransmitterMail")
                        {
                            throw new NotImplementedException();
                        }

                        ICommsTransmitter transmitter = new CommsTransmitterMail();

                        OutboundCommRecipients recipients = comm.Recipients;
                        PayloadEnvelope        envelope   = PayloadEnvelope.FromXml(comm.PayloadXml);

                        foreach (OutboundCommRecipient recipient in recipients)
                        {
                            transmitter.Transmit(envelope, recipient.Person);
                        }
                    }


                    Console.Write("\r\nAll tests run. Waiting for mail queue to flush... ");
                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");
                    BotLog.Write(0, "MainCycle", "Exiting self-tests");
                    return;
                }

                if (args[0].ToLower() == "console")
                {
                    Console.WriteLine("\r\nRunning Swarmops-Backend in CONSOLE mode.\r\n");

                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------

                    // -----------------------    INSERT ANY ONE-OFF ACTIONS HERE  -------------------------


                    Console.Write("\r\nWaiting for mail queue to flush... ");

                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");

                    return;
                }

                if (args[0].ToLower() == "rsm")
                {
                    Console.WriteLine("Testing character encoding: räksmörgås RÄKSMÖRGÅS");
                    return;
                }
            }

            /*
             * MailMessage message = new MailMessage();
             * message.From = new MailAddress(Strings.MailSenderAddress, Strings.MailSenderName);
             * message.To.Add (new MailAddress ("*****@*****.**", "Rick Falkvinge (Piratpartiet)"));
             * message.Subject = "Räksmörgåsarnas ékÖNÖMÏåvdëlnïng";
             * message.Body = "Hejsan hoppsan Räksmörgåsar.";
             * message.BodyEncoding = Encoding.Default;
             * message.SubjectEncoding = Encoding.Default;
             *
             * SmtpClient smtpClient = new SmtpClient ("localhost");
             * smtpClient.Credentials = null; // mono bug
             * smtpClient.Send (message);*/

            Console.WriteLine(" * Swarmops Backend starting");

            BotLog.Write(0, "MainCycle", "Backend STARTING");

            OutboundComm.CreateNotification(null, NotificationResource.System_Startup);

            // Checking for schemata upgrade

            DatabaseMaintenance.UpgradeSchemata();

            // Check for existence of installation ID. If not, create one. Warning: has privacy implications when communicated.

            if (Persistence.Key["SwarmopsInstallationId"] == string.Empty)
            {
                Persistence.Key["SwarmopsInstallationId"] = Guid.NewGuid().ToString();
            }

            DateTime cycleStartTime = DateTime.Now;

            int lastSecond = cycleStartTime.Second;
            int lastMinute = cycleStartTime.Minute;
            int lastHour   = cycleStartTime.Hour;

            bool exitFlag = false;

            while (!exitFlag) // exit is handled by signals handling at end of loop
            {
                BotLog.Write(0, "MainCycle", "Cycle Start");

                cycleStartTime = DateTime.Now;

                try
                {
                    OnEveryTenSeconds();

                    if (cycleStartTime.Second < lastSecond)
                    {
                        OnEveryMinute();

                        if (cycleStartTime.Minute % 5 == 0)
                        {
                            OnEveryFiveMinutes();
                        }
                    }

                    if (cycleStartTime.Minute < lastMinute)
                    {
                        OnEveryHour();

                        if (DateTime.Now.Hour == 10 && DateTime.Today.DayOfWeek == DayOfWeek.Tuesday)
                        {
                            OnTuesdayMorning();
                        }
                    }

                    if (cycleStartTime.Hour >= 12 && lastHour < 12)
                    {
                        OnNoon();
                    }

                    if (cycleStartTime.Hour < lastHour)
                    {
                        OnMidnight();
                    }
                }

                catch (Exception e)
                {
                    // Note each "OnEvery..." catches its own errors and sends Exception mails,
                    // so that failure in one should not stop the others from running. This particular
                    // code should never run.

                    ExceptionMail.Send(new Exception("Failed in swarmops-backend main loop", e), true);
                }

                lastSecond = cycleStartTime.Second;
                lastMinute = cycleStartTime.Minute;
                lastHour   = cycleStartTime.Hour;

                // Wait for a maximum of ten seconds

                while (DateTime.Now < cycleStartTime.AddSeconds(10) && !exitFlag)
                {
                    // block until a SIGINT or SIGTERM signal is generated, or one second has passed.
                    int signalIndex = UnixSignal.WaitAny(killSignals, 1000);

                    if (signalIndex < 1000)
                    {
                        exitFlag = true;
                        Console.WriteLine("Caught signal " + killSignals[signalIndex].Signum + ", exiting");
                        BotLog.Write(0, "MainCycle",
                                     "EXIT SIGNAL (" + killSignals[signalIndex].Signum + "), terminating backend");
                    }
                }
            }

            Console.WriteLine(" * Swarmops Backend stopping");
            BotLog.Write(0, "MainCycle", "BACKEND EXITING, sending backend-termination notices");

            /*
             * if (HeartBeater.Instance.WasKilled)
             * {
             *  // removed unconditional delete, cron job that restarts bot uses it to know that it is intentionally down.
             *  ExceptionMail.Send(new Exception("HeartBeater triggered restart of Swarmops Backend. Will commence after 800 seconds."), false);
             * }*/

            BotLog.Write(0, "MainCycle", "...done");

            /*
             * while (!MailTransmitter.CanExit)
             * {
             *  System.Threading.Thread.Sleep(50);
             * }*/

            Thread.Sleep(2000);
        }
Example #12
0
        public static void Run()
        {
            BotLog.Write(1, "SeForumCheck", "Entering");

            Memberships    memberships   = Memberships.ForOrganization(Organization.PPSE);
            IForumDatabase forumDatabase = SwedishForumDatabase.GetDatabase();

            int[] accountIds;
            try
            {
                accountIds = forumDatabase.GetAccountList();
            }
            catch (Exception e)
            {
                ExceptionMail.Send(new Exception("Failed to connect to vBulletin", e), true);
                BotLog.Write(1, "SeForumCheck", "Failed to connect -- exiting");

                return;
            }

            BotLog.Write(1, "SeForumCheck", "Primed db - entering promotion cycle");

            Dictionary <int, bool> memberAccountLookup = new Dictionary <int, bool>();

            // This is kind of suboptimal, but hey, it only runs once a night in the wolf hour.

            Person currentMember = null;

            foreach (Membership membership in memberships)
            {
                if (!membership.Active)
                {
                    continue;
                }

                currentMember = membership.Person;

                try
                {
                    if (currentMember.SwedishForumAccountId != 0)
                    {
                        if (!forumDatabase.IsPartyMember(currentMember.SwedishForumAccountId))
                        {
                            // This guy is not listed as a party member, but should be.

                            BotLog.Write(2, "SeForumCheck", "Promoting " + currentMember.Name);
                            forumDatabase.SetPartyMember(currentMember.SwedishForumAccountId);
                        }

                        memberAccountLookup[currentMember.SwedishForumAccountId] = true;
                    }
                }
                catch (Exception e)
                {
                    // The forum account probably doesn't exist. Just remove it from the profile.

                    BotLog.Write(2, "SeForumCheck", "Exception reading " + currentMember.Name + ": " + e.ToString());

                    try
                    {
                        currentMember.SwedishForumAccountId = 0;
                    }
                    catch (Exception e2)
                    {
                        string logMessage = "Exception removing " + currentMember.Name + "'s forum account: " + e2.ToString();
                        BotLog.Write(2, "SeForumCheck", logMessage);
                        ExceptionMail.Send(new Exception(logMessage, e2));
                    }
                }
            }

            // Now that we have flagged all member accounts as member accounts, flag the rest as
            // non-party members.

            BotLog.Write(1, "SeForumCheck", "Promotion cycle done - entering demotion cycle");

            foreach (int accountId in accountIds)
            {
                if (!memberAccountLookup.ContainsKey(accountId))
                {
                    if (forumDatabase.IsPartyMember(accountId))
                    {
                        BotLog.Write(2, "SeForumCheck", "Demoting forum account " + forumDatabase.GetAccountName(accountId));
                        forumDatabase.SetPartyNonmember(accountId);
                    }
                }
            }
            BotLog.Write(1, "SeForumCheck", "Demotion cycle complete -- exiting");
        }
Example #13
0
        public static void Send(Newsletter newsletter, string forumUrl)
        {
            string directory = "content" + Path.DirectorySeparatorChar + "mailtemplate-" +
                               newsletter.TemplateId;

            string htmlTemplate = "Failed to read HTML mail template.";

            using (
                StreamReader reader = new StreamReader(directory + Path.DirectorySeparatorChar + "template.html",
                                                       Encoding.Default))
            {
                htmlTemplate = reader.ReadToEnd();
            }

            /*
             * using (StreamReader reader = new StreamReader(textTemplateFile, System.Text.Encoding.Default))
             * {
             *  textTemplate = reader.ReadToEnd();
             * }*/

            // PREPARE DATE

            // assume Swedish

            CultureInfo culture = new CultureInfo("sv-SE");
            string      date    = DateTime.Today.ToString("d MMMM yyyy", culture);


            // PREPARE HTML VIEW:

            // Write in the title, intro, and body

            htmlTemplate = htmlTemplate.
                           Replace("%TITLE%", HttpUtility.HtmlEncode(newsletter.Title.ToUpper())).
                           Replace("%title%", HttpUtility.HtmlEncode(newsletter.Title)).
                           Replace("%date%", HttpUtility.HtmlEncode(date)).
                           Replace("%DATE%", HttpUtility.HtmlEncode(date.ToUpper())).
                           Replace("%forumposturl%", forumUrl);

            string body = newsletter.Body;

            body = body.
                   Replace("<", "({[(").
                   Replace(">", ")}])").
                   Replace("\"", "quotQUOTquot");

            body = HttpUtility.HtmlEncode(body);

            body = body.
                   Replace("({[(", "<").
                   Replace(")}])", ">").
                   Replace("quotQUOTquot", "\"").
                   Replace("&amp;#", "&#");

            htmlTemplate = htmlTemplate.Replace("%body%", body);

            // Embed any inline images directly into the message

            string newsletterIdentifier = DateTime.Now.ToString("yyyyMMddhhMMssfff") + "@piratpartiet.se";

            // TODO: Read the replacements from a config file

            htmlTemplate = htmlTemplate.Replace("header-pp-logo.png", "cid:pplogo" + newsletterIdentifier);


            /*
             * htmlTemplate = htmlTemplate.Replace("TopRight.png", "cid:topright" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("MiddleRight.png", "cid:middleright" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("BottomRight.png", "cid:bottomright" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("TopLeft.png", "cid:topleft" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("MiddleLeft.png", "cid:middleleft" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("BottomLeft.png", "cid:bottomleft" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("TopMiddle.png", "cid:topmiddle" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("BottomMiddle.png", "cid:bottommiddle" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("PPShield.png", "cid:ppshield" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("Rick.png", "cid:rick" + newsletterIdentifier);
             * htmlTemplate = htmlTemplate.Replace("RFe-signature.gif", "cid:rick-signature" + newsletterIdentifier);*/


            // MemoryStream memStream = new MemoryStream();

            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlTemplate,
                                                                                 new ContentType(
                                                                                     MediaTypeNames.Text.Html));

            htmlView.TransferEncoding = TransferEncoding.Base64;

            /*
             * LinkedResource image = new LinkedResource(directory + Path.DirectorySeparatorChar + "header-pp-logo.png");
             * image.ContentId = "pplogo" + newsletterIdentifier;
             * htmlView.LinkedResources.Add(image);*/


            /*
             * -- DISABLED -- code writing a forum-style text file
             *
             *
             * // PREPARE FORUM FILE:
             *
             * string forumTemplate = textTemplate.
             *  Replace("%TITLE%", "[h1]" + title.ToUpper() + "[/h1]").
             *  Replace("%title%", "[h1]" + title + "[/h1]").
             *  Replace("%intro%", intro).
             *  Replace("%body%", mailBody);
             *
             * // Replace "<a href="http://link">Text</a>" with "Text (http://link)"
             *
             * Regex regexLinksForum = new Regex("(?s)\\[a\\s+href=\\\"(?<link>[^\\\"]+)\\\"\\](?<description>[^\\[]+)\\[/a\\]", RegexOptions.Multiline);
             *
             * forumTemplate = regexLinksForum.Replace(forumTemplate, new MatchEvaluator(NewsletterTransmitter2.RewriteUrlsInForum));
             *
             * using (StreamWriter writer = new StreamWriter(directory + "\\" + "forum.txt", false, System.Text.Encoding.Default))
             * {
             *  writer.WriteLine(forumTemplate);
             * }*/


            /*
             *  -- DISABLED -- no text view
             *
             *
             *
             * // PREPARE TEXT VIEW:
             *
             * // Write in the title, intro, and body
             *
             * textTemplate = textTemplate.
             *  Replace("%TITLE%", title.ToUpper()).
             *  Replace("%title%", title).
             *  Replace("%intro%", intro).
             *  Replace("%body%", mailBody);
             *
             * // Replace "<a href="http://link">Text</a>" with "Text (http://link)"
             *
             * Regex regexLinks = new Regex("(?s)\\[a\\s+href=\\\"(?<link>[^\\\"]+)\\\"\\](?<description>[^\\[]+)\\[/a\\]", RegexOptions.Multiline);
             *
             * textTemplate = regexLinks.Replace(textTemplate, new MatchEvaluator(NewsletterTransmitter2.RewriteUrlsInText));
             *
             * Regex regexHtmlCodes = new Regex("(?s)\\[[^\\[]+\\]", RegexOptions.Multiline);
             *
             * textTemplate = regexHtmlCodes.Replace(textTemplate, string.Empty);
             *
             * ContentType typeUnicode = new ContentType(MediaTypeNames.Text.Plain);
             * typeUnicode.CharSet = "utf-8";
             *
             * AlternateView textUnicodeView = AlternateView.CreateAlternateViewFromString(textTemplate, typeUnicode);
             *
             * ContentType typeIsoLatin1 = new ContentType(MediaTypeNames.Text.Plain);
             * typeIsoLatin1.CharSet = "iso-8859-1";
             *
             * AlternateView textHotmailView = new AlternateView(new MemoryStream(Encoding.Default.GetBytes(textTemplate)), typeIsoLatin1);
             *
             * */

            foreach (Person recipient in newsletter.Recipients)
            {
                //Console.Write (recipient.Name + "(#" + recipient.Identity.ToString() + ")... ");

                if (recipient.Mail.Length < 2)
                {
                    //Console.WriteLine("canceled.");
                    continue; // no email on file
                }

                if (recipient.NeverMail)
                {
                    //Console.WriteLine("canceled.");
                    continue; // This person has a total mail block on his or her mail
                }

                try
                {
                    SmtpClient client = new SmtpClient(Config.SmtpHost, Config.SmtpPort);
                    client.Credentials = null;

                    MailMessage message = new MailMessage(
                        new MailAddress(newsletter.SenderAddress, qp8859.EncodeMailHeaderString(newsletter.SenderName),
                                        Encoding.GetEncoding("ISO-8859-1")),
                        new MailAddress(recipient.Mail, qp8859.EncodeMailHeaderString(recipient.Name),
                                        Encoding.GetEncoding("ISO-8859-1")));

                    message.Subject = "Piratpartiet: Nyhetsbrev " + DateTime.Today.ToString("yyyy-MM-dd");  // HACK

                    message.Body         = htmlTemplate;
                    message.BodyEncoding = Encoding.ASCII;
                    message.IsBodyHtml   = true;

                    // COMPENSATE FOR MONO BUG -- put logo online instead of attached

                    message.Body = message.Body.Replace("cid:pplogo" + newsletterIdentifier,
                                                        "http://docs.piratpartiet.se/banners/newsletter-banner-pp-logo.png");

                    /*
                     * Attachment attachment = new Attachment(directory + Path.DirectorySeparatorChar + "header-pp-logo.png", "image/png");
                     * attachment.ContentId = "pplogo" + newsletterIdentifier;
                     * attachment.ContentDisposition.Inline = true;
                     * message.Attachments.Add(attachment);*/

                    string personEmail = recipient.Mail.Trim().ToLower();

                    string identifier = " [PP" + recipient.HexIdentifier() + "]";

                    message.Subject += identifier;

                    bool successOrPermanentFail = false;

                    while (!successOrPermanentFail)
                    {
                        try
                        {
                            client.Send(message);
                            successOrPermanentFail = true;
                        }
                        catch (SmtpException e)
                        {
                            if (!(e.ToString().StartsWith("System.Net.Mail.SmtpException: 4")))
                            {
                                // This is NOT a temporary error (SMTP 4xx). Fail.

                                successOrPermanentFail = true;
                                throw e;
                            }

                            // Otherwise, sleep for a while and try again.

                            Thread.Sleep(1000);
                        }
                    }

                    //Console.WriteLine("ok");
                }
                catch (Exception e)
                {
                    //Console.WriteLine("FAIL! <" + recipient.Email + ">");
                    ExceptionMail.Send(
                        new Exception(
                            "Error sending mail to " + recipient.Name + " (#" + recipient.Identity + ") <" +
                            recipient.Mail + ">:", e));
                }
            }
        }
Example #14
0
 private static void TraceAndReport(Exception e)
 {
     TestTrace(" failed.\r\n");
     ExceptionMail.Send(e, true);
     TestTrace(e.ToString());
 }
Example #15
0
        private static void OnMidnight()
        {
            try
            {
                BotLog.Write(0, "MainCycle", "Midnight entry");

                try
                {
                    if (!testMode)
                    {
                        /*TestTrace("Running RosterHousekeeping.ChurnExpiredMembers()...");
                         * RosterHousekeeping.ChurnExpiredMembers();
                         * TestTrace(" done.\r\n");*/
                    }

                    ExchangeRateSnapshot.Create();
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running InternalPollMaintenance.Run()...");
                     * InternalPollMaintenance.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running SwedishForumMemberCheck.Run()...");
                     * SwedishForumMemberCheck.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running SalaryProcessor.Run()...");
                     * SalaryProcessor.Run();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running TurnaroundTracker.Housekeeping()...");
                     * TurnaroundTracker.Housekeeping();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running Mappery.CreateUngPiratUptakeMap()...");
                     * Mappery.CreateUngPiratUptakeMap();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                try
                {
                    /*TestTrace("Running RosterHousekeeping.TimeoutVolunteers()...");
                     * RosterHousekeeping.TimeoutVolunteers();
                     * TestTrace(" done.\r\n");*/
                }
                catch (Exception e)
                {
                    TraceAndReport(e);
                }

                BotLog.Write(0, "MainCycle", "Midnight exit");
            }
            catch (Exception e)
            {
                ExceptionMail.Send(e, true);
                TestTrace(e.ToString());
            }
        }
Example #16
0
        /// <summary>
        /// 發exception信件
        /// </summary>
        /// <param name="ex">The ex.</param>
        protected void NotifyException(Exception ex, string input = "")
        {
            IMail exMail = new ExceptionMail(ex, input);

            exMail.SendMail();
        }
Example #17
0
        /// <summary>
        /// 發exception信件
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="account">The account.</param>
        /// <param name="ctx">The CTX.</param>
        protected void NotifyException(Exception ex, string account, HttpContext ctx, string input = "")
        {
            IMail exMail = new ExceptionMail(ex, account, ctx, input);

            exMail.SendMail();
        }
Example #18
0
        private static void Main(string[] args)
        {
            // Are we running yet?

            if (!SystemSettings.DatabaseInitialized)
            {
                // will restart the service every 15s until db initialized on OOBE
                // also, the read of DatabaseInitialized can and will fail if
                // we're not initalized enough to even have a database

                throw new InvalidOperationException();
            }

            // Checking for schemata upgrade first of all, after seeing that db exists

            int startupDbVersion = Database.SwarmDb.DbVersion;

            DatabaseMaintenance.UpgradeSchemata();

            testMode = false;

            SystemSettings.BackendHostname = Dns.GetHostName();


            // Other one-time initializations

            FinancialTransactions.FixAllUnsequenced();
            SupportFunctions.OperatingTopology = OperatingTopology.Backend;

            // Begin main loop

            UnixSignal[] killSignals = null;

            if (!Debugger.IsAttached)
            {
                killSignals = new UnixSignal[] { new UnixSignal(Signum.SIGINT), new UnixSignal(Signum.SIGTERM) };
            }

            BotLog.Write(0, "MainCycle", string.Empty);
            BotLog.Write(0, "MainCycle", "-----------------------------------------------");
            BotLog.Write(0, "MainCycle", string.Empty);

            if (args.Length > 0)
            {
                if (args[0].ToLower() == "test")
                {
/*
 *                  BotLog.Write(0, "MainCycle", "Running self-tests");
 *                  HeartBeater.Instance.Beat(heartbeatFile);  // Otherwise Heartbeater.Beat() will fail in various places
 *
 *                  testMode = true;
 *                  Console.WriteLine("Testing All Maintenance Processes (except membership-changing ones).");
 *                  PWLog.Write(PWLogItem.None, 0, PWLogAction.SystemTest, string.Empty, string.Empty);
 *
 *                  Console.WriteLine("\r\n10-second intervals:");
 *                  OnEveryTenSeconds();
 *                  Console.WriteLine("\r\nEvery minute:");
 *                  OnEveryMinute();
 *                  Console.WriteLine("\r\nEvery five minutes:");
 *                  OnEveryFiveMinutes();
 *                  Console.WriteLine("\r\nEvery hour:");
 *                  OnEveryHour();
 *                  Console.WriteLine("\r\nNoon:");
 *                  OnNoon();
 *                  Console.WriteLine("\r\nMidnight:");
 *                  OnMidnight();
 */

                    Console.WriteLine("Testing database access...");

                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).Name);
                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).PasswordHash);

                    Console.WriteLine("Creating OutboundComm...");

                    OutboundComm.CreateNotification(null, NotificationResource.System_Startup_Backend);

                    Console.WriteLine("Transmitting...");

                    OutboundComms comms = OutboundComms.GetOpen();

                    Console.WriteLine("{0} open items in outbound comms.", comms.Count);

                    foreach (OutboundComm comm in comms)
                    {
                        if (comm.TransmitterClass != "Swarmops.Utility.Communications.CommsTransmitterMail")
                        {
                            throw new NotImplementedException();
                        }

                        ICommsTransmitter transmitter = new CommsTransmitterMail();

                        OutboundCommRecipients recipients = comm.Recipients;
                        PayloadEnvelope        envelope   = PayloadEnvelope.FromXml(comm.PayloadXml);

                        foreach (OutboundCommRecipient recipient in recipients)
                        {
                            transmitter.Transmit(envelope, recipient.Person);
                        }
                    }


                    Console.Write("\r\nAll tests run. Waiting for mail queue to flush... ");
                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");
                    BotLog.Write(0, "MainCycle", "Exiting self-tests");
                    return;
                }

                if (args[0].ToLower() == "console")
                {
                    Console.WriteLine("\r\nRunning Swarmops-Backend in CONSOLE mode.\r\n");

                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------

                    // -----------------------    INSERT ANY ONE-OFF ACTIONS HERE  -------------------------


                    Console.Write("\r\nWaiting for mail queue to flush... ");

                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");

                    return;
                }

                if (args[0].ToLowerInvariant() == "pdfregen")
                {
                    if (args.Length > 1)
                    {
                        int docId = Int32.Parse(args[1]);
                        PdfProcessor.Rerasterize(Document.FromIdentity(docId));
                    }
                    else
                    {
                        Console.WriteLine("Regenerating all bitmaps from PDF uploads.");
                        PdfProcessor.RerasterizeAll();
                        Console.WriteLine("Done.");
                    }

                    return;
                }


                if (args[0].ToLower() == "rsm")
                {
                    Console.WriteLine("Testing character encoding: räksmörgås RÄKSMÖRGÅS");
                    return;
                }
            }

            /*
             * MailMessage message = new MailMessage();
             * message.From = new MailAddress(Strings.MailSenderAddress, Strings.MailSenderName);
             * message.To.Add (new MailAddress ("*****@*****.**", "Rick Falkvinge (Piratpartiet)"));
             * message.Subject = "Räksmörgåsarnas ékÖNÖMÏåvdëlnïng";
             * message.Body = "Hejsan hoppsan Räksmörgåsar.";
             * message.BodyEncoding = Encoding.Default;
             * message.SubjectEncoding = Encoding.Default;
             *
             * SmtpClient smtpClient = new SmtpClient ("localhost");
             * smtpClient.Credentials = null; // mono bug
             * smtpClient.Send (message);*/

            Console.WriteLine(" * Swarmops Backend starting");

            BotLog.Write(0, "MainCycle", "Backend STARTING");

            // Disable certificate checking due to Mono not installing with a certificate repository - this is UTTERLY broken

            SupportFunctions.DisableSslCertificateChecks(); // MONO BUG/MISFEATURE: Mono has no root certificates, so can't verify cert

            // Tell sysop we're starting

            OutboundComm.CreateNotification(null, NotificationResource.System_Startup_Backend);

            // Check for existence of installation ID. If not, create one. Warning: has privacy implications when communicated.

            if (Persistence.Key["SwarmopsInstallationId"] == string.Empty)
            {
                Persistence.Key["SwarmopsInstallationId"] = Guid.NewGuid().ToString();
            }

            // Check for existence of bitcoin hotwallet root

            BitcoinUtility.VerifyBitcoinHotWallet();

            // Initialize backend socket server

            int backendSocketPort = SystemSettings.WebsocketPortBackend;

            _socketServer = new WebSocketServer(backendSocketPort);
            _socketServer.AddWebSocketService <BackendServices>("/Backend");
            _socketServer.Start();

            // Initialize socket client to Blockchain.Info (pending our own services)

            using (
                _blockChainInfoSocket =
                    new WebSocket("wss://ws.blockchain.info/inv?api_code=" + SystemSettings.BlockchainSwarmopsApiKey))
            {
                // Begin maintenance loop

                DateTime cycleStartTime = DateTime.UtcNow;
                DateTime cycleEndTime;

                int lastSecond = cycleStartTime.Second;
                int lastMinute = cycleStartTime.Minute;
                int lastHour   = cycleStartTime.Hour;

                bool exitFlag = false;

                _blockChainInfoSocket.OnOpen    += new EventHandler(OnBlockchainOpen);
                _blockChainInfoSocket.OnError   += new EventHandler <ErrorEventArgs>(OnBlockchainError);
                _blockChainInfoSocket.OnClose   += new EventHandler <CloseEventArgs>(OnBlockchainClose);
                _blockChainInfoSocket.OnMessage += new EventHandler <MessageEventArgs>(OnBlockchainMessage);

                _blockChainInfoSocket.Connect();

                while (!exitFlag) // exit is handled by signals handling at end of loop
                {
                    BotLog.Write(0, "MainCycle", "Cycle Start");

                    cycleStartTime = DateTime.UtcNow;
                    cycleEndTime   = cycleStartTime.AddSeconds(10);

                    try
                    {
                        OnEveryTenSeconds();

                        if (cycleStartTime.Second < lastSecond)
                        {
                            OnEveryMinute();

                            if (cycleStartTime.Minute % 5 == 0)
                            {
                                OnEveryFiveMinutes();
                            }
                        }

                        if (cycleStartTime.Minute < lastMinute)
                        {
                            OnEveryHour();

                            if (DateTime.Now.Hour == 10 && DateTime.Today.DayOfWeek == DayOfWeek.Tuesday)
                            {
                                OnTuesdayMorning();
                            }

                            if (DateTime.Now.Hour == 7 && DateTime.Today.DayOfWeek == DayOfWeek.Monday)
                            {
                                OnMondayMorning();
                            }
                        }

                        if (cycleStartTime.Hour >= 12 && lastHour < 12)
                        {
                            OnNoon();
                        }

                        if (cycleStartTime.Hour < lastHour)
                        {
                            OnMidnight();
                        }
                    }

                    catch (Exception e)
                    {
                        // Note each "OnEvery..." catches its own errors and sends Exception mails,
                        // so that failure in one should not stop the others from running. This particular
                        // code should never run.

                        ExceptionMail.Send(new Exception("Failed in swarmops-backend main loop", e), true);
                    }

                    lastSecond = cycleStartTime.Second;
                    lastMinute = cycleStartTime.Minute;
                    lastHour   = cycleStartTime.Hour;

                    // Wait for a maximum of ten seconds (the difference between cycleStartTime and cycleEndTime)

                    int      iterationCount = 0;
                    DateTime utcNow         = DateTime.UtcNow;
                    while (utcNow < cycleEndTime && !exitFlag)
                    {
                        int signalIndex = 250;

                        // Handle important service orders (those that can't be lost in a random loss
                        // of connection of a socket):

                        BackendServiceOrders backendOrders = BackendServiceOrders.GetNextBatch(5);
                        backendOrders.Execute(); // takes at most 250ms per BSO reqs

                        // Block until a SIGINT or SIGTERM signal is generated, or 1/4 second has passed.
                        // However, we can't do that in a development environment - it won't have the
                        // Mono.Posix assembly, and won't understand UnixSignals. So people running this in
                        // a dev environment will need to stop it manually.

                        if (!Debugger.IsAttached)
                        {
                            signalIndex = UnixSignal.WaitAny(killSignals, 250);
                        }
                        else
                        {
                            TimeSpan timeLeft = (cycleEndTime - utcNow);

                            BotLog.Write(0, "MainCycle Debug",
                                         string.Format(CultureInfo.InvariantCulture,
                                                       "Waiting for {0:F2} more seconds for cycle end",
                                                       timeLeft.TotalMilliseconds / 1000.0));
                            Thread.Sleep(250);
                        }

                        if (signalIndex < 250)
                        {
                            exitFlag = true;
                            Console.WriteLine("Caught signal " + killSignals[signalIndex].Signum + ", exiting");
                            BotLog.Write(0, "MainCycle",
                                         "EXIT SIGNAL (" + killSignals[signalIndex].Signum + "), terminating backend");
                        }

                        utcNow = DateTime.UtcNow;

                        // Every second, send an internal heartbeat

                        if (iterationCount++ % 4 == 0)
                        {
                            InternalHeartbeat();
                        }
                    }
                }
            }

            Console.WriteLine(" * Swarmops Backend stopping");
            BotLog.Write(0, "MainCycle", "BACKEND EXITING, sending backend-termination notices");

            /*
             * if (HeartBeater.Instance.WasKilled)
             * {
             *  // removed unconditional delete, cron job that restarts bot uses it to know that it is intentionally down.
             *  ExceptionMail.Send(new Exception("HeartBeater triggered restart of Swarmops Backend. Will commence after 800 seconds."), false);
             * }*/

            BotLog.Write(0, "MainCycle", "...done");

            /*
             * while (!MailTransmitter.CanExit)
             * {
             *  System.Threading.Thread.Sleep(50);
             * }*/

            _socketServer.Stop();

            Thread.Sleep(2000);
        }
Example #19
0
        public static void RemindExpiriesMail()
        {
            // Get expiring

            Console.WriteLine("Inside RemindExpiriesMail()");

            Organizations orgs = Organizations.GetAll();

            Dictionary <int, bool>   personLookup = new Dictionary <int, bool>();
            Dictionary <string, int> dateLookup   = new Dictionary <string, int>();

            DateTime      lowerBound      = DateTime.Today;
            DateTime      upperBound      = lowerBound.AddDays(31);
            List <string> failedReminders = new List <string>();

            int weekDayInteger = (int)DateTime.Today.DayOfWeek;

            foreach (Organization org in orgs)
            {
                Memberships memberships = Memberships.GetExpiring(org, lowerBound, upperBound);

                foreach (Membership membership in memberships)
                {
                    if (membership.OrganizationId % 7 != weekDayInteger)
                    {
                        continue;
                    }

                    try
                    {
                        Console.Write("Reminding " + membership.Person.Canonical + " about " +
                                      membership.Organization.Name + ".");
                        SendReminderMail(membership);
                        Console.Write(".");
                        PWLog.Write(PWLogItem.Person, membership.PersonId,
                                    PWLogAction.MembershipRenewReminder,
                                    "Mail was sent to " + membership.Person.Mail +
                                    " reminding to renew membership in " + membership.Organization.Name + ".", string.Empty);

                        Console.Write(".");

                        string dateString = membership.Expires.ToString("yyyy-MM-dd");
                        if (!dateLookup.ContainsKey(dateString))
                        {
                            dateLookup[dateString] = 0;
                        }
                        dateLookup[dateString]++;

                        Console.WriteLine(" done.");
                    }
                    catch (Exception x)
                    {
                        string logText = "FAILED sending mail to " + membership.Person.Mail +
                                         " for reminder of pending renewal in " + membership.Organization.Name + ".";
                        failedReminders.Add(membership.Person.Canonical);
                        PWLog.Write(PWLogItem.Person, membership.PersonId,
                                    PWLogAction.MembershipRenewReminder,
                                    logText, string.Empty);
                        ExceptionMail.Send(new Exception(logText, x));
                    }
                }
            }

            string notifyBody = String.Format("Sending renewal reminders to {0} people:\r\n\r\n", personLookup.Count);

            Console.WriteLine("Sending renewal reminders to {0} people", personLookup.Count);

            List <string> dateSummary = new List <string>();
            int           total       = 0;

            foreach (string dateString in dateLookup.Keys)
            {
                dateSummary.Add(string.Format("{0}: {1,5}", dateString, dateLookup[dateString]));
                total += dateLookup[dateString];
            }

            dateSummary.Sort();

            foreach (string dateString in dateSummary)
            {
                notifyBody += dateString + "\r\n";
                Console.WriteLine(dateString);
            }

            notifyBody += string.Format("Total sent: {0,5}\r\n\r\n", total);
            Console.WriteLine("Total sent: {0,5}\r\n\r\n", total);

            notifyBody += "FAILED reminders:\r\n";
            Console.WriteLine("FAILED reminders:");

            foreach (string failed in failedReminders)
            {
                notifyBody += failed + "\r\n";
                Console.WriteLine(failed);
            }

            if (failedReminders.Count == 0)
            {
                notifyBody += "none.\r\n";
                Console.WriteLine("none.");
            }

            /* no. just no. we should do a global search for "FromIdentity(1)"
             * Person.FromIdentity(1).SendOfficerNotice("Reminders sent today", notifyBody, 1);  */
        }
Example #20
0
        internal static OutboundMailRecipient TransmitOneMail(OutboundMailRecipient recipient)
        {
            try
            {
                // If the mail address in illegal format, do not try to send anything:
                if (!Formatting.ValidateEmailFormat(recipient.EmailPerson.Email.Trim()))
                {
                    string msg = "Invalid email address:\r\nEmailPerson [" + recipient.EmailPerson.Identity +
                                 "], mail [" +
                                 recipient.EmailPerson.Email + "]\r\nwill not send mail:" + recipient.OutboundMail.Title;
                    throw new InvalidRecipientException(msg, null);
                }

                // If the mail address is marked as unreachable, do not try to send anything
                if (recipient.Person != null && recipient.Person.MailUnreachable)
                {
                    string msg = "MailUnreachable email address:\r\nEmailPerson [" + recipient.EmailPerson.Identity +
                                 "], mail [" +
                                 recipient.EmailPerson.Email + "]\r\nwill not send mail:" + recipient.OutboundMail.Title;
                    throw new InvalidRecipientException(msg, null);
                }

                // If the mail address is marked as unreachable, do not try to send anything
                if (recipient.Person != null && recipient.Person.NeverMail)
                {
                    string msg = "NeverMail email address:\r\nEmailPerson [" + recipient.EmailPerson.Identity +
                                 "], mail [" +
                                 recipient.EmailPerson.Email + "]\r\nwill not send mail:" + recipient.OutboundMail.Title;
                    throw new IgnoreRecipientException(msg, null);
                }


                // Otherwise, let's start processing

                OutboundMail mail = recipient.OutboundMail;

                bool     limitToLatin1   = false;
                bool     limitToText     = false;
                Encoding currentEncoding = Encoding.UTF8;

                string email = recipient.EmailPerson.Email.ToLower();


                if (mail.MailType == 0 || mail.TemplateName.EndsWith("Plain"))
                {
                    limitToText = true;
                }

                // TEST: Does this user require the use of a text-only message (as opposed to multipart/alternative)?
                if (recipient.Person != null && recipient.Person.LimitMailToText)
                {
                    limitToText = true;
                }

                // This is supposedly not a problem anymore
                //if (email.EndsWith("@hotmail.com") || email.EndsWith("@msn.com"))
                //{
                //    limitToLatin1 = true;
                //}

                // TEST: Does this user require the limited use of the Latin-1 charset (as opposed to Unicode?)
                if (recipient.Person != null && recipient.Person.LimitMailToLatin1)
                {
                    limitToLatin1 = true;
                }

                // Capability tests end here

                if (limitToLatin1)
                {
                    currentEncoding = Encoding.GetEncoding("ISO-8859-1");
                }
                else
                {
                    currentEncoding = Encoding.UTF8;
                }

                QuotedPrintable qp = QuotedPrintableEncoder[currentEncoding];


                MailMessage message = new MailMessage();

                if (mail.AuthorType == MailAuthorType.Person)
                {
                    try
                    {
                        message.From = new MailAddress(mail.Author.PartyEmail,
                                                       qp.EncodeMailHeaderString(mail.Author.Name + " (" + mail.Organization.MailPrefixInherited +
                                                                                 ")"),
                                                       currentEncoding);

                        if (mail.Author.Identity == 1)
                        {
                            //TODO: Create alternative party mail optional data field, or organization chairman (based on roles) differently
                            // Ugly hack
                            message.From = new MailAddress("*****@*****.**",
                                                           qp.EncodeMailHeaderString(mail.Author.Name + " (" +
                                                                                     mail.Organization.MailPrefixInherited + ")"),
                                                           currentEncoding);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidSenderException(
                                  "Invalid author address in MailProcessor.TransmitOneMail:" + (mail.AuthorPersonId) + ";" +
                                  mail.Author.PartyEmail, ex);
                    }
                }
                else
                {
                    try
                    {
                        FunctionalMail.AddressItem aItem =
                            mail.Organization.GetFunctionalMailAddressInh(mail.AuthorType);
                        message.From = new MailAddress(aItem.Email, qp.EncodeMailHeaderString(aItem.Name),
                                                       currentEncoding);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidSenderException(
                                  "Unknown MailAuthorType in MailProcessor.TransmitOneMail:" + ((int)mail.AuthorType), ex);
                    }
                }


                if (recipient.AsOfficer && recipient.Person != null)
                {
                    try
                    {
                        message.To.Add(new MailAddress(recipient.Person.PartyEmail,
                                                       qp.EncodeMailHeaderString(recipient.Person.Name + " (" +
                                                                                 mail.Organization.MailPrefixInherited + ")"),
                                                       currentEncoding));
                    }
                    catch (FormatException e)
                    {
                        string msg = "Invalid officer email address:\r\nperson [" + recipient.Person.Identity +
                                     "], mail [" +
                                     recipient.Person.PartyEmail + "]\r\nwill not send mail:" +
                                     recipient.OutboundMail.Title;
                        throw new InvalidRecipientException(msg, e);
                    }
                }
                else
                {
                    try
                    {
                        message.To.Add(new MailAddress(recipient.EmailPerson.Email,
                                                       qp.EncodeMailHeaderString(recipient.EmailPerson.Name),
                                                       currentEncoding));
                    }
                    catch (FormatException e)
                    {
                        string msg = "Invalid email address:\r\nEmailPerson [" + recipient.EmailPerson.Identity +
                                     "], mail [" +
                                     recipient.EmailPerson.Email + "]\r\nwill not send mail:" +
                                     recipient.OutboundMail.Title;
                        throw new InvalidRecipientException(msg, e);
                    }
                }

                string culture = mail.Organization.DefaultCountry.Culture;

                // UGLY UGLY UGLY HACK, NEEDS TO CHANGE ASAP:
                // We need to determine the culture of the recipient in order to use the right template. However, this is also dependent on the text body, which needs to be
                // in the same culture. At this point, we don't have the mail/recipient cultures in the schema. This would be the correct solution.

                // The INCORRECT but working solution is to do as we do here and check if a) it's a reporter and b) the reporter has International/English as a category. If so,
                // we change the culture to en-US. It's an ugly as all hell hack but it should work as a temporary stopgap.

                if (recipient.Reporter != null)
                {
                    MediaCategories categories = recipient.Reporter.MediaCategories;

                    foreach (MediaCategory category in categories)
                    {
                        if (category.Name == "International/English")
                        {
                            culture = Strings.InternationalCultureCode;
                            break;
                        }
                    }
                }

                if (limitToText)
                {
                    // if just text, then just add a plaintext body;
                    string text = "";

                    //Cant really see any reson the HtmlAgilityPack shouldn't be thread safe, but what the heck, just in case..
                    lock (lockObject)
                    {
                        try
                        {
                            text = mail.RenderText(recipient.EmailPerson, culture);
                        }
                        catch (Exception ex)
                        {
                            throw new RemoveRecipientException(
                                      "TextRendering failed for " + mail.Title + " to " + recipient.EmailPerson.Email +
                                      " will not retry.\n", ex);
                        }
                    }
                    message.BodyEncoding = currentEncoding;
                    message.Body         = text;
                }
                else
                {
                    // otherwise, add a multipart/alternative with text and HTML
                    string text = "";
                    string html = "";

                    //Cant really see any reson the HtmlAgilityPack shouldn't be thread safe, but what the heck, just in case..
                    Exception ex = null;
                    lock (lockObject)
                    {
                        try
                        {
                            text = mail.RenderText(recipient.EmailPerson, culture);
                            html = mail.RenderHtml(recipient.EmailPerson, culture);
                        }
                        catch (Exception e)
                        {
                            ex = e;
                        }
                    }
                    if (text == "")
                    {
                        throw new RemoveRecipientException(
                                  "Rendering (text) failed for " + mail.Title + " to " + recipient.EmailPerson.Email +
                                  " will not retry.\n", ex);
                    }
                    if (html == "" || ex != null)
                    {
                        throw new RemoveRecipientException(
                                  "Rendering (html) failed for " + mail.Title + " to " + recipient.EmailPerson.Email +
                                  " will not retry.\n", ex);
                    }

                    ContentType textContentType = new ContentType(MediaTypeNames.Text.Plain);
                    textContentType.CharSet = currentEncoding.BodyName;

                    ContentType htmlContentType = new ContentType(MediaTypeNames.Text.Html);
                    htmlContentType.CharSet = currentEncoding.BodyName;

                    AlternateView textView = null;
                    AlternateView htmlView = null;


                    if (limitToLatin1)
                    {
                        textView = new AlternateView(new MemoryStream(currentEncoding.GetBytes(text)),
                                                     textContentType);
                        htmlView = new AlternateView(new MemoryStream(currentEncoding.GetBytes(text)),
                                                     htmlContentType);
                    }
                    else
                    {
                        textView = AlternateView.CreateAlternateViewFromString(text, textContentType);
                        htmlView = AlternateView.CreateAlternateViewFromString(html, htmlContentType);
                    }

                    // A f*****g stupid Mono bug forces us to transfer-encode in base64: it can't encode qp properly
                    // (the "=" is not encoded to "=3D")

                    htmlView.TransferEncoding = TransferEncoding.Base64;
                    textView.TransferEncoding = TransferEncoding.Base64;

                    // Add the views in increasing order of preference

                    message.AlternateViews.Add(textView);
                    message.AlternateViews.Add(htmlView);
                }

                if (mail.AuthorType == MailAuthorType.PirateWeb)
                {
                    message.Subject = mail.Title;
                }
                else if (mail.MailType == 0)
                {
                    message.Subject = mail.Organization.MailPrefixInherited + ": " + mail.Title;
                }
                else
                {
                    //Title is set up in template processing in OutboundMail rendering.
                    message.Subject = mail.Title;
                }

                message.SubjectEncoding = currentEncoding;

                string smtpServer = ConfigurationManager.AppSettings["SmtpServer"];

                if (Debugger.IsAttached)
                {
                    Debug.WriteLine("sending " + message.Subject + " to " + recipient.EmailPerson.Email);
                    Thread.Sleep(200);  //simulate delay
                }


                if (smtpServer.ToLower() != "none")
                {
                    if (smtpServer == null || smtpServer.Length < 2)
                    {
                        smtpServer = "localhost";
                    }

                    try
                    {
                        SmtpClient client = new SmtpClient(smtpServer, 25);
                        client.Send(message);
                    }
                    catch (SmtpException e)
                    {
                        if (e.ToString().StartsWith("System.Net.Mail.SmtpException: 4"))
                        {
                            // Temporary error (SMTP 4xx). Try again.

                            Thread.Sleep(2000);  // Allow 2 seconds pause to wait for smtp-server to become available
                            throw new ReportAndRetryRecipientException("Temporary smtp error, will retry.", e);
                        }

                        // Otherwise, bad recipient (assume so). Have the mail removed from the queue.

                        List <string> recipients = new List <string>();
                        foreach (MailAddress address in message.To)
                        {
                            recipients.Add(address.Address);
                        }

                        ExceptionMail.Send(
                            new ArgumentException(
                                "Bad Recipients when sending to " + recipient.EmailPerson.Email + ": " +
                                String.Join(", ", recipients.ToArray()), e));

                        if (mail.AuthorType == MailAuthorType.Person)
                        {
                            try
                            {
                                mail.Author.SendOfficerNotice(
                                    "Failed recipient(s): " + String.Join(", ", recipients.ToArray()),
                                    "Some recipients failed inexplicably in a mail from you.", 1);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Failed to SendOfficerNotice to :" + mail.AuthorPersonId, ex);
                            }
                        }
                    }
                }
                return(recipient); // To pass this object onto the we're-done callback
            }
            catch (InvalidRecipientException ex)
            {
                throw ex;
            }
            catch (RetryRecipientException ex)
            {
                Thread.Sleep(2000);
                // Allow 2 seconds pause to avoid flooding the errorlog too fast in case of a permanent failure
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Example #21
0
        private static void CheckOneFeed(string readerUrl, string persistAsKey, int orgIdForTemplate)
        {
            string persistenceKey = String.Format("Pressrelease-Highwater-{0}", persistAsKey);

            DateTime highWaterMark = DateTime.MinValue;

            RssReader reader = null;

            try
            {
                string highWaterMarkString = Persistence.Key[persistenceKey];

                if (string.IsNullOrEmpty(highWaterMarkString))
                {
                    //Initialize highwatermark if never used
                    highWaterMark = DateTime.Now;
                    Persistence.Key[persistenceKey] = DateTime.Now.ToString();
                }
                else
                {
                    try
                    {
                        highWaterMark = DateTime.Parse(highWaterMarkString);
                    }
                    catch (Exception ex)
                    {
                        HeartBeater.Instance.SuggestRestart();
                        throw new Exception(
                                  "Triggered restart. Unable to read/parse old highwater mark from database in PressReleaseChecker.Run(), from key:" +
                                  persistenceKey + ", loaded string was '" + highWaterMarkString + "' expected format is " +
                                  DateTime.Now, ex);
                    }
                }
                DateTime storedHighWaterMark = highWaterMark;
                reader = new RssReader(readerUrl);
                Rss rss = reader.Read();

                foreach (RssChannelItem item in rss.Channel.Items)
                {
                    // Ignore any items older than the highwater mark.
                    // Also ignore if older than two days

                    if (item.PubDate < highWaterMark || item.PubDate < DateTime.Now.AddDays(-2))
                    {
                        continue;
                    }

                    // This is an item we should publish.

                    // Set highwater datetime mark. We do this first, BEFORE processing, as a defense against mail floods,
                    // if should something go wrong and unexpected exceptions happen.

                    // We used to add 70 minutes as a defense against mistakes on DST switch in spring and fall (yes, it has happened), but have reduced to two.

                    if (item.PubDate > storedHighWaterMark)
                    {
                        Persistence.Key[persistenceKey] = item.PubDate.AddMinutes(2).ToString();
                        storedHighWaterMark             = item.PubDate.AddMinutes(2);

                        // Verify that it was written correctly to database. This is defensive programming to avoid a mail flood,
                        // in case we can't write to the database for some reason.
                        string newStoredHighWaterString = "";
                        try
                        {
                            newStoredHighWaterString = Persistence.Key[persistenceKey];
                            DateTime temp = DateTime.Parse(newStoredHighWaterString);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(
                                      "Unable to commit/parse new highwater mark to database in PressReleaseChecker.Run(), loaded string was '" +
                                      newStoredHighWaterString + "'", ex);
                        }

                        if (DateTime.Parse(Persistence.Key[persistenceKey]) < item.PubDate)
                        {
                            throw new Exception(
                                      "Unable to commit new highwater mark to database in PressReleaseChecker.Run()");
                        }
                    }

                    bool            allReporters  = false;
                    bool            international = false;
                    MediaCategories categories    = new MediaCategories();

                    foreach (RssCategory category in item.Categories)
                    {
                        if (category.Name == "Alla")
                        {
                            allReporters = true;
                        }
                        else if (category.Name == "Uncategorized")
                        {
                        }
                        else
                        {
                            try
                            {
                                MediaCategory mediaCategory = MediaCategory.FromName(category.Name);
                                categories.Add(mediaCategory);

                                if (category.Name.StartsWith("International"))
                                {
                                    international = true;
                                }
                            }
                            catch (Exception)
                            {
                                ExceptionMail.Send(
                                    new Exception("Unrecognized media category in press release: " + category.Name));
                            }
                        }
                    }

                    string mailText = Blog2Mail(item.Content);

                    // Create recipient list of relevant reporters

                    Reporters reporters = null;

                    if (allReporters)
                    {
                        reporters = Reporters.GetAll();
                    }
                    else
                    {
                        reporters = Reporters.FromMediaCategories(categories);
                    }

                    // Add officers if not int'l

                    People officers = new People();
                    Dictionary <int, bool> officerLookup = new Dictionary <int, bool>();

                    if (!international)
                    {
                        int[] officerIds = Roles.GetAllDownwardRoles(1, 1);
                        foreach (int officerId in officerIds)
                        {
                            officerLookup[officerId] = true;
                        }
                    }
                    else
                    {
                        officerLookup[1] = true;
                    }


                    // Send press release

                    //TODO: hardcoded  geo ... using  World
                    Organization     org = Organization.FromIdentity(orgIdForTemplate);
                    Geography        geo = Geography.Root;
                    PressReleaseMail pressreleasemail = new PressReleaseMail();

                    pressreleasemail.pSubject     = item.Title;
                    pressreleasemail.pDate        = DateTime.Now;
                    pressreleasemail.pBodyContent = Blog2Mail(item.Content);
                    pressreleasemail.pOrgName     = org.MailPrefixInherited;
                    if (allReporters)
                    {
                        pressreleasemail.pPostedToCategories = "Alla"; // TODO: TRANSLATE
                    }
                    else if (international)
                    {
                        pressreleasemail.pPostedToCategories = "International/English"; // TODO: THIS IS HARDCODED
                    }
                    else
                    {
                        pressreleasemail.pPostedToCategories =
                            PressReleaseMail.GetConcatenatedCategoryString(categories);
                    }

                    OutboundMail newMail = pressreleasemail.CreateFunctionalOutboundMail(MailAuthorType.PressService,
                                                                                         OutboundMail.PriorityHighest, org, geo);

                    int recipientCount = 0;
                    foreach (Reporter recipient in reporters)
                    {
                        if (!Formatting.ValidateEmailFormat(recipient.Email))
                        {
                            continue;
                        }
                        ++recipientCount;
                        newMail.AddRecipient(recipient);
                    }
                    foreach (int key in officerLookup.Keys)
                    {
                        Person recipient = Person.FromIdentity(key);
                        if (!Formatting.ValidateEmailFormat(recipient.Mail))
                        {
                            continue;
                        }
                        ++recipientCount;
                        newMail.AddRecipient(recipient, true);
                    }

                    newMail.SetRecipientCount(recipientCount);
                    newMail.SetResolved();
                    newMail.SetReadyForPickup();
                }
            }
            catch (Exception ex)
            {
                ExceptionMail.Send(
                    new Exception("PressReleaseChecker failed:" + ex.Message + "\r\nwhen checking " + readerUrl, ex));
            }
            finally
            {
                reader.Close();
            }
        }
Example #22
0
        internal static void MailSent(IAsyncResult result)
        {
            lock (lockObject)
            {
                MailTransmissionAsyncState asyncState       = (MailTransmissionAsyncState)result.AsyncState;
                MailTransmissionDelegate   asyncTransmitter = asyncState.dlgt;
                OutboundMailRecipient      recipient        = asyncState.recipient;
                try
                {
                    asyncTransmitter.EndInvoke(result);

                    try
                    {
                        recipient.Delete();
                        recipient.OutboundMail.IncrementSuccesses();
                    }
                    catch (Exception ex)
                    {
                        // whatever.. The mail is sent, but we couldn't mark it as such, probably a database failure.
                        asyncState.exception = new RemoveRecipientException("Couldn't remove mail recipient.", ex);
                        ExceptionMail.Send(asyncState.exception, true);
                    }
                }
                catch (ReportAndRetryRecipientException e)
                {
                    asyncState.exception = e;
                    Debug.WriteLine(e.ToString());
                    ExceptionMail.Send(e, true);
                }
                catch (RetryRecipientException e)
                {
                    // No action - handled in async delegate - retry this mail
                    asyncState.exception = e;
                }
                catch (Exception e)
                {
                    asyncState.exception = e;

                    try
                    {
                        recipient.Delete();
                        recipient.OutboundMail.IncrementFailures();

                        if (e is InvalidRecipientException)
                        {
                            if (recipient.Person != null && recipient.Person.EMailIsInvalid == false)
                            {
                                //Mark address as invalid.
                                recipient.Person.EMailIsInvalid = true;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // Return this exception in asyncState since it is important to stop flooding.
                        asyncState.exception =
                            new RemoveRecipientException("Couldn't remove mail recipient after exception.", ex);
                        ExceptionMail.Send(asyncState.exception, true);  //Report the secondary exception
                    }


                    Debug.WriteLine(e.ToString());
                    ExceptionMail.Send(e, true);
                }

                asyncState.callbackCompleted = true;
            }
        }
Example #23
0
        public void Send()
        {
            //Send method now sending syncronously.

            //List to keep track of started async send's
            List <IAsyncResult> sendInProgress = new List <IAsyncResult>();

            foreach (Person recipient in recipients)
            {
                try
                {
                    MailMessage message = null;

                    if (toOfficers && recipient.Country.Identity == 1) // HACK until PirateWeb Exchange server up
                    {
                        if (!Formatting.ValidateEmailFormat(recipient.PartyEmail.Trim()))
                        {
                            if (recipient.Identity == 13354)
                            {
                                // HACK - UP auditor

                                continue;
                            }

                            Person.FromIdentity(1).SendOfficerNotice("PirateBot Warning", String.Format("The officer {0} (#{1}) does not have a party email.", recipient.Name,
                                                                                                        recipient.Identity), 1);

                            continue;
                        }

                        message = new MailMessage(new MailAddress(fromAddress, qp8859.EncodeMailHeaderString(fromName), Encoding.Default),
                                                  new MailAddress(recipient.PartyEmail, qp8859.EncodeMailHeaderString(recipient.Name + " (Piratpartiet)"),
                                                                  Encoding.Default));
                    }
                    else
                    {
                        if (!Formatting.ValidateEmailFormat(recipient.Mail.Trim()))
                        {
                            continue;
                        }

                        message = new MailMessage(new MailAddress(fromAddress, qpUTF8.EncodeMailHeaderString(fromName), Encoding.UTF8),
                                                  new MailAddress(recipient.Mail, qpUTF8.EncodeMailHeaderString(recipient.Name), Encoding.UTF8));
                    }

                    if (message == null)
                    {
                        continue;
                    }

                    message.Subject = subject;
                    message.Body    = bodyPlain;

                    message.SubjectEncoding = Encoding.UTF8;
                    message.BodyEncoding    = Encoding.UTF8;


                    // Start the transmission process, synchronously

                    #region Commented out asynchronous sending
                    //lock (lockObject)
                    //{
                    //    MailTransmissionDelegate asyncTransmitter = new MailTransmissionDelegate(TransmitOneMessage);
                    //    outstandingTransmissions++;
                    //    sendInProgress.Add(asyncTransmitter.BeginInvoke(message, null, asyncTransmitter));
                    //}
                    //System.Threading.Thread.Sleep(25); // Allow some time

                    #endregion

                    TransmitOneMessage(message); // Sending synchronosly
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e.ToString());
                    ExceptionMail.Send(new Exception("Excepton in Mailtransmitter.Send:", e), true);
                }
            }

            #region Commented out handling of wait for asyncronous completion (Wich isn't even good...)
            //// now wait for them to finish;
            //int numberStillExecuting = sendInProgress.Count;
            //int numberExecutingLast = numberStillExecuting + 1;
            //DateTime lastProgress = DateTime.Now;

            //while (numberStillExecuting > 0)
            //{
            //    System.Threading.Thread.Sleep(25); // Allow some time

            //    numberStillExecuting = 0;
            //    for (int i = 0; i < sendInProgress.Count; ++i)
            //    {
            //        IAsyncResult iares = sendInProgress[i];
            //        if (iares != null)
            //        {
            //            if (!iares.IsCompleted)
            //            {
            //                numberStillExecuting++;
            //            }
            //            else
            //            {
            //                MessageSent(iares);
            //                sendInProgress[i] = null;
            //            }
            //        }
            //    }

            //    if (numberExecutingLast != numberStillExecuting)
            //        lastProgress = DateTime.Now;

            //    numberExecutingLast = numberStillExecuting;

            //    if (lastProgress.AddSeconds(60) < DateTime.Now)
            //    {
            //        //60 seconds since last change, something must have hanged
            //        lock (lockObject)
            //        {
            //            outstandingTransmissions = -1000;
            //        }
            //        throw new Exception("Timeout in MailTransmitter");
            //    }

            //}

            #endregion
        }
Example #24
0
        public static void RemindChangeOrg()
        {
            HeartBeater.Instance.Beat();

            // Get expiring
            DateTime                       starttime                  = DateTime.Now;
            Organizations                  orgs                       = Organization.FromIdentity(Organization.UPSEid).GetTree();
            Dictionary <int, Person>       personLookup               = new Dictionary <int, Person>();
            Dictionary <int, Memberships>  personMembershipsLookup    = new Dictionary <int, Memberships>();
            Dictionary <int, Organization> orgLookup                  = new Dictionary <int, Organization>();
            Dictionary <int, Organization> mostLocalOrganizationCache = new Dictionary <int, Organization>();
            List <ChangeOrgReport>         report                     = new List <ChangeOrgReport>();

            foreach (Organization org in orgs)
            {
                orgLookup[org.OrganizationId] = org;
            }

            Memberships allMemberships = Memberships.ForOrganizations(orgs);

            foreach (Membership ms in allMemberships)
            {
                //Handle defunct Memberships.ForOrganizations
                if (orgLookup.ContainsKey(ms.OrganizationId))
                {
                    if (!personLookup.ContainsKey(ms.PersonId))
                    {
                        personLookup[ms.PersonId]            = null;
                        personMembershipsLookup[ms.PersonId] = new Memberships();
                    }
                    personMembershipsLookup[ms.PersonId].Add(ms);
                }
            }
            allMemberships = null;

            People peeps = People.FromIdentities((new List <int>(personLookup.Keys)).ToArray());

            foreach (Person p in peeps)
            {
                personLookup[p.PersonId] = p;
            }


            if (Debugger.IsAttached)
            {
                Console.WriteLine("Found " + personLookup.Count + " people");
            }

            int processedCounter = 0;
            int sentCounter      = 0;
            int failCounter      = 0;

            DateTime lastDisplay = DateTime.Now;

            foreach (Person person in personLookup.Values)
            {
                ++processedCounter;
                if ((processedCounter % 50) == 0)
                {
                    HeartBeater.Instance.Beat();
                    if (Debugger.IsAttached)
                    {
                        Console.WriteLine("Processed " + processedCounter + " t=" + DateTime.Now.Subtract(lastDisplay).TotalSeconds);
                    }
                    lastDisplay = DateTime.Now;
                }

                int geoid = person.GeographyId;

                //check for error, geography broken.
                if (person.GeographyId == 0)
                {
                    geoid = person.Geography.GeographyId; //Will force resolve Geography
                    if (geoid != 0)
                    {
                        person.Geography = person.Geography;
                    }
                    ;                                          //repair person.
                }

                if (geoid == 0)
                {
                    continue; //give up on that...
                }
                Organization expectedLowOrg = null;

                if (mostLocalOrganizationCache.ContainsKey(geoid))
                {
                    expectedLowOrg = mostLocalOrganizationCache[geoid];
                }
                else
                {
                    expectedLowOrg = Organizations.GetMostLocalOrganization(geoid, Organization.UPSEid);
                    mostLocalOrganizationCache[geoid] = expectedLowOrg;
                }

                bool found = false;
                Dictionary <int, Membership> personMS = new Dictionary <int, Membership>();

                foreach (Membership ms in personMembershipsLookup[person.PersonId])
                {
                    if (orgLookup.ContainsKey(ms.OrganizationId))
                    {   //Its an UP org
                        personMS[ms.OrganizationId] = ms;
                    }
                    if (ms.OrganizationId == expectedLowOrg.Identity)
                    {
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    //OK we didnt find the recommended org. Find out why.

                    // loop thru the persons up orgs to find an inactive
                    List <Organization> foundInactiveOrg = new List <Organization>();
                    List <Organization> foundActiveOrg   = new List <Organization>();
                    Membership          membership       = null;
                    try
                    {
                        Organization org = null;

                        foreach (Membership ms in personMS.Values)
                        {
                            org = orgLookup[ms.OrganizationId];
                            if (org.AcceptsMembers == false)
                            {
                                foundInactiveOrg.Add(org);
                            }
                            else if (org.AutoAssignNewMembers == true)
                            {
                                foundActiveOrg.Add(org);
                            }
                        }

                        if (foundInactiveOrg.Count > 0)
                        {
                            //inactive
                            membership = personMS[foundInactiveOrg[0].Identity];
                        }
                        else if (foundActiveOrg.Count > 0)
                        {
                            //change
                            membership = personMS[foundActiveOrg[0].Identity];
                        }
                        else
                        {
                            //already a member but not of an autoassign org
                            if (Debugger.IsAttached)
                            {
                                Console.WriteLine("Debug:nochange " + person.Name + ";" + person.Geography.Name + ";" + (org != null ? org.Name : "UnknownOrg") + ";" + expectedLowOrg.Name);
                            }
                            continue;
                        }
                        DateTime lastReminder = PWLog.CheckLatest(PWLogItem.Person, membership.PersonId, PWLogAction.MembershipRenewReminder);

                        if (DateTime.Now.Subtract(lastReminder).TotalDays > 25)
                        {
                            if (Debugger.IsAttached)
                            {
                                Console.Write("Debug:" + person.Name + ";" + person.Geography.Name + ";" + membership.Organization.Name + ";" + expectedLowOrg.Name);
                                foreach (var o in foundActiveOrg)
                                {
                                    Console.Write(";" + o.Name);
                                }
                                Console.WriteLine("");
                            }

                            SendChangeOrgMail(person, membership, expectedLowOrg);
                            report.Add(new ChangeOrgReport {
                                FromOrg = membership.Organization, ToOrg = expectedLowOrg
                            });
                            ++sentCounter;
                            PWLog.Write(PWLogItem.Person, membership.PersonId,
                                        PWLogAction.MembershipRenewReminder,
                                        "Mail was sent to " + membership.Person.Mail +
                                        " for recommendation of organisation change in " + membership.Organization.Name + ".",
                                        membership.Organization.Identity.ToString() + "/" + expectedLowOrg.Identity.ToString());
                        }
                    }
                    catch (Exception x)
                    {
                        ++failCounter;
                        string logText = "FAILED sending mail to " + membership.Person.Mail +
                                         " for recommendation of organisation change in " + membership.Organization.Name + ".";
                        PWLog.Write(PWLogItem.Person, membership.PersonId,
                                    PWLogAction.MembershipRenewReminder,
                                    logText, string.Empty);
                        ExceptionMail.Send(new Exception(logText, x));
                    }
                }
            }

            Dictionary <Organization, Dictionary <Organization, int> > fromdict = new Dictionary <Organization, Dictionary <Organization, int> >();
            StringBuilder fromOrgReport = new StringBuilder();

            report.ForEach(delegate(ChangeOrgReport r)
            {
                if (!fromdict.ContainsKey(r.FromOrg))
                {
                    fromdict[r.FromOrg] = new Dictionary <Organization, int>();
                }
                if (!fromdict[r.FromOrg].ContainsKey(r.ToOrg))
                {
                    fromdict[r.FromOrg][r.ToOrg] = 0;
                }
                fromdict[r.FromOrg][r.ToOrg]++;
            });
            foreach (var fd in fromdict.Keys)
            {
                StringBuilder tmp = new StringBuilder();
                int           cnt = 0;
                foreach (var td in fromdict[fd].Keys)
                {
                    tmp.Append(", " + td.Name);
                    cnt += fromdict[fd][td];
                }
                fromOrgReport.Append("\r\nFrån " + fd.Name + " (" + cnt + " st) till " + tmp.ToString().Substring(2));
            }

            Dictionary <Organization, Dictionary <Organization, int> > todict = new Dictionary <Organization, Dictionary <Organization, int> >();
            StringBuilder toOrgReport = new StringBuilder();

            report.ForEach(delegate(ChangeOrgReport r)
            {
                if (!todict.ContainsKey(r.ToOrg))
                {
                    todict[r.ToOrg] = new Dictionary <Organization, int>();
                }
                if (!todict[r.ToOrg].ContainsKey(r.FromOrg))
                {
                    todict[r.ToOrg][r.FromOrg] = 0;
                }
                todict[r.ToOrg][r.FromOrg]++;
            });
            foreach (var td in todict.Keys)
            {
                StringBuilder tmp = new StringBuilder();
                int           cnt = 0;
                foreach (var fd in todict[td].Keys)
                {
                    tmp.Append(", " + fd.Name);
                    cnt += todict[td][fd];
                }
                toOrgReport.Append("\r\nTill " + td.Name + " (" + cnt + " st) från " + tmp.ToString().Substring(2));
            }


            string reportMessage = string.Format(
                "Result from running recommendation to change org mails:\r\n"
                + "Time:    {0,10:#0.0} minutes. \r\n"
                + "Checked: {1,10:g}\r\n"
                + "Sent:    {2,10:g}\r\n"
                + "Failed:  {3,10:g}\r\n",
                DateTime.Now.Subtract(starttime).TotalMinutes, processedCounter, sentCounter, failCounter)
                                   + fromOrgReport + "\r\n"
                                   + toOrgReport;

            BasicPersonRole[] UPSecretary = SwarmDb.GetDatabaseForReading().GetPeopleWithRoleType(RoleType.OrganizationSecretary,
                                                                                                  new int[] { Organization.UPSEid },
                                                                                                  new int[] { });
            if (UPSecretary.Length > 0)
            {
                Person.FromIdentity(UPSecretary[0].PersonId).SendOfficerNotice("ChangeOrg Mails Job report", reportMessage, Organization.UPSEid);
            }

            Person.FromIdentity(7838).SendOfficerNotice("ChangeOrgMails run", reportMessage, Organization.UPSEid);//Debug
        }