root/docs.py

Revision 1469, 7.5 kB (checked in by Alexandre Rossi <alexandre.rossi@…>, 3 months ago)

[doc] rename protocol doc file to be consistent with new protocol

Line 
1#!/usr/bin/env python
2
3# Deejayd, a media player daemon
4# Copyright (C) 2007-2009 Mickael Royer <mickael.royer@gmail.com>
5#                         Alexandre Rossi <alexandre.rossi@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21"""
22Use to create documentation of the protocol
23"""
24
25# init translation
26import gettext
27from deejayd.ui.i18n import DeejaydTranslations
28try: t = gettext.translation("deejayd", class_=DeejaydTranslations)
29except IOError:
30    t = DeejaydTranslations()
31t.install()
32
33from twisted.python import reflect
34from deejayd.mediafilters import *
35from deejayd.interfaces import DeejaydSignal
36from deejayd.rpc import protocol
37from deejayd.rpc.jsonbuilders import JSONRPCResponse, JSONRPCRequest,\
38                                     Get_json_filter, DeejaydJSONSignal
39
40common_request = [
41        {"prefix": "", "desc": "General Commands",\
42                       "object": protocol._DeejaydMainJSONRPC},
43        {"prefix": "player.", "desc": "Player Commands",\
44                       "object": protocol.DeejaydPlayerJSONRPC},
45        {"prefix": "audiolib.", "desc": "Audio Library Commands",\
46                       "object": protocol.DeejaydAudioLibraryJSONRPC},
47        {"prefix": "videolib.", "desc": "Video Library Commands",\
48                       "object": protocol.DeejaydVideoLibraryJSONRPC},
49        {"prefix": "playlist.", "desc": "Playlist Mode Commands",\
50                       "object": protocol.DeejaydPlaylistModeJSONRPC},
51        {"prefix": "panel.", "desc": "Panel Mode Commands",\
52                       "object": protocol.DeejaydPanelModeJSONRPC},
53        {"prefix": "video.", "desc": "Video Mode Commands",\
54                       "object": protocol.DeejaydVideoModeJSONRPC},
55        {"prefix": "webradio.", "desc": "Webradio Mode Commands",\
56                       "object": protocol.DeejaydWebradioModeJSONRPC},
57        {"prefix": "dvd.", "desc": "Dvd Mode Commands",\
58                       "object": protocol.DeejaydDvdModeJSONRPC},
59        {"prefix": "queue.", "desc": "Queue Commands",\
60                       "object": protocol.DeejaydQueueJSONRPC},
61        {"prefix": "queue.", "desc": "Queue Commands",\
62                       "object": protocol.DeejaydQueueJSONRPC},
63        {"prefix": "recpls.", "desc": "Recorded Playlist Commands",\
64                       "object": protocol.DeejaydRecordedPlaylistJSONRPC},
65    ]
66
67class WikiFormat:
68
69    def commandDoc(self):
70        return """
71As written in specification, request is like that :
72{{{
73`%(request)s`
74}}}
75
76""" % {
77    "request": JSONRPCRequest("method_name",\
78                          ["params1", "params2"], id="id").to_pretty_json(),\
79    }
80
81    def answerDoc(self):
82        return """
83As written in specification, response is like that :
84{{{
85%s
86}}}
87
88For deejayd, result parameter has always the same syntax :
89{{{
90`{
91    "type": answer_type,
92    "answer": the real answer value
93}`
94}}}
95With response types equals to:
96    * ack
97    * list
98    * dict
99    * mediaList
100    * dvdInfo
101    * fileAndDirList
102""" % JSONRPCResponse("deejayd_response", "id").to_pretty_json()
103
104    def formatSectionDoc(self, section):
105        cmds = reflect.prefixedMethodNames(section["object"], 'jsonrpc_')
106        cmds = [getattr(section["object"], 'jsonrpc_%s'%cmd) for cmd in cmds]
107        return """
108=== `%(section)s` ===
109
110%(commands)s
111""" % {
112        "section": section["desc"],
113        "commands": "\n\n".join(map(self.formatCommandDoc, cmds,\
114                        [section["prefix"] for i in range(len(cmds))])),
115    }
116
117    def formatCommandDoc(self, cmd, prefix = ""):
118        args = ''
119
120        command_args = cmd.params or []
121        for arg in command_args:
122            props = []
123
124            # An argument is optional by default
125            if 'req' not in arg.keys():
126                arg['req'] = False
127            if arg['req']:
128                props.append('Mandatory')
129            else:
130                props.append('Optional')
131
132            args += "  * {{{%(name)s}}} (%(props)s) : %(type)s\n"\
133                        % { 'name':  arg['name'],
134                            'props': ' and '.join(props),
135                            'type' : arg['type'] }
136
137        if len(command_args) == 0:
138            args = "  * ''This command does not accept any argument.''\n"
139
140        rvalues = None
141        try:
142            if isinstance(cmd.answer_type, list):
143                rvalues = cmd.answer_type
144            else:
145                rvalues = [cmd.answer_type]
146        except AttributeError:
147            rvalues = ['ack']
148
149        return """==== `%(name)s` ====
150
151%(desc)s
152
153Arguments :
154%(args)s
155Expected return value : ''`%(rvalues)s`''
156
157""" % { 'name'    : prefix+cmd.__name__[8:],
158        'desc'    : cmd.__doc__.strip('\n'),
159        'args'    : args,
160        'rvalues' : rvalues }
161
162    def build(self, sections):
163        filter = And(Equals("artist", "artist_name"),\
164                Or(Contains("genre", "Rock"), Higher("Rating", "4")))
165        signal = DeejaydSignal("signal_name", {"attr1": "value1"})
166        return """= deejayd - JSON-RPC Protocol =
167
168Deejayd protocol follows JSON-RPC 1.0 specification available
169[http://json-rpc.org/wiki/specification here].
170All data between the client and server is encoded in UTF-8.
171
172== Commands Format ==
173
174%(cmd_format)s
175
176== Response Format ==
177
178%(answer)s
179
180== Specific Objects ==
181
182=== Mediafilter Objects ===
183
184Mediafilter object has been serialized in a specific way to be passed as
185an method argument or receive with an answer. An example is given here.
186{{{
187`%(filter)s`
188}}}
189
190=== Signal Objects ===
191
192Signal is available for TCP connection only.
193Signal object has been serialized in a specific way to be send to client.
194An example is given here.
195{{{
196`%(signal)s`
197}}}
198
199== Common Available Commands ==
200
201%(commands)s
202
203== Http Specific Commands ==
204
205=== General Commands ===
206
207%(serverinfo_cmd)s
208
209%(web_commands)s
210
211== TCP Specific Commands ==
212
213=== General Commands ===
214
215%(close_cmd)s
216
217%(tcp_commands)s
218""" % {
219        "cmd_format": self.commandDoc(),
220        "answer": self.answerDoc(),
221        "filter": Get_json_filter(filter).to_pretty_json(),
222        "commands": "\n\n".join(map(self.formatSectionDoc, sections)),
223        "signal": DeejaydJSONSignal(signal).to_pretty_json(),
224        "web_commands": self.formatSectionDoc({\
225                "prefix": "web.",
226                "desc": "Commands specific to webui",
227                "object": protocol.DeejaydWebJSONRPC,
228            }),
229        "tcp_commands": self.formatSectionDoc({\
230                "prefix": "signal.",
231                "desc": "Signal subscription commands",
232                "object": protocol.DeejaydSignalJSONRPC,
233            }),
234        "serverinfo_cmd": self.formatCommandDoc(\
235                protocol.DeejaydHttpJSONRPC.jsonrpc_serverInfo),
236        "close_cmd": self.formatCommandDoc(\
237                protocol.DeejaydTcpJSONRPC.jsonrpc_close),
238    }
239
240if __name__ == "__main__":
241    docs = WikiFormat().build(common_request)
242
243    f = open("doc/deejayd_rpc_protocol","w")
244    try: f.write(docs)
245    finally: f.close()
246
247
248# vim: ts=4 sw=4 expandtab
Note: See TracBrowser for help on using the browser.