Python三百行代码实现一简约个人博客网站(全网最小巧)

这是全互联网最小巧的博客,没有比这更小的了。虽然小巧,但功能一点儿也不弱,支持文章的分页展示,文章表格,图片和代码语法高亮。文章无限制分类,访问量统计,按时间和按点击量排序,展示最新文章,最热文章,文章留言评论等功能。

前言

如果你也想拥有一个属于自己的个性博客,这种尝试将大幅降低准入门槛,让你看到实现一个个人博客网站是多么的简单。其它的又是建库建表的,或是需要登录管理后台管理,我还是觉得不够简单好用。

用这种写好的markdown文档的形式,你可以直接把markdown笔记变成动态的博客展示出来。后续可基于微信小程序做个入口,如果想要发布文章,则直接把编写好的markdown文件提交发送过去就可以啦,操作使用上更加简单和快捷。这才应该是现在博客该有的特色和创新,原有的旧的登录网站后台编辑和使用的方式,太落后了。

况且使用这种方式还有个好处,可以方便多人同时使用。比如可以在公司内部搭建一个公共博客平台,做个简单入口界面,让每个人都可以往上面提交文档,这也是个不错的内部方案交流平台和技术分享平台。相比传统word文档的方式优点很多,方便文档的查看、归档和线上展示及分享,连留言评论都有啦。

项目开源地址:

tiny-blog: 极小的个人博客,虽然很小,但是很全。使用python+flask+html实现。

体验地址:

我的个人博客

实现原理

其实就是一个基于markdown的轻量级博客,需要按一定格式编写好markdown文件,提交到后台服务。当用户访问网页时由后台读取文件内容并经由流行的markdown-it组件渲染。

后台使用python的flask框架,整个代码仅三百多行。相当的小巧,很容易根据需要修改源码去增加一些其他的功能。当然一个css或js文件都不可能这么短,这里仅指的是后台代码。网页使用了流行的markdown-it(MarkDown渲染),highlight.js(语法高亮)和mermaid.js(画流程图、时序图等的js库)组件。留言评论功能,使用比较火的Valine博客评论系统。

网站模板我是从素材火网站上找了一个好看的博客网站模板。如果你有中意的其他博客网站模板,也可以很容易的改造过来用。文末介绍和分享几个好看的博客模板。

效果展示:

Flask介绍

Flask是一个轻量级的Python Web框架,用于构建Web应用程序和API。它基于Werkzeug工具箱和Jinja2模板引擎,并且具有灵活性和可扩展性。

Flask提供了一些基本的功能,例如路由、请求和响应处理、会话管理等,同时支持各种扩展,可以轻松添加身份验证、数据库集成、邮件发送等功能。由于其简单的学习曲线和活跃的社区支持,Flask已成为最受欢迎的Python Web框架之一。

源码实现

源码实现很简单,仅有三个文件,总代码量三百多行。为了提高访问速度,设计了一种基于字典map的简单数据结构。只有应用启动时加载一次文件,后续文章访问直接从字典数据中取数据,避免每次访问都读文件,提高访问效率。为了方便的查看数据结构,加载完文件后保存了几个json格式的文件。通过json文件很容易看出来。

main.py

# encoding: utf-8
# author:yangyongzhen
from flask import  Flask,render_template,request,redirect
import articles
import atexit
import json
import sysapp=Flask(__name__,template_folder="templates", static_folder="static", static_url_path="/static")# 首页
@app.route('/')
def index():articles.Stat.totalVisit += 1page = 1page = request.args.get('page',1,int)print(page)nums = len(articles.AllArts)print(nums)allpage = nums / 5if nums %5 != 0:allpage = int(nums/5) + 1print(allpage)curArts = articles.AllArtsif (page * 5) < nums :curArts = articles.AllArts[(page-1)*5 : page*5]else:curArts = articles.AllArts[(page-1)*5 : nums]#分页表tabs = []for i in range(0,allpage):print(i)tabs.append(i)print(tabs)return render_template("index.html",arts=curArts,news=articles.NewArts[:9],hots=articles.HotArts[:9],items=articles.ItemList,curPage=page,tab=tabs)  #加入变量传递@app.route('/about')
def about():msg="my name is caojianhua, China up!"return render_template("about.html",data=msg)  #加入变量传递#分类页
@app.route('/items')
def items():try:id = request.args.get('id')print(id)allArts = []allMaps = articles.ItemMap[id]#遍历 hashfor v in allMaps.values():allArts.append(v) #按日期排序allArts.sort(key=lambda x: x['date'],reverse=True)#print(allArts)page = 1page = request.args.get('page',1,int)print(page)nums = len(allArts)print(nums)allpage = int(nums / 5)if nums %5 != 0:allpage = int(nums/5) + 1print(allpage)curArts = allArtsif (page * 5) < nums :curArts = allArts[(page-1)*5 : page*5]else:curArts = allArts[(page-1)*5 : nums]#分页表tabs = []for i in range(0,allpage):#print(i)tabs.append(i)#print(tabs)return render_template("items.html",arts=curArts,item=id,news=articles.NewArts[:9],hots=articles.HotArts[:9],curPage=page,tab=tabs) except Exception as e:print("Exception occured")print(e)return render_template('404.html')# 文章详情页
@app.route('/article_detail')
def article_detail():art = articles.Article("","","","","","","","",0,0)item_index = 0try:id = request.args.get('id')#print(id)#取出分类item = articles.ArtRouteMap[id]['item']print(item)art = articles.ItemMap[item][id]  #art_index  = NewPosts.index(id)articles.Stat.artStat[id]['visitCnt'] += 1articles.Stat.totalVisit += 1articles.ItemMap[item][id]['visitCnt'] = articles.Stat.artStat[id]['visitCnt']#print(art)#print(item_index)#print(art_index)return render_template("article_detail.html",data=art,news=articles.NewArts[:9],hots=articles.HotArts[:9] ) except Exception as e:print("Exception occured")return render_template('404.html')# 说说页面  
@app.route('/moodList')
def moodList():msg="my name is caojianhua, China up!"return render_template("moodList.html",data=msg) # 留言页面 
@app.route('/comment')
def comment():msg="my name is caojianhua, China up!"return render_template("comment.html",data=msg) @app.route('/404')
def error_404():print("error_404")return render_template("404.html") @app.errorhandler(404)
def page_not_found(e):print("page_not_found")print(e)return render_template('404.html'), 404@app.errorhandler(Exception)
def handle_exception(e):# 捕获其他异常print("handle_exception")print(e)return render_template('404.html'), 500def saveData():#保存访问量数据       with open('statistic.json1', 'w',encoding='utf-8') as f:json.dump(articles.Stat.__dict__, f,ensure_ascii=False)# 监控退出时保存统计信息
@atexit.register
def exit_handler():print("应用程序退出")saveData()if __name__=="__main__":#启动时加载访问量数据articles.getPosts()app.run(port=8000,host="127.0.0.1",debug=False)print("over")

articles.py

# encoding: utf-8
# author:yangyongzhen
import glob
import os
import pprint
import hashlib
import json
import statistic#访问量阅读量统计信息
Stat = statistic.AllStat()# AllArts 总的文章,(按时间排过序的)
AllArts = []
# NewArts 最新文章
NewArts = []
# HotArts 热门文章
HotArts = []
# 文章分类信息
ItemList = []ItemMap = {}
ArtRouteMap = {}#文章信息类定义
class Article(object):def __init__(self, id, item, title, date, summary, body, imgFile, author, cmtCnt, visitCnt):self.id = idself.item = itemself.title = titleself.date = dateself.summary = summaryself.body = bodyself.imgFile = imgFileself.author = authorself.cmtCnt = cmtCntself.visitCnt = visitCntdef mPrint(self):print(self.id)print(self.item)print(self.title)print(self.date)print(self.summary)print(self.body)print(self.imgFile)print(self.author)class ArticlesData():def __init__(self):self.item = ""self.articlesMap = {}# ArticleRoute 文章的分类和路径信息
class ArticleRoute:def __init__(self, item, name):self.item = itemself.name = name#文章分类 是个集合类型,无重复元素
class ItemCfg:def __init__(self):self.items = set()def strTrip(src):str = src.replace(" ", "")str = str.replace("\r", "")str = str.replace("\n", "")return str#从文件中读取信息,并返回itemMap,artRouteMap,items
def getPosts():global ItemMap,ArtRouteMap,ItemList,NewArts# 打开访问量统计JSON文件并读取内容with open('statistic.json1', 'r',encoding='utf-8') as file:json_data = file.read()# 将JSON字符串反序列化为字典对象Stat.__dict__ = json.loads(json_data)print(Stat.totalVisit)# 获取"posts/"目录下的所有文件files = glob.glob("posts/*")# 按修改日期进行排序files = sorted(files, key=lambda x: os.path.getmtime(x))articleMap = {}itemMap = {}artRouteMap = {}#文章分类,是个集合类型,无重复items = set()# 遍历文件列表for i, f in enumerate(files):#print(i)#print(f)file = ffile = os.path.basename(file) # 转换路径分隔符print(file)file = os.path.splitext(file)[0]  # 移除".md"后缀fileread = open(f, 'r',encoding='utf-8').read()lines = fileread.split('\n')#print(lines)title = lines[0].strip()date = strTrip(lines[1].strip())summary = lines[2].strip()imgfile = lines[3].strip()id = hashlib.md5(file.encode(encoding='UTF-8'))id = id.hexdigest()#print(id.hexdigest())item = strTrip(lines[4].strip())author = lines[5].strip()imgfile = strTrip(imgfile)body = '\n'.join(lines[6:])  # 获取第6行及以后的行ar = ArticleRoute(item, title)artRouteMap[id] = ar.__dict__visitCnt = 0if id in Stat.artStat:visitCnt = Stat.artStat[id]['visitCnt']#print(visitCnt)else:Stat.artStat[id] = statistic.ArtStat(title,visitCnt,0).__dict__post = Article(id,item,title, date, summary, body, imgfile, author, 0,visitCnt)articleMap[id] = postitems.add(item)#json_data = json.dumps(posts,ensure_ascii=False)#print(json_data)itemList = []for itm in items:itmMp= {}for v in articleMap.values():if(v.item == itm):itmMp[v.id] = v.__dict__itemMap[itm] = itmMpitemList.append(itm)#保存为json文件with open('Articles.json1', 'w',encoding='utf-8') as f:json.dump(itemMap, f,ensure_ascii=False)with open('artRouteMap.json1', 'w',encoding='utf-8') as f:json.dump(artRouteMap, f,ensure_ascii=False)itemList.sort()#遍历字典for key, val in itemMap.items():for idx,art in val.items():AllArts.append(art)HotArts.append(art)        #按日期排序AllArts.sort(key=lambda x: x['date'],reverse=True)#按访问量排序HotArts.sort(key=lambda x: x['visitCnt'],reverse=True)NewArts = AllArtsItemList = itemList#print((HotArts[0]))ItemMap = itemMapArtRouteMap = artRouteMapreturn itemMap,artRouteMap,itemListif __name__=="__main__":p,p1,items = getPosts()#print(p)print(type(p))print(type(p1))print(p['go学习笔记'])print(p1['3eaf98ad2b949b3f93d16aeaa1f45ab0'])print(items)

statistic.py

# encoding: utf-8
# author:yangyongzhen
# 文章和总阅读量统计#文章访问量统计
#param:名称,访问量,评论量
class ArtStat:def __init__(self, title,visitCnt,cmtCnt):self.title = titleself.visitCnt = visitCntself.commentCnt = cmtCnt#总的统计        
class AllStat:def __init__(self):#总访问量self.totalVisit = 0self.artStat = {}if __name__=="__main__":pass

如何使用

除了flask,无其它依赖。下载源码,pip install flask安装好依赖。然后python main.py即可运行起来。编写新文章,需要按照特定格式写前面几行。因为文章作者,文章分类和日期等信息,都在一个文件里写的。

文章内容格式如下(test.md):

This is a title!
2020-10-22
你好aaaaaaaasssssssssssssssss! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
08.jpg
感悟
yangyongzhenThis is the main post!# Markdown1!
## Markdown2!
### 欢迎使用Markdown编辑器Name    | Age
--------|------
Bob     | 27
Alice   | 23你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。```golang
package mainimport "fmt"func main() {fmt.Println("hello ")
}
```

网页前端小技巧 

导航栏选中高亮

网站头部导航栏根据选择自动高亮显示,代码在silder.js中实现:

var obj=null;
var As=document.querySelector(".w_header_nav").getElementsByTagName('a');
obj = As[0];
for(i=1;i<As.length;i++){if(window.location.href.indexOf(As[i].href)>=0)
obj=As[i];}
console.log(obj)
// 添加class属性
obj.classList.add("active");

返回到顶部

返回到顶部,可复用js代码:

var $backToTopEle=$('<a href="javascript:void(0)" class="Hui-iconfont toTop" title="返回顶部" alt="返回顶部" style="display:none">^^</a>').appendTo($("body")).click(function(){$("html, body").animate({ scrollTop: 0 }, 120);
});
var backToTopFun = function() {var st = $(document).scrollTop(), winh = $(window).height();(st > 0)? $backToTopEle.show(): $backToTopEle.hide();/*IE6下的定位*/if(!window.XMLHttpRequest){$backToTopEle.css("top", st + winh - 166);}
};$(function(){$(window).on("scroll",backToTopFun);backToTopFun();});

分页显示js代码 :

/* 
*page plugin 1.0 
*/
(function ($) {//默认参数var defaults = {totalPages: 9,//总页数liNums: 9,//分页的数字按钮数(建议取奇数)activeClass: 'active' ,//active类firstPage: '首页',//首页按钮名称lastPage: '末页',//末页按钮名称prv: '«',//前一页按钮名称next: '»',//后一页按钮名称hasFirstPage: true,//是否有首页按钮hasLastPage: true,//是否有末页按钮hasPrv: true,//是否有前一页按钮hasNext: true,//是否有后一页按钮callBack : function(page){//回掉,page选中页数}};//插件名称$.fn.Page = function (options) {//覆盖默认参数var opts = $.extend(defaults, options);//主函数return this.each(function () {var obj = $(this);var l = opts.totalPages;var n = opts.liNums;var active = opts.activeClass;var str = '';var str1 = '<li><a href="javascript:" class="'+ active +'">1</a></li>';if (l > 1&&l < n+1) {for (i = 2; i < l + 1; i++) {str += '<li><a href="javascript:">' + i + '</a></li>';}}else if(l > n){for (i = 2; i < n + 1; i++) {str += '<li><a href="javascript:">' + i + '</a></li>';}}var dataHtml = '';if(opts.hasNext){dataHtml += '<div class="next fr">' + opts.next + '</div>';}if(opts.hasLastPage){dataHtml += '<div class="last fr">' + opts.lastPage + '</div>';}dataHtml += '<ul class="pagingUl">' + str1 + str + '</ul>';if(opts.hasFirstPage){dataHtml += '<div class="first fr">' + opts.firstPage + '</div>';}if(opts.hasPrv){dataHtml += '<div class="prv fr">' + opts.prv + '</div>';}obj.html(dataHtml).off("click");//防止插件重复调用时,重复绑定事件obj.on('click', '.next', function () {var pageshow = parseInt($('.' + active).html());var nums,flag;var a = n % 2;if(a == 0){//偶数nums = n;flag = true;}else if(a == 1){//奇数nums = (n+1);flag = false;}if(pageshow >= l) {return;}else if(pageshow > 0&&pageshow <= nums/2){//最前几项$('.' + active).removeClass(active).parent().next().find('a').addClass(active);}else if((pageshow > l-nums/2&&pageshow < l&&flag==false)||(pageshow > l-nums/2-1&&pageshow < l&&flag==true)){//最后几项$('.' + active).removeClass(active).parent().next().find('a').addClass(active);}else{$('.' + active).removeClass(active).parent().next().find('a').addClass(active);fpageShow(pageshow+1);}opts.callBack(pageshow+1);});obj.on('click', '.prv', function () {var pageshow = parseInt($('.' + active).html());var nums = odevity(n);if (pageshow <= 1) {return;}else if((pageshow > 1&&pageshow <= nums/2)||(pageshow > l-nums/2&&pageshow < l+1)){//最前几项或最后几项$('.' + active).removeClass(active).parent().prev().find('a').addClass(active);}else {$('.' + active).removeClass(active).parent().prev().find('a').addClass(active);fpageShow(pageshow-1);}opts.callBack(pageshow-1);});obj.on('click', '.first', function(){var activepage = parseInt($('.' + active).html());if (activepage <= 1){return}//当前第一页opts.callBack(1);fpagePrv(0);});obj.on('click', '.last', function(){var activepage = parseInt($('.' + active).html());if (activepage >= l){return;}//当前最后一页opts.callBack(l);if(l>n){fpageNext(n-1);}else{fpageNext(l-1);}});obj.on('click', 'li', function(){var $this = $(this);var pageshow = parseInt($this.find('a').html());var nums = odevity(n);opts.callBack(pageshow);if(l>n){if(pageshow > l-nums/2&&pageshow < l+1){//最后几项fpageNext((n-1)-(l-pageshow));}else if(pageshow > 0&&pageshow < nums/2){//最前几项fpagePrv(pageshow-1);}else{fpageShow(pageshow);}}else{$('.' + active).removeClass(active);$this.find('a').addClass(active);}});//重新渲染结构/*activePage 当前项*/function fpageShow(activePage){var nums = odevity(n);var pageStart = activePage - (nums/2-1);var str1 = '';for(i=0;i<n;i++){str1 += '<li><a href="javascript:" class="">' + (pageStart+i) + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(nums/2-1).find('a').addClass(active);}/*index 选中项索引*/function fpagePrv(index){var str1 = '';if(l>n-1){for(i=0;i<n;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}}else{for(i=0;i<l;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}/*index 选中项索引*/function fpageNext(index){var str1 = '';if(l>n-1){for(i=l-(n-1);i<l+1;i++){str1 += '<li><a href="javascript:" class="">' + i + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}else{for(i=0;i<l;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}}//判断liNums的奇偶性function odevity(n){var a = n % 2;if(a == 0){//偶数return n;}else if(a == 1){//奇数return (n+1);}}});}
})(jQuery);

使用方法,在需要分页展示的文章下方添加以下div标签:

<div class="page">
</div>

 在网页头部引入以下js:

<script type="text/javascript" src="plugin/fenye.page.js"></script>
<script type="text/javascript">
$(function(){$("#page").Page({totalPages: 7,//分页总数liNums: 5,//分页的数字按钮数(建议取奇数)activeClass: 'activP', //active 类样式定义callBack : function(page){//console.log(page)}});
})
</script>

markdown文档渲染

<ul class="info>
<div class="md_render">
</div>
</ul>
	<script>var md;var defaults = {html: false, // Enable HTML tags in sourcexhtmlOut: false, // Use '/' to close single tags (<br />)breaks: false, // Convert '\n' in paragraphs into <br>langPrefix: 'language-', // CSS language prefix for fenced blockslinkify: true, // autoconvert URL-like texts to linkstypographer: true, // Enable smartypants and other sweet transforms// options below are for demo only_highlight: true,_strict: false,_view: 'html' // html / src / debug};defaults.highlight = function (str, lang) {var esc = md.utils.escapeHtml;if (lang && hljs.getLanguage(lang)) {try {return '<pre class="hljs"><code>' +hljs.highlight(lang, str, true).value +'</code></pre>';} catch (__) {}}return '<pre class="hljs"><code>' + esc(str) + '</code></pre>';};md = window.markdownit(defaults).use(window.markdownitCheckbox).use(window.markdownitEmoji).use(window.markdownitFootnote);var dat = document.querySelector('#enrolled_id').value;$('.md_render').html(md.render(dat));</script>

 这里有个坑需要注意,jinjia2模版是在后端渲染的,所以在网页的js代码中想使用模版变量不是那么美,不能像网页中{{data}}的方式使用。这里采用了一种取巧的方式,通过一个隐藏标签,先把需要的内容在html网页中渲染出来,再在js中通过操作dom的方式去获取。

<input type="hidden"  id="enrolled_id" value="{{ data.body }}">

其他资源

(自适应手机端)响应式个人博客网站模板

我的博客模版

JSON在线 | JSON解析格式化—SO JSON在线工具

风宇个人博客

丰富的计算机技术分享,多样化的互联网资源分享,第1页 - 吱吱工具箱butterPig

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/205453.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【matlab程序】南海土台风画法

【matlab程序】南海土台风画法 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深地图图像修饰 【Python海洋专…

将图像的rgb数据转成DICOM医学图像格式

dcmtk官方文档&#xff1a;https://support.dcmtk.org/docs/ dcmtk最新源码下载&#xff1a;https://www.dcmtk.org/en/dcmtk/dcmtk-software-development/ dcmtk旧版本源码下载&#xff1a;https://dicom.offis.de/download/dcmtk/ 用DCMTK库实现将图像转成dcm格式 dcmtk库的…

三.排序与分页

目录 一.排序数据二.分页 一.排序数据 1.排序规则 使用ORDER BY 子句排序 ASC&#xff08;ascend&#xff09;升序DESC&#xff08;descend&#xff09;降序 ORDER BY 子句在SELECT语句的结尾 2.单列排序 SELECT last_name, job_id, department_id, hire_date FROM e…

Linux(CentOS7)上安装mysql

在CentOS中默认安装有MariaDB&#xff08;MySQL的一个分支&#xff09;&#xff0c;可先移除/卸载MariaDB。 yum remove mariadb // 查看是否存在mariadb rpm -qa|grep -i mariadb // 卸载 mariadb rpm -e --nodeps rpm -qa|grep mariadb yum安装 下载rpm // 5.6版本 wge…

zookeeper集群+kafka集群:

kafka3.0之前依赖于zookeeper。 zookeeper开源&#xff0c;分布式的架构。提供协调服务&#xff08;Apache项目&#xff09; 基于观察者模式涉及的分布式服务管理架构。 存储和管理数据。分布式节点上的服务接受观察者的注册。一旦分布式节点上的数据发生变化&#xff0c;由zoo…

7、信息收集(2)

文章目录 一、指纹识别1、Nmap工具2、Wafw00f工具 二、使用Maltego进行情报收集 一、指纹识别 1、Nmap工具 命令一&#xff1a;nmap -sS -sV <ip>&#xff0c;使用TCP SYN的方式&#xff0c;扫描目标主机上常规端口运行的服务版本。 -sS&#xff1a;指定使用TCP SYN的方…

k8s中批量处理Pod应用的Job和CronJob控制器介绍

目录 一.Job控制器 1.简介 2.Jobs较完整解释 3.示例演示 4.注意&#xff1a;如上例的话&#xff0c;执行“kubectl delete -f myJob.yaml”就可以将job删掉 二.CronJob&#xff08;简写为cj&#xff09; 1.简介 2.CronJob较完整解释 3.案例演示 4.如上例的话&#xf…

C#,《小白学程序》第三课:类class,类的数组及类数组的排序

类class把数值与功能巧妙的进行了结合&#xff0c;是编程技术的主要进步。 下面的程序你可以确立 分数 与 姓名 之间关系&#xff0c;并排序。 1 文本格式 /// <summary> /// 同学信息类 /// </summary> public class Classmate { /// <summary> /…

注册Zoho Mail邮箱:优势与使用体验

如何注册Zoho Mail邮箱&#xff1f;要注册Zoho Mail邮箱&#xff0c;首先打开浏览器&#xff0c;访问Zoho Mail官网&#xff0c;点击页面右上角的“创建帐户”按钮。接下来&#xff0c;按照提示输入你的姓名、生日和性别&#xff0c;以及一个有效的手机号码或电子邮件地址。然后…

20231122给RK3399的挖掘机开发板适配Android12

20231122给RK3399的挖掘机开发板适配Android12 2023/11/22 9:30 主要步骤&#xff1a; rootrootrootroot-X99-Turbo:~$ tar --use-compress-programpigz -xvpf rk356x_android12_220722.tgz rootrootrootroot-X99-Turbo:~$ cd rk_android12_220722/ rootrootrootroot-X99-Tur…

【学习记录】从0开始的Linux学习之旅——驱动模块编译与加载

一、概述 Linux操作系统通常是基于Linux内核&#xff0c;并结合GNU项目中的工具和应用程序而成。Linux操作系统支持多用户、多任务和多线程&#xff0c;具有强大的网络功能和良好的兼容性。本文主要讲述如何编译及加载linux驱动模块。 二、概念及原理 应用程序通过系统调用与内…

(二)基于高尔夫优化算法GOA求解无人机三维路径规划研究(MATLAB)

一、无人机模型简介&#xff1a; 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、高尔夫优化算法GOA简介 高尔夫优化算法…

PHP 双门双向门禁控制板实时监控源码

本示例使用设备&#xff1a; 实时网络双门双向门禁控制板可二次编程控制网络继电器远程开关-淘宝网 (taobao.com) <?PHPheader("content-type:text/html;charsetGBK");$ThisIpget_local_ip(); //获取电脑IP地址 $server udp://.$ThisIp.:39192; $sock…

【JavaEE初阶】 HTTP响应报文

文章目录 &#x1f332;序言&#x1f38d;200 OK&#x1f340;404 Not Found&#x1f384;403 Forbidden&#x1f334;405 Method Not Allowed&#x1f38b;500 Internal Server Error&#x1f333;504 Gateway Timeout&#x1f332;302 Move temporarily&#x1f38d;301 Move…

构建智能医患沟通:陪诊小程序开发实战

在医疗科技的浪潮中&#xff0c;陪诊小程序的开发成为改善医患沟通的创新途径之一。本文将介绍如何使用Node.js和Express框架构建一个简单而强大的陪诊小程序&#xff0c;实现患者导诊和医生咨询功能。 1. 安装Node.js和Express 首先确保已安装Node.js&#xff0c;然后使用以…

【机器学习 | 可视化】回归可视化方案

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

【微服务】SaaS云智慧工地管理平台源码

智慧工地系统是一种利用人工智能和物联网技术来监测和管理建筑工地的系统。它可以通过感知设备、数据处理和分析、智能控制等技术手段&#xff0c;实现对工地施工、设备状态、人员安全等方面的实时监控和管理。 一、智慧工地让工程施工智能化 1、内容全面&#xff0c;多维度数…

Docker快速搭建RTMP服务(tiangolo/nginx-rtmp:Docker + Nginx+ nginx-rtmp-module)

Linux Docker快速搭建多媒体/视频流的 RTMP 服务 第一步 安装Docker 点击这里查看 第二步 拉取并运行镜像 tiangolo/nginx-rtmp/ docker pull tiangolo/nginx-rtmp docker run -d -p 1935:1935 --name nginx-rtmp tiangolo/nginx-rtmpOBS客户端测试 OBS客户端设置直播的推…

Go——二、变量和数据类型

Go 一、Go语言中的变量和常量1、Go语言中变量的声明2、如何定义变量方式1&#xff1a;方式2&#xff1a;带类型方式3&#xff1a;类型推导方式定义变量方式4&#xff1a;声明多个变量总结 3、如何定义常量4、Const常量结合iota的使用 二、Golang的数据类型1、概述2、整型2.1 类…

LeetCode Hot100 124.二叉树中的最大路径和

题目&#xff1a; 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点…