【翻译】编写一个小型静态网站生成器

Python 【翻译】编写一个小型静态网站生成器 大概有一百多种用 Python 编写的静态站点生成器(甚至还有其他语言编写的静态站点生成器)。 所以我决定写我自己的。为什么?好吧,我只是想。我希望将自己的博客从Ghost移开,并且希望保持真正的简约性。我决定使用 GitHub Pages 托管,因为他们最近宣布支持 自定义域的SSL。 渲染内容 每个静态网站生成器都需要采用某种源格式(例如 Markdown 或 ReStructuredText)并将其转换为 HTML。自从我离开 Ghost 以来,我决定坚持 Markdown。 自从我最近将 Github风格的Markdown渲染 集成到 Warehouse 中以来,我决定使用 cmarkgfm 。使用以下方式将 Markdown 渲染为 HTML: import cmarkgfm def render_markdown(content: str) -> str: content = cmarkgfm.markdown_to_html_with_extensions( content, extensions=['table', 'autolink', 'strikethrough']) return content cmarkgfm 确实有一个名为 github_flavored_markdown_to_html 的便捷方法,但是它使用 GitHub 的 tagfilter 扩展名,当我要将脚本和内容嵌入到帖子中时,这是不希望的。因此,我只是选择了我想使用的扩展。 收集资源(所有文档) 好的,我们有一种渲染 Markdown 的方法,但是我们还需要一种收集所有源文件的方法。我决定将所有来源存储在 ./src。我们可以pathlib用来收集它们: import pathlib from typing import Iterator def get_sources() -> Iterator[pathlib.Path]: return pathlib.Path('.').glob('srcs/*.md') 头部元数据 许多静态网站生成器都有 “前题” 的概念-一种为每个源文件设置元数据等的方法。我想支持 frontmatter,让我为每个帖子设置日期和标题。看起来像这样: --- title: Post time date: 2018-05-11 --- # Markdown content here. 对于 frontmatter 有一个非常好的和简单的现有库,称为 python-frontmatter。我可以用它来提取前题和原始内容: ...

【转载】Python 包管理工具解惑

Python 【转载】Python 包管理工具解惑 一、困惑 作为一个 Python 初学者,我在包管理上感到相当疑惑(嗯,是困惑)。主要表现在下面几个方面: 这几个包管理工具有什么不同? distutils setuptools distribute disutils2 distlib pip 什么时候该用pip,什么时候该用 setup.py ,它们有关系么? easy_install、ez_setup.py、setup.py、setup.cfg 分别都是干啥的? wheel 和 pip 的关系? Egg 和 whl 的关系? 如何发布自己的模块(发布到PyPI)? 如何进行模块的私有发布(不发布到PyPI)? 为了弄清这些问题,我找了许多资料。最后发现最好的资料还是 python 的官方文档。 下面是阅读了所有我找到的资料后的一个总结,希望能帮到几个月后又把这些全部忘光的那个自己。 二、python 包管理工具大乱斗 我用时间顺序来描述乱斗过程。 1. distutils distutils 是 python 标准库的一部分,2000年发布。使用它能够进行 python 模块的 安装 和 发布。 setup.py 就是利用 distutils 的功能写成,我们可以看一个简单的 setup.py 的例子。 在这里可以看到关于 setupt.py 格式的所有详细描述:Writing the Setup Script。 要安装一个模块到当前的 python 环境中,可以使用这个模块提供的 setup.py 文件: python setup.py install 下面的代码会发布一个 python 模块,将其打包成 tar.gz 或者 zip 压缩包: ...

【转载】Python 源码安装

Python 【转载】Python 源码安装 这里的 Python 源码指的是从官网下载的 官方版本的解释器:CPython。 官网 python.org 下载压缩包,解压 然后,在 ./configure 的时候,需要加上 –enable-optimizations 参数,这样才能启用很多功能。 网上看到很多人说要用 ./configure –with-ssl,这是没用的,日志上写明白了 not recognized option ‘–with-ssl’。 编译的时候日志跑的很快,很多人就忽略了细节,年轻人,不要慌,回去翻翻日志,你会有新发现,很多东西别人都给了提示的了。 接下来官方步骤 make && make install 重新试试 python3> import ssl 有了。 另外在编译安装git等工具时,都把 –enable-optimizations 参数带上,这样才是以“官方发布的稳定版本”编译。 转载信息 作者:EncoderJ 来源:CSDN 原文:https://blog.csdn.net/Pretendness/article/details/80032016 版权声明:本文为博主原创文章,转载请附上博文链接!

【转载】你可能还没有使用过的python3特性---但你应该用

Python 【转载】你可能还没有使用过的python3特性—但你应该用 很多人因为看到了Python EOL而将代码从 python2.x 迁移到了 python3.x。不幸的是,大多数的 python3 代码看起来很像 python2.在下面我将展示一些例子来说明部分 python3 特性,希望它们可以让你用 python 解决问题更简单。 以下的代码将以 Python3.7 书写。 f-Strings(3.6+) 在任何编程语言中,没有字符串结构,都很难以工作。大多数人使用 format 格式化文本,如下所示: user = "Jane Doe" action = "buy" log_message = 'User {} has logged in and did an action {}.'.format( user, action ) print(log_message) # User Jane Doe has logged in and did an action buy. 除此之外,Python3 还提供了一种通过 f-string 进行字符串插值的灵活方法。使用 f-strings 的上述代码如下所示: user = "Jane Doe" action = "buy" log_message = f'User {user} has logged in and did an action {action}.' print(log_message) # User Jane Doe has logged in and did an action buy. 有时候会写一种很蠢的写法,如果用 f-String 就能解决,实例如下: ...

【转载】面向对象(深入)| python描述器详解

Python 【转载】面向对象(深入)| python描述器详解 本文分为如下部分 引言——用 @property 批量使用的例子来引出描述器的功能 描述器的基本理论及简单实例 描述器的调用机制 描述器的细节 实例方法、静态方法和类方法的描述器原理 property 装饰器的原理 描述器的应用 参考资料 引言 前面 python 面向对象的文章中我们讲到过,我们可以用 @property 装饰器将方法包装成属性,这样的属性,相比于其他属性有一个优点就是可以在对属性赋值时,进行变量检查,举例代码如下: class A: def __init__(self, name, score): self.name = name # 普通属性 self._score = score @property def score(self): return self._score @score.setter def score(self, value): print('setting score here') if isinstance(value, int): self._score = value else: print('please input an int') a = A('Bob',90) a.name # 'Bob' a.score # 90 a.name = 1 a.name # 1 ,名字本身不应该允许赋值为数字,但是这里无法控制其赋值 a.score = 83 a.score # 83,当赋值为数值型的时候,可以顺利运行 a.score = 'bob' # please input an int a.score # 83,赋值为字符串时,score没有被改变 当我们有很多这样的属性时,如果每一个都去使用 @property,代码就会过于冗余。如下 ...

bumpversion的简单学习

Python Python Module bumpversion 的简单学习 如果只是闭门造车,写点小脚本的话可以不用在意版本的问题。 但是一旦脚本或者项目需要被他人使用,如果没有版本信息,又出现了 bug,那么你很难定位他使用的是什么版本,这个 bug 到底有没有修复,有了版本信息你可以很确定一些 feather 或者 bug 是否实现。 最简单的版本信息制作,在项目下新建一个 VERSION 文件,在该文件中记录版本号,做了些代码修改就手动修改 VERSION。 但是这样会带来更多问题,你只能在修改过 VERSION 后做个 git commit 才能够更好地跟踪;多个文件会提到版本信息该怎么处理;大版本和 patch 版本如何区分? bumpversion 横空出世,给上述的问题给了些答案。Bumpversion 是一个简化工程版本号修改的工具,可以通过 pip 安装。使用它可以一键将当前工程的文件中的旧版本号替换成新版本号还可以顺便 Commit 和 打上 Tag(如有需要)。 语法 bumpversion [options] part [file] 这里面 part 是关键,它可以简化很多事。 使用 先看一个简单的例子: 工程里有 main.py 和 Makefile 两个文件。 main.py 打印当前的版本号: version = '0.0.1' if __name__ == '__main__': print(version) Makefile 将 py 文件压缩起来: VERSION = 0.0.1 .PHONY: build build: tar zcvf tellversion-v$(VERSION).tar.gz main.py 要使用 Bumpversion 需要在目录里添加 .bumpversion.cfg 文件: ...

CTF(鶸)密码学

Python Algorithm CTF(鶸)密码学 一、摩斯密码 1、特点 题面只有三个值。 2、解题思路 转换成 ascii,出现 flag 标识符即结束,否则根据转后的数据进行下一步处理。 二、栅栏密码 1、特点 密文字符串出间隔性的出现 flag 的标识符。 2、解题思路 分栏破译。 def inputData(): string = input("请输入栅栏加密的文字:") code = input("请输入分栏:(0代表从2到6逐个分栏):") code = int(code) return string,code def code2(string): string_temp = [] string_temp.append(string[0::2]) string_temp.append(string[1::2]) print("分成2栏的结果是:%s" % (''.join(string_temp))) def code3(string): string_temp = [] string_temp.append(string[0::3]) string_temp.append(string[1::3]) string_temp.append(string[2::3]) print("分成3栏的结果是:%s" % (''.join(string_temp))) def code4(string): string_temp = [] string_temp.append(string[0::4]) string_temp.append(string[1::4]) string_temp.append(string[2::4]) string_temp.append(string[3::4]) print("分成4栏的结果是:%s" % (''.join(string_temp))) def code5(string): string_temp = [] string_temp.append(string[0::5]) string_temp.append(string[1::5]) string_temp.append(string[2::5]) string_temp.append(string[3::5]) string_temp.append(string[4::5]) print("分成5栏的结果是:%s" % (''.join(string_temp))) def code6(string): string_temp = [] string_temp.append(string[0::6]) string_temp.append(string[1::6]) string_temp.append(string[2::6]) string_temp.append(string[3::6]) string_temp.append(string[4::6]) string_temp.append(string[5::6]) print("分成6栏的结果是:%s" % (''.join(string_temp))) def main(): string, code = inputData() if (code == 0): code2(string) code3(string) code4(string) code5(string) code6(string) elif (code == 2): code2(string) elif (code == 3): code3(string) elif (code == 4): code4(string) elif (code == 5): code4(string) elif (code == 6): code4(string) else: print("error") if __name__ == "__main__": main() 三、Rot13 1、特点 凯撒加密的第十二种方式,但是可以字符和数字混合在其中。 ...

Deepin 切换壁纸小工具

Linux Python Deepin 切换壁纸小工具 切换壁纸这种事,找到接口,一行代码就可以解决,本来打算用 bash 脚本,但是考虑到随机选取壁纸等因素,用 python 的 os 模块完成任务。 一、思路 找到切换壁纸的接口 设置壁纸库(文件夹) python 脚本完成功能 半小时触发脚本自动切换壁纸 二、实现过程 1、切换壁纸接口 本脚本只在 Linux 下使用。 在 Linux 下(准确说是 GNOME 桌面),通过 gsettings set 指令完成对特定值(壁纸文件位置)进行修改,即可修改壁纸。 # Ubuntu 下切换指令(注意有个 file) gsettings set org.gnome.desktop.background picture-uri "file:/home/user/Desktop/1.jpg" #Deepin 下切换指令(注意没有 file) gsettings set com.deepin.wrap.gnome.desktop.background picture-uri "/home/user/Desktop/1.jpg" 2、设置壁纸库 这步没什么好说的啊,把喜欢的壁纸放在一个文件夹下,方便之后的存取使用。 3、python 完成功能 直接上代码,看代码注释就好了。 # -*- coding: utf-8 -*- # @Date : 2018-05-21 12:07:17 # @Author : Light (halysl0817@gmail.com) # @Link : ${link} # @Version : $Id$ import os import random """ TODO(halysl0817@gmail.com):Change the wallpaper by changing the time 利用linux下的crontab工具实现半小时切换一次, */30 * * * * python /xxx/changebackground.py """ # 更换壁纸指令,此为deepin更换指令,不代表所有linux发行版更换指令 cmd = "gsettings set com.deepin.wrap.gnome.desktop.background picture-uri " # 图片目录,用户可自主更换 path = "/home/light/Documents/code/spider-on-lol/lolSpider/lolSpider/img/hero_skin_img/full/" # 利用os.listdir()方法获取图片目录下的所有文件名的列表 pic_list = os.listdir(path) # 确切的文件位置,以及确切的更换指令 real_path = path + str(random.choices(pic_list))[2:-2] real_cmd = cmd + "\"" + real_path +"\"" # 执行 os.system(real_cmd) 4、自动切换壁纸 利用 Linux 下的 crontab 完成定时任务。 ...

marshmallow 库的简单学习

[Python [[Python Module]] marshmallow 库的简单学习 marshmallow 是一个简单序列化/反序列化模块。 它可以很轻松的做到 object-->dict objects-->list 等序列化操作,同时经过添加简单的函数做到 dict-->object list-->objects 等反序列化操作。 同时,它对于数据的校检非常友好,有多种校检方式,同时相对于 Schema 库,它可以更有针对性的校检数据,序列化数据等(例如只取某些数据,只校检某些数据等)。 一、简单说明 marshmallow 库非常易于使用,下面将以实际的代码演示如何使用这个库。 先明确下使用流程。 创建类–>创建 Schema 类–>(创建 ValidSchema 类) 序列化<—>反序列化 二、创建Schema类 创建基础的类 # -*- coding:utf-8 -*- from datetime import date from marshmallow import Schema, fields, pprint, post_load from marshmallow import ValidationError, validate, validates class Artist(object): """基础艺术家类""" def __init__(self, name): self.name = name class Album(object): """基础专辑类""" def __init__(self, title, release_date, artist): self.title = title self.release_date = release_date self.artist = artist 根据自己的类创建对应的 Schema 类,继承自 marshmallow 的 Schema 类。 ...

paramiko 库的简单学习

[[Python]] [[Python Module]] paramiko 库的简单学习 paramiko,一个听起来不像英语的库,在诸多英文名的库中独立旗帜(官方解释为:“Paramiko” is a combination of the Esperanto words for “paranoid” and “friend”)。 它的主要功能就是实现对 ssh 协议的封装,能够在一个更高层面上,轻松地使用 ssh 以及 sftp 等功能。 一、安装 pip install paramiko 二、ssh 连接对象 1.使用密码连接 import paramiko # 这行代码可以生成连接日志,大部分情况下不需要 # paramiko.util.log_to_file('/tmp/sshout') ssh = paramiko.SSHClient() #这行代码的作用是允许连接不在know_hosts文件中的主机。 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("IP", port, "username", "password") 2.使用秘钥连接 import paramiko ssh = paramiko.SSHClient() ssh.connect('10.120.48.109', port, '用户名', key_filename='私钥') 三、ssh 执行指令 成功连接主机后,可以使用 ssh.exec_command(cmd) 的方法执行指令。 但默认返回三个 paramiko.channelfile 对象,我们可以用以下的方法读取数据或者写入确认等。 stdin, stdout, stderr = ssh.exec_command(cmd) # 如果成功,stdout会拿到输出的结果 for line in stdout.readlines(): print(line) # 执行过程中,可以使用以下方法进行确认,但此时的确认是对指令操作过程中的指令,例如“确认删除”等 stdin.write('Y') # 执行过程中若出现错误信息,报错信息会保存在stderr中 四、sftp 对象 paramiko 的 sftp 对象有多种生成方式。 倘若已有 ssh 对象,则: ...