Package flumotion :: Package admin :: Module connections
[hide private]

Source Code for Module flumotion.admin.connections

  1  # -*- Mode: Python; fill-column: 80 -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with th 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """recent connections""" 
 23   
 24  import datetime 
 25  import os 
 26  from xml.dom import minidom, Node 
 27   
 28  from flumotion.common import log, common 
 29  from flumotion.common.connection import PBConnectionInfo, parsePBConnectionInfo 
 30  from flumotion.common.errors import OptionError 
 31  # FIXME: make pychecker able to suppress shadowed builtins like these 
 32  # at the defining site, not caller site 
 33  # P2.4 
 34  __pychecker__ = 'no-shadowbuiltin' 
 35  from flumotion.common.python import sorted 
 36  __pychecker__ = '' 
 37  from flumotion.configure import configure 
 38  from flumotion.twisted.pb import Authenticator 
 39   
 40  __version__ = "$Rev: 7162 $" 
 41   
 42   
43 -class RecentConnection(object):
44 """ 45 I am an object representing a recent connection. 46 You can access some of my state and update the timestamp 47 (eg, when I was last connected to) by calling L{updateTimestamp}. 48 49 @ivar name: name of the recent connection usually host:port 50 @type name: string 51 @ivar host: hostname 52 @type host: string 53 @ivar filename: filename of the connection 54 @type filename: string 55 @ivar info: connection info 56 @type info: L{PBConnectionInfo} 57 @ivar timestamp: timestamp 58 @type timestamp: datetime.datetime 59 """ 60
61 - def __init__(self, host, filename, info):
62 self.name = str(info) 63 self.host = host 64 self.filename = filename 65 self.info = info 66 self.timestamp = datetime.datetime.fromtimestamp( 67 os.stat(filename).st_ctime)
68
69 - def updateTimestamp(self):
70 os.utime(self.filename, None)
71 72
73 -def _getRecentFilenames():
74 # DSU, or as perl folks call it, a Schwartz Transform 75 common.ensureDir(configure.registrydir, "registry dir") 76 77 for filename in os.listdir(configure.registrydir): 78 filename = os.path.join(configure.registrydir, filename) 79 if filename.endswith('.connection'): 80 yield filename
81 82
83 -def hasRecentConnections():
84 """ 85 Returns if we have at least one recent connection 86 @returns: if we have a recent connection 87 @rtype: bool 88 """ 89 gen = _getRecentFilenames() 90 try: 91 gen.next() 92 except StopIteration: 93 return False 94 95 return True
96 97
98 -def getRecentConnections():
99 """ 100 Fetches a list of recently used connections 101 @returns: recently used connections 102 @rtype: list of L{RecentConnection} 103 """ 104 105 def _parseConnection(filename): 106 tree = minidom.parse(filename) 107 state = {} 108 for childNode in tree.documentElement.childNodes: 109 if (childNode.nodeType != Node.TEXT_NODE and 110 childNode.nodeType != Node.COMMENT_NODE): 111 state[childNode.nodeName] = childNode.childNodes[0].wholeText 112 state['port'] = int(state['port']) 113 state['use_insecure'] = (state['use_insecure'] != '0') 114 authenticator = Authenticator(username=state['user'], 115 password=state['passwd']) 116 return PBConnectionInfo(state['host'], state['port'], 117 not state['use_insecure'], 118 authenticator)
119 120 recentFilenames = _getRecentFilenames() 121 recentConnections = [] 122 for filename in sorted(recentFilenames, reverse=True): 123 try: 124 state = _parseConnection(filename) 125 recentConnections.append( 126 RecentConnection(str(state), 127 filename=filename, 128 info=state)) 129 except Exception, e: 130 log.warning('connections', 'Error parsing %s: %r', filename, e) 131 return recentConnections 132 133
134 -def parsePBConnectionInfoRecent(managerString, use_ssl=True, 135 defaultPort=configure.defaultSSLManagerPort):
136 """The same as L{flumotion.common.connection.parsePBConnectionInfo}, 137 but fills in missing information from the recent connections cache 138 if possible. 139 @param managerString: manager string we should connect to 140 @type managerString: string 141 @param use_ssl: True if we should use ssl 142 @type use_ssl: bool 143 @param defaultPort: default port to use 144 @type defaultPort: int 145 @returns: connection info 146 @rtype: a L{PBConnectionInfo} 147 """ 148 recent = getRecentConnections() 149 if not managerString: 150 if recent: 151 return recent[0].info 152 else: 153 raise OptionError('No string given and no recent ' 154 'connections to use') 155 156 info = parsePBConnectionInfo(managerString, username=None, 157 password=None, 158 port=defaultPort, 159 use_ssl=use_ssl) 160 161 def compatible(i1, i2): 162 if i1.port and i1.port != i2.port: 163 return False 164 if i1.use_ssl != i2.use_ssl: 165 return False 166 a1, a2 = i1.authenticator, i2.authenticator 167 if a1.username and a1.username != a2.username: 168 return False 169 if a1.password and a1.password != a2.password: 170 return False 171 return True
172 173 if not info.authenticator.username: 174 for c in recent: 175 recent = c.info 176 if compatible(info, recent): 177 info.authenticator.username = recent.authenticator.username 178 info.authenticator.password = recent.authenticator.password 179 break 180 elif not info.authenticator.password: 181 for c in recent: 182 recent = c.info 183 if compatible(info, recent): 184 info.authenticator.password = recent.authenticator.password 185 break 186 if not (info.authenticator.username and info.authenticator.password): 187 raise OptionError('You are connecting to %s for the ' 188 'first time; please specify a user and ' 189 'password (e.g. user:test@%s).' 190 % (managerString, managerString)) 191 else: 192 return info 193