Beispiel #1
0
    protected void SetUpCurrencyAndTotalsForUser(string szAuthKey, string szParam)
    {
        try
        {
            ValidateAuthorization(szAuthKey);

            Profile pf = MyFlightbook.Profile.GetUser(Username);
            EmailSubscriptionManager em = new EmailSubscriptionManager(pf.Subscriptions);

            IEnumerable <CurrencyStatusItem> rgExpiringCurrencies    = null;
            IEnumerable <CurrencyStatusItem> rgPrecomputedCurrencies = null;
            if (pf.AssociatedData.TryGetValue(CurrencyStatusItem.AssociatedDateKeyExpiringCurrencies, out object o))
            {
                rgExpiringCurrencies = (IEnumerable <CurrencyStatusItem>)o;
            }
            if (pf.AssociatedData.TryGetValue(CurrencyStatusItem.AssociatedDataKeyCachedCurrencies, out object o2))
            {
                rgPrecomputedCurrencies = (IEnumerable <CurrencyStatusItem>)o2;
            }

            pf.AssociatedData.Remove(CurrencyStatusItem.AssociatedDateKeyExpiringCurrencies);
            pf.AssociatedData.Remove(CurrencyStatusItem.AssociatedDataKeyCachedCurrencies);

            bool fHasCurrency = em.HasSubscription(SubscriptionType.Currency) || (em.HasSubscription(SubscriptionType.Expiration) && rgExpiringCurrencies != null && rgPrecomputedCurrencies != null);
            bool fHasTotals   = em.HasSubscription(SubscriptionType.Totals);
            bool fHasMonthly  = em.HasSubscription(SubscriptionType.MonthlyTotals);

            bool fMonthlySummary = (String.Compare(szParam, "monthly", StringComparison.OrdinalIgnoreCase) == 0);

            if (!fHasCurrency && !fHasTotals && !fMonthlySummary)
            {
                throw new MyFlightbookException("Email requested but no subscriptions found! User ="******"Monthly email requested but user does not subscribe to monthly email.  User = "******"http://{0}{1}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Member/EditProfile.aspx/pftDonate"));
            mvDonations.SetActiveView(Payment.TotalPaidSinceDate(DateTime.Now.AddYears(-1), Username) > 0 ? vwThankyou : vwPleaseGive);

            // Fix up the unsubscribe link.
            lnkUnsubscribe.NavigateUrl      = String.Format(CultureInfo.InvariantCulture, "http://{0}{1}/{2}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Member/EditProfile.aspx"), tabID.pftPrefs.ToString());
            lnkQuickUnsubscribe.NavigateUrl = String.Format(CultureInfo.InvariantCulture, "http://{0}{1}?u={2}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Public/Unsubscribe.aspx"), HttpUtility.UrlEncode(new UserAccessEncryptor().Encrypt(Username)));

            bool fAnnual = (DateTime.Now.Month == 1 && DateTime.Now.Day == 1);  // if it's January 1, show prior year; else show YTD
            mfbTotalsByTimePeriod.BindTotalsForUser(Username, !fMonthlySummary, !fMonthlySummary, true, true, !fAnnual);

            if (fAnnual)
            {
                mfbRecentAchievements.Refresh(Username, new DateTime(DateTime.Now.Year - 1, 1, 1), new DateTime(DateTime.Now.Year - 1, 12, 31), true);
            }
            else
            {
                mfbRecentAchievements.Refresh(Username, new DateTime(DateTime.Now.Year, 1, 1), DateTime.Now, true);
            }

            lblRecentAchievementsTitle.Text    = mfbRecentAchievements.Summary;
            lblRecentAchievementsTitle.Visible = mfbRecentAchievements.AchievementCount > 0;

            lblCurrency.Text = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailCurrencyHeader, DateTime.Now.ToLongDateString());

            pnlTotals.Visible = fHasTotals || fMonthlySummary;
            lblTotal.Text     = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsHeader, DateTime.Now.ToLongDateString());

            lblIntroHeader.Text = String.Format(CultureInfo.CurrentCulture, fMonthlySummary ? Resources.Profile.EmailMonthlyMailIntro : Resources.Profile.EmailWeeklyMailIntro, Branding.CurrentBrand.AppName);

            if (fHasCurrency || fMonthlySummary)
            {
                mfbCurrency.UserName = pf.UserName;
                mfbCurrency.RefreshCurrencyTable(rgPrecomputedCurrencies);
                pnlCurrency.Visible = true;

                if (rgExpiringCurrencies != null && rgExpiringCurrencies.Any())
                {
                    pnlExpiringCurrencies.Visible = true;
                    rptExpiring.DataSource        = rgExpiringCurrencies;
                    rptExpiring.DataBind();
                }
            }
        }
        catch (Exception ex) when(ex is MyFlightbookException || ex is FormatException)
        {
            MyFlightbookException.NotifyAdminException(ex);
            throw;  // ensure that the success tag doesn't show!
        }
    }
Beispiel #2
0
        /// <summary>
        /// Parses GPX-based flight data
        /// </summary>
        /// <param name="szData">The string of flight data</param>
        /// <returns>True for success</returns>
        public override bool Parse(string szData)
        {
            if (String.IsNullOrEmpty(szData))
            {
                return(false);
            }

            StringBuilder sbErr = new StringBuilder();

            ParsedData.Clear();
            Boolean fResult = true;

            byte[]       bytes  = Encoding.UTF8.GetBytes(szData);
            MemoryStream stream = null;

            try
            {
                stream = new MemoryStream(bytes);
                using (StreamReader sr = new StreamReader(stream))
                {
                    stream = null;
                    XDocument xml = XDocument.Load(sr);

                    GPXPathRoot root = FindRoot(xml);

                    if (root == null)
                    {
                        return(false);
                    }

                    if (root.elements != null)
                    {
                        int  iRow       = 0;
                        bool fHasAlt    = false;
                        bool fHasDate   = false;
                        bool fHasLatLon = false;
                        bool fHasSpeed  = false;

                        List <Position> lst = new List <Position>();

                        foreach (XElement e in root.elements)
                        {
                            foreach (XElement coord in e.Descendants(root.xnamespace + "trkpt"))
                            {
                                XAttribute xLat         = null;
                                XAttribute xLon         = null;
                                XElement   xAlt         = null;
                                XElement   xTime        = null;
                                XElement   xSpeed       = null;
                                XElement   xBadElfSpeed = null;

                                xLat   = coord.Attribute("lat");
                                xLon   = coord.Attribute("lon");
                                xAlt   = coord.Descendants(root.xnamespace + "ele").FirstOrDefault();
                                xTime  = coord.Descendants(root.xnamespace + "time").FirstOrDefault();
                                xSpeed = SpeedElement(coord, root);

                                fHasAlt    = (xAlt != null);
                                fHasDate   = (xTime != null);
                                fHasSpeed  = (xSpeed != null || xBadElfSpeed != null);
                                fHasLatLon = (xLat != null && xLon != null);

                                if (!fHasAlt && !fHasDate && !fHasSpeed && !fHasLatLon)
                                {
                                    throw new MyFlightbookException(Resources.FlightData.errGPXNoPath);
                                }

                                if (fHasLatLon)
                                {
                                    try
                                    {
                                        Position samp = new Position(Convert.ToDouble(xLat.Value, System.Globalization.CultureInfo.InvariantCulture), Convert.ToDouble(xLon.Value, System.Globalization.CultureInfo.InvariantCulture));
                                        if (fHasAlt)
                                        {
                                            samp.Altitude = (Int32)Convert.ToDouble(xAlt.Value, System.Globalization.CultureInfo.InvariantCulture);
                                        }
                                        if (fHasDate)
                                        {
                                            samp.Timestamp = xTime.Value.ParseUTCDate();
                                        }
                                        if (fHasSpeed)
                                        {
                                            samp.Speed = Convert.ToDouble(xSpeed.Value, System.Globalization.CultureInfo.InvariantCulture);
                                        }
                                        lst.Add(samp);
                                    }
                                    catch (Exception ex) when(ex is FormatException)
                                    {
                                        fResult = false;
                                        sbErr.AppendFormat(CultureInfo.CurrentCulture, Resources.FlightData.errGPXBadRow, iRow);
                                        sbErr.Append("\r\n");
                                    }
                                    catch (Exception ex)
                                    {
                                        MyFlightbookException.NotifyAdminException(new MyFlightbookException("Unknown error in ParseFlightDataGPX", ex));
                                        throw;
                                    }
                                }
                                iRow++;
                            }
                        }

                        // Derive speed and put it into a data table
                        if (!fHasSpeed)
                        {
                            Position.DeriveSpeed(lst);
                        }
                        ToDataTable(lst);
                    }
                    else
                    {
                        throw new MyFlightbookException(Resources.FlightData.errGPXNoPath);
                    }
                }
            }
            catch (System.Xml.XmlException ex)
            {
                sbErr.Append(Resources.FlightData.errGeneric + ex.Message);
                fResult = false;
            }
            catch (MyFlightbookException ex)
            {
                sbErr.Append(Resources.FlightData.errGeneric + ex.Message);
                fResult = false;
            }
            finally
            {
                stream?.Dispose();
            }
            ErrorString = sbErr.ToString();

            return(fResult);
        }
Beispiel #3
0
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string szAuthKey = util.GetStringParam(Request, "k");
            string szUser    = util.GetStringParam(Request, "u");
            string szParam   = util.GetStringParam(Request, "p");

            // This page is public, so that it doesn't require any authentication, making it easy to set up a scheduled task.
            // SO, we do the following:
            // If you request the page from ANOTHER machine, we return an error
            // If you request it from THIS machine, then we perform a very simple authentication (pass an encrypted datetime) to ourselves.
            // If we receive this request with a valid encrypted key, we return the email for the specified user.
            if (String.IsNullOrEmpty(szAuthKey))
            {
                // see if this is coming from the local machine
                string szIPThis = System.Net.Dns.GetHostAddresses(Request.Url.Host)[0].ToString();
                if (String.Compare(Request.UserHostAddress, szIPThis, StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    // request came from this machine - make a request to ourselves and send it out in email
                    EmailSubscriptionManager em = new EmailSubscriptionManager();
                    em.ActiveBrand = Branding.CurrentBrand;
                    if (util.GetIntParam(Request, "dbg", 0) != 0)
                    {
                        em.UserRestriction = Page.User.Identity.Name;
                    }
                    string szTasksToRun = util.GetStringParam(Request, "tasks");
                    if (!String.IsNullOrEmpty(szTasksToRun))
                    {
                        try { em.TasksToRun = (EmailSubscriptionManager.SelectedTasks)Convert.ToInt32(szTasksToRun, CultureInfo.InvariantCulture); }
                        catch (FormatException)
                        { em.TasksToRun = EmailSubscriptionManager.SelectedTasks.All; }
                    }
                    new Thread(new ThreadStart(em.NightlyRun)).Start();
                    lblSuccess.Visible = true;
                }
                else
                {
                    lblErr.Visible = true;
                }
            }
            else
            {
                try
                {
                    AdminAuthEncryptor enc            = new AdminAuthEncryptor();
                    string             szDate         = enc.Decrypt(szAuthKey);
                    DateTime           dt             = DateTime.Parse(szDate, CultureInfo.InvariantCulture);
                    double             elapsedSeconds = DateTime.Now.Subtract(dt).TotalSeconds;
                    if (elapsedSeconds < 0 || elapsedSeconds > 10)
                    {
                        throw new MyFlightbookException("Unauthorized attempt to view stats for mail");
                    }

                    Profile pf = MyFlightbook.Profile.GetUser(szUser);
                    EmailSubscriptionManager em = new EmailSubscriptionManager(pf.Subscriptions);

                    bool fHasCurrency = em.HasSubscription(SubscriptionType.Currency);
                    bool fHasTotals   = em.HasSubscription(SubscriptionType.Totals);
                    bool fHasMonthly  = em.HasSubscription(SubscriptionType.MonthlyTotals);

                    bool fMonthlySummary = (String.Compare(szParam, "monthly", StringComparison.OrdinalIgnoreCase) == 0);

                    if (!fHasCurrency && !fHasTotals && !fMonthlySummary)
                    {
                        throw new MyFlightbookException("Email requested but no subscriptions found!");
                    }

                    if (fMonthlySummary && !fHasMonthly)
                    {
                        throw new MyFlightbookException("Monthly email requested but user does not subscribe to monthly email");
                    }

                    // Donation solicitation: thank-them if they've made a donation within the previous 12 months, else solicit.
                    lblThankyou.Text         = Branding.ReBrand(Resources.LocalizedText.DonateThankYouTitle);
                    lblSolicitDonation.Text  = Branding.ReBrand(Resources.LocalizedText.DonatePrompt);
                    lnkDonateNow.Text        = Branding.ReBrand(Resources.LocalizedText.DonateSolicitation);
                    lnkDonateNow.NavigateUrl = String.Format(CultureInfo.InvariantCulture, "http://{0}/logbook/Member/EditProfile.aspx/pftDonate", Branding.CurrentBrand.HostName);
                    mvDonations.SetActiveView(Payment.TotalPaidSinceDate(DateTime.Now.AddYears(-1), szUser) > 0 ? vwThankyou : vwPleaseGive);

                    // Fix up the unsubscribe link.
                    lnkUnsubscribe.NavigateUrl      = String.Format(CultureInfo.InvariantCulture, "http://{0}/logbook/Member/EditProfile.aspx/{1}", Branding.CurrentBrand.HostName, tabID.pftPrefs.ToString());
                    lnkQuickUnsubscribe.NavigateUrl = String.Format(CultureInfo.InvariantCulture, "http://{0}/logbook/Public/Unsubscribe.aspx?u={1}", Branding.CurrentBrand.HostName, HttpUtility.UrlEncode(new UserAccessEncryptor().Encrypt(szUser)));

                    // And set HHMM mode explicitly (since not otherwise going to be set in totals
                    mfbTotalSummary.UseHHMM = mfbTotalSummaryYTD.UseHHMM = pf.UsesHHMM;

                    if (fMonthlySummary)
                    {
                        bool fAnnual = (DateTime.Now.Month == 1);  // if it's January, show prior year; else show YTD
                        lblIntroHeader.Text = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailMonthlyMailIntro, Branding.CurrentBrand.AppName);
                        DateTime dtPriorMonth = DateTime.Now.AddMonths(-1);
                        lblTotal.Text     = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsPriorMonthHeader, dtPriorMonth.ToString("MMMM", CultureInfo.CurrentCulture), dtPriorMonth.Year);
                        lblYTD.Text       = fAnnual ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsPriorYearHeader, DateTime.Now.Year - 1) : String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsYTDHeader, DateTime.Now.Year);
                        pnlTotals.Visible = pnlYTD.Visible = true;

                        mfbTotalSummary.Username = mfbTotalSummaryYTD.Username = pf.UserName;

                        FlightQuery fqPriorMonth = new FlightQuery(pf.UserName);
                        fqPriorMonth.DateRange            = FlightQuery.DateRanges.PrevMonth;
                        mfbTotalSummary.CustomRestriction = fqPriorMonth;

                        FlightQuery fqYTD = new FlightQuery(pf.UserName);
                        fqYTD.DateRange = fAnnual ? FlightQuery.DateRanges.PrevYear : FlightQuery.DateRanges.YTD;
                        mfbTotalSummaryYTD.CustomRestriction = fqYTD;
                    }
                    else
                    {
                        lblIntroHeader.Text = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailWeeklyMailIntro, Branding.CurrentBrand.AppName);
                        lblCurrency.Text    = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailCurrencyHeader, DateTime.Now.ToLongDateString());
                        lblTotal.Text       = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsHeader, DateTime.Now.ToLongDateString());

                        if (fHasTotals)
                        {
                            mfbTotalSummary.Username          = pf.UserName;
                            mfbTotalSummary.CustomRestriction = new FlightQuery(pf.UserName);
                            pnlTotals.Visible = true;
                        }
                    }

                    if (fHasCurrency || fMonthlySummary)
                    {
                        mfbCurrency.UserName = pf.UserName;
                        mfbCurrency.RefreshCurrencyTable();
                        pnlCurrency.Visible = true;
                    }
                }
                catch (MyFlightbookException ex)
                {
                    MyFlightbookException.NotifyAdminException(ex);
                    throw;  // ensure that the success tag doesn't show!
                }
                catch (FormatException ex)
                {
                    MyFlightbookException.NotifyAdminException(ex);
                    throw;
                }
            }
        }
    }
Beispiel #4
0
        public override bool Parse(string szData)
        {
            if (szData == null)
            {
                throw new ArgumentNullException("szData");
            }

            Boolean       fResult = true;
            StringBuilder sbErr   = new StringBuilder();

            /*
             * GGA - essential fix data which provide 3D location and accuracy data.
             *
             * $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
             *
             * Where:
             *   GGA          Global Positioning System Fix Data
             *   123519       Fix taken at 12:35:19 UTC
             *   4807.038,N   Latitude 48 deg 07.038' N
             *   01131.000,E  Longitude 11 deg 31.000' E
             *   1            Fix quality: 0 = invalid
             *                             1 = GPS fix (SPS)
             *                             2 = DGPS fix
             *                             3 = PPS fix
             *                 4 = Real Time Kinematic
             *                 5 = Float RTK
             *                             6 = estimated (dead reckoning) (2.3 feature)
             *                 7 = Manual input mode
             *                 8 = Simulation mode
             *   08           Number of satellites being tracked
             *   0.9          Horizontal dilution of position
             *   545.4,M      Altitude, Meters, above mean sea level
             *   46.9,M       Height of geoid (mean sea level) above WGS84
             *                    ellipsoid
             *   (empty field) time in seconds since last DGPS update
             *   (empty field) DGPS station ID number
             * 47          the checksum data, always begins with *
             *
             *
             * RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data. It is called RMC, The Recommended Minimum, which will look similar to:
             *
             * $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
             *
             * Where:
             *   RMC          Recommended Minimum sentence C
             *   123519       Fix taken at 12:35:19 UTC
             *   A            Status A=active or V=Void.
             *   4807.038,N   Latitude 48 deg 07.038' N
             *   01131.000,E  Longitude 11 deg 31.000' E
             *   022.4        Speed over the ground in knots
             *   084.4        Track angle in degrees True
             *   230394       Date - 23rd of March 1994
             *   003.1,W      Magnetic Variation
             * 6A          The checksum data, always begins with *
             *
             * */

            char[] wordSep = { ',' };
            char[] lineSep = { '\n' };
            ParsedData.Clear();
            try
            {
                string[] rgSentences = szData.Split(lineSep, StringSplitOptions.RemoveEmptyEntries);

                double alt = 0.0;
                ParsedData.Columns.Add(new DataColumn(KnownColumnNames.DATE, typeof(DateTime)));
                ParsedData.Columns.Add(new DataColumn(KnownColumnNames.ALT, typeof(Int32)));
                ParsedData.Columns.Add(new DataColumn(KnownColumnNames.LON, typeof(double)));
                ParsedData.Columns.Add(new DataColumn(KnownColumnNames.LAT, typeof(double)));
                ParsedData.Columns.Add(new DataColumn(KnownColumnNames.SPEED, typeof(double)));

                CultureInfo ci = System.Globalization.CultureInfo.InvariantCulture;

                int iSentence = 0;
                foreach (string sentence in rgSentences)
                {
                    try
                    {
                        string[] rgWords = sentence.Split(wordSep, StringSplitOptions.None);
                        if (String.Compare(rgWords[0], "$GPGGA", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            if (String.Compare(rgWords[6], "0", StringComparison.Ordinal) != 0) // is this valid?
                            {
                                alt = Convert.ToDouble(rgWords[9], CultureInfo.InvariantCulture) * ConversionFactors.FeetPerMeter;
                            }
                        }
                        else if (String.Compare(rgWords[0], "$GPRMC", StringComparison.Ordinal) == 0) // actual sample
                        {
                            string szTime = rgWords[1];
                            string szDate = rgWords[9];

                            int year2digit      = Convert.ToInt16(szDate.Substring(4), CultureInfo.InvariantCulture);
                            int curYear         = DateTime.Now.Year;
                            int year20thCentury = 1900 + year2digit;
                            int year21stCentury = 2000 + year2digit;
                            int year            = (Math.Abs(curYear - year20thCentury) < Math.Abs(curYear - year21stCentury)) ? year20thCentury : year21stCentury;

                            DataRow dr = ParsedData.NewRow();

                            DateTime dt = new DateTime(year,
                                                       Convert.ToInt16(szDate.Substring(2, 2), ci),
                                                       Convert.ToInt16(szDate.Substring(0, 2), ci),
                                                       Convert.ToInt16(szTime.Substring(0, 2), ci),
                                                       Convert.ToInt16(szTime.Substring(2, 2), ci),
                                                       Convert.ToInt16(szTime.Substring(4, 2), ci),
                                                       DateTimeKind.Utc);

                            dr[KnownColumnNames.DATE]  = dt;
                            dr[KnownColumnNames.ALT]   = alt;
                            dr[KnownColumnNames.LAT]   = (Convert.ToDouble(rgWords[3].Substring(0, 2), ci) + (Convert.ToDouble(rgWords[3].Substring(2), ci) / 60.0)) * ((String.Compare(rgWords[4], "N", StringComparison.OrdinalIgnoreCase) == 0) ? 1 : -1);
                            dr[KnownColumnNames.LON]   = (Convert.ToDouble(rgWords[5].Substring(0, 3), ci) + (Convert.ToDouble(rgWords[5].Substring(3), ci) / 60.0)) * ((String.Compare(rgWords[6], "E", StringComparison.OrdinalIgnoreCase) == 0) ? 1 : -1);
                            dr[KnownColumnNames.SPEED] = Convert.ToDouble(rgWords[7], ci);

                            ParsedData.Rows.Add(dr);
                        }
                    }
                    catch (System.FormatException ex)
                    {
                        sbErr.AppendFormat(CultureInfo.CurrentCulture, Resources.FlightData.errInRow, iSentence, ex.Message);
                        fResult = false;
                    }
                    catch (System.IndexOutOfRangeException ex)
                    {
                        sbErr.AppendFormat(CultureInfo.CurrentCulture, Resources.FlightData.errInRow, iSentence, ex.Message);
                        fResult = false;
                    }
                    catch (Exception ex)
                    {
                        MyFlightbookException.NotifyAdminException(ex);
                        throw;
                    }

                    iSentence++;
                }
            }
            catch (Exception ex)
            {
                MyFlightbookException.NotifyAdminException(ex);
                throw;
            }

            ErrorString = sbErr.ToString();
            return(fResult);
        }
    protected void Page_Load(object sender, EventArgs e)
    {
        // see if this is coming from the local machine - reject anything that isn't.
        string szIPThis = System.Net.Dns.GetHostAddresses(Request.Url.Host)[0].ToString();

        if (Request.UserHostAddress.CompareCurrentCultureIgnoreCase(szIPThis) != 0)
        {
            throw new UnauthorizedAccessException("Attempt to view this page from other than local machine");
        }

        if (!IsPostBack)
        {
            cssRef.Href = "~/Public/Stylesheet.css?v=18".ToAbsoluteURL(Request.Url.Scheme, Branding.CurrentBrand.HostName, Request.Url.Port).ToString();
            baseRef.Attributes["href"] = "~/Public/".ToAbsoluteURL(Request.Url.Scheme, Branding.CurrentBrand.HostName, Request.Url.Port).ToString();

            string szAuthKey = util.GetStringParam(Request, "k");
            string szUser    = util.GetStringParam(Request, "u");
            string szParam   = util.GetStringParam(Request, "p");

            // This page is public, so that it doesn't require any authentication, making it easy to set up a scheduled task.
            // SO, we do the following:
            // If you request the page from ANOTHER machine, we return an error
            // If you request it from THIS machine, then we perform a very simple authentication (pass an encrypted datetime) to ourselves.
            // If we receive this request with a valid encrypted key, we return the email for the specified user.
            if (String.IsNullOrEmpty(szAuthKey))
            {
                KickOffRun();
            }
            else
            {
                try
                {
                    if (szAuthKey.CompareCurrentCultureIgnoreCase("local") != 0 || !Page.User.Identity.IsAuthenticated)
                    {
                        AdminAuthEncryptor enc            = new AdminAuthEncryptor();
                        string             szDate         = enc.Decrypt(szAuthKey);
                        DateTime           dt             = DateTime.Parse(szDate, CultureInfo.InvariantCulture);
                        double             elapsedSeconds = DateTime.Now.Subtract(dt).TotalSeconds;
                        if (elapsedSeconds < 0 || elapsedSeconds > 10)
                        {
                            throw new MyFlightbookException("Unauthorized attempt to view stats for mail");
                        }
                    }

                    Profile pf = MyFlightbook.Profile.GetUser(szUser);
                    EmailSubscriptionManager em = new EmailSubscriptionManager(pf.Subscriptions);

                    IEnumerable <CurrencyStatusItem> rgExpiringCurrencies    = null;
                    IEnumerable <CurrencyStatusItem> rgPrecomputedCurrencies = null;
                    if (pf.AssociatedData.TryGetValue(CurrencyStatusItem.AssociatedDateKeyExpiringCurrencies, out object o))
                    {
                        rgExpiringCurrencies = (IEnumerable <CurrencyStatusItem>)o;
                    }
                    if (pf.AssociatedData.TryGetValue(CurrencyStatusItem.AssociatedDataKeyCachedCurrencies, out o))
                    {
                        rgPrecomputedCurrencies = (IEnumerable <CurrencyStatusItem>)o;
                    }

                    pf.AssociatedData.Remove(CurrencyStatusItem.AssociatedDateKeyExpiringCurrencies);
                    pf.AssociatedData.Remove(CurrencyStatusItem.AssociatedDataKeyCachedCurrencies);

                    bool fHasCurrency = em.HasSubscription(SubscriptionType.Currency) || (em.HasSubscription(SubscriptionType.Expiration) && rgExpiringCurrencies != null && rgPrecomputedCurrencies != null);
                    bool fHasTotals   = em.HasSubscription(SubscriptionType.Totals);
                    bool fHasMonthly  = em.HasSubscription(SubscriptionType.MonthlyTotals);

                    bool fMonthlySummary = (String.Compare(szParam, "monthly", StringComparison.OrdinalIgnoreCase) == 0);

                    if (!fHasCurrency && !fHasTotals && !fMonthlySummary)
                    {
                        throw new MyFlightbookException("Email requested but no subscriptions found!");
                    }

                    if (fMonthlySummary && !fHasMonthly)
                    {
                        throw new MyFlightbookException("Monthly email requested but user does not subscribe to monthly email");
                    }

                    // Donation solicitation: thank-them if they've made a donation within the previous 12 months, else solicit.
                    lblThankyou.Text         = Branding.ReBrand(Resources.LocalizedText.DonateThankYouTitle);
                    lblSolicitDonation.Text  = Branding.ReBrand(Resources.LocalizedText.DonatePrompt);
                    lnkDonateNow.Text        = Branding.ReBrand(Resources.LocalizedText.DonateSolicitation);
                    lnkDonateNow.NavigateUrl = String.Format(CultureInfo.InvariantCulture, "http://{0}{1}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Member/EditProfile.aspx/pftDonate"));
                    mvDonations.SetActiveView(Payment.TotalPaidSinceDate(DateTime.Now.AddYears(-1), szUser) > 0 ? vwThankyou : vwPleaseGive);

                    // Fix up the unsubscribe link.
                    lnkUnsubscribe.NavigateUrl      = String.Format(CultureInfo.InvariantCulture, "http://{0}{1}/{2}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Member/EditProfile.aspx"), tabID.pftPrefs.ToString());
                    lnkQuickUnsubscribe.NavigateUrl = String.Format(CultureInfo.InvariantCulture, "http://{0}{1}?u={2}", Branding.CurrentBrand.HostName, VirtualPathUtility.ToAbsolute("~/Public/Unsubscribe.aspx"), HttpUtility.UrlEncode(new UserAccessEncryptor().Encrypt(szUser)));

                    // And set HHMM mode explicitly (since not otherwise going to be set in totals
                    mfbTotalSummary.UseHHMM = mfbTotalSummaryYTD.UseHHMM = pf.UsesHHMM;

                    if (fMonthlySummary)
                    {
                        bool fAnnual = (DateTime.Now.Month == 1);  // if it's January, show prior year; else show YTD
                        lblIntroHeader.Text = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailMonthlyMailIntro, Branding.CurrentBrand.AppName);
                        DateTime dtPriorMonth = DateTime.Now.AddMonths(-1);
                        lblTotal.Text     = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsPriorMonthHeader, dtPriorMonth.ToString("MMMM", CultureInfo.CurrentCulture), dtPriorMonth.Year);
                        lblYTD.Text       = fAnnual ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsPriorYearHeader, DateTime.Now.Year - 1) : String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsYTDHeader, DateTime.Now.Year);
                        pnlTotals.Visible = pnlYTD.Visible = true;

                        mfbTotalSummary.Username = mfbTotalSummaryYTD.Username = pf.UserName;

                        FlightQuery fqPriorMonth = new FlightQuery(pf.UserName)
                        {
                            DateRange = FlightQuery.DateRanges.PrevMonth
                        };
                        mfbTotalSummary.CustomRestriction = fqPriorMonth;

                        FlightQuery fqYTD = new FlightQuery(pf.UserName)
                        {
                            DateRange = fAnnual ? FlightQuery.DateRanges.PrevYear : FlightQuery.DateRanges.YTD
                        };
                        mfbTotalSummaryYTD.CustomRestriction = fqYTD;

                        if (fAnnual)
                        {
                            mfbRecentAchievements.Refresh(szUser, new DateTime(DateTime.Now.Year - 1, 1, 1), new DateTime(DateTime.Now.Year - 1, 12, 31), true);
                        }
                        else
                        {
                            mfbRecentAchievements.Refresh(szUser, new DateTime(DateTime.Now.Year, 1, 1), DateTime.Now, true);
                        }

                        lblRecentAchievementsTitle.Text    = mfbRecentAchievements.Summary;
                        lblRecentAchievementsTitle.Visible = mfbRecentAchievements.AchievementCount > 0;
                    }
                    else
                    {
                        lblIntroHeader.Text = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailWeeklyMailIntro, Branding.CurrentBrand.AppName);
                        lblCurrency.Text    = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailCurrencyHeader, DateTime.Now.ToLongDateString());
                        lblTotal.Text       = String.Format(CultureInfo.CurrentCulture, Resources.Profile.EmailTotalsHeader, DateTime.Now.ToLongDateString());

                        if (fHasTotals)
                        {
                            mfbTotalSummary.Username          = pf.UserName;
                            mfbTotalSummary.CustomRestriction = new FlightQuery(pf.UserName);
                            pnlTotals.Visible = true;
                        }
                    }

                    if (fHasCurrency || fMonthlySummary)
                    {
                        mfbCurrency.UserName = pf.UserName;
                        mfbCurrency.RefreshCurrencyTable(rgPrecomputedCurrencies);
                        pnlCurrency.Visible = true;

                        if (rgExpiringCurrencies != null && rgExpiringCurrencies.Count() > 0)
                        {
                            pnlExpiringCurrencies.Visible = true;
                            rptExpiring.DataSource        = rgExpiringCurrencies;
                            rptExpiring.DataBind();
                        }
                    }
                }
                catch (MyFlightbookException ex)
                {
                    MyFlightbookException.NotifyAdminException(ex);
                    throw;  // ensure that the success tag doesn't show!
                }
                catch (FormatException ex)
                {
                    MyFlightbookException.NotifyAdminException(ex);
                    throw;
                }
            }
        }
    }