예제 #1
0
        private static void download(INovelDownloadPlugin plugin, string url, NDTBook bookToken = null)
        {
            if (bookToken == null && !plugin.TryGetBookToken(new Uri(url, UriKind.RelativeOrAbsolute), out bookToken))
            {
                return;
            }

            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(string.Format("{0}({1}) v{2}\n{3}", plugin.DisplayName, plugin.Name, plugin.Version, plugin.Description));
            Console.ForegroundColor = ConsoleColor.Gray;

            Console.WriteLine();

            if (bookToken is NovelDownloader.Plugin.luoqiu.com.BookToken ||
                bookToken is NovelDownloader.Plugin._81zw.com.BookToken ||
                bookToken is NovelDownloader.Plugin.顶点小说.BookToken)
            {
                downloadNormal(plugin, bookToken);
            }
            else if (bookToken is NovelDownloader.Plugin.wenku8.com.BookToken ||
                     bookToken is NovelDownloader.Plugin.qidian.com.BookToken)
            {
                downloadLight(plugin, bookToken);
            }
            else
            {
                Console.WriteLine("无法下载《{0]》", bookToken.Title);
            }
        }
예제 #2
0
        /// <summary>
        /// 寻找合适的书籍输出器,并异步保存书籍到文件。
        /// </summary>
        /// <param name="bookToken">书籍节点。</param>
        /// <param name="outputDir">输出目录。</param>
        /// <exception cref="ArgumentNullException"><paramref name="bookToken"/> 的值为 <see langword="null"/> 。</exception>
        /// <exception cref="NotSupportedException">未找到支持节点的小说下载插件。</exception>
        /// <exception cref="NotSupportedException">不支持的插件类型。</exception>
        public Task SaveToAsync(NDTBook bookToken, string outputDir)
        {
            if (bookToken == null)
            {
                throw new ArgumentNullException(nameof(bookToken));
            }

            IBookWriter bookWriter = this.FindBookWriterForBookToken(bookToken);

            // 异步写入文件。
            return(bookWriter.WriteAsync(bookToken, outputDir));
        }
예제 #3
0
        /// <summary>
        /// 寻找合适的书籍输出器,并保存书籍到文件。
        /// </summary>
        /// <param name="bookToken">书籍节点。</param>
        /// <param name="outputDir">输出目录。</param>
        /// <exception cref="ArgumentNullException"><paramref name="bookToken"/> 的值为 <see langword="null"/> 。</exception>
        /// <exception cref="NotSupportedException">未找到支持节点的小说下载插件。</exception>
        /// <exception cref="NotSupportedException">不支持的插件类型。</exception>
        public void SaveTo(NDTBook bookToken, string outputDir)
        {
            if (bookToken == null)
            {
                throw new ArgumentNullException(nameof(bookToken));
            }

            IBookWriter bookWriter = this.FindBookWriterForBookToken(bookToken);

            // 写入文件。
            bookWriter.Write(bookToken, outputDir);
        }
예제 #4
0
        /// <summary>
        /// 尝试获取位于指定的 <see cref="Uri"/> 位置的小说标签。
        /// </summary>
        /// <param name="uri">指定的统一资源标识符。</param>
        /// <param name="bookToken">位于指定的 <see cref="Uri"/> 位置的小说标签。</param>
        /// <returns>是否获取成功。</returns>
        public override bool TryGetBookToken(Uri uri, out NDTBook bookToken)
        {
            try
            {
                bookToken = this.GetBookToken(uri);

                return(bookToken != null);
            }
            catch (Exception)
            {
                bookToken = null;

                return(false);
            }
        }
예제 #5
0
        public BookInfo(NDTBook bookToken)
        {
            if (bookToken == null)
            {
                throw new ArgumentNullException(nameof(bookToken));
            }

            this.Title  = bookToken.Title;
            this.Author = bookToken.Author;

            var description = bookToken.Description;
            var lines       = description.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            if (lines.Length == 0)
            {
                this.Description = string.Empty;
            }
            else if (lines.Length == 1)
            {
                this.Description = lines[0].Trim();
            }
            else
            {
                this.Description = string.Join(Environment.NewLine, new[] { string.Empty }.Concat(lines.Select(line => "  " + line.Trim())));
            }

            this.Cover = bookToken.Cover;

            bookToken.StartCreep();
            foreach (var token in bookToken.Children.OfType <NDTChapter>().Select(token => new ChapterInfo(token)))
            {
                this.Chapters.Add(token);
            }

            if (this.Chapters.Count == 0)
            {
                foreach (var token in bookToken.Children.OfType <NDTVolume>().SelectMany(token =>
                {
                    token.StartCreep();
                    return(token.Children.OfType <NDTChapter>());
                }).Select(token => new ChapterInfo(token)))
                {
                    this.Chapters.Add(token);
                }
            }
        }
예제 #6
0
        private static void downloadNormal(INovelDownloadPlugin plugin, NDTBook bookToken)
        {
            new Thread(() =>
            {
                using (StreamWriter writer = new StreamWriter(string.Format("{0}.txt", process(bookToken.Title)), false, Encoding.UTF8))
                {
                    //StringBuilder sb = new StringBuilder();

                    Console.WriteLine("{0} - {1}", bookToken.Type, bookToken.Title);
                    writer.WriteLine(string.Format("书名:{0}", bookToken.Title));
                    writer.WriteLine(string.Format("作者:{0}", bookToken.Author));
                    writer.WriteLine();
                    writer.WriteLine();

                    bookToken.CreepStarted  += (sender, e) => Console.WriteLine("\t开始下载书籍《{0}》", bookToken.Title);
                    bookToken.CreepFetched  += (sender, e) => Console.WriteLine("\t获取 【{0}】", e.Data);
                    bookToken.CreepFinished += (sender, e) => Console.WriteLine("\t下载书籍《{0}》完成。", bookToken.Title);
                    bookToken.StartCreep();
                    foreach (NDTChapter chapterToken in bookToken.Children)
                    {
                        chapterToken.CreepStarted += (sender, e) =>
                        {
                            Console.WriteLine("\t开始下载章节【{0}】”", chapterToken.Title);
                            writer.WriteLine("--------------------");
                            writer.WriteLine();
                            writer.WriteLine(chapterToken.Title);
                        };
                        chapterToken.CreepFetched += (sender, e) =>
                        {
                            //Console.WriteLine("{0}", e.Data);
                            writer.WriteLine(string.Format("  {0}", e.Data));
                        };
                        chapterToken.CreepFinished += (sender, e) =>
                        {
                            Console.WriteLine("\t下载章节【{0}】完成。\n", chapterToken.Title);
                            writer.WriteLine();
                        };
                        chapterToken.StartCreep();
                    }

                    //Console.WriteLine(sb.ToString());
                }
            }).Start();
        }
예제 #7
0
        public virtual void Write(NDTBook bookToken, string outputDir)
        {
            if (bookToken == null)
            {
                throw new ArgumentNullException(nameof(bookToken));
            }
            if (outputDir == null)
            {
                throw new ArgumentNullException(nameof(outputDir));
            }

            var di = new DirectoryInfo(outputDir);

            if (!di.Exists)
            {
                di.Create();
            }

            this.WriteInternal(bookToken, outputDir);
        }
예제 #8
0
        /// <summary>
        /// 提供输出书籍的实现。
        /// </summary>
        /// <param name="bookToken">书籍节点。</param>
        /// <param name="outputDir">输出目录。</param>
        protected override void WriteInternal(NDTBook bookToken, string outputDir)
        {
            using (StreamWriter writer = new StreamWriter(Path.Combine(outputDir, $"{bookToken.Title}.txt"), false, Encoding.UTF8))
            {
                //StringBuilder sb = new StringBuilder();

                this.LogWriter.WriteLine("{0} - {1}", bookToken.Type, bookToken.Title);
                writer.WriteLine(string.Format("书名:{0}", bookToken.Title));
                writer.WriteLine(string.Format("作者:{0}", bookToken.Author));
                writer.WriteLine();
                writer.WriteLine();

                bookToken.CreepStarted  += (sender, e) => this.LogWriter.WriteLine("\t开始获取书籍《{0}》", bookToken.Title);
                bookToken.CreepFetched  += (sender, e) => this.LogWriter.WriteLine("\t获取 【{0}】", e.Data);
                bookToken.CreepFinished += (sender, e) => this.LogWriter.WriteLine("\t书籍《{0}》获取完成。", bookToken.Title);
                bookToken.StartCreep();
                foreach (NDTChapter chapterToken in bookToken.Children)
                {
                    chapterToken.CreepStarted += (sender, e) =>
                    {
                        this.LogWriter.WriteLine("\t开始获取章节【{0}】”", chapterToken.Title);
                        writer.WriteLine("--------------------");
                        writer.WriteLine();
                        writer.WriteLine(chapterToken.Title);
                    };
                    chapterToken.CreepFetched += (sender, e) =>
                    {
                        //this.LogWriter.WriteLine("{0}", e.Data);
                        writer.WriteLine(string.Format("  {0}", e.Data));
                    };
                    chapterToken.CreepFinished += (sender, e) =>
                    {
                        this.LogWriter.WriteLine("\t章节【{0}】获取完成。\n", chapterToken.Title);
                        writer.WriteLine();
                    };
                    chapterToken.StartCreep();
                }

                //this.LogWriter.WriteLine(sb.ToString());
            }
        }
예제 #9
0
        /// <summary>
        /// 寻找合适的书籍输出器。
        /// </summary>
        /// <param name="bookToken">书籍节点。</param>
        /// <returns>支持指定书籍节点的书籍输出器。</returns>
        /// <exception cref="NotSupportedException">未找到支持节点的小说下载插件。</exception>
        /// <exception cref="NotSupportedException">不支持的插件类型。</exception>
        protected internal IBookWriter FindBookWriterForBookToken(NDTBook bookToken)
        {
            NovelDownLoadPluginBookTokenAttribute attribute = bookToken.GetType().GetCustomAttribute <NovelDownLoadPluginBookTokenAttribute>(true);

            if (attribute == null)
            {
                throw new NotSupportedException("未找到支持节点的小说下载插件。");
            }

            // 获取已注册的插件实例。
            if (this.Plugins.TryGetValue(attribute.PluginGuid, out IPlugin plugin) && plugin is INovelDownloadPlugin ndPlugin)
            {
                if (!this.BookWriters.TryGetValue(ndPlugin.Guid, out IBookWriter bookWriter)) // 尝试从已注册的书籍输出器中寻找。
                {
                    // 指定插件未注册书籍输出器,采用默认书籍输出器。
                    if (ndPlugin is ILightNovelDownloadPlugin)
                    {
                        bookWriter = new LightNovelBookWriter();
                    }
                    else
                    {
                        bookWriter = new NormalBookWriter();
                    }
                }

                // 组装组件。
                var catalog   = new TypeCatalog(typeof(NovelDownloadPluginBase), typeof(BookWriterBase), typeof(PluginManager));
                var container = new CompositionContainer(catalog);
                container.ComposeParts(plugin, bookWriter, this);

                return(bookWriter);
            }
            else
            {
                throw new NotSupportedException("不支持的插件类型。");
            }
        }
예제 #10
0
 static async void download(NDTBook bookToken)
 {
     await manager.SaveToAsync(bookToken, @"downloads\");
 }
예제 #11
0
        private static void downloadLight(INovelDownloadPlugin plugin, NDTBook bookToken)
        {
            new Thread(() =>
            {
                Console.WriteLine("{0} - {1}", bookToken.Type, bookToken.Title);

                DirectoryInfo directory = new DirectoryInfo(process(bookToken.Title));
                bookToken.CreepStarted += (sender, e) =>
                {
                    Console.WriteLine("\t开始下载书籍《{0}》", bookToken.Title);

                    if (!directory.Exists)
                    {
                        directory.Create();
                    }
                };
                bookToken.CreepFetched  += (sender, e) => Console.WriteLine("\t获取 ({0})", e.Data);
                bookToken.CreepFinished += (sender, e) => Console.WriteLine("\t下载书籍《{0}》完成。", bookToken.Title);
                bookToken.StartCreep();
                foreach (NDTVolume volumeToken in bookToken.Children)
                {
                    FileInfo file             = new FileInfo(Path.Combine(directory.FullName, process(volumeToken.Title) + ".txt"));
                    StreamWriter writer       = null;
                    volumeToken.CreepStarted += (sender, e) =>
                    {
                        Console.WriteLine("\t\t开始下载卷({0})", volumeToken.Title);

                        writer = file.CreateText();
                    };
                    volumeToken.CreepFetched  += (sender, e) => Console.WriteLine("\t\t获取 【{0}】", e.Data);
                    volumeToken.CreepFinished += (sender, e) => Console.WriteLine("\t\t下载卷({0})完成。", volumeToken.Title);
                    volumeToken.StartCreep();

                    writer.WriteLine("[{0}][{1}][{2}]", bookToken.Author, bookToken.Title, volumeToken.Title);
                    writer.WriteLine();
                    writer.WriteLine("≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡");
                    writer.WriteLine();
                    writer.WriteLine("  书名:{0}", bookToken.Title);
                    writer.WriteLine("  作者:{0}", bookToken.Author);
                    writer.WriteLine("  来源:{0}", bookToken.Uri.Host);
                    writer.WriteLine();
                    writer.WriteLine("  本资源由小说下载插件 {0}({1}) v{2} 【{3}】 扫描提供。", plugin.DisplayName, plugin.Name, plugin.Version, plugin.Description);
                    writer.WriteLine();
                    writer.WriteLine("≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡");
                    writer.WriteLine();
                    writer.WriteLine();
                    writer.WriteLine(volumeToken.Title);
                    writer.WriteLine();
                    writer.Flush();
                    foreach (NDTChapter chapterToken in volumeToken.Children)
                    {
                        chapterToken.CreepStarted += (sender, e) =>
                        {
                            Console.WriteLine("\t\t\t开始下载章节【{0}】”", chapterToken.Title);
                            writer.WriteLine();
                            writer.WriteLine();
                            writer.WriteLine(chapterToken.Title);
                            writer.WriteLine();
                        };
                        chapterToken.CreepFetched += (sender, e) =>
                        {
                            writer.WriteLine("  {0}", e.Data);
                        };
                        chapterToken.CreepFinished += (sender, e) =>
                        {
                            Console.WriteLine("\t\t\t下载章节【{0}】完成。\n", chapterToken.Title);
                            writer.WriteLine();
                        };
                        chapterToken.StartCreep();
                    }

                    writer.Flush();
                    writer.Close();
                    writer.Dispose();
                }
            }).Start();
        }
예제 #12
0
        /// <summary>
        /// 提供输出书籍的实现。
        /// </summary>
        /// <param name="bookToken">书籍节点。</param>
        /// <param name="outputDir">输出目录。</param>
        protected override void WriteInternal(NDTBook bookToken, string outputDir)
        {
            this.LogWriter.WriteLine("{0} - {1}", bookToken.Type, bookToken.Title);
            DirectoryInfo book = null;

            bookToken.CreepStarted += (sender, e) =>
            {
                this.LogWriter.WriteLine("\t开始获取书籍《{0}》", bookToken.Title);

                // 创建书籍根目录。
                book = new DirectoryInfo(outputDir).CreateSubdirectory(bookToken.Title);
            };
            bookToken.CreepFetched  += (sender, e) => this.LogWriter.WriteLine("\t获取({0})", e.Data);
            bookToken.CreepFinished += (sender, e) => this.LogWriter.WriteLine("\t书籍《{0}》获取完成。", bookToken.Title);
            bookToken.StartCreep();
            foreach (NDTVolume volumeToken in bookToken.Children)
            {
                FileInfo     file   = new FileInfo(Path.Combine(book.FullName, volumeToken.Title + ".txt"));
                StreamWriter writer = null;
                volumeToken.CreepStarted += (sender, e) =>
                {
                    this.LogWriter.WriteLine("\t\t开始获取卷({0})", volumeToken.Title);

                    writer = file.CreateText();
                };
                volumeToken.CreepFetched  += (sender, e) => this.LogWriter.WriteLine("\t\t获取 【{0}】", e.Data);
                volumeToken.CreepFinished += (sender, e) => this.LogWriter.WriteLine("\t\t卷({0})获取完成。", volumeToken.Title);
                volumeToken.StartCreep();

                writer.WriteLine("[{0}][{1}][{2}]", bookToken.Author, bookToken.Title, volumeToken.Title);
                writer.WriteLine();
                writer.WriteLine("≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡");
                writer.WriteLine();
                writer.WriteLine("  书名:{0}", bookToken.Title);
                writer.WriteLine("  作者:{0}", bookToken.Author);
                writer.WriteLine("  来源:{0}", bookToken.Uri.Host);
                writer.WriteLine();
                writer.WriteLine("  本资源由小说下载插件 {0}({1}) v{2} 【{3}】 扫描提供。", this.Plugin.DisplayName, this.Plugin.Name, this.Plugin.Version, this.Plugin.Description);
                writer.WriteLine();
                writer.WriteLine("≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡");
                writer.WriteLine();
                writer.WriteLine();
                writer.WriteLine(volumeToken.Title);
                writer.WriteLine();
                writer.Flush();
                foreach (NDTChapter chapterToken in volumeToken.Children)
                {
                    chapterToken.CreepStarted += (sender, e) =>
                    {
                        this.LogWriter.WriteLine("\t\t\t开始下载章节【{0}】”", chapterToken.Title);
                        writer.WriteLine();
                        writer.WriteLine();
                        writer.WriteLine(chapterToken.Title);
                        writer.WriteLine();
                    };
                    chapterToken.CreepFetched += (sender, e) =>
                    {
                        writer.WriteLine("  {0}", e.Data);
                    };
                    chapterToken.CreepFinished += (sender, e) =>
                    {
                        this.LogWriter.WriteLine("\t\t\t章节【{0}】下载完成。\n", chapterToken.Title);
                        writer.WriteLine();
                    };
                    chapterToken.StartCreep();
                }

                writer.Flush();
                writer.Close();
                writer.Dispose();
            }
        }
예제 #13
0
 public void SaveTo(NDTBook bookToken, string outputDir)
 {
     this.manager.SaveTo(bookToken, outputDir);
 }
예제 #14
0
 public abstract bool TryGetBookToken(Uri uri, out NDTBook bookToken);
예제 #15
0
 /// <summary>
 /// 异步将书籍输出到文件。
 /// </summary>
 /// <param name="bookToken">书籍节点。</param>
 /// <param name="outputDir">输出目录。</param>
 public virtual Task WriteAsync(NDTBook bookToken, string outputDir)
 {
     return(Task.Run(() => Write(bookToken, outputDir)));
 }
예제 #16
0
 /// <summary>
 /// 子类提供输出书籍的实现。
 /// </summary>
 /// <param name="bookToken">书籍节点。</param>
 /// <param name="outputDir">输出目录。</param>
 protected abstract void WriteInternal(NDTBook bookToken, string outputDir);