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: 7036 $" 
 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 - def __init__(self, host, filename, info):
61 self.name = str(info) 62 self.host = host 63 self.filename = filename 64 self.info = info 65 self.timestamp = datetime.datetime.fromtimestamp( 66 os.stat(filename).st_ctime)
67
68 - def updateTimestamp(self):
69 os.utime(self.filename, None)
70 71
72 -def _getRecentFilenames():
73 # DSU, or as perl folks call it, a Schwartz Transform 74 common.ensureDir(configure.registrydir, "registry dir") 75 76 for filename in os.listdir(configure.registrydir): 77 filename = os.path.join(configure.registrydir, filename) 78 if filename.endswith('.connection'): 79 yield filename
80
81 -def hasRecentConnections():
82 """ 83 Returns if we have at least one recent connection 84 @returns: if we have a recent connection 85 @rtype: bool 86 """ 87 gen = _getRecentFilenames() 88 try: 89 gen.next() 90 except StopIteration: 91 return False 92 93 return True
94
95 -def getRecentConnections():
96 """ 97 Fetches a list of recently used connections 98 @returns: recently used connections 99 @rtype: list of L{RecentConnection} 100 """ 101 def _parseConnection(filename): 102 tree = minidom.parse(filename) 103 state = {} 104 for childNode in tree.documentElement.childNodes: 105 if (childNode.nodeType != Node.TEXT_NODE and 106 childNode.nodeType != Node.COMMENT_NODE): 107 state[childNode.nodeName] = childNode.childNodes[0].wholeText 108 state['port'] = int(state['port']) 109 state['use_insecure'] = (state['use_insecure'] != '0') 110 authenticator = Authenticator(username=state['user'], 111 password=state['passwd']) 112 return PBConnectionInfo(state['host'], state['port'], 113 not state['use_insecure'], 114 authenticator)
115 116 recentFilenames = _getRecentFilenames() 117 recentConnections = [] 118 for filename in sorted(recentFilenames, reverse=True): 119 try: 120 state = _parseConnection(filename) 121 recentConnections.append( 122 RecentConnection(str(state), 123 filename=filename, 124 info=state)) 125 except Exception, e: 126 log.warning('connections', 'Error parsing %s: %r', filename, e) 127 return recentConnections 128
129 -def parsePBConnectionInfoRecent(managerString, use_ssl=True, 130 defaultPort=configure.defaultSSLManagerPort):
131 """The same as L{flumotion.common.connection.parsePBConnectionInfo}, 132 but fills in missing information from the recent connections cache 133 if possible. 134 @param managerString: manager string we should connect to 135 @type managerString: string 136 @param use_ssl: True if we should use ssl 137 @type use_ssl: bool 138 @param defaultPort: default port to use 139 @type defaultPort: int 140 @returns: connection info 141 @rtype: a L{PBConnectionInfo} 142 """ 143 recent = getRecentConnections() 144 if not managerString: 145 if recent: 146 return recent[0].info 147 else: 148 raise OptionError('No string given and no recent ' 149 'connections to use') 150 151 info = parsePBConnectionInfo(managerString, username=None, 152 password=None, 153 port=defaultPort, 154 use_ssl=use_ssl) 155 156 def compatible(i1, i2): 157 if i1.port and i1.port != i2.port: 158 return False 159 if i1.use_ssl != i2.use_ssl: 160 return False 161 a1, a2 = i1.authenticator, i2.authenticator 162 if a1.username and a1.username != a2.username: 163 return False 164 if a1.password and a1.password != a2.password: 165 return False 166 return True
167 168 if not info.authenticator.username: 169 for c in recent: 170 recent = c.info 171 if compatible(info, recent): 172 info.authenticator.username = recent.authenticator.username 173 info.authenticator.password = recent.authenticator.password 174 break 175 elif not info.authenticator.password: 176 for c in recent: 177 recent = c.info 178 if compatible(info, recent): 179 info.authenticator.password = recent.authenticator.password 180 break 181 if not (info.authenticator.username and info.authenticator.password): 182 raise OptionError('You are connecting to %s for the ' 183 'first time; please specify a user and ' 184 'password (e.g. user:test@%s).' 185 % (managerString, managerString)) 186 else: 187 return info 188