/// <summary> /// Gets the component identifier by foreign key and ChannelId, and creates it if it doesn't exist. /// If foreignKey is blank, this will throw a <seealso cref="ArgumentNullException" /> /// If creating a new InteractionComponent with this, componentName must be specified /// </summary> /// <param name="foreignKey">The foreign key.</param> /// <param name="interactionChannelId">The interaction channel identifier.</param> /// <param name="componentName">Name of the component.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">ForeignKey must be specified when using GetComponentIdByForeignKey</exception> public static int GetComponentIdByForeignKeyAndChannelId(string foreignKey, int interactionChannelId, string componentName) { if (foreignKey.IsNullOrWhiteSpace()) { throw new ArgumentNullException("ForeignKey must be specified when using GetComponentIdByForeignKey"); } var lookupKey = $"{foreignKey}|interactionChannelId:{interactionChannelId}"; if (_interactionComponentIdLookupFromForeignKey.TryGetValue(lookupKey, out int channelId)) { return(channelId); } using (var rockContext = new RockContext()) { var interactionComponentService = new InteractionComponentService(rockContext); var interactionComponent = interactionComponentService.Queryable() .Where(a => a.ForeignKey == foreignKey && a.InteractionChannelId == interactionChannelId).FirstOrDefault(); if (interactionComponent == null) { interactionComponent = new InteractionComponent(); interactionComponent.Name = componentName; interactionComponent.ForeignKey = foreignKey; interactionComponent.InteractionChannelId = interactionChannelId; interactionComponentService.Add(interactionComponent); rockContext.SaveChanges(); } var interactionComponentId = Get(interactionComponent).Id; _interactionComponentIdLookupFromForeignKey.AddOrUpdate(lookupKey, interactionComponentId, (k, v) => interactionComponentId); return(interactionComponentId); } }
public HttpResponseMessage Post(List <MACPresence> presenceList) { using (var rockContext = new RockContext()) { var interactionChannel = new InteractionChannelService(rockContext).Get(Rock.SystemGuid.InteractionChannel.WIFI_PRESENCE.AsGuid()); if (interactionChannel != null) { var interactionComponentIds = new Dictionary <string, int>(); var personalDeviceService = new PersonalDeviceService(rockContext); var interactionService = new InteractionService(rockContext); var interactionComponentService = new InteractionComponentService(rockContext); // Can't set to local time here as it won't compute DST correctly later. var epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); foreach (var macPresence in presenceList.Where(l => l.Mac != null && l.Mac != "")) { var device = personalDeviceService.GetByMACAddress(macPresence.Mac); if (device == null) { device = new PersonalDevice(); device.MACAddress = macPresence.Mac; personalDeviceService.Add(device); rockContext.SaveChanges(); } if (macPresence.Presence != null && macPresence.Presence.Any()) { foreach (var presence in macPresence.Presence) { // Calc data needed for new and existing data DateTime interactionStart = epochTime.AddSeconds(presence.Arrive).ToLocalTime(); DateTime interactionEnd = epochTime.AddSeconds(presence.Depart).ToLocalTime(); TimeSpan ts = interactionEnd.Subtract(interactionStart); string duration = (ts.TotalMinutes >= 60 ? $"{ts:%h} hours and " : "") + $"{ts:%m} minutes"; Interaction interaction = interactionService.Queryable().Where(i => i.ForeignKey != null && i.ForeignKey == presence.SessionId).FirstOrDefault(); if (interaction == null) { if (!interactionComponentIds.ContainsKey(presence.Space)) { var component = interactionComponentService .Queryable().AsNoTracking() .Where(c => c.InteractionChannelId == interactionChannel.Id && c.Name == presence.Space) .FirstOrDefault(); if (component == null) { component = new InteractionComponent(); interactionComponentService.Add(component); component.InteractionChannelId = interactionChannel.Id; component.Name = presence.Space; rockContext.SaveChanges(); } interactionComponentIds.Add(presence.Space, component.Id); } interaction = new Interaction(); interaction.InteractionDateTime = interactionStart; interaction.InteractionEndDateTime = interactionEnd; interaction.Operation = "Present"; interaction.InteractionSummary = $"Arrived at {presence.Space} on {interactionStart.ToShortDateTimeString()}. Stayed for {duration}."; interaction.InteractionComponentId = interactionComponentIds[presence.Space]; interaction.InteractionData = presence.ToJson(); interaction.PersonalDeviceId = device.Id; interaction.PersonAliasId = device.PersonAliasId; interaction.ForeignKey = presence.SessionId; interactionService.Add(interaction); } else { // Update the existing interaction interaction.InteractionEndDateTime = interactionEnd; interaction.InteractionSummary = $"Arrived at {presence.Space} on {interactionStart.ToShortDateTimeString()}. Stayed for {duration}."; interaction.InteractionData = presence.ToJson(); } rockContext.SaveChanges(); } } } var response = ControllerContext.Request.CreateResponse(HttpStatusCode.Created); return(response); } else { var response = ControllerContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "A WiFi Presense Interaction Channel Was Not Found!"); throw new HttpResponseException(response); } } }
/// <summary> /// Execute method to write transaction to the database. /// </summary> public void Execute() { using ( var rockContext = new RockContext() ) { var userAgent = (this.UserAgent ?? string.Empty).Trim(); if ( userAgent.Length > 450 ) { userAgent = userAgent.Substring( 0, 450 ); // trim super long useragents to fit in pageViewUserAgent.UserAgent } // get user agent info var clientType = PageViewUserAgent.GetClientType( userAgent ); // don't log visits from crawlers if ( clientType != "Crawler" ) { InteractionChannelService interactionChannelService = new InteractionChannelService( rockContext ); InteractionComponentService interactionComponentService = new InteractionComponentService( rockContext ); InteractionDeviceTypeService interactionDeviceTypeService = new InteractionDeviceTypeService( rockContext ); InteractionSessionService interactionSessionService = new InteractionSessionService( rockContext ); InteractionService interactionService = new InteractionService( rockContext ); ClientInfo client = uaParser.Parse( userAgent ); var clientOs = client.OS.ToString(); var clientBrowser = client.UserAgent.ToString(); // lookup the interactionDeviceType, and create it if it doesn't exist var interactionDeviceType = interactionDeviceTypeService.Queryable().Where( a => a.Application == clientBrowser && a.OperatingSystem == clientOs && a.ClientType == clientType ).FirstOrDefault(); if ( interactionDeviceType == null ) { interactionDeviceType = new InteractionDeviceType(); interactionDeviceType.DeviceTypeData = userAgent; interactionDeviceType.ClientType = clientType; interactionDeviceType.OperatingSystem = clientOs; interactionDeviceType.Application = clientBrowser; interactionDeviceType.Name = string.Format( "{0} - {1}", clientOs, clientBrowser ); interactionDeviceTypeService.Add( interactionDeviceType ); rockContext.SaveChanges(); } // lookup interactionSession, and create it if it doesn't exist Guid sessionId = this.SessionId.AsGuid(); int? interactionSessionId = interactionSessionService.Queryable() .Where( a => a.DeviceTypeId == interactionDeviceType.Id && a.Guid == sessionId ) .Select( a => (int?)a.Id ) .FirstOrDefault(); if ( !interactionSessionId.HasValue ) { var interactionSession = new InteractionSession(); interactionSession.DeviceTypeId = interactionDeviceType.Id; interactionSession.IpAddress = this.IPAddress; interactionSession.Guid = sessionId; interactionSessionService.Add( interactionSession ); rockContext.SaveChanges(); interactionSessionId = interactionSession.Id; } int componentEntityTypeId = EntityTypeCache.Read<Rock.Model.Page>().Id; string siteName = SiteCache.Read( SiteId ?? 1 ).Name; // lookup the interaction channel, and create it if it doesn't exist int channelMediumTypeValueId = DefinedValueCache.Read( SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid() ).Id; // check that the site exists as a channel var interactionChannel = interactionChannelService.Queryable() .Where( a => a.ChannelTypeMediumValueId == channelMediumTypeValueId && a.ChannelEntityId == this.SiteId ) .FirstOrDefault(); if ( interactionChannel == null ) { interactionChannel = new InteractionChannel(); interactionChannel.Name = siteName; interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId; interactionChannel.ChannelEntityId = this.SiteId; interactionChannel.ComponentEntityTypeId = componentEntityTypeId; interactionChannelService.Add( interactionChannel ); rockContext.SaveChanges(); } // check that the page exists as a component var interactionComponent = interactionComponentService.Queryable() .Where( a => a.EntityId == PageId && a.ChannelId == interactionChannel.Id ) .FirstOrDefault(); if ( interactionComponent == null ) { interactionComponent = new InteractionComponent(); interactionComponent.Name = PageTitle; interactionComponent.EntityId = PageId; interactionComponent.ChannelId = interactionChannel.Id; interactionComponentService.Add( interactionComponent ); rockContext.SaveChanges(); } // add the interaction Interaction interaction = new Interaction(); interactionService.Add( interaction ); // obfuscate rock magic token Regex rgx = new Regex( @"rckipid=([^&]*)" ); string cleanUrl = rgx.Replace( this.Url, "rckipid=XXXXXXXXXXXXXXXXXXXXXXXXXXXX" ); interaction.InteractionData = cleanUrl; interaction.Operation = "View"; interaction.PersonAliasId = this.PersonAliasId; interaction.InteractionDateTime = this.DateViewed; interaction.InteractionSessionId = interactionSessionId; interaction.InteractionComponentId = interactionComponent.Id; rockContext.SaveChanges(); } } }