using dy.net.model.dto; using Newtonsoft.Json.Linq; namespace dy.net.utils { public static class DouyinLiveStatusParser { public static DouyinLiveStatusProbe Parse( int? liveStatus, string roomId, string roomIdStr, JToken roomData) { var room = NormalizeRoomData(roomData); var roomStatus = FindInt(room, "status"); var isLive = liveStatus == 1 || (!liveStatus.HasValue && roomStatus == 2); var hasKnownStatus = liveStatus.HasValue || roomStatus.HasValue; return new DouyinLiveStatusProbe { Status = isLive ? DouyinLiveStatusState.Live : hasKnownStatus ? DouyinLiveStatusState.Offline : DouyinLiveStatusState.Unknown, RoomId = FirstNonEmpty( roomIdStr, roomId, FindString(room, "id_str"), FindString(room, "room_id_str"), FindString(room, "room_id")), WebRid = FirstNonEmpty( FindString(room, "web_rid"), FindString(room, "webRid")), Title = Limit(FindString(room, "title"), 500), StartedAt = ParseUnixTime(FindLong(room, "start_time") ?? FindLong(room, "create_time")) }; } private static JToken NormalizeRoomData(JToken value) { if (value == null || value.Type == JTokenType.Null) return null; if (value.Type != JTokenType.String) return value; var text = value.Value(); if (string.IsNullOrWhiteSpace(text)) return null; try { return JToken.Parse(text); } catch { return null; } } private static string FindString(JToken token, string name) { var value = Find(token, name); return value?.Type == JTokenType.Null ? null : value?.ToString(); } private static int? FindInt(JToken token, string name) { var value = Find(token, name); return int.TryParse(value?.ToString(), out var parsed) ? parsed : null; } private static long? FindLong(JToken token, string name) { var value = Find(token, name); return long.TryParse(value?.ToString(), out var parsed) ? parsed : null; } private static JToken Find(JToken token, string name) { if (token == null) return null; if (token is JObject obj) { var property = obj.Properties().FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); if (property != null) return property.Value; foreach (var child in obj.Properties()) { var found = Find(child.Value, name); if (found != null) return found; } } else if (token is JArray array) { foreach (var child in array) { var found = Find(child, name); if (found != null) return found; } } return null; } private static string FirstNonEmpty(params string[] values) => values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x))?.Trim(); private static DateTime? ParseUnixTime(long? value) { if (!value.HasValue || value <= 0) return null; try { var timestamp = value > 10_000_000_000 ? DateTimeOffset.FromUnixTimeMilliseconds(value.Value) : DateTimeOffset.FromUnixTimeSeconds(value.Value); return timestamp.LocalDateTime; } catch { return null; } } private static string Limit(string value, int maxLength) => string.IsNullOrWhiteSpace(value) ? null : value.Trim().Length <= maxLength ? value.Trim() : value.Trim()[..maxLength]; } }