On the Last Day of 2025, Sharing the Ebook Conversion Tool Website I Built with Go
Fed up with conversion tools plastered with ads, I casually wrapped a CLI tool in a Go-Gin shell. I just wanted some peace and quiet, but these people crashed my server outright, so I've been forced to take it down for now. The code is dumped on GitHub—don't expect me to go fix that unfinished login feature.
目录7 个章节
Preface
A web-based novel conversion tool that supports converting txt files to ebook formats such as epub, mobi, and azw3
I actually built this project in August this year and never shared it.
When I was looking for a tool to convert txt ebooks to EPUB, a lot of them had ads. I found a Go CLI tool on GitHub: kaf-cli. It worked pretty well, but having to type commands every time was a bit of a hassle, so I turned it into a website with go-gin to make it more convenient.
I posted it in a reading group, and quite a few people have been using it.
But recently this website has overwhelmed my server, so I've been forced to take it down.
This post is a brief share of the website, as a wrap-up for 2025~
This project also spawned an internationalization feature implemented with Alpine.js.
This project is forked from ystyle/kaf-cli. On top of keeping the original CLI functionality, it adds a visual web interface for a more convenient experience.
Project URL: https://github.com/Deali-Axy/ebook-generator
Main Features
🌐 Web Features
- 📁 File upload: Supports txt file uploads, up to 50MB
- 🔄 Format conversion: Supports converting to epub, mobi, and azw3 formats
- 📊 Real-time progress: View conversion progress in real time via SSE
- 📥 File download: Download the ebook file after conversion completes
- 🗑️ Auto cleanup: Supports manually cleaning up temporary files
- 📖 API docs: Integrated Swagger UI for easy debugging
- 🎨 Visual interface: A simple, easy-to-use HTML interface
📚 Conversion Features
- Automatically detect book title and chapters
- Automatically detect character encoding (fixes Chinese garbled text)
- Custom chapter title detection rules
- Custom volume title detection rules
- Automatically generate bold, centered titles for chapter bodies
- Automatic paragraph detection and indentation
- Support for generating Orly-style book covers
- Automatically extract title and author from Zhixuan Cangshu-format filenames
- Ultra-fast conversion (epub generation at 300+ chapters/s)
Screenshots
Home page

Conversion progress and download

Web code
I'll just paste some of the code. I actually also built login and registration, but there were bugs, so I didn't wire them up on the frontend~
// main 启动Web服务
func main() {
// 设置Gin模式
if os.Getenv("GIN_MODE") == "" {
gin.SetMode(gin.DebugMode)
}
// 初始化服务管理器
serviceManager, err := initServiceManager()
if err != nil {
log.Fatal("初始化服务管理器失败:", err)
}
// 启动所有服务
if err := serviceManager.Start(); err != nil {
log.Fatal("启动服务失败:", err)
}
// 设置优雅关闭
defer func() {
if err := serviceManager.Stop(); err != nil {
log.Printf("停止服务时出错: %v", err)
}
}()
// 初始化Web服务相关组件
initWebServices(serviceManager)
// 创建Gin引擎
r := gin.Default()
// 初始化SEO服务
seoService := initSEOService()
// 添加中间件
r.Use(middleware.CORS())
r.Use(middleware.Logger())
r.Use(middleware.Recovery())
r.Use(middleware.AddSecurityHeaders())
r.Use(middleware.AddCacheHeaders())
r.Use(middleware.SEOMiddleware(seoService))
// 设置文件上传大小限制 (50MB)
r.MaxMultipartMemory = 50 << 20
// API路由组
api := r.Group("/api")
{
// 基础转换功能
api.POST("/upload", handlers.UploadFile)
api.POST("/convert", handlers.ConvertBook)
api.GET("/status/:taskId", handlers.GetTaskStatus)
api.GET("/download/:fileId", handlers.DownloadFile)
api.DELETE("/cleanup/:taskId", handlers.CleanupTask)
api.GET("/events/:taskId", handlers.GetTaskEvents)
// 用户认证相关路由
auth := api.Group("/auth")
{
auth.POST("/register", handlers.Register)
auth.POST("/login", handlers.Login)
auth.GET("/profile", handlers.AuthMiddleware(), handlers.GetProfile)
auth.PUT("/profile", handlers.AuthMiddleware(), handlers.UpdateProfile)
auth.POST("/logout", handlers.AuthMiddleware(), handlers.Logout)
auth.POST("/refresh", handlers.AuthMiddleware(), handlers.RefreshToken)
auth.PUT("/password", handlers.AuthMiddleware(), handlers.ChangePassword)
}
// 转换历史相关路由(需要认证)
history := api.Group("/history")
history.Use(handlers.AuthMiddleware())
{
history.GET("", handlers.GetHistories)
history.GET("/stats", handlers.GetHistoryStats)
history.DELETE("/:id", handlers.DeleteHistory)
}
// 转换预设相关路由(需要认证)
presets := api.Group("/presets")
presets.Use(handlers.AuthMiddleware())
{
presets.POST("", handlers.CreatePreset)
presets.GET("", handlers.GetPresets)
presets.GET("/:id", handlers.GetPreset)
presets.PUT("/:id", handlers.UpdatePreset)
presets.DELETE("/:id", handlers.DeletePreset)
}
// 批量转换相关路由(需要认证)
batch := api.Group("/batch")
batch.Use(handlers.AuthMiddleware())
{
batch.POST("/convert", handlers.BatchConvert)
}
}
// 集成Swagger文档
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// 静态文件服务
r.Static("/static", "./web/static")
r.StaticFile("/", "./web/static/index.html")
r.StaticFile("/demo", "./web/static/index.html")
// SEO相关文件 - 动态生成
r.GET("/sitemap.xml", handlers.GenerateSitemap)
r.GET("/robots.txt", handlers.GenerateRobotsTxt)
// SEO状态监控
seo := r.Group("/seo")
{
seo.GET("/status", handlers.GetSEOStatus)
}
// 健康检查接口
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// 启动服务
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Printf("服务启动在端口: %s", port)
log.Printf("Swagger文档地址: http://localhost:%s/swagger/index.html", port)
if err := r.Run(":" + port); err != nil {
log.Fatal("启动服务失败:", err)
}
}
Wrap-up
That's all for now. It's getting late—happy New Year everyone~
_EOF_
On the Last Day of 2025, Sharing the Ebook Conversion Tool Website I Built with Go
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
使用go语言开发自动化API测试工具
这个工具我使用了 go 语言开发,主要是考虑到了 go 语言可以傻瓜式的实现交叉编译,生成的可执行文件直接上传到服务器就可以执行,非常方便。
2024-03-08 · Go · 约 1 分钟
使用go语言开发hive导出工具
作者弃bash、Python、C#,选Go写Hive导出工具,只因部署简单。Go的err处理烦人,但交叉编译省事。工具交互式,搞定导出。
2023-10-17 · Go · 约 1 分钟
当 CGO 遇见 Zig:一种更优雅的折腾方式,对比 GCC 后端
“GCC 赢了跑分,但 Zig 赢了人生。” (GCC wins the benchmark, but Zig wins the DX/Developer Experience.) Windows下cgo编译器从gcc换到zig?GCC快但环境配置可能比较麻烦,zig单文件轻量但编译慢且首跑延迟离谱。性能差距大吗?或许吧,但开发效率的提升值得折腾。
2026-04-14 · Go · 约 1 分钟
编写爬虫下载公众号上好看的壁纸
很多年前我还在大学的时候,曾经写过一篇类似的文章,不过当时是采集某游戏官网上好看的壁纸。 最近微信公众号总是给我推荐各种壁纸,里面有不少好看的,不过一张张保存太麻烦了,索性写个爬虫自动下载。
2025-01-20 · 爬虫 · 约 1 分钟
讨论
共 0 条加载评论中…