使用 Flask 实现的 DAAP 服务器框架
项目描述
流媒体的 DAAP 服务器,围绕 Flask 微框架构建。支持 iTunes、艺术品和修订。
介绍。
数字音频访问协议 (DAAP) 是 Apple 设计的一种协议,用于通过网络共享媒体,使用 HTTP 作为传输层。它通过 Bonjour/Zeroconf 为自己做广告。
这个 Python 模块实现了完整的堆栈,提供了一个 HTTP 服务器(围绕 Flask 构建)、一个高级应用层和 Bonjour/Zeroconf 广告。
数据模型
DAAP 数据模型由以下实体组成:
服务器
数据库
容器
项目
容器物品
还有一些,但上面的已经实现了。
服务器包含数据库,数据库包含容器和项目,容器包含容器项目,容器项目是项目和容器之间的一对多映射。虽然 iTunes 的 DAAP 客户端实现仅支持每个服务器一个数据库(这是在 iTunes 中显示的数据库),但模型没有施加任何限制。因此,此实现不会阻止您将多个数据库添加到服务器。
DAAP 协议有效地更新实体。只有增量发送到客户端。为此,服务器必须向实体添加修订(版本)号,并将实体映射到修订。由于多个客户端可能处于不同的修订版,因此有必要跟踪所有修订版。当所有客户端都是最新的时,可以清除旧版本。
DAAP 协议假定字符串被编码为 UTF-8。因此,我们鼓励您尽可能使用 unicode 对象。
可变与不可变
Python 是一种不实现访问修饰符(私有/受保护/公共)的语言。因此,无论从哪里更改实例变量都可以。这使得实现不可变类型变得更加困难。Cython(将 Python 转换为 C)在某种意义上允许您添加这些修饰符。
计划支持不可变类型,但由于以下原因而放弃:
创建(复制)对象的成本很高,而且对象很多。
Cython 对象(扩展类型)在 Python 中应该是可子类化的,这会给修饰符带来问题。
DAAP 协议不关心对象内容。例如,如果obj_in_v3 是 obj_in_v4,并且您更改 了 obj_in_v4.name,任何仍然需要更新到修订版 3 的客户端都将收到修订版 4 中所做的更改。如果您想将客户端更新到最新版本,这不是问题.
请注意,此模块不会合并具有不同修订版本的相同 ID 的对象。例如,以下将失败:
db_rev1 = Database(id=1, name="My DB")
server.databases.add(db_rev1)
server.databases[1] is db_rev1 # Is True
db_rev1.items.add(Item(id=1, name="Song 1"))
db_rev1.items.add(Item(id=2, name="Song 2"))
db_rev1.items.add(Item(id=3, name="Song 3"))
db_rev2 = Database(id=2, name="My Updated DB")
server.databases.add(db_rev2)
server.databases[1] is db_rev2 # Is True
len(db_rev1.items) is not len(db_rev2.items) # Reference to items lost because
# db_rev1.items was overwritten.
如果您想要不变性,正确的方法如下:
db_rev2 = copy.copy(server.databases[1])
db_rev2.name = "My DB, version 2"
db_rev1.items is db_rev2.items # Is True
如果您不关心实际的不变性并且不介意中间版本都是相同的,甚至可以跳过该副本:
db_rev3 = server.databases[1]
db_rev3.name = "My DB, version 3"
db_rev1.items is db_rev2.items is db_rev3.items # Is True
db_rev2.name == db_rev3.name # Is True because db_rev3 is not a copy. However,
# the revisioning store will detect this as
# another update.
安装
确保已安装 Cython。需要显着提高某些模块的性能。
要安装,只需运行pip install flask-daapserver。它应该安装所有依赖项并编译基于 Cython 的模块。如果您想要最新版本,请键入 pip install git+https://github.com/basilfx/flask-daapserver。
升级通知
修订存储 API 在 v2.3.0 和 v3.0.0 版本之间发生了变化。由于修订的开销很大,因此决定应该减少内存使用和更快的访问。虽然 API 保持相似,但进行了一些更改:
现在需要 Cython。
全局对象存储已被删除。现在,每个容器都有自己的子容器存储。因此,以正确的顺序添加对象非常重要。例如,在将数据库添加到服务器之前不要将项目添加到数据库(模型不提供高级 ORM 功能)。
以前的版本修复了与 iTunes 12.1 的兼容性。出于某种原因,iTunes 预计第一个版本是两个。修复只是包括从 2 开始修订。这个版本删除了这个“解决方法”,现在期望第一个修订首先提交,例如首先设置初始结构。有关更多信息,请参阅示例。
已删除更改的自动提交。用户应手动提交。daapserver.models.BaseServer有一个提交方法,该 方法会将提交传播到所有附加的数据库、容器等。
daapserver.models.Collection上的added()和added( )方法 已替换为updated()。DAAP 协议在两者之间没有区别。
为了了解性能影响,utils/benchmark.py 脚本在内存使用方面产生了 108MB 和 196MB 的改进,时间上提高了 0.8375 秒和 4.3017 秒(100,000 个项目,Python 2.7.9,OS X 10.10,64 位) .
运行测试
包含几个单元测试来测试核心组件。可以使用python setup.py nosetests调用测试套件。
用法
查看示例,或使用 Flask-DAAPServer 的项目:
SubDaap ——SubSonic 和 iTunes 之间的桥梁。
例子
examples/目录中包含四个示例。您可以使用python examples/<filename>运行它们。检查来源以获取更多信息和详细信息。
ExampleServer.py — DAAP 服务器的最基本示例。
RevisionServer.py — 演示修订功能。
SoundcloudServer.py — 流式传输特定用户的所有曲目的 Soundcloud 服务器。需要客户端 ID 和 Soundcloud Python 模块。
贡献
随时提交拉取请求。所有拉取请求都必须针对开发分支提出。Python 代码应遵循 PEP-8 约定并经过测试(如果适用)。
执照
请参阅许可证文件(MIT 许可证)。
这项工作的一部分(DAAP 对象编码)基于 Davyd Madeley 的原作。