104 lines
2.9 KiB
Python
104 lines
2.9 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2012 Adam Sutton <dev@adamsutton.me.uk>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, version 3 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
"""
|
|
This is a very simple HTSP client library written in python mainly just
|
|
for demonstration purposes.
|
|
|
|
Much of the code is pretty rough, but might help people get started
|
|
with communicating with HTSP server
|
|
"""
|
|
|
|
import htsmsg
|
|
import log
|
|
|
|
# ###########################################################################
|
|
# HTSP Client
|
|
# ###########################################################################
|
|
|
|
HTSP_PROTO_VERSION = 6
|
|
|
|
# Create passwd digest
|
|
def htsp_digest ( user, passwd, chal ):
|
|
import hashlib
|
|
ret = hashlib.sha1(passwd + chal).digest()
|
|
return ret
|
|
|
|
# Client object
|
|
class HTSPClient:
|
|
|
|
# Setup connection
|
|
def __init__ ( self, addr, name = 'HTSP PyClient' ):
|
|
import socket
|
|
|
|
# Setup
|
|
self._sock = socket.create_connection(addr)
|
|
self._name = name
|
|
self._auth = None
|
|
self._user = None
|
|
self._pass = None
|
|
|
|
# Send
|
|
def send ( self, func, args = {} ):
|
|
args['method'] = func
|
|
if self._user: args['username'] = self._user
|
|
if self._pass: args['digest'] = htsmsg.hmf_bin(self._pass)
|
|
log.debug('htsp tx:')
|
|
log.debug(args, pretty=True)
|
|
self._sock.send(htsmsg.serialize(args))
|
|
|
|
# Receive
|
|
def recv ( self ):
|
|
ret = htsmsg.deserialize(self._sock, False)
|
|
log.debug('htsp rx:')
|
|
log.debug(ret, pretty=True)
|
|
return ret
|
|
|
|
# Setup
|
|
def hello ( self ):
|
|
args = {
|
|
'htspversion' : HTSP_PROTO_VERSION,
|
|
'clientname' : self._name
|
|
}
|
|
self.send('hello', args)
|
|
resp = self.recv()
|
|
|
|
# Store
|
|
self._version = min(HTSP_PROTO_VERSION, resp['htspversion'])
|
|
self._auth = resp['challenge']
|
|
|
|
# Return response
|
|
return resp
|
|
|
|
# Authenticate
|
|
def authenticate ( self, user, passwd = None ):
|
|
self._user = user
|
|
if passwd:
|
|
self._pass = htsp_digest(user, passwd, self._auth)
|
|
self.send('authenticate')
|
|
resp = self.recv()
|
|
if 'noaccess' in resp:
|
|
raise Exception('Authentication failed')
|
|
|
|
# Enable async receive
|
|
def enableAsyncMetadata ( self, args = {} ):
|
|
self.send('enableAsyncMetadata', args)
|
|
|
|
# ############################################################################
|
|
# Editor Configuration
|
|
#
|
|
# vim:sts=2:ts=2:sw=2:et
|
|
# ############################################################################
|