private static async Task <bool> UpdateUserSteamFrinedsAsync([NotNull] string userId, KeylolDbContext dbContext, KeylolUserManager userManager, RedisProvider redis) { var cacheKey = UserSteamFriendRecordsCrawlerStampCacheKey(userId); var redisDb = redis.GetDatabase(); var cacheResult = await redisDb.StringGetAsync(cacheKey); if (cacheResult.HasValue) { return(false); } await redisDb.StringSetAsync(cacheKey, DateTime.Now.ToTimestamp(), UserSteamFriendsUpdatePeriod); try { var steamId = new SteamID(); steamId.SetFromSteam3String(await userManager.GetSteamIdAsync(userId)); var result = JObject.Parse(await HttpClient.GetStringAsync( $"http://api.steampowered.com/ISteamUser/GetFriendList/v1/?key={ApiKey}&format=json&steamid={steamId.ConvertToUInt64()}&relationship=friend")); var oldRecords = (await dbContext.UserSteamFriendRecords.Where(r => r.UserId == userId).ToListAsync()) .ToDictionary(r => r.FriendSteamId, r => r); foreach (var friend in result["friendslist"]["friends"]) { var friendSteamId = (new SteamID(ulong.Parse((string)friend["steamid"]))).Render(true); UserSteamFriendRecord record; if (oldRecords.TryGetValue(friendSteamId, out record)) { oldRecords.Remove(friendSteamId); } else { record = new UserSteamFriendRecord { UserId = userId, FriendSteamId = friendSteamId }; dbContext.UserSteamFriendRecords.Add(record); if (friend["friend_since"] != null) { record.FriendSince = Helpers.DateTimeFromTimeStamp((ulong)friend["friend_since"]); } } } dbContext.UserSteamFriendRecords.RemoveRange(oldRecords.Values); await dbContext.SaveChangesAsync(); return(true); } catch (Exception) { await redisDb.KeyExpireAsync(cacheKey, SilenceTime); return(false); } }
/// <summary> /// 创建 <see cref="UserBasicInfo"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="user">用户对象</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="userManager"><see cref="KeylolUserManager"/></param> /// <returns><see cref="UserBasicInfo"/></returns> public static async Task <UserBasicInfo> CreateAsync(string currentUserId, KeylolUser user, KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager) { var basicInfo = new UserBasicInfo { Id = user.Id, IdCode = user.IdCode, HeaderImage = user.HeaderImage, AvatarImage = user.AvatarImage, UserName = user.UserName, GamerTag = user.GamerTag, RegisterTime = user.RegisterTime, IsFriend = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsFriendAsync(currentUserId, user.Id), Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, user.Id, SubscriptionTargetType.User), FriendCount = await cachedData.Subscriptions.GetFriendCountAsync(user.Id), SubscribedUserCount = await cachedData.Subscriptions.GetSubscribedUserCountAsync(user.Id), SubscriberCount = await cachedData.Subscriptions.GetSubscriberCountAsync(user.Id, SubscriptionTargetType.User), ThemeColor = user.ThemeColor, LightThemeColor = user.LightThemeColor, SteamId = await userManager.GetSteamIdAsync(user.Id) }; if (!string.IsNullOrWhiteSpace(basicInfo.SteamId)) { basicInfo.SteamProfileName = user.SteamProfileName; } int steamCnUid; if (int.TryParse(await userManager.GetSteamCnUidAsync(user.Id), out steamCnUid)) { basicInfo.SteamCnUid = steamCnUid; basicInfo.SteamCnUserName = user.SteamCnUserName; } return(basicInfo); }
/// <summary> /// 抓取指定用户的 Steam App 库 /// </summary> /// <param name="userId">用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="userManager"><see cref="KeylolUserManager"/></param> /// <param name="redis"><see cref="RedisProvider"/></param> /// <param name="cachedData"><see cref="CachedDataProvider.CachedDataProvider"/></param> /// <returns>如果抓取成功,返回 <c>true</c></returns> public static async Task <bool> UpdateUserSteamGameRecordsAsync([NotNull] string userId, KeylolDbContext dbContext, KeylolUserManager userManager, RedisProvider redis, CachedDataProvider.CachedDataProvider cachedData) { var cacheKey = UserSteamGameRecordsCrawlerStampCacheKey(userId); var redisDb = redis.GetDatabase(); var cacheResult = await redisDb.StringGetAsync(cacheKey); if (cacheResult.HasValue) { return(false); } await redisDb.StringSetAsync(cacheKey, DateTime.Now.ToTimestamp(), UserSteamGameRecordsUpdatePeriod); try { var user = await userManager.FindByIdAsync(userId); var steamId = new SteamID(); steamId.SetFromSteam3String(await userManager.GetSteamIdAsync(user.Id)); string allGamesHtml; if (user.SteamBotId != null && user.SteamBot.IsOnline()) { var botCoordinator = SteamBotCoordinator.Sessions[user.SteamBot.SessionId]; allGamesHtml = await botCoordinator.Client.Curl(user.SteamBotId, $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } else { allGamesHtml = await HttpClient.GetStringAsync( $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } if (string.IsNullOrWhiteSpace(allGamesHtml)) { throw new Exception(); } var match = Regex.Match(allGamesHtml, @"<script language=""javascript"">\s*var rgGames = (.*)"); if (!match.Success) { throw new Exception(); } var trimed = match.Groups[1].Value.Trim(); var games = JArray.Parse(trimed.Substring(0, trimed.Length - 1)); var oldRecords = (await dbContext.UserSteamGameRecords.Where(r => r.UserId == user.Id).ToListAsync()) .ToDictionary(r => r.SteamAppId, r => r); foreach (var game in games) { var appId = (int)game["appid"]; UserSteamGameRecord record; if (oldRecords.TryGetValue(appId, out record)) { oldRecords.Remove(appId); } else { record = new UserSteamGameRecord { UserId = user.Id, SteamAppId = appId }; dbContext.UserSteamGameRecords.Add(record); } record.TwoWeekPlayedTime = game["hours"] != null ? (double)game["hours"] : 0; record.TotalPlayedTime = game["hours_forever"] != null ? (double)game["hours_forever"] : 0; if (game["last_played"] != null) { record.LastPlayTime = Helpers.DateTimeFromTimeStamp((ulong)game["last_played"]); } } dbContext.UserSteamGameRecords.RemoveRange(oldRecords.Values); await dbContext.SaveChangesAsync(); await cachedData.Users.PurgeSteamAppLibraryCacheAsync(userId); return(true); } catch (Exception) { await redisDb.KeyExpireAsync(cacheKey, SilenceTime); return(false); } }
/// <summary> /// 创建 <see cref="ActivityPage"/> /// </summary> /// <param name="authorIdCode">作者识别码</param> /// <param name="sidForAuthor">动态在作者名下的序号</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="isOperator">当前登录用户是否为运维职员</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="userManager"><see cref="KeylolUserManager"/></param> /// <returns><see cref="ActivityPage"/></returns> public static async Task <ActivityPage> CreateAsync(string authorIdCode, int sidForAuthor, string currentUserId, bool isOperator, KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager) { var activityPage = new ActivityPage(); var activity = await dbContext.Activities .Include(a => a.Author) .Include(a => a.TargetPoint) .Where(a => a.Author.IdCode == authorIdCode && a.SidForAuthor == sidForAuthor) .SingleOrDefaultAsync(); if (activity == null) { return(activityPage); } activityPage.Archived = activity.Archived != ArchivedState.None; if (activityPage.Archived.Value && currentUserId != activity.AuthorId && !isOperator) { return(activityPage); } activityPage.PointBasicInfo = await PointBasicInfo.CreateAsync(currentUserId, activity.TargetPoint, dbContext, cachedData); activityPage.AuthorBasicInfo = new UserBasicInfo { Id = activity.Author.Id, IdCode = activity.Author.IdCode, AvatarImage = activity.Author.AvatarImage, UserName = activity.Author.UserName, FriendCount = await cachedData.Subscriptions.GetFriendCountAsync(activity.AuthorId), SubscribedUserCount = await cachedData.Subscriptions .GetSubscribedUserCountAsync(activity.AuthorId), SubscriberCount = await cachedData.Subscriptions .GetSubscriberCountAsync(activity.AuthorId, SubscriptionTargetType.User), IsFriend = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsFriendAsync(currentUserId, activity.AuthorId), Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, activity.AuthorId, SubscriptionTargetType.User), SteamId = await userManager.GetSteamIdAsync(activity.AuthorId) }; if (!string.IsNullOrWhiteSpace(activityPage.AuthorBasicInfo.SteamId)) { activityPage.AuthorBasicInfo.SteamProfileName = activity.Author.SteamProfileName; } activityPage.AuthorPlayedTime = activity.TargetPoint.SteamAppId == null ? null : (await dbContext.UserSteamGameRecords .Where(r => r.UserId == activity.AuthorId && r.SteamAppId == activity.TargetPoint.SteamAppId) .SingleOrDefaultAsync())?.TotalPlayedTime; activityPage.Id = activity.Id; activityPage.Rejected = activity.Rejected; activityPage.Warned = activity.Warned; activityPage.PublishTime = activity.PublishTime; activityPage.Rating = activity.Rating; activityPage.Content = activity.Content; activityPage.CoverImage = activity.CoverImage; var attachedPointIds = Helpers.SafeDeserialize <List <string> >(activity.AttachedPoints) ?? new List <string>(); activityPage.AttachedPoints = (from id in attachedPointIds join point in await(from point in dbContext.Points where attachedPointIds.Contains(point.Id) select new { point.Type, point.Id, point.IdCode, point.AvatarImage, point.ChineseName, point.EnglishName }).ToListAsync() on id equals point.Id select new PointBasicInfo { Type = point.Type, Id = point.Id, IdCode = point.IdCode, AvatarImage = point.AvatarImage, ChineseName = point.ChineseName, EnglishName = point.EnglishName }).ToList(); var comments = await ActivityCommentList.CreateAsync(activity, 1, currentUserId, isOperator, true, dbContext, cachedData); activityPage.CommentCount = comments.Item2; activityPage.CommentPageCount = comments.Item3; activityPage.Comments = comments.Item1; activityPage.LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(activity.Id, LikeTargetType.Activity); activityPage.Liked = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Likes.IsLikedAsync(currentUserId, activity.Id, LikeTargetType.Activity); return(activityPage); }