Package entropy :: Package transceivers

Source Code for Package entropy.transceivers

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3   
  4      @author: Fabio Erculiani <[email protected]> 
  5      @contact: [email protected] 
  6      @copyright: Fabio Erculiani 
  7      @license: GPL-2 
  8   
  9      B{Entropy base transceivers module}. 
 10   
 11  """ 
 12  import os 
 13  import time 
 14  import tempfile 
 15   
 16  from entropy.tools import print_traceback, get_file_size, \ 
 17      convert_seconds_to_fancy_output, bytes_into_human, spliturl 
 18  from entropy.const import const_isnumber 
 19  from entropy.output import TextInterface, blue, brown, darkgreen, red 
 20  from entropy.i18n import _ 
 21  from entropy.misc import Lifo 
 22  from entropy.transceivers.exceptions import TransceiverError, \ 
 23      UriHandlerNotFound, TransceiverConnectionError 
 24  from entropy.transceivers.uri_handlers.skel import EntropyUriHandler 
25 26 27 -class EntropyTransceiver(TextInterface):
28 29 """ 30 Base class for Entropy transceivers. This provides a common API across 31 all the available URI handlers. 32 33 How to use this class: 34 Let's consider that we have a valid EntropyUriHandler for ftp:// protocol 35 already installed via "add_uri_handler". 36 37 >> txc = EntropyTransceiver("ftp://myuser:[email protected]") 38 >> txc.set_speed_limit(150) # set speed limit to 150kb/sec 39 >> handler = txc.swallow() 40 >> handler.download("ftp://myuser:[email protected]/myfile.txt", "/tmp") 41 # download 42 """ 43 44 _URI_HANDLERS = [] 45 46 @staticmethod
47 - def add_uri_handler(entropy_uri_handler_class):
48 """ 49 Add custom URI handler to EntropyTransceiver class. 50 51 @param entropy_uri_handler_class: EntropyUriHandler based class 52 @type entropy_uri_handler_class; EntropyUriHandler instance 53 """ 54 if not issubclass(entropy_uri_handler_class, EntropyUriHandler): 55 raise AttributeError("EntropyUriHandler based class expected") 56 EntropyTransceiver._URI_HANDLERS.append(entropy_uri_handler_class)
57 58 @staticmethod
59 - def remove_uri_handler(entropy_uri_handler_class):
60 """ 61 Remove custom URI handler to EntropyTransceiver class. 62 63 @param entropy_uri_handler_class: EntropyUriHandler based instance 64 @type entropy_uri_handler_class; EntropyUriHandler instance 65 @raise ValueError: if provided EntropyUriHandler is not in storage. 66 """ 67 if not issubclass(entropy_uri_handler_class, EntropyUriHandler): 68 raise AttributeError("EntropyUriHandler based class expected") 69 EntropyTransceiver._URI_HANDLERS.remove(entropy_uri_handler_class)
70 71 @staticmethod
72 - def get_uri_handlers():
73 """ 74 Return a copy of the internal list of URI handler instances. 75 76 @return: URI handlers instances list 77 @rtype: list 78 """ 79 return EntropyTransceiver._URI_HANDLERS[:]
80 81 @staticmethod
82 - def get_uri_name(uri):
83 """ 84 Given an URI, extract and return the URI name (hostname). 85 86 @param uri: URI to handle 87 @type uri: string 88 @return: URI name 89 @rtype: string 90 @raise UriHandlerNotFound: if no URI handlers can deal with given URI 91 string 92 """ 93 handlers = EntropyTransceiver.get_uri_handlers() 94 for handler in handlers: 95 if handler.approve_uri(uri): 96 return handler.get_uri_name(uri) 97 98 raise UriHandlerNotFound( 99 "no URI handler available for %s" % (uri,))
100 101 @staticmethod
102 - def hide_sensible_data(uri):
103 """ 104 Given an URI, hide sensible data from string and return it back. 105 106 @param uri: URI to handle 107 @type uri: string 108 @return: URI cleaned 109 @rtype: string 110 @raise UriHandlerNotFound: if no URI handlers can deal with given URI 111 string 112 """ 113 handlers = EntropyTransceiver.get_uri_handlers() 114 for handler in handlers: 115 if handler.approve_uri(uri): 116 return handler.hide_sensible_data(uri) 117 118 raise UriHandlerNotFound( 119 "no URI handler available for %s" % (uri,))
120
121 - def __init__(self, uri):
122 """ 123 EntropyTransceiver constructor, just pass the friggin URI(tm). 124 125 @param uri: URI to handle 126 @type uri: string 127 """ 128 self._uri = uri 129 self._speed_limit = 0 130 self._verbose = False 131 self._timeout = None 132 self._silent = None 133 self._output_interface = None 134 self.__with_stack = Lifo()
135
136 - def __enter__(self):
137 """ 138 Support for "with" statement, this method will execute swallow() and 139 return a valid EntropyUriHandler instance. 140 """ 141 handler = self.swallow() 142 self.__with_stack.push(handler) 143 return handler
144
145 - def __exit__(self, exc_type, exc_value, traceback):
146 """ 147 Support for "with" statement, this method will automagically close the 148 previously created EntropyUriHandler instance connection. 149 """ 150 handler = self.__with_stack.pop() # if this fails, it's not a good sign 151 handler.close()
152
153 - def set_output_interface(self, output_interface):
154 """ 155 Provide alternative Entropy output interface (must be based on 156 entropy.output.TextInterface) 157 158 @param output_interface: new entropy.output.TextInterface instance to 159 use 160 @type output_interface: entropy.output.TextInterface based instance 161 @raise AttributeError: if argument passed is not correct 162 """ 163 if not isinstance(output_interface, TextInterface): 164 raise AttributeError( 165 "expected a valid TextInterface based instance") 166 self._output_interface = output_interface
167
168 - def set_speed_limit(self, speed_limit):
169 """ 170 Set download/upload speed limit in kb/sec form. 171 Zero value will be considered as "disable speed limiter". 172 173 @param speed_limit: speed limit in kb/sec form. 174 @type speed_limit: int 175 @raise AttributeError: if speed_limit is not an integer 176 """ 177 if not const_isnumber(speed_limit): 178 raise AttributeError("expected a valid number") 179 self._speed_limit = speed_limit
180
181 - def set_timeout(self, timeout):
182 """ 183 Set transceiver tx/rx timeout value in seconds. 184 185 @param timeout: timeout in seconds 186 @type timeout: int 187 """ 188 if not const_isnumber(timeout): 189 raise AttributeError("not a number") 190 self._timeout = timeout
191
192 - def set_silent(self, silent):
193 """ 194 Disable transceivers verbosity. 195 196 @param verbosity: verbosity value 197 @type verbosity: bool 198 """ 199 self._silent = silent
200
201 - def set_verbosity(self, verbosity):
202 """ 203 Set transceiver verbosity. 204 205 @param verbosity: verbosity value 206 @type verbosity: bool 207 """ 208 if not isinstance(verbosity, bool): 209 raise AttributeError("expected a valid bool") 210 self._verbose = verbosity
211
212 - def swallow(self):
213 """ 214 Given the URI at the constructor, this method returns the first valid 215 URI handler instance found that can be used to do required action. 216 217 @raise entropy.exceptions.UriHandlerNotFound: when URI handler for given 218 URI is not available. 219 """ 220 handlers = EntropyTransceiver.get_uri_handlers() 221 for handler in handlers: 222 if handler.approve_uri(self._uri): 223 handler_instance = handler(self._uri) 224 if self._output_interface is not None: 225 handler_instance.set_output_interface( 226 self._output_interface) 227 if const_isnumber(self._speed_limit): 228 handler_instance.set_speed_limit(self._speed_limit) 229 handler_instance.set_verbosity(self._verbose) 230 handler_instance.set_silent(self._silent) 231 if const_isnumber(self._timeout): 232 handler_instance.set_timeout(self._timeout) 233 return handler_instance 234 235 raise UriHandlerNotFound( 236 "no URI handler available for %s" % (self._uri,))
237 238 ### 239 # Automatically add installed plugins 240 ### 241 from .uri_handlers.plugins import factory 242 available_plugins = factory.get_available_plugins() 243 for plug_id in available_plugins: 244 EntropyTransceiver.add_uri_handler(available_plugins[plug_id]) 245