/// <summary>
        /// コメントをダウンロードする
        /// </summary>
        private async Task <IAttemptResult> TryDownloadCommentAsync(IDownloadSettings settings, IWatchSession session, Action <string> onMessage, IDownloadContext context, CancellationToken token)
        {
            Cdl::ICommentDownloader?      v1 = null;
            V2Comment::ICommentDownloader?v2 = null;

            if (settings.EnableExperimentalCommentSafetySystem)
            {
                v2 = DIFactory.Provider.GetRequiredService <V2Comment::ICommentDownloader>();
            }
            else
            {
                v1 = DIFactory.Provider.GetRequiredService <Cdl::ICommentDownloader>();
            }

            IAttemptResult result;

            try
            {
                result = v2 is null ? await v1 !.DownloadComment(session, settings, onMessage, context, token) : await v2.DownloadCommentAsync(session.Video !.DmcInfo, settings, context, token);
            }
            catch (Exception e)
            {
                this.logger.Error("コメントのダウンロードに失敗しました。", e);
                return(AttemptResult.Fail($"コメントのダウンロードに失敗しました。({e.Message})"));
            }

            return(result);
        }
        private string GetFileName(IWatchSession session, IDownloadSettings settings)
        {
            string?economySuffix = session.Video !.DmcInfo.IsEnonomy ? settings.EconomySuffix : null;
            string?suffix        = economySuffix;
            string ext           = settings.SaveWithoutEncode ? FileFolder.TsFileExt : FileFolder.Mp4FileExt;
            string format        = string.IsNullOrEmpty(settings.FileNameFormat) ? Format.DefaultFileNameFormat : settings.FileNameFormat;

            return(this._pathOrganizer.GetFilePath(format, session.Video !.DmcInfo, ext, settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite, suffix));
        }
 public DownloadHelper(IDownloadSettings downloadSettings, IDownloadStreamManager downloadStreamManager)
 {
     NetworkProtocolProviderFactory networkProtocolProviderFactory = new NetworkProtocolProviderFactory(new UrlProtocolParser());
     HttpProtocolProvider httpProtocolProvider = new HttpProtocolProvider(new WebRequestManager(new WebRequestFactory()));
     networkProtocolProviderFactory.RegisterProvider("http", httpProtocolProvider);
     networkProtocolProviderFactory.RegisterProvider("https", httpProtocolProvider);
     m_EventManager = new EventManager();
     m_DownloadManager = new DownloadManager(
         downloadSettings,
         downloadStreamManager,
         networkProtocolProviderFactory,
         m_EventManager);
 }
        public DownloadHelper(IDownloadSettings downloadSettings, IDownloadStreamManager downloadStreamManager)
        {
            NetworkProtocolProviderFactory networkProtocolProviderFactory = new NetworkProtocolProviderFactory(new UrlProtocolParser());
            HttpProtocolProvider           httpProtocolProvider           = new HttpProtocolProvider(new WebRequestManager(new WebRequestFactory()));

            networkProtocolProviderFactory.RegisterProvider("http", httpProtocolProvider);
            networkProtocolProviderFactory.RegisterProvider("https", httpProtocolProvider);
            m_EventManager    = new EventManager();
            m_DownloadManager = new DownloadManager(
                downloadSettings,
                downloadStreamManager,
                networkProtocolProviderFactory,
                m_EventManager);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DownloadTask"/> class.
 /// </summary>
 /// <param name="networkProtocolProviderFactory">The network protocol provider factory.</param>
 /// <param name="downloadSegmentCalculator">The download segment calculator.</param>
 /// <param name="downloadStreamManager">The download stream manager.</param>
 /// <param name="settings">The settings.</param>
 /// <param name="file">The file.</param>
 /// <param name="eventManager">The event manager.</param>
 public DownloadTask(
     INetworkProtocolProviderFactory networkProtocolProviderFactory,
     IDownloadSegmentPositionsCalculator downloadSegmentCalculator,
     IDownloadStreamManager downloadStreamManager,
     IDownloadSettings settings,
     DownloadFileInfo file,
     IEventManager eventManager)
 {
     m_NetworkProtocolProviderFactory = networkProtocolProviderFactory;
     m_DownloadSegmentCalculator      = downloadSegmentCalculator;
     m_Settings = settings;
     m_File     = file;
     m_DownloadStreamManager = downloadStreamManager;
     m_EventManager          = eventManager;
     m_CreateDate            = DateTime.Now;
 }
        /// <summary>
        /// 非同期で動画をダウンロードする
        /// </summary>
        private async Task <IAttemptResult> TryDownloadVideoAsync(IDownloadSettings settings, Action <string> onMessage, IWatchSession session, IDownloadContext context, CancellationToken token)
        {
            var            videoDownloader = DIFactory.Provider.GetRequiredService <Vdl::IVideoDownloader>();
            IAttemptResult result;

            try
            {
                result = await videoDownloader.DownloadVideoAsync(settings, onMessage, context, session, token);
            }
            catch (Exception e)
            {
                this.logger.Error($"動画のダウンロードに失敗しました。({context.GetLogContent()})", e);
                return(AttemptResult.Fail($"動画のダウンロードに失敗しました。(詳細:{e.Message})"));
            }
            return(result);
        }
        /// <summary>
        /// 市場情報をダウンロードする
        /// </summary>
        private async Task <IAttemptResult> DownloadIchibaInfoAsync(IDownloadSettings settings, IWatchSession session, Action <string> onMessage, IDownloadContext context)
        {
            var            iDownloader = DIFactory.Provider.GetRequiredService <IIchibaInfoDownloader>();
            IAttemptResult result;

            try
            {
                result = await iDownloader.DownloadIchibaInfo(session, settings, onMessage, context);
            }
            catch (Exception e)
            {
                this.logger.Error("市場情報のダウンロードに失敗しました。", e);
                return(AttemptResult.Fail($"市場情報のダウンロードに失敗しました。({e.Message})"));
            }
            return(result);
        }
        public DownloadManager(IDownloadSettings downloadSettings, 
                               IDownloadStreamManager downloadStreamManager, 
                               INetworkProtocolProviderFactory networkProtocolProviderFactory,
                               IEventManager eventManager)
        {
            if (downloadSettings == null)
            {
                throw new ArgumentNullException("downloadSettings");
            }

            m_DownloadTaskList = new DownloadTaskList();
            m_DownloadTaskQueue = new DownloadTaskQueue(downloadSettings.MaximumConcurrentDownloads);
            m_DownloadSettings = downloadSettings;
            m_LocalFileDownloadStreamManager = downloadStreamManager;
            m_NetworkProtocolProviderFactory = networkProtocolProviderFactory;
            m_EventManager = eventManager;
        }
Exemple #9
0
        public DownloadManager(IDownloadSettings downloadSettings,
                               IDownloadStreamManager downloadStreamManager,
                               INetworkProtocolProviderFactory networkProtocolProviderFactory,
                               IEventManager eventManager)
        {
            if (downloadSettings == null)
            {
                throw new ArgumentNullException("downloadSettings");
            }

            m_DownloadTaskList  = new DownloadTaskList();
            m_DownloadTaskQueue = new DownloadTaskQueue(downloadSettings.MaximumConcurrentDownloads);
            m_DownloadSettings  = downloadSettings;
            m_LocalFileDownloadStreamManager = downloadStreamManager;
            m_NetworkProtocolProviderFactory = networkProtocolProviderFactory;
            m_EventManager = eventManager;
        }
        /// <summary>
        /// サムネイルをダウンロードする
        /// </summary>
        private async Task <IAttemptResult> TryDownloadThumbAsync(IDownloadSettings setting, IWatchSession session)
        {
            var            thumbDownloader = DIFactory.Provider.GetRequiredService <Tdl::IThumbDownloader>();
            IAttemptResult result;

            try
            {
                result = await thumbDownloader.DownloadThumbnailAsync(setting, session);
            }
            catch (Exception e)
            {
                this.logger.Error($"サムネイルのダウンロードに失敗しました。", e);
                return(AttemptResult.Fail($"サムネイルのダウンロードに失敗しました。(詳細:{e.Message})"));
            }

            return(result);
        }
Exemple #11
0
        public async Task <IAttemptResult> DownloadThumbnailAsync(IDownloadSettings settings, IWatchSession session)
        {
            if (session.Video is null)
            {
                return(AttemptResult.Fail("動画情報が未取得です。"));
            }

            var filepath = this._pathOrganizer.GetFilePath(settings.FileNameFormat, session.Video !.DmcInfo, settings.ThumbnailExt, settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite, settings.ThumbSuffix);

            string?thumbUrl;

            try
            {
                thumbUrl = session.Video !.DmcInfo.ThumbInfo.GetSpecifiedThumbnail(settings.ThumbSize);
            }
            catch (Exception e)
            {
                this._logger.Error($"サムネイルURLの取得に失敗しました。", e);
                return(AttemptResult.Fail("サムネイルのURLを取得できませんでした。"));
            }


            byte[] data;
            try
            {
                data = await this.DownloadAsync(thumbUrl);
            }
            catch (Exception e)
            {
                this._logger.Error($"サムネイルの取得に失敗しました。", e);
                return(AttemptResult.Fail($"サムネイルの取得に失敗しました。(詳細: {e.Message})"));
            }

            try
            {
                this.WriteThumb(data, filepath);
            }
            catch (Exception e)
            {
                this._logger.Error($"サムネイルの保存に失敗しました。", e);
                return(AttemptResult.Fail($"サムネイルの保存に失敗しました。(詳細: {e.Message})"));
            }

            return(AttemptResult.Succeeded());
        }
        /// <summary>
        /// 動画情報をダウンロードする
        /// </summary>
        private IAttemptResult TryDownloadDescriptionAsync(IDownloadSettings settings, IWatchSession session, Action <string> onMessage)
        {
            var descriptionDownloader = DIFactory.Provider.GetRequiredService <DDL::IDescriptionDownloader>();

            IAttemptResult result;

            try
            {
                result = descriptionDownloader.DownloadVideoInfoAsync(settings, session, onMessage);
            }
            catch (Exception e)
            {
                this.logger.Error($"動画情報のダウンロードに失敗しました。", e);
                return(AttemptResult.Fail($"動画情報のダウンロードに失敗しました。(詳細:{e.Message})"));
            }

            return(result);
        }
Exemple #13
0
        /// <summary>
        /// 動画情報ファイルを保存する
        /// </summary>
        /// <param name="setting"></param>
        /// <param name="dmcInfo"></param>
        /// <returns></returns>
        public IAttemptResult DownloadVideoInfoAsync(IDownloadSettings setting, IWatchSession session, Action <string> onMessage)
        {
            if (session.Video is null)
            {
                return(AttemptResult.Fail("動画情報が未取得です。"));
            }

            onMessage($"動画情報の保存を開始します。");
            this._logger.Log($"{session.Video.Id}の動画情報保存を開始");

            string fileName = this._pathOrganizer.GetFilePath(setting.FileNameFormat, session.Video.DmcInfo, setting.VideoInfoExt, setting.FolderPath, setting.IsReplaceStrictedEnable, setting.Overwrite, setting.VideoInfoSuffix);


            var filePath = Path.Combine(setting.FolderPath, fileName);

            string content = setting.VideoInfoType switch
            {
                VideoInfoTypeSettings.Json => this._producer.GetJsonContent(session.Video.DmcInfo),
                VideoInfoTypeSettings.Xml => this._producer.GetXmlContent(session.Video.DmcInfo),
                _ => this._producer.GetContent(session.Video.DmcInfo),
            };

            try
            {
                IOUtils.CreateDirectoryIfNotExist(fileName);
                this._fileIO.Write(filePath, content);
            }
            catch (Exception e)
            {
                onMessage("動画情報ファイルの書き込みに失敗しました。");
                this._logger.Error("動画情報ファイルの書き込みに失敗しました。", e);
                return(AttemptResult.Fail($"動画情報ファイルの書き込みに失敗しました。(詳細:{e.Message})"));
            }

            onMessage($"動画情報ファイルを保存しました。");
            return(AttemptResult.Succeeded());
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DownloadTask"/> class.
 /// </summary>
 /// <param name="networkProtocolProviderFactory">The network protocol provider factory.</param>
 /// <param name="downloadSegmentCalculator">The download segment calculator.</param>
 /// <param name="downloadStreamManager">The download stream manager.</param>
 /// <param name="settings">The settings.</param>
 /// <param name="file">The file.</param>
 /// <param name="eventManager">The event manager.</param>
 public DownloadTask(
                    INetworkProtocolProviderFactory networkProtocolProviderFactory,
                    IDownloadSegmentPositionsCalculator downloadSegmentCalculator,
                    IDownloadStreamManager downloadStreamManager,
                    IDownloadSettings settings,
                    DownloadFileInfo file,
                    IEventManager eventManager)
 {
     m_NetworkProtocolProviderFactory = networkProtocolProviderFactory;
     m_DownloadSegmentCalculator = downloadSegmentCalculator;
     m_Settings = settings;
     m_File = file;
     m_DownloadStreamManager = downloadStreamManager;
     m_EventManager = eventManager;
     m_CreateDate = DateTime.Now;
 }
        public async Task <IAttemptResult> DownloadIchibaInfo(IWatchSession session, IDownloadSettings settings, Action <string> onMessage, IDownloadContext context)
        {
            if (session.Video is null)
            {
                return(new AttemptResult()
                {
                    Message = "セッション情報のVideoがnullです。"
                });
            }

            onMessage($"市場APIへのアクセスを開始します。({session.Video.Id})");
            var getResult = await this._niconicoIchibaHandler.GetIchibaInfo(session.Video.Id);

            if (!getResult.IsSucceeded || getResult.Data is null)
            {
                onMessage($"市場APIからの情報取得に失敗しました。({session.Video.Id})");
                if (getResult.Exception is not null)
                {
                    this._logger.Error($"市場情報の取得に失敗しました。(詳細:{getResult.Message} ,{context.GetLogContent()})", getResult.Exception);
                }
                else
                {
                    this._logger.Error($"市場情報の取得に失敗しました。(詳細:{getResult.Message} ,{context.GetLogContent()})");
                }
                return(new AttemptResult()
                {
                    Message = getResult.Message
                });
            }

            onMessage($"市場APIからの情報取得を取得しました。({session.Video.Id})");

            string content;

            if (settings.IchibaInfoType != IchibaInfoTypeSettings.Html)
            {
                try
                {
                    content = this.GetContent(getResult.Data, settings.IchibaInfoType == IchibaInfoTypeSettings.Xml);
                }
                catch (Exception e)
                {
                    this._logger.Error($"市場情報のシリアル化に失敗しました。(詳細:{getResult.Message} ,{context.GetLogContent()})", e);
                    onMessage($"市場情報のシリアル化に失敗しました。({session.Video.Id})");
                    return(new AttemptResult()
                    {
                        Message = "市場情報のシリアル化に失敗しました。"
                    });
                }
            }
            else
            {
                try
                {
                    content = this.GetHtmlContent(getResult.Data, session.Video.Id);
                }
                catch (Exception e)
                {
                    this._logger.Error($"市場情報のシリアル化に失敗しました。(詳細:{getResult.Message} ,{context.GetLogContent()})", e);
                    onMessage($"市場情報のシリアル化に失敗しました。({session.Video.Id})");
                    return(new AttemptResult()
                    {
                        Message = "市場情報のシリアル化に失敗しました。"
                    });
                }
            }


            string filePath = this._path.GetFilePath(settings.FileNameFormat, session.Video !.DmcInfo, settings.IchibaInfoExt, settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite, settings.IchibaInfoSuffix);

            try
            {
                this._fileIO.Write(filePath, content);
            }
            catch (Exception e)
            {
                this._logger.Error($"市場情報ファイルの書き込みに失敗しました。({context.GetLogContent()})", e);
                onMessage($"市場情報ファイルの書き込みに失敗しました。({session.Video.Id})");
                return(new AttemptResult()
                {
                    Message = $"市場情報ファイルの書き込みに失敗しました。(詳細:{e.Message})"
                });
            }

            onMessage($"市場情報ファイルの保存が完了しました。({session.Video.Id})");
            return(new AttemptResult()
            {
                IsSucceeded = true
            });
        }
Exemple #16
0
 public HtmlLoader(IDownloadSettings settings)
 {
     client = new HttpClient();
     url    = $"{settings.BaseUrl}{settings.RhymeType}/{settings.Word}.html";
 }
 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))));
 }
        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));
        }
Exemple #19
0
        private async Task <IAttemptResult> EncodeVideosAsync(IWatchSession session, IDownloadContext context, IDownloadSettings settings, Action <string> onMessage, IEnumerable <string> segmentFilePaths, CancellationToken token)
        {
            var encodeSetting = new EncodeSettings()
            {
                FilePath           = context.FileName,
                CommandFormat      = settings.CommandFormat,
                TsFilePaths        = segmentFilePaths,
                IsOverwriteEnable  = settings.Overwrite,
                IsOverrideDTEnable = settings.OverrideVideoFileDateToUploadedDT,
                UploadedOn         = session.Video !.DmcInfo.UploadedOn,
                IsNoEncodeEnable   = settings.SaveWithoutEncode,
            };

            try
            {
                await this._encorder.EncodeAsync(encodeSetting, onMessage, token);
            }
            catch (Exception e)
            {
                this._logger.Error($"ファイルの変換中にエラーが発生しました。({this.context!.GetLogContent()})", e);
                onMessage("動画の変換中にエラー発生");
                return(AttemptResult.Fail($"ファイルの変換中にエラーが発生しました。(詳細: {e.Message})"));
            }

            return(AttemptResult.Succeeded());
        }
Exemple #20
0
        private async Task <IAttemptResult> EnsureSessionAsync(IWatchSession session, IDownloadSettings settings)
        {
            await session.EnsureSessionAsync(settings.NiconicoId);

            if (!session.IsSessionEnsured)
            {
                string message = session.State switch
                {
                    WatchSessionState.HttpRequestOrPageAnalyzingFailure => "視聴ページの取得、または解析に失敗しました。",
                    WatchSessionState.EncryptedVideo => "暗号化された動画のため、ダウンロードできません。",
                    WatchSessionState.SessionEnsuringFailure => "セッションの確立に失敗しました。",
                    _ => "不明なエラーにより、セッションの確立に失敗しました。"
                };

                return(AttemptResult.Fail(message));
            }
            else
            {
                this._logger.Log($"視聴セッションを確立しました。({this.context!.GetLogContent()})");
                return(AttemptResult.Succeeded());
            }
        }
Exemple #21
0
 public RhymesDownloader(IParser <T> parser, IDownloadSettings downloadSettings) : this(parser)
 {
     Settings = downloadSettings;
 }
Exemple #22
0
        public async Task <IAttemptResult> DownloadVideoAsync(IDownloadSettings settings, Action <string> onMessage, IDownloadContext context, IWatchSession session, CancellationToken token)
        {
            IAttemptResult OnCanceled()
            {
                this._logger.Log($"ユーザーの操作によって動画のダウンロード処理がキャンセルされました。({context.GetLogContent()})");
                onMessage("ダウンロードをキャンセル");
                return(AttemptResult.Fail("処理がキャンセルされました"));
            }

            this.context = context;
            this._logger.Log($"動画のダウンロードを開始しました。({context.GetLogContent()})");

            if (session.IsSessionExipired)
            {
                this._logger.Log($"セッションが失効していたため動画のダウンロードをキャンセルします。({context.GetLogContent()})");
                return(AttemptResult <string> .Fail("セッションが失効済のためダウンロード出来ません。"));
            }

            if (!session.IsSessionEnsured)
            {
                if (token.IsCancellationRequested)
                {
                    return(OnCanceled());
                }

                IAttemptResult sessionR = await this.EnsureSessionAsync(session, settings);

                if (!sessionR.IsSucceeded)
                {
                    onMessage(sessionR.Message ?? "");
                    return(sessionR);
                }
            }


            //ファイル名取得
            string fileName = this.GetFileName(session, settings);

            context.FileName = fileName;


            if (token.IsCancellationRequested)
            {
                return(OnCanceled());
            }


            //ストリーム系
            IAttemptResult <IStreamInfo> streamResult = await this.GetStream(session, settings.VerticalResolution);

            if (!streamResult.IsSucceeded || streamResult.Data is null)
            {
                return(AttemptResult.Fail(streamResult.Message, streamResult.Exception));
            }

            IStreamInfo   targetStream        = streamResult.Data;
            List <string> rawsegmentFilePaths = targetStream.StreamUrls.Select(u => u.FileName).ToList();

            context.ActualVerticalResolution = targetStream.Resolution?.Vertical ?? 0;
            context.OriginalSegmentsCount    = targetStream.StreamUrls.Count;


            if (token.IsCancellationRequested)
            {
                return(OnCanceled());
            }


            //レジューム系
            string segmentDirectoryName;
            IAttemptResult <string> sResult = settings.ResumeEnable ? this.GetAndSetSegmentsDirectoryInfoIfExists(settings.NiconicoId, targetStream.Resolution?.Vertical ?? 0, targetStream) : AttemptResult <string> .Fail();

            if (sResult.IsSucceeded && sResult.Data is not null)
            {
                segmentDirectoryName = sResult.Data;
                onMessage("DLをレジューム");
                this._logger.Log($"ダウンロードをレジュームします。({context.GetLogContent()})");
            }
            else
            {
                segmentDirectoryName = $"{settings.NiconicoId}-{targetStream.Resolution?.Vertical ?? 0}-{DateTime.Now.ToString("yyyy-MM-dd")}";
            }
            List <string> segmentFilePaths = rawsegmentFilePaths.Select(p => Path.Combine(AppContext.BaseDirectory, "tmp", segmentDirectoryName, p)).ToList();


            //DL系
            IAttemptResult downloadresult = await this.DownloadVideoInternalAsync(targetStream, onMessage, context, settings.MaxParallelSegmentDLCount, segmentDirectoryName, token);

            if (!downloadresult.IsSucceeded)
            {
                return(downloadresult);
            }

            if (token.IsCancellationRequested)
            {
                return(OnCanceled());
            }

            onMessage("動画を変換中...");
            IAttemptResult encodeResult = await this.EncodeVideosAsync(session, context, settings, onMessage, segmentFilePaths, token);

            if (!encodeResult.IsSucceeded)
            {
                return(encodeResult);
            }
            onMessage("動画の変換が完了");

            this.DeleteTmpFolder(segmentDirectoryName, onMessage);


            bool isEconomy = session.Video !.DmcInfo.IsEnonomy;

            if (settings.IsEconomy && settings.DeleteExistingEconomyFile && !isEconomy)
            {
                this.RemoveEconomyFile(settings.FilePath);
            }

            this._fileStorehandler.Add(settings.NiconicoId, Path.Combine(settings.FolderPath, fileName));

            this._logger.Log($"動画のダウンロードが完了しました。({context.GetLogContent()})");

            return(AttemptResult.Succeeded());
        }
Exemple #23
0
        /// <summary>
        /// コメントをダウンロードする
        /// </summary>
        /// <param name="dmcInfo"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public async Task <ICommentCollection> DownloadCommentAsync(IDmcInfo dmcInfo, IDownloadSettings settings, Action <string> onMessage, IDownloadContext context, CancellationToken token)
        {
            var(dThread, dFork) = this.GetDefaultPosyTarget(dmcInfo);

            if (dThread == -1 || dFork == -1)
            {
                throw new InvalidOperationException("DefaultPostTargetが見つかりません。");
            }

            var            comments = CommentCollection.GetInstance(settings.CommentOffset, dThread, dFork, settings.EnableUnsafeCommentHandle, settings.EnableExperimentalCommentSafetySystem);
            Response::Chat?first    = null;
            int            index    = 0;
            long           lastNo   = 0;

            do
            {
                int count = comments.Count;

                if (index > 0)
                {
                    if (settings.CommentFetchWaitSpan > 0)
                    {
                        onMessage($"待機中...({settings.CommentFetchWaitSpan}ms)");
                        try
                        {
                            await Task.Delay(settings.CommentFetchWaitSpan, token);
                        }
                        catch { }
                    }
                    onMessage($"過去ログをダウンロード中({index + 1}件目・{count}コメ)");
                }

                long?when = count == 0 ? 0 : first?.Date - 1;
                List <Response::Comment> retlieved = await this.GetCommentsAsync(dmcInfo, settings, when);

                comments.Add(retlieved);

                if (index > 0)
                {
                    this.logger.Log($"過去ログをダウンロードしました。({index}個目, {retlieved.Count}コメント, {context.GetLogContent()})");
                }
                else
                {
                    this.logger.Log($"現行スレッドをダウンロードしました。({retlieved.Count}コメント, {context.GetLogContent()})");
                }

                first = comments.GetFirstComment(false);
                if ((first?.No ?? 0) == lastNo)
                {
                    break;
                }
                else
                {
                    lastNo = first?.No ?? 0;
                }

                if (settings.MaxCommentsCount > 0 && comments.Count > settings.MaxCommentsCount)
                {
                    var rmCount = comments.Count - settings.MaxCommentsCount;
                    comments.RemoveFor(rmCount);
                    break;
                }

                if (!settings.DownloadLog)
                {
                    break;
                }
                else if (index == 0)
                {
                    onMessage("過去ログのダウンロードを開始します。");
                }

                ++index;
            } while (first?.No > 1 && !token.IsCancellationRequested);

            if (token.IsCancellationRequested)
            {
                throw new TaskCanceledException("コメントのダウンロードがキャンセルされました。");
            }

            onMessage($"コメントの正規化処理を開始します。");
            comments.Distinct();
            onMessage($"コメントの正規化処理が完了しました。");

            this.logger.Log($"コメントのダウンロードが完了しました。({comments.Count}コメント, {context.GetLogContent()})");

            return(comments);
        }
Exemple #24
0
        /// <summary>
        /// コメントを取得する
        /// </summary>
        /// <param name="dmcInfo"></param>
        /// <param name="settings"></param>
        /// <param name="when"></param>
        /// <returns></returns>
        private async Task <List <Response::Comment> > GetCommentsAsync(IDmcInfo dmcInfo, IDownloadSettings settings, long?when = null)
        {
            var option = new CommentOptions()
            {
                NoEasyComment = !settings.DownloadEasy,
                OwnerComment  = settings.DownloadOwner,
                When          = when ?? 0
            };
            var request = await this.requestBuilder.GetRequestDataAsync(dmcInfo, option);

            string server = dmcInfo.CommentThreads.FirstOrDefault()?.Server ?? @"https://nmsg.nicovideo.jp/api.json";

            if (!server.EndsWith("/api.json"))
            {
                server += "/api.json";
            }

            var res = await this.http.PostAsync(new Uri(server), new StringContent(request));

            if (!res.IsSuccessStatusCode)
            {
                throw new HttpRequestException($"コメントの取得に失敗しました。(status_code:{(int)res.StatusCode}, reason_phrase:{res.ReasonPhrase})");
            }

            string content = await res.Content.ReadAsStringAsync();

            var data = JsonParser.DeSerialize <List <Response::Comment> >(content);

            return(data);
        }
        public async Task <IAttemptResult> DownloadComment(IWatchSession session, IDownloadSettings settings, Action <string> onMessage, IDownloadContext context, CancellationToken token)
        {
            if (session.Video is null)
            {
                return(AttemptResult.Fail("動画情報が未取得です。"));
            }

            string filePath      = this._pathOrganizer.GetFilePath(settings.FileNameFormat, session.Video !.DmcInfo, ".xml", settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite);
            string ownerFileName = this._pathOrganizer.GetFilePath(settings.FileNameFormat, session.Video !.DmcInfo, ".xml", settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite, settings.OwnerComSuffix);

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

            onMessage("コメントのダウンロードを開始します。");
            this._logger.Log($"{settings.NiconicoId}のコメントダウンロードを開始します。({context.GetLogContent()})");

            ICommentCollection result;

            try
            {
                result = await this._client.DownloadCommentAsync(session.Video !.DmcInfo, settings, onMessage, context, token);
            }
            catch (Exception e)
            {
                this._logger.Error($"コメントの取得に失敗しました。({context.GetLogContent()})", e);
                return(AttemptResult.Fail($"コメントの取得に失敗しました。(詳細:{e.Message})"));
            }
            onMessage("コメントのダウンロードが完了しました。");

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

            onMessage("コメントの変換処理を開始します。");
            IStoreCommentsData data;

            try
            {
                data = this._commentConverter.ConvertToStoreCommentsData(result, settings);
            }
            catch (Exception e)
            {
                this._logger.Error($"コメントの解析に失敗しました。({context.GetLogContent()})", e);
                return(AttemptResult.Fail($"コメントの解析に失敗しました。"));
            }
            onMessage("コメントの変換処理が完了しました。");

            data.FilePath     = filePath;
            data.OwnerFilPath = ownerFileName;

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

            onMessage($"コメントの書き込みを開始します。");
            try
            {
                this._commentStream.Write(data, settings.Overwrite);
            }
            catch (Exception e)
            {
                this._logger.Error($"コメントの書き込みに失敗しました。({context.GetLogContent()})", e);
                return(AttemptResult.Fail("コメントの書き込みに失敗しました。"));
            }
            onMessage("コメントのダウンロードが完了しました。");
            this._logger.Log($"コメントのダウンロードが完了しました。({context.GetLogContent()})");

            return(AttemptResult.Succeeded());
        }
Exemple #26
0
        public async Task <IAttemptResult> DownloadCommentAsync(IDmcInfo dmcInfo, IDownloadSettings settings, IDownloadContext context, CancellationToken token)
        {
            //コメント追記処理
            var origination          = DateTime.Now;
            var originationSpecidied = false;
            var oldComments          = new List <Core::IComment>();

            if (settings.AppendingToLocalComment && this._commentLoader.CommentExists(settings.FolderPath, settings.NiconicoId))
            {
                IAttemptResult <Local::LocalCommentInfo> localResult = this._commentLoader.LoadComment(settings.FolderPath, settings.NiconicoId);
                if (localResult.IsSucceeded && localResult.Data is not null)
                {
                    origination          = localResult.Data.LastUpdatedTime;
                    originationSpecidied = true;
                    oldComments.AddRange(localResult.Data.Comments);
                }
            }

            //キャンセル処理
            token.ThrowIfCancellationRequested();

            //コメント取得処理
            var dlOption = new Fetch::CommentClientOption(originationSpecidied, origination);
            IAttemptResult <(Core::ICommentCollection, Core::IThreadInfo)> dlResult = await this._commentClient.DownloadCommentAsync(dmcInfo, settings, dlOption, context, token);

            if (!dlResult.IsSucceeded)
            {
                return(AttemptResult.Fail(dlResult.Message));
            }

            //キャンセル処理
            token.ThrowIfCancellationRequested();

            //コメント統合処理
            var(collection, threadInfo) = dlResult.Data;
            if (oldComments.Count > 0)
            {
                foreach (var comment in oldComments)
                {
                    collection.Add(comment);
                }
            }

            //コメント書き込み処理
            string path         = this._path.GetFilePath(settings.FileNameFormat, dmcInfo, ".xml", settings.FolderPath, settings.IsReplaceStrictedEnable, settings.Overwrite);
            var    writerOption = new Local::CommentWriterOption(path, settings.OmittingXmlDeclaration, dmcInfo.Id);

            IAttemptResult writeResult = this._commentWriter.WriteComment(collection.Comments, threadInfo, writerOption);

            if (!writeResult.IsSucceeded)
            {
                return(writeResult);
            }

            //キャンセル処理
            token.ThrowIfCancellationRequested();

            //コメ数記録
            context.CommentCount = collection.Count;

            return(AttemptResult.Succeeded());
        }