public static void SendChangeOrgMail(Person person, Membership membership, Organization newOrg) { // HACK for UPSE // This is a hack for the Swedish structure. ChangeOrgMail changeorgmail = new ChangeOrgMail(); Organization topOrg = Organization.FromIdentity(Organization.UPSEid); Organization lowOrg = membership.Organization; DateTime currentExpiry = membership.Expires; DateTime newExpiry = DateTime.Today.AddYears(1); changeorgmail.pCurrentOrg = lowOrg.Name; changeorgmail.pCurrentGeo = person.Geography.Name; changeorgmail.pNextDate = newExpiry; string tokenBase = person.PasswordHash + "-" + membership.Identity.ToString() + "-" + currentExpiry.Year.ToString(); if (newOrg.AnchorGeographyId == Geography.RootIdentity && newOrg.AutoAssignNewMembers) {//Fallback org changeorgmail.pNoLocalOrg = newOrg.Name; changeorgmail.pChangeOrg = ""; } else { changeorgmail.pNoLocalOrg = ""; changeorgmail.pChangeOrg = newOrg.Name; } if (lowOrg.AcceptsMembers) { changeorgmail.pInactiveOrg = ""; changeorgmail.pInactiveEnding = " "; } else { changeorgmail.pInactiveOrg = newOrg.Name; } changeorgmail.pStdRenewLink = "https://pirateweb.net/Pages/Public/SE/People/MemberRenew.aspx?PersonId=" + person.Identity.ToString() + "&Transfer=" + lowOrg.Identity.ToString() + "," + newOrg.Identity.ToString() + "&MembershipId=" + membership.Identity.ToString() + "&SecHash=" + SHA1.Hash(tokenBase + "-Transfer" + lowOrg.Identity.ToString() + "/" + newOrg.Identity.ToString()).Replace(" ", "").Substring(0, 8); OutboundMail mail = changeorgmail.CreateFunctionalOutboundMail(MailAuthorType.MemberService, OutboundMail.PriorityNormal, topOrg, Geography.Root); string test = mail.RenderHtml(person, person.PreferredCulture); test = mail.RenderText(person, person.PreferredCulture); if (mail.Body.Trim() == "") { throw new InvalidOperationException("Failed to create a mailBody"); } else { //mail.AddRecipient(7838, true); mail.AddRecipient(person.Identity, false); mail.SetRecipientCount(1); mail.SetResolved(); mail.SetReadyForPickup(); } }
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.ToString(), 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") { continue; } 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(); } }
public static void SendReminderMail(Membership membership) { // First, determine the organization template to use. Prioritize a long ancestry. // This is a hack for the Swedish structure. ReminderMail remindermail = new ReminderMail(); // NEW December 2010: Organizations are separated as per common agreement, there are no common reminder mails. Every membership renews on its own. Organization lowOrg = membership.Organization; DateTime currentExpiry = membership.Expires; Person person = membership.Person; DateTime newExpiry = currentExpiry; //do not mess with lifetime memberships (100 years) if (newExpiry < DateTime.Today.AddYears(10)) { newExpiry = newExpiry.AddYears(1); } remindermail.pPreamble = "<p> Nu är det dags att <strong>förnya ditt medlemskap</strong> i " + membership.Organization.Name + "."; remindermail.pExpirationDate = currentExpiry; remindermail.pNextDate = newExpiry; remindermail.pOrgName = membership.Organization.MailPrefixInherited; string tokenBase = person.PasswordHash + "-" + membership.Identity.ToString() + "-" + currentExpiry.Year.ToString(); // REMOVED DEC2010: suggestion that people older than 25 may leave UP, as renewal mails are separated // HACK for UPSE: Organization expectedLowOrg = Organizations.GetMostLocalOrganization(person.GeographyId, Organization.UPSEid); if (expectedLowOrg != null && lowOrg.Inherits(Organization.UPSEid) && lowOrg.Identity != expectedLowOrg.Identity) { // Is this person in the wrong locale? remindermail.pCurrentOrg = lowOrg.Name; remindermail.pOtherOrg = expectedLowOrg.Name; remindermail.pGeographyName = person.Geography.Name; //mailBody += "Du är medlem i " + lowOrg.Name + ", men när du bor i [b]" + person.Geography.Name + // "[/b] så rekommenderar " + // "vi att du byter till din lokala organisation, [b]" + expectedLowOrg.Name + // "[/b]. Klicka här för att göra det:\r\n\r\n"; string link = "https://pirateweb.net/Pages/Public/SE/People/MemberRenew.aspx?PersonId=" + person.Identity.ToString() + "&Transfer=" + lowOrg.Identity.ToString() + "," + expectedLowOrg.Identity.ToString() + "&MembershipId=" + membership.Identity.ToString() + "&SecHash=" + SHA1.Hash(tokenBase + "-Transfer" + lowOrg.Identity.ToString() + "/" + expectedLowOrg.Identity.ToString()).Replace(" ", "").Substring(0, 8); remindermail.pOtherRenewLink = link; remindermail.pTooOldForYouthOrgSpan = " "; //clear the other span //mailBody += "[a href=\"" + link + "\"]" + link + "[/a]\r\n\r\n" + // "Det är naturligtvis inget krav, utan du kan fortsätta precis som förut om du vill. " + // "För att fortsätta i dina befintliga föreningar, klicka här:\r\n\r\n"; } else { remindermail.pTooOldForYouthOrgSpan = " "; //clear the other span remindermail.pWrongOrgSpan = " "; //clear the other span //mailBody += "Klicka på den här länken för att förnya för ett år till:\r\n\r\n"; } string stdLink = "https://pirateweb.net/Pages/Public/SE/People/MemberRenew.aspx?PersonId=" + person.Identity.ToString() + "&MembershipId=" + membership.Identity.ToString() + "&SecHash=" + SHA1.Hash(tokenBase).Replace(" ", "").Substring(0, 8); remindermail.pStdRenewLink = stdLink; tokenBase = person.PasswordHash + "-" + membership.Identity.ToString(); string terminateLink = "https://pirateweb.net/Pages/Public/SE/People/MemberTerminate.aspx?MemberId=" + person.Identity.ToString() + "&SecHash=" + SHA1.Hash(tokenBase).Replace(" ", "").Substring(0, 8) + "&MID=" + membership.Identity.ToString(); remindermail.pTerminateLink = terminateLink; //mailBody += "[a href=\"" + stdLink + "\"]" + stdLink + "[/a]\r\n\r\n" + // "[br]Välkommen att vara med oss i [b]ett år till![/b]\r\n\r\n" + // "Hälsningar,[br]Medlemsservice\r\n\r\n"; // + /*"PS: [b]Du fick ett likadant mail alldeles nyss. Om du har å, ä eller ö i ditt namn fungerade " + * "inte länken i det mailet. Tack till alla som hörde av sig om det; felet är fixat nu och länken ovan ska fungera.[/b]\r\n\r\n";*/ //OutboundMail mail = remindermail.CreateOutboundMail(sender, OutboundMail.PriorityNormal, topOrg, Geography.Root); OutboundMail mail = remindermail.CreateFunctionalOutboundMail(MailAuthorType.MemberService, OutboundMail.PriorityNormal, membership.Organization, Geography.Root); if (mail.Body.Trim() == "") { throw new InvalidOperationException("Failed to create a mailBody"); } else { mail.AddRecipient(person.Identity, false); mail.SetRecipientCount(2); mail.SetResolved(); mail.SetReadyForPickup(); } }