本文内容已过时,云梯0.98b版本开始,直接支持向Bambook中传送原生EPUB格式文件,不再需要用本文的方法去折腾了。
上一篇Blog中提供了在Bambook上阅读EPUB书籍一个折腾方法,但那个方法显然很tricky,依赖环境多,成功率低,要传多本图书更复杂。这次又折腾出个改进版的方法,虽然也比较复杂,但成功率比以前高多了,而且也更直观好用,分享给大家。原理:用calibre提供的OPDS服务,把这个服务器添加到Bambook的第三方书城列表中。用到的软件和技术跟以前差不多:calibre,DNS劫持,nginx反向代理与rewrite。
前提条件:有一台正常上网的电脑A,Bambook用无线上网并在上网过程中可以访问到电脑A。或者,有两台电脑(可以是虚拟机)A和B,A用来做服务器,B上安装云梯给Bambook共享网络,AB之间也可以相互访问。
1. 在电脑A上下载安装nginx for Windows
http://nginx.org/download/nginx-1.1.15.zip
下载后,解压缩到C:\,得到C:\nginx-1.1.15
2. 配置nginx,实现Web服务和反向代理
用记事本打开C:\nginx-1.1.15\conf\nginx.conf,把它修改成以下内容,其中的192.168.8.102为A电脑的IP地址,请自行替换(下同):
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name opds.gk.sdo.com;
location / {
proxy_pass http://$http_host$request_uri;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
rewrite ^.*Default.aspx.*$ http://192.168.8.102:81/1.xml redirect;
}
}
server {
listen 81;
location / {
root html;
index index.html index.htm;
}
}
sendfile on;
keepalive_timeout 65;
}
3. 在C:\nginx-1.1.15\html中创建1.xml文件,内容如下,使用UTF-8编码(如果用记事本,那就需要用“另存为”对话框,把下面的“编码”由ANSI改为UTF-8)。
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:opds="http://opds-spec.org/2010/catalog" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/" xmlns="http://www.w3.org/2005/Atom">
<title type="text">锦书OPDS源列表</title>
<id>uuid:ea8a979d-7e28-4bf7-8d11-31aafb2ac66a;id=60</id>
<updated>2012-03-11T15:49:25Z</updated>
<link rel="search" type="application/atom+xml" href="http://opds.gk.sdo.com/Search.aspx?ST=ALL&PageIndex=1&k={searchTerms}&{bbtk}" />
<entry>
<id>JiuYue</id>
<title type="text">新华书店九月网</title>
<updated>2012-03-11T15:49:25Z</updated>
<link rel="alternate" type="application/atom+xml" href="http://opds.9yue.com/category.atom?site=BamBook" />
<content type="text">新华书店九月网</content>
</entry>
<entry>
<id>http://m.gutenberg.org/ebooks/?format=opds</id>
<title type="text">古腾堡计划</title>
<updated>2012-03-11T15:49:25Z</updated>
<link rel="alternate" type="application/atom+xml" href="http://m.gutenberg.org/ebooks/?format=opds" />
<content type="text">英文电子书</content>
</entry>
<entry>
<id>http://www.feedbooks.com/site/free_books.atom</id>
<title type="text">feedbooks</title>
<updated>2012-03-11T15:49:25Z</updated>
<link rel="alternate" type="application/atom+xml" href="http://www.feedbooks.com/site/free_books.atom" />
<content type="text">在线阅读网线图书</content>
</entry>
<entry>
<id>http://www.feedbooks.com/site/free_books.atom</id>
<title type="text">calibre</title>
<updated>2012-03-11T15:49:25Z</updated>
<link rel="alternate" type="application/atom+xml" href="http://192.168.8.102:8080/opds" />
<content type="text">calibre</content>
</entry>
</feed>
4. 启动nginx
双击运行C:\nginx-1.1.15\nginx.exe,用任务管理查看nginx进程,确认启动成功。如果用netstat -na检查,应该在80和81端口上有LISTENING。如果访问http://192.168.8.102:81/1.xml,可以看到上面我们建立的1.xml文件。
5. 安装Python 2.7
从http://www.python.org/getit下载Python Windows Installer并安装到C:\Python27目录。
6. 写Python脚本,建假DNS。把下面的内容存为C:\FakeDNS.py。同样,其中的192.168.8.102为A电脑的IP地址,请自行替换。
#! /usr/bin/env python
# This code comes from
# http://code.activestate.com/recipes/491264-mini-fake-dns-server/
# with some modifications
import socket
class DNSQuery:
def __init__(self, data):
self.data=data
self.domain=''
tipo = (ord(data[2]) >> 3) & 15
if tipo == 0:
ini=12
lon=ord(data[ini])
while lon != 0:
self.domain+=data[ini+1:ini+lon+1]+'.'
ini+=lon+1
lon=ord(data[ini])
def respuesta(self, ip):
packet=''
if self.domain:
packet+=self.data[:2] + "\x81\x80"
packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00'
packet+=self.data[12:]
packet+='\xc0\x0c'
packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04'
packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.')))
return packet
if __name__ == '__main__':
udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('',53))
try:
while 1:
data, addr = udps.recvfrom(1024)
p = DNSQuery(data)
if p.domain == 'opds.gk.sdo.com.':
ip = '192.168.8.102'
else:
ip = socket.gethostbyname(p.domain)
udps.sendto(p.respuesta(ip), addr)
print p.domain + "=>" + ip
except KeyboardInterrupt:
udps.close()
7. 启动假DNS
在命行提示符中运行:
C:\Python27\python.exe C:\FakeDNS.py
启动后应该会停在那里,有请求时会打印出解析结果。可以再开一个窗口用nslookup确认它的工作状态:对于除了opds.gk.sdo.com以外的域名,都解析为正常IP地址;对于opds.gk.sdo.com.,解析为电脑A的IP地址。
8. Bambook设置
设置Bambook的无线连接,其中DNS服务器地址设为假DNS所在电脑A的IP地址。
如果采用两台电脑的方案,就把电脑B的网卡配置中的DNS指向电脑A的IP地址。然后连接Bambook与电脑B,让Bambook通过电脑B上网。
9. 启动calibre服务器
运行calibre,主界面下“连接/共享”->“启动连接服务”,这时calibre应该会在8080端口上启动http服务器,提供OPDS服务,可以通过访问http://127.0.0.1:8080/opds来验证。(这是在默认配置的情况下,如果有改变过配置,上面的1.xml做相应改动即可)
一切就绪,在Bambook上按“找书”->1.访问云中书城->*.切换到第三方书库,或者最新固件上书架主菜单中选3.更多书城,就可以看到被我们“篡改”过的第三方书城列表,选择其中的5. calibre,就可以尽情的享用你本地calibre书库中的EPUB图书了。
注意:这个方法只支持Bambook从calibre书库中下载EPUB格式的图书。如果书城列表获取不正常,可能是DNS缓存的问题,重启Bambook后再试一次。
calibre除了自带的OPDS连接服务,也可以用calibre2opds这个软件来提供更美好的OPDS服务器,以后另文介绍calibre2opds。