#!/usr/bin/env python '''Tool to upload graphical overlays to an NCast Telepresenter. Rewritten version by Matt Eastman Updated by H. S. Magnuski Usage: ncgo -d, --debug Turn debug statements on (not used) -h, --help Print usage information -p, --pswd=password Use "password" -v, --version Report program version -1, --g1 Overlay graphic 1 -2, --g2 Overlay graphic 2 -3, --g3 Overlay graphic 3 -4, --g4 Overlay graphic 4 ''' __author__ = 'Matt Eastman ' __version__ = '2.1 (meastman rewrite, updated)' import getopt import mimetools import mimetypes import os import sys import urllib import urllib2 def main(): debug = False username = 'api' password = 'ncast' images = {} try: getopt_func = getopt.gnu_getopt except AttributeError: getopt_func = getopt.getopt shortopts = 'dhp:v1:2:3:4:' longopts = ('debug', 'help', 'pswd=', 'version', 'g1=', 'g2=', 'g3=', 'g4=') try: opts, args = getopt_func(sys.argv[1:], shortopts, longopts) except getopt.GetoptError, e: print >>sys.stderr, 'Error: %s' % str(e) print >>sys.stderr usage(sys.stderr) sys.exit(1) for optname, optvalue in opts: if optname in ('-d', '--debug'): debug = True elif optname in ('-h', '--help'): usage(sys.stdout) sys.exit(0) elif optname in ('-p', '--pswd'): password = optvalue elif optname in ('-v', '--version'): print __version__ sys.exit(0) elif optname in ('-1', '-2', '-3', '-4', '--g1', '--g2', '--g3', '--g4'): imgnum = int(optname[-1]) if not os.path.exists(optvalue): raise Exception('Invalid image file', optvalue) images[imgnum] = optvalue else: raise Exception('BUG: should have caught %s but didn\'t' % `optname`) if not images: print >>sys.stderr, 'Error: no images specified' print >>sys.stderr usage(sys.stderr) sys.exit(1) if not args: print >>sys.stderr, 'Error: no server specified' print >>sys.stderr usage(sys.stderr) sys.exit(1) server = args[0] upload(server, username, password, images) def usage(stream): stream.write(__doc__) def upload(server, username, password, filenames): # build payload print 'ncgo: building payload' fields = {} for key, filename in filenames.items(): fields['overlay_%d_file' % key] = { 'filename': os.path.basename(filename), 'value': file(filename).read(), 'content-type': get_content_type(filename), } content_type, data = encode_multipart_formdata(fields) # upload print 'ncgo: uploading image(s)' url = 'http://%s/api.cgi' % server # Create an OpenerDirector with support for Basic HTTP Authentication... auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(realm='NCast Telepresenter', uri=url, user=username, passwd=password) opener = urllib2.build_opener(auth_handler) # ...and install it globally so it can be used with urlopen. urllib2.install_opener(opener) request = urllib2.Request(url, data) request.add_header('Content-Type', content_type) try: response = urllib2.urlopen(request) except urllib2.HTTPError, msg: print "ncgo: Urllib2 HTTP Error (%s)" % msg sys.exit(1) except socket.error, (errno, strerror): print "ncgo: Socket error (%s) for host %s (%s)" % (errno, host, strerror) sys.exit(1) print 'ncgo: finished' def encode_multipart_formdata(fields): boundary = mimetools.choose_boundary() lines = [] for key in fields: if isinstance(fields[key], dict): entry = fields[key] else: entry = {'value': fields[key]} lines.append('--' + boundary) if 'filename' in entry: lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, entry['filename'])) else: lines.append('Content-Disposition: form-data; name="%s"' % key) if 'content-type' in entry: lines.append('Content-Type: %s' % entry['content-type']) lines.append('') lines.append(entry['value']) lines.append('--' + boundary + '--') lines.append('') body = '\r\n'.join(lines) content_type = 'multipart/form-data; boundary=%s' % boundary return (content_type, body) def get_content_type(filename): type = mimetypes.guess_type(filename)[0] if type is None: type = 'application/octet-stream' return type if __name__ == '__main__': main()