基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传
前言
九月太忙,只更新了三篇文章,本来这个功能是从九月初就开始做的,结果一直拖到现在国庆假期才有时间完善并且写文章~
之前我更新了几篇关于 Python 的文章,有朋友留言问是不是不更新 .Net 了,那肯定不能啊,我只能说「我 全 都 要」,所以我反手就更新了一篇Asp-Net-Core开发笔记。
然后顺便立个Flag:今年底前完成StarBlog系列文章的主体部分(即API开发+后台前端开发,目前只完成博客前后端部分),加油吧~
OK,说回本文,程序员都喜欢用Markdown来写文章,但由于markdown是纯文本格式,在其中插入的图片要如何保存,就成了一大烦恼,有人选择图床,但不一定永久有效;有人选择本地存储,图片永久有效,但如何分享文章又成了一个难题…
我选的就是第二种,本地存储。使用Typora写文章,图片保存在和Markdown文件同名的目录(markdown.assets)下,这样可以获得很好的写作体验,然后分享的问题就交给StarBlog吧,这个项目开发的初衷就是为了把本地的文章发表成博客。
不过之前只有批量导入文章的功能,现在我要做的就是单独实现一个单篇文章打包导入的功能。
随着文章越来越多,系列文章的目录放前面有点影响阅读了,所以从这篇开始我把它放到最后面~
实现思路
假设我用Typora写了一篇Markdown文章,文件名为:StarBlog.md,并且在里面插入了若干图片,根据配置,Typora会自动生成一个目录(StarBlog.assets)来存放这些图片。
为了实现导入,我要把这个markdown文件和这个存图片的目录一起打包成zip压缩文件上传,后端将zip压缩包解压到临时目录,读取Markdown文件,解析其中的内容,进行导入操作。
代码实现
OK,开始写代码吧
同时所有项目代码已经上传GitHub,欢迎各位大佬Star/Fork!
- 博客后端+前台项目地址:https://github.com/Deali-Axy/StarBlog
- 管理后台前端项目地址:https://github.com/Deali-Axy/StarBlog-Admin
解压缩
首先是解压缩功能,.Net标准库自带 ZipFile 这个库用于操作zip压缩包,在 System.IO.Compression 里,直接用就完事了。
解压前得先把文件复制到临时目录,并创建一个新的临时目录来放解压后的文件。
在 Services/BlogServices.cs 里新增代码
public async Task<Post> Upload(PostCreationDto dto, IFormFile file) {
// 先复制到临时文件
var tempFile = Path.GetTempFileName();
await using (var fs = new FileStream(tempFile, FileMode.Create)) {
await file.CopyToAsync(fs);
}
// 设定解压用的临时目录
var extractPath = Path.Combine(Path.GetTempPath(), "StarBlog", Guid.NewGuid().ToString());
// 使用 GBK 编码解压,防止中文文件名乱码
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
ZipFile.ExtractToDirectory(tempFile, extractPath, Encoding.GetEncoding("GBK"));
}
本来直接 ZipFile.ExtractToDirectory() 就能解压了,但如果压缩包里的文件用了中文名,就得先设置编码。
解析Markdown
关于 C# 解析 Markdown ,在本系列一开始就写过,所以这里就不再当复读机了,可以直接看这两篇文章:
直接上代码了
因为是做单篇文章导入,所以我这里获取临时目录写的所有 *.md 文件之后只取第一个文件来处理(理论上也不应该有多个~)
var dir = new DirectoryInfo(extractPath);
var files = dir.GetFiles("*.md");
var mdFile = files.First();
using var reader = mdFile.OpenText();
var content = await reader.ReadToEndAsync();
var post = new Post {
Id = GuidUtils.GuidTo16String(),
Status = "已发布",
Title = dto.Title ?? $"{DateTime.Now.ToLongDateString()} 文章",
IsPublish = true,
Content = content,
Path = "",
CreationTime = DateTime.Now,
LastUpdateTime = DateTime.Now,
CategoryId = dto.CategoryId,
};
var assetsPath = Path.Combine(_environment.WebRootPath, "media", "blog");
var processor = new PostProcessor(extractPath, assetsPath, post);
// 处理文章标题和状态
processor.InflateStatusTitle();
// 处理文章正文内容
// 导入文章的时候一并导入文章里的图片,并对图片相对路径做替换操作
post.Content = processor.MarkdownParse();
post.Summary = processor.GetSummary(200);
Markdown相关的处理,我封装了 PostProcessor 这个对象,在 StarBlog.Share 里。
处理多级分类
如果文章的分类不是一级分类,那么把它上面的所有分类找出来,一个个排好队,方便后面处理。
// 处理多级分类
var category = await _categoryRepo.Where(a => a.Id == dto.CategoryId).FirstAsync();
if (category == null) {
post.Categories = "0";
}
else {
var categories = new List<Category> {category};
var parent = category.Parent;
while (parent != null) {
categories.Add(parent);
parent = parent.Parent;
}
categories.Reverse();
post.Categories = string.Join(",", categories.Select(a => a.Id));
}
最后保存
搞定~
// 存入数据库
post = await _postRepo.InsertAsync(post);
系列文章
- 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?
- 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
- 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
- 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
- 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示
- 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入
- 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流
- 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计
- 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
- 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能
- 基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片
- 基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)
- 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片
- 基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传
参考资料
基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传的更多相关文章
- 基于.NetCore开发博客项目 StarBlog - (19) Markdown渲染方案探索
前言 笔者认为,一个博客网站,最核心的是阅读体验. 在开发StarBlog的过程中,最耗时的恰恰也是文章的展示部分功能. 最开始还没研究出来如何很好的使用后端渲染,所以只能先用Editor.md组件做 ...
- 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 ... 基于. ...
- 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
随机推荐
- static关键字和代码块
static关键字 static修饰的变量称为静态变量/共享变量/类变量 用于修饰类的成员,如成员变量.成员方法以及代码块等,内static修饰的成员具备一些特殊性 1.静态变量 在java类中使用s ...
- python jinjia2 高级
高层api class jinja2.Environment([options]) Enviroment:环境,是Jinjia2的核心组件,它包含重要的共享变量,如配置.过滤器.测试.全局变量.模板加 ...
- python常用功能模块
路径相关:os.pathlib Windows注册表相关:winreg 系统cpu.内存.线程相关:psutil 文件.文件夹处理:shutil 解析和生成ini文件:ConfigParser:(co ...
- css基础02
熟练快捷键!方便,要多练! css复合选择器 不会选孙子,有一个儿子和另一个儿子的孩子(也是孙子)同名了,但子选择器子选择儿子,同名的孙子不选.和后代选择器有一点不一样的. " ,&quo ...
- MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL
MYSQL(进阶篇)--一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL 温馨提醒:该文章大 ...
- 解析MySQL存储过程的游标执行过程
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 内容提纲 一.测试环境搭建 二.执行过程解析 三.注意事项 一.测试环境搭建 首先创建一张表,并插入几行数据字段: CRE ...
- Apache DolphinScheduler 源码剖析之 Worker 容错处理流程
今天给大家带来的分享是 Apache DolphinScheduler 源码剖析之 Worker 容错处理流程 DolphinScheduler源码剖析之Worker容错处理流程 Worker容错流程 ...
- Python自学教程2:大牛们怎么写注释
在还没开始学代码前,就要先学会写注释.不会写注释的程序员会遭到鄙视和唾弃,甚至在工作中会被人穿小鞋.注释也不是随便写一下就行,用好注释还是有点讲究的. 注释有什么用? 注释(Comments)主要是向 ...
- C# Hashtable VS. Dictionary 性能对比
Hashtable VS Dictionary 因为Hashtable的Key和Value都是object类型,所以在使用值类型的时候,必然会出现装箱和拆箱的操作,因此性能肯定是不如Dictionar ...
- 记录一次数据库CPU被打满的排查过程
1 前言 近期随着数据量的增长,数据库CPU使用率100%报警频繁起来.第一个想到的就是慢Sql,我们对未合理运用索引的表加入索引后,问题依然没有得到解决,深入排查时,发现在 order by id ...