Beispiel #1
0
        /// <summary>
        /// 実装
        /// </summary>
        /// <param name="nicoId"></param>
        /// <param name="info"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        private async Task <IAttemptResult <IListVideoInfo> > GetVideoInfoAsync(string nicoId)
        {
            IAttemptResult <IDomainVideoInfo> result;

            try
            {
                result = await this.handler.GetVideoInfoAsync(nicoId);
            }
            catch (Exception e)
            {
                this.logger.Error($"動画情報を取得中に不明なエラーが発生しました。(id:{nicoId})", e);
                return(new AttemptResult <IListVideoInfo>()
                {
                    Message = $"不明なエラーが発生しました。(詳細:{e.Message})"
                });
            }

            if (!result.IsSucceeded || result.Data is null)
            {
                return(new AttemptResult <IListVideoInfo>()
                {
                    Message = result.Message, Exception = result.Exception
                });
            }

            IListVideoInfo info = this.container.GetVideo(nicoId);

            this.converter.ConvertDomainVideoInfoToListVideoInfo(info, result.Data);


            return(new AttemptResult <IListVideoInfo>()
            {
                IsSucceeded = true, Data = info
            });
        }
Beispiel #2
0
        public IAttemptResult WireVideoToPlaylist(int videoID, int playlistID)
        {
            IAttemptResult <STypes::Video> vResult = this._videoStoreHandler.GetVideo(videoID);

            if (!vResult.IsSucceeded || vResult.Data is null)
            {
                return(AttemptResult.Fail("追加する動画はDBに保存されていません。"));
            }

            STypes::Video video = vResult.Data;

            video.PlaylistIds.AddUnique(playlistID);
            this._videoStoreHandler.Update(video);

            IAttemptResult result = this._playlistStoreHandler.WireVideo(video, playlistID);

            ITreePlaylistInfo playlistInfo = this._playlistInfoContainer.GetPlaylist(playlistID);
            IListVideoInfo    videoInfo    = this._videoInfoContainer.GetVideo(video.NiconicoId);

            if (!playlistInfo.Videos.Any(v => v.Id.Value == videoID))
            {
                playlistInfo.Videos.Add(videoInfo);
            }

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// プレイヤーで開く
        /// </summary>
        /// <param name="appPath"></param>
        /// <param name="videoInfo"></param>
        /// <returns></returns>
        private IAttemptResult OpenPlayer(string appPath, IListVideoInfo videoInfo)
        {
            var folderPath = this.current.SelectedPlaylist.Value?.Folderpath;

            if (!videoInfo.IsDownloaded.Value || videoInfo.FileName.Value.IsNullOrEmpty())
            {
                return new AttemptResult()
                       {
                           Message = $"{videoInfo.NiconicoId.Value}はダウンロードされていません。",
                       }
            }
            ;
            if (folderPath is null)
            {
                return new AttemptResult()
                       {
                           Message = "フォルダーパスが設定されていません。"
                       }
            }
            ;

            var path = Path.Combine(folderPath, videoInfo.FileName.Value)
                       .Replace(@"\\?\", string.Empty)
            ;

            return(this.commandExecuter.Execute(appPath, $"\"{path}\""));
        }
        /// <summary>
        /// サムネイルのパスをサーバーから取得して設定する
        /// </summary>
        /// <param name="video"></param>
        /// <param name="fource"></param>
        /// <returns></returns>
        public void GetThumbAsync(IListVideoInfo video, Action onDone, bool overwrite = false)
        {
            if (!this.IsValidThumbnailUrl(video))
            {
                return;
            }

            lock (this.lockObj)
            {
                if (this.niconicoIDsAndActions.ContainsKey(video.NiconicoId.Value))
                {
                    this.niconicoIDsAndActions[video.NiconicoId.Value] += onDone;
                }

                if (!this.niconicoIDsAndActions.Any(p => p.Key == video.NiconicoId.Value))
                {
                    this.thumbConfigs.Enqueue(new ThumbConfig()
                    {
                        NiconicoID = video.NiconicoId.Value, Url = video.ThumbUrl.Value, Overwrite = overwrite
                    });
                    this.niconicoIDsAndActions.Add(video.NiconicoId.Value, onDone);
                }
            }

            if (!this.isFetching)
            {
                Task.Run(() => this.GetThumbAsync());
            }
        }
        public async Task <IAttemptResult <IListVideoInfo> > GetVideoListInfoAsync(string id, CancellationToken?ct = null)
        {
            IListVideoInfo video = this._videoInfoContainer.GetVideo(id);

            bool registerOnlyID = this._settingHandler.GetBoolSetting(SettingsEnum.StoreOnlyNiconicoID);

            if (registerOnlyID)
            {
                return(AttemptResult <IListVideoInfo> .Succeeded(video));
            }



            this._messageHandler.AppendMessage($"{id}の取得を開始します。");

            IAttemptResult <IListVideoInfo> result = await this._wacthPagehandler.TryGetVideoInfoAsync(id);

            if (!result.IsSucceeded || result.Data is null)
            {
                this._messageHandler.AppendMessage($"{id}の取得に失敗しました。(詳細:{result.Message})");
                return(AttemptResult <IListVideoInfo> .Fail($"{id}の取得に失敗しました。(詳細:{result.Message})"));
            }
            else
            {
                this._messageHandler.AppendMessage($"{id}の取得に成功しました。");
                video.SetNewData(result.Data);
            }

            return(AttemptResult <IListVideoInfo> .Succeeded(video));
        }
Beispiel #6
0
        public IAttemptResult Update(IListVideoInfo video)
        {
            STypes::Video converted = this._converter.ConvertLocalVideoToStoreVideo(video);

            IAttemptResult result = this._videoStoreHandler.Update(converted);

            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// アプリに送る
        /// </summary>
        /// <param name="appPath"></param>
        /// <param name="argBase"></param>
        /// <param name="videoInfo"></param>
        /// <returns></returns>
        private IAttemptResult SendToAppCommand(string appPath, string argBase, IListVideoInfo videoInfo)
        {
            var constructedArg = argBase
                                 .Replace("<url>", NetConstant.NiconicoWatchUrl + videoInfo.NiconicoId.Value)
                                 .Replace("<url:short>", NetConstant.NiconicoShortUrl + videoInfo.NiconicoId.Value)
                                 .Replace("<id>", videoInfo.NiconicoId.Value)
            ;

            return(this.commandExecuter.Execute(appPath, constructedArg));
        }
        public void インスタンスの同一性を確認する()
        {
            string         title   = "レッツゴー!陰陽師";
            IListVideoInfo onmyoji = this.container !.GetVideo("sm9");

            onmyoji.Title.Value = title;

            IListVideoInfo reOnmyoji = this.container !.GetVideo("sm9");

            Assert.That(reOnmyoji.Title.Value, Is.EqualTo(title));
        }
 /// <summary>
 /// リモートプレイリストの動画情報を変換する
 /// </summary>
 /// <param name="remoteVideoInfo"></param>
 /// <param name="listVideoInfo"></param>
 public void ConvertRemoteVideoInfoToListVideoInfo(VideoInfo remoteVideoInfo, IListVideoInfo listVideoInfo)
 {
     listVideoInfo.NiconicoId.Value   = remoteVideoInfo.ID;
     listVideoInfo.Title.Value        = remoteVideoInfo.Title;
     listVideoInfo.OwnerName.Value    = remoteVideoInfo.OwnerName;
     listVideoInfo.OwnerID.Value      = remoteVideoInfo.OwnerID;
     listVideoInfo.UploadedOn.Value   = remoteVideoInfo.UploadedDT;
     listVideoInfo.ViewCount.Value    = (int)remoteVideoInfo.ViewCount;
     listVideoInfo.CommentCount.Value = (int)remoteVideoInfo.CommentCount;
     listVideoInfo.MylistCount.Value  = (int)remoteVideoInfo.MylistCount;
     listVideoInfo.ThumbUrl.Value     = remoteVideoInfo.ThumbUrl;
 }
Beispiel #10
0
        /// <summary>
        /// ローカルファイルの取得を試行する
        /// </summary>
        /// <param name="video"></param>
        /// <param name="folderPath"></param>
        /// <returns></returns>
        public string GetFilePath(IListVideoInfo video, string folderPath, string format, bool replaceStricted, bool searchExact)
        {
            if (!Path.IsPathRooted(folderPath))
            {
                folderPath = Path.Combine(AppContext.BaseDirectory, folderPath);
            }

            if (this.cachedFiles is null)
            {
                this.cachedFiles = new List <string>();
                if (this.directoryIO.Exists(folderPath))
                {
                    this.cachedFiles.AddRange(this.directoryIO.GetFiles(folderPath, $"*{FileFolder.Mp4FileExt}", true).Select(p => Path.Combine(folderPath, p)).ToList());
                    this.cachedFiles.AddRange(this.directoryIO.GetFiles(folderPath, $"*{FileFolder.TsFileExt}", true).Select(p => Path.Combine(folderPath, p)).ToList());
                }
            }

            bool SearchFunc(string currentPath, string targetPath)
            {
                if (searchExact)
                {
                    return(currentPath == targetPath);
                }
                else
                {
                    return(currentPath.Contains(video.NiconicoId.Value));
                }
            }

            var fn   = this.niconicoUtils.GetFileName(format, video, FileFolder.Mp4FileExt, replaceStricted);
            var path = IOUtils.GetPrefixedPath(Path.Combine(folderPath, fn));

            string?firstMp4 = this.cachedFiles.FirstOrDefault(p => SearchFunc(p, path));

            //.mp4ファイルを確認
            if (firstMp4 is not null)
            {
                return(firstMp4);
            }
            else
            //.tsファイルを確認
            {
                fn   = this.niconicoUtils.GetFileName(format, video, FileFolder.TsFileExt, replaceStricted);
                path = IOUtils.GetPrefixedPath(Path.Combine(folderPath, fn));
                string?firstTS = this.cachedFiles.FirstOrDefault(p => SearchFunc(p, path));
                if (firstTS is not null)
                {
                    return(firstTS);
                }
            }

            return(Path.GetDirectoryName(path) ?? folderPath);
        }
Beispiel #11
0
        public IAttemptResult <IListVideoInfo> GetVideo(int id)
        {
            IAttemptResult <STypes::Video> sResult = this._videoStoreHandler.GetVideo(id);

            if (!sResult.IsSucceeded || sResult.Data is null)
            {
                return(AttemptResult <IListVideoInfo> .Fail(sResult.Message));
            }

            IListVideoInfo converted = this._converter.ConvertStoreVideoToLocalVideo(sResult.Data);

            return(AttemptResult <IListVideoInfo> .Succeeded(converted));
        }
Beispiel #12
0
        /// <summary>
        /// プレイヤーBで開く
        /// </summary>
        /// <param name="videoInfo"></param>
        /// <returns></returns>
        public IAttemptResult OpenInPlayerB(IListVideoInfo videoInfo)
        {
            var appPath = this.localSettingHandler.GetStringSetting(SettingsEnum.PlayerBPath);

            if (appPath is null)
            {
                return new AttemptResult()
                       {
                           Message = "プレイヤーBは登録されていません。"
                       }
            }
            ;

            return(this.OpenPlayer(appPath, videoInfo));
        }
Beispiel #13
0
        /// <summary>
        /// 動画情報からファイル名を取得する
        /// </summary>
        /// <param name="format"></param>
        /// <param name="video"></param>
        /// <param name="extension"></param>
        /// <param name="replaceStricted"></param>
        /// <param name="suffix"></param>
        /// <returns></returns>
        public string GetFileName(string format, IListVideoInfo video, string extension, bool replaceStricted, string?suffix = null)
        {
            var info = new VideoInfoForPath()
            {
                Title             = video.Title.Value,
                OwnerName         = video.OwnerName.Value,
                NiconicoID        = video.NiconicoId.Value,
                UploadedOn        = video.UploadedOn.Value,
                DownloadStartedOn = DateTime.Now,
                OwnerID           = video.OwnerID.Value.ToString(),
                Duration          = video.Duration.Value,
            };

            return(this.GetFilenameInternal(format, info, extension, replaceStricted, suffix));
        }
Beispiel #14
0
        public IAttemptResult UnWireVideoToPlaylist(int videoID, int playlistID)
        {
            IAttemptResult <STypes::Video> vResult = this._videoStoreHandler.GetVideo(videoID);

            if (!vResult.IsSucceeded || vResult.Data is null)
            {
                return(AttemptResult.Fail("削除する動画はDBに保存されていません。"));
            }

            STypes::Video     video        = vResult.Data;
            ITreePlaylistInfo playlistInfo = this._playlistInfoContainer.GetPlaylist(playlistID);
            IListVideoInfo    videoInfo    = this._videoInfoContainer.GetVideo(video.NiconicoId);

            playlistInfo.Videos.RemoveAll(v => v.Id.Value == videoID);

            IAttemptResult result = this._playlistStoreHandler.UnWireVideo(videoID, playlistID);

            return(result);
        }
        public void 動画を更新する()
        {
            var count    = 100;
            var original = new NonBindableListVideoInfo()
            {
                NiconicoId = new Reactive.Bindings.ReactiveProperty <string>("1")
            };
            var newItem = new NonBindableListVideoInfo()
            {
                NiconicoId = new Reactive.Bindings.ReactiveProperty <string>("1"), ViewCount = new Reactive.Bindings.ReactiveProperty <int>(count)
            };

            this.videoListContainer !.Add(original);
            IAttemptResult result = this.videoListContainer.Update(newItem);

            IListVideoInfo video = this.videoListContainer.Videos.First();

            Assert.That(result.IsSucceeded, Is.True);
            Assert.That(video.ViewCount.Value, Is.EqualTo(count));
        }
        /// <summary>
        /// Domainの動画情報を変換する
        /// </summary>
        /// <param name="videoInfo"></param>
        /// <returns></returns>
        public void ConvertDomainVideoInfoToListVideoInfo(IListVideoInfo info, IDomainVideoInfo domainVideoInfo)
        {
            //タイトル
            info.Title.Value = domainVideoInfo.Title;

            //ID
            info.NiconicoId.Value = domainVideoInfo.Id;

            //タグ
            info.Tags = domainVideoInfo.Tags;

            //再生回数
            info.ViewCount.Value    = domainVideoInfo.ViewCount;
            info.CommentCount.Value = domainVideoInfo.CommentCount;
            info.MylistCount.Value  = domainVideoInfo.MylistCount;
            info.LikeCount.Value    = domainVideoInfo.LikeCount;

            //チャンネル情報
            info.ChannelID.Value   = domainVideoInfo.ChannelID;
            info.ChannelName.Value = domainVideoInfo.ChannelName;

            //投稿者情報
            info.OwnerID.Value   = domainVideoInfo.OwnerID;
            info.OwnerName.Value = domainVideoInfo.Owner;

            //再生時間
            info.Duration.Value = domainVideoInfo.Duration;

            //投稿日時
            if (domainVideoInfo.DmcInfo is not null)
            {
                info.UploadedOn.Value = domainVideoInfo.DmcInfo.UploadedOn;
            }

            //サムネイル
            if (domainVideoInfo.DmcInfo is not null && domainVideoInfo.DmcInfo.ThumbInfo is not null)
            {
                info.ThumbUrl.Value = domainVideoInfo.DmcInfo.ThumbInfo.GetSpecifiedThumbnail(ThumbSize.Large);
            }
        }
Beispiel #17
0
        /// <summary>
        /// アプリAで開く
        /// </summary>
        /// <param name="videoInfo"></param>
        /// <returns></returns>
        public IAttemptResult SendToAppA(IListVideoInfo videoInfo)
        {
            var appPath = this.localSettingHandler.GetStringSetting(SettingsEnum.AppAPath);

            if (appPath is null)
            {
                return new AttemptResult()
                       {
                           Message = "アプリAは登録されていません。"
                       }
            }
            ;

            var paramBase = this.localSettingHandler.GetStringSetting(SettingsEnum.AppAParam);

            if (paramBase is null)
            {
                paramBase = "<url>";
            }

            return(this.SendToAppCommand(appPath, paramBase, videoInfo));
        }
Beispiel #18
0
        /// <summary>
        /// 検索する
        /// </summary>
        /// <param name="query"></param>
        /// <param name="searchType"></param>
        /// <returns></returns>
        public async Task <ISearchResult> SearchAsync(ISearchQuery query)
        {
            string url = this.urlConstructor.GetUrl(query);

            Api::Response data;

            try
            {
                data = await this.client.GetResponseAsync(url);
            }
            catch (Exception e)
            {
                this.logger.Error("スナップショット検索APIへのアクセスに失敗しました。", e);
                return(new SearchResult()
                {
                    Message = $"APIへのアクセスに失敗しました。(詳細: {e.Message})"
                });
            }

            var videos = data.Data.Select(v =>
            {
                IListVideoInfo videoInfo     = this.container.GetVideo(v.ContentId);
                videoInfo.NiconicoId.Value   = v.ContentId;
                videoInfo.UploadedOn.Value   = v.StartTime.Date;
                videoInfo.Title.Value        = v.Title;
                videoInfo.ViewCount.Value    = v.ViewCounter;
                videoInfo.CommentCount.Value = v.CommentCounter;
                videoInfo.MylistCount.Value  = v.MylistCounter;
                videoInfo.Tags           = v.Tags.Split(" ");
                videoInfo.ThumbUrl.Value = v.ThumbnailUrl;
                return(videoInfo);
            });

            return(new SearchResult()
            {
                IsSucceeded = true, Videos = videos
            });
        }
        public STypes::Video ConvertLocalVideoToStoreVideo(IListVideoInfo source)
        {
            var converted = new STypes::Video();

            converted.Id            = source.Id.Value;
            converted.NiconicoId    = source.NiconicoId.Value;
            converted.Title         = source.Title.Value;
            converted.UploadedOn    = source.UploadedOn.Value;
            converted.ThumbUrl      = source.ThumbUrl.Value;
            converted.LargeThumbUrl = source.LargeThumbUrl.Value;
            converted.ThumbPath     = source.ThumbPath.Value;
            converted.IsSelected    = source.IsSelected.Value;
            converted.FileName      = source.FileName.Value;
            converted.Tags          = source.Tags.ToList();
            converted.ViewCount     = source.ViewCount.Value;
            converted.CommentCount  = source.CommentCount.Value;
            converted.MylistCount   = source.MylistCount.Value;
            converted.LikeCount     = source.LikeCount.Value;
            converted.Duration      = source.Duration.Value;
            converted.OwnerID       = source.OwnerID.Value;
            converted.OwnerName     = source.OwnerName.Value;

            return(converted);
        }
        public IListVideoInfo ConvertStoreVideoToLocalVideo(STypes::Video source)
        {
            IListVideoInfo converted = this._container.GetVideo(source.NiconicoId);

            converted.Id.Value            = source.Id;
            converted.NiconicoId.Value    = source.NiconicoId;
            converted.Title.Value         = source.Title;
            converted.IsDeleted.Value     = source.IsDeleted;
            converted.OwnerName.Value     = source.OwnerName;
            converted.UploadedOn.Value    = source.UploadedOn;
            converted.LargeThumbUrl.Value = source.LargeThumbUrl;
            converted.ThumbUrl.Value      = source.ThumbUrl;
            converted.ThumbPath.Value     = source.ThumbPath;
            converted.FileName.Value      = source.FileName;
            converted.Tags               = source.Tags ?? new List <string>();
            converted.ViewCount.Value    = source.ViewCount;
            converted.CommentCount.Value = source.CommentCount;
            converted.MylistCount.Value  = source.MylistCount;
            converted.LikeCount.Value    = source.LikeCount;
            converted.OwnerID.Value      = source.OwnerID;
            converted.Duration.Value     = source.Duration;

            return(converted);
        }
 public Task <IAttemptResult <IDownloadContext> > TryDownloadContentAsync(IListVideoInfo videoInfo, IDownloadSettings setting, Action <string> OnMessage, CancellationToken token)
 {
     return(Task.FromResult <IAttemptResult <IDownloadContext> >(AttemptResult <IDownloadContext> .Succeeded(new DownloadContext(string.Empty))));
 }
        /// <summary>
        /// サムネイルのパスが正しいかどうかを確認する
        /// </summary>
        /// <param name="video"></param>
        /// <returns></returns>
        public bool IsValidThumbnailPath(IListVideoInfo video)
        {
            string deletedVideoPath = this.GetThumbFilePath("0");

            return(!video.ThumbPath.Value.IsNullOrEmpty() && video.ThumbPath.Value != deletedVideoPath);
        }
Beispiel #23
0
 public IAttemptResult Update(IListVideoInfo video)
 {
     return(AttemptResult.Succeeded());
 }
Beispiel #24
0
 public IAttemptResult RemoveVideo(IListVideoInfo video)
 {
     return(AttemptResult.Succeeded());
 }
 /// <summary>
 /// サムネイルキャッシュの存在を確認する
 /// </summary>
 /// <param name="video"></param>
 /// <returns></returns>
 public bool HasThumbnailCache(IListVideoInfo video)
 {
     return(this.cacheHandler.HasCache(video.NiconicoId.Value, CacheType.Thumbnail));
 }
Beispiel #26
0
        public IAttemptResult RemoveVideo(IListVideoInfo video)
        {
            IAttemptResult result = this._videoStoreHandler.RemoveVideo(video.Id.Value);

            return(result);
        }
Beispiel #27
0
 public IAttemptResult Update(IListVideoInfo video, int?playlistID = null, bool commit = true)
 {
     return(AttemptResult.Succeeded());
 }
Beispiel #28
0
 public IAttemptResult <int> AddVideo(IListVideoInfo video)
 {
     return(AttemptResult <int> .Succeeded(video.Id.Value));
 }
        public async Task <IAttemptResult <IDownloadContext> > TryDownloadContentAsync(IListVideoInfo videoInfo, IDownloadSettings setting, Action <string> OnMessage, CancellationToken token)
        {
            var context = new DownloadContext(setting.NiconicoId);
            var session = DIFactory.Provider.GetRequiredService <IWatchSession>();

            context.RegisterMessageHandler(OnMessage);

            await session.GetVideoDataAsync(setting.NiconicoId);

            if (session.Video is not null)
            {
                this.converter.ConvertDomainVideoInfoToListVideoInfo(videoInfo, session.Video);
            }


            if (session.Video?.DmcInfo.DownloadStartedOn is not null)
            {
                session.Video.DmcInfo.DownloadStartedOn = DateTime.Now;
            }

            if (session.State != WatchSessionState.GotPage || session.Video is null)
            {
                string message = session.State switch
                {
                    WatchSessionState.PaymentNeeded => "視聴ページの解析に失敗しました。",
                    WatchSessionState.HttpRequestOrPageAnalyzingFailure => "視聴ページの取得、または視聴ページの解析に失敗しました。",
                    _ => "不明なエラーにより、視聴ページの取得に失敗しました。"
                };
                return(AttemptResult <IDownloadContext> .Fail(message));
            }

            if (token.IsCancellationRequested)
            {
                return(this.CancelledDownloadAndGetResult());
            }

            ILocalContentInfo?info = null;

            if (setting.Skip)
            {
                string fileNameFormat = setting.FileNameFormat;
                info = this.localContentHandler.GetLocalContentInfo(setting.FolderPath, fileNameFormat, session.Video.DmcInfo, setting.IsReplaceStrictedEnable, setting.VideoInfoExt, setting.IchibaInfoExt, setting.ThumbnailExt, setting.IchibaInfoSuffix, setting.VideoInfoSuffix);
            }

            if (!Directory.Exists(setting.FolderPath))
            {
                Directory.CreateDirectory(setting.FolderPath);
            }

            //動画

            if (setting.Video)
            {
                if (info?.VideoExist ?? false)
                {
                    OnMessage("動画を保存済みのためスキップしました。");
                }
                else if (setting.FromAnotherFolder && (info?.VIdeoExistInOnotherFolder ?? false) && info?.LocalPath is not null)
                {
                    var vResult = this.localContentHandler.MoveDownloadedFile(setting.NiconicoId, info.LocalPath, setting.FolderPath);
                    if (!vResult.IsSucceeded)
                    {
                        return(AttemptResult <IDownloadContext> .Fail(vResult.Message ?? "None"));
                    }
                    else
                    {
                        OnMessage("別フォルダーに保存済みの動画をコピーしました。");
                    }
                }
                else
                {
                    var vResult = await this.TryDownloadVideoAsync(setting, OnMessage, session, context, token);

                    if (!vResult.IsSucceeded)
                    {
                        OnMessage("DL失敗");
                        return(AttemptResult <IDownloadContext> .Fail(vResult.Message ?? "None"));
                    }
                }
            }

            if (token.IsCancellationRequested)
            {
                return(this.CancelledDownloadAndGetResult());
            }

            //サムネイル
            if (setting.Thumbnail)
            {
                if (!info?.ThumbExist ?? true)
                {
                    var tResult = await this.TryDownloadThumbAsync(setting, session);

                    if (token.IsCancellationRequested)
                    {
                        return(this.CancelledDownloadAndGetResult());
                    }

                    if (!tResult.IsSucceeded)
                    {
                        OnMessage("DL失敗");
                        return(AttemptResult <IDownloadContext> .Fail(tResult.Message ?? "None"));
                    }
                }
                else if (info?.ThumbExist ?? false)
                {
                    OnMessage("サムネイルを保存済みのためスキップしました。");
                }
            }

            if (token.IsCancellationRequested)
            {
                return(this.CancelledDownloadAndGetResult());
            }

            //コメント
            if (setting.Comment)
            {
                if (!info?.CommentExist ?? true)
                {
                    var cResult = await this.TryDownloadCommentAsync(setting, session, OnMessage, context, token);

                    if (token.IsCancellationRequested)
                    {
                        return(this.CancelledDownloadAndGetResult());
                    }

                    if (!cResult.IsSucceeded)
                    {
                        OnMessage("DL失敗");
                        return(AttemptResult <IDownloadContext> .Fail(cResult.Message ?? "None"));
                    }
                }
                else if (info?.CommentExist ?? false)
                {
                    OnMessage("コメントを保存済みのためスキップしました。");
                }
            }

            if (token.IsCancellationRequested)
            {
                return(this.CancelledDownloadAndGetResult());
            }

            //動画情報
            if (setting.DownloadVideoInfo)
            {
                if (!info?.VideoInfoExist ?? true)
                {
                    var iResult = this.TryDownloadDescriptionAsync(setting, session, OnMessage);

                    if (token.IsCancellationRequested)
                    {
                        return(this.CancelledDownloadAndGetResult());
                    }

                    if (!iResult.IsSucceeded)
                    {
                        OnMessage("DL失敗");
                        return(AttemptResult <IDownloadContext> .Fail(iResult.Message ?? "None"));
                    }
                }
            }

            if (token.IsCancellationRequested)
            {
                return(this.CancelledDownloadAndGetResult());
            }

            //市場情報
            if (setting.DownloadIchibaInfo)
            {
                if (!info?.IchibaInfoExist ?? true)
                {
                    var iResult = await this.DownloadIchibaInfoAsync(setting, session, OnMessage, context);

                    if (token.IsCancellationRequested)
                    {
                        return(this.CancelledDownloadAndGetResult());
                    }

                    if (!iResult.IsSucceeded)
                    {
                        OnMessage("DL失敗");
                        return(AttemptResult <IDownloadContext> .Fail(iResult.Message ?? "None"));
                    }
                }
                else
                {
                    OnMessage("市場情報を保存済みのためスキップしました。");
                }
            }

            if (session.IsSessionEnsured)
            {
                session.Dispose();
            }

            return(AttemptResult <IDownloadContext> .Succeeded(context));
        }
        /// <summary>
        /// サムネイルURLの形式が正しいかどうかを確認する
        /// </summary>
        /// <param name="video"></param>
        /// <returns></returns>
        public bool IsValidThumbnailUrl(IListVideoInfo video)
        {
            string deletedVideoUrl = NetConstant.NiconicoDeletedVideothumb;

            return(!(video.ThumbUrl.Value.IsNullOrEmpty() || video.ThumbUrl.Value == deletedVideoUrl));
        }