Git Product home page Git Product logo

owllook's Introduction

owllook - 在线小说搜索引擎

Python3.6+ license

owllook是一个基于其他搜索引擎构建的垂直小说搜索引擎,owllook目的是让阅读更简单、优雅,让每位读者都有舒适的阅读体验,如搜书、阅读、收藏、追更、推荐等功能

img

衍生项目:

注意:若将本项目部署并发行,请声明来源,本项目纯属共享学习之用,不得用于商业!

Overview

owllook使用了mongodb储存了用户使用过程中的产生的基本信息,诸如注册信息、搜索小说信息、收藏小说数据等,对于某些必要的缓存,则利用redis进行缓存处理,如小说缓存、session缓存,注意,对于限制数据:都将在24小时删除

对于不同网站的小说,页面规则都不尽相同,我希望能够在代码解析后再统一展示出来,这样方便且美观,而不是仅仅跳转到对应网站就完事,清新简洁的阅读体验才是最重要的

目前采用的是直接在搜索引擎上进行结果检索,我尽量写少量的规则来完成解析,具体见规则定义,遇到自己喜欢的小说网站,你也可以自己添加解析,owllook目前解析了超过 200+ 网站,追更网站解析了50+

有一些地方需要用到爬虫,比如说排行榜,一些书籍信息等,我不想动用重量级爬虫框架来写,于是我在owllook里面编写了一个很轻量的爬虫框架来做这件事,见 ruia

BTW,sanic写界面确实不是很方便,至于为什么写这个,一是想利用sanic尽量做成异步服务,二是想就此练习下推荐系统,顺便作为毕业设计

Installation

请先装好mongo以及redis,不会安装mongo看这里owllook使用pipenv管理虚拟环境,所以使用前请确保安装一个Python3.6环境(比如我这里环境路径在/Users/howie/anaconda3/envs/python36/bin/python3.6),然后安装好pipenv

mongo以及redis装好后,进入项目目录,依照步骤执行:

# 下载代码
git clone https://github.com/howie6879/owllook
cd owllook
pip install pipenv
# 请先提前创建好Python3.6环境
pipenv install --python /Users/howie/anaconda3/envs/python36/bin/python3.6 --skip-lock
# 进入虚拟环境
pipenv shell

# 先配置好相关数据库配置,具体看`config/dev_config.py`

# 方案一
# 运行:
cd owllook
pipenv run gunicorn -c owllook/config/gunicorn.py --worker-class sanic.worker.GunicornWorker owllook.server:app

# 方案二 推荐 
# 安装docker并打包镜像
docker build -t howie6879/owllook .
# 实际运行
docker-compose up -d
# 退出
docker-compose down

Features

  • 多搜索源
  • 丰富的解析源
  • 界面统一解析
  • 完善的阅读体验
  • 搜索记录
  • 缓存
  • 书架
  • 书签
  • 登录
  • 初步兼容手机(后续跟进)
  • 注册(开放注册)
  • 上次阅读记录
  • 最新章节
  • 书友推荐(简单地基于相似度进行推荐)
  • 目录获取
  • 翻页
  • 搜索排行
  • 章节异步加载 感谢@mscststs
  • 排行榜 - 起点+owllook
  • 自带爬虫框架,统一爬虫规范,对爬虫感兴趣的可以看看 - ruia

TODO

  • 评分
  • 阅读书单
  • 推荐
  • 小说圈 - 小说界的消息

Screenshots

首页:

搜索:

榜单:

书架:

books

目录解析页:

demo

阅读:

content

FAQ

为什么首页榜单为空白?

这个是根据小说搜索次数显示的,每天刷新一次,使用多了就会有

为什么会出现302跳转?

为了防止直接运行服务被恶意域名绑定,所以作出如下修改:

vim config/config.py
# 将 true 改为 false
VAL_HOST = os.getenv('VAL_HOST', 'true')
VAL_HOST = os.getenv('VAL_HOST', 'false')

小说榜单页面为什么没有内容?

需要运行owllook/spiders/spider_console.py, 目前代码中是设定60分钟运行一次,运行的时候请酌情更改, os.environ['MODE'] = 'PRO' 这段代码也请注释掉

Reference

owllook使用了以下第三方包:

  • sanic:基于Python 3.5+的异步web服务器

  • motor:异步的mongodb驱动

  • ​Jinja2:基于python的模板引擎

  • aiohttp:异步请求

  • caddy:基于go的web服务器

    …...更多见Pipfile,感谢开发者

web框架:

  • bootstrap:Sleek, intuitive, and powerful front-end framework for faster and easier web development.
  • mdui:MDUI 是一个基于 Material Design 的前端框架

License

owllook is offered under the Apache 2 license.

Donate

捐赠:

美酒加咖啡,我只要喝一杯~

donate

感谢以下捐赠者,具体见捐赠名单 ^_^

owllook's People

Contributors

dependabot[bot] avatar fuxuemingzhu avatar howie6879 avatar mashpolo avatar mscststs avatar putengfi avatar ruiruizhou avatar zhiyue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

owllook's Issues

按照 readme 无法正常启动

python 小白,不是很懂,原本准备自己造一个小说采集器,故找到了这个项目

环境是 ubuntu,安装了 python3,通过如下的命令启动
启动命令:python3 novels_search/server.py

2017-04-05 03:57:05,659 WARNING aiocache.log(13) | cPickle module not found, using pickle
Traceback (most recent call last):
File "novels_search/server.py", line 12, in
from novels_search.views.novels_blueprint import novels_bp
ImportError: No module named 'novels_search'

安装模块的时候,是不是哪里不对,没安装成功
root@localhost:~/novels-search# python3 setup.py install
running install
Checking .pth file support in /usr/local/lib/python3.5/dist-packages/
/usr/bin/python3 -E -c pass
TEST PASSED: /usr/local/lib/python3.5/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
writing novels_search.egg-info/PKG-INFO
writing dependency_links to novels_search.egg-info/dependency_links.txt
writing top-level names to novels_search.egg-info/top_level.txt
reading manifest file 'novels_search.egg-info/SOURCES.txt'
writing manifest file 'novels_search.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
warning: install_lib: 'build/lib' does not exist -- no Python modules to install

creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying novels_search.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying novels_search.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying novels_search.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying novels_search.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/novels_search-0.0.0-py3.5.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing novels_search-0.0.0-py3.5.egg
Removing /usr/local/lib/python3.5/dist-packages/novels_search-0.0.0-py3.5.egg
Copying novels_search-0.0.0-py3.5.egg to /usr/local/lib/python3.5/dist-packages
novels-search 0.0.0 is already the active version in easy-install.pth

Installed /usr/local/lib/python3.5/dist-packages/novels_search-0.0.0-py3.5.egg
Processing dependencies for novels-search==0.0.0
Finished processing dependencies for novels-search==0.0.0

ModuleNotFoundError: No module named 'aiocache.utils

你好,我很高兴可以找到类似的项目.
我编译时出现了问题:
/Users/yuhang/Android/python/owllook-master/venv/bin/python /Users/yuhang/Android/python/owllook-master/owllook/server.py
msgpack not installed, MsgPackSerializer unavailable
[2018-11-05 17:14:14,818] 37407-INFO init::load_config():l24: owllook 启动模式:DEV
Traceback (most recent call last):
File "/Users/yuhang/Android/python/owllook-master/owllook/server.py", line 12, in
from owllook.views import admin_bp, api_bp, except_bp, md_bp, novels_bp, operate_bp
File "/Users/yuhang/Android/python/owllook-master/owllook/views/init.py", line 1, in
from .admin_blueprint import admin_bp
File "/Users/yuhang/Android/python/owllook-master/owllook/views/admin_blueprint.py", line 9, in
from owllook.fetcher.cache import get_the_latest_chapter
File "/Users/yuhang/Android/python/owllook-master/owllook/fetcher/cache.py", line 16, in
from owllook.fetcher.decorators import cached
File "/Users/yuhang/Android/python/owllook-master/owllook/fetcher/decorators.py", line 10, in
from aiocache.utils import get_args_dict, get_cache
ModuleNotFoundError: No module named 'aiocache.utils'

进入到 decorators.py文件发现有问题文件过时了

from aiocache.log import logger
from aiocache.utils import get_args_dict, get_cache

导入文件的时候 logger get_args_dict, get_cache 这两个方法没有

目前最新的方法是封装成了类.
我不知道该怎么解决.可以帮助我吗

最新的:
https://github.com/argaen/aiocache/blob/634348f40ce8caa01c7c35010acf32d8c3e17ba6/aiocache/decorators.py

排行榜数据为空

你好,我的部署方式为docker-compose,具体截图如下:
docker-compose.yml

目前的问题是,排行榜打开后数据为空,具体截图如下:
default

麻烦排查一下是不是部署方式存在问题导致的!

怎么才能让它随系统自启动?我用的debian9

Create a service:

sudo vi /etc/systemd/system/rc-local.service
Add your code there:
[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target

Create and make sure /etc/rc.local is executable and add this code inside it:

sudo chmod +x /etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exit 0

Enable the service:
sudo systemctl enable rc-local
Start service and check status:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

/etc/rc.local中这么写的。
image
发现不行,也没有提示错误信息。
求帮助

Set of coroutines/Futures is empty.

时不时会报这个错误,是啥原因造成的呢?
而且我也没有找到requirements.txt。

ValueError
Set of coroutines/Futures is empty.
Traceback (most recent call last):

File /Users/cals/.local/share/virtualenvs/Owllook-4Lm_G_fn/lib/python3.6/site-packages/sanic/app.py, line 556, in handle_request

response = await response

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/views/novels_blueprint.py, line 303, in owllook_search

parse_result = await get_novels_info(class_name='baidu', novels_name=novels_name)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/fetcher/novels_tools.py, line 13, in get_novels_info

novels_info = await novels_module.start(novels_name)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/fetcher/decorators.py, line 128, in wrapper

result = await func(*args, **kwargs)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/fetcher/novels_factory/baidu_novels.py, line 101, in start

return await BaiduNovels.start(novels_name)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/fetcher/novels_factory/base_novels.py, line 48, in start

return await cls().novels_search(novels_name)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py, line 110, in __next__

return self.gen.send(None)

File /Users/cals/PycharmProjects/Owllook/owllook/fetcher/novels_factory/baidu_novels.py, line 88, in novels_search

done_list, pending_list = await asyncio.wait(tasks)

File /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py, line 304, in wait

raise ValueError('Set of coroutines/Futures is empty.')

ValueError: Set of coroutines/Futures is empty. while handling path /search

访问问题

image
我在VPS上成功安装和部署了项目, VPS是可以访问的,但是在别的地址访问就是会跳转到https://www.owllook.net/ 请问一下这个是在什么地方配置

使用docker的方法,搭建好,用我的ip:8001,怎么会跳转到https://www.owllook.net/这里?

直接下载镜像
docker pull howie6879/owllook
创建dev_owllook.env文件
vim dev_owllook.env
写入一些环境变量,改成了我的设置,如下
MODE=DEV
REDIS_ENDPOINT= 127.0.0.1
REDIS_PORT= 6379
REDIS_PASSWORD=''
MONGO_HOST= 127.0.0.1
MONGO_PORT= 27017
MONGO_USERNAME=''
MONGO_PASSWORD=''
运行下面的
docker run --env-file ./dev_owllook.env -d -p 8001:8001 howie6879/owllook:lates
访问
ip:8001
为什么会跳转到https://www.owllook.net,你的网站了。
哪里有出错了?
谢谢

另一个分类方法

我有一个想法,仅供参考。
目前的分类机制是对于一个书名,有不同的提供网站。
但实际上每本书都有一个或几个官方发布网站,网站可以抓取到书的目录和每一章的前两段,那么
1.通过网友的共同劳动,像Wiki一样建立一个书名与官方发布页面地址的映射目录。
2.抓取官方发布的目录建立书籍的目录,然后通过每章前两段内容与其他网站内容的比对抽取完整章节。
而不用显示多个源。

可能存在以下问题
1.抓取官方目录和前两段可能涉嫌侵权。
2.文字对比可能正确率低。

我又用debian9试着装,出现这个问题

我又用debian9试着装,
debian9上安装了宝塔面板,搭建了lnmp
在安装你的教程,安装,都蛮顺利的,到这里
(python36) root@ip-172-26-13-169:/owllook# pipenv run pip install pip==18.0
Creating a virtualenv for this project…
Pipfile: /root/owllook/Pipfile
Using /root/anaconda3/envs/python36/bin/python3.6m (3.6.8) to create virtualenv…
⠦ Creating virtual environment...Using base prefix '/root/anaconda3/envs/python36'
New python executable in /root/.local/share/virtualenvs/owllook-kjRL-ddR/bin/python3.6m
Also creating executable in /root/.local/share/virtualenvs/owllook-kjRL-ddR/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /root/anaconda3/envs/python36/bin/python3.6m
✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/owllook-kjRL-ddR
Collecting pip==18.0
Downloading https://files.pythonhosted.org/packages/5f/25/e52d3f31441505a5f3af41213346e5b6c221c9e086a166f3703d2ddaf940/pip-18.0-py2.py3-none-any.whl (1.3MB)
100% |████████████████████████████████| 1.3MB 19.0MB/s
Installing collected packages: pip
Found existing installation: pip 19.0
Uninstalling pip-19.0:
Successfully uninstalled pip-19.0
Successfully installed pip-18.0
(python36) root@ip-172-26-13-169:
/owllook# pipenv install
Installing dependencies from Pipfile.lock (39f5cc)…
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 15/52

进行到15/52这里时,不动了,不知道是什么情况?

新的docker镜像无法启动

报错信息如下:
novel | [2018-12-14 13:31:49,682] 12-INFO log::info():l15: GET: http://r.qidian.com/?chn=1 novel | [2018-12-14 13:31:49,974] 12-ERROR log::exception():l30: there are no users authenticated novel | Traceback (most recent call last): novel | File "/opt/owllook/spiders/qidian_ranking.py", line 93, in save novel | upsert=True) novel | File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run novel | result = self.fn(*self.args, **self.kwargs) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/collection.py", line 995, in update_one novel | session=session), novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/collection.py", line 851, in _update_retryable novel | _update, session) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1243, in _retryable_write novel | return self._retry_with_session(retryable, func, s, None) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1196, in _retry_with_session novel | return func(session, sock_info, retryable) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/collection.py", line 847, in _update novel | retryable_write=retryable_write) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/collection.py", line 817, in _update novel | retryable_write=retryable_write).copy() novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/pool.py", line 579, in command novel | unacknowledged=unacknowledged) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/network.py", line 150, in command novel | parse_write_concern_error=parse_write_concern_error) novel | File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.6/site-packages/pymongo/helpers.py", line 155, in _check_command_response novel | raise OperationFailure(msg % errmsg, code, response) novel | pymongo.errors.OperationFailure: there are no users authenticated

建议每次发docker包使用新的tag ,这样可以使用指定的tag运行 ,现在看tag全都是latest

新增网站检测机制

有些网站看书可以解析出来目录 ,点击目录之后出现500异常,建议增加检测机制检测是否可以看

加入书架问题

加入书架按钮从源码上来看是

<p>状    态:连载中,
  <a href="javascript:;" onclick="addBookCase(43995);" rel="nofollow">加入书架</a>,
  <a href="#footer">直达底部</a>
</p>

而 这个 href="javascript:;" 在浏览器(chrome, firefox)中均被解析为http://www.owllook.net/owllook_content?url=http://www.23txt.com/javascript:;&name=...打开了一个新页面,而没有触发 addBookCase 函数

改成 href="javascript:void(0)" 应该就ok了:smile:

浏览小说内容的时候,上下章按钮无反应/只能加载上、下一章

新增全本排行榜

目前开发完成的排行榜包含起点排行和纵横排行 ,可能很多的人比较热衷于看全本 ,建议开发一个全本排行

正常启动,但redis出错,无法进行爬虫

如题:python3 server.py出现如下错误:

owllook/fetcher/cache.py", line 52, in wrapper
    if await cache_instance.exists(cache_key):
  File "/usr/lib/python3.5/asyncio/coroutines.py", line 105, in __next__
    return self.gen.send(None)
......
exists = await redis.exists(key)
AttributeError: 'RedisConnection' object has no attribute 'exists'

版本:Python 3.5.2

KeyError: 'session' while handling path /

按正常方式安装的屏蔽了redirect,host已经改为0.0.0.0
python server.py 之后就报错
KeyError
'session'
Traceback (most recent call last):
File /root/.local/share/virtualenvs/owllook-kjRL-ddR/lib/python3.6/site-packages/sanic/app.py, line 556, in handle_request
response = await response
File /root/.miniconda3/lib/python3.6/asyncio/coroutines.py, line 110, in next
return self.gen.send(None)
File /root/owllook/owllook/views/novels_blueprint.py, line 82, in index
user = request['session'].get('user', None)
KeyError: 'session' while handling path /

未发现pro_config.py

如题,代码里有如下:
if mode == 'PRO':
from .pro_config import ProConfig
return ProConfig

建议收录一些文学站

建议收录一些文学站点(我搜到过《活着》,但是打开提示Internal Server Error),增加用户面

搜索一念永恒

出现bug

Internal Server Error

The server encountered an internal error and cannot complete your request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.