Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        //動画ページを指定
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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("&", "&amp;");


                Owner.Status = "";
                return(ret);
            } catch (RequestFailed) {
                Owner.Status = "ユーザー情報の取得に失敗しました";
                return(null);
            }
        }