You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.8 KiB
155 lines
5.8 KiB
#!/usr/bin/python
|
|
|
|
# rtorrent_xmlrpc
|
|
# (c) 2011 Roger Que <alerante@bellsouth.net>
|
|
#
|
|
# Modified portions:
|
|
# (c) 2013 Dean Gardiner <gardiner91@gmail.com>
|
|
#
|
|
# Python module for interacting with rtorrent's XML-RPC interface
|
|
# directly over SCGI, instead of through an HTTP server intermediary.
|
|
# Inspired by Glenn Washburn's xmlrpc2scgi.py [1], but subclasses the
|
|
# built-in xmlrpclib classes so that it is compatible with features
|
|
# such as MultiCall objects.
|
|
#
|
|
# [1] <http://libtorrent.rakshasa.no/wiki/UtilsXmlrpc2scgi>
|
|
#
|
|
# Usage: server = SCGIServerProxy('scgi://localhost:7000/')
|
|
# server = SCGIServerProxy('scgi:///path/to/scgi.sock')
|
|
# print server.system.listMethods()
|
|
# mc = xmlrpclib.MultiCall(server)
|
|
# mc.get_up_rate()
|
|
# mc.get_down_rate()
|
|
# print mc()
|
|
#
|
|
#
|
|
#
|
|
# 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; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# 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, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# In addition, as a special exception, the copyright holders give
|
|
# permission to link the code of portions of this program with the
|
|
# OpenSSL library under certain conditions as described in each
|
|
# individual source file, and distribute linked combinations
|
|
# including the two.
|
|
#
|
|
# You must obey the GNU General Public License in all respects for
|
|
# all of the code used other than OpenSSL. If you modify file(s)
|
|
# with this exception, you may extend this exception to your version
|
|
# of the file(s), but you are not obligated to do so. If you do not
|
|
# wish to do so, delete this exception statement from your version.
|
|
# If you delete this exception statement from all source files in the
|
|
# program, then also delete it here.
|
|
#
|
|
#
|
|
#
|
|
# Portions based on Python's xmlrpclib:
|
|
#
|
|
# Copyright (c) 1999-2002 by Secret Labs AB
|
|
# Copyright (c) 1999-2002 by Fredrik Lundh
|
|
#
|
|
# By obtaining, using, and/or copying this software and/or its
|
|
# associated documentation, you agree that you have read, understood,
|
|
# and will comply with the following terms and conditions:
|
|
#
|
|
# Permission to use, copy, modify, and distribute this software and
|
|
# its associated documentation for any purpose and without fee is
|
|
# hereby granted, provided that the above copyright notice appears in
|
|
# all copies, and that both that copyright notice and this permission
|
|
# notice appear in supporting documentation, and that the name of
|
|
# Secret Labs AB or the author not be used in advertising or publicity
|
|
# pertaining to distribution of the software without specific, written
|
|
# prior permission.
|
|
#
|
|
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
|
|
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
|
|
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
|
|
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
|
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
# OF THIS SOFTWARE.
|
|
|
|
|
|
import errno
|
|
import httplib
|
|
import re
|
|
import socket
|
|
import urllib
|
|
import xmlrpclib
|
|
|
|
|
|
class SCGITransport(xmlrpclib.Transport):
|
|
# Added request() from Python 2.7 xmlrpclib here to backport to Python 2.6
|
|
def request(self, host, handler, request_body, verbose=0):
|
|
#retry request once if cached connection has gone cold
|
|
for i in (0, 1):
|
|
try:
|
|
return self.single_request(host, handler, request_body, verbose)
|
|
except socket.error, e:
|
|
if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE):
|
|
raise
|
|
except httplib.BadStatusLine: #close after we sent request
|
|
if i:
|
|
raise
|
|
|
|
def single_request(self, host, handler, request_body, verbose=0):
|
|
# Add SCGI headers to the request.
|
|
headers = {'CONTENT_LENGTH': str(len(request_body)), 'SCGI': '1'}
|
|
header = '\x00'.join(('%s\x00%s' % item for item in headers.iteritems())) + '\x00'
|
|
header = '%d:%s' % (len(header), header)
|
|
request_body = '%s,%s' % (header, request_body)
|
|
|
|
sock = None
|
|
|
|
try:
|
|
if host:
|
|
host, port = urllib.splitport(host)
|
|
addrinfo = socket.getaddrinfo(host, int(port), socket.AF_INET,
|
|
socket.SOCK_STREAM)
|
|
sock = socket.socket(*addrinfo[0][:3])
|
|
sock.connect(addrinfo[0][4])
|
|
else:
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
sock.connect(handler)
|
|
|
|
self.verbose = verbose
|
|
|
|
sock.send(request_body)
|
|
return self.parse_response(sock.makefile())
|
|
finally:
|
|
if sock:
|
|
sock.close()
|
|
|
|
def parse_response(self, response):
|
|
p, u = self.getparser()
|
|
|
|
response_body = ''
|
|
while True:
|
|
data = response.read(1024)
|
|
if not data:
|
|
break
|
|
response_body += data
|
|
|
|
# Remove SCGI headers from the response.
|
|
response_header, response_body = re.split(r'\n\s*?\n', response_body,
|
|
maxsplit=1)
|
|
|
|
if self.verbose:
|
|
print 'body:', repr(response_body)
|
|
|
|
p.feed(response_body)
|
|
p.close()
|
|
|
|
return u.close()
|
|
|