Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
huataihuang committed Jul 20, 2023
1 parent b3b1065 commit b2e5c45
Show file tree
Hide file tree
Showing 29 changed files with 455 additions and 16 deletions.
21 changes: 12 additions & 9 deletions source/devops/docs/kindle/calibre_remove_drm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,17 @@ Google了相关信息,共享书籍的方法概括如下:
dedrm-ebook-tools
====================

`dedrm-ebook-tools(DRM Removal Tools for eBooks) <https://github.com/psyrendust/dedrm-ebook-tools>`_ 最早是为了保存 `Apprentice Alf's Blog <http://www.apprenticealf.wordpress.com/>`_ (景德镇居民无法访问的WordPress网站)提供的工具,但是目前因为apprenticeharper从2015年开始也建立了GitHub仓库,所以已经不再更新维护。当前可以直接从 `apprenticeharper/DeDRM_tools <https://github.com/apprenticeharper/DeDRM_tools>`_ 获取最新的插件工具。
`dedrm-ebook-tools(DRM Removal Tools for eBooks) <https://github.com/psyrendust/dedrm-ebook-tools>`_ 最早是为了保存 `Apprentice Alf's Blog <http://www.apprenticealf.wordpress.com/>`_ (景德镇居民无法访问的WordPress网站)提供的工具,但是目前因为apprenticeharper从2015年开始也建立了GitHub仓库,所以已经不再更新维护。

请参考 `DeDRM_tools/FAQs.md <https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md>`_ 进行安装,其中面向最终用户的软件包发布可以从 `DeDRM_tools releases page <https://github.com/apprenticeharper/DeDRM_tools/releases>`_ 下载到。
- (已失效)可以直接从 `apprenticeharper/DeDRM_tools <https://github.com/apprenticeharper/DeDRM_tools>`_ 获取最新的插件工具。 请参考 `DeDRM_tools/FAQs.md <https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md>`_ 进行安装,其中面向最终用户的软件包发布可以从 `DeDRM_tools releases page <https://github.com/apprenticeharper/DeDRM_tools/releases>`_ 下载到。
- 2023年7月时,我使用 Calibre 6.23 ,发现上述 `apprenticeharper/DeDRM_tools <https://github.com/apprenticeharper/DeDRM_tools>`_ 已经不能工作(Calibre crash),参考 `DeDRM not working #2250 <https://github.com/apprenticeharper/DeDRM_tools/issues/2250>`_ 改为使用 `noDRM/DeDRM_tools (GitHub) <https://github.com/noDRM/DeDRM_tools>`_

.. note::

请尊重版权,开发者提供开源工具是为了正当的知识和文化传播,并不是支持盗版!

安装Calibre DeDRM
-------------------
`apprenticeharper/DeDRM_tools <https://github.com/apprenticeharper/DeDRM_tools>`_ (归档)
----------------------------------------------------------------------------------------------

- 下载和解压缩::

Expand All @@ -56,10 +57,14 @@ dedrm-ebook-tools

然后在 ``Are you sure?`` 对话框中点击 ``Yes`` 并确认加载这个插件。(提示有安全性因患,务必使用可靠来源的插件)

`noDRM/DeDRM_tools (GitHub) <https://github.com/noDRM/DeDRM_tools>`_
---------------------------------------------------------------------------

安装方法和 `apprenticeharper/DeDRM_tools <https://github.com/apprenticeharper/DeDRM_tools>`_ ,不再重复

配置Calibre使用DeDRM
------------------------


如果是从Kindle设备或者从亚马逊的web网站下载 - 在亚马逊网站的 ``管理我的内容和设备`` 页面,每个文件都有一个 ``通过电脑下载USB传输`` 。

推荐使用这个方法下载,下载时会提示 ``从下拉列表中选择一个设备`` ,实际上,这个步骤就是亚马逊根据你的注册设备为下载文件加上DRM加密。
Expand Down Expand Up @@ -89,13 +94,11 @@ dedrm-ebook-tools
使用Calibre+DeDRM
---------------------

- 把Kindle for PC下载的那些azw文件添加到Calibre即可(直接拖进去吧),DeDRM插件会自动去除azw文件的DRM保护并转换成原始格式(azw3或者mobi、prc等)
- 把Kindle for PC下载的那些azw文件添加到Calibre即可(直接拖进去吧),DeDRM插件会自动去除azw文件的DRM保护并转换成原始格式: 导入后是去除DRM的 ``.azw3`` 格式文件,这个文件可以直接放到Kindle中阅读。例如,可以将文件存放到美区Kindle账号的Personal Documents中

.. note::

Calibre支持 `send to kindle <https://www.amazon.com/gp/sendtokindle>`_(即 `Kindle Personal Documents Service <https://www.amazon.com/gp/help/customer/display.html?nodeId=200767340>`_ ,非常方便把各种文档通过电子邮件方式发送给Kindle设备阅读),这样可以将中国区购买的Kindle书籍转换成去除DRM的 ``.mobi`` 文档发送到美国区Kindle设备,方便自己的学习。

转换支持epub和mobi格式输出,epub通用性较好,可以输出到其他阅读软件(如苹果的ibook)中阅读,但是似乎转换图片排版有些异常;mobi格式则保持原有排版格式(本身就是kindle的无加密格式),但是转换后似乎丢失内容索引,阅读时转跳章节不便。
Calibre支持 `send to kindle <https://www.amazon.com/gp/sendtokindle>`_ (即 `Kindle Personal Documents Service <https://www.amazon.com/gp/help/customer/display.html?nodeId=200767340>`_ ,非常方便把各种文档通过电子邮件方式发送给Kindle设备阅读),这样可以将中国区购买的Kindle书籍转换成去除DRM的 ``.azw3`` 文档发送到美国区Kindle设备,方便自己的学习。

参考
======
Expand Down
9 changes: 9 additions & 0 deletions source/devops/docs/kindle/convert_doc_to_kindle.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ Kindle 邮箱是非常有效的在线转换工具,支持将不同格式文档

通常我们可以发送zip压缩格式的pdf,txt,docx等文件到kindle,会自动转换并进行设备同步。而且,Kindle邮箱还曲线支持了epub文件,也就是说你可以在Kindle中阅读epub文件,虽然这是通过Kindle在线服务做了转换的方式,但毕竟不需要自己安装类似Calibre这样的桌面工具就能在线完成,所以还是很方便的。

- 注册一个 QQ 邮箱,然后在 Amazon 网站 ``Manage Your Content & Devices> Preferences > Personal Document Settings`` 找到 ``Send-to-Kindle E-Mail Settings`` ,添加信任的发件人地址(也就是你注册的QQ邮箱地址)。这样就能够通过 Calibre 的 ``Preferences > Sharing books by email`` 设置,通过QQ邮箱给Kindle的邮件地址发送文件来实现转换
- 或者直接访问 `Send to Kindle <https://www.amazon.com/sendtokindle>`_ 通过WEB页面拖放,可以上传最高200MB的 ``.epub`` / ``.pdf`` / ``.doc`` 文档

.. note::

``Send-to-Kindle`` 已经不再支持 ``.mobile`` ,只支持 ``.epub`` 和 ``.pdf`` 电子书了

在传输文件之前,请先将电子书文件名改成中文,否则传输后无法修改

参考
======

Expand Down
75 changes: 75 additions & 0 deletions source/devops/docs/kindle/kindle_download_helper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,81 @@
kindle电子书批量下载
=========================

Kindle中国电子书店在2023年6月30日18店停止运营,留给我们只有1年的时间(2024年6月30日)可以下载已经购买过的电子书。

对于中国读者而言,这是一个无奈且悲伤的象征性事件,然而我们不得不面对现实:

- 批量下载已购买的电子书
- 移除DRM( :ref:`calibre_remove_drm` ),将电子书转到其他平台继续阅读(我准备通过 ``Send to Kindle`` 转一部分到美亚账号,并且通过 :ref:`read_e-books_after_kindle` 方式在Apple iBook和Google Books中归档阅读)

批量下载
==========

- 准备 :ref:`virtualenv` ( :ref:`macos` ) :

.. literalinclude:: ../../../python/startup/virtualenv/brew_install_pip3_venv
:language: bash
:caption::ref:`macos` 环境安装 ``pip3`` 以及 ``venv``

.. literalinclude:: ../../../python/startup/virtualenv/venv
:language: bash
:caption: venv初始化

.. literalinclude:: ../../../python/startup/virtualenv/venv_active
:language: bash
:caption: 激活venv

- clone `Kindle_download_helper (Github) <https://github.com/yihong0618/Kindle_download_helper>`_ ,然后 ``pip`` 安装对应模块:

.. literalinclude:: kindle_download_helper/install_kindle_download_helper
:caption: 安装 ``Kindle_download_helper``

- 执行以下命令下载自己的购买书籍,同时移除DRM:

.. literalinclude:: kindle_download_helper/kindle_download_helper
:caption: 运行 ``kindle_download_helper`` 下载书籍

默认(如果是已经通过浏览器登陆在 amazon 网站)会使用 ``browser-cookie3`` 库自动从浏览器获得cookie。如果不是本级下载,则需要手工获得cookie来下载,详见 `Kindle_download_helper (Github) <https://github.com/yihong0618/Kindle_download_helper>`_

不过,我还是遇到无法获取 ``CSRF token`` 报错:

.. literalinclude:: kindle_download_helper/kindle_download_helper_error
:caption: 运行 ``kindle_download_helper`` 下载书籍报错: 没有找到 ``csrf token``

这个 ``CSRF Token`` 参考 `Kindle_download_helper (Github) <https://github.com/yihong0618/Kindle_download_helper>`_ 帮助,从 `Amazon.cn全部书籍 <https://www.amazon.cn/hz/mycd/myx#/home/content/booksAll/dateDsc/>`_ 页面中,通过网页源码,搜索 ``csrfToken`` 添加到命令行参数 ``${csrfToken}`` :

.. literalinclude:: kindle_download_helper/kindle_download_helper_device_csrftoken
:caption: 运行 ``kindle_download_helper`` 下载书籍(结合 ``device_sn`` 和 ``csrfToken`` )

还是遇到一个报错,和 `python kindle.py --pdoc --mode sel --cn --cookie ${cookie} ${csrf}报错 #139 <https://github.com/yihong0618/Kindle_download_helper/issues/139>`_ 报错相同

.. literalinclude:: kindle_download_helper/kindle_download_helper_device_csrftoken_error
:caption: 运行 ``kindle_download_helper`` 下载书籍(结合 ``device_sn`` 和 ``csrfToken`` )报错

可以看到是 ``kindle_download_helper/kindle.py`` 中::

def download_books(self, start_index=0, filetype="EBOK"):
# use default device
device = self.find_device()

获取默认设备报错

顺着报错,可以定位到 ``get_devices`` 函数:

.. literalinclude:: kindle_download_helper/kindle.py
:language: python
:caption: kindle.py 代码片段 ``get_devices``

可以看出这里 ``get_devices`` 实际上是从 ``cookie`` 中获取的,这说明程序中 ``browser-cookie3`` 库自动从浏览器获得cookie存在问题。所以按照 `Kindle_download_helper (Github) <https://github.com/yihong0618/Kindle_download_helper>`_ 帮助,从浏览器页面获取 ``cookie`` : 在 `Amazon.cn全部书籍 <https://www.amazon.cn/hz/mycd/myx#/home/content/booksAll/dateDsc/>`_ 页面中,按 ``F12`` ,进入 ``Network`` 面板。在 ``Name`` 栏找到任意一个 ``ajax`` 请求,右键,找到 ``Copy request headers``
,从这个复制出来的文本中找到 ``Cookie: ZZZ`` ,然后按照以下命令执行:

.. literalinclude:: kindle_download_helper/kindle_download_helper_device_cookie_csrftoken
:caption: 运行 ``kindle_download_helper`` 下载书籍(结合手工获取的 ``cookie`` 和 ``csrfToken`` )

.. note::

``DeDRM`` 是失败的,所以我还是采用 :ref:`calibre_remove_drm`

参考
======

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
git clone git@github.com:yihong0618/Kindle_download_helper.git
cd Kindle_download_helper
pip3 install -r requirements.txt
24 changes: 24 additions & 0 deletions source/devops/docs/kindle/kindle_download_helper/kindle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
def get_devices(self):
"""
This method must be called before each download, so we ensure
the session cookies before it is called
"""
self.ensure_cookie_token()

payload = {"param": {"GetDevices": {}}}
r = self.session.post(
self.urls["payload"],
data={
"data": json.dumps(payload),
"csrfToken": self.csrf_token,
},
)
r.raise_for_status()
devices = r.json()
if devices.get("error"):
self.revoke_cookie_token(open_page=True)
raise Exception(
f"Error: {devices.get('error')}, please visit {self.urls['bookall']} to revoke the csrftoken and cookie"
)
devices = r.json()["GetDevices"]["devices"]
...
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python3 kindle.py --dedrm --cn ## --dedrm 移除 DRM
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cookie="ZZZ"
csrfToken="XXXXXXXX"
device_sn="YYYYYY"

python3 kindle.py --device_sn ${device_sn} --dedrm --cn --cookie ${cookie} ${csrfToken}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
csrfToken="XXXXXXXX"
device_sn="YYYYYY"

python3 kindle.py --device_sn ${device_sn} --dedrm --cn ${csrfToken}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Traceback (most recent call last):
File "/Users/huataihuang/docs/github.com/yihong0618/Kindle_download_helper/kindle.py", line 5, in <module>
main()
File "/Users/huataihuang/docs/github.com/yihong0618/Kindle_download_helper/kindle_download_helper/cli.py", line 318, in main
kindle.download_books(
File "/Users/huataihuang/docs/github.com/yihong0618/Kindle_download_helper/kindle_download_helper/kindle.py", line 529, in download_books
device = self.find_device()
^^^^^^^^^^^^^^^^^^
File "/Users/huataihuang/docs/github.com/yihong0618/Kindle_download_helper/kindle_download_helper/kindle.py", line 130, in find_device
devices = self.get_devices()
^^^^^^^^^^^^^^^^^^
File "/Users/huataihuang/docs/github.com/yihong0618/Kindle_download_helper/kindle_download_helper/kindle.py", line 224, in get_devices
r.raise_for_status()
File "/Users/huataihuang/venv3/lib/python3.11/site-packages/requests/models.py", line 1021, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 503 Server Error: Service Unavailable for url: https://www.amazon.cn/hz/mycd/ajax
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
...
Exception: Can't get the csrf token, please refresh the page at https://www.amazon.cn/hz/mycd/myx#/home/content/booksAll and retry
73 changes: 73 additions & 0 deletions source/flask/flask_startup.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
.. _flask_startup:

====================
flask快速起步
====================

最小化运行
=============

- 最小化的flask应用:

.. literalinclude:: flask_startup/hello.py
:language: python
:caption: 最小化的flask应用

- 运行:

.. literalinclude:: flask_startup/flask_hello_run
:caption: 运行最小化的flask应用

简单说明:

- ``route()`` 告知Flask是哪个URL触发这段程序的功能
- 这里我使用了 ``hello.py`` ,所以采用 ``--app hello`` 来运行;如果程序名字是 ``app.py`` 或者 ``wsgi.py`` 就不需要 ``--app`` 参数

- 对外开放访问的运行:

.. literalinclude:: flask_startup/flask_hello_run_service
:caption: 运行最小化的flask应用对外提供服务(绑定所有IP)

简单说明:

- 默认flask运行只监听本地 ``127.0.0.1`` ,所以需要使用 ``--host=0.0.0.0`` 让flask监听在所有网络接口,也就是对外提供服务
- 默认flask运行端口是 ``5000`` ,但是在 :ref:`macos` 上和 'AirPlay Receiver' 服务冲突,所以指定 ``--port=5001``

现在就可以访问主机的实际IP地址和端口来访问flask: http://192.168.6.1:5001

- 开启debug模式(方便调试):

.. literalinclude:: flask_startup/flask_hello_run_debug
:caption: debug模式运行最小化的flask应用

HTML逃逸
=============

由于Flask默认响应是返回HTML,所以如果用户提供的值渲染时候需要防范输入特殊的HTML内容,例如,如果用户恶意嵌入一段 JS 代码,必须阻止渲染成HTML,否则就会导致在浏览器中执行恶意脚本。这种技术称为HTML逃逸(HTML Escaping)。

Flask 使用的 HTML 渲染模版 `Jinja2 template <http://quintagroup.com/cms/python/jinja2>`_ 已经内嵌了自动防范的功能,也就是说用户恶意注入JS会被自动阻止渲染。不过,这个 ``escape()`` 也可以人工添加:

.. literalinclude:: flask_startup/flask_escape.py
:language: python
:caption: 明确编写 ``escape()`` 防止恶意注入JS
:emphasize-lines: 2,8

此时用户在浏览器中输入 http:://127.0.0.1:5000/<script>alert("bad")</script> 这样的注入,就会直接被拒绝渲染,页面提示::

Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

.. note::

注意, `Jinja2 template <http://quintagroup.com/cms/python/jinja2>`_ 已经内嵌了自动防范的功能,上述代码片段不使用 ``escape()`` 也是有同样效果的

所以用户只能输入正常的名字 如 http:://127.0.0.1:5000/huatai

此时页面才能正常渲染::

Hello,huatai!

参考
=======

- `Flask docs: Quickstart <https://flask.palletsprojects.com/en/2.3.x/quickstart/>`_
8 changes: 8 additions & 0 deletions source/flask/flask_startup/flask_escape.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from flask import Flask
from markupsafe import escape

app = Flask(__name__)

@app.route("/<name>")
def hello_world(name):
return f"Hello, {escape(name)}!"
1 change: 1 addition & 0 deletions source/flask/flask_startup/flask_hello_run
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask --app hello run
1 change: 1 addition & 0 deletions source/flask/flask_startup/flask_hello_run_debug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask --app hello run --debug
5 changes: 5 additions & 0 deletions source/flask/flask_startup/flask_hello_run_output
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Serving Flask app 'hello'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
1 change: 1 addition & 0 deletions source/flask/flask_startup/flask_hello_run_service
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask --app hello run --host=0.0.0.0 --port=5001
7 changes: 7 additions & 0 deletions source/flask/flask_startup/hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
2 changes: 2 additions & 0 deletions source/flask/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Flask Atlas
:maxdepth: 1

intro_flask.rst
install_flask.rst
flask_startup.rst
flask-admin/index

.. only:: subproject and html
Expand Down
40 changes: 40 additions & 0 deletions source/flask/install_flask.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.. _install_flask:

====================
安装Flask
====================

flask支持Python 3.8以及更新版本

:ref:`virtualenv`
=====================

- 安装和初始化 :ref:`virtualenv` :

.. literalinclude:: ../python/startup/virtualenv/apt_install_pip3_venv
:language: bash
:caption::ref:`ubuntu_linux` 22.04 LTS 安装 ``pip3`` 以及 ``venv``

.. literalinclude:: ../python/startup/virtualenv/venv
:language: bash
:caption: venv初始化

.. literalinclude:: ../python/startup/virtualenv/venv_active
:language: bash
:caption: 激活venv

然后在 :ref:`virtualenv` 就可以继续使用 ``pip`` 安装Flask了

安装
=======

- 使用pip安装flask:

.. literalinclude:: install_flask/pip_install_flask
:caption: 使用pip安装flask

参考
=====

- `Flask docs: Installation <https://flask.palletsprojects.com/en/2.3.x/installation/>`_
- ``OReilly Flak Web Development 2nd Edition``
1 change: 1 addition & 0 deletions source/flask/install_flask/pip_install_flask
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pip install flask
13 changes: 12 additions & 1 deletion source/flask/intro_flask.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ Flask比Django更为轻量级,主要因为它是一个微框架,而不像Dja
Flask依赖以下开源项目:

- `Werkzeug WSGI toolkit <http://werkzeug.pocoo.org/>`_
- `Jinja2 template <http://quintagroup.com/cms/python/jinja2>`_
- `Jinja2 template <http://quintagroup.com/cms/python/jinja2>`_
- `MarkupSafe <https://palletsprojects.com/p/markupsafe/>`_ 随Jinja提供,渲染模版是避免注入攻击
- `ItsDangerous <https://palletsprojects.com/p/itsdangerous/>`_ 对数据进行安全签名确保完整性,用于保护flask的会话cookie
- `click command line interfaces <https://click.palletsprojects.com/>`_ 编写命令行应用程序的框架,提供了flask命令以及允许添加定制的管理命令
- `Blinker <https://blinker.readthedocs.io/>` 实现 ``Signals`` 功能(轻量级订阅通知)

Flask 并不原生支持数据库、Web表单、用户认证等高级功能,这些功能以及大多数Web程序所需的关键服务都以扩展的方式集成到核心包:

- 开发者可以任意选择符合项目需求的扩展,甚至自己开发(这和大型框架已经集成并且难以替换的方案不同)


参考
======

- `The Best Python Web Frameworks 2023 <https://dev.to/theme_selection/the-best-python-web-frameworks-d2d>`_
- `Flask vs Django: A Detailed Comparison of Python Web Frameworks <https://www.monocubed.com/blog/flask-vs-django/>`_
- `CherryPy Vs Flask – Which Is The Better Framework for Python? <https://www.monocubed.com/blog/cherrypy-vs-flask/>`_
- ``OReilly Flak Web Development 2nd Edition``
- `Flask docs: Installation <https://flask.palletsprojects.com/en/2.3.x/installation/>`_

0 comments on commit b2e5c45

Please sign in to comment.