Package entropy :: Package transceivers

Source Code for Package entropy.transceivers

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