private static ItemViewDiscountedReason VerifyView(Core core, ItemView view) { ItemViewDiscountedReason returnValue = ItemViewDiscountedReason.None; if (SessionState.IsBotUserAgent(view.HttpUserAgent) != null) { return ItemViewDiscountedReason.BotDetected; } // Select the number of views within 24 hours of the view SelectQuery query = new SelectQuery(typeof(ItemView)); query.AddField(new QueryFunction("view_id", QueryFunctions.Count, "real_views")); query.AddCondition("view_item_id", view.ViewKey.Id); query.AddCondition("view_item_type_id", view.ViewKey.TypeId); //query.AddCondition("view_processed", true); QueryCondition qc1 = query.AddCondition("view_ip", view.viewIp); QueryCondition qc2 = qc1.AddCondition("view_time_ut", ConditionEquality.GreaterThan, view.viewTimeRaw - 60 * 60 * 24); // last 24 hours qc2.AddCondition("view_time_ut", ConditionEquality.LessThan, view.viewTimeRaw + 60 * 5); // any in the next 5 minutes discounts the whole set qc1.AddCondition(ConditionRelations.Or, "view_session_id", view.viewSessionId); if (view.userId > 0) { qc1.AddCondition(ConditionRelations.Or, "user_id", view.userId); } if ((long)core.Db.Query(query).Rows[0]["real_views"] > 1) { returnValue = returnValue | ItemViewDiscountedReason.RateLimited; } if ((!view.viewHttpUserAgent.ToLower().Contains("mozilla/") && !view.viewHttpUserAgent.ToLower().Contains("gecko")) || view.viewHttpUserAgent.Length < 32) { returnValue = returnValue | ItemViewDiscountedReason.BadUserAgent; } // query = new SelectQuery(typeof(ItemView)); query.AddField(new QueryFunction("view_id", QueryFunctions.Count, "real_views")); query.AddCondition("view_ip", view.viewIp); query.AddCondition("view_time_ut", ConditionEquality.GreaterThan, view.viewTimeRaw - 10); query.AddCondition("view_time_ut", ConditionEquality.LessThan, view.viewTimeRaw + 10); if ((long)core.Db.Query(query).Rows[0]["real_views"] > 8) { returnValue = returnValue | ItemViewDiscountedReason.RateLimited; } // ensure that the session is only used by ONE browser, no session hijacking query = new SelectQuery(typeof(ItemView)); query.AddField(new DataField(typeof(ItemView), "view_http_user_agent")); query.AddCondition("view_session_id", view.viewSessionId); query.AddCondition("view_time_ut", ConditionEquality.GreaterThan, view.viewTimeRaw - 3600); query.AddCondition("view_time_ut", ConditionEquality.LessThan, view.viewTimeRaw + 3600); query.Distinct = true; if ((long)core.Db.Query(query).Rows.Count > 1) { returnValue = returnValue | ItemViewDiscountedReason.BotDetected; } long viewQuality = 0; if (view.viewTimespan > 60) { viewQuality += 3; } else if (view.viewTimespan > 30) { viewQuality += 2; } else if (view.viewTimespan > 5) { viewQuality++; } if (view.viewJavascript) { viewQuality++; } if (view.viewCookies) { viewQuality++; } else { // cookies can't be detected on the landing page, but a legit IP with a cookie is unlikely to go bad even if shared query = new SelectQuery(typeof(ItemView)); query.AddField(new QueryFunction("view_id", QueryFunctions.Count, "real_views")); query.AddCondition("view_ip", view.viewIp); query.AddCondition("view_cookies", true); if ((long)core.Db.Query(query).Rows[0]["real_views"] > 0) { viewQuality++; } } if (IsRecentBrowser(view.viewHttpUserAgent)) { viewQuality += 2; } else { returnValue = returnValue | ItemViewDiscountedReason.OldUserAgent; } if (!string.IsNullOrEmpty(view.viewHttpReferer)) { viewQuality++; } if (viewQuality < 3) { returnValue = returnValue | ItemViewDiscountedReason.LowQuality; } return returnValue; }
/// <summary> /// /// </summary> /// <param name="core"></param> public static void UpdateView(Core core, bool response) { if (core == null) { throw new NullCoreException(); } long viewId = core.Functions.FormLong("vid", core.Functions.RequestLong("vid", 0)); string mode = core.Http.Form["view-mode"]; // tick, background, foreground, unload if (string.IsNullOrEmpty(mode)) { mode = core.Http["view-mode"]; } long timestamp = UnixTime.UnixTimeStamp(); if (viewId > 0) { ItemView view = new ItemView(core, viewId); if (view.viewSessionId == core.Session.SessionId) { switch (mode.ToLower()) { case "tick": if (view.viewState != (int)ItemViewState.Exited && view.viewState != (int)ItemViewState.Inactive) { if (timestamp - view.viewUpdateTimeRaw < 120) // ticks happen every 60 seconds with a 60 second page timeout { UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_timespan", new QueryOperation("view_timespan", QueryOperations.Addition, timestamp - view.viewUpdateTimeRaw)); uQuery.AddField("view_update_time_ut", timestamp); uQuery.AddField("view_cookies", core.Session.SessionMethod == SessionMethods.Cookie); uQuery.AddField("view_javascript", true); uQuery.AddField("view_state", (int)ItemViewState.Foreground); uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } else { UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_update_time_ut", timestamp); uQuery.AddField("view_state", (int)ItemViewState.Foreground); uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } } break; case "background": case "unload": case "inactive": { UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_javascript", true); if (timestamp - view.viewUpdateTimeRaw < 120) { uQuery.AddField("view_timespan", new QueryOperation("view_timespan", QueryOperations.Addition, timestamp - view.viewUpdateTimeRaw)); } uQuery.AddField("view_update_time_ut", timestamp); if (mode.ToLower() == "unload") { uQuery.AddField("view_state", (int)ItemViewState.Exited); } else if (mode.ToLower() == "inactive") { uQuery.AddField("view_state", (int)ItemViewState.Inactive); } else { uQuery.AddField("view_state", (int)ItemViewState.Background); } uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } break; case "foreground": { UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_update_time_ut", timestamp); uQuery.AddField("view_state", (int)ItemViewState.Foreground); uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } break; case "active": { UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_update_time_ut", timestamp); uQuery.AddField("view_state", (int)ItemViewState.Active); uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } break; } } else { // probably a view bot UpdateQuery uQuery = new UpdateQuery(typeof(ItemView)); uQuery.AddField("view_discounted", true); uQuery.AddField("view_processed", true); uQuery.SetBitField("view_discounted_reason", (int)ItemViewDiscountedReason.InvalidSession); uQuery.AddCondition("view_id", viewId); core.Db.Query(uQuery); } } if (response) { core.Response.SendStatus("viewLogged"); } }