Ejemplo n.º 1
0
        /// <summary>
        /// Creates the asset from blob object.
        /// </summary>
        /// <param name="assetStorageProvider">The asset storage provider.</param>
        /// <param name="blobItem">The blob object.</param>
        /// <param name="createThumbnail">if set to <c>true</c> [create thumbnail].</param>
        /// <returns></returns>
        private Asset TranslateBlobToRockAsset(AssetStorageProvider assetStorageProvider, CloudBlob blobItem, bool createThumbnail = true)
        {
            var asset = new Asset
            {
                Name = GetNameFromKey(blobItem.Name),
                Key  = blobItem.Name,
                Uri  = blobItem.Uri.ToString(),
                Type = AssetType.File,
                AssetStorageProviderId = assetStorageProvider.Id
            };

            if (blobItem.Properties != null)
            {
                asset.FileSize    = blobItem.Properties.Length;
                asset.Description = $"{blobItem.Properties.Length} byte{( blobItem.Properties.Length == 1 ? string.Empty : "s" )}";
                if (blobItem.Properties.LastModified != null)
                {
                    asset.LastModifiedDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(blobItem.Properties.LastModified.Value.LocalDateTime);
                }
            }

            if (createThumbnail)
            {
                asset.IconPath = createThumbnail ?
                                 GetThumbnail(assetStorageProvider, blobItem.Name, asset.LastModifiedDateTime) :
                                 GetFileTypeIcon(blobItem.Name);
            }
            return(asset);
        }
Ejemplo n.º 2
0
        public void TestFirstDateOfWeekTuesday()
        {
            var sundayDate20191006 = new DateTime(2019, 10, 6);
            var sundayDate20191013 = new DateTime(2019, 10, 13);
            var sundayDate20191020 = new DateTime(2019, 10, 20);
            var sundayDate20191027 = new DateTime(2019, 10, 27);

            Rock.Web.SystemSettings.SetValue(Rock.SystemKey.SystemSetting.START_DAY_OF_WEEK, DayOfWeek.Tuesday.ConvertToInt().ToString());
            RockDateTime.UpdateSundayDateData();

            Assert.That.IsTrue(new DateTime(2019, 10, 1).SundayDate() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 5).SundayDate() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 6).SundayDate() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 7).SundayDate() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 8).SundayDate() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 14).SundayDate() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 13).SundayDate() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 21).SundayDate() == sundayDate20191020, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 22).SundayDate() != sundayDate20191020, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 10, 22).SundayDate() == sundayDate20191027, "Incorrect Sunday Date");

            var rockContext = new RockContext();

            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 1 )}')").FirstOrDefault() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 5 )}')").FirstOrDefault() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 6 )}')").FirstOrDefault() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 7 )}')").FirstOrDefault() == sundayDate20191006, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 8 )}')").FirstOrDefault() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 14 )}')").FirstOrDefault() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 13 )}')").FirstOrDefault() == sundayDate20191013, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 21 )}')").FirstOrDefault() == sundayDate20191020, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 22 )}')").FirstOrDefault() != sundayDate20191020, "Incorrect Sunday Date");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 10, 22 )}')").FirstOrDefault() == sundayDate20191027, "Incorrect Sunday Date");
        }
Ejemplo n.º 3
0
        private void LoadFiscalYearList()
        {
            ddlFiscalYear.Items.Insert(0, new ListItem("All", DateTime.MinValue.ToString()));

            for (int i = 0; i <= 10; i++)
            {
                string date = RockDateTime.New(RockDateTime.Now.Year - i, 1, 1).ToString();
                ddlFiscalYear.Items.Insert(0, new ListItem((RockDateTime.Now.Year - i).ToString(), date.ToString()));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Sets the RockDateTime timezone to a value that is suitable for testing an operating environment
        /// in which the organization timezone does not match the local system timezone.
        /// This configuration simulates a Rock server hosted in a different timezone to the Rock organization.
        /// </summary>
        public static void SetRockDateTimeToAlternateTimezone()
        {
            var tz = GetTestTimeZoneAlternate();

            RockDateTime.Initialize(tz);

            // Re-initialize the lava engine options.
            var options = GetCurrentEngineOptions();

            _fluidEngine.Initialize(options);
        }
        /// <summary>
        /// Returns a human-friendly description of the time of day.
        /// </summary>
        /// <param name="input">A valid date/time value</param>
        /// <returns></returns>
        public static string TimeOfDay(object input)
        {
            var dtoInput = GetDateTimeOffsetFromInputParameter(input, null);

            if (dtoInput == null)
            {
                return(string.Empty);
            }

            var response = RockDateTime.GetTimeOfDay(dtoInput.Value.DateTime);

            return(response);
        }
Ejemplo n.º 6
0
        public void TestFirstDateOfWeekMonday()
        {
            var sundayDate20190825 = new DateTime(2019, 8, 25);
            var sundayDate20190901 = new DateTime(2019, 9, 1);
            var sundayDate20190908 = new DateTime(2019, 9, 8);
            var sundayDate20190915 = new DateTime(2019, 9, 15);
            var sundayDate20190922 = new DateTime(2019, 9, 22);

            Rock.Web.SystemSettings.SetValue(Rock.SystemKey.SystemSetting.START_DAY_OF_WEEK, DayOfWeek.Monday.ConvertToInt().ToString());
            RockDateTime.UpdateSundayDateData();

            Assert.That.IsTrue(new DateTime(2019, 8, 23).SundayDate() == sundayDate20190825, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 24).SundayDate() == sundayDate20190825, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 25).SundayDate() == sundayDate20190825, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 26).SundayDate() == sundayDate20190901, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 27).SundayDate() == sundayDate20190901, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 28).SundayDate() == sundayDate20190901, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 29).SundayDate() == sundayDate20190901, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 8, 30).SundayDate() == sundayDate20190901, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 9, 5).SundayDate() == sundayDate20190908, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 9, 9).SundayDate() == sundayDate20190915, "Incorrect Sunday Date");
            Assert.That.IsTrue(new DateTime(2019, 9, 17).SundayDate() == sundayDate20190922, "Incorrect Sunday Date");

            var attendanceOccurrence = new AttendanceOccurrence()
            {
                OccurrenceDate = new DateTime(2019, 9, 17)
            };

            Assert.That.IsTrue(attendanceOccurrence.SundayDate == new DateTime(2019, 9, 17).SundayDate());
            attendanceOccurrence = new AttendanceOccurrence()
            {
                OccurrenceDate = new DateTime(2019, 9, 19)
            };
            Assert.That.IsTrue(attendanceOccurrence.SundayDate == new DateTime(2019, 9, 19).SundayDate());

            var rockContext = new RockContext();

            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 23 )}')").FirstOrDefault() == sundayDate20190825, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 24 )}')").FirstOrDefault() == sundayDate20190825, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 25 )}')").FirstOrDefault() == sundayDate20190825, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 26 )}')").FirstOrDefault() == sundayDate20190901, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 27 )}')").FirstOrDefault() == sundayDate20190901, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 28 )}')").FirstOrDefault() == sundayDate20190901, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 29 )}')").FirstOrDefault() == sundayDate20190901, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 8, 30 )}')").FirstOrDefault() == sundayDate20190901, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 9, 5 )}')").FirstOrDefault() == sundayDate20190908, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 9, 9 )}')").FirstOrDefault() == sundayDate20190915, "Incorrect Sunday Date (SQL)");
            Assert.That.IsTrue(rockContext.Database.SqlQuery <DateTime>($@"SELECT dbo.ufnUtility_GetSundayDate('{new DateTime( 2019, 9, 17 )}')").FirstOrDefault() == sundayDate20190922, "Incorrect Sunday Date (SQL)");
        }
 /// <inheritdoc/>
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     if (reader.TokenType == JsonToken.Date && reader.Value is DateTimeOffset dateTimeOffset)
     {
         return(RockDateTime.ConvertLocalDateTimeToRockDateTime(dateTimeOffset.LocalDateTime));
     }
     else if (reader.TokenType == JsonToken.Date && reader.Value is DateTime dateTime)
     {
         return(RockDateTime.ConvertLocalDateTimeToRockDateTime(dateTime));
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 8
0
        /// <inheritdoc/>
        public override object ConvertTo(Type type, CultureInfo culture)
        {
            if (type == typeof(DateTime) || type == typeof(DateTime? ))
            {
                var value = base.ConvertTo(type, culture);

                // If the value is a DateTime then it will be in the local system
                // date and time. Convert it to Rock Organization date time.
                if (value is DateTime dateTime)
                {
                    return(RockDateTime.ConvertLocalDateTimeToRockDateTime(dateTime));
                }
            }

            return(base.ConvertTo(type, culture));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sets the RockDateTime timezone to a value that is suitable for testing an operating environment
        /// in which the organization timezone supports daylight saving time.
        /// </summary>
        public static void SetRockDateTimeToDaylightSavingTimezone()
        {
            // Set to Mountain Standard Time (MST), a timezone that supports Daylight Saving Time (DST).
            var tz = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");

            Assert.That.IsNotNull(tz, "Timezone 'MST' is not available in this environment.");

            Assert.That.IsTrue(tz.SupportsDaylightSavingTime, "Test Timezone should be configured for Daylight Saving Time (DST).");

            RockDateTime.Initialize(tz);

            // Re-initialize the lava engine options.
            var options = GetCurrentEngineOptions();

            _fluidEngine.Initialize(options);
        }
        /// <summary>
        /// Sets the RockDateTime timezone to a value that is suitable for testing an operating environment
        /// in which the organization timezone does not match the local system timezone.
        /// This configuration simulates a Rock server hosted in a different timezone to the Rock organization.
        /// </summary>
        public static void SetRockOrganizationTimeZone(string timeZoneId)
        {
            try
            {
                var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);

                RockDateTime.Initialize(tz);
            }
            catch (TimeZoneNotFoundException)
            {
                throw new Exception($"Timezone '{timeZoneId}' is not available in this environment.");
            }

            // Re-initialize the lava engine options.
            var options = GetCurrentEngineOptions();

            _fluidEngine.Initialize(options);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Cleans expired cached files from the cache folder
        /// </summary>
        /// <param name="directoryPath">The directory path.</param>
        /// <param name="expirationDate">The file expiration date. Files older than this date will be deleted</param>
        private void CleanCacheDirectory(string directoryPath, DateTime expirationDate)
        {
            // verify that the directory exists
            if (!Directory.Exists(directoryPath))
            {
                // if directory doesn't exist return
                return;
            }

            // loop through each file in the directory
            foreach (string filePath in Directory.GetFiles(directoryPath))
            {
                // if the file creation date is older than the expiration date
                DateTime adjustedFileDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(File.GetCreationTime(filePath));
                if (adjustedFileDateTime < expirationDate)
                {
                    // delete the file
                    DeleteFile(filePath, false);
                }
            }

            // loop through each subdirectory in the current directory
            foreach (string subDirectory in Directory.GetDirectories(directoryPath))
            {
                // if the directory is not a reparse point
                if ((File.GetAttributes(subDirectory) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
                {
                    // clean the directory
                    CleanCacheDirectory(subDirectory, expirationDate);
                }
            }

            // get subdirectory and file count
            int directoryCount = Directory.GetDirectories(directoryPath).Length;
            int fileCount      = Directory.GetFiles(directoryPath).Length;

            // if directory is empty
            if ((directoryCount + fileCount) == 0)
            {
                // delete the directory
                DeleteDirectory(directoryPath, false);
            }
        }
Ejemplo n.º 12
0
    private void ProcessForWorkflow(Guid?actionGuid, Rock.Data.RockContext rockContext, SendGridEvent payload)
    {
        RockLogger.Log.Debug(RockLogDomains.Communications, "ProcessForWorkflow {@payload}", payload);

        string status = string.Empty;

        switch (payload.EventType)
        {
        case "unsubscribe":
        case "delivered":
            status = SendEmailWithEvents.SENT_STATUS;
            break;

        case "click":
            status = SendEmailWithEvents.CLICKED_STATUS;
            break;

        case "open":
            status = SendEmailWithEvents.OPENED_STATUS;
            break;

        case "failed":
        case "dropped":
        case "blocked":
        case "bounce":
        case "bounced":
            status = SendEmailWithEvents.FAILED_STATUS;
            string message = payload.ServerResponse.IsNotNullOrWhiteSpace() ? payload.ServerResponse : payload.EventTypeReason;

            Rock.Communication.Email.ProcessBounce(
                payload.Email,
                Rock.Communication.BounceType.HardBounce,
                message,
                RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(payload.Timestamp).ToLocalTime()));
            break;
        }

        if (actionGuid != null && !string.IsNullOrWhiteSpace(status))
        {
            SendEmailWithEvents.UpdateEmailStatus(actionGuid.Value, status, payload.EventType, rockContext, true);
        }
    }
Ejemplo n.º 13
0
        /// <summary>
        /// Checks if the interaction is for a communication and if so do
        /// additional steps to mark the communication as opened..
        /// </summary>
        /// <param name="session">The interaction session.</param>
        /// <param name="interaction">The interaction data.</param>
        /// <param name="rockContext">The rock context.</param>
        private void ProcessCommunicationInteraction(MobileInteractionSession session, MobileInteraction interaction, Rock.Data.RockContext rockContext)
        {
            // The interaction must be for the communication channel.
            if (interaction.ChannelGuid != _communicationInteractionChannelGuid && interaction.ChannelId != CommunicationInteractionChannelId)
            {
                return;
            }

            // We need the communication recipient identifier and the communication identifier.
            if (!interaction.EntityId.HasValue || !interaction.ComponentEntityId.HasValue)
            {
                return;
            }

            // Only process "Opened" operations for now.
            if (!interaction.Operation.Equals("OPENED", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            // Because this is a mostly open API, don't trust just the
            // recipient identifier. Do a query that makes sure both the
            // communication identifier and the recipient identifier match
            // for a bit of extra security.
            var communicationRecipient = new CommunicationRecipientService(rockContext).Queryable()
                                         .Where(a => a.Id == interaction.EntityId && a.CommunicationId == interaction.ComponentEntityId)
                                         .FirstOrDefault();

            if (communicationRecipient == null)
            {
                return;
            }

            communicationRecipient.Status         = CommunicationRecipientStatus.Opened;
            communicationRecipient.OpenedDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(interaction.DateTime.LocalDateTime);
            communicationRecipient.OpenedClient   = string.Format(
                "{0} {1} ({2})",
                session.OperatingSystem ?? "unknown",
                session.Application ?? "unknown",
                session.ClientType ?? "unknown");
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Initializes the Rock organization time zone.
        /// </summary>
        private static void InitializeRockOrgTimeZone()
        {
            string orgTimeZoneSetting = ConfigurationManager.AppSettings["OrgTimeZone"];

            if (string.IsNullOrWhiteSpace(orgTimeZoneSetting))
            {
                RockDateTime.Initialize(TimeZoneInfo.Local);
            }
            else
            {
                // if Web.Config has the OrgTimeZone set to the special "Local" (intended for Developer Mode), just use the Local DateTime. However, a production install of Rock will always have a real Time Zone string
                if (orgTimeZoneSetting.Equals("Local", StringComparison.OrdinalIgnoreCase))
                {
                    RockDateTime.Initialize(TimeZoneInfo.Local);
                }
                else
                {
                    RockDateTime.Initialize(TimeZoneInfo.FindSystemTimeZoneById(orgTimeZoneSetting));
                }
            }
        }
Ejemplo n.º 15
0
    /// <summary>
    /// Processes for workflow.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="actionGuid">The action unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForWorkflow(Guid?actionGuid, Rock.Data.RockContext rockContext)
    {
        string status = string.Empty;

        switch (mailgunRequestPayload.EventType)
        {
        case "complained":
        case "unsubscribed":
        case "delivered":
            status = SendEmailWithEvents.SENT_STATUS;
            break;

        case "clicked":
            status = SendEmailWithEvents.CLICKED_STATUS;
            break;

        case "opened":
            status = SendEmailWithEvents.OPENED_STATUS;
            break;

        case "failed":
        case "dropped":
        case "suppress-bounce":
        case "bounced":
            status = SendEmailWithEvents.FAILED_STATUS;
            string message = mailgunRequestPayload.Notification.IsNotNullOrWhiteSpace() ? mailgunRequestPayload.Notification : mailgunRequestPayload.Description;

            Rock.Communication.Email.ProcessBounce(
                mailgunRequestPayload.Recipient,
                Rock.Communication.BounceType.HardBounce,
                message,
                RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(mailgunRequestPayload.TimeStamp).ToLocalTime()));
            break;
        }

        if (actionGuid != null && !string.IsNullOrWhiteSpace(status))
        {
            SendEmailWithEvents.UpdateEmailStatus(actionGuid.Value, status, mailgunRequestPayload.EventType, rockContext, true);
        }
    }
Ejemplo n.º 16
0
        /// <summary>
        /// Handles the Click event of the btnSaveStartDayOfWeek control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnSaveStartDayOfWeek_Click(object sender, EventArgs e)
        {
            if (dowpStartingDayOfWeek.SelectedDayOfWeek != RockDateTime.FirstDayOfWeek)
            {
                Rock.Web.SystemSettings.SetValue(Rock.SystemKey.SystemSetting.START_DAY_OF_WEEK, dowpStartingDayOfWeek.SelectedDayOfWeek.ConvertToInt().ToString());
                Task.Run(() =>
                {
                    try
                    {
                        RockDateTime.UpdateSundayDateData();
                    }
                    catch (Exception ex)
                    {
                        ExceptionLogService.LogException(new Exception("An error occurred applying the Start Of Week setting", ex));
                    }
                });

                nbStartDayOfWeekSaveMessage.NotificationBoxType = NotificationBoxType.Success;
                nbStartDayOfWeekSaveMessage.Title = string.Empty;
                nbStartDayOfWeekSaveMessage.Text  = string.Format("Start Day of Week is now set to <strong>{0}</strong>. ", dowpStartingDayOfWeek.SelectedDayOfWeek.ConvertToString());
            }
        }
Ejemplo n.º 17
0
    /// <summary>
    /// Processes for workflow.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="actionGuid">The action unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForWorkflow(string eventType, Guid?actionGuid, Rock.Data.RockContext rockContext)
    {
        string status = string.Empty;

        switch (eventType)
        {
        case "complained":
        case "unsubscribed":
        case "delivered":
            status = SendEmailWithEvents.SENT_STATUS;
            break;

        case "clicked":
            status = SendEmailWithEvents.CLICKED_STATUS;
            break;

        case "opened":
            status = SendEmailWithEvents.OPENED_STATUS;
            break;

        case "dropped":
        case "suppress-bounce":
        case "bounced":
            status = SendEmailWithEvents.FAILED_STATUS;
            int secs = request.Form["timestamp"].AsInteger();
            Rock.Communication.Email.ProcessBounce(
                request.Form["recipient"],
                Rock.Communication.BounceType.HardBounce,
                request.Form["notification"],
                RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(secs).ToLocalTime()));
            break;
        }

        if (actionGuid != null && !string.IsNullOrWhiteSpace(status))
        {
            SendEmailWithEvents.UpdateEmailStatus(actionGuid.Value, status, eventType, rockContext, true);
        }
    }
Ejemplo n.º 18
0
        /// <summary>
        /// Processes the binary file request.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ProcessBinaryFileRequest(HttpContext context)
        {
            int  fileId   = context.Request.QueryString["id"].AsInteger();
            Guid fileGuid = context.Request.QueryString["guid"].AsGuid();

            if (fileId == 0 && fileGuid == Guid.Empty)
            {
                SendBadRequest(context, "File id key must be a guid or an int.");
                return;
            }

            var rockContext = new RockContext();

            var binaryFileQuery = new BinaryFileService(rockContext).Queryable();

            if (fileGuid != Guid.Empty)
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Guid == fileGuid);
            }
            else
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Id == fileId);
            }

            //// get just the binaryFileMetaData (not the file content) just in case we can get the filecontent faster from the cache
            //// a null ModifiedDateTime shouldn't happen, but just in case, set it to DateTime.MaxValue so we error on the side of not getting it from the cache
            var binaryFileMetaData = binaryFileQuery.Select(a => new
            {
                a.Id,
                BinaryFileType_AllowCaching         = a.BinaryFileType.AllowCaching,
                BinaryFileType_RequiresViewSecurity = a.BinaryFileType.RequiresViewSecurity,
                ModifiedDateTime = a.ModifiedDateTime ?? DateTime.MaxValue,
                a.MimeType,
                a.FileName
            }).FirstOrDefault();

            if (binaryFileMetaData == null)
            {
                SendNotFound(context);
                return;
            }

            //// if the binaryFile's BinaryFileType requires view security, check security
            //// note: we put a RequiresViewSecurity flag on BinaryFileType because checking security for every image would be slow (~40ms+ per image request)
            if (binaryFileMetaData.BinaryFileType_RequiresViewSecurity)
            {
                var        currentUser    = new UserLoginService(rockContext).GetByUserName(UserLogin.GetCurrentUserName());
                Person     currentPerson  = currentUser != null ? currentUser.Person : null;
                BinaryFile binaryFileAuth = new BinaryFileService(rockContext).Queryable("BinaryFileType").First(a => a.Id == binaryFileMetaData.Id);
                if (!binaryFileAuth.IsAuthorized(Authorization.VIEW, currentPerson))
                {
                    SendNotAuthorized(context);
                    return;
                }
            }


            Stream fileContent = null;

            try
            {
                // Is it cached
                string cacheName          = UrlQueryToCachedFileName(context.Request.QueryString, binaryFileMetaData.MimeType);
                string physCachedFilePath = context.Request.MapPath(string.Format("~/App_Data/Cache/{0}", cacheName));
                if (binaryFileMetaData.BinaryFileType_AllowCaching && File.Exists(physCachedFilePath))
                {
                    //// Compare the File's LastWrite DateTime (which comes from the OS's clock), adjust it for the Rock OrgTimeZone, then compare to BinaryFile's ModifiedDateTime (which is already in OrgTimeZone).
                    //// If the BinaryFile record in the database is less recent than the last time this was cached, it is safe to use the Cached version.
                    //// NOTE: A BinaryFile record is typically just added and never modified (a modify is just creating a new BinaryFile record and deleting the old one), so the cached version will probably always be the correct choice.
                    DateTime cachedFileDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(File.GetLastWriteTime(physCachedFilePath));
                    if (binaryFileMetaData.ModifiedDateTime < cachedFileDateTime)
                    {
                        // NOTE: the cached file has already been resized (the size is part of the cached file's filename), so we don't need to resize it again
                        fileContent = FetchFromCache(physCachedFilePath);
                    }
                }

                if (fileContent == null)
                {
                    // If we didn't get it from the cache, get it from the binaryFileService
                    BinaryFile binaryFile = GetFromBinaryFileService(context, binaryFileMetaData.Id);

                    if (binaryFile != null)
                    {
                        fileContent = binaryFile.ContentStream;
                    }

                    // If we got the image from the binaryFileService, it might need to be resized and cached
                    if (fileContent != null)
                    {
                        // If more than 1 query string param is passed in, or the mime type is TIFF, assume resize is needed
                        // Note: we force "image/tiff" to get resized so that it gets converted into a jpg (browsers don't like tiffs)
                        if (context.Request.QueryString.Count > 1 || binaryFile.MimeType == "image/tiff")
                        {
                            // if it isn't an SVG file, do a Resize
                            if (binaryFile.MimeType != "image/svg+xml")
                            {
                                fileContent = GetResized(context.Request.QueryString, fileContent);
                            }
                        }

                        if (binaryFileMetaData.BinaryFileType_AllowCaching)
                        {
                            Cache(fileContent, physCachedFilePath);

                            // Reset stream
                            if (fileContent.CanSeek)
                            {
                                fileContent.Seek(0, SeekOrigin.Begin);
                            }
                            else
                            {
                                fileContent = FetchFromCache(physCachedFilePath);
                            }
                        }
                    }
                }

                if (fileContent == null)
                {
                    // if we couldn't get the file from the binaryFileServie or the cache, respond with NotFound
                    SendNotFound(context);
                    return;
                }

                // respond with File
                if (binaryFileMetaData.BinaryFileType_AllowCaching)
                {
                    // if binaryFileType is set to allowcaching, also tell the browser to cache it for 365 days
                    context.Response.Cache.SetLastModified(binaryFileMetaData.ModifiedDateTime);
                    context.Response.Cache.SetMaxAge(new TimeSpan(365, 0, 0, 0));
                }

                // set the mime-type to that of the binary file
                context.Response.ContentType = binaryFileMetaData.MimeType != "image/tiff" ? binaryFileMetaData.MimeType : "image/jpg";

                // check that the format of the image wasn't changed by a format query parm if so adjust the mime-type to reflect the conversion
                if (context.Request["format"].IsNotNullOrWhitespace())
                {
                    switch (context.Request["format"])
                    {
                    case "png":
                    {
                        context.Response.ContentType = "image/png";
                        break;
                    }

                    case "gif":
                    {
                        context.Response.ContentType = "image/gif";
                        break;
                    }

                    case "jpg":
                    {
                        context.Response.ContentType = "image/jpeg";
                        break;
                    }
                    }
                }

                using (var responseStream = fileContent)
                {
                    context.Response.AddHeader("content-disposition", "inline;filename=" + binaryFileMetaData.FileName.MakeValidFileName().UrlEncode());
                    if (responseStream.CanSeek)
                    {
                        responseStream.Seek(0, SeekOrigin.Begin);
                    }
                    responseStream.CopyTo(context.Response.OutputStream);
                    context.Response.Flush();
                }
            }
            finally
            {
                if (fileContent != null)
                {
                    fileContent.Dispose();
                }
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Processes the binary file request.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ProcessBinaryFileRequest(HttpContext context)
        {
            int  fileId   = context.Request.QueryString["id"].AsInteger() ?? 0;
            Guid fileGuid = context.Request.QueryString["guid"].AsGuid();

            if (fileId == 0 && fileGuid.Equals(Guid.Empty))
            {
                SendNotFound(context);
            }

            var rockContext = new RockContext();

            var binaryFileQuery = new BinaryFileService(rockContext).Queryable();

            if (fileGuid != Guid.Empty)
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Guid == fileGuid);
            }
            else
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Id == fileId);
            }

            //// get just the binaryFileMetaData (not the file content) just in case we can get the filecontent faster from the cache
            //// a null ModifiedDateTime shouldn't happen, but just in case, set it to DateTime.MaxValue so we error on the side of not getting it from the cache
            var binaryFileMetaData = binaryFileQuery.Select(a => new
            {
                BinaryFileType_AllowCaching     = a.BinaryFileType.AllowCaching,
                BinaryFileType_RequiresSecurity = a.BinaryFileType.RequiresSecurity,
                ModifiedDateTime = a.ModifiedDateTime ?? DateTime.MaxValue,
                a.MimeType,
                a.FileName
            }).FirstOrDefault();

            if (binaryFileMetaData == null)
            {
                SendNotFound(context);
                return;
            }

            //// if the binaryFile's BinaryFileType requires security, check security
            //// note: we put a RequiresSecurity flag on BinaryFileType because checking security for every image would be slow (~40ms+ per image request)
            if (binaryFileMetaData.BinaryFileType_RequiresSecurity)
            {
                var        currentUser    = new UserLoginService(rockContext).GetByUserName(UserLogin.GetCurrentUserName());
                Person     currentPerson  = currentUser != null ? currentUser.Person : null;
                BinaryFile binaryFileAuth = new BinaryFileService(rockContext).Queryable("BinaryFileType").First(a => a.Guid == fileGuid || a.Id == fileId);
                if (!binaryFileAuth.IsAuthorized(Authorization.VIEW, currentPerson))
                {
                    SendNotAuthorized(context);
                    return;
                }
            }

            byte[] fileContent = null;

            // Is it cached
            string cacheName          = UrlQueryToCachedFileName(context.Request.QueryString, binaryFileMetaData.MimeType);
            string physCachedFilePath = context.Request.MapPath(string.Format("~/App_Data/Cache/{0}", cacheName));

            if (binaryFileMetaData.BinaryFileType_AllowCaching && File.Exists(physCachedFilePath))
            {
                //// Compare the File's Creation DateTime (which comes from the OS's clock), adjust it for the Rock OrgTimeZone, then compare to BinaryFile's ModifiedDateTime (which is already in OrgTimeZone).
                //// If the BinaryFile record in the database is less recent than the last time this was cached, it is safe to use the Cached version.
                //// NOTE: A BinaryFile record is typically just added and never modified (a modify is just creating a new BinaryFile record and deleting the old one), so the cached version will probably always be the correct choice.
                DateTime cachedFileDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(File.GetCreationTime(physCachedFilePath));
                if (binaryFileMetaData.ModifiedDateTime < cachedFileDateTime)
                {
                    // NOTE: the cached file has already been resized (the size is part of the cached file's filename), so we don't need to resize it again
                    fileContent = FetchFromCache(physCachedFilePath);
                }
            }

            if (fileContent == null)
            {
                // If we didn't get it from the cache, get it from the binaryFileService
                BinaryFile binaryFile = GetFromBinaryFileService(context, fileId, fileGuid);

                if (binaryFile != null && binaryFile.Data != null)
                {
                    fileContent = binaryFile.Data.Content;
                }

                // If we got the image from the binaryFileService, it might need to be resized and cached
                if (fileContent != null)
                {
                    // If more than 1 query string param is passed in, assume resize is needed
                    if (context.Request.QueryString.Count > 1)
                    {
                        // if it isn't an SVG file, do a Resize
                        if (binaryFile.MimeType != "image/svg+xml")
                        {
                            fileContent = GetResized(context.Request.QueryString, fileContent);
                        }
                    }

                    if (binaryFileMetaData.BinaryFileType_AllowCaching)
                    {
                        Cache(fileContent, physCachedFilePath);
                    }
                }
            }

            if (fileContent == null)
            {
                // if we couldn't get the file from the binaryFileServie or the cache, respond with NotFound
                SendNotFound(context);
                return;
            }

            // respond with File
            context.Response.ContentType = binaryFileMetaData.MimeType;
            context.Response.AddHeader("content-disposition", "inline;filename=" + binaryFileMetaData.FileName);
            if (binaryFileMetaData.BinaryFileType_AllowCaching)
            {
                // if binaryFileType is set to allowcaching, also tell the browser to cache it for 365 days
                context.Response.Cache.SetLastModified(binaryFileMetaData.ModifiedDateTime);
                context.Response.Cache.SetMaxAge(new TimeSpan(365, 0, 0, 0));
            }

            context.Response.BinaryWrite(fileContent);
            context.Response.Flush();
        }
Ejemplo n.º 20
0
    /// <summary>
    /// Processes for recipient.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="communicationRecipientGuid">The communication recipient unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForReceipent(Guid?communicationRecipientGuid, Rock.Data.RockContext rockContext)
    {
        if (!communicationRecipientGuid.HasValue)
        {
            return;
        }

        var communicationRecipient = new CommunicationRecipientService(rockContext).Get(communicationRecipientGuid.Value);

        if (communicationRecipient != null && communicationRecipient.Communication != null)
        {
            var communicationGuid    = Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid();
            var interactionComponent = new InteractionComponentService(rockContext)
                                       .GetComponentByEntityId(communicationGuid, communicationRecipient.CommunicationId, communicationRecipient.Communication.Subject);

            rockContext.SaveChanges();

            var      interactionService = new InteractionService(rockContext);
            DateTime timeStamp          = RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(mailgunRequestPayload.TimeStamp).ToLocalTime());

            switch (mailgunRequestPayload.EventType)
            {
            case "delivered":
                communicationRecipient.Status     = CommunicationRecipientStatus.Delivered;
                communicationRecipient.StatusNote = string.Format("Confirmed delivered by Mailgun at {0}", timeStamp.ToString());
                break;

            case "opened":
                communicationRecipient.Status         = CommunicationRecipientStatus.Opened;
                communicationRecipient.OpenedDateTime = timeStamp;
                communicationRecipient.OpenedClient   = string.Format(
                    "{0} {1} ({2})",
                    mailgunRequestPayload.ClientOs ?? "unknown",
                    mailgunRequestPayload.ClientName ?? "unknown",
                    mailgunRequestPayload.DeviceType ?? "unknown");

                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Opened",
                        string.Empty,
                        communicationRecipient.PersonAliasId,
                        timeStamp,
                        mailgunRequestPayload.ClientName,
                        mailgunRequestPayload.ClientOs,
                        mailgunRequestPayload.ClientType,
                        mailgunRequestPayload.DeviceType,
                        mailgunRequestPayload.Ip,
                        null);
                }

                break;

            case "clicked":
                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Click",
                        mailgunRequestPayload.Url,
                        communicationRecipient.PersonAliasId,
                        timeStamp,
                        mailgunRequestPayload.ClientName,
                        mailgunRequestPayload.ClientOs,
                        mailgunRequestPayload.ClientType,
                        mailgunRequestPayload.DeviceType,
                        mailgunRequestPayload.Ip,
                        null);
                }

                break;

            case "complained":
                break;

            case "unsubscribed":
                break;

            case "dropped":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = mailgunRequestPayload.Description;
                break;

            case "bounced":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = mailgunRequestPayload.Notification;

                Rock.Communication.Email.ProcessBounce(
                    mailgunRequestPayload.Recipient,
                    Rock.Communication.BounceType.HardBounce,
                    mailgunRequestPayload.Notification,
                    timeStamp);
                break;

            case "failed":
                // The new mailgun API bundles undeliverable mail into a failed event. The reason (e.g. bounced) is in a seperate property called reason.
                if (mailgunRequestPayload.EventTypeReason.IsNotNullOrWhiteSpace())
                {
                    switch (mailgunRequestPayload.EventTypeReason)
                    {
                    case "bounce":
                    case "suppress-bounce":
                        communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                        communicationRecipient.StatusNote = mailgunRequestPayload.Description;

                        Rock.Communication.Email.ProcessBounce(
                            mailgunRequestPayload.Recipient,
                            Rock.Communication.BounceType.HardBounce,
                            mailgunRequestPayload.Description,
                            timeStamp);
                        break;

                    default:
                        communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                        communicationRecipient.StatusNote = mailgunRequestPayload.Description;
                        break;
                    }
                }

                break;
            }

            rockContext.SaveChanges();
        }
    }
Ejemplo n.º 21
0
    /// <summary>
    /// Processes for recipient.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="communicationRecipientGuid">The communication recipient unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForReceipent(string eventType, Guid?communicationRecipientGuid, Rock.Data.RockContext rockContext)
    {
        if (!communicationRecipientGuid.HasValue)
        {
            return;
        }

        var communicationRecipient = new CommunicationRecipientService(rockContext).Get(communicationRecipientGuid.Value);

        if (communicationRecipient != null && communicationRecipient.Communication != null)
        {
            int      secs = request.Form["timestamp"].AsInteger();
            DateTime ts   = RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(secs).ToLocalTime());

            var communicationGuid = Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid();

            InteractionComponent interactionComponent = new InteractionComponentService(rockContext)
                                                        .GetComponentByEntityId(communicationGuid, communicationRecipient.CommunicationId, communicationRecipient.Communication.Subject);

            rockContext.SaveChanges();

            var interactionService = new InteractionService(rockContext);

            switch (eventType)
            {
            case "delivered":
                communicationRecipient.Status     = CommunicationRecipientStatus.Delivered;
                communicationRecipient.StatusNote = string.Format("Confirmed delivered by Mailgun at {0}", ts.ToString());
                break;

            case "opened":
                communicationRecipient.Status         = CommunicationRecipientStatus.Opened;
                communicationRecipient.OpenedDateTime = ts;
                communicationRecipient.OpenedClient   = string.Format(
                    "{0} {1} ({2})",
                    request.Form["client-os"] ?? "unknown",
                    request.Form["client-name"] ?? "unknown",
                    request.Form["device-type"] ?? "unknown");

                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Opened",
                        string.Empty,
                        communicationRecipient.PersonAliasId,
                        ts,
                        request.Form["client-name"],
                        request.Form["client-os"],
                        request.Form["client-type"],
                        request.Form["device-type"],
                        request.Form["ip"],
                        null);
                }

                break;

            case "clicked":
                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Click",
                        request.Form["url"],
                        communicationRecipient.PersonAliasId,
                        ts,
                        request.Form["client-name"],
                        request.Form["client-os"],
                        request.Form["client-type"],
                        request.Form["device-type"],
                        request.Form["ip"],
                        null);
                }

                break;

            case "complained":
                break;

            case "unsubscribed":
                break;

            case "dropped":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = request.Form["description"];
                break;

            case "bounced":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = request.Form["notification"];

                Rock.Communication.Email.ProcessBounce(
                    request.Form["recipient"],
                    Rock.Communication.BounceType.HardBounce,
                    request.Form["notification"],
                    ts);

                break;
            }

            rockContext.SaveChanges();
        }
    }
Ejemplo n.º 22
0
    /// <summary>
    /// Processes for recipient.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="communicationRecipientGuid">The communication recipient unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForRecipient(Guid?communicationRecipientGuid, Rock.Data.RockContext rockContext, SendGridEvent payload)
    {
        RockLogger.Log.Debug(RockLogDomains.Communications, "ProcessForRecipient {@payload}", payload);

        if (!communicationRecipientGuid.HasValue)
        {
            return;
        }

        var communicationRecipient = new CommunicationRecipientService(rockContext).Get(communicationRecipientGuid.Value);

        if (communicationRecipient != null && communicationRecipient.Communication != null)
        {
            var communicationGuid    = Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid();
            var interactionComponent = new InteractionComponentService(rockContext)
                                       .GetComponentByEntityId(communicationGuid, communicationRecipient.CommunicationId, communicationRecipient.Communication.Subject);

            rockContext.SaveChanges();

            var      interactionService = new InteractionService(rockContext);
            DateTime timeStamp          = RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(payload.Timestamp).ToLocalTime());

            switch (payload.EventType)
            {
            case "processed":
                // Do nothing.
                break;

            case "dropped":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = payload.EventTypeReason;

                if (payload.EventTypeReason == "Bounced Address")
                {
                    Rock.Communication.Email.ProcessBounce(
                        payload.Email,
                        Rock.Communication.BounceType.HardBounce,
                        payload.EventTypeReason,
                        timeStamp);
                }

                break;

            case "delivered":
                communicationRecipient.Status     = CommunicationRecipientStatus.Delivered;
                communicationRecipient.StatusNote = string.Format("Confirmed delivered by SendGrid at {0}", timeStamp.ToString());
                break;

            case "deferred":
                // TODO: handle deferred.
                break;

            case "bounce":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = payload.EventTypeReason + payload.ServerResponse;

                Rock.Communication.Email.ProcessBounce(
                    payload.Email,
                    Rock.Communication.BounceType.HardBounce,
                    payload.EventTypeReason,
                    timeStamp);
                break;

            case "blocked":
                // TODO: handle blocked.
                break;

            case "open":
                communicationRecipient.Status         = CommunicationRecipientStatus.Opened;
                communicationRecipient.OpenedDateTime = timeStamp;
                communicationRecipient.OpenedClient   = string.Format(
                    "{0} {1} ({2})",
                    payload.ClientOs ?? "unknown",
                    payload.ClientBrowser ?? "unknown",
                    payload.ClientDeviceType ?? "unknown");

                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Opened",
                        payload.SendGridEventId,
                        communicationRecipient.PersonAliasId,
                        timeStamp,
                        payload.ClientBrowser,
                        payload.ClientOs,
                        payload.ClientDeviceType,
                        payload.ClientDeviceBrand,
                        payload.IpAddress,
                        null);
                }

                break;

            case "click":
                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Click",
                        payload.Url,
                        communicationRecipient.PersonAliasId,
                        timeStamp,
                        payload.ClientBrowser,
                        payload.ClientOs,
                        payload.ClientDeviceType,
                        payload.ClientDeviceBrand,
                        payload.IpAddress,
                        null);
                }

                break;

            case "spamreport":
            case "unsubscribe":
            case "group_unsubscribe":
            case "group_resubscribe":
                // Do nothing.
                break;
            }

            rockContext.SaveChanges();
        }
    }
Ejemplo n.º 23
0
 /// <summary>
 /// Sets the RockDateTime timezone to the current system local timezone.
 /// </summary>
 public static void SetRockDateTimeToLocalTimezone()
 {
     RockDateTime.Initialize(TimeZoneInfo.Local);
 }
 /// <summary>
 /// Sets the RockDateTime timezone to the current system local timezone.
 /// </summary>
 public static void SetRockOrganizationLocalTimeZone()
 {
     RockDateTime.Initialize(TimeZoneInfo.Local);
 }
Ejemplo n.º 25
0
        public IHttpActionResult PostInteractions([FromBody] List <MobileInteractionSession> sessions, Guid?personalDeviceGuid = null)
        {
            var person    = GetPerson();
            var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress;

            using (var rockContext = new Data.RockContext())
            {
                var interactionChannelService   = new InteractionChannelService(rockContext);
                var interactionComponentService = new InteractionComponentService(rockContext);
                var interactionSessionService   = new InteractionSessionService(rockContext);
                var interactionService          = new InteractionService(rockContext);
                var userLoginService            = new UserLoginService(rockContext);
                var channelMediumTypeValue      = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE);
                var pageEntityTypeId            = EntityTypeCache.Get(typeof(Model.Page)).Id;

                //
                // Check to see if we have a site and the API key is valid.
                //
                if (MobileHelper.GetCurrentApplicationSite() == null)
                {
                    return(StatusCode(System.Net.HttpStatusCode.Forbidden));
                }

                //
                // Get the personal device identifier if they provided it's unique identifier.
                //
                int?personalDeviceId = null;
                if (personalDeviceGuid.HasValue)
                {
                    personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value);
                }

                //
                // Create a quick way to cache data since we have to loop twice.
                //
                var interactionComponentLookup = new Dictionary <string, int>();

                //
                // Helper method to get a cache key for looking up the component Id.
                //
                string GetComponentCacheKey(MobileInteraction mi)
                {
                    return($"{mi.AppId}:{mi.PageGuid}:{mi.ChannelGuid}:{mi.ChannelId}:{mi.ComponentId}:{mi.ComponentName}");
                }

                //
                // Interactions Components will now try to load from cache which
                // causes problems if we are inside a transaction. So first loop through
                // everything and make sure all our components and channels exist.
                //
                var prePassInteractions = sessions.SelectMany(a => a.Interactions)
                                          .DistinctBy(a => GetComponentCacheKey(a));

                //
                // It's safe to do this pre-pass outside the transaction since we are just creating
                // the channels and components (if necessary), which is going to have to be done at
                // at some point no matter what.
                //
                foreach (var mobileInteraction in prePassInteractions)
                {
                    //
                    // Lookup the interaction channel, and create it if it doesn't exist
                    //
                    if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue)
                    {
                        var site = SiteCache.Get(mobileInteraction.AppId.Value);
                        var page = PageCache.Get(mobileInteraction.PageGuid.Value);

                        if (site == null || page == null)
                        {
                            continue;
                        }

                        //
                        // Try to find an existing interaction channel.
                        //
                        var interactionChannelId = InteractionChannelCache.GetChannelIdByTypeIdAndEntityId(channelMediumTypeValue.Id, site.Id, site.Name, pageEntityTypeId, null);

                        //
                        // Get an existing or create a new component.
                        //
                        var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, page.Id, page.InternalName);

                        interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                    }
                    else if (mobileInteraction.ChannelId.HasValue || mobileInteraction.ChannelGuid.HasValue)
                    {
                        int?interactionChannelId = null;

                        if (mobileInteraction.ChannelId.HasValue)
                        {
                            interactionChannelId = mobileInteraction.ChannelId.Value;
                        }
                        else if (mobileInteraction.ChannelGuid.HasValue)
                        {
                            interactionChannelId = InteractionChannelCache.Get(mobileInteraction.ChannelGuid.Value)?.Id;
                        }

                        if (interactionChannelId.HasValue)
                        {
                            if (mobileInteraction.ComponentId.HasValue)
                            {
                                // Use the provided component identifier.
                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), mobileInteraction.ComponentId.Value);
                            }
                            else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace())
                            {
                                int interactionComponentId;

                                // Get or create a new component with the details we have.
                                if (mobileInteraction.ComponentEntityId.HasValue)
                                {
                                    interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId.Value, mobileInteraction.ComponentEntityId, mobileInteraction.ComponentName);
                                }
                                else
                                {
                                    var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName);

                                    rockContext.SaveChanges();

                                    interactionComponentId = interactionComponent.Id;
                                }

                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                            }
                        }
                    }
                }

                //
                // Now wrap the actual interaction creation inside a transaction. We should
                // probably move this so it uses the InteractionTransaction class for better
                // performance. This is so we can inform the client that either everything
                // saved or that nothing saved. No partial saves here.
                //
                rockContext.WrapTransaction(() =>
                {
                    foreach (var mobileSession in sessions)
                    {
                        var interactionGuids         = mobileSession.Interactions.Select(i => i.Guid).ToList();
                        var existingInteractionGuids = interactionService.Queryable()
                                                       .Where(i => interactionGuids.Contains(i.Guid))
                                                       .Select(i => i.Guid)
                                                       .ToList();

                        //
                        // Loop through all interactions that don't already exist and add each one.
                        //
                        foreach (var mobileInteraction in mobileSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid)))
                        {
                            string cacheKey = GetComponentCacheKey(mobileInteraction);

                            if (!interactionComponentLookup.ContainsKey(cacheKey))
                            {
                                // Shouldn't happen, but just in case.
                                continue;
                            }

                            var interactionComponentId = interactionComponentLookup[cacheKey];

                            //
                            // Add the interaction
                            //
                            var interaction = interactionService.CreateInteraction(interactionComponentId,
                                                                                   mobileInteraction.EntityId,
                                                                                   mobileInteraction.Operation,
                                                                                   mobileInteraction.Summary,
                                                                                   mobileInteraction.Data,
                                                                                   person?.PrimaryAliasId,
                                                                                   RockDateTime.ConvertLocalDateTimeToRockDateTime(mobileInteraction.DateTime.LocalDateTime),
                                                                                   mobileSession.Application,
                                                                                   mobileSession.OperatingSystem,
                                                                                   mobileSession.ClientType,
                                                                                   null,
                                                                                   ipAddress,
                                                                                   mobileSession.Guid);

                            interaction.Guid                  = mobileInteraction.Guid;
                            interaction.PersonalDeviceId      = personalDeviceId;
                            interaction.RelatedEntityTypeId   = mobileInteraction.RelatedEntityTypeId;
                            interaction.RelatedEntityId       = mobileInteraction.RelatedEntityId;
                            interaction.ChannelCustom1        = mobileInteraction.ChannelCustom1;
                            interaction.ChannelCustom2        = mobileInteraction.ChannelCustom2;
                            interaction.ChannelCustomIndexed1 = mobileInteraction.ChannelCustomIndexed1;

                            interactionService.Add(interaction);

                            // Attempt to process this as a communication interaction.
                            ProcessCommunicationInteraction(mobileSession, mobileInteraction, rockContext);
                        }
                    }

                    rockContext.SaveChanges();
                });
            }

            return(Ok());
        }
        public void Execute(IJobExecutionContext context)
        {
            var      rockContext = new RockContext();
            var      dataMap     = context.JobDetail.JobDataMap;
            DateTime?lastRun     = null;

            if (context.PreviousFireTimeUtc.HasValue)
            {
                lastRun = RockDateTime.ConvertLocalDateTimeToRockDateTime(context.PreviousFireTimeUtc.Value.LocalDateTime);
            }

            var systemEmailGuid = dataMap.GetString("Email").AsGuidOrNull();

            string appRoot = Rock.Web.Cache.GlobalAttributesCache.Read().GetValue("PublicApplicationRoot");

            if (appRoot.IsNullOrWhiteSpace())
            {
                throw new Exception("Couldn't fetch application root!");
            }

            if (systemEmailGuid == null)
            {
                throw new Exception("A system email template needs to be set.");
            }

            var systemEmailTemplate = new SystemEmailService(rockContext).Get(systemEmailGuid.Value);

            if (systemEmailTemplate == null)
            {
                throw new Exception("The system email template setting is not a valid system email template.");
            }

            var cutOffHours = dataMap.GetString("IncludeHours").AsIntegerOrNull();

            if (!cutOffHours.HasValue)
            {
                throw new Exception("A cutoff period needs to be set.");
            }

            if (lastRun == null)
            {
                lastRun = RockDateTime.Now.AddHours(-1 * cutOffHours.Value);
            }

            var connectionRequestService = new ConnectionRequestService(rockContext);
            var openConnectionRequests   =
                connectionRequestService.Queryable()
                .AsNoTracking()
                .Where(cr => cr.CreatedDateTime >= lastRun && cr.ConnectionState != ConnectionState.Connected && cr.ConnectorPersonAliasId != null);

            if (!openConnectionRequests.Any())
            {
                context.Result = "There are no open and assigned connection requests to send alerts for";
                return;
            }

            var groupedRequests = openConnectionRequests
                                  .ToList()
                                  .GroupBy(cr => cr.ConnectorPersonAlias);

            int mailedCount = 0;

            foreach (var connectionRequestGrouping in groupedRequests)
            {
                if (connectionRequestGrouping.Key == null)
                {
                    continue;
                }
                var connectionRequests = connectionRequestGrouping.ToList();

                var mergeFields = new Dictionary <string, object>
                {
                    { "ConnectionRequests", connectionRequests },
                    { "Person", connectionRequestGrouping.Key.Person }
                };

                var recipients = new List <string> {
                    connectionRequestGrouping.Key.Person.Email
                };

                Email.Send(systemEmailTemplate.From.ResolveMergeFields(mergeFields), systemEmailTemplate.FromName.ResolveMergeFields(mergeFields), systemEmailTemplate.Subject.ResolveMergeFields(mergeFields), recipients, systemEmailTemplate.Body.ResolveMergeFields(mergeFields), appRoot, null);
                mailedCount++;
            }
            context.Result = string.Format("{0} reminders were sent ", mailedCount);
        }