{"id":28443136,"url":"https://github.com/tetr4lab/novels","last_synced_at":"2026-05-17T17:41:12.770Z","repository":{"id":295747783,"uuid":"990540184","full_name":"tetr4lab/Novels","owner":"tetr4lab","description":"Web小説からEPUBを生成しSendToKindleします","archived":false,"fork":false,"pushed_at":"2025-07-19T02:36:32.000Z","size":596,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-19T07:48:40.087Z","etag":null,"topics":["blazor","epub","smtp-mail","webscraping"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tetr4lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T09:13:57.000Z","updated_at":"2025-07-19T02:36:36.000Z","dependencies_parsed_at":"2025-06-29T10:23:28.961Z","dependency_job_id":"60dcce8c-94f7-45af-b150-53181ad3325d","html_url":"https://github.com/tetr4lab/Novels","commit_stats":null,"previous_names":["tetr4lab/novels"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tetr4lab/Novels","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetr4lab%2FNovels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetr4lab%2FNovels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetr4lab%2FNovels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetr4lab%2FNovels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tetr4lab","download_url":"https://codeload.github.com/tetr4lab/Novels/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetr4lab%2FNovels/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267057768,"owners_count":24028892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","epub","smtp-mail","webscraping"],"created_at":"2025-06-06T07:00:33.660Z","updated_at":"2026-05-17T17:41:12.712Z","avatar_url":"https://github.com/tetr4lab.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿---\r\ntitle: Web小説の取得と発行\r\ntags: epub webscraping smtp-mail blazor\r\n---\r\n\r\n# Web小説の取得と発行\r\n## はじめに\r\nこれは極めて個人的なプロジェクトです。\r\n実装がBlazor Serverになっていて、Blazor WASM+SQLiteのようなスタンドアロンアプリにしなかったのは、個人的な都合です。\r\n\r\n### 目的\r\nWeb小説を取得し、EPUBを生成して、Kindleパーソナルドキュメント向けに発行(Send To Kindle)します。\r\n\r\n#### 経緯\r\n元々、FileMakerとAozora Epub3で実現していたものをBlazorで置き換えました。\r\n\r\n### 環境\r\n#### ビルド\r\n- .NET 8.0\r\n  - Microsoft.AspNetCore.Authentication.Google 8.0.18\r\n  - Microsoft.AspNetCore.Authorization 8.0.18\r\n- MudBlazor 8.10.0\r\n- PetaPoco 6.0.683\r\n- MySqlConnector 2.4.0\r\n- [AngleSharp](https://github.com/AngleSharp/AngleSharp) 1.3.0\r\n  - The ultimate angle brackets parser library parsing HTML5, MathML, SVG and CSS to construct a DOM based on the official W3C specifications.\r\n- [MailKit](https://github.com/jstedfast/MailKit) 4.13.0\r\n  - A cross-platform .NET library for IMAP, POP3, and SMTP.\r\n- [QuickEPUB](https://github.com/tetr4lab/QuickEPUB/tree/feature/spine-page-progression)\r\n  - Feat: Implement page-progression-direction attribute for spine. Users can now define the reading direction (LTR or RTL) within the spine element of the EPUB.\r\n- [Tetr4labNugetPackages](https://github.com/tetr4lab/Tetr4labNugetPackages)\r\n\r\n#### サーバ\r\n\r\nhttps://zenn.dev/tetr4lab/articles/ad947ade600764\r\n\r\nhttps://zenn.dev/tetr4lab/articles/3fb1d4e8e7ff21\r\n\r\n#### その他\r\n##### メールサーバ\r\nさくらインターネット (TLS, SMTP認証)\r\n\r\n##### ブラウザ\r\nGoogle Chrome\r\n\r\n##### 認証\r\n\r\nhttps://zenn.dev/tetr4lab/articles/1946ec08aec508\r\n\r\n## できること\r\n- Web小説の取得・更新 (なろう、ノクターン、カクヨム、ノベルアップ他)\r\n- 小説内容の確認、各種メモ、文字校正\r\n- EPUBの生成、取得\r\n- Kindleパーソナルドキュメント向け送信\r\n\r\n## データ構造\r\n### 論理構成\r\n- 書誌\r\n  - 書誌と目次\r\n- シート\r\n  - 発表単位の本文\r\n- 設定\r\n  - 取得設定、発行設定\r\n\r\n### テーブルスキーマ\r\n\r\n\u003cdetails\u003e\u003csummary\u003esql\u003c/summary\u003e\r\n\r\n```sql:MariaDB\r\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\r\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\r\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\r\n/*!40101 SET NAMES utf8mb4 */;\r\n/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\r\n/*!40103 SET TIME_ZONE='+00:00' */;\r\n/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\r\n/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\r\n/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\r\n/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\r\n\r\n--\r\n-- Table structure for table `books`\r\n--\r\n\r\nDROP TABLE IF EXISTS `books`;\r\n/*!40101 SET @saved_cs_client     = @@character_set_client */;\r\n/*!40101 SET character_set_client = utf8 */;\r\nCREATE TABLE `books` (\r\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\r\n  `version` int(11) NOT NULL DEFAULT 0,\r\n  `created` datetime NOT NULL DEFAULT current_timestamp(),\r\n  `creator` varchar(50) NOT NULL DEFAULT '',\r\n  `modified` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\r\n  `modifier` varchar(50) NOT NULL DEFAULT '',\r\n  `url1` varchar(255) NOT NULL DEFAULT '',\r\n  `url2` varchar(255) NOT NULL DEFAULT '',\r\n  `html` longtext DEFAULT NULL,\r\n  `site` int(11) NOT NULL DEFAULT 0,\r\n  `title` varchar(255) DEFAULT NULL,\r\n  `author` varchar(255) DEFAULT NULL,\r\n  `number_of_published` int(20) DEFAULT NULL,\r\n  `published_at` datetime DEFAULT NULL,\r\n  `read` bit(1) NOT NULL DEFAULT b'0',\r\n  `memorandum` varchar(255) DEFAULT NULL,\r\n  `status` varchar(50) NOT NULL DEFAULT '',\r\n  `html_backup` longtext DEFAULT NULL,\r\n  `errata` longtext DEFAULT NULL,\r\n  `wish` bit(1) NOT NULL DEFAULT b'0',\r\n  `bookmark` bigint(20) DEFAULT NULL,\r\n  `remarks` varchar(255) DEFAULT NULL,\r\n  PRIMARY KEY (`id`) USING BTREE\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;\r\n/*!40101 SET character_set_client = @saved_cs_client */;\r\n/*!50003 SET @saved_cs_client      = @@character_set_client */ ;\r\n/*!50003 SET @saved_cs_results     = @@character_set_results */ ;\r\n/*!50003 SET @saved_col_connection = @@collation_connection */ ;\r\n/*!50003 SET character_set_client  = utf8mb4 */ ;\r\n/*!50003 SET character_set_results = utf8mb4 */ ;\r\n/*!50003 SET collation_connection  = utf8mb4_general_ci */ ;\r\n/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;\r\n/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;\r\nDELIMITER ;;\r\n/*!50003 CREATE*/ /*!50003 TRIGGER `version_check_before_update_on_books` BEFORE UPDATE ON `books` FOR EACH ROW begin\r\n    if new.version \u003c= old.version then\r\n        signal SQLSTATE '45000'\r\n        set MESSAGE_TEXT = 'Version mismatch detected.';\r\n    end if;\r\nEND */;;\r\nDELIMITER ;\r\n/*!50003 SET sql_mode              = @saved_sql_mode */ ;\r\n/*!50003 SET character_set_client  = @saved_cs_client */ ;\r\n/*!50003 SET character_set_results = @saved_cs_results */ ;\r\n/*!50003 SET collation_connection  = @saved_col_connection */ ;\r\n\r\n--\r\n-- Table structure for table `settings`\r\n--\r\n\r\nDROP TABLE IF EXISTS `settings`;\r\n/*!40101 SET @saved_cs_client     = @@character_set_client */;\r\n/*!40101 SET character_set_client = utf8 */;\r\nCREATE TABLE `settings` (\r\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\r\n  `version` int(11) NOT NULL DEFAULT 0,\r\n  `created` datetime NOT NULL DEFAULT current_timestamp(),\r\n  `creator` varchar(50) NOT NULL DEFAULT '',\r\n  `modified` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\r\n  `modifier` varchar(50) NOT NULL DEFAULT '',\r\n  `personal_document_limit_size` int(11) NOT NULL DEFAULT 0,\r\n  `smtp_mailaddress` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_server` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_port` int(11) NOT NULL DEFAULT 25,\r\n  `smtp_username` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_password` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_mailto` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_cc` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_bcc` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_subject` varchar(255) NOT NULL DEFAULT '',\r\n  `smtp_body` varchar(255) NOT NULL DEFAULT '',\r\n  `user_agent` VARCHAR(255) NOT NULL DEFAULT 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko',\r\n  `access_interval_time` INT(11) NOT NULL DEFAULT 1000,\r\n  `default_cookies` LONGTEXT NOT NULL DEFAULT '{ \"over18\": \"yes\" }',\r\n  `include_image` bit(1) NOT NULL DEFAULT b'0',\r\n  `remarks` varchar(255) DEFAULT NULL,\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;\r\n/*!40101 SET character_set_client = @saved_cs_client */;\r\n/*!50003 SET @saved_cs_client      = @@character_set_client */ ;\r\n/*!50003 SET @saved_cs_results     = @@character_set_results */ ;\r\n/*!50003 SET @saved_col_connection = @@collation_connection */ ;\r\n/*!50003 SET character_set_client  = utf8mb4 */ ;\r\n/*!50003 SET character_set_results = utf8mb4 */ ;\r\n/*!50003 SET collation_connection  = utf8mb4_general_ci */ ;\r\n/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;\r\n/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;\r\nDELIMITER ;;\r\n/*!50003 CREATE*/ /*!50003 TRIGGER `version_check_before_update_on_settings` BEFORE UPDATE ON `settings` FOR EACH ROW begin\r\n    if new.version \u003c= old.version then\r\n        signal SQLSTATE '45000'\r\n        set MESSAGE_TEXT = 'Version mismatch detected.';\r\n    end if;\r\nEND */;;\r\nDELIMITER ;\r\n/*!50003 SET sql_mode              = @saved_sql_mode */ ;\r\n/*!50003 SET character_set_client  = @saved_cs_client */ ;\r\n/*!50003 SET character_set_results = @saved_cs_results */ ;\r\n/*!50003 SET collation_connection  = @saved_col_connection */ ;\r\n\r\n--\r\n-- Table structure for table `sheets`\r\n--\r\n\r\nDROP TABLE IF EXISTS `sheets`;\r\n/*!40101 SET @saved_cs_client     = @@character_set_client */;\r\n/*!40101 SET character_set_client = utf8 */;\r\nCREATE TABLE `sheets` (\r\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\r\n  `version` int(11) NOT NULL DEFAULT 0,\r\n  `created` datetime NOT NULL DEFAULT current_timestamp(),\r\n  `creator` varchar(50) NOT NULL DEFAULT '',\r\n  `modified` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\r\n  `modifier` varchar(50) NOT NULL DEFAULT '',\r\n  `book_id` bigint(20) NOT NULL,\r\n  `url` varchar(255) NOT NULL DEFAULT '',\r\n  `html` longtext DEFAULT NULL,\r\n  `sheet_update` datetime DEFAULT NULL,\r\n  `novel_no` INT(20) NOT NULL DEFAULT 0,\r\n  `errata` longtext DEFAULT NULL,\r\n  `remarks` varchar(255) DEFAULT NULL,\r\n  PRIMARY KEY (`id`) USING BTREE,\r\n  CONSTRAINT `fk_bookid_books_id` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;\r\n/*!40101 SET character_set_client = @saved_cs_client */;\r\n/*!50003 SET @saved_cs_client      = @@character_set_client */ ;\r\n/*!50003 SET @saved_cs_results     = @@character_set_results */ ;\r\n/*!50003 SET @saved_col_connection = @@collation_connection */ ;\r\n/*!50003 SET character_set_client  = utf8mb4 */ ;\r\n/*!50003 SET character_set_results = utf8mb4 */ ;\r\n/*!50003 SET collation_connection  = utf8mb4_general_ci */ ;\r\n/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;\r\n/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;\r\nDELIMITER ;;\r\n/*!50003 CREATE*/ /*!50003 TRIGGER `version_check_before_update_on_sheets` BEFORE UPDATE ON `sheets` FOR EACH ROW begin\r\n    if new.version \u003c= old.version then\r\n        signal SQLSTATE '45000'\r\n        set MESSAGE_TEXT = 'Version mismatch detected.';\r\n    end if;\r\nEND */;;\r\nDELIMITER ;\r\n/*!50003 SET sql_mode              = @saved_sql_mode */ ;\r\n/*!50003 SET character_set_client  = @saved_cs_client */ ;\r\n/*!50003 SET character_set_results = @saved_cs_results */ ;\r\n/*!50003 SET collation_connection  = @saved_col_connection */ ;\r\n/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\r\n\r\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\r\n/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\r\n/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\r\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\r\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\r\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\r\n/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n## 画面と機能\r\n当初、複数ページで作成したものをSPA化したので、名残があります。\r\n\r\n![](ScreenShot.png)\r\n\r\n### 構成\r\n- 共通: 上部ナビゲーションバー\r\n  - ページ切り替え、検索、テーマ切り替え\r\n- ページ\r\n  - Books(ホーム)\r\n    - 書誌一覧、新規作成\r\n  - Issue\r\n    - 書誌編集、校正、取得・更新、発行、削除\r\n  - Contents\r\n    - シート一覧\r\n  - Read\r\n    - シート閲覧、校正\r\n  - Settings\r\n    - 設定\r\n\r\n## おわりに\r\nお読みいただきありがとうございました。\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetr4lab%2Fnovels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftetr4lab%2Fnovels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetr4lab%2Fnovels/lists"}