1
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
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
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
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
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
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
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
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
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()
154 handler.close()
155
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
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
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
196 """
197 Disable transceivers verbosity.
198
199 @param verbosity: verbosity value
200 @type verbosity: bool
201 """
202 self._silent = silent
203
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
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
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