Source

eodsfetch / eodsfetch / eodsfetch.py

#!/usr/bin/env python

# $Id$

import urllib2, sys
from getpass import getpass
from ClientForm import ParseResponse
from optparse import OptionParser
from urlparse import urljoin
import logging

# subclass the default ProxyBasicAuthHandler because it doesn't read multiple
# proxy entries (see urllib2.AbstractBasicAuthHandler.http_error_auth_reqed)
class ProxyBasicAuthHandler( urllib2.ProxyBasicAuthHandler ):

	def http_error_407(self, req, fp, code, msg, headers):
		authority = req.get_host()
		log.debug( 'authority is' )
		return self.http_error_auth_reqed('proxy-authenticate',
										  authority, req, headers)

	def http_error_auth_reqed(self, authreq, host, req, headers):
		log.debug( 'headers are %s', headers )
		result = urllib2.ProxyBasicAuthHandler.http_error_auth_reqed( self, authreq, host, req, headers )
		if result is None:
			headers[authreq] = 'Basic realm="NTLM_PWS"'
			result = urllib2.ProxyBasicAuthHandler.http_error_auth_reqed( self, authreq, host, req, headers )
		return result

class OCCProxyPasswordManager( object ):
	"A simple password manager that always returns the same username and password"
	def __init__( self ):
		self.username = None
		self.password = None
		
	def add_password( self, realm, uri, username, password ):
		self.username = username
		self.password = password

	def find_user_password( self, realm, uri ):
		return self.username, self.password

def getArgs( ):
	parser = OptionParser()
	parser.add_option( "-u", "--url", dest="url", default="http://dev01.hrworx.com:8180/occ/formworx/admin/", help="URL for the admin site" )
	parser.add_option( "-n", "--username", default="admin", dest="username", help="Username with export priveleges" )
	parser.add_option( "-p", "--password", default="pa55word", dest="password", help="Password" )
	parser.add_option( "-l", "--log-level", dest="log_level", default="info", help="level should be DEBUG, INFO, WARNING, ERROR" )
	parser.add_option( "-c", "--retrieve-command", default="newhires/ReviewQueuedExport.do", help="Web site path to retrieval command (relative to url)" )
	parser.add_option( "-r", "--proxy-server", help="Optional proxy server and port (server:port)" )
	parser.add_option( "-s", "--save-file", help="filename to save data" )
	parser.add_option( "-w", "--proxy-password", help="Password for the proxy server '-' for prompt" )
	parser.add_option( "-i", "--proxy-user", help="User name for the proxy server" )
	return parser.parse_args()

def setupLogging():
	global log
	log = logging.getLogger( 'eodsfetch' )
	logging.basicConfig( level = getattr( logging, options.log_level.upper() ) )
	log.debug( 'debug logging enabled' )

def installOpener():
	handlers = [ urllib2.HTTPCookieProcessor ]
	if options.proxy_user and options.proxy_password:
		pwMgr = OCCProxyPasswordManager()
		if options.proxy_password == '-':
			options.proxy_password = getpass( )
		pwMgr.add_password( None, None, options.proxy_user, options.proxy_password )	
		handler = ProxyBasicAuthHandler( pwMgr )
		handlers.append( handler )
	if options.proxy_server:
		handlers.append( urllib2.ProxyHandler( { 'http': options.proxy_server } ) )
	opener = urllib2.build_opener( *handlers )
	urllib2.install_opener( opener )

def getLoginPage():
	log.info( 'Retrieving %s for login', options.url )
	login_page = urllib2.urlopen( options.url )
	try:
		login_form = ParseResponse( login_page, backwards_compat=False )[0]
	except IndexError:
		log.exception( 'Did not find any forms on the login page (%s)', options.url )
		log.info( "Check for <br/> elements, which don't follow the spec (use <br />)." )
		sys.exit(1)
	log.debug( 'login form follows' )
	log.debug( str( login_form ) )
	return login_form

def submitLoginPage( login_form ):
	login_form['userName'] = options.username
	login_form['password'] = options.password
	log.debug( 'Submitting login form' )
	urllib2.urlopen(login_form.click()).read()
	# consider checking the response above for some confirmation value (string "Main Menu" ?)

def runRetrievalCommand():
	command = urljoin( options.url, options.retrieve_command )
	log.info( 'Assuming login was successful, retrieving %s', command )
	result = urllib2.urlopen( command ).read()
	try:
		output = open( options.save_file, 'w' )
		log.info( 'Writing response to file %s', options.save_file )
	except TypeError:
		log.warning( 'Writing response to console' )
		output = sys.stdout
	output.write( result )

def main():
	global options
	options, args = getArgs()
	setupLogging()
	installOpener()
	login_form = getLoginPage()
	submitLoginPage( login_form )
	runRetrievalCommand()

if __name__ == '__main__':
	main()