if callable(path): path, callback = None, path<EOL>plugins = makelist(apply)<EOL>skiplist = makelist(skip)<EOL>def decorator(callback):<EOL><INDENT>if isinstance(callback, basestring): callback = load(callback)<EOL>for rule in makelist(path) or yieldroutes(callback):<EOL><INDENT>for verb in makelist(method):<EOL><INDENT>verb = verb.upper()<EOL>route = Route(self, rule, verb, callback,<EOL>name=name,<EOL>plugins=plugins,<EOL>skiplist=skiplist, **config)<EOL>self.add_route(route)<EOL><DEDENT><DEDENT>return callback<EOL><DEDENT>return decorator(callback) if callback else decorator<EOL>

A decorator to bind a function to a request URL. Example::

                @app.route('/hello/<name>')
                def hello(name):
                    return 'Hello %s' % name

            The ``:name`` part is a wildcard. See :class:`Router` for syntax
            details.

            :param path: Request path or a list of paths to listen to. If no
              path is specified, it is automatically generated from the
              signature of the function.
            :param method: HTTP method (`GET`, `POST`, `PUT`, ...) or a list of
              methods to listen to. (default: `GET`)
            :param callback: An optional shortcut to avoid the decorator
              syntax. ``route(..., callback=func)`` equals ``route(...)(func)``
            :param name: The name for this route. (default: None)
            :param apply: A decorator or plugin or a list of plugins. These are
              applied to the route callback in addition to installed plugins.
            :param skip: A list of plugins, plugin classes or names. Matching
              plugins are not installed to this route. ``True`` skips all.

            Any additional keyword arguments are stored as route-specific
            configuration and passed to plugins (see :meth:`Plugin.apply`).


def get(self, path=None, method='<STR_LIT:GET>', **options):

return self.route(path, method, **options)<EOL>


def post(self, path=None, method='<STR_LIT:POST>', **options):

Equals :meth:`route` with a ``POST`` method parameter.


def put(self, path=None, method='<STR_LIT>', **options):

Equals :meth:`route` with a ``PUT`` method parameter.


def delete(self, path=None, method='<STR_LIT>', **options):

Equals :meth:`route` with a ``DELETE`` method parameter.


def patch(self, path=None, method='<STR_LIT>', **options):

Equals :meth:`route` with a ``PATCH`` method parameter.


def wrapper(handler):<EOL><INDENT>self.error_handler[int(code)] = handler<EOL>return handler<EOL><DEDENT>return wrapper<EOL>

Decorator: Register an output handler for a HTTP error code


<EOL>if not out:<EOL><INDENT>if '<STR_LIT>' not in response:<EOL><INDENT>response['<STR_LIT>'] = <NUM_LIT:0><EOL><DEDENT>return []<EOL><DEDENT>if isinstance(out, (tuple, list))and isinstance(out[<NUM_LIT:0>], (bytes, unicode)):<EOL><INDENT>out = out[<NUM_LIT:0>][<NUM_LIT:0>:<NUM_LIT:0>].join(out)  <EOL><DEDENT>if isinstance(out, unicode):<EOL><INDENT>out = out.encode(response.charset)<EOL><DEDENT>if isinstance(out, bytes):<EOL><INDENT>if '<STR_LIT>' not in response:<EOL><INDENT>response['<STR_LIT>'] = len(out)<EOL><DEDENT>return [out]<EOL><DEDENT>if isinstance(out, HTTPError):<EOL><INDENT>out.apply(response)<EOL>out = self.error_handler.get(out.status_code,<EOL>self.default_error_handler)(out)<EOL>return self._cast(out)<EOL><DEDENT>if isinstance(out, HTTPResponse):<EOL><INDENT>out.apply(response)<EOL>return self._cast(out.body)<EOL><DEDENT>if hasattr(out, '<STR_LIT>'):<EOL><INDENT>if '<STR_LIT>' in request.environ:<EOL><INDENT>return request.environ['<STR_LIT>'](out)<EOL><DEDENT>elif hasattr(out, '<STR_LIT>') or not hasattr(out, '<STR_LIT>'):<EOL><INDENT>return WSGIFileWrapper(out)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>iout = iter(out)<EOL>first = next(iout)<EOL>while not first:<EOL><INDENT>first = next(iout)<EOL><DEDENT><DEDENT>except StopIteration:<EOL><INDENT>return self._cast('<STR_LIT>')<EOL><DEDENT>except HTTPResponse:<EOL><INDENT>first = _e()<EOL><DEDENT>except (KeyboardInterrupt, SystemExit, MemoryError):<EOL><INDENT>raise<EOL><DEDENT>except:<EOL><INDENT>if not self.catchall: raise<EOL>first = HTTPError(<NUM_LIT>, '<STR_LIT>', _e(), format_exc())<EOL><DEDENT>if isinstance(first, HTTPResponse):<EOL><INDENT>return self._cast(first)<EOL><DEDENT>elif isinstance(first, bytes):<EOL><INDENT>new_iter = itertools.chain([first], iout)<EOL><DEDENT>elif isinstance(first, unicode):<EOL><INDENT>encoder = lambda x: x.encode(response.charset)<EOL>new_iter = imap(encoder, itertools.chain([first], iout))<EOL><DEDENT>else:<EOL><INDENT>msg = '<STR_LIT>' % type(first)<EOL>return self._cast(HTTPError(<NUM_LIT>, msg))<EOL><DEDENT>if hasattr(out, '<STR_LIT>'):<EOL><INDENT>new_iter = _closeiter(new_iter, out.close)<EOL><DEDENT>return new_iter<EOL>

Try to convert the parameter into something WSGI compatible and set
        correct HTTP headers when possible.
        Support: False, str, unicode, dict, HTTPResponse, HTTPError, file-like,
        iterable of strings and iterable of unicodes


def wsgi(self, environ, start_response):

try:<EOL><INDENT>out = self._cast(self._handle(environ))<EOL>if response._status_code in (<NUM_LIT:100>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>)or environ['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>if hasattr(out, '<STR_LIT>'): out.close()<EOL>out = []<EOL><DEDENT>start_response(response._status_line, response.headerlist)<EOL>return out<EOL><DEDENT>except (KeyboardInterrupt, SystemExit, MemoryError):<EOL><INDENT>raise<EOL><DEDENT>except:<EOL><INDENT>if not self.catchall: raise<EOL>err = '<STR_LIT>'% html_escape(environ.get('<STR_LIT>', '<STR_LIT:/>'))<EOL>if DEBUG:<EOL><INDENT>err += '<STR_LIT>''<STR_LIT>'% (html_escape(repr(_e())), html_escape(format_exc()))<EOL><DEDENT>environ['<STR_LIT>'].write(err)<EOL>headers = [('<STR_LIT:Content-Type>', '<STR_LIT>')]<EOL>start_response('<STR_LIT>', headers, sys.exc_info())<EOL>return [tob(err)]<EOL><DEDENT>


def __call__(self, environ, start_response):

return self.wsgi(environ, start_response)<EOL>

Each instance of :class:'Bottle' is a WSGI application.


default_app.push(self)<EOL>return self<EOL>

Use this application as default for all module-level shortcuts.


<EOL>self.environ = {} if environ is None else environ<EOL>self.environ['<STR_LIT>'] = self<EOL>


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def app(self):<DEDENT>

raise RuntimeError('<STR_LIT>')<EOL>

Bottle application handling this request.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def route(self):<DEDENT>

raise RuntimeError('<STR_LIT>')<EOL>

The bottle :class:`Route` object that matches this request.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def url_args(self):<DEDENT>

raise RuntimeError('<STR_LIT>')<EOL>


return '<STR_LIT:/>' + self.environ.get('<STR_LIT>', '<STR_LIT>').lstrip('<STR_LIT:/>')<EOL>

The value of ``PATH_INFO`` with exactly one prefixed slash (to fix
            broken clients and avoid the "empty path" edge case).


return self.environ.get('<STR_LIT>', '<STR_LIT:GET>').upper()<EOL>

The ``REQUEST_METHOD`` value as an uppercase string.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def headers(self):<DEDENT>

return WSGIHeaderDict(self.environ)<EOL>

A :class:`WSGIHeaderDict` that provides case-insensitive access to
            HTTP request headers.


def get_header(self, name, default=None):

return self.headers.get(name, default)<EOL>

Return the value of a request header, or a given default value.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def cookies(self):<DEDENT>

cookies = SimpleCookie(self.environ.get('<STR_LIT>', '<STR_LIT>')).values()<EOL>return FormsDict((c.key, c.value) for c in cookies)<EOL>

Cookies parsed into a :class:`FormsDict`. Signed cookies are NOT
            decoded. Use :meth:`get_cookie` if you expect signed cookies.


def get_cookie(self, key, default=None, secret=None):

value = self.cookies.get(key)<EOL>if secret and value:<EOL><INDENT>dec = cookie_decode(value, secret)  <EOL>return dec[<NUM_LIT:1>] if dec and dec[<NUM_LIT:0>] == key else default<EOL><DEDENT>return value or default<EOL>

Return the content of a cookie. To read a `Signed Cookie`, the
            `secret` must match the one used to create the cookie (see
            :meth:`BaseResponse.set_cookie`). If anything goes wrong (missing
            cookie or wrong signature), return a default value.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def query(self):<DEDENT>

get = self.environ['<STR_LIT>'] = FormsDict()<EOL>pairs = _parse_qsl(self.environ.get('<STR_LIT>', '<STR_LIT>'))<EOL>for key, value in pairs:<EOL><INDENT>get[key] = value<EOL><DEDENT>return get<EOL>

The :attr:`query_string` parsed into a :class:`FormsDict`. These
            values are sometimes called "URL arguments" or "GET parameters", but
            not to be confused with "URL wildcards" as they are provided by the
            :class:`Router`.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def forms(self):<DEDENT>

forms = FormsDict()<EOL>for name, item in self.POST.allitems():<EOL><INDENT>if not isinstance(item, FileUpload):<EOL><INDENT>forms[name] = item<EOL><DEDENT><DEDENT>return forms<EOL>

Form values parsed from an `url-encoded` or `multipart/form-data`
            encoded POST or PUT request body. The result is returned as a
            :class:`FormsDict`. All keys and values are strings. File uploads
            are stored separately in :attr:`files`.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def params(self):<DEDENT>

params = FormsDict()<EOL>for key, value in self.query.allitems():<EOL><INDENT>params[key] = value<EOL><DEDENT>for key, value in self.forms.allitems():<EOL><INDENT>params[key] = value<EOL><DEDENT>return params<EOL>

A :class:`FormsDict` with the combined values of :attr:`query` and
            :attr:`forms`. File uploads are stored in :attr:`files`.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def files(self):<DEDENT>

files = FormsDict()<EOL>for name, item in self.POST.allitems():<EOL><INDENT>if isinstance(item, FileUpload):<EOL><INDENT>files[name] = item<EOL><DEDENT><DEDENT>return files<EOL>

File uploads parsed from `multipart/form-data` encoded POST or PUT
            request body. The values are instances of :class:`FileUpload`.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def json(self):<DEDENT>

ctype = self.environ.get('<STR_LIT>', '<STR_LIT>').lower().split('<STR_LIT:;>')[<NUM_LIT:0>]<EOL>if ctype == '<STR_LIT:application/json>':<EOL><INDENT>b = self._get_body_string()<EOL>if not b:<EOL><INDENT>return None<EOL><DEDENT>return json_loads(b)<EOL><DEDENT>return None<EOL>

If the ``Content-Type`` header is ``application/json``, this
            property holds the parsed content of the request body. Only requests
            smaller than :attr:`MEMFILE_MAX` are processed to avoid memory
            exhaustion.


clen = self.content_length<EOL>if clen > self.MEMFILE_MAX:<EOL><INDENT>raise HTTPError(<NUM_LIT>, '<STR_LIT>')<EOL><DEDENT>if clen < <NUM_LIT:0>: clen = self.MEMFILE_MAX + <NUM_LIT:1><EOL>data = self.body.read(clen)<EOL>if len(data) > self.MEMFILE_MAX:  <EOL><INDENT>raise HTTPError(<NUM_LIT>, '<STR_LIT>')<EOL><DEDENT>return data<EOL>

read body until content-length or MEMFILE_MAX into a string. Raise
            HTTPError(413) on requests that are to large.


self._body.seek(<NUM_LIT:0>)<EOL>return self._body<EOL>

The HTTP request body as a seek-able file-like object. Depending on
            :attr:`MEMFILE_MAX`, this is either a temporary file or a
            :class:`io.BytesIO` instance. Accessing this property for the first
            time reads and replaces the ``wsgi.input`` environ variable.
            Subsequent accesses just do a `seek(0)` on the file object.


return '<STR_LIT>' in self.environ.get(<EOL>'<STR_LIT>', '<STR_LIT>').lower()<EOL>


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def POST(self):<DEDENT>

post = FormsDict()<EOL>if not self.content_type.startswith('<STR_LIT>'):<EOL><INDENT>pairs = _parse_qsl(tonat(self._get_body_string(), '<STR_LIT>'))<EOL>for key, value in pairs:<EOL><INDENT>post[key] = value<EOL><DEDENT>return post<EOL><DEDENT>safe_env = {'<STR_LIT>': '<STR_LIT>'}  <EOL>for key in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if key in self.environ: safe_env[key] = self.environ[key]<EOL><DEDENT>args = dict(fp=self.body, environ=safe_env, keep_blank_values=True)<EOL>if py31:<EOL><INDENT>args['<STR_LIT>'] = NCTextIOWrapper(args['<STR_LIT>'],<EOL>encoding='<STR_LIT:utf8>',<EOL>newline='<STR_LIT:\n>')<EOL><DEDENT>elif py3k:<EOL><INDENT>args['<STR_LIT>'] = '<STR_LIT:utf8>'<EOL><DEDENT>data = cgi.FieldStorage(**args)<EOL>self['<STR_LIT>'] = data  <EOL>data = data.list or []<EOL>for item in data:<EOL><INDENT>if item.filename:<EOL><INDENT>post[item.name] = FileUpload(item.file, item.name,<EOL>item.filename, item.headers)<EOL><DEDENT>else:<EOL><INDENT>post[item.name] = item.value<EOL><DEDENT><DEDENT>return post<EOL>

The values of :attr:`forms` and :attr:`files` combined into a single
            :class:`FormsDict`. Values are either strings (form values) or
            instances of :class:`cgi.FieldStorage` (file uploads).


return self.urlparts.geturl()<EOL>

The full request URI including hostname and scheme. If your app
            lives behind a reverse proxy or load balancer and you get confusing
            results, make sure that the ``X-Forwarded-Host`` header is set
            correctly.


@DictProperty('<STR_LIT>', '<STR_LIT>', read_only=True)<EOL><INDENT>def urlparts(self):<DEDENT>

env = self.environ<EOL>http = env.get('<STR_LIT>')or env.get('<STR_LIT>', '<STR_LIT:http>')<EOL>host = env.get('<STR_LIT>') or env.get('<STR_LIT>')<EOL>if not host:<EOL><INDENT>host = env.get('<STR_LIT>', '<STR_LIT:127.0.0.1>')<EOL>port = env.get('<STR_LIT>')<EOL>if port and port != ('<STR_LIT>' if http == '<STR_LIT:http>' else '<STR_LIT>'):<EOL><INDENT>host += '<STR_LIT::>' + port<EOL><DEDENT><DEDENT>path = urlquote(self.fullpath)<EOL>return UrlSplitResult(http, host, path, env.get('<STR_LIT>'), '<STR_LIT>')<EOL>

The :attr:`url` string as an :class:`urlparse.SplitResult` tuple.
            The tuple contains (scheme, host, path, query_string and fragment),
            but the fragment is always empty because it is not visible to the
            server.


return urljoin(self.script_name, self.path.lstrip('<STR_LIT:/>'))<EOL>

Request path including :attr:`script_name` (if present).


return self.environ.get('<STR_LIT>', '<STR_LIT>')<EOL>

The raw :attr:`query` part of the URL (everything in between ``?``
            and ``#``) as a string.


script_name = self.environ.get('<STR_LIT>', '<STR_LIT>').strip('<STR_LIT:/>')<EOL>return '<STR_LIT:/>' + script_name + '<STR_LIT:/>' if script_name else '<STR_LIT:/>'<EOL>

The initial portion of the URL's `path` that was removed by a higher
            level (server or routing middleware) before the application was
            called. This script path is returned with leading and tailing
            slashes.


script, path = path_shift(self.environ.get('<STR_LIT>', '<STR_LIT:/>'), self.path, shift)<EOL>self['<STR_LIT>'], self['<STR_LIT>'] = script, path<EOL>

Shift path segments from :attr:`path` to :attr:`script_name` and
            vice versa.

           :param shift: The number of path segments to shift. May be negative
                         to change the shift direction. (default: 1)


return int(self.environ.get('<STR_LIT>') or -<NUM_LIT:1>)<EOL>

The request body length as an integer. The client is responsible to
            set this header. Otherwise, the real length of the body is unknown
            and -1 is returned. In this case, :attr:`body` will be empty.


return self.environ.get('<STR_LIT>', '<STR_LIT>').lower()<EOL>

The Content-Type header as a lowercase-string (default: empty).


requested_with = self.environ.get('<STR_LIT>', '<STR_LIT>')<EOL>return requested_with.lower() == '<STR_LIT>'<EOL>

True if the request was triggered by a XMLHttpRequest. This only
            works with JavaScript libraries that support the `X-Requested-With`
            header (most of the popular libraries do).


return self.is_xhr<EOL>

Alias for :attr:`is_xhr`. "Ajax" is not the right term.


basic = parse_auth(self.environ.get('<STR_LIT>', '<STR_LIT>'))<EOL>if basic: return basic<EOL>ruser = self.environ.get('<STR_LIT>')<EOL>if ruser: return (ruser, None)<EOL>return None<EOL>

HTTP authentication data as a (user, password) tuple. This
            implementation currently supports basic (not digest) authentication
            only. If the authentication happened at a higher level (e.g. in the
            front web-server or a middleware), the password field is None, but
            the user field is looked up from the ``REMOTE_USER`` environ
            variable. On any errors, None is returned.


proxy = self.environ.get('<STR_LIT>')<EOL>if proxy: return [ip.strip() for ip in proxy.split('<STR_LIT:U+002C>')]<EOL>remote = self.environ.get('<STR_LIT>')<EOL>return [remote] if remote else []<EOL>

A list of all IPs that were involved in this request, starting with
            the client IP and followed by zero or more proxies. This does only
            work if all proxies support the ```X-Forwarded-For`` header. Note
            that this information can be forged by malicious clients.


route = self.remote_route<EOL>return route[<NUM_LIT:0>] if route else None<EOL>

The client IP as a string. Note that this information can be forged
            by malicious clients.


return Request(self.environ.copy())<EOL>

Return a new :class:`Request` with a shallow :attr:`environ` copy.


if self.environ.get('<STR_LIT>'):<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>self.environ[key] = value<EOL>todelete = ()<EOL>if key == '<STR_LIT>':<EOL><INDENT>todelete = ('<STR_LIT:body>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>elif key == '<STR_LIT>':<EOL><INDENT>todelete = ('<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>elif key.startswith('<STR_LIT>'):<EOL><INDENT>todelete = ('<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>for key in todelete:<EOL><INDENT>self.environ.pop('<STR_LIT>' + key, None)<EOL><DEDENT>

Change an environ value and clear all caches that depend on it.


try:<EOL><INDENT>var = self.environ['<STR_LIT>' % name]<EOL>return var.__get__(self) if hasattr(var, '<STR_LIT>') else var<EOL><DEDENT>except KeyError:<EOL><INDENT>raise AttributeError('<STR_LIT>' % name)<EOL><DEDENT>

Search in self.environ for additional user defined attributes.


cls = cls or BaseResponse<EOL>assert issubclass(cls, BaseResponse)<EOL>copy = cls()<EOL>copy.status = self.status<EOL>copy._headers = dict((k, v[:]) for (k, v) in self._headers.items())<EOL>if self._cookies:<EOL><INDENT>copy._cookies = SimpleCookie()<EOL>copy._cookies.load(self._cookies.output(header='<STR_LIT>'))<EOL><DEDENT>return copy<EOL>


return self._status_line<EOL>

The HTTP status line as a string (e.g. ``404 Not Found``).


return self._status_code<EOL>

The HTTP status code as an integer (e.g. 404).


hdict = HeaderDict()<EOL>hdict.dict = self._headers<EOL>return hdict<EOL>

An instance of :class:`HeaderDict`, a case-insensitive dict-like
            view on the response headers.


return self._headers.get(_hkey(name), [default])[-<NUM_LIT:1>]<EOL>

Return the value of a previously defined header. If there is no
            header with that name, return a default value.


self._headers[_hkey(name)] = [value if isinstance(value, unicode)<EOL>else str(value)]<EOL>

Create a new response header, replacing any previously defined
            headers with the same name.


self._headers.setdefault(_hkey(name), []).append(<EOL>value if isinstance(value, unicode) else str(value))<EOL>

Add an additional response header, not removing duplicates.


return self.headerlist<EOL>

Yield (header, value) tuples, skipping headers that are not
            allowed with the current response status code.


out = []<EOL>headers = list(self._headers.items())<EOL>if '<STR_LIT:Content-Type>' not in self._headers:<EOL><INDENT>headers.append(('<STR_LIT:Content-Type>', [self.default_content_type]))<EOL><DEDENT>if self._status_code in self.bad_headers:<EOL><INDENT>bad_headers = self.bad_headers[self._status_code]<EOL>headers = [h for h in headers if h[<NUM_LIT:0>] not in bad_headers]<EOL><DEDENT>out += [(name, val) for (name, vals) in headers for val in vals]<EOL>if self._cookies:<EOL><INDENT>for c in self._cookies.values():<EOL><INDENT>out.append(('<STR_LIT>', c.OutputString()))<EOL><DEDENT><DEDENT>if py3k:<EOL><INDENT>return [(k, v.encode('<STR_LIT:utf8>').decode('<STR_LIT>')) for (k, v) in out]<EOL><DEDENT>else:<EOL><INDENT>return [(k, v.encode('<STR_LIT:utf8>') if isinstance(v, unicode) else v)<EOL>for (k, v) in out]<EOL><DEDENT>

WSGI conform list of (header, value) tuples.


if '<STR_LIT>' in self.content_type:<EOL><INDENT>return self.content_type.split('<STR_LIT>')[-<NUM_LIT:1>].split('<STR_LIT:;>')[<NUM_LIT:0>].strip()<EOL><DEDENT>return default<EOL>

Return the charset specified in the content-type header (default: utf8).


def set_cookie(self, name, value, secret=None, **options):

if not self._cookies:<EOL><INDENT>self._cookies = SimpleCookie()<EOL><DEDENT>if secret:<EOL><INDENT>value = touni(cookie_encode((name, value), secret))<EOL><DEDENT>elif not isinstance(value, basestring):<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>if len(value) > <NUM_LIT>: raise ValueError('<STR_LIT>')<EOL>self._cookies[name] = value<EOL>for key, value in options.items():<EOL><INDENT>if key == '<STR_LIT>':<EOL><INDENT>if isinstance(value, timedelta):<EOL><INDENT>value = value.seconds + value.days * <NUM_LIT> * <NUM_LIT><EOL><DEDENT><DEDENT>if key == '<STR_LIT>':<EOL><INDENT>if isinstance(value, (datedate, datetime)):<EOL><INDENT>value = value.timetuple()<EOL><DEDENT>elif isinstance(value, (int, float)):<EOL><INDENT>value = time.gmtime(value)<EOL><DEDENT>value = time.strftime("<STR_LIT>", value)<EOL><DEDENT>self._cookies[name][key.replace('<STR_LIT:_>', '<STR_LIT:->')] = value<EOL><DEDENT>

Create a new cookie or replace an old one. If the `secret` parameter is
            set, create a `Signed Cookie` (described below).

            :param name: the name of the cookie.
            :param value: the value of the cookie.
            :param secret: a signature key required for signed cookies.

            Additionally, this method accepts all RFC 2109 attributes that are
            supported by :class:`cookie.Morsel`, including:

            :param max_age: maximum age in seconds. (default: None)
            :param expires: a datetime object or UNIX timestamp. (default: None)
            :param domain: the domain that is allowed to read the cookie.
              (default: current domain)
            :param path: limits the cookie to a given path (default: current path)
            :param secure: limit the cookie to HTTPS connections (default: off).
            :param httponly: prevents client-side javascript to read this cookie
              (default: off, requires Python 2.6 or newer).

            If neither `expires` nor `max_age` is set (default), the cookie will
            expire at the end of the browser session (as soon as the browser
            window is closed).

            Signed cookies may store any pickle-able object and are
            cryptographically signed to prevent manipulation. Keep in mind that
            cookies are limited to 4kb in most browsers.

            Warning: Signed cookies are not encrypted (the client can still see
            the content) and not copy-protected (the client can restore an old
            cookie). The main intention is to make pickling and unpickling
            save, not to store secret information at client side.


kwargs['<STR_LIT>'] = -<NUM_LIT:1><EOL>kwargs['<STR_LIT>'] = <NUM_LIT:0><EOL>self.set_cookie(key, '<STR_LIT>', **kwargs)<EOL>

Delete a cookie. Be sure to use the same `domain` and `path`
            settings as used to create the cookie.


self.name = name<EOL>self.impmask = impmask<EOL>self.module = sys.modules.setdefault(name, imp.new_module(name))<EOL>self.module.__dict__.update({<EOL>'<STR_LIT>': __file__,<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': self<EOL>})<EOL>sys.meta_path.append(self)<EOL>

Create a virtual package that redirects imports (see PEP 302).


def get(self, key, default=None, index=-<NUM_LIT:1>, type=None):

try:<EOL><INDENT>val = self.dict[key][index]<EOL>return type(val) if type else val<EOL><DEDENT>except Exception:<EOL><INDENT>pass<EOL><DEDENT>return default<EOL>

Return the most recent value for a key.

            :param default: The default value to be returned if the key is not
                   present or the type conversion fails.
            :param index: An index for the list of available values.
            :param type: If defined, this callable is used to cast the value
                    into a specific type. Exception are suppressed and result in
                    the default value to be returned.


self.dict.setdefault(key, []).append(value)<EOL>

Add a new value to the list of values for this key.


self.dict[key] = [value]<EOL>

Replace the list of values with a single value.


return self.dict.get(key) or []<EOL>

Return a (possibly empty) list of values for a key.


copy = FormsDict()<EOL>enc = copy.input_encoding = encoding or self.input_encoding<EOL>copy.recode_unicode = False<EOL>for key, value in self.allitems():<EOL><INDENT>copy.append(self._fix(key, enc), self._fix(value, enc))<EOL><DEDENT>return copy<EOL>

Returns a copy with all keys and values de- or recoded to match
            :attr:`input_encoding`. Some libraries (e.g. WTForms) want a
            unicode dictionary.


def getunicode(self, name, default=None, encoding=None):

try:<EOL><INDENT>return self._fix(self[name], encoding)<EOL><DEDENT>except (UnicodeError, KeyError):<EOL><INDENT>return default<EOL><DEDENT>

Return the value as a unicode string, or the default.


key = key.replace('<STR_LIT:->', '<STR_LIT:_>').upper()<EOL>if key in self.cgikeys:<EOL><INDENT>return key<EOL><DEDENT>return '<STR_LIT>' + key<EOL>

Translate header field name to CGI/WSGI environ key.


return self.environ.get(self._ekey(key), default)<EOL>

Return the header value as is (may be bytes or unicode).


conf = ConfigParser()<EOL>conf.read(filename)<EOL>for section in conf.sections():<EOL><INDENT>for key, value in conf.items(section):<EOL><INDENT>if section not in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>key = section + '<STR_LIT:.>' + key<EOL><DEDENT>self[key] = value<EOL><DEDENT><DEDENT>return self<EOL>

Load values from an ``*.ini`` style config file.

            If the config file contains sections, their names are used as
            namespaces for the values within. The two special sections
            ``DEFAULT`` and ``bottle`` refer to the root namespace (no prefix).


def load_dict(self, source, namespace='<STR_LIT>'):

for key, value in source.items():<EOL><INDENT>if isinstance(key, str):<EOL><INDENT>nskey = (namespace + '<STR_LIT:.>' + key).strip('<STR_LIT:.>')<EOL>if isinstance(value, dict):<EOL><INDENT>self.load_dict(value, namespace=nskey)<EOL><DEDENT>else:<EOL><INDENT>self[nskey] = value<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>' % type(key))<EOL><DEDENT><DEDENT>return self<EOL>

Load values from a dictionary structure. Nesting can be used to
            represent namespaces.

            >>> c = ConfigDict()
            >>> c.load_dict({'some': {'namespace': {'key': 'value'} } })
            {'some.namespace.key': 'value'}


prefix = '<STR_LIT>'<EOL>if a and isinstance(a[<NUM_LIT:0>], str):<EOL><INDENT>prefix = a[<NUM_LIT:0>].strip('<STR_LIT:.>') + '<STR_LIT:.>'<EOL>a = a[<NUM_LIT:1>:]<EOL><DEDENT>for key, value in dict(*a, **ka).items():<EOL><INDENT>self[prefix + key] = value<EOL><DEDENT>

If the first parameter is a string, all keys are prefixed with this
            namespace. Apart from that it works just as the usual dict.update().
            Example: ``update('some.namespace', key='value')``


def meta_get(self, key, metafield, default=None):

return self._meta.get(key, {}).get(metafield, default)<EOL>

Return the value of a meta field for a key.


def meta_set(self, key, metafield, value):

self._meta.setdefault(key, {})[metafield] = value<EOL>if key in self:<EOL><INDENT>self[key] = self[key]<EOL><DEDENT>

Set the meta field for a key to a new value. This triggers the
            on-change handler for existing keys.


return self._meta.get(key, {}).keys()<EOL>

Return an iterable of meta field names defined for a key.


return self[-<NUM_LIT:1>]<EOL>


if not isinstance(value, Bottle):<EOL><INDENT>value = Bottle()<EOL><DEDENT>self.append(value)<EOL>return value<EOL>

Add a new :class:`Bottle` instance to the stack


def add_path(self, path, base=None, index=None, create=False):

base = os.path.abspath(os.path.dirname(base or self.base))<EOL>path = os.path.abspath(os.path.join(base, os.path.dirname(path)))<EOL>path += os.sep<EOL>if path in self.path:<EOL><INDENT>self.path.remove(path)<EOL><DEDENT>if create and not os.path.isdir(path):<EOL><INDENT>os.makedirs(path)<EOL><DEDENT>if index is None:<EOL><INDENT>self.path.append(path)<EOL><DEDENT>else:<EOL><INDENT>self.path.insert(index, path)<EOL><DEDENT>self.cache.clear()<EOL>return os.path.exists(path)<EOL>

Add a new path to the list of search paths. Return False if the
            path does not exist.

            :param path: The new search path. Relative paths are turned into
                an absolute and normalized form. If the path looks like a file
                (not ending in `/`), the filename is stripped off.
            :param base: Path used to absolutize relative search paths.
                Defaults to :attr:`base` which defaults to ``os.getcwd()``.
            :param index: Position within the list of search paths. Defaults
                to last index (appends to the list).

            The `base` parameter makes it easy to reference files installed
            along with a python module or package::

                res.add_path('./resources/', __file__)


search = self.path[:]<EOL>while search:<EOL><INDENT>path = search.pop()<EOL>if not os.path.isdir(path): continue<EOL>for name in os.listdir(path):<EOL><INDENT>full = os.path.join(path, name)<EOL>if os.path.isdir(full): search.append(full)<EOL>else: yield full<EOL><DEDENT><DEDENT>

Iterate over all existing files in all registered paths.


if name not in self.cache or DEBUG:<EOL><INDENT>for path in self.path:<EOL><INDENT>fpath = os.path.join(path, name)<EOL>if os.path.isfile(fpath):<EOL><INDENT>if self.cachemode in ('<STR_LIT:all>', '<STR_LIT>'):<EOL><INDENT>self.cache[name] = fpath<EOL><DEDENT>return fpath<EOL><DEDENT><DEDENT>if self.cachemode == '<STR_LIT:all>':<EOL><INDENT>self.cache[name] = None<EOL><DEDENT><DEDENT>return self.cache[name]<EOL>

Search for a resource and return an absolute file path, or `None`.

            The :attr:`path` list is searched in order. The first match is
            returend. Symlinks are followed. The result is cached to speed up
            future lookups.


def open(self, name, mode='<STR_LIT:r>', *args, **kwargs):

fname = self.lookup(name)<EOL>if not fname: raise IOError("<STR_LIT>" % name)<EOL>return self.opener(fname, mode=mode, *args, **kwargs)<EOL>

Find a resource and return a file object, or raise IOError.


def __init__(self, fileobj, name, filename, headers=None):

<EOL>self.file = fileobj<EOL>self.name = name<EOL>self.raw_filename = filename<EOL>self.headers = HeaderDict(headers) if headers else HeaderDict()<EOL>


fname = self.raw_filename<EOL>if not isinstance(fname, unicode):<EOL><INDENT>fname = fname.decode('<STR_LIT:utf8>', '<STR_LIT:ignore>')<EOL><DEDENT>fname = normalize('<STR_LIT>', fname)<EOL>fname = fname.encode('<STR_LIT>', '<STR_LIT:ignore>').decode('<STR_LIT>')<EOL>fname = os.path.basename(fname.replace('<STR_LIT:\\>', os.path.sep))<EOL>fname = re.sub(r'<STR_LIT>', '<STR_LIT>', fname).strip()<EOL>fname = re.sub(r'<STR_LIT>', '<STR_LIT:->', fname).strip('<STR_LIT>')<EOL>return fname[:<NUM_LIT:255>] or '<STR_LIT>'<EOL>

Name of the file on the client file system, but normalized to ensure
            file system compatibility. An empty filename is returned as 'empty'.

            Only ASCII letters, digits, dashes, underscores and dots are
            allowed in the final filename. Accents are removed, if possible.
            Whitespace is replaced by a single dash. Leading or tailing dots
            or dashes are removed. The filename is limited to 255 characters.


def save(self, destination, overwrite=False, chunk_size=<NUM_LIT:2> ** <NUM_LIT:16>):

if isinstance(destination, basestring):  <EOL><INDENT>if os.path.isdir(destination):<EOL><INDENT>destination = os.path.join(destination, self.filename)<EOL><DEDENT>if not overwrite and os.path.exists(destination):<EOL><INDENT>raise IOError('<STR_LIT>')<EOL><DEDENT>with open(destination, '<STR_LIT:wb>') as fp:<EOL><INDENT>self._copy_file(fp, chunk_size)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._copy_file(destination, chunk_size)<EOL><DEDENT>

Save file to disk or copy its content to an open file(-like) object.
            If *destination* is a directory, :attr:`filename` is added to the
            path. Existing files are not overwritten by default (IOError).

            :param destination: File path, directory or file(-like) object.
            :param overwrite: If True, replace existing files. (default: False)
            :param chunk_size: Bytes to read at a time. (default: 64kb)


self.name = name<EOL>self.source = source.read() if hasattr(source, '<STR_LIT>') else source<EOL>self.filename = source.filename if hasattr(source, '<STR_LIT:filename>') else None<EOL>self.lookup = [os.path.abspath(x) for x in lookup] if lookup else []<EOL>self.encoding = encoding<EOL>self.settings = self.settings.copy()  <EOL>self.settings.update(settings)  <EOL>if not self.source and self.name:<EOL><INDENT>self.filename = self.search(self.name, self.lookup)<EOL>if not self.filename:<EOL><INDENT>raise TemplateError('<STR_LIT>' % repr(name))<EOL><DEDENT><DEDENT>if not self.source and not self.filename:<EOL><INDENT>raise TemplateError('<STR_LIT>')<EOL><DEDENT>self.prepare(**self.settings)<EOL>

Create a new template.
        If the source parameter (str or buffer) is missing, the name argument
        is used to guess a template filename. Subclasses can assume that
        self.source and/or self.filename are set. Both are strings.
        The lookup, encoding and settings parameters are stored as instance
        variables.
        The lookup parameter stores a list containing directory paths.
        The encoding parameter should be used to decode byte strings or files.
        The settings parameter contains a dict for engine-specific settings.


@classmethod<EOL><INDENT>def search(cls, name, lookup=None):<DEDENT>

if not lookup:<EOL><INDENT>depr('<STR_LIT>',<EOL>True)  <EOL>lookup = ['<STR_LIT:.>']<EOL><DEDENT>if os.path.isabs(name) and os.path.isfile(name):<EOL><INDENT>depr('<STR_LIT>', True)  <EOL>return os.path.abspath(name)<EOL><DEDENT>for spath in lookup:<EOL><INDENT>spath = os.path.abspath(spath) + os.sep<EOL>fname = os.path.abspath(os.path.join(spath, name))<EOL>if not fname.startswith(spath): continue<EOL>if os.path.isfile(fname): return fname<EOL>for ext in cls.extensions:<EOL><INDENT>if os.path.isfile('<STR_LIT>' % (fname, ext)):<EOL><INDENT>return '<STR_LIT>' % (fname, ext)<EOL><DEDENT><DEDENT><DEDENT>

Search name in all directories specified in lookup.
        First without, then with common extensions. Return first hit.


@classmethod<EOL><INDENT>def global_config(cls, key, *args):<DEDENT>

if args:<EOL><INDENT>cls.settings = cls.settings.copy()  <EOL>cls.settings[key] = args[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return cls.settings[key]<EOL><DEDENT>

This reads or sets the global settings stored in class.settings.


raise NotImplementedError<EOL>

Run preparations (parsing, caching, ...).
        It should be possible to call this again to refresh a template or to
        update settings.


raise NotImplementedError<EOL>

Render the template with the specified local variables and return
        a single byte or unicode string. If it is a byte string, the encoding
        must match self.encoding. This method must be thread-safe!
        Local variables may be provided in dictionaries (args)
        or directly, as keywords (kwargs).


env = {}<EOL>stdout = []<EOL>for dictarg in args:<EOL><INDENT>env.update(dictarg)<EOL><DEDENT>env.update(kwargs)<EOL>self.execute(stdout, env)<EOL>return '<STR_LIT>'.join(stdout)<EOL>

Render the template using keyword arguments as local variables.


return self._syntax<EOL>

Tokens as a space separated string (default: <% %> % {{ }})


log.debug('<STR_LIT>' % list(args))<EOL>def _pathjoin(*args, **kwargs):<EOL><INDENT>len_ = len(args) - <NUM_LIT:1><EOL>if len_ < <NUM_LIT:0>:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>elif len_ == <NUM_LIT:0>:<EOL><INDENT>if not isinstance(args, basestring):<EOL><INDENT>if hasattr(args, '<STR_LIT>'):<EOL><INDENT>_args = args<EOL>_args<EOL>args = args[<NUM_LIT:0>]<EOL><DEDENT><DEDENT><DEDENT>for i, arg in enumerate(args):<EOL><INDENT>if not i:<EOL><INDENT>yield arg.rstrip('<STR_LIT:/>')<EOL><DEDENT>elif i == len_:<EOL><INDENT>yield arg.lstrip('<STR_LIT:/>')<EOL><DEDENT>else:<EOL><INDENT>yield arg.strip('<STR_LIT:/>')<EOL><DEDENT><DEDENT><DEDENT>joined_path = u'<STR_LIT:/>'.join(_pathjoin(*args))<EOL>return sanitize_path(joined_path)<EOL>

Arguments:
    args (list): *args list of paths
        if len(args) == 1, args[0] is not a string, and args[0] is iterable,
        set args to args[0].

Basically::

    joined_path = u'/'.join(
        [args[0].rstrip('/')] +
        [a.strip('/') for a in args[1:-1]] +
        [args[-1].lstrip('/')])


path = sanitize_path(_path)<EOL>log.debug('<STR_LIT>' % path)<EOL>if FS.exists(path):<EOL><INDENT>if FS.isdir(path):<EOL><INDENT>dir_index_html_path = pathjoin(path, '<STR_LIT>')<EOL>if (FS.exists(dir_index_html_path)<EOL>and FS.isfile(dir_index_html_path)):<EOL><INDENT>path = dir_index_html_path<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>if not (path.endswith('<STR_LIT:/>') or path.endswith('<STR_LIT>')):<EOL><INDENT>path_dot_html = path + "<STR_LIT>"<EOL>if FS.exists(path_dot_html) and FS.isfile(path_dot_html):<EOL><INDENT>path = path_dot_html<EOL><DEDENT><DEDENT><DEDENT>return path<EOL>

Args:
    _path (str): path to rewrite (in search of index.html)
    root_path (str): filesystem root_path


yield '<STR_LIT>'<EOL>if filepath == '<STR_LIT:/>':<EOL><INDENT>filepath = '<STR_LIT>'<EOL><DEDENT>for name in FS.listdir(filepath):<EOL><INDENT>full_path = pathjoin(filepath, name)<EOL>if FS.isdir(full_path):<EOL><INDENT>full_path = full_path + '<STR_LIT:/>'<EOL><DEDENT>yield u'<STR_LIT>'.format(<EOL>cgi.escape(full_path))  <EOL><DEDENT>yield '<STR_LIT>'<EOL>

Generate directory listing HTML

Arguments:
    FS (FS): filesystem object to read files from
    filepath (str): path to generate directory listings for

Keyword Arguments:
    list_dir (callable: list[str]): list file names in a directory
    isdir (callable: bool): os.path.isdir

Yields:
    str: lines of an HTML table


<EOL>filename = filename.strip('<STR_LIT>')<EOL>headers = dict()<EOL>FS = request.app.config['<STR_LIT>']<EOL>if not FS.exists(filename):<EOL><INDENT>return HTTPError(<NUM_LIT>, "<STR_LIT>")<EOL><DEDENT>if mimetype == '<STR_LIT>':<EOL><INDENT>if download and download is not True:<EOL><INDENT>mimetype, encoding = mimetypes.guess_type(download)<EOL><DEDENT>else:<EOL><INDENT>mimetype, encoding = mimetypes.guess_type(filename)<EOL><DEDENT>if encoding:<EOL><INDENT>headers['<STR_LIT>'] = encoding<EOL><DEDENT><DEDENT>if mimetype:<EOL><INDENT>if mimetype[:<NUM_LIT:5>] == '<STR_LIT>' and charset and '<STR_LIT>' not in mimetype:<EOL><INDENT>mimetype += '<STR_LIT>' % charset<EOL><DEDENT>headers['<STR_LIT:Content-Type>'] = mimetype<EOL><DEDENT>if download:<EOL><INDENT>download = os.path.basename(filename if download else download)<EOL>headers['<STR_LIT>'] = '<STR_LIT>' % download<EOL><DEDENT>info = FS.getinfo(filename)<EOL>headers['<STR_LIT>'] = clen = info['<STR_LIT:size>']<EOL>lm = time.strftime("<STR_LIT>",<EOL>time.gmtime(info['<STR_LIT>']))<EOL>headers['<STR_LIT>'] = lm<EOL>ims = request.environ.get('<STR_LIT>')<EOL>if ims:<EOL><INDENT>ims = parse_date(ims.split("<STR_LIT:;>")[<NUM_LIT:0>].strip())<EOL><DEDENT>mtime = info['<STR_LIT>']<EOL>if mtime and ims is not None and ims >= int(mtime):<EOL><INDENT>headers['<STR_LIT>'] = time.strftime("<STR_LIT>",<EOL>time.gmtime())<EOL>return HTTPResponse(status=<NUM_LIT>, **headers)<EOL><DEDENT>body = '<STR_LIT>' if request.method == '<STR_LIT>' else FS.get_fileobj(filename)<EOL>clen<EOL>return HTTPResponse(body, **headers)<EOL>

This method is derived from bottle.static_file:

        Open [a file] and return :exc:`HTTPResponse` with status
        code 200, 305, 403 or 404. The ``Content-Type``, ``Content-Encoding``,
        ``Content-Length`` and ``Last-Modified`` headers are set if possible.
        Special support for ``If-Modified-Since`` [...].

        :param filename: Name or path of the file to send.
        :param mimetype: Defines the content-type header (default: guess from
            file extension)
        :param download: If True, ask the browser to open a `Save as...` dialog
            instead of opening the file with the associated program. You can
            specify a custom filename as a string. If not specified, the
            original filename is used (default: False).
        :param charset: The charset to use for files with a ``text/*``
            mime-type. (default: UTF-8)


return True<EOL>

Executes when a plugin is loaded.

Override this if your plugin needs to do initialization when loading.
Do not use this to restore runtime changes to variables -- they will be overwritten later on by
PluginManager.load_state()


return True<EOL>

(Not Implemented Yet) Executes when a plugin is unloaded.

Override this if your plugin needs to do cleanup when unloading.


return True<EOL>

Executes immediately after connecting to slack.

Will not fire on reconnects.


if isinstance(channel, SlackIM) or isinstance(channel, SlackUser):<EOL><INDENT>self._bot.send_im(channel, text)<EOL><DEDENT>elif isinstance(channel, SlackRoom):<EOL><INDENT>self._bot.send_message(channel, text)<EOL><DEDENT>elif isinstance(channel, basestring):<EOL><INDENT>if channel[<NUM_LIT:0>] == '<STR_LIT:@>':<EOL><INDENT>self._bot.send_im(channel[<NUM_LIT:1>:], text)<EOL><DEDENT>elif channel[<NUM_LIT:0>] == '<STR_LIT:#>':<EOL><INDENT>self._bot.send_message(channel[<NUM_LIT:1>:], text)<EOL><DEDENT>else:<EOL><INDENT>self._bot.send_message(channel, text)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._bot.send_message(channel, text)<EOL><DEDENT>

Used to send a message to the specified channel.

* channel - can be a channel or user
* text - message to send


def start_timer(self, duration, func, *args):

t = threading.Timer(duration, self._timer_callback, (func, args))<EOL>self._timer_callbacks[func] = t<EOL>t.start()<EOL>self.log.info("<STR_LIT>", func.__name__, duration)<EOL>

Schedules a function to be called after some period of time.

* duration - time in seconds to wait before firing
* func - function to be called
* args - arguments to pass to the function


if func in self._timer_callbacks:<EOL><INDENT>t = self._timer_callbacks[func]<EOL>t.cancel()<EOL>del self._timer_callbacks[func]<EOL><DEDENT>

Stops a timer if it hasn't fired yet

* func - the function passed in start_timer


if hasattr(self._bot, '<STR_LIT>'):<EOL><INDENT>user = self._bot.user_manager.get_by_username(username)<EOL>if user:<EOL><INDENT>return user<EOL><DEDENT>user = SlackUser.get_user(self._bot.sc, username)<EOL>self._bot.user_manager.set(user)<EOL>return user<EOL><DEDENT>return SlackUser.get_user(self._bot.sc, username)<EOL>

Utility function to query slack for a particular user

:param username: The username of the user to lookup
:return: SlackUser object or None


return SlackChannel.get_channel(self._bot.sc, channel)<EOL>

Utility function to query slack for a particular channel

:param channel: The channel name or id of the channel to lookup
:return: SlackChannel object or None


def cmd(admin_only=False, acl='<STR_LIT:*>', aliases=None, while_ignored=False, *args, **kwargs):

def wrapper(func):<EOL><INDENT>func.is_cmd = True<EOL>func.is_subcmd = len(func.__name__.split('<STR_LIT:_>')) > <NUM_LIT:1><EOL>func.cmd_name = func.__name__.replace('<STR_LIT:_>', '<STR_LIT:U+0020>')<EOL>func.admin_only = admin_only<EOL>func.acl = acl<EOL>func.aliases = aliases<EOL>func.while_ignored = while_ignored<EOL>return func<EOL><DEDENT>return wrapper<EOL>

Decorator to mark plugin functions as commands in the form of !<cmd_name>

* admin_only - indicates only users in bot_admin are allowed to execute (only used if AuthManager is loaded)
* acl - indicates which ACL to perform permission checks against (only used if AuthManager is loaded)
* aliases - register function with additional commands (i.e. !alias1, !alias2, etc)
* while_ignored - allows a command to be run, even if channel has been !sleep


def wrapper(func):<EOL><INDENT>func.is_webhook = True<EOL>func.route = args[<NUM_LIT:0>]<EOL>func.form_params = kwargs.get('<STR_LIT>', [])<EOL>func.method = kwargs.get('<STR_LIT>', '<STR_LIT:POST>')<EOL>return func<EOL><DEDENT>return wrapper<EOL>

Decorator to mark plugin functions as entry points for web calls

* route - web route to register, uses Flask syntax
* method - GET/POST, defaults to POST


def wrapper(func):<EOL><INDENT>if isinstance(kwargs['<STR_LIT>'], basestring):<EOL><INDENT>kwargs['<STR_LIT>'] = [kwargs['<STR_LIT>']]<EOL><DEDENT>func.is_eventhandler = True<EOL>func.events = kwargs['<STR_LIT>']<EOL>return func<EOL><DEDENT>return wrapper<EOL>

Decorator.  Marks a function as a receiver for the specified slack event(s).

* events - String or list of events to handle


self.bot_start_time = datetime.now()<EOL>self.webserver = Webserver(self.config['<STR_LIT>']['<STR_LIT:host>'], self.config['<STR_LIT>']['<STR_LIT:port>'])<EOL>self.plugins.load()<EOL>self.plugins.load_state()<EOL>self._find_event_handlers()<EOL>self.sc = ThreadedSlackClient(self.config['<STR_LIT>'])<EOL>self.always_send_dm = ['<STR_LIT>']<EOL>if '<STR_LIT>' in self.config:<EOL><INDENT>self.always_send_dm.extend(map(lambda x: '<STR_LIT:!>' + x, self.config['<STR_LIT>']))<EOL><DEDENT>logging.getLogger('<STR_LIT>').setLevel(logging.INFO)<EOL>self.is_setup = True<EOL>if self.test_mode:<EOL><INDENT>self.metrics['<STR_LIT>'] = (datetime.now() - self.bot_start_time).total_seconds() * <NUM_LIT><EOL><DEDENT>

Initializes the bot, plugins, and everything.


<EOL>if not self.is_setup:<EOL><INDENT>raise NotSetupError<EOL><DEDENT>self.webserver.start()<EOL>first_connect = True<EOL>try:<EOL><INDENT>while self.runnable:<EOL><INDENT>if self.reconnect_needed:<EOL><INDENT>if not self.sc.rtm_connect(with_team_state=start):<EOL><INDENT>return False<EOL><DEDENT>self.reconnect_needed = False<EOL>if first_connect:<EOL><INDENT>first_connect = False<EOL>self.plugins.connect()<EOL><DEDENT><DEDENT>try:<EOL><INDENT>events = self.sc.rtm_read()<EOL><DEDENT>except AttributeError:<EOL><INDENT>self.log.exception('<STR_LIT>')<EOL>self.runnable = False<EOL>events = []<EOL><DEDENT>except:<EOL><INDENT>self.log.exception('<STR_LIT>')<EOL>self.reconnect_needed = True<EOL>events = []<EOL><DEDENT>for e in events:<EOL><INDENT>try:<EOL><INDENT>self._handle_event(e)<EOL><DEDENT>except KeyboardInterrupt:<EOL><INDENT>self.runnable = False<EOL><DEDENT>except:<EOL><INDENT>self.log.exception('<STR_LIT>')<EOL><DEDENT><DEDENT>sleep(<NUM_LIT:0.1>)<EOL><DEDENT><DEDENT>except KeyboardInterrupt:<EOL><INDENT>pass<EOL><DEDENT>except:<EOL><INDENT>self.log.exception('<STR_LIT>')<EOL><DEDENT>

Connects to slack and enters the main loop.

* start - If True, rtm.start API is used. Else rtm.connect API is used

For more info, refer to
https://python-slackclient.readthedocs.io/en/latest/real_time_messaging.html#rtm-start-vs-rtm-connect


if self.webserver is not None:<EOL><INDENT>self.webserver.stop()<EOL><DEDENT>if not self.test_mode:<EOL><INDENT>self.plugins.save_state()<EOL><DEDENT>


def send_message(self, channel, text, thread=None, reply_broadcast=None):

<EOL>if isinstance(channel, SlackRoomIMBase):<EOL><INDENT>channel = channel.id<EOL><DEDENT>self.log.debug("<STR_LIT>", channel, text)<EOL>self.sc.rtm_send_message(channel, text, thread=thread, reply_broadcast=reply_broadcast)<EOL>

Sends a message to the specified channel

* channel - The channel to send to.  This can be a SlackChannel object, a channel id, or a channel name
(without the #)
* text - String to send
* thread - reply to the thread. See https://api.slack.com/docs/message-threading#threads_party
* reply_broadcast - Set to true to indicate your reply is germane to all members of a channel


if isinstance(user, SlackUser):<EOL><INDENT>user = user.id<EOL>channelid = self._find_im_channel(user)<EOL><DEDENT>else:<EOL><INDENT>channelid = user.id<EOL><DEDENT>self.send_message(channelid, text)<EOL>

Sends a message to a user as an IM

* user - The user to send to.  This can be a SlackUser object, a user id, or the username (without the @)
* text - String to send


if self._ignore_event(message):<EOL><INDENT>return None, None<EOL><DEDENT>args = self._parse_message(message)<EOL>self.log.debug("<STR_LIT>", args)<EOL>cmd, msg_args = self._find_longest_prefix_command(args)<EOL>if cmd is not None:<EOL><INDENT>if message.user is None:<EOL><INDENT>self.log.debug("<STR_LIT>", message)<EOL>return None, None<EOL><DEDENT>sender = message.user.username<EOL>if message.channel is not None:<EOL><INDENT>sender = "<STR_LIT>" % (message.channel.name, sender)<EOL><DEDENT>self.log.info("<STR_LIT>", sender, cmd, msg_args)<EOL>f = self._get_command(cmd, message.user)<EOL>if f:<EOL><INDENT>if self._is_channel_ignored(f, message.channel):<EOL><INDENT>self.log.info("<STR_LIT>", message.channel, cmd)<EOL>return '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>return cmd, f.execute(message, msg_args)<EOL><DEDENT>return '<STR_LIT>', "<STR_LIT>" % cmd<EOL><DEDENT>return None, None<EOL>

Takes a SlackEvent, parses it for a command, and runs against registered plugin


if hasattr(message, '<STR_LIT>') and message.subtype in self.ignored_events:<EOL><INDENT>return True<EOL><DEDENT>return False<EOL>

message_replied event is not truly a message event and does not have a message.text
don't process such events

commands may not be idempotent, so ignore message_changed events.


self.log.info("<STR_LIT>", type(plugin).__name__)<EOL>self._register_commands(plugin)<EOL>plugin.on_load()<EOL>

Registers a plugin and commands with the dispatcher for push()


@cmd()<EOL><INDENT>def echo(self, msg, args):<DEDENT>

self.log.debug("<STR_LIT>", args)<EOL>return '<STR_LIT:U+0020>'.join(args)<EOL>


@cmd()<EOL><INDENT>def xyzzy(self, msg, args):<DEDENT>

return "<STR_LIT>" % msg.user<EOL>


@cmd()<EOL><INDENT>def alert(self, msg, args):<DEDENT>

self.send_message(self.config['<STR_LIT>'], '<STR_LIT>')<EOL>return None<EOL>


@cmd()<EOL><INDENT>def shortsleep(self, msg, args):<DEDENT>

self.start_timer(<NUM_LIT:5>, self._sleep_func)<EOL>


@cmd()<EOL><INDENT>def shortsleep2(self, msg, args):<DEDENT>

self.start_timer(<NUM_LIT:5>, self._sleep_func2, msg.channel, '<STR_LIT:U+0020>'.join(args))<EOL>

Sleep for a bit, then echo the message back


@cmd(admin_only=True)<EOL><INDENT>def admincmd(self, msg, args):<DEDENT>

return '<STR_LIT>'<EOL>

A command only admins should be able to run.


if userid in self.users:<EOL><INDENT>return self.users[userid]<EOL><DEDENT>return None<EOL>


res = filter(lambda x: x.username == username, self.users.values())<EOL>if len(res) > <NUM_LIT:0>:<EOL><INDENT>return res[<NUM_LIT:0>]<EOL><DEDENT>return None<EOL>


self.log.info("<STR_LIT>", user.id, user.username)<EOL>self.load_user_info(user)<EOL>self.log.info("<STR_LIT>", user.id, user.username)<EOL>self.load_user_rights(user)<EOL>self.log.info("<STR_LIT>", user.id, user.username)<EOL>self._add_user_to_cache(user)<EOL>return user<EOL>

Adds a user object to the user manager

user - a SlackUser object


<EOL>pass<EOL>

Loads additional user information and stores in user object


if user.username in self.admins:<EOL><INDENT>user.is_admin = True<EOL><DEDENT>elif not hasattr(user, '<STR_LIT>'):<EOL><INDENT>user.is_admin = False<EOL><DEDENT>


@cmd()<EOL><INDENT>def help(self, msg, args):<DEDENT>

output = []<EOL>if len(args) == <NUM_LIT:0>:<EOL><INDENT>commands = sorted(self._bot.dispatcher.commands.items(), key=itemgetter(<NUM_LIT:0>))<EOL>commands = filter(lambda x: x[<NUM_LIT:1>].is_subcmd is False, commands)<EOL>if self._should_filter_help_commands(msg.user):<EOL><INDENT>commands = filter(lambda x: x[<NUM_LIT:1>].admin_only is False, commands)<EOL><DEDENT>for name, cmd in commands:<EOL><INDENT>output.append(self._get_short_help_for_command(name))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>name = '<STR_LIT:!>' + args[<NUM_LIT:0>]<EOL>output = [self._get_help_for_command(name)]<EOL><DEDENT>return '<STR_LIT:\n>'.join(output)<EOL>


@cmd(admin_only=True)<EOL><INDENT>def save(self, msg, args):<DEDENT>

self.send_message(msg.channel, "<STR_LIT>")<EOL>self._bot.plugins.save_state()<EOL>self.send_message(msg.channel, "<STR_LIT>")<EOL>

Causes the bot to write its current state to backend.


@cmd(admin_only=True)<EOL><INDENT>def shutdown(self, msg, args):<DEDENT>

self.log.info("<STR_LIT>", msg.user.username)<EOL>self._bot.runnable = False<EOL>return "<STR_LIT>"<EOL>


@cmd()<EOL><INDENT>def whoami(self, msg, args):<DEDENT>

output = ["<STR_LIT>" % msg.user]<EOL>if hasattr(self._bot.dispatcher, '<STR_LIT>') and msg.user.is_admin is True:<EOL><INDENT>output.append("<STR_LIT>")<EOL><DEDENT>output.append("<STR_LIT>" % (self._bot.version, self._bot.commit))<EOL>return '<STR_LIT:\n>'.join(output)<EOL>

Prints information about the user and bot version.


self.log.info('<STR_LIT>', channel)<EOL>self._bot.dispatcher.ignore(channel)<EOL>self.send_message(channel, '<STR_LIT>')<EOL>

Causes the bot to ignore all messages from the channel.

        Usage:
        !sleep [channel name] - ignore the specified channel (or current if none specified)


@cmd(admin_only=True, while_ignored=True)<EOL><INDENT>@channel_wrapper<EOL>def wake(self, channel):<DEDENT>

self.log.info('<STR_LIT>', channel)<EOL>self._bot.dispatcher.unignore(channel)<EOL>self.send_message(channel, '<STR_LIT>')<EOL>

Causes the bot to resume operation in the channel.

        Usage:
        !wake [channel name] - unignore the specified channel (or current if none specified)


@cmd(admin_only=True)<EOL><INDENT>def acl(self, msg, args):<DEDENT>

if len(args) == <NUM_LIT:0>:<EOL><INDENT>return "<STR_LIT>"<EOL><DEDENT>valid_actions = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>return "<STR_LIT>" % '<STR_LIT:U+002CU+0020>'.join(valid_actions)<EOL>

ACL Management.

        Usage:
        !acl _action_ [args]

        Actions:
        new _acl_ - Create a new ACL
        delete _acl_ - Delete an ACL

        allow _acl_ _user_ - Add user to the acl allow block
        deny _acl_ _user_ - Add user to the acl deny block
        remove _acl_ _user_ - Remove user from acl allow and deny blocks

        show - Show all defined ACLs
        show _acl_ - Show allow and deny blocks of specified ACL


@cmd(admin_only=True)<EOL><INDENT>def acl_show(self, msg, args):<DEDENT>

name = args[<NUM_LIT:0>] if len(args) > <NUM_LIT:0> else None<EOL>if name is None:<EOL><INDENT>return "<STR_LIT>" % (msg.user, '<STR_LIT:U+002CU+0020>'.join(self._acl.keys()))<EOL><DEDENT>if name not in self._acl:<EOL><INDENT>return "<STR_LIT>" % name<EOL><DEDENT>return '<STR_LIT:\n>'.join([<EOL>"<STR_LIT>" % (msg.user, name),<EOL>"<STR_LIT>" % '<STR_LIT:U+002CU+0020>'.join(self._acl[name]['<STR_LIT>']),<EOL>"<STR_LIT>" % '<STR_LIT:U+002CU+0020>'.join(self._acl[name]['<STR_LIT>'])<EOL>])<EOL>

Show current allow and deny blocks for the given acl.


def add_user_to_allow(self, name, user):

<EOL>if not self.remove_user_from_acl(name, user):<EOL><INDENT>return False<EOL><DEDENT>if name not in self._acl:<EOL><INDENT>return False<EOL><DEDENT>self._acl[name]['<STR_LIT>'].append(user)<EOL>return True<EOL>

Add a user to the given acl allow block.


if not self.remove_user_from_acl(name, user):<EOL><INDENT>return False<EOL><DEDENT>if name not in self._acl:<EOL><INDENT>return False<EOL><DEDENT>self._acl[name]['<STR_LIT>'].append(user)<EOL>return True<EOL>


def remove_user_from_acl(self, name, user):

if name not in self._acl:<EOL><INDENT>return False<EOL><DEDENT>if user in self._acl[name]['<STR_LIT>']:<EOL><INDENT>self._acl[name]['<STR_LIT>'].remove(user)<EOL><DEDENT>if user in self._acl[name]['<STR_LIT>']:<EOL><INDENT>self._acl[name]['<STR_LIT>'].remove(user)<EOL><DEDENT>return True<EOL>

Remove a user from the given acl (both allow and deny).


if name in self._acl:<EOL><INDENT>return False<EOL><DEDENT>self._acl[name] = {<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': []<EOL>}<EOL>return True<EOL>


if name not in self._acl:<EOL><INDENT>return False<EOL><DEDENT>del self._acl[name]<EOL>return True<EOL>


def __init__(self, id, sc=None, **kwargs):

self.id = id<EOL>self._sc = sc<EOL>self.logger = logging.getLogger(type(self).__name__)<EOL>self.logger.setLevel(logging.DEBUG)<EOL>

Base class for rooms (channels, groups) and IMs


output = core.run("<STR_LIT>")<EOL>networks = {}<EOL>net_lines = [n.strip() for n in output.splitlines()[<NUM_LIT:2>:]]<EOL>for line in net_lines:<EOL><INDENT>if not line:<EOL><INDENT>continue<EOL><DEDENT>name, state, auto = line.split()<EOL>networks[name] = state == "<STR_LIT>"<EOL><DEDENT>return networks<EOL>

Return a dictionary of network name to active status bools.

        Sample virsh net-list output::

    Name                 State      Autostart
    -----------------------------------------
    default              active     yes
    juju-test            inactive   no
    foobar               inactive   no

    Parsing the above would return::
    {"default": True, "juju-test": False, "foobar": False}

    See: http://goo.gl/kXwfC


def __init__(self, fsapi_device_url, pin, timeout=DEFAULT_TIMEOUT_IN_SECONDS):

self.fsapi_device_url = fsapi_device_url<EOL>self.pin = pin<EOL>self.timeout = timeout<EOL>self.sid = None<EOL>self.__webfsapi = None<EOL>self.__modes = None<EOL>self.__volume_steps = None<EOL>self.__equalisers = None<EOL>self.__session = aiohttp.ClientSession()<EOL>


self.call('<STR_LIT>')<EOL>if not self.__session.closed:<EOL><INDENT>if self.__session._connector_owner:<EOL><INDENT>self.__session._connector.close()<EOL><DEDENT>self.__session._connector = None<EOL><DEDENT>


endpoint = yield from self.__session.get(self.fsapi_device_url, timeout = self.timeout)<EOL>text = yield from endpoint.text(encoding='<STR_LIT:utf-8>')<EOL>doc = objectify.fromstring(text)<EOL>return doc.webfsapi.text<EOL>

Parse the fsapi endpoint from the device url.


req_url = '<STR_LIT>' % (self.__webfsapi, '<STR_LIT>')<EOL>sid = yield from self.__session.get(req_url, params=dict(pin=self.pin),<EOL>timeout = self.timeout)<EOL>text = yield from sid.text(encoding='<STR_LIT:utf-8>')<EOL>doc = objectify.fromstring(text)<EOL>return doc.sessionId.text<EOL>

Create a session on the frontier silicon device.


@asyncio.coroutine<EOL><INDENT>def call(self, path, extra=None):<DEDENT>

try:<EOL><INDENT>if not self.__webfsapi:<EOL><INDENT>self.__webfsapi = yield from self.get_fsapi_endpoint()<EOL><DEDENT>if not self.sid:<EOL><INDENT>self.sid = yield from self.create_session()<EOL><DEDENT>if not isinstance(extra, dict):<EOL><INDENT>extra = dict()<EOL><DEDENT>params = dict(pin=self.pin, sid=self.sid)<EOL>params.update(**extra)<EOL>req_url = ('<STR_LIT>' % (self.__webfsapi, path))<EOL>result = yield from self.__session.get(req_url, params=params,<EOL>timeout = self.timeout)<EOL>if result.status == <NUM_LIT:200>:<EOL><INDENT>text = yield from result.text(encoding='<STR_LIT:utf-8>')<EOL><DEDENT>else:<EOL><INDENT>self.sid = yield from self.create_session()<EOL>params = dict(pin=self.pin, sid=self.sid)<EOL>params.update(**extra)<EOL>result = yield from self.__session.get(req_url, params=params,<EOL>timeout = self.timeout)<EOL>text = yield from result.text(encoding='<STR_LIT:utf-8>')<EOL><DEDENT>return objectify.fromstring(text)<EOL><DEDENT>except Exception as e:<EOL><INDENT>logging.info('<STR_LIT>' +traceback.format_exc())<EOL><DEDENT>return None<EOL>


res = yield from self.call('<STR_LIT>'.format(item))<EOL>return res<EOL>

Helper method for reading a value by using the fsapi API.


@asyncio.coroutine<EOL><INDENT>def handle_set(self, item, value):<DEDENT>

doc = yield from self.call('<STR_LIT>'.format(item), dict(value=value))<EOL>if doc is None:<EOL><INDENT>return None<EOL><DEDENT>return doc.status == '<STR_LIT>'<EOL>

Helper method for setting a value by using the fsapi API.


doc = yield from self.handle_get(item)<EOL>if doc is None:<EOL><INDENT>return None<EOL><DEDENT>return doc.value.c8_array.text or None<EOL>

Helper method for fetching a text value.


doc = yield from self.handle_get(item)<EOL>if doc is None:<EOL><INDENT>return None<EOL><DEDENT>return int(doc.value.u8.text) or None<EOL>

Helper method for fetching a integer value.


doc = yield from self.handle_get(item)<EOL>if doc is None:<EOL><INDENT>return None<EOL><DEDENT>return int(doc.value.u32.text) or None<EOL>

Helper method for fetching a long value. Result is integer.


doc = yield from self.call('<STR_LIT>'+item+'<STR_LIT>', dict(<EOL>maxItems=<NUM_LIT:100>,<EOL>))<EOL>if doc is None:<EOL><INDENT>return []<EOL><DEDENT>if not doc.status == '<STR_LIT>':<EOL><INDENT>return []<EOL><DEDENT>ret = list()<EOL>for index, item in enumerate(list(doc.iterchildren('<STR_LIT>'))):<EOL><INDENT>temp = dict(band=index)<EOL>for field in list(item.iterchildren()):<EOL><INDENT>temp[field.get('<STR_LIT:name>')] = list(field.iterchildren()).pop()<EOL><DEDENT>ret.append(temp)<EOL><DEDENT>return ret<EOL>

Helper method for fetching a list(map) value.


if items is None:<EOL><INDENT>return []<EOL><DEDENT>return [str(item['<STR_LIT:label>']) for item in items if item['<STR_LIT:label>']]<EOL>

Helper methods for extracting the labels from a list with maps.


return (yield from self.handle_text(self.API.get('<STR_LIT>')))<EOL>


return (yield from self.handle_set(<EOL>self.API.get('<STR_LIT>'), value))<EOL>


power = (yield from self.handle_int(self.API.get('<STR_LIT>')))<EOL>return bool(power)<EOL>


power = (yield from self.handle_set(<EOL>self.API.get('<STR_LIT>'), int(value)))<EOL>return bool(power)<EOL>


if not self.__modes:<EOL><INDENT>self.__modes = yield from self.handle_list(<EOL>self.API.get('<STR_LIT>'))<EOL><DEDENT>return self.__modes<EOL>


self.__modes = yield from self.get_modes()<EOL>return (yield from self.collect_labels(self.__modes))<EOL>

Get the label list of the supported modes.


mode = None<EOL>int_mode = (yield from self.handle_long(self.API.get('<STR_LIT>')))<EOL>modes = yield from self.get_modes()<EOL>for temp_mode in modes:<EOL><INDENT>if temp_mode['<STR_LIT>'] == int_mode:<EOL><INDENT>mode = temp_mode['<STR_LIT:label>']<EOL><DEDENT><DEDENT>return str(mode)<EOL>

Get the currently active mode on the device (DAB, FM, Spotify).


mode = -<NUM_LIT:1><EOL>modes = yield from self.get_modes()<EOL>for temp_mode in modes:<EOL><INDENT>if temp_mode['<STR_LIT:label>'] == value:<EOL><INDENT>mode = temp_mode['<STR_LIT>']<EOL><DEDENT><DEDENT>return (yield from self.handle_set(self.API.get('<STR_LIT>'), mode))<EOL>

Set the currently active mode on the device (DAB, FM, Spotify).


if not self.__volume_steps:<EOL><INDENT>self.__volume_steps = yield from self.handle_int(<EOL>self.API.get('<STR_LIT>'))<EOL><DEDENT>return self.__volume_steps<EOL>

Read the maximum volume level of the device.


return (yield from self.handle_int(self.API.get('<STR_LIT>')))<EOL>


return (yield from self.handle_set(self.API.get('<STR_LIT>'), value))<EOL>


mute = (yield from self.handle_int(self.API.get('<STR_LIT>')))<EOL>return bool(mute)<EOL>


mute = (yield from self.handle_set(self.API.get('<STR_LIT>'), int(value)))<EOL>return bool(mute)<EOL>


status = yield from self.handle_int(self.API.get('<STR_LIT:status>'))<EOL>return self.PLAY_STATES.get(status)<EOL>


return (yield from self.handle_text(self.API.get('<STR_LIT:name>')))<EOL>


return (yield from self.handle_text(self.API.get('<STR_LIT:text>')))<EOL>

Get the text associated with the played media.


Get the artists of the current media(song).


Get the album art associated with the song/album/artist.


return (yield from self.handle_long(self.API.get('<STR_LIT>')))<EOL>


Control the player of the device.

1=Play; 2=Pause; 3=Next; 4=Previous (song/station)


return (yield from self.play_control(<NUM_LIT:1>))<EOL>


return (yield from self.play_control(<NUM_LIT:2>))<EOL>


return (yield from self.play_control(<NUM_LIT:3>))<EOL>


return (yield from self.play_control(<NUM_LIT:4>))<EOL>


if not self.__equalisers:<EOL><INDENT>self.__equalisers = yield from self.handle_list(<EOL>self.API.get('<STR_LIT>'))<EOL><DEDENT>return self.__equalisers<EOL>

Get the equaliser modes supported by this device.


self.__equalisers = yield from self.get_equalisers()<EOL>return (yield from self.collect_labels(self.__equalisers))<EOL>


Check when and if the device is going to sleep.


return (yield from self.handle_set(self.API.get('<STR_LIT>'), int(value)))<EOL>


doc = self.id()[self.id().rfind('<STR_LIT:.>')+<NUM_LIT:1>:]<EOL>return "<STR_LIT>".format(self.__class__.__name__, doc)<EOL>

Get's the one liner description to be displayed.
Source:
http://erikzaadi.com/2012/09/13/inheritance-within-python-unit-tests/


for verb in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>yield getattr(c, verb)<EOL><DEDENT>

A simple helper method to iterate through a range of
            HTTP Verbs and return the test_client bound instance,
            keeping writing our tests as DRY as possible.


_options = kwargs<EOL>def decorator(f):<EOL><INDENT>LOG.debug("<STR_LIT>", f, _options)<EOL>if _options.get('<STR_LIT>', True):<EOL><INDENT>f.required_methods = getattr(f, '<STR_LIT>', set())<EOL>f.required_methods.add('<STR_LIT>')<EOL>f.provide_automatic_options = False<EOL><DEDENT>def wrapped_function(*args, **kwargs):<EOL><INDENT>options = get_cors_options(current_app, _options)<EOL>if options.get('<STR_LIT>') and request.method == '<STR_LIT>':<EOL><INDENT>resp = current_app.make_default_options_response()<EOL><DEDENT>else:<EOL><INDENT>resp = make_response(f(*args, **kwargs))<EOL><DEDENT>set_cors_headers(resp, options)<EOL>setattr(resp, FLASK_CORS_EVALUATED, True)<EOL>return resp<EOL><DEDENT>return update_wrapper(wrapped_function, f)<EOL><DEDENT>return decorator<EOL>

This function is the decorator which is used to wrap a Flask route with.
In the simplest case, simply use the default parameters to allow all
origins in what is the most permissive configuration. If this method
modifies state or performs authentication which may be brute-forced, you
should add some degree of protection, such as Cross Site Forgery
Request protection.

:param origins:
    The origin, or list of origins to allow requests from.
    The origin(s) may be regular expressions, case-sensitive strings,
    or else an asterisk

    Default : '*'
:type origins: list, string or regex

:param methods:
    The method or list of methods which the allowed origins are allowed to
    access for non-simple requests.

    Default : [GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE]
:type methods: list or string

:param expose_headers:
    The header or list which are safe to expose to the API of a CORS API
    specification.

    Default : None
:type expose_headers: list or string

:param allow_headers:
    The header or list of header field names which can be used when this
    resource is accessed by allowed origins. The header(s) may be regular
    expressions, case-sensitive strings, or else an asterisk.

    Default : '*', allow all headers
:type allow_headers: list, string or regex

:param supports_credentials:
    Allows users to make authenticated requests. If true, injects the
    `Access-Control-Allow-Credentials` header in responses. This allows
    cookies and credentials to be submitted across domains.

    :note: This option cannot be used in conjuction with a '*' origin

    Default : False
:type supports_credentials: bool

:param max_age:
    The maximum time for which this CORS request maybe cached. This value
    is set as the `Access-Control-Max-Age` header.

    Default : None
:type max_age: timedelta, integer, string or None

:param send_wildcard: If True, and the origins parameter is `*`, a wildcard
    `Access-Control-Allow-Origin` header is sent, rather than the
    request's `Origin` header.

    Default : False
:type send_wildcard: bool

:param vary_header:
    If True, the header Vary: Origin will be returned as per the W3
    implementation guidelines.

    Setting this header when the `Access-Control-Allow-Origin` is
    dynamically generated (e.g. when there is more than one allowed
    origin, and an Origin than '*' is returned) informs CDNs and other
    caches that the CORS headers are dynamic, and cannot be cached.

    If False, the Vary header will never be injected or altered.

    Default : True
:type vary_header: bool

:param automatic_options:
    Only applies to the `cross_origin` decorator. If True, Flask-CORS will
    override Flask's default OPTIONS handling to return CORS headers for
    OPTIONS requests.

    Default : True
:type automatic_options: bool


try:<EOL><INDENT>return regexp.pattern<EOL><DEDENT>except AttributeError:<EOL><INDENT>return str(regexp)<EOL><DEDENT>

Helper that returns regexp pattern from given value.

:param regexp: regular expression to stringify
:type regexp: _sre.SRE_Pattern or str
:returns: string representation of given regexp pattern
:rtype: str


<EOL>if hasattr(resp, FLASK_CORS_EVALUATED):<EOL><INDENT>LOG.debug('<STR_LIT>')<EOL>return resp<EOL><DEDENT>if (not isinstance(resp.headers, Headers)<EOL>and not isinstance(resp.headers, MultiDict)):<EOL><INDENT>resp.headers = MultiDict(resp.headers)<EOL><DEDENT>headers_to_set = get_cors_headers(options, request.headers, request.method)<EOL>LOG.debug('<STR_LIT>', str(headers_to_set))<EOL>for k, v in headers_to_set.items():<EOL><INDENT>resp.headers.add(k, v)<EOL><DEDENT>return resp<EOL>

Performs the actual evaluation of Flas-CORS options and actually
modifies the response object.

This function is used both in the decorator and the after_request
callback


return r'<STR_LIT>' if reg == r'<STR_LIT:*>' else reg<EOL>

Replace the invalid regex r'*' with the valid, wildcard regex r'/.*' to
enable the CORS app extension to have a more user friendly api.


if isinstance(maybe_regex, RegexObject):<EOL><INDENT>return re.match(maybe_regex, request_origin)<EOL><DEDENT>elif probably_regex(maybe_regex):<EOL><INDENT>return re.match(maybe_regex, request_origin, flags=re.IGNORECASE)<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>return request_origin.lower() == maybe_regex.lower()<EOL><DEDENT>except AttributeError:<EOL><INDENT>return request_origin == maybe_regex<EOL><DEDENT><DEDENT>

Safely attempts to match a pattern or string to a request origin.


options = DEFAULT_OPTIONS.copy()<EOL>options.update(get_app_kwarg_dict(appInstance))<EOL>if dicts:<EOL><INDENT>for d in dicts:<EOL><INDENT>options.update(d)<EOL><DEDENT><DEDENT>return serialize_options(options)<EOL>

Compute CORS options for an application by combining the DEFAULT_OPTIONS,
the app's configuration-specified options and any dictionaries passed. The
last specified option wins.


app = (appInstance or current_app)<EOL>app_config = getattr(app, '<STR_LIT>', {})<EOL>return {<EOL>k.lower().replace('<STR_LIT>', '<STR_LIT>'): app_config.get(k)<EOL>for k in CONFIG_OPTIONS<EOL>if app_config.get(k) is not None<EOL>}<EOL>

Returns the dictionary of CORS specific app configurations.


if obj is None:<EOL><INDENT>return None<EOL><DEDENT>elif(not isinstance(obj, string_types)<EOL>and isinstance(obj, collections.Iterable)):<EOL><INDENT>return '<STR_LIT:U+002CU+0020>'.join(str(item) for item in sorted(obj))<EOL><DEDENT>else:<EOL><INDENT>return str(obj)<EOL><DEDENT>

A more flexible str function which intelligently handles stringifying
strings, lists and other iterables. The results are lexographically sorted
to ensure generated responses are consistent when iterables such as Set
are used.


if isinstance(inst, string_types):<EOL><INDENT>return [inst]<EOL><DEDENT>elif not isinstance(inst, collections.Iterable):<EOL><INDENT>return [inst]<EOL><DEDENT>else:<EOL><INDENT>return inst<EOL><DEDENT>

Wraps scalars or string types as a list, or returns the iterable instance.


options = (opts or {}).copy()<EOL>for key in opts.keys():<EOL><INDENT>if key not in DEFAULT_OPTIONS:<EOL><INDENT>LOG.warning("<STR_LIT>", key)<EOL><DEDENT><DEDENT>options['<STR_LIT>'] = sanitize_regex_param(options.get('<STR_LIT>'))<EOL>options['<STR_LIT>'] = sanitize_regex_param(options.get('<STR_LIT>'))<EOL>if r'<STR_LIT>' in options['<STR_LIT>'] and options['<STR_LIT>'] and options['<STR_LIT>']:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>serialize_option(options, '<STR_LIT>')<EOL>serialize_option(options, '<STR_LIT>', upper=True)<EOL>if isinstance(options.get('<STR_LIT>'), timedelta):<EOL><INDENT>options['<STR_LIT>'] = str(int(options['<STR_LIT>'].total_seconds()))<EOL><DEDENT>return options<EOL>

A helper method to serialize and processes the options dictionary.


return '''<STR_LIT>'''<EOL>

This view has CORS enabled for all domains, representing the simplest
configuration of view-based decoration. The expected result is as
follows:

$ curl --include -X GET http://127.0.0.1:5000/ \
    --header Origin:www.examplesite.com

>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 184
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:29:56 GMT

Hello CORS!
 Read about my spec at the
W3 Or, checkout my documentation
on Github


return jsonify(success=True)<EOL>

This view has CORS enabled for all domains, and allows browsers
       to send the Content-Type header, allowing cross domain AJAX POST
       requests.

Browsers will first make a preflight request to verify that the resource
       allows cross-origin POSTs with a JSON Content-Type, which can be simulated
       as:
       $ curl --include -X OPTIONS http://127.0.0.1:5000/api/v1/users/create \
           --header Access-Control-Request-Method:POST \
           --header Access-Control-Request-Headers:Content-Type \
           --header Origin:www.examplesite.com
       >> HTTP/1.0 200 OK
       Content-Type: text/html; charset=utf-8
       Allow: POST, OPTIONS
       Access-Control-Allow-Origin: *
       Access-Control-Allow-Headers: Content-Type
       Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
       Content-Length: 0
       Server: Werkzeug/0.9.6 Python/2.7.9
       Date: Sat, 31 Jan 2015 22:25:22 GMT

       $ curl --include -X POST http://127.0.0.1:5000/api/v1/users/create \
           --header Content-Type:application/json \
           --header Origin:www.examplesite.com

       >> HTTP/1.0 200 OK
       Content-Type: application/json
       Content-Length: 21
       Access-Control-Allow-Origin: *
       Server: Werkzeug/0.9.6 Python/2.7.9
       Date: Sat, 31 Jan 2015 22:25:04 GMT

       {
         "success": true
       }


return

Since the path '/' does not match the regular expression r'/api/*',
this route does not have CORS headers set.


return jsonify(user="<STR_LIT>")<EOL>

Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set. The expected result is as follows:

$ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ \
    --header Origin:www.examplesite.com
HTTP/1.0 200 OK
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: *
Content-Length: 21
Content-Type: application/json
Date: Sat, 09 Aug 2014 00:26:41 GMT
Server: Werkzeug/0.9.4 Python/2.7.8

{
    "success": true
}


return jsonify(success=True)<EOL>

Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set.

Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/api/v1/users/create \
    --header Access-Control-Request-Method:POST \
    --header Access-Control-Request-Headers:Content-Type \
    --header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT

$ curl --include -X POST http://127.0.0.1:5000/api/v1/users/create \
    --header Content-Type:application/json \
    --header Origin:www.examplesite.com

>> HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 21
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:04 GMT

{
  "success": true
}


raise Exception("<STR_LIT>")<EOL>

Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set.

Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/exception \
    --header Access-Control-Request-Method:POST \
    --header Access-Control-Request-Headers:Content-Type \
    --header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT


return jsonify(user="<STR_LIT>")<EOL>


return jsonify(success=True)<EOL>


return '''<STR_LIT>'''<EOL>


def write_data_to_files_in_temp_directory(data: List[Any], spread_over_n_files: int, separator: str='<STR_LIT:\n>', dir: str=None,<EOL>file_prefix="<STR_LIT>") -> str:

if dir is None:<EOL><INDENT>dir = mkdtemp(suffix=write_data_to_files_in_temp_directory.__name__)<EOL><DEDENT>datum_per_file = ceil(len(data) / spread_over_n_files)<EOL>for i in range(spread_over_n_files):<EOL><INDENT>start_at = i * datum_per_file<EOL>end_at = start_at + datum_per_file<EOL>to_write = separator.join([str(x) for x in data[start_at:end_at]])<EOL>write_to_temp_file(dir, to_write, file_prefix=file_prefix)<EOL><DEDENT>return dir<EOL>

Writes the given data over the given number of files in a temporary directory.
:param data: the data that is to be written to the files
:param spread_over_n_files: the number of files in which the data is to be spread over
:param separator: the separator between data items in each file
:param dir: the specific temp directory to use
:param file_prefix: prefix to the files created
:return: the location of the temp directory


def write_to_temp_file(dir: str, contents: str, file_prefix="<STR_LIT>") -> str:

temp_temp_file_location = mkstemp(dir=dir, prefix=file_prefix)[<NUM_LIT:1>]<EOL>destination = os.path.join(dir, os.path.basename(temp_temp_file_location))<EOL>with open(temp_temp_file_location, '<STR_LIT:w>') as file:<EOL><INDENT>file.write(contents)<EOL><DEDENT>os.rename(temp_temp_file_location, destination)<EOL>return destination<EOL>

Writes the given contents to a temp file, with the given name prefix, within the given directory.
:param dir: the directory to place the temp file in
:param contents: the contents of the temp file
:param file_prefix: (optional) name prefix of the temp file
:return: the path to the created temp file


def extract_data_from_file(file_location: str, parser: Callable[[str], Any]=lambda data: data, separator: str=None)-> List[Any]:

with open(file_location, '<STR_LIT:r>') as file:<EOL><INDENT>contents = file.read()<EOL><DEDENT>if separator is not None:<EOL><INDENT>raw_data = contents.split(separator)<EOL><DEDENT>else:<EOL><INDENT>raw_data = [contents]<EOL><DEDENT>extracted = []<EOL>for item in raw_data:<EOL><INDENT>parsed = parser(item)<EOL>extracted.append(parsed)<EOL><DEDENT>return extracted<EOL>

Extracts data from the file at the given location, using the given parser.
:param file_location: the location of the file to read data from
:param parser: the parser to extract data from the file
:param separator: (optional) separator for data in the file
:return: the extracted data


blocked = True<EOL>def unblock(*args):<EOL><INDENT>nonlocal blocked<EOL>blocked = False<EOL><DEDENT>event_handler = FileSystemEventHandler()<EOL>event_handler.on_modified = unblock<EOL>source._observer.schedule(event_handler, source._directory_location, recursive=True)<EOL>temp_file_name = "<STR_LIT>" % block_until_synchronised_files_data_source_started.__name__<EOL>temp_file_path = os.path.join(source._directory_location, temp_file_name)<EOL>i = <NUM_LIT:0><EOL>while blocked:<EOL><INDENT>with open(temp_file_path, '<STR_LIT:a>') as file:<EOL><INDENT>file.write(str(i))<EOL><DEDENT>sleep(<NUM_LIT:10> / <NUM_LIT:1000>)<EOL>i += <NUM_LIT:1><EOL><DEDENT>

Blocks until the given synchronised files data source has started to notice changes in the file system (may be a few
milliseconds after it has been started).
:param source: the synchronised files data source that has been started


def _add_more_data_in_nested_directory(self, number_of_extra_files: int=<NUM_LIT:1>) -> Tuple[str, List[int]]:

nested_directory_path = os.path.join(self.temp_directory, "<STR_LIT>")<EOL>os.makedirs(nested_directory_path)<EOL>more_data = [i for i in range(<NUM_LIT:50>)]<EOL>write_data_to_files_in_temp_directory(more_data, number_of_extra_files, dir=nested_directory_path,<EOL>file_prefix=TestSynchronisedFilesDataSource._FILE_PREFIX)<EOL>return (nested_directory_path, more_data)<EOL>

Adds more data in a directory nested inside the temp directory.
:param number_of_extra_files: (optional) the number of files to put the new data in inside the nested directory
:return: a tuple where the first value is the path to the new nested directory and the second is the new data


def _create_data_file_in_temp_directory(self) -> str:

temp_file_location = mkstemp()[<NUM_LIT:1>]<EOL>rule_file_location = "<STR_LIT>" % temp_file_location<EOL>os.rename(temp_file_location, rule_file_location)<EOL>return rule_file_location<EOL>

Creates a data file in the temp directory used by this test.
:return: the file path of the created file


@abstractmethod<EOL><INDENT>def this_will_fail_unless(self, condition:bool) -> bool:<DEDENT>

This method will raise an exception unless condition is True


@staticmethod<EOL><INDENT>def _add_n_mock_listeners_to_listenable(number_of_listeners_to_add: int, listenable: Listenable) -> List[MagicMock]:<DEDENT>

listeners = []<EOL>for i in range(number_of_listeners_to_add):<EOL><INDENT>listener = MagicMock()<EOL>listenable.add_listener(listener)<EOL>listeners.append(listener)<EOL><DEDENT>return listeners<EOL>

Adds the given number of mock listeners to the given listenable.
:param number_of_listeners_to_add: the number of mock listeners to add
:param listenable: the listenable to add the listeners to
:return: the mock listeners that were added


self._data = dict(seq)<EOL>self._key_locks = ThreadSafeDefaultdict(Lock)<EOL>

Constructor.
:param seq: initial metadata items


def rename(self, key: Any, new_key: Any):

if new_key == key:<EOL><INDENT>return<EOL><DEDENT>required_locks = [self._key_locks[key], self._key_locks[new_key]]<EOL>ordered_required_locks = sorted(required_locks, key=lambda x: id(x))<EOL>for lock in ordered_required_locks:<EOL><INDENT>lock.acquire()<EOL><DEDENT>try:<EOL><INDENT>if key not in self._data:<EOL><INDENT>raise KeyError("<STR_LIT>" % key)<EOL><DEDENT>self._data[new_key] = self[key]<EOL>del self._data[key]<EOL><DEDENT>finally:<EOL><INDENT>for lock in required_locks:<EOL><INDENT>lock.release()<EOL><DEDENT><DEDENT>

Renames an item in this collection as a transaction.

Will override if new key name already exists.
:param key: the current name of the item
:param new_key: the new name that the item should have


listenable = registration_event_listenable_map[type(registerable)]<EOL>event = RegistrationEvent(registerable, RegistrationEvent.Type.REGISTERED)<EOL>listenable.notify_listeners(event)<EOL>

Registers an object, notifying any listeners that may be interested in it.
:param registerable: the object to register


listenable = registration_event_listenable_map[type(registerable)]<EOL>event = RegistrationEvent(registerable, RegistrationEvent.Type.UNREGISTERED)<EOL>listenable.notify_listeners(event)<EOL>

Unregisters an object, notifying any listeners that may be interested in it.
:param registerable: the object to unregister


def __init__(self, directory_location: str, data_type: type):

super().__init__(directory_location)<EOL>self._data_type = data_type<EOL>

Constructor.
:param directory_location: the location of the directory
:param data_type: the type of data that is loaded from files in the given directory


spec = spec_from_file_location(os.path.basename(path), path)<EOL>module = module_from_spec(spec)<EOL>spec.loader.exec_module(module)<EOL>

Dynamically loads the python module at the given path.
:param path: the path to load the module from


def __init__(self, sources: Iterable[DataSource]=()):

self.sources = copy.copy(sources)<EOL>

Constructor.
:param sources: the sources of instances of `DataSourceType`


@abstractmethod<EOL><INDENT>def get_all(self) -> Sequence[DataSourceType]:<DEDENT>

Gets the data at the source.
:return: instances of `DataSourceType`


def __init__(self, directory_location: str):

super().__init__()<EOL>self._directory_location = directory_location<EOL>

Default constructor.
:param directory_location: the location of the directory that contains files holding data


@abstractmethod<EOL><INDENT>def extract_data_from_file(self, file_path: str) -> Iterable[DataSourceType]:<DEDENT>

Extracts data from the file at the given file path.
:param file_path: the path to the file to extract data from
:return: the extracted data


@abstractmethod<EOL><INDENT>def is_data_file(self, file_path: str) -> bool:<DEDENT>

Determines whether the file at the given path is of interest.
:param file_path: path to the updated file
:return: whether the file is of interest


def no_error_extract_data_from_file(self, file_path: str) -> Iterable[DataSourceType]:

try:<EOL><INDENT>return self.extract_data_from_file(file_path)<EOL><DEDENT>except Exception as e:<EOL><INDENT>logging.warning(e)<EOL>return []<EOL><DEDENT>

Proxy for `extract_data_from_file` that suppresses any errors and instead just returning an empty list.
:param file_path: see `extract_data_from_file`
:return: see `extract_data_from_file`


def _load_all_in_directory(self) -> Dict[str, Iterable[DataSourceType]]:

origin_mapped_data = dict()    <EOL>for file_path in glob.iglob("<STR_LIT>" % self._directory_location, recursive=True):<EOL><INDENT>if self.is_data_file(file_path):<EOL><INDENT>origin_mapped_data[file_path] = self.no_error_extract_data_from_file(file_path)<EOL><DEDENT><DEDENT>return origin_mapped_data<EOL>

Loads all of the data from the files in directory location.
:return: a origin map of all the loaded data


@staticmethod<EOL><INDENT>def _extract_data_from_origin_map(origin_mapped_data: Dict[str, Iterable[DataSourceType]])-> Iterable[DataSourceType]:<DEDENT>

data = []<EOL>for _, data_item in origin_mapped_data.items():<EOL><INDENT>data.extend(data_item)<EOL><DEDENT>return data<EOL>

Extracts the data from a data origin map.
:param origin_mapped_data: a map containing the origin of the data as the key string and the data as the value
:return: the data contained within the map


super().__init__(directory_location)<EOL>self._status_lock = Lock()<EOL>self._running = False<EOL>self._observer = None<EOL>self._origin_mapped_data = dict()   <EOL>self._event_handler = FileSystemEventHandler()<EOL>self._event_handler.on_created = self._on_file_created<EOL>self._event_handler.on_modified = self._on_file_modified<EOL>self._event_handler.on_deleted = self._on_file_deleted<EOL>self._event_handler.on_moved = self._on_file_moved<EOL>self._event_handler.on_any_event = SynchronisedFilesDataSource._on_any_event<EOL>


with self._status_lock:<EOL><INDENT>if self._running:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>self._running = True<EOL><DEDENT>self._observer = Observer()<EOL>self._observer.schedule(self._event_handler, self._directory_location, recursive=True)<EOL>self._observer.start()<EOL>self._origin_mapped_data = self._load_all_in_directory()<EOL>

Monitors data kept in files in the predefined directory in a new thread.

Note: Due to the underlying library, it may take a few milliseconds after this method is started for changes to
start to being noticed.


with self._status_lock:<EOL><INDENT>if self._running:<EOL><INDENT>assert self._observer is not None<EOL>self._observer.stop()<EOL>self._running = False<EOL>self._origin_mapped_data = dict()<EOL><DEDENT><DEDENT>

Stops monitoring the predefined directory.


def _on_file_created(self, event: FileSystemEvent):

if not event.is_directory and self.is_data_file(event.src_path):<EOL><INDENT>assert event.src_path not in self._origin_mapped_data<EOL>self._origin_mapped_data[event.src_path] = self.no_error_extract_data_from_file(event.src_path)<EOL>self.notify_listeners(FileSystemChange.CREATE)<EOL><DEDENT>

Called when a file in the monitored directory has been created.
:param event: the file system event


def _on_file_modified(self, event: FileSystemEvent):

if not event.is_directory and self.is_data_file(event.src_path):<EOL><INDENT>assert event.src_path in self._origin_mapped_data<EOL>self._origin_mapped_data[event.src_path] = self.no_error_extract_data_from_file(event.src_path)<EOL>self.notify_listeners(FileSystemChange.MODIFY)<EOL><DEDENT>

Called when a file in the monitored directory has been modified.
:param event: the file system event


def _on_file_deleted(self, event: FileSystemEvent):

if not event.is_directory and self.is_data_file(event.src_path):<EOL><INDENT>assert event.src_path in self._origin_mapped_data<EOL>del(self._origin_mapped_data[event.src_path])<EOL>self.notify_listeners(FileSystemChange.DELETE)<EOL><DEDENT>

Called when a file in the monitored directory has been deleted.
:param event: the file system event


def _on_file_moved(self, event: FileSystemMovedEvent):

if not event.is_directory and self.is_data_file(event.src_path):<EOL><INDENT>delete_event = FileSystemEvent(event.src_path)<EOL>delete_event.event_type = EVENT_TYPE_DELETED<EOL>self._on_file_deleted(delete_event)<EOL>create_event = FileSystemEvent(event.dest_path)<EOL>create_event.event_type = EVENT_TYPE_CREATED<EOL>self._on_file_created(create_event)<EOL><DEDENT>

Called when a file in the monitored directory has been moved.

Breaks move down into a delete and a create (which it is sometimes detected as!).
:param event: the file system event


logging.debug("<STR_LIT>" % event)<EOL>

Called when any file system event was detected
:param event: the detected event


def _create_client(base_url: str, tls: TLSConfig=False) -> Optional[APIClient]:

try:<EOL><INDENT>client = APIClient(base_url=base_url, tls=tls, version="<STR_LIT>")<EOL>return client if client.ping() else None<EOL><DEDENT>except:<EOL><INDENT>return None<EOL><DEDENT>

Creates a Docker client with the given details.
:param base_url: the base URL of the Docker daemon
:param tls: the Docker daemon's TLS config (if any)
:return: the created client else None if unable to connect the client to the daemon


global _client<EOL>client = _client()<EOL>if client is None:<EOL><INDENT>docker_environment = kwargs_from_env(assert_hostname=False)<EOL>if "<STR_LIT>" in docker_environment:<EOL><INDENT>client = _create_client(docker_environment.get("<STR_LIT>"), docker_environment.get("<STR_LIT>"))<EOL>if client is None:<EOL><INDENT>raise ConnectionError(<EOL>"<STR_LIT>"<EOL>% docker_environment)<EOL><DEDENT>else:<EOL><INDENT>logging.info("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>client = _create_client("<STR_LIT>")<EOL>if client is not None:<EOL><INDENT>logging.info("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>raise ConnectionError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>_client = weakref.ref(client)<EOL><DEDENT>assert isinstance(client, APIClient)<EOL>return client<EOL>

Clients a Docker client.

Will raise a `ConnectionError` if the Docker daemon is not accessible.
:return: the Docker client


def __init__(self, default_mkdtemp_kwargs: dict=None, default_mkstemp_kwargs: dict=None):

self.default_mkdtemp_kwargs = default_mkdtemp_kwargs if default_mkdtemp_kwargs is not None else {}<EOL>self.default_mkstemp_kwargs = default_mkstemp_kwargs if default_mkstemp_kwargs is not None else {}<EOL>self._temp_directories = set()  <EOL>self._temp_files = set()    <EOL>atexit.register(self.tear_down)<EOL>

Constructor.
:param default_mkdtemp_kwargs:
:param default_mkstemp_kwargs:


while len(self._temp_directories) > <NUM_LIT:0>:<EOL><INDENT>directory = self._temp_directories.pop()<EOL>shutil.rmtree(directory, ignore_errors=True)<EOL><DEDENT>while len(self._temp_files) > <NUM_LIT:0>:<EOL><INDENT>file = self._temp_files.pop()<EOL>try:<EOL><INDENT>os.remove(file)<EOL><DEDENT>except OSError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>

Tears down all temp files and directories.


def create_temp_directory(self, **mkdtemp_kwargs) -> str:

kwargs = {**self.default_mkdtemp_kwargs, **mkdtemp_kwargs}<EOL>location = tempfile.mkdtemp(**kwargs)<EOL>self._temp_directories.add(location)<EOL>return location<EOL>

Creates a temp directory.
:param mkdtemp_kwargs: named arguments to be passed to `tempfile.mkdtemp`
:return: the location of the temp directory


def create_temp_file(self, **mkstemp_kwargs) -> Tuple[int, str]:

kwargs = {**self.default_mkstemp_kwargs, **mkstemp_kwargs}<EOL>handle, location = tempfile.mkstemp(**kwargs)<EOL>self._temp_files.add(location)<EOL>return handle, location<EOL>

Creates a temp file.
:param mkstemp_kwargs: named arguments to be passed to `tempfile.mkstemp`
:return: tuple where the first element is the file handle and the second is the location of the temp file


def create_random_string(postfix: str= "<STR_LIT>", prefix: str="<STR_LIT>") -> str:

return "<STR_LIT>" % (prefix, uuid4(), postfix)<EOL>

Creates a random string.
:param postfix: optional postfix
:param prefix: optional prefix
:return: created string


free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<EOL>free_socket.bind(("<STR_LIT>", <NUM_LIT:0>))<EOL>free_socket.listen(<NUM_LIT:1>)<EOL>port = free_socket.getsockname()[<NUM_LIT:1>]<EOL>free_socket.close()<EOL>return port<EOL>

Gets a PORT that will (probably) be available on the machine.
It is possible that in-between the time in which the open PORT of found and when it is used, another process may
bind to it instead.
:return: the (probably) available PORT


def extract_version_number(string: str) -> str:

matched = _EXTRACT_VERSION_PATTERN.search(string)<EOL>if matched is None:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return matched.group().replace("<STR_LIT:_>", "<STR_LIT:.>")<EOL>

Extracts a version from a string in the form: `.*[0-9]+(_[0-9]+)*.*`, e.g. Irods4_1_9CompatibleController.

If the string contains multiple version numbers, the first (from left) is extracted.

Will raise a `ValueError` if there is no version number in the given string.
:param string: the string containing the version number
:return: the extracted version


self._lock = Lock(*args, **kwargs)<EOL>self._stat_lock = Lock()<EOL>self._waiting = <NUM_LIT:0><EOL>self._locked = False  <EOL>self._last_released = datetime.now()<EOL>


with self._stat_lock:<EOL><INDENT>self._waiting += <NUM_LIT:1><EOL><DEDENT>self._lock.acquire(*args, **kwargs)<EOL>with self._stat_lock:<EOL><INDENT>self._locked = True<EOL>self._waiting -= <NUM_LIT:1><EOL><DEDENT>


self._lock.release()<EOL>with self._stat_lock:<EOL><INDENT>self._locked = False<EOL>self._last_released = datetime.now()<EOL><DEDENT>


with self._stat_lock:<EOL><INDENT>return self._waiting<EOL><DEDENT>

Return the number of threads waiting to acquire the lock


with self._stat_lock:<EOL><INDENT>return self._locked<EOL><DEDENT>


with self._stat_lock:<EOL><INDENT>return self._last_released<EOL><DEDENT>


def __init__(self, target: _RegistrationTarget, event_type: Type):

self.target = target<EOL>self.event_type = event_type<EOL>

Constructor.
:param target: the object the event refers to
:param event_type: the type of update event


def get_listeners(self) -> Sequence[Callable[[_ListenableDataType], None]]:

return self._listeners<EOL>

Get all of the registered listeners.
:return: list of the registered listeners


def add_listener(self, listener: Callable[[_ListenableDataType], None]):

Adds a listener.
:param listener: the event listener


def remove_listener(self, listener: Callable[[_ListenableDataType], None]):

Removes a listener.
:param listener: the event listener to remove


def notify_listeners(self, data: Optional[_ListenableDataType]=_NO_DATA_MARKER):

for listener in self._listeners:<EOL><INDENT>if data is not Listenable._NO_DATA_MARKER:<EOL><INDENT>listener(data)<EOL><DEDENT>else:<EOL><INDENT>listener()<EOL><DEDENT><DEDENT>

Notify event listeners, passing them the given data (if any).
:param data: the data to pass to the event listeners


if value == Priority.MAX_PRIORITY:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return value - <NUM_LIT:1><EOL>

Gets a higher priority value than that given.

Will raise a `ValueError` if already highest priority value.
:param value: gets a higher priority value than this
:return: the higher priority value


if value == Priority.MIN_PRIORITY:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return value + <NUM_LIT:1><EOL>

Gets a lower priority value than that given.

Will raise a `ValueError` if already lowest priority value.
:param value: gets a lower priority value than this
:return: the lower priority value


if isinstance(value, bool):<EOL><INDENT>if value:<EOL><INDENT>return '<STR_LIT:true>'<EOL><DEDENT>return '<STR_LIT:false>'<EOL><DEDENT>return value or arg<EOL>

Given a Python boolean value converts it to string representation so
    we can use it in HTML data attributes. If value is None use given default
    or '' if default is not provided.

    -----       ------
    Value       Output
    -----       ------
    True        "true"
    False       "false"
    None        arg