public NicoNicoUserEntry GetUserInfo() { Owner.Status = "ユーザー情報取得中"; var ret = new NicoNicoUserEntry(); //ユーザーページのhtmlを取得 var a = NicoNicoWrapperMain.Session.GetAsync(UserPage).Result; //htmlをロード var doc = new HtmlDocument(); doc.LoadHtml2(a); //ユーザープロファイル var detail = doc.DocumentNode.SelectSingleNode("//div[@class='userDetail']"); var profile = detail.SelectSingleNode("child::div[@class='profile']"); var account = profile.SelectSingleNode("child::div[@class='account']"); ret.UserIconUrl = detail.SelectSingleNode("child::div[@class='avatar']/img").Attributes["src"].Value; ret.UserName = profile.SelectSingleNode("child::h2").InnerText.Trim(); ret.Id = account.SelectSingleNode("child::p[@class='accountNumber']").InnerText.Trim(); ret.Gender = account.SelectSingleNode("child::p[2]").InnerText.Trim(); ret.BirthDay = account.SelectSingleNode("child::p[3]").InnerText.Trim(); ret.Region = account.SelectSingleNode("child::p[4]").InnerText.Trim(); var temp = profile.SelectSingleNode("child::ul[@class='userDetailComment channel_open_mt0']/li/p/span"); ret.Description = temp == null ? "" : temp.InnerHtml; ret.UserPage = UserPage; //html特殊文字をデコード ret.Description = HttpUtility.HtmlDecode(ret.Description); //URLをハイパーリンク化する エンコードされてると正しく動かない ret.Description = HyperLinkReplacer.Replace(ret.Description); //&だけエンコード エンコードしないとUIに&が表示されない ret.Description = ret.Description.Replace("&", "&"); Owner.Status = ""; return(ret); }
public NicoNicoCommunityContent GetCommunity() { try { var a = NicoNicoWrapperMain.Session.GetAsync(CommunityUrl).Result; var doc = new HtmlDocument(); doc.LoadHtml2(a); var community_main = doc.DocumentNode.SelectSingleNode("//div[@id='community_main']"); var profile = community_main.SelectSingleNode("child::div/div/div[@id='cbox_profile']"); var news = community_main.SelectNodes("//div[parent::div[@id='community_news']]"); var ret = new NicoNicoCommunityContent(); ret.CommunityUrl = CommunityUrl; ret.ThumbnailUrl = profile.SelectSingleNode("child::table/tr/td/p/img").Attributes["src"].Value; ret.OwnerUrl = community_main.SelectSingleNode("child::div/div/div/div[@class='r']/p/a").Attributes["href"].Value; ret.OwnerName = "<a href=\"" + ret.OwnerUrl + "\">" + community_main.SelectSingleNode("child::div/div/div/div[@class='r']/p/a/strong").InnerText + "</a>"; ret.CommunityTitle = community_main.SelectSingleNode("child::div/div/h1").InnerText; ret.OpeningDate = community_main.SelectSingleNode("child::div/div/div/div/p/strong").InnerText; //---お知らせ--- ret.CommunityNews = new List <NicoNicoCommunityNews>(); if (news != null) { foreach (var notify in news) { var b = new NicoNicoCommunityNews(); b.Title = notify.SelectSingleNode("child::h2").InnerText; b.Description = HyperLinkReplacer.Replace(notify.SelectSingleNode("child::div[@class='desc']").InnerHtml.Trim()); b.Date = notify.SelectSingleNode("child::div[@class='date']").InnerText.Trim(); ret.CommunityNews.Add(b); } } //------ ret.CommunityLevel = profile.SelectSingleNode("child::table/tr/td/table/tr[1]/td[2]/strong").InnerText; ret.CommunityStars = profile.SelectSingleNode("child::table/tr/td/table/tr[1]/td[2]/span").InnerText; ret.CommunityMember = profile.SelectSingleNode("child::table/tr/td/table/tr[2]/td[2]").InnerHtml.Trim(); //---登録タグ--- ret.CommunityTags = new List <string>(); var tags = profile.SelectNodes("child::table/tr/td/table/tr[4]/td[2]/a"); if (tags != null) { foreach (var tag in tags) { ret.CommunityTags.Add(tag.SelectSingleNode("child::strong").InnerText); } } //------ ret.CommunityProfile = HyperLinkReplacer.Replace(profile.SelectSingleNode("child::div[@id='community_description']/div/div/div").InnerHtml.Trim()); //---特権--- ret.Privilege = new List <string>(); var privileges = profile.SelectNodes("child::table/tr/td/table/tr[7]/td[2]/div[2]/p"); ret.Privilege.Add(profile.SelectSingleNode("child::table/tr/td/table/tr[7]/td[2]/div[1]/p").InnerText); if (privileges != null) { foreach (var privilege in privileges) { ret.Privilege.Add(privilege.InnerText); } } //------ ret.TotalVisitors = profile.SelectSingleNode("child::table/tr/td/table/tr[6]/td[2]/strong").InnerText; ret.Videos = profile.SelectSingleNode("child::table/tr/td/table/tr[9]/td[2]").InnerHtml.Trim(); return(ret); } catch (RequestTimeout) { return(null); } }
public async Task <NicoNicoWatchApiData> GetWatchApiDataAsync() { try { var res = await App.ViewModelRoot.CurrentUser.Session.GetResponseAsync(Owner.VideoUrl); //チャンネル動画などでリダイレクトされるURLの可能性があるのでリダイレクトされた場合はリダイレクト先を読み込む if (res.StatusCode == HttpStatusCode.MovedPermanently) { res = await App.ViewModelRoot.CurrentUser.Session.GetResponseAsync(res.Headers.Location.OriginalString); } //削除された動画は404を律儀に返してくる if (res.StatusCode == HttpStatusCode.NotFound) { Owner.Status = "動画が削除されている可能性があります"; return(null); } //鯖落ちかな? if (res.StatusCode == HttpStatusCode.ServiceUnavailable) { Owner.Status = "サーバーが混み合っているようです"; return(null); } //Cookieを取得してWebBrowserの方に反映させる //これがないと動画を取得しようとしても403が返ってくる IEnumerable <string> cookie; if (res.Headers.TryGetValues("Set-Cookie", out cookie)) { foreach (string s in cookie) { foreach (string ss in s.Split(';')) { App.SetCookie(new Uri("http://nicovideo.jp/"), ss); } } } //html var a = await res.Content.ReadAsStringAsync(); //Responsehはもう必要ない res.Dispose(); var doc = new HtmlDocument(); doc.LoadHtml(a); var container = doc.DocumentNode.SelectSingleNode("//div[@id='js-initial-watch-data']"); if (container == null) { container = doc.DocumentNode.SelectSingleNode("//div[@id='watchAPIDataContainer']"); //html5版ページで視聴できなかった場合 if (container != null) { var json = DynamicJson.Parse(HttpUtility.HtmlDecode(container.InnerText)); var flash = json.flashvars; var flv = HttpUtility.UrlDecode(HttpUtility.UrlDecode(flash.flvInfo)); var getFlv = HttpUtility.ParseQueryString(flv); var videoDetail = json.videoDetail; var ret = new NicoNicoWatchApiData(); //動画情報 ret.Video = new NicoNicoVideo() { Id = videoDetail.id, SmileInfo = new NicoNicoVideo.NicoNicoSmileInfo() { Url = getFlv["url"] }, Title = videoDetail.title, OriginalTitle = videoDetail.title_original, Description = videoDetail.description, OriginalDescription = videoDetail.description_original, ThumbNailUrl = videoDetail.thumbnail, PostedDateTime = DateTime.Parse(videoDetail.postedAt), OriginalPostedDateTime = DateTime.MinValue, Duration = (int)videoDetail.length, ViewCount = (int)videoDetail.viewCount, MylistCount = (int)videoDetail.mylistCount }; ret.Thread = new NicoNicoThread() { CommentCount = (int)videoDetail.commentCount, HasOwnerThread = videoDetail.has_owner_thread, ServerUrl = getFlv["ms"].Replace("api", "api.json"), SubServerurl = getFlv["ms_sub"], ThreadIds = new NicoNicoThreadIds() { Default = getFlv["thread_id"], Nicos = getFlv["thread_id"], Community = getFlv["thread_id"] } }; ret.Tags = new List <NicoNicoVideoTag>(); foreach (var tag in videoDetail.tagList) { var entry = new NicoNicoVideoTag() { Id = tag.id, Tag = HttpUtility.HtmlDecode(tag.tag), Dic = tag.dic(), Lck = tag.lck == "1" ? true : false, Cat = tag.cat() }; entry.Url = "http://dic.nicovideo.jp/a/" + entry.Tag; ret.Tags.Add(entry); } if (json.uploaderInfo()) { var owner = json.uploaderInfo; ret.Owner = new NicoNicoVideoOwner() { Id = owner.id, UserUrl = "http://www.nicovideo.jp/user/" + owner.id, Nickname = owner.nickname, IconUrl = owner.icon_url, IsUserVideoPublic = owner.is_uservideo_public, IsUserMyVideoPublic = owner.is_user_myvideo_public, IsUserOpenListPublic = owner.is_user_openlist_public }; //投稿者をお気に入り登録しているか調べる var follow = await App.ViewModelRoot.CurrentUser.Session.GetAsync(string.Format(UploaderInfoApi, ret.Owner.Id)); ret.IsUploaderFollowed = DynamicJson.Parse(follow).data.following; } if (json.channelInfo()) { var channel = json.channelInfo; ret.Channel = new NicoNicoVideoChannel() { Id = channel.id, Name = channel.name, IconUrl = channel.icon_url, FavoriteToken = channel.favorite_token, FavoriteTokenTime = (long)channel.favorite_token_time, IsFavorited = channel.is_favorited == 1D }; ret.Channel.ChannelUrl = "http://ch.nicovideo.jp/ch" + ret.Channel.Id; ret.IsChannelVideo = true; ret.IsUploaderFollowed = ret.Channel.IsFavorited; } var viewer = json.viewerInfo; ret.Viewer = new NicoNicoVideoViewer() { Id = Convert.ToString(viewer.id), Nickname = viewer.nickname, IsPremium = viewer.isPremium, IsPrivileged = viewer.isPrivileged, }; ret.Context = new NicoNicoVideoContext() { HighestRank = videoDetail.highest_rank != null?int.Parse(videoDetail.highest_rank) : null, YesterdayRank = videoDetail.yesterday_rank != null?int.Parse(videoDetail.yesterday_rank) : null, CsrfToken = flash.csrfToken, UserKey = getFlv["userkey"] }; ret.FmsToken = getFlv["fmst"]; return(ret); } Owner.Status = "動画の読み込みに失敗しました"; return(null); } else { //htmlから取得したJsonをhtmlデコードしてdynamic型に変える var json = DynamicJson.Parse(HttpUtility.HtmlDecode(container.Attributes["data-api-data"].Value.Trim())); var ret = new NicoNicoWatchApiData(); //動画情報 var video = json.video; ret.Video = new NicoNicoVideo() { Id = video.id, SmileInfo = new NicoNicoVideo.NicoNicoSmileInfo() { Url = video.smileInfo.url, IsSlowLine = video.smileInfo.isSlowLine, CurrentQualityId = video.smileInfo.currentQualityId }, Title = HttpUtility.HtmlDecode(video.title), OriginalTitle = video.originalTitle, Description = HyperLinkReplacer.Replace(video.description), OriginalDescription = video.originalDescription, ThumbNailUrl = video.thumbnailURL, PostedDateTime = DateTime.Parse(video.postedDateTime), OriginalPostedDateTime = video.originalPostedDateTime() && video.originalPostedDateTime != null?DateTime.Parse(video.originalPostedDateTime) : DateTime.MinValue, Width = (int?)video.width, Height = (int?)video.height, Duration = (int)video.duration, ViewCount = (int)video.viewCount, MylistCount = (int)video.mylistCount, Translation = video.translation, Translator = video.translator, MovieType = video.movieType, Badges = video.badges, IntroducedNicoliveDJInfo = video.introducedNicoliveDJInfo, DmcInfo = video.dmcInfo != null ? new NicoNicoDmc() { Time = (long)video.dmcInfo.time, TimeMs = (long)video.dmcInfo.time_ms, VideoId = video.dmcInfo.video.video_id, LengthSeconds = (int)video.dmcInfo.video.length_seconds, Deleted = (int)video.dmcInfo.video.deleted, ServerUrl = video.dmcInfo.thread.server_url, SubServerUrl = video.dmcInfo.thread.sub_server_url, ThreadId = Convert.ToString(video.dmcInfo.thread.thread_id), NicosThreadId = Convert.ToString(video.dmcInfo.thread.nicos_thread_id), OptionalThreadId = Convert.ToString(video.dmcInfo.thread.optional_thread_id), ThreadKeyRequired = video.dmcInfo.thread.thread_key_required, ChannelNGWords = video.dmcInfo.thread.channel_ng_words, OwnerNGWords = video.dmcInfo.thread.owner_ng_words, MaintenancesNg = video.dmcInfo.thread.maintenances_ng, PostkeyAvailable = video.dmcInfo.thread.postkey_available, NgRevision = (int?)video.dmcInfo.thread.ng_revision, ApiUrls = video.dmcInfo.session_api.api_urls, RecipeId = video.dmcInfo.session_api.recipe_id, PlayerId = video.dmcInfo.session_api.player_id, Videos = video.dmcInfo.session_api.videos, Audios = video.dmcInfo.session_api.audios, Movies = video.dmcInfo.session_api.movies, Protocols = video.dmcInfo.session_api.protocols, AuthType = video.dmcInfo.session_api.auth_types.http, ServiceUserId = video.dmcInfo.session_api.service_user_id, Token = video.dmcInfo.session_api.token, Signature = video.dmcInfo.session_api.signature, ContentId = video.dmcInfo.session_api.content_id, HeartbeatLifeTime = (int)video.dmcInfo.session_api.heartbeat_lifetime, ContentKeyTimeout = (int)video.dmcInfo.session_api.content_key_timeout, Priority = video.dmcInfo.session_api.priority } : null, BackCommentType = video.backCommentType, IsCommentExpired = video.isCommentExpired, IsWide = video.isWide, IsOfficialAnime = (int?)video.isOfficialAnime, IsNoBanner = video.isNoBanner, IsDeleted = video.isDeleted, IsTranslated = video.isTranslated, IsR18 = video.isR18, IsAdult = video.isAdult, IsNicowari = video.isNicowari, IsPublic = video.isPublic, IsPublishedNicoscript = video.isPublishedNicoscript, IsNoNGS = video.isNoNGS, IsCommunityMemberOnly = video.isCommunityMemberOnly, IsCommonsTreeExists = video.isCommonsTreeExists, IsNoIchiba = video.isNoIchiba, IsOfficial = video.isOfficial, IsMonetized = video.isMonetized }; var thread = json.thread; ret.Thread = new NicoNicoThread() { CommentCount = (int)thread.commentCount, HasOwnerThread = thread.hasOwnerThread, MymemoryLanguage = thread.mymemoryLanguage, ServerUrl = thread.serverUrl.Replace("api", "api.json"), SubServerurl = thread.subServerUrl, ThreadIds = new NicoNicoThreadIds() { Default = thread.ids.@default, Nicos = thread.ids.nicos, Community = thread.ids.community } }; //タグを走査 ret.Tags = new List <NicoNicoVideoTag>(); foreach (var tag in json.tags) { var entry = new NicoNicoVideoTag() { Id = tag.id, Tag = HttpUtility.HtmlDecode(tag.name), Dic = tag.isDictionaryExists, Lck = tag.isLocked, Cat = tag.isCategory }; entry.Url = "http://dic.nicovideo.jp/a/" + entry.Tag; ret.Tags.Add(entry); } var owner = json.owner; if (owner != null) { ret.Owner = new NicoNicoVideoOwner() { Id = owner.id, UserUrl = "http://www.nicovideo.jp/user/" + owner.id, Nickname = owner.nickname, IconUrl = owner.iconURL, NicoliveInfo = owner.nicoliveInfo, ChannelInfo = owner.channelInfo, IsUserVideoPublic = owner.isUserVideoPublic, IsUserMyVideoPublic = owner.isUserMyVideoPublic, IsUserOpenListPublic = owner.isUserOpenListPublic }; //投稿者をお気に入り登録しているか調べる var follow = await App.ViewModelRoot.CurrentUser.Session.GetAsync(string.Format(UploaderInfoApi, ret.Owner.Id)); ret.IsUploaderFollowed = DynamicJson.Parse(follow).data.following; } var channel = json.channel; if (channel != null) { ret.Channel = new NicoNicoVideoChannel() { Id = channel.id, Name = channel.name, IconUrl = channel.iconURL, FavoriteToken = channel.favoriteToken, FavoriteTokenTime = (long)channel.favoriteTokenTime, IsFavorited = channel.isFavorited, NGFilters = new List <NicoNicoVideoNGFilter>(), ThreadType = channel.threadType, GlobalId = channel.globalId }; ret.Channel.ChannelUrl = "http://ch.nicovideo.jp/" + ret.Channel.GlobalId; foreach (var filter in channel.ngList) { ret.Channel.NGFilters.Add(new NicoNicoVideoNGFilter() { Source = filter.source, Destination = filter.destination }); } ret.IsChannelVideo = true; ret.IsUploaderFollowed = ret.Channel.IsFavorited; } var viewer = json.viewer; ret.Viewer = new NicoNicoVideoViewer() { Id = Convert.ToString(viewer.id), Nickname = viewer.nickname, Prefecture = (int)viewer.prefecture, Sex = (int)viewer.sex, Age = (int)viewer.age, IsPremium = viewer.isPremium, IsPrivileged = viewer.isPrivileged, IsPostLocked = viewer.isPostLocked, IsHtrzm = viewer.isHtrzm, IsTwitterConnection = viewer.isTwitterConnection }; var context = json.context; ret.Context = new NicoNicoVideoContext() { PlayFrom = context.playFrom, InitialPlaybackPosition = (int?)context.initialPlaybackPosition, InitialPlaybackType = context.initialPlaybackType, PlayLength = context.playLength, ReturnId = context.returnId, ReturnTo = context.returnTo, ReturnMsg = context.returnMsg, WatchId = context.watchId, IsNoMovie = context.isNoMovie, IsNoRelatedVideo = context.isNoRelatedVideo, IsDownloadCompleteWait = context.isDownloadCompleteWait, IsNoNicotic = context.isNoNicotic, IsNeedPayment = context.isNeedPayment, IsAdultRatingNG = context.isAdultRatingNG, IsPlayable = context.isPlayable, IsTranslatable = context.isTranslatable, IsTagUneditable = context.isTagUneditable, IsVideoOwner = context.isVideoOwner, IsThreadOwner = context.isThreadOwner, IsOwnerThreadEditable = context.isOwnerThreadEditable, UseChecklistCache = context.useChecklistCache, IsDisabledMarquee = context.isDisabledMarquee, IsDictionaryDisplayable = context.isDictionaryDisplayable, IsDefaultCommentInvisible = context.isDefaultCommentInvisible, AccessFrom = context.accessFrom, CsrfToken = context.csrfToken, TranslationVersionJsonUpdateTime = (long)context.translationVersionJsonUpdateTime, UserKey = context.userkey, WatchAuthKey = context.watchAuthKey, WatchTrackId = context.watchTrackId, WatchPageServerTime = (long)context.watchPageServerTime, IsAuthenticationRequired = context.isAuthenticationRequired, IsPeakTime = context.isPeakTime, NgRevision = (int)context.ngRevision, CategoryName = context.categoryName, CategoryKey = context.categoryKey, CategoryGroupName = context.categoryGroupName, CategoryGroupKey = context.categoryGroupKey, YesterdayRank = (int?)context.yesterdayRank, HighestRank = (int?)context.highestRank, IsMyMemory = context.isMyMemory, OwnerNGFilters = new List <NicoNicoVideoNGFilter>() }; //垢消しうp主 if (ret.Channel == null && ret.Owner == null) { ret.IsOwnerDeleted = true; } if (!Settings.Instance.UseResumePlay) { ret.Context.InitialPlaybackPosition = 0; } foreach (var filter in context.ownerNGList) { ret.Context.OwnerNGFilters.Add(new NicoNicoVideoNGFilter() { Source = filter.source, Destination = filter.destination }); } return(ret); } } catch (RequestFailed) { Owner.Status = "動画情報の取得に失敗しました"; return(null); } }
public List <NicoNicoUserMylistEntry> GetUserMylist() { var url = UserPage + "/mylist"; Owner.Status = "ユーザーマイリスト取得中"; List <NicoNicoUserMylistEntry> ret = new List <NicoNicoUserMylistEntry>(); try { var a = NicoNicoWrapperMain.Session.GetAsync(url).Result; var doc = new HtmlDocument(); doc.LoadHtml2(a); var content = doc.DocumentNode.SelectSingleNode("//div[@class='content']"); var outers = content.SelectNodes("child::div[@class='articleBody']/div[@class='outer']"); //終了 if (outers == null) { Owner.Status = ""; return(null); } //ニコレポタイムライン走査 foreach (var node in outers) { NicoNicoUserMylistEntry entry = new NicoNicoUserMylistEntry(); //h4タグ var h4 = node.SelectSingleNode("child::div/h4"); entry.Url = "http://www.nicovideo.jp/" + h4.SelectSingleNode("child::a").Attributes["href"].Value; //名前取得 entry.Name = HttpUtility.HtmlDecode(h4.SelectSingleNode("child::a").InnerText.Trim()); //説明文取得 var desc = node.SelectSingleNode("child::div/p[@data-nico-mylist-desc-full='true']"); entry.Description = desc == null ? "" : desc.InnerText.Trim(); entry.Description = HyperLinkReplacer.Replace(entry.Description); //サムネイル取得 var thumb1 = node.SelectSingleNode("child::div/ul/li[1]/img"); var thumb2 = node.SelectSingleNode("child::div/ul/li[2]/img"); var thumb3 = node.SelectSingleNode("child::div/ul/li[3]/img"); if (thumb1 != null) { entry.ThumbNail1Available = true; entry.ThumbNail1Url = thumb1.Attributes["src"].Value; entry.ThumbNail1ToolTip = HttpUtility.HtmlDecode(thumb1.Attributes["alt"].Value); } else { goto next; } if (thumb2 != null) { entry.ThumbNail2Available = true; entry.ThumbNail2Url = thumb2.Attributes["src"].Value; entry.ThumbNail2ToolTip = HttpUtility.HtmlDecode(thumb2.Attributes["alt"].Value); } else { goto next; } if (thumb3 != null) { entry.ThumbNail3Available = true; entry.ThumbNail3Url = thumb3.Attributes["src"].Value; entry.ThumbNail3ToolTip = HttpUtility.HtmlDecode(thumb3.Attributes["alt"].Value); } next: ret.Add(entry); } Owner.Status = ""; return(ret); } catch (RequestTimeout) { Owner.Status = "ユーザーマイリストの取得に失敗しました"; return(null); } }
//動画ページを指定 public WatchApiData GetWatchApiData() { //動画ページのhtml取得 var response = NicoNicoWrapperMain.GetSession().GetResponseAsync(VideoPage).Result; //チャンネル、公式動画 if (response.StatusCode == HttpStatusCode.MovedPermanently) { response = NicoNicoWrapperMain.GetSession().GetResponseAsync(response.Headers.Location.OriginalString).Result; } //削除された動画 if (response.StatusCode == HttpStatusCode.NotFound) { return(null); } //混雑中 if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { return(null); } string html = response.Content.ReadAsStringAsync().Result; HtmlDocument doc = new HtmlDocument(); doc.LoadHtml2(html); //htmlからAPIデータだけを綺麗に抜き出す すごい var container = doc.DocumentNode.QuerySelector("#watchAPIDataContainer"); if (container == null) { return(null); } var data = container.InnerHtml; //html特殊文字をデコードする data = HttpUtility.HtmlDecode(data); //jsonとしてAPIデータを展開していく var json = DynamicJson.Parse(data); //GetFlvの結果 string flv = json.flashvars.flvInfo; //2重にエンコードされてるので二回 flv = HttpUtility.UrlDecode(flv); flv = HttpUtility.UrlDecode(flv); WatchApiData ret = new WatchApiData(); //&で繋がれているので剥がす var getFlv = flv.Split(new char[] { '&' }).ToDictionary(source => source.Substring(0, source.IndexOf('=')), source => Uri.UnescapeDataString(source.Substring(source.IndexOf('=') + 1))); ret.GetFlv = new NicoNicoGetFlvData(getFlv); //動画情報 var videoDetail = json.videoDetail; //---情報を詰める--- ret.Cmsid = videoDetail.id; ret.MovieType = json.flashvars.movie_type; ret.Title = HttpUtility.HtmlDecode(videoDetail.title); //html特殊文字をデコード ret.Thumbnail = videoDetail.thumbnail; ret.Description = videoDetail.description; ret.PostedAt = videoDetail.postedAt; ret.Length = (int)videoDetail.length; ret.ViewCounter = (int)videoDetail.viewCount; ret.CommentCounter = (int)videoDetail.commentCount; ret.MylistCounter = (int)videoDetail.mylistCount; ret.YesterdayRank = videoDetail.yesterday_rank == null ? "圏外" : videoDetail.yesterday_rank + "位"; ret.HighestRank = videoDetail.highest_rank == null ? "圏外" : videoDetail.highest_rank + "位"; ret.IsOfficial = videoDetail.is_official; ret.Token = json.flashvars.csrfToken; ret.HasOwnerThread = json.flashvars.has_owner_thread(); if (json.uploaderInfo()) { //投稿者情報 var uploaderInfo = json.uploaderInfo; ret.UploaderId = uploaderInfo.id; ret.UploaderIconUrl = uploaderInfo.icon_url; ret.UploaderName = uploaderInfo.nickname; ret.UploaderIsFavorited = uploaderInfo.is_favorited; } else if (json.channelInfo()) { //投稿者情報 var channelInfo = json.channelInfo; ret.UploaderId = channelInfo.id; ret.UploaderIconUrl = channelInfo.icon_url; ret.UploaderName = channelInfo.name; ret.UploaderIsFavorited = channelInfo.is_favorited == 1 ? true : false; ret.IsChannelVideo = true; } ret.Description = HyperLinkReplacer.Replace(ret.Description); ret.TagList = new ObservableCollection <VideoTagViewModel>(); foreach (var tag in videoDetail.tagList) { NicoNicoTag entry = new NicoNicoTag() { Id = tag.id, Tag = HttpUtility.HtmlDecode(tag.tag), Dic = tag.dic(), Lck = tag.lck == "1" ? true : false, Cat = tag.cat() }; ret.TagList.Add(new VideoTagViewModel(entry)); } //------ //有料動画 if (ret.GetFlv.VideoUrl == null || ret.GetFlv.VideoUrl.Count() == 0) { ret.IsPaidVideo = true; return(ret); } //念のためCookieを設定 var cookie = response.Headers.GetValues("Set-Cookie"); foreach (string s in cookie) { foreach (string ss in s.Split(';')) { App.SetCookie(new Uri("http://nicovideo.jp/"), ss); } } return(ret); }
public NicoNicoPublicMylistEntry GetMylist() { try { var a = NicoNicoWrapperMain.Session.GetAsync(MylistUrl).Result; //該当JavaScriptの部分から取得 var globals = a.Substring(a.IndexOf("Jarty.globals(")); //改行で分割 var splitted = globals.Split('\n'); //正規表現でダブルクォーテ内の名前を取得 var regex = new Regex("\"(.*)\""); string nickname = null; string userid = null; string mylistname = null; string description = null; string json = null; foreach (var text in splitted) { //マイリストオーナーだったら if (text.Contains("mylist_owner:")) { //マイリストオーナーのニックネームを取得 nickname = text.Substring(text.IndexOf("nickname: ")); var match = regex.Match(nickname); //グループから取得 nickname = match.Groups[1].Value; continue; } if (nickname != null && text.Contains("user_id:")) { userid = new Regex(@"\d+").Match(text).Value; continue; } if (userid != null && text.Contains("name:")) { mylistname = regex.Match(text).Groups[1].Value; continue; } if (mylistname != null && text.Contains("description:")) { description = regex.Match(text).Groups[1].Value; continue; } if (description != null && text.Contains("Mylist.preload(")) { //Json取得 json = text.Substring(text.IndexOf(",") + 1, text.Length - text.IndexOf(",") - 3); break; } } var ret = new NicoNicoPublicMylistEntry(); ret.NickName = @"<a href=""http://www.nicovideo.jp/user/" + userid + @""">" + nickname + "</a> さんの公開マイリスト"; ret.MylistName = mylistname; ret.Description = description; //\nを改行に置換 ret.Description = ret.Description.Replace("\\n", "<br>").Replace("\\r", ""); ret.Description = HyperLinkReplacer.Replace(ret.Description); var list = new List <MylistListEntryViewModel>(); var data = DynamicJson.Parse(json); StoreItem(data, list); ret.Data = list; return(ret); } catch (RequestTimeout) { return(null); } }
public async Task <NicoNicoPublicMylistGroupEntry> GetMylistAsync() { try { var a = await App.ViewModelRoot.CurrentUser.Session.GetAsync(MylistUrl); var index = a.IndexOf("Jarty.globals("); if (index == -1) { return(null); } //該当JavaScriptの部分から取得 var globals = a.Substring(index); //改行で分割 var splitted = globals.Split('\n'); //正規表現でダブルクォーテ内の名前を取得 var regex = new Regex("\"(.*)\""); string nickname = null; string userid = null; string mylistname = null; string description = null; string json = null; foreach (var text in splitted) { //マイリストオーナーだったら if (text.Contains("mylist_owner:")) { //マイリストオーナーのニックネームを取得 nickname = text.Substring(text.IndexOf("nickname: ")); var match = regex.Match(nickname); //グループから取得 nickname = match.Groups[1].Value; continue; } if (nickname != null && text.Contains("user_id:")) { userid = new Regex(@"\d+").Match(text).Value; continue; } if (userid != null && text.Contains("name:")) { mylistname = regex.Match(text).Groups[1].Value; continue; } if (mylistname != null && text.Contains("description:")) { description = regex.Match(text).Groups[1].Value; continue; } if (description != null && text.Contains("Mylist.preload(")) { //Json取得 json = text.Substring(text.IndexOf(",") + 1, text.Length - text.IndexOf(",") - 3); break; } } var ret = new NicoNicoPublicMylistGroupEntry(); ret.OwnerName = @"<a href=""http://www.nicovideo.jp/user/" + userid + @""">" + nickname + "</a> さんの公開マイリスト"; ret.Name = mylistname; ret.Description = description; //\nを改行に置換 ret.Description = ret.Description.Replace("\\n", "<br>").Replace("\\r", ""); ret.Description = HyperLinkReplacer.Replace(ret.Description); var list = new List <NicoNicoMylistEntry>(); StoreItems(json, list); ret.Data = list; return(ret); } catch (RequestFailed) { Owner.Status = "公開マイリストの取得に失敗しました"; return(null); } }
public async Task <NicoNicoCommunityEntry> GetCommunityAsync() { try { Owner.Status = "コミュニティ情報取得中"; var a = await App.ViewModelRoot.CurrentUser.Session.GetAsync(CommunityUrl); var doc = new HtmlDocument(); doc.LoadHtml(a); var ret = new NicoNicoCommunityEntry(); var header = doc.DocumentNode.SelectSingleNode("//header[@class='area-communityHeader']"); if (header == null) { return(null); } ret.CommunityUrl = CommunityUrl; ret.ThumbnailUrl = header.SelectSingleNode("div/div/div/a/img").Attributes["src"].Value; //コミュニティタイプ if (header.SelectSingleNode("div/div/div/div/img").Attributes["src"].Value.Contains("open")) { ret.Status = NicoNicoCommunityStatus.Open; } else { ret.Status = NicoNicoCommunityStatus.Close; } var data = header.SelectSingleNode("div/div/div[@class='communityData']"); ret.OwnerUrl = data.SelectSingleNode("table/tr[1]/td/a").Attributes["href"].Value; ret.OwnerName = "<a href=\"" + ret.OwnerUrl + "\">" + data.SelectSingleNode("table/tr[1]/td/a").InnerText.Trim() + "</a>"; ret.CommmunityName = HttpUtility.HtmlDecode(data.SelectSingleNode("h2/a").InnerText.Trim()); ret.OpeningDate = data.SelectSingleNode("table/tr[2]/td").InnerText.Trim(); var tags = data.SelectNodes("table/tr[3]/td/ul/li/a"); ret.CommunityTags = new List <string>(); if (tags != null) { foreach (var tag in tags) { ret.CommunityTags.Add(tag.InnerText.Trim()); } } var scale = header.SelectSingleNode("div/div/div/dl[@class='communityScale']"); ret.CommunityLevel = int.Parse(scale.SelectSingleNode("dd[1]").InnerText.Trim()); ret.CommunityMember = int.Parse(scale.SelectSingleNode("dd[2]/text()").InnerText.Trim()); ret.CommunityMaxMember = int.Parse(Regex.Match(scale.SelectSingleNode("dd[2]/span[@class='max']").InnerText, @"\d+").Value); //お知らせ取得 var noticeList = doc.DocumentNode.SelectNodes("//ul[@class='noticeList']/li"); ret.CommunityNews = new List <NicoNicoCommunityNews>(); if (noticeList != null) { foreach (var notice in noticeList) { var news = new NicoNicoCommunityNews(); news.Title = notice.SelectSingleNode("div/div/h3").InnerText.Trim(); news.Description = HyperLinkReplacer.Replace(notice.SelectSingleNode("p").InnerHtml); news.Date = notice.SelectSingleNode("div/div/div/span").InnerText.Trim(); ret.CommunityNews.Add(news); } } //プロフィール ret.CommunityProfile = HyperLinkReplacer.Replace(doc.DocumentNode.SelectSingleNode("//span[@id='profile_text_content']").InnerHtml); Owner.Status = ""; return(ret); } catch (RequestFailed) { Owner.Status = "コミュニティの取得に失敗しました"; return(null); } }
public async Task <NicoNicoUserEntry> GetUserInfoAsync() { try { Owner.Status = "ユーザー情報取得中"; var ret = new NicoNicoUserEntry(); //ユーザーページのhtmlを取得 var a = await App.ViewModelRoot.CurrentUser.Session.GetAsync(Owner.UserPageUrl); //htmlをロード var doc = new HtmlDocument(); doc.LoadHtml(a); //ユーザープロファイル var detail = doc.DocumentNode.SelectSingleNode("//div[@class='userDetail']"); var profile = detail.SelectSingleNode("div[@class='profile']"); var account = profile.SelectSingleNode("div[@class='account']"); ret.UserIconUrl = detail.SelectSingleNode("div[@class='avatar']/img").Attributes["src"].Value; ret.UserName = profile.SelectSingleNode("h2").InnerText.Trim(); ret.IdAndMemberType = account.SelectSingleNode("p[@class='accountNumber']").InnerText.Trim(); var desc = profile.SelectSingleNode("ul[@class='userDetailComment channel_open_mt0']/li/p/span"); ret.Description = desc != null ? desc.InnerHtml : ""; var stats = profile.SelectSingleNode("ul[@class='stats channel_open_mb8']"); ret.FollowedCount = int.Parse(stats.SelectSingleNode("li/span").InnerText, System.Globalization.NumberStyles.AllowThousands); ret.StampExp = int.Parse(stats.SelectSingleNode("li/a/span").InnerText, System.Globalization.NumberStyles.AllowThousands); ret.CsrfToken = GlobalHashRegex.Match(a).Groups[1].Value; ret.UserId = Regex.Match(Owner.UserPageUrl, @"user/(\d+)").Groups[1].Value; ret.UserPageUrl = Owner.UserPageUrl; var watching = profile.SelectSingleNode("div[@class='watching']"); ret.IsFollow = watching != null; var channel = profile.SelectSingleNode("div[@class='channel_open_box']"); if (channel != null) { ret.HasChannel = true; ret.ChannelName = channel.SelectSingleNode("p/a").InnerText; ret.ChannelThumbNail = channel.SelectSingleNode("img").Attributes["src"].Value; ret.ChannelUrl = channel.SelectSingleNode("p/a").Attributes["href"].Value; } //html特殊文字をデコード ret.Description = HttpUtility.HtmlDecode(ret.Description); //URLをハイパーリンク化する エンコードされてると正しく動かない ret.Description = HyperLinkReplacer.Replace(ret.Description); //&だけエンコード エンコードしないとUIに&が表示されない ret.Description = ret.Description.Replace("&", "&"); Owner.Status = ""; return(ret); } catch (RequestFailed) { Owner.Status = "ユーザー情報の取得に失敗しました"; return(null); } }