<commit_before>"""
This module contains the RestController implementation

Rest controller provides a RESTful dispatch mechanism, and
combines controller decoration for TG-Controller behavior.
"""
import pylons
from pylons.controllers.util import abort
import inspect
from dispatcher          import ObjectDispatcher
from decoratedcontroller import DecoratedController

class RestDispatcher(ObjectDispatcher):
    """Defines a restful interface for a set of HTTP verbs.
    Please see RestController for a rundown of of the controller
    methods used.
    """

    def _method_matches_args(self, method, state, remainder):
            argspec = self._get_argspec(method)
            #skip self,
            argvars = argspec[0][1:]
            argvals = argspec[3]
            if argvals is None:
                argvals = []

            required_vars = argvars[:-len(argvals)]

            #remove the appropriate remainder quotient
            if len(remainder)<len(required_vars):
                #pull the first few off with the remainder
                required_vars = required_vars[len(remainder):]
                new_remainder = []
            else:
                #there is more of a remainder than there is non optional vars
                new_remainder = remainder[len(required_vars):]
                required_vars = []

            #remove vars found in the params list
            params = state.params
            for var in required_vars:
                if var in params:
                    required_vars.pop(0)
                else:
                    break;

            var_in_params = 0
            for var in argvars:
                if var in params:
                    var_in_params+=1

            #make sure all of the non-optional-vars are
            if not required_vars:
                var_args = argspec[1]
                if (len(remainder)+var_in_params) == len(argvars) or var_args:
                    return True
            return False

    def _handle_put_or_post(self, method, state, remainder):
        current_controller = state.controller
        if remainder:
            current_path = remainder[0]
            if self._is_exposed(current_controller, current_path):
                state.add_method(getattr(current_controller, current_path), remainder[1:])
                return state

            if self._is_controller(current_controller, current_path):
                current_controller = getattr(current_controller, current_path)
                return self._dispatch_controller(current_path, current_controller, state, remainder[1:])

        method_name = method
        method = self._find_first_exposed(current_controller, [method,])
        if method and self._method_matches_args(method, state, remainder):
            state.add_method(method, remainder)
            return state

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    def _handle_delete(self, method, state, remainder):
        current_controller = state.controller
        method_name = method
        method = self._find_first_exposed(current_controller, ('post_delete', 'delete'))

        if method and self._method_matches_args(method, state, remainder):
            state.add_method(method, remainder)
            return state

        #you may not send a delete request to a non-delete function
        if remainder and self._is_exposed(current_controller, remainder[0]):
            abort(405)

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    def _check_for_sub_controllers(self, state, remainder):
        current_controller = state.controller
        method = None
        for find in ('get_one', 'get'):
            if hasattr(current_controller, find):
                method = find
                break
        if method is None:
            return
        args = self._get_argspec(getattr(current_controller, method))
        fixed_args = args[0][1:]
        fixed_arg_length = len(fixed_args)
        var_args = args[1]
        if var_args:
            for i, item in enumerate(remainder):
                if hasattr(current_controller, item) and self._is_controller(current_controller, item):
                    current_controller = getattr(current_controller, item)
                    state.add_routing_args(item, remainder[:i], fixed_args, var_args)
                    return self._dispatch_controller(item, current_controller, state, remainder[i+1:])
        elif fixed_arg_length< len(remainder) and hasattr(current_controller, remainder[fixed_arg_length]):
            item = remainder[fixed_arg_length]
            if hasattr(current_controller, item):
                if self._is_controller(current_controller, item):
                    state.add_routing_args(item, remainder, fixed_args, var_args)
                    return self._dispatch_controller(item, getattr(current_controller, item), state, remainder[fixed_arg_length+1:])

    def _handle_delete_edit_or_new(self, state, remainder):
        method_name = remainder[-1]
        if method_name not in ('new', 'edit', 'delete'):
            return
        if method_name == 'delete':
            method_name = 'get_delete'

        current_controller = state.controller

        if self._is_exposed(current_controller, method_name):
            method = getattr(current_controller, method_name)
            new_remainder = remainder[:-1]
            if method and self._method_matches_args(method, state, new_remainder):
                state.add_method(method, new_remainder)
                return state

    def _handle_get(self, method, state, remainder):
        current_controller = state.controller
        if not remainder:
            method = self._find_first_exposed(current_controller, ('get_all', 'get'))
            if method:
                state.add_method(method, remainder)
                return state
            if self._is_exposed(current_controller, 'get_one'):
                method = current_controller.get_one
                if method and self._method_matches_args(method, state, remainder):
                    state.add_method(method, remainder)
                    return state
            return self._dispatch_first_found_default_or_lookup(state, remainder)

        #test for "edit" or "new"
        r = self._handle_delete_edit_or_new(state, remainder)
        if r:
            return r

        current_path = remainder[0]
        if self._is_exposed(current_controller, current_path):
            state.add_method(getattr(current_controller, current_path), remainder[1:])
            return state

        if self._is_controller(current_controller, current_path):
            current_controller = getattr(current_controller, current_path)
            return self._dispatch_controller(current_path, current_controller, state, remainder[1:])

        if self._is_exposed(current_controller, 'get_one'):
            method = current_controller.get_one
            if method and self._method_matches_args(method, state, remainder):
                state.add_method(method, remainder)
                return state

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    _handler_lookup = {
        'put':_handle_put_or_post,
        'post':_handle_put_or_post,
        'delete':_handle_delete,
        'get':_handle_get,
        }

    def _dispatch(self, state, remainder):
        """returns: populated DispachState object
        """
        if not hasattr(state, 'http_method'):
            method = pylons.request.method.lower()
            params = state.params

            #conventional hack for handling methods which are not supported by most browsers
            request_method = params.get('_method', None)
            if request_method:
                request_method = request_method.lower()
                #make certain that DELETE and PUT requests are not sent with GET
                if method == 'get' and request_method == 'put':
                    abort(405)
                if method == 'get' and request_method == 'delete':
                    abort(405)
                method = request_method
            state.http_method = method

        r = self._check_for_sub_controllers(state, remainder)
        if r:
            return r

        r = self._handler_lookup[state.http_method](self, state.http_method, state, remainder)

        #clear out the method hack
        if '_method' in pylons.request.POST:
            del pylons.request.POST['_method']
            del state.params['_method']
        if '_method' in pylons.request.GET:
            del pylons.request.GET['_method']
            del state.params['_method']

        return r

class RestController(DecoratedController, RestDispatcher):
    """A Decorated Controller that dispatches in a RESTful Manner.

    This controller was designed to follow Representational State Transfer protocol, also known as REST.
    The goal of this controller method is to provide the developer a way to map
    RESTful URLS to controller methods directly, while still allowing Normal Object Dispatch to occur.

    Here is a brief rundown of the methods which are called on dispatch along with an example URL.

    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | Method          | Description                                                  | Example Method(s) / URL(s)                 |
    +=================+==============================================================+============================================+
    | get_one         | Display one record.                                          | GET /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get_all         | Display all records in a resource.                           | GET /movies/                               |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get             | A combo of get_one and get_all.                              | GET /movies/                               |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | GET /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | new             | Display a page to prompt the User for resource creation.     | GET /movies/new                            |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | edit            | Display a page to prompt the User for resource modification. |  GET /movies/1/edit                        |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | post            | Create a new record.                                         | POST /movies/                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | put             | Update an existing record.                                   | POST /movies/1?_method=PUT                 |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | PUT /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | post_delete     | Delete an existing record.                                   | POST /movies/1?_method=DELETE              |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/1                           |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get_delete      | Display a delete Confirmation page.                          | GET /movies/1/delete                       |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | delete          | A combination of post_delete and get_delete.                 | GET /movies/delete                         |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/1                           |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/                            |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | POST /movies/1/delete                      |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | POST /movies/delete                        |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+

    You may note the ?_method on some of the URLs.  This is basically a hack because exiting browsers
    do not support the PUT and DELETE methods.  Just note that if you decide to use a this resource with a web browser,
    you will likely have to add a _method as a hidden field in your forms for these items.  Also note that RestController differs
    from TGController in that it offers no index, default, or lookup.  It is intended primarily for  resource management.

    :References:

      `Controller <../main/Controllers.html>`_  A basic overview on how to write controller methods.

      `CrudRestController <../main/Extensions/Crud/index.html>`_  A way to integrate ToscaWdiget Functionality with RESTful Dispatch.

    """
<commit_msg>some notes about the method arg comparison function.<commit_after>"""
This module contains the RestController implementation

Rest controller provides a RESTful dispatch mechanism, and
combines controller decoration for TG-Controller behavior.
"""
import pylons
from pylons.controllers.util import abort
import inspect
from dispatcher          import ObjectDispatcher
from decoratedcontroller import DecoratedController

class RestDispatcher(ObjectDispatcher):
    """Defines a restful interface for a set of HTTP verbs.
    Please see RestController for a rundown of of the controller
    methods used.
    """

    def _method_matches_args(self, method, state, remainder):
        """
        This method matches the params from the request along with the remainder to the
        method's function signiture.  If the two jive, it returns true.

        It is very likely that this method would go into ObjectDispatch in the future.
        """
        argspec = self._get_argspec(method)
        #skip self,
        argvars = argspec[0][1:]
        argvals = argspec[3]
        if argvals is None:
            argvals = []

        required_vars = argvars[:-len(argvals)]

        #remove the appropriate remainder quotient
        if len(remainder)<len(required_vars):
            #pull the first few off with the remainder
            required_vars = required_vars[len(remainder):]
            new_remainder = []
        else:
            #there is more of a remainder than there is non optional vars
            new_remainder = remainder[len(required_vars):]
            required_vars = []

        #remove vars found in the params list
        params = state.params
        for var in required_vars:
            if var in params:
                required_vars.pop(0)
            else:
                break;

        var_in_params = 0
        for var in argvars:
            if var in params:
                var_in_params+=1

        #make sure all of the non-optional-vars are
        if not required_vars:
            var_args = argspec[1]
            if (len(remainder)+var_in_params) == len(argvars) or var_args:
                return True
        return False

    def _handle_put_or_post(self, method, state, remainder):
        current_controller = state.controller
        if remainder:
            current_path = remainder[0]
            if self._is_exposed(current_controller, current_path):
                state.add_method(getattr(current_controller, current_path), remainder[1:])
                return state

            if self._is_controller(current_controller, current_path):
                current_controller = getattr(current_controller, current_path)
                return self._dispatch_controller(current_path, current_controller, state, remainder[1:])

        method_name = method
        method = self._find_first_exposed(current_controller, [method,])
        if method and self._method_matches_args(method, state, remainder):
            state.add_method(method, remainder)
            return state

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    def _handle_delete(self, method, state, remainder):
        current_controller = state.controller
        method_name = method
        method = self._find_first_exposed(current_controller, ('post_delete', 'delete'))

        if method and self._method_matches_args(method, state, remainder):
            state.add_method(method, remainder)
            return state

        #you may not send a delete request to a non-delete function
        if remainder and self._is_exposed(current_controller, remainder[0]):
            abort(405)

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    def _check_for_sub_controllers(self, state, remainder):
        current_controller = state.controller
        method = None
        for find in ('get_one', 'get'):
            if hasattr(current_controller, find):
                method = find
                break
        if method is None:
            return
        args = self._get_argspec(getattr(current_controller, method))
        fixed_args = args[0][1:]
        fixed_arg_length = len(fixed_args)
        var_args = args[1]
        if var_args:
            for i, item in enumerate(remainder):
                if hasattr(current_controller, item) and self._is_controller(current_controller, item):
                    current_controller = getattr(current_controller, item)
                    state.add_routing_args(item, remainder[:i], fixed_args, var_args)
                    return self._dispatch_controller(item, current_controller, state, remainder[i+1:])
        elif fixed_arg_length< len(remainder) and hasattr(current_controller, remainder[fixed_arg_length]):
            item = remainder[fixed_arg_length]
            if hasattr(current_controller, item):
                if self._is_controller(current_controller, item):
                    state.add_routing_args(item, remainder, fixed_args, var_args)
                    return self._dispatch_controller(item, getattr(current_controller, item), state, remainder[fixed_arg_length+1:])

    def _handle_delete_edit_or_new(self, state, remainder):
        method_name = remainder[-1]
        if method_name not in ('new', 'edit', 'delete'):
            return
        if method_name == 'delete':
            method_name = 'get_delete'

        current_controller = state.controller

        if self._is_exposed(current_controller, method_name):
            method = getattr(current_controller, method_name)
            new_remainder = remainder[:-1]
            if method and self._method_matches_args(method, state, new_remainder):
                state.add_method(method, new_remainder)
                return state

    def _handle_get(self, method, state, remainder):
        current_controller = state.controller
        if not remainder:
            method = self._find_first_exposed(current_controller, ('get_all', 'get'))
            if method:
                state.add_method(method, remainder)
                return state
            if self._is_exposed(current_controller, 'get_one'):
                method = current_controller.get_one
                if method and self._method_matches_args(method, state, remainder):
                    state.add_method(method, remainder)
                    return state
            return self._dispatch_first_found_default_or_lookup(state, remainder)

        #test for "edit" or "new"
        r = self._handle_delete_edit_or_new(state, remainder)
        if r:
            return r

        current_path = remainder[0]
        if self._is_exposed(current_controller, current_path):
            state.add_method(getattr(current_controller, current_path), remainder[1:])
            return state

        if self._is_controller(current_controller, current_path):
            current_controller = getattr(current_controller, current_path)
            return self._dispatch_controller(current_path, current_controller, state, remainder[1:])

        if self._is_exposed(current_controller, 'get_one'):
            method = current_controller.get_one
            if method and self._method_matches_args(method, state, remainder):
                state.add_method(method, remainder)
                return state

        return self._dispatch_first_found_default_or_lookup(state, remainder)

    _handler_lookup = {
        'put':_handle_put_or_post,
        'post':_handle_put_or_post,
        'delete':_handle_delete,
        'get':_handle_get,
        }

    def _dispatch(self, state, remainder):
        """returns: populated DispachState object
        """
        if not hasattr(state, 'http_method'):
            method = pylons.request.method.lower()
            params = state.params

            #conventional hack for handling methods which are not supported by most browsers
            request_method = params.get('_method', None)
            if request_method:
                request_method = request_method.lower()
                #make certain that DELETE and PUT requests are not sent with GET
                if method == 'get' and request_method == 'put':
                    abort(405)
                if method == 'get' and request_method == 'delete':
                    abort(405)
                method = request_method
            state.http_method = method

        r = self._check_for_sub_controllers(state, remainder)
        if r:
            return r

        r = self._handler_lookup[state.http_method](self, state.http_method, state, remainder)

        #clear out the method hack
        if '_method' in pylons.request.POST:
            del pylons.request.POST['_method']
            del state.params['_method']
        if '_method' in pylons.request.GET:
            del pylons.request.GET['_method']
            del state.params['_method']

        return r

class RestController(DecoratedController, RestDispatcher):
    """A Decorated Controller that dispatches in a RESTful Manner.

    This controller was designed to follow Representational State Transfer protocol, also known as REST.
    The goal of this controller method is to provide the developer a way to map
    RESTful URLS to controller methods directly, while still allowing Normal Object Dispatch to occur.

    Here is a brief rundown of the methods which are called on dispatch along with an example URL.

    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | Method          | Description                                                  | Example Method(s) / URL(s)                 |
    +=================+==============================================================+============================================+
    | get_one         | Display one record.                                          | GET /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get_all         | Display all records in a resource.                           | GET /movies/                               |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get             | A combo of get_one and get_all.                              | GET /movies/                               |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | GET /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | new             | Display a page to prompt the User for resource creation.     | GET /movies/new                            |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | edit            | Display a page to prompt the User for resource modification. |  GET /movies/1/edit                        |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | post            | Create a new record.                                         | POST /movies/                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | put             | Update an existing record.                                   | POST /movies/1?_method=PUT                 |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | PUT /movies/1                              |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | post_delete     | Delete an existing record.                                   | POST /movies/1?_method=DELETE              |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/1                           |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | get_delete      | Display a delete Confirmation page.                          | GET /movies/1/delete                       |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+
    | delete          | A combination of post_delete and get_delete.                 | GET /movies/delete                         |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/1                           |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | DELETE /movies/                            |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | POST /movies/1/delete                      |
    |                 |                                                              +--------------------------------------------+
    |                 |                                                              | POST /movies/delete                        |
    +-----------------+--------------------------------------------------------------+--------------------------------------------+

    You may note the ?_method on some of the URLs.  This is basically a hack because exiting browsers
    do not support the PUT and DELETE methods.  Just note that if you decide to use a this resource with a web browser,
    you will likely have to add a _method as a hidden field in your forms for these items.  Also note that RestController differs
    from TGController in that it offers no index, default, or lookup.  It is intended primarily for  resource management.

    :References:

      `Controller <../main/Controllers.html>`_  A basic overview on how to write controller methods.

      `CrudRestController <../main/Extensions/Crud/index.html>`_  A way to integrate ToscaWdiget Functionality with RESTful Dispatch.

    """
<|endoftext|>


<commit_before>import asyncio
import importlib
import inspect
import mimetypes
import re
from collections.abc import Container, Iterable, Mapping, Sized
from itertools import chain
from urllib import parse
from pathlib import Path

import yarl
from aiohttp import hdrs
from aiohttp.abc import AbstractView
from aiohttp.web_exceptions import \
    HTTPMethodNotAllowed, HTTPNotFound, HTTPForbidden
from aiohttp.web import Response

from .compat import (
    CompatRouter, AbstractRoute, UrlMappingMatchInfo, MatchInfoError,
)

class SubLocation:
    SPLIT = re.compile(r'/((?:(?:\{.+?\})|(?:[^/{}]+))+)')

    def __init__(self, name, formatter=None, parent=None):
        self._name = name
        self._formatter = formatter or name
        self._parent = parent
        self._subs = {}
        self._patterns = []
        self._routes = {}

    @property
    def name(self):
        return self._name

    def url(self, *, parts=None, query=None):
        formatters = [self._formatter]
        parent = self._parent
        while parent is not None:
            formatters.append(parent._formatter)
            parent = parent._parent
        if len(formatters) == 1:
            url = self._formatter or '/'
        else:
            url = '/'.join(reversed(formatters))
        if parts:
            url = url.format_map(parts)
        if query:
            url += "?" + parse.urlencode(query)
        return url

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return yarl.URL(self.url(parts=kwargs))

    def get_info(self):
        return {}

    def __repr__(self):
        return '<SubLocation {name}, url={url}>' \
               ''.format(name=self.name, url=self.url())

    @classmethod
    def split(cls, path):
        locations = [i for i in cls.SPLIT.split(path) if i]
        if locations[-1] == '/':
            locations[-1] = ''
        return locations

    def resolve(self, request, path: str, match_dict: dict):
        method = request.method
        allowed_methods = set()

        if path is None:
            allowed_methods.update(self._routes)
            if method in self._routes:
                route = self._routes[method]
            elif hdrs.METH_ANY in self._routes:
                route = self._routes[hdrs.METH_ANY]
            else:
                return None, allowed_methods
            return UrlMappingMatchInfo(match_dict, route), allowed_methods
        elif not path:
            location = path
            tail = None
        else:
            parts = path.split('/', 1)
            if len(parts) == 2:
                location, tail = parts
            else:
                location = parts[0]
                tail = None

        if location in self._subs:
            return self._subs[location].resolve(
                request=request,
                path=tail,
                match_dict=match_dict)

        for pattern, sublocation in self._patterns:
            m = pattern.match(path)
            if m is not None:
                for key, value in m.groupdict().items():
                    match_dict[key] = parse.unquote(value)

                index = m.end()
                if len(path) > index:
                    if path[index] == '/':
                        index += 1
                    tail = path[index:]
                else:
                    tail = None

                return sublocation.resolve(
                    request=request, path=tail, match_dict=match_dict)
        return None, allowed_methods

    def register_route(self, path, route):
        if not path:
            assert route.method not in self._routes, self
            self._routes[route.method] = route
            return self
        location = self.add_location(path)
        return location.register_route(None, route)

    def add_location(self, path):
        if isinstance(path, str):
            path = self.split(path)
        if not path:
            return self

        location_name, *path = path

        if '{' in location_name:
            for pattern, loc in self._patterns:
                if loc.name == location_name:
                    location = loc
                    break
            else:
                pattern, formatter = \
                    TreeUrlDispatcher.get_pattern_formatter(location_name)
                location = type(self)(location_name, formatter, parent=self)
                self._patterns.append((re.compile(pattern), location))
        elif location_name in self._subs:
            location = self._subs[location_name]
        else:
            location = type(self)(location_name, parent=self)
            self._subs[location_name] = location

        return location.add_location(path)

class Route(AbstractRoute):
    def __init__(self, method, handler, resource, *,
                 expect_handler=None, location=None, **kwargs):
        handler, self._handler_args = self._wrap_handler(handler)
        super().__init__(method, handler,
                         expect_handler=expect_handler,
                         resource=resource)
        self._location = location

    def __repr__(self):
        return type(self).__name__

    @property
    def name(self):
        return self._location.name

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url_for(*args, **kwargs)

    def url(self, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url(**kwargs)

    def get_info(self):
        return self._location.get_info()

    @property
    def location(self):
        return self._location

    @location.setter
    def location(self, value):
        self._location = value

    @classmethod
    def _wrap_handler(cls, handler):
        if isinstance(handler, str):
            return cls._import_handler(handler)
        signature = inspect.signature(handler)
        handler_kwargs = frozenset(signature.parameters.keys())
        return handler, handler_kwargs

    @classmethod
    def _import_handler(cls, path: str):
        p = path.rsplit('.', 2)
        if len(p) == 3:
            p, v, h = p
            if v == v.lower():
                p = '.'.join((p, v))
                v = None
        elif len(p) == 2:
            p, h = p
            v = None
        else:
            raise ValueError('.'.join(p))

        package = importlib.import_module(p)

        if not v:
            return cls._wrap_handler(getattr(package, h))

        View = getattr(package, v)

        if issubclass(View, AbstractView):
            return cls._wrap_handler(View)

        handler = getattr(View, h)
        signature = inspect.signature(getattr(View(), h))
        handler_kwargs = frozenset(signature.parameters.keys())
        if 'request' in handler_kwargs:
            def wrap_handler(request, *args, **kwargs):
                vi = View()
                vi.request = request
                return handler(vi, request, *args, **kwargs)
        else:
            def wrap_handler(request, *args, **kwargs):
                vi = View()
                vi.request = request
                return handler(vi, *args, **kwargs)

        wrap_handler.__signature__ = signature
        return wrap_handler, {'request'}.union(handler_kwargs)

class TreeResource:
    def __init__(self, *, name=None,
                 route_factory=None,
                 sublocation_factory=None):
        self._routes = []
        self._route_factory = route_factory or Route
        self._sublocation_factory = sublocation_factory or SubLocation
        self._location = self._sublocation_factory('')
        self._name = name

    @property
    def name(self):
        return self._name

    def add_route(self, method, handler, *,
                  path='/', expect_handler=None, **kwargs):
        path = self._location.split(path)
        route = self._route_factory(method, handler, self,
                                    expect_handler=expect_handler, **kwargs)
        location = self._location.register_route(path, route)
        route.location = location
        return route

    @asyncio.coroutine
    def resolve(self, request):
        path = getattr(request, 'rel_url', request).raw_path
        return self._location.resolve(request, path[1:], {})

    def get_info(self):
        return {}

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url_for(*args, **kwargs)

    def url(self, *, parts=None, query=None):
        return self._location.url(parts=parts, query=query)

    def add_prefix(self, prefix):
        pass  # TODO

    def __repr__(self):
        name = "'" + self.name + "' " if self.name is not None else ""
        return "<TreeResource {name}>".format(name=name)

    def __len__(self):
        return len(self._routes)

    def __iter__(self):
        return iter(self._routes)

class ResourcesView(Sized, Iterable, Container):

    def __init__(self, resource: TreeResource):
        location = resource._location
        self._resources = self._append(location, [location])

    def _append(self, location: SubLocation, acc):
        ptrns = (l for p, l in location._patterns)
        for i in chain(location._subs.values(), ptrns):
            acc.append(i)
            self._append(i, acc)
        return acc

    def __len__(self):
        return len(self._resources)

    def __iter__(self):
        yield from self._resources

    def __contains__(self, resource):
        return resource in self._resources

class RoutesView(Sized, Iterable, Container):

    def __init__(self, resource: TreeResource):
        location = resource._location
        self._routes = self._append(location, [])

    def _append(self, location: SubLocation, acc):
        ptrns = (l for p, l in location._patterns)
        for i in chain(location._subs.values(), ptrns):
            acc.extend(i._routes.values())
            self._append(i, acc)
        return acc

    def __len__(self):
        return len(self._routes)

    def __iter__(self):
        yield from self._routes

    def __contains__(self, route):
        return route in self._routes

class TreeUrlDispatcher(CompatRouter, Mapping):
    def __init__(self, *,
                 resource_factory=TreeResource,
                 route_factory=Route):
        super().__init__()
        self._resource = resource_factory(route_factory=route_factory)
        self._executor = None

    @asyncio.coroutine
    def resolve(self, request):
        match, allowed = yield from self._resource.resolve(request)

        if match is not None:
            return match
        elif allowed:
            return MatchInfoError(
                HTTPMethodNotAllowed(request.method, allowed))
        else:
            return MatchInfoError(HTTPNotFound())

    def resources(self):
        return ResourcesView(self._resource)

    def routes(self):
        return RoutesView(self._resource)

    @property
    def tree_resource(self) -> TreeResource:
        return self._resource

    def add_route(self, method, path, handler,
                  *, name=None, expect_handler=None, **kwargs):
        if path and not path.startswith('/'):
            raise ValueError("path should be started with / or be empty")
        if name:
            self.validate_name(name)

        route = self.tree_resource.add_route(
            method=method, handler=handler,
            path=path, expect_handler=expect_handler,
            **kwargs)

        if name:
            self._named_resources[name] = route.location
        return route

    def add_resource(self, path, *, name=None):
        if path and not path.startswith('/'):
            raise ValueError("path should be started with / or be empty")
        if name:
            self.validate_name(name)

        location = self._resource._location.add_location(path)

        if name:
            self._named_resources[name] = location

        return location

    def add_static(self, prefix, path, *, name=None):
        from concurrent.futures import ThreadPoolExecutor

        if not prefix.endswith('/'):
            prefix += '/'

        if self._executor is None:
            self._executor = ThreadPoolExecutor(max_workers=1)

        if isinstance(path, str):
            path = Path(path)

        def read_bytes(path):
            with path.open() as f:
                return f.read()

        @asyncio.coroutine
        def content(request):
            filename = request.match_info['filename']
            if '..' in filename:
                raise HTTPForbidden()
            ct, encoding = mimetypes.guess_type(filename)
            if not ct:
                ct = 'application/octet-stream'
            f = path / filename
            body = yield from request.app.loop.run_in_executor(
                self._executor, read_bytes, f)
            return Response(body=body, content_type=ct)

        self.add_route('GET', prefix + '{filename:.*}', content, name=name)
<commit_msg>read_bytes mode br<commit_after>import asyncio
import importlib
import inspect
import mimetypes
import re
from collections.abc import Container, Iterable, Mapping, Sized
from itertools import chain
from urllib import parse
from pathlib import Path

import yarl
from aiohttp import hdrs
from aiohttp.abc import AbstractView
from aiohttp.web_exceptions import \
    HTTPMethodNotAllowed, HTTPNotFound, HTTPForbidden
from aiohttp.web import Response

from .compat import (
    CompatRouter, AbstractRoute, UrlMappingMatchInfo, MatchInfoError,
)

class SubLocation:
    SPLIT = re.compile(r'/((?:(?:\{.+?\})|(?:[^/{}]+))+)')

    def __init__(self, name, formatter=None, parent=None):
        self._name = name
        self._formatter = formatter or name
        self._parent = parent
        self._subs = {}
        self._patterns = []
        self._routes = {}

    @property
    def name(self):
        return self._name

    def url(self, *, parts=None, query=None):
        formatters = [self._formatter]
        parent = self._parent
        while parent is not None:
            formatters.append(parent._formatter)
            parent = parent._parent
        if len(formatters) == 1:
            url = self._formatter or '/'
        else:
            url = '/'.join(reversed(formatters))
        if parts:
            url = url.format_map(parts)
        if query:
            url += "?" + parse.urlencode(query)
        return url

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return yarl.URL(self.url(parts=kwargs))

    def get_info(self):
        return {}

    def __repr__(self):
        return '<SubLocation {name}, url={url}>' \
               ''.format(name=self.name, url=self.url())

    @classmethod
    def split(cls, path):
        locations = [i for i in cls.SPLIT.split(path) if i]
        if locations[-1] == '/':
            locations[-1] = ''
        return locations

    def resolve(self, request, path: str, match_dict: dict):
        method = request.method
        allowed_methods = set()

        if path is None:
            allowed_methods.update(self._routes)
            if method in self._routes:
                route = self._routes[method]
            elif hdrs.METH_ANY in self._routes:
                route = self._routes[hdrs.METH_ANY]
            else:
                return None, allowed_methods
            return UrlMappingMatchInfo(match_dict, route), allowed_methods
        elif not path:
            location = path
            tail = None
        else:
            parts = path.split('/', 1)
            if len(parts) == 2:
                location, tail = parts
            else:
                location = parts[0]
                tail = None

        if location in self._subs:
            return self._subs[location].resolve(
                request=request,
                path=tail,
                match_dict=match_dict)

        for pattern, sublocation in self._patterns:
            m = pattern.match(path)
            if m is not None:
                for key, value in m.groupdict().items():
                    match_dict[key] = parse.unquote(value)

                index = m.end()
                if len(path) > index:
                    if path[index] == '/':
                        index += 1
                    tail = path[index:]
                else:
                    tail = None

                return sublocation.resolve(
                    request=request, path=tail, match_dict=match_dict)
        return None, allowed_methods

    def register_route(self, path, route):
        if not path:
            assert route.method not in self._routes, self
            self._routes[route.method] = route
            return self
        location = self.add_location(path)
        return location.register_route(None, route)

    def add_location(self, path):
        if isinstance(path, str):
            path = self.split(path)
        if not path:
            return self

        location_name, *path = path

        if '{' in location_name:
            for pattern, loc in self._patterns:
                if loc.name == location_name:
                    location = loc
                    break
            else:
                pattern, formatter = \
                    TreeUrlDispatcher.get_pattern_formatter(location_name)
                location = type(self)(location_name, formatter, parent=self)
                self._patterns.append((re.compile(pattern), location))
        elif location_name in self._subs:
            location = self._subs[location_name]
        else:
            location = type(self)(location_name, parent=self)
            self._subs[location_name] = location

        return location.add_location(path)

class Route(AbstractRoute):
    def __init__(self, method, handler, resource, *,
                 expect_handler=None, location=None, **kwargs):
        handler, self._handler_args = self._wrap_handler(handler)
        super().__init__(method, handler,
                         expect_handler=expect_handler,
                         resource=resource)
        self._location = location

    def __repr__(self):
        return type(self).__name__

    @property
    def name(self):
        return self._location.name

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url_for(*args, **kwargs)

    def url(self, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url(**kwargs)

    def get_info(self):
        return self._location.get_info()

    @property
    def location(self):
        return self._location

    @location.setter
    def location(self, value):
        self._location = value

    @classmethod
    def _wrap_handler(cls, handler):
        if isinstance(handler, str):
            return cls._import_handler(handler)
        signature = inspect.signature(handler)
        handler_kwargs = frozenset(signature.parameters.keys())
        return handler, handler_kwargs

    @classmethod
    def _import_handler(cls, path: str):
        p = path.rsplit('.', 2)
        if len(p) == 3:
            p, v, h = p
            if v == v.lower():
                p = '.'.join((p, v))
                v = None
        elif len(p) == 2:
            p, h = p
            v = None
        else:
            raise ValueError('.'.join(p))

        package = importlib.import_module(p)

        if not v:
            return cls._wrap_handler(getattr(package, h))

        View = getattr(package, v)

        if issubclass(View, AbstractView):
            return cls._wrap_handler(View)

        handler = getattr(View, h)
        signature = inspect.signature(getattr(View(), h))
        handler_kwargs = frozenset(signature.parameters.keys())
        if 'request' in handler_kwargs:
            def wrap_handler(request, *args, **kwargs):
                vi = View()
                vi.request = request
                return handler(vi, request, *args, **kwargs)
        else:
            def wrap_handler(request, *args, **kwargs):
                vi = View()
                vi.request = request
                return handler(vi, *args, **kwargs)

        wrap_handler.__signature__ = signature
        return wrap_handler, {'request'}.union(handler_kwargs)

class TreeResource:
    def __init__(self, *, name=None,
                 route_factory=None,
                 sublocation_factory=None):
        self._routes = []
        self._route_factory = route_factory or Route
        self._sublocation_factory = sublocation_factory or SubLocation
        self._location = self._sublocation_factory('')
        self._name = name

    @property
    def name(self):
        return self._name

    def add_route(self, method, handler, *,
                  path='/', expect_handler=None, **kwargs):
        path = self._location.split(path)
        route = self._route_factory(method, handler, self,
                                    expect_handler=expect_handler, **kwargs)
        location = self._location.register_route(path, route)
        route.location = location
        return route

    @asyncio.coroutine
    def resolve(self, request):
        path = getattr(request, 'rel_url', request).raw_path
        return self._location.resolve(request, path[1:], {})

    def get_info(self):
        return {}

    def url_for(self, *args, **kwargs):
        """Construct url for route with additional params."""
        return self._location.url_for(*args, **kwargs)

    def url(self, *, parts=None, query=None):
        return self._location.url(parts=parts, query=query)

    def add_prefix(self, prefix):
        pass  # TODO

    def __repr__(self):
        name = "'" + self.name + "' " if self.name is not None else ""
        return "<TreeResource {name}>".format(name=name)

    def __len__(self):
        return len(self._routes)

    def __iter__(self):
        return iter(self._routes)

class ResourcesView(Sized, Iterable, Container):

    def __init__(self, resource: TreeResource):
        location = resource._location
        self._resources = self._append(location, [location])

    def _append(self, location: SubLocation, acc):
        ptrns = (l for p, l in location._patterns)
        for i in chain(location._subs.values(), ptrns):
            acc.append(i)
            self._append(i, acc)
        return acc

    def __len__(self):
        return len(self._resources)

    def __iter__(self):
        yield from self._resources

    def __contains__(self, resource):
        return resource in self._resources

class RoutesView(Sized, Iterable, Container):

    def __init__(self, resource: TreeResource):
        location = resource._location
        self._routes = self._append(location, [])

    def _append(self, location: SubLocation, acc):
        ptrns = (l for p, l in location._patterns)
        for i in chain(location._subs.values(), ptrns):
            acc.extend(i._routes.values())
            self._append(i, acc)
        return acc

    def __len__(self):
        return len(self._routes)

    def __iter__(self):
        yield from self._routes

    def __contains__(self, route):
        return route in self._routes

class TreeUrlDispatcher(CompatRouter, Mapping):
    def __init__(self, *,
                 resource_factory=TreeResource,
                 route_factory=Route):
        super().__init__()
        self._resource = resource_factory(route_factory=route_factory)
        self._executor = None

    @asyncio.coroutine
    def resolve(self, request):
        match, allowed = yield from self._resource.resolve(request)

        if match is not None:
            return match
        elif allowed:
            return MatchInfoError(
                HTTPMethodNotAllowed(request.method, allowed))
        else:
            return MatchInfoError(HTTPNotFound())

    def resources(self):
        return ResourcesView(self._resource)

    def routes(self):
        return RoutesView(self._resource)

    @property
    def tree_resource(self) -> TreeResource:
        return self._resource

    def add_route(self, method, path, handler,
                  *, name=None, expect_handler=None, **kwargs):
        if path and not path.startswith('/'):
            raise ValueError("path should be started with / or be empty")
        if name:
            self.validate_name(name)

        route = self.tree_resource.add_route(
            method=method, handler=handler,
            path=path, expect_handler=expect_handler,
            **kwargs)

        if name:
            self._named_resources[name] = route.location
        return route

    def add_resource(self, path, *, name=None):
        if path and not path.startswith('/'):
            raise ValueError("path should be started with / or be empty")
        if name:
            self.validate_name(name)

        location = self._resource._location.add_location(path)

        if name:
            self._named_resources[name] = location

        return location

    def add_static(self, prefix, path, *, name=None):
        from concurrent.futures import ThreadPoolExecutor

        if not prefix.endswith('/'):
            prefix += '/'

        if self._executor is None:
            self._executor = ThreadPoolExecutor(max_workers=1)

        if isinstance(path, str):
            path = Path(path)

        def read_bytes(path):
            with path.open('br') as f:
                return f.read()

        @asyncio.coroutine
        def content(request):
            filename = request.match_info['filename']
            if '..' in filename:
                raise HTTPForbidden()
            ct, encoding = mimetypes.guess_type(filename)
            if not ct:
                ct = 'application/octet-stream'
            f = path / filename
            body = yield from request.app.loop.run_in_executor(
                self._executor, read_bytes, f)
            return Response(body=body, content_type=ct)

        self.add_route('GET', prefix + '{filename:.*}', content, name=name)
<|endoftext|>


<commit_before># Copyright 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file is autogenerated by copybara, please do not edit.

buildtools_version = "ea23b22a5994820220102fcb8ddd0b7f0cb1fc0f"
buildtools_sha256 = "e705f98876250524cc182b3b3aabe77ef8b5ab9dfbc19ccaf8032da6b11796f7"
<commit_msg>Update dependency bazelbuild/buildtools to latest version<commit_after># Copyright 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file is autogenerated by copybara, please do not edit.

buildtools_version = "0b848d2e5e83b953e089194150fec04df7e8f96d"
buildtools_sha256 = "56d4c0ea3c32bed45139561df235afa35a3e5e49977edeab78d71c5826722abf"
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009-2010 Guillaume Pellerin <yomguy@parisson.com>

# This file is part of TimeSide.

# TimeSide is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# TimeSide is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.

# Author: Guillaume Pellerin <yomguy@parisson.com>

version = '0.1-beta'

import os
import sys
import timeside

class GrapherScheme:

    def __init__(self):

        self.color_scheme = {
            'waveform': [ # Four (R,G,B) tuples for three main color channels for the spectral centroid method
                        (50,0,200), (0,220,80), (255,224,0), (255,0,0)
                        ],
            'spectrogram': [
                        (0, 0, 0), (58/4,68/4,65/4), (80/2,100/2,153/2), (90,180,100), (224,224,44), (255,60,30), (255,255,255)
                        ]}

        # Width of the image
        self.width = 655

        # Height of the image
        self.height = 96

        # Background color
        self.bg_color = (0,0,0)

        # Force computation. By default, the class doesn't overwrite existing image files.
        self.force = True

class Media2Waveform(object):

    def __init__(self, media_dir, img_dir):
        self.root_dir = os.path.join(os.path.dirname(__file__), media_dir)
        self.img_dir = os.path.join(os.path.dirname(__file__), img_dir)
        self.scheme = GrapherScheme()
        self.width = self.scheme.width
        self.height = self.scheme.height
        self.bg_color = self.scheme.bg_color
        self.color_scheme = self.scheme.color_scheme
        self.force = self.scheme.force

        self.media_list = self.get_media_list()
        if not os.path.exists(self.img_dir):
            os.makedirs(self.img_dir)
        self.path_dict = self.get_path_dict()

    def get_media_list(self):
        media_list = []
        for root, dirs, files in os.walk(self.root_dir):
            if root:
                for file in files:
                    ext = file.split('.')[-1]
                    media_list.append(root+os.sep+file)
        return media_list

    def get_path_dict(self):
        path_dict = {}
        for media in self.media_list:
            filename = media.split(os.sep)[-1]
            name, ext = os.path.splitext(filename)
            path_dict[media] = self.img_dir + os.sep + filename.replace('.',  '_') + '.png'
        return path_dict

    def process(self):
        for source, image in self.path_dict.iteritems():
            if not os.path.exists(image) or self.force:
                print 'Processing ', source
                audio = os.path.join(os.path.dirname(__file__), source)
                decoder  = timeside.decoder.FileDecoder(audio)
                analyzer = timeside.analyzer.Duration()
                waveform = timeside.grapher.WaveformJoyDiv(width=self.width, height=self.height,
                                            bg_color=self.bg_color, color_scheme=self.color_scheme)
                (decoder | analyzer | waveform).run()
                duration = analyzer.result()
                img_name = os.path.split(image)[1]
                image = os.path.split(image)[0]+os.sep+os.path.splitext(img_name)[0] + '_' +\
                        '_'.join([str(self.width),  str(self.height),  str(int(duration))])+os.path.splitext(img_name)[1]
                waveform.graph.filename = image
                print 'Rendering ', source, ' to ', waveform.graph.filename, '...'
                print 'frames per pixel = ', waveform.graph.samples_per_pixel
                waveform.render(output=image)

if __name__ == '__main__':
    if len(sys.argv) <= 2:
        print """
        Usage : python waveform_batch /path/to/media_dir /path/to/img_dir

        Dependencies : timeside, python, python-numpy, python-gst0.10, gstreamer0.10-plugins-base
        See http://code.google.com/p/timeside/ for more information.
        """
    else:
        media_dir = sys.argv[-2]
        img_dir = sys.argv[-1]
        m = Media2Waveform(media_dir, img_dir)
        m.process()
<commit_msg>fix bg for waveform_batch script + cleanup<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009-2010 Guillaume Pellerin <yomguy@parisson.com>

# This file is part of TimeSide.

# TimeSide is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# TimeSide is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.

# Author: Guillaume Pellerin <yomguy@parisson.com>

version = '0.2'

import os
import sys
import timeside

class GrapherScheme:

    def __init__(self):

        self.color_scheme = {
            'waveform': [
            # Four (R,G,B) tuples for three main color channels for the spectral centroid method
                        (30,144,255), (30,144,255), (30,144,255), (30,144,255)
                        ],
            'spectrogram': [
                        (0, 0, 0), (58/4,68/4,65/4), (80/2,100/2,153/2),
                        (90,180,100), (224,224,44), (255,60,30), (255,255,255)
                        ]}

        # Width of the image
        self.width = 925

        # Height of the image
        self.height = 67

        # Background color
        self.bg_color = (-1, -1, -1, -1)

        # Force computation. By default, the class doesn't overwrite existing image files.
        self.force = True

class Media2Waveform(object):

    def __init__(self, media_dir, img_dir):
        self.root_dir = os.path.join(os.path.dirname(__file__), media_dir)
        self.img_dir = os.path.join(os.path.dirname(__file__), img_dir)
        self.scheme = GrapherScheme()
        self.width = self.scheme.width
        self.height = self.scheme.height
        self.bg_color = self.scheme.bg_color
        self.color_scheme = self.scheme.color_scheme
        self.force = self.scheme.force

        self.media_list = self.get_media_list()
        if not os.path.exists(self.img_dir):
            os.makedirs(self.img_dir)
        self.path_dict = self.get_path_dict()

    def get_media_list(self):
        media_list = []
        for root, dirs, files in os.walk(self.root_dir):
            if root:
                for file in files:
                    ext = file.split('.')[-1]
                    if not file[0] == '.':
                        media_list.append(root+os.sep+file)
        return media_list

    def get_path_dict(self):
        path_dict = {}
        for media in self.media_list:
            filename = media.split(os.sep)[-1]
            name, ext = os.path.splitext(filename)
            path_dict[media] = self.img_dir + os.sep + filename.replace('.',  '_') + '.png'
        return path_dict

    def process(self):
        waveform = timeside.grapher.Waveform(width=self.width, height=self.height,
                            bg_color=self.bg_color, color_scheme=self.color_scheme)
        for source, image in self.path_dict.iteritems():
            if not os.path.exists(image) or self.force:
                print 'Processing ', source
                audio = os.path.join(os.path.dirname(__file__), source)
                decoder  = timeside.decoder.FileDecoder(audio)
                duration = decoder.duration
                (decoder | waveform).run()
                img_name = os.path.split(image)[1]
                image = os.path.split(image)[0]+os.sep+os.path.splitext(img_name)[0] + '_' +\
                        '_'.join([str(self.width),  str(self.height),
                                  str(int(duration))])+os.path.splitext(img_name)[1]
                waveform.graph.filename = image
                print 'Rendering ', waveform.graph.filename
                #print 'frames per pixel = ', waveform.graph.samples_per_pixel
                waveform.render(output=image)

if __name__ == '__main__':
    if len(sys.argv) <= 1:
        print """
        TimeSide simple waveform generator

        Usage : python waveform_batch.py /path/to/media_dir /path/to/img_dir

        Dependencies : timeside, python, python-numpy, python-gst0.10, gstreamer0.10-plugins-base
        See http://code.google.com/p/timeside/ for more information.
        """
    else:
        media_dir = sys.argv[-2]
        img_dir = sys.argv[-1]
        m = Media2Waveform(media_dir, img_dir)
        m.process()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
import mongodb_store_msgs.srv as dc_srv
import mongodb_store.util as dc_util
from mongodb_store.message_store import MessageStoreProxy
from strands_executive_msgs.msg import Task, TaskEvent
from datetime import datetime, timedelta
from task_executor import task_routine, task_query
from task_executor.utils import rostime_to_python

import argparse
import cmd

class RoutineAnalyser(cmd.Cmd):

    def __init__(self, msg_store, routine_pairs):
        cmd.Cmd.__init__(self)
        # super(RoutineAnalyser, self).__init__()
        self.routine_pairs = routine_pairs
        self.msg_store = msg_store

    def check_idx(self, idx):
        if idx < 0 or idx >= len(self.routine_pairs):
            print 'idx must be greater than 0 and less than %s' % len(self.routine_pairs)
            return False
        else:
            return True

    def do_merge(self, idx):
        try:
            if idx == 'all':
                self.routine_pairs = [(self.routine_pairs[0][0], self.routine_pairs[-1][1])]
            else:
                idx = int(idx)
                if idx >= 0 and idx < len(self.routine_pairs) - 1:
                    print 'merging %s into %s' % (idx, idx+1)
                    self.routine_pairs[idx+1] = (self.routine_pairs[idx][0], self.routine_pairs[idx+1][1])
                    del self.routine_pairs[idx]
                else:
                    print 'invalid routine index, valid range from 0 to %s' % (len(self.routine_pairs) - 2)
        except ValueError, e:
            print 'provided argument was not an int: %s' % idx

    def do_print(self, line):
        for i in range(len(self.routine_pairs)):
            start = rostime_to_python(self.routine_pairs[i][0].time)
            end = rostime_to_python(self.routine_pairs[i][1].time)
            results = task_query.query_tasks(msg_store,
                        start_date=start,
                        end_date=end,
                        event=[TaskEvent.TASK_STARTED]
                        )

            print 'routine %s: %s to %s, duration: %s, tasks: %s' % (i, start, end, end-start, len(results))

    def do_summarise(self, idx):

        try:
            idx = int(idx)

            if not self.check_idx(idx):
                return

            window_start = rostime_to_python(self.routine_pairs[idx][0].time)
            window_end = rostime_to_python(self.routine_pairs[idx][1].time)

            results = task_query.query_tasks(self.msg_store,
                        event=range(TaskEvent.TASK_STARTED, TaskEvent.ROUTINE_STARTED),
                        start_date=window_start,
                        end_date=window_end,
                        )
            task_query.aggregate(results)

        except ValueError, e:
            print 'provided argument was not an int: %s' % idx

    def do_executions(self, line):
        try:

            tokens = line.split(' ')
            idx = tokens[0]

            if len(tokens) > 1 and len(tokens[1]) > 0:
                action = tokens[1]
                print 'only showing action: %s' % action
            else:
                action = None

            idx = int(idx)

            if not self.check_idx(idx):
                return

            print 'executions in routine %s' % idx
            window_start = rostime_to_python(self.routine_pairs[idx][0].time)
            window_end = rostime_to_python(self.routine_pairs[idx][1].time)

            results = task_query.query_tasks(self.msg_store,
                        event=range(TaskEvent.TASK_STARTED, TaskEvent.ROUTINE_STARTED),
                        action=action,
                        start_date=window_start,
                        end_date=window_end,
                        )
            task_query.executions(results)

        except ValueError, e:
            print 'provided argument was not an int: %s' % idx
            print e

    def help_print(self):
        print '\n'.join([ 'print', 'Print the available routines'])

    def help_merge(self):
        print '\n'.join([ 'merge [idx | all]', 'Merge routine idx (int) into the routine after it. If idx is the string all, then merge all routines together.'])

    def help_executions(self):
        print '\n'.join([ 'executions [idx]', 'Show all task executions in routine idx (int).'])

    def help_summarise(self):
        print '\n'.join([ 'summarise [idx]', 'Summarise task executions in routine idx (int).'])

if __name__ == '__main__':

    rospy.init_node("routine_analysis")

    msg_store = MessageStoreProxy(collection='task_events')

    parser = argparse.ArgumentParser(description='Analyses the task execution behaviour in a routine window. Assumes all task ids are unique in this window.')
    parser.add_argument('start', metavar='S', type=task_query.mkdatetime, nargs='?',
                   help='Start datetime of window for routines. Formatted "d/m/y H:M" e.g. "06/07/14 06:38"')

    parser.add_argument('end', metavar='E', type=task_query.mkdatetime, nargs='?',
                   help='End datetime of window for routines. Formatted "d/m/y H:M" e.g. "06/07/14 06:38"')

    parser.add_argument('-t', '--tasks', type=int, default=1, nargs='?',
                    help='Number of tasks required for a routine to be considered')

    parser.add_argument('-o', '--open', type=task_query.mktime, nargs='?',
                    help='Daily start time of the routine. Formatted "H:M" e.g. "06:38"')

    parser.add_argument('-c', '--close', type=task_query.mktime, nargs='?',
                    help='Daily end time of the routine. Formatted "H:M" e.g. "17:45"')

    args = parser.parse_args()

    try:

        results = task_query.query_tasks(msg_store, event=[TaskEvent.ROUTINE_STARTED, TaskEvent.ROUTINE_STOPPED])

        # make sure we start with a ROUTINE_STARTED
        while results[0][0].event == TaskEvent.ROUTINE_STOPPED:
            del results[0]
            print 'pruned stop start'

        routines = []
        start = None

        # make sure we just have the pairs which are start/end
        for e in results:
            event = e[0]
            if event.event == TaskEvent.ROUTINE_STARTED:
                start = event
            elif event.event == TaskEvent.ROUTINE_STOPPED:
                assert start is not None
                routines.append((start, event))
                start = None

        allow_open = True
        if results[-1][0].event == TaskEvent.ROUTINE_STARTED and allow_open:
            print 'adding open'
            dummy_end = TaskEvent(event = TaskEvent.ROUTINE_STOPPED, task = Task(), time = rospy.get_rostime())
            routines.append((results[-1][0], dummy_end))

        filtered_routines = []
        for i in range(len(routines)):
            start = rostime_to_python(routines[i][0].time)
            end = rostime_to_python(routines[i][1].time)
            results = task_query.query_tasks(msg_store,
                        start_date=start,
                        end_date=end,
                        event=[TaskEvent.TASK_STARTED]
                        )

            if len(results) >= args.tasks:
                filtered_routines.append(routines[i])
                # print 'routine %s: %s to %s, duration: %s, tasks: %s' % (len(filtered_routines)-1, start, end, end-start, len(results))

        RoutineAnalyser(msg_store, filtered_routines).cmdloop()

        # if args.start is None:
        #     # find latest routine start
        #     results = task_query.query_tasks(msg_store, event=TaskEvent.ROUTINE_STARTED)
        #     assert len(results) > 0
        #     start = rostime_to_python(results[-1][0].time)
        # else:
        #     start = args.start

        # end = args.end
        # if end is None:
        #     results = task_query.query_tasks(msg_store, event=TaskEvent.ROUTINE_STOPPED)
        #     if len(results) > 0:
        #         end_routine = rostime_to_python(results[-1][0].time)
        #         if start is not None and end_routine > start:
        #             end = end_routine

        # results = task_query.query_tasks(msg_store,
        #                 start_date=start,
        #                 end_date=end,
        #                 event=[TaskEvent.TASK_STARTED, TaskEvent.TASK_FINISHED, TaskEvent.NAVIGATION_SUCCEEDED]
        #                 )

        # print 'Tasks Start: %s' % start
        # print 'Tasks End: %s' % end
        # task_query.summarise(results)

    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

<commit_msg>Messed formatting<commit_after>#!/usr/bin/env python
 -*- coding: utf-8 -*-

import rospy
import mongodb_store_msgs.srv as dc_srv
import mongodb_store.util as dc_util
from mongodb_store.message_store import MessageStoreProxy
from strands_executive_msgs.msg import Task, TaskEvent
from datetime import datetime, timedelta
from task_executor import task_routine, task_query
from task_executor.utils import rostime_to_python

import argparse
import cmd

class RoutineAnalyser(cmd.Cmd):

    def __init__(self, msg_store, routine_pairs):
        cmd.Cmd.__init__(self)
        # super(RoutineAnalyser, self).__init__()
        self.routine_pairs = routine_pairs
        self.msg_store = msg_store

    def check_idx(self, idx):
        if idx < 0 or idx >= len(self.routine_pairs):
            print 'idx must be greater than 0 and less than %s' % len(self.routine_pairs)
            return False
        else:
            return True

    def do_merge(self, idx):
        try:
            if idx == 'all':
                self.routine_pairs = [(self.routine_pairs[0][0], self.routine_pairs[-1][1])]
            else:
                idx = int(idx)
                if idx >= 0 and idx < len(self.routine_pairs) - 1:
                    print 'merging %s into %s' % (idx, idx+1)
                    self.routine_pairs[idx+1] = (self.routine_pairs[idx][0], self.routine_pairs[idx+1][1])
                    del self.routine_pairs[idx]
                else:
                    print 'invalid routine index, valid range from 0 to %s' % (len(self.routine_pairs) - 2)
        except ValueError, e:
            print 'provided argument was not an int: %s' % idx

    def do_print(self, line):
        for i in range(len(self.routine_pairs)):
            start = rostime_to_python(self.routine_pairs[i][0].time)
            end = rostime_to_python(self.routine_pairs[i][1].time)
            results = task_query.query_tasks(msg_store,
                        start_date=start,
                        end_date=end,
                        event=[TaskEvent.TASK_STARTED]
                        )

            print 'routine %s: %s to %s, duration: %s, tasks: %s' % (i, start, end, end-start, len(results))

    def do_summarise(self, idx):

        try:
            idx = int(idx)

            if not self.check_idx(idx):
                return

            window_start = rostime_to_python(self.routine_pairs[idx][0].time)
            window_end = rostime_to_python(self.routine_pairs[idx][1].time)

            results = task_query.query_tasks(self.msg_store,
                        event=range(TaskEvent.TASK_STARTED, TaskEvent.ROUTINE_STARTED),
                        start_date=window_start,
                        end_date=window_end,
                        )
            task_query.aggregate(results)

        except ValueError, e:
            print 'provided argument was not an int: %s' % idx

    def do_executions(self, line):
        try:

            tokens = line.split(' ')
            idx = tokens[0]

            if len(tokens) > 1 and len(tokens[1]) > 0:
                action = tokens[1]
                print 'only showing action: %s' % action
            else:
                action = None

            idx = int(idx)

            if not self.check_idx(idx):
                return

            print 'executions in routine %s' % idx
            window_start = rostime_to_python(self.routine_pairs[idx][0].time)
            window_end = rostime_to_python(self.routine_pairs[idx][1].time)

            results = task_query.query_tasks(self.msg_store,
                        event=range(TaskEvent.TASK_STARTED, TaskEvent.ROUTINE_STARTED),
                        action=action,
                        start_date=window_start,
                        end_date=window_end,
                        )
            task_query.executions(results)

        except ValueError, e:
            print 'provided argument was not an int: %s' % idx
            print e

    def help_print(self):
        print '\n'.join([ 'print', 'Print the available routines'])

    def help_merge(self):
        print '\n'.join([ 'merge [idx | all]', 'Merge routine idx (int) into the routine after it. If idx is the string all, then merge all routines together.'])

    def help_executions(self):
        print '\n'.join([ 'executions [idx]', 'Show all task executions in routine idx (int).'])

    def help_summarise(self):
        print '\n'.join([ 'summarise [idx]', 'Summarise task executions in routine idx (int).'])

if __name__ == '__main__':

    rospy.init_node("routine_analysis")

    msg_store = MessageStoreProxy(collection='task_events')

    parser = argparse.ArgumentParser(description='Analyses the task execution behaviour in a routine window. Assumes all task ids are unique in this window.')
    parser.add_argument('start', metavar='S', type=task_query.mkdatetime, nargs='?',
                   help='Start datetime of window for routines. Formatted "d/m/y H:M" e.g. "06/07/14 06:38"')

    parser.add_argument('end', metavar='E', type=task_query.mkdatetime, nargs='?',
                   help='End datetime of window for routines. Formatted "d/m/y H:M" e.g. "06/07/14 06:38"')

    parser.add_argument('-t', '--tasks', type=int, default=1, nargs='?',
                    help='Number of tasks required for a routine to be considered')

    parser.add_argument('-o', '--open', type=task_query.mktime, nargs='?',
                    help='Daily start time of the routine. Formatted "H:M" e.g. "06:38"')

    parser.add_argument('-c', '--close', type=task_query.mktime, nargs='?',
                    help='Daily end time of the routine. Formatted "H:M" e.g. "17:45"')

    args = parser.parse_args()

    try:

        results = task_query.query_tasks(msg_store, event=[TaskEvent.ROUTINE_STARTED, TaskEvent.ROUTINE_STOPPED])

        # make sure we start with a ROUTINE_STARTED
        while results[0][0].event == TaskEvent.ROUTINE_STOPPED:
            del results[0]
            print 'pruned stop start'

        routines = []
        start = None

        # make sure we just have the pairs which are start/end
        for e in results:
            event = e[0]
            if event.event == TaskEvent.ROUTINE_STARTED:
                start = event
            elif event.event == TaskEvent.ROUTINE_STOPPED:
                assert start is not None
                routines.append((start, event))
                start = None

        allow_open = True
        if results[-1][0].event == TaskEvent.ROUTINE_STARTED and allow_open:
            print 'adding open'
            dummy_end = TaskEvent(event = TaskEvent.ROUTINE_STOPPED, task = Task(), time = rospy.get_rostime())
            routines.append((results[-1][0], dummy_end))

        filtered_routines = []
        for i in range(len(routines)):
            start = rostime_to_python(routines[i][0].time)
            end = rostime_to_python(routines[i][1].time)
            results = task_query.query_tasks(msg_store,
                        start_date=start,
                        end_date=end,
                        event=[TaskEvent.TASK_STARTED]
                        )

            if len(results) >= args.tasks:
                filtered_routines.append(routines[i])
                # print 'routine %s: %s to %s, duration: %s, tasks: %s' % (len(filtered_routines)-1, start, end, end-start, len(results))

        RoutineAnalyser(msg_store, filtered_routines).cmdloop()

        # if args.start is None:
        #     # find latest routine start
        #     results = task_query.query_tasks(msg_store, event=TaskEvent.ROUTINE_STARTED)
        #     assert len(results) > 0
        #     start = rostime_to_python(results[-1][0].time)
        # else:
        #     start = args.start

        # end = args.end
        # if end is None:
        #     results = task_query.query_tasks(msg_store, event=TaskEvent.ROUTINE_STOPPED)
        #     if len(results) > 0:
        #         end_routine = rostime_to_python(results[-1][0].time)
        #         if start is not None and end_routine > start:
        #             end = end_routine

        # results = task_query.query_tasks(msg_store,
        #                 start_date=start,
        #                 end_date=end,
        #                 event=[TaskEvent.TASK_STARTED, TaskEvent.TASK_FINISHED, TaskEvent.NAVIGATION_SUCCEEDED]
        #                 )

        # print 'Tasks Start: %s' % start
        # print 'Tasks End: %s' % end
        # task_query.summarise(results)

    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

<|endoftext|>


<commit_before># Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Value for RaggedTensor."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

class RaggedTensorValue(object):
  """Represents the value of a `RaggedTensor`.

  See `RaggedTensor` for a description of ragged tensors.
  """

  def __init__(self, values, row_splits):
    """Creates a `RaggedTensorValue`.

    Args:
      values: A numpy array of any type and shape; or a RaggedTensorValue.
      row_splits: A 1-D int64 numpy array.
    """
    if not (isinstance(row_splits, (np.ndarray, np.generic)) and
            row_splits.dtype == np.int64 and row_splits.ndim == 1):
      raise TypeError("row_splits must be a 1D int64 numpy array")
    if not isinstance(values, (np.ndarray, np.generic, RaggedTensorValue)):
      raise TypeError("values must be a numpy array or a RaggedTensorValue")
    self._values = values
    self._row_splits = row_splits

  row_splits = property(
      lambda self: self._row_splits,
      doc="""The split indices for the ragged tensor value.""")
  values = property(
      lambda self: self._values,
      doc="""The concatenated values for all rows in this tensor.""")
  dtype = property(
      lambda self: self._values.dtype,
      doc="""The numpy dtype of values in this tensor.""")

  @property
  def flat_values(self):
    """The innermost `values` array for this ragged tensor value."""
    rt_values = self.values
    while isinstance(rt_values, RaggedTensorValue):
      rt_values = rt_values.values
    return rt_values

  @property
  def nested_row_splits(self):
    """The row_splits for all ragged dimensions in this ragged tensor value."""
    rt_nested_splits = [self.row_splits]
    rt_values = self.values
    while isinstance(rt_values, RaggedTensorValue):
      rt_nested_splits.append(rt_values.row_splits)
      rt_values = rt_values.values
    return tuple(rt_nested_splits)

  @property
  def ragged_rank(self):
    """The number of ragged dimensions in this ragged tensor value."""
    values_is_ragged = isinstance(self._values, RaggedTensorValue)
    return self._values.ragged_rank + 1 if values_is_ragged else 1

  @property
  def shape(self):
    """A tuple indicating the shape of this RaggedTensorValue."""
    return (self._row_splits.shape[0] - 1,) + (None,) + self._values.shape[1:]

  def __str__(self):
    return "<tf.RaggedTensorValue %s>" % self.to_list()

  def __repr__(self):
    return "tf.RaggedTensorValue(values=%r, row_splits=%r)" % (self._values,
                                                               self._row_splits)

  def to_list(self):
    """Returns this ragged tensor value as a nested Python list."""
    if isinstance(self._values, RaggedTensorValue):
      values_as_list = self._values.to_list()
    else:
      values_as_list = self._values.tolist()
    return [
        values_as_list[self._row_splits[i]:self._row_splits[i + 1]]
        for i in range(len(self._row_splits) - 1)
    ]
<commit_msg>Internal Change<commit_after># Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Value for RaggedTensor."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

class RaggedTensorValue(object):
  """Represents the value of a `RaggedTensor`.

  See `RaggedTensor` for a description of ragged tensors.
  """

  def __init__(self, values, row_splits):
    """Creates a `RaggedTensorValue`.

    Args:
      values: A numpy array of any type and shape; or a RaggedTensorValue.
      row_splits: A 1-D int64 numpy array.
    """
    if not (isinstance(row_splits, (np.ndarray, np.generic)) and
            row_splits.dtype == np.int64 and row_splits.ndim == 1):
      raise TypeError("row_splits must be a 1D int64 numpy array")
    if not isinstance(values, (np.ndarray, np.generic, RaggedTensorValue)):
      raise TypeError("values must be a numpy array or a RaggedTensorValue")
    self._values = values
    self._row_splits = row_splits

  row_splits = property(
      lambda self: self._row_splits,
      doc="""The split indices for the ragged tensor value.""")
  values = property(
      lambda self: self._values,
      doc="""The concatenated values for all rows in this tensor.""")
  dtype = property(
      lambda self: self._values.dtype,
      doc="""The numpy dtype of values in this tensor.""")

  @property
  def flat_values(self):
    """The innermost `values` array for this ragged tensor value."""
    rt_values = self.values
    while isinstance(rt_values, RaggedTensorValue):
      rt_values = rt_values.values
    return rt_values

  @property
  def nested_row_splits(self):
    """The row_splits for all ragged dimensions in this ragged tensor value."""
    rt_nested_splits = [self.row_splits]
    rt_values = self.values
    while isinstance(rt_values, RaggedTensorValue):
      rt_nested_splits.append(rt_values.row_splits)
      rt_values = rt_values.values
    return tuple(rt_nested_splits)

  @property
  def ragged_rank(self):
    """The number of ragged dimensions in this ragged tensor value."""
    values_is_ragged = isinstance(self._values, RaggedTensorValue)
    return self._values.ragged_rank + 1 if values_is_ragged else 1

  @property
  def shape(self):
    """A tuple indicating the shape of this RaggedTensorValue."""
    return (self._row_splits.shape[0] - 1,) + (None,) + self._values.shape[1:]

  def __str__(self):
    return "<tf.RaggedTensorValue %s>" % self.to_list()

  def __repr__(self):
    return "tf.RaggedTensorValue(values=%r, row_splits=%r)" % (self._values,
                                                               self._row_splits)

  def to_list(self):
    """Returns this ragged tensor value as a nested Python list."""
    if isinstance(self._values, RaggedTensorValue):
      values_as_list = self._values.to_list()
    else:
      values_as_list = self._values.tolist()
    return [
        values_as_list[self._row_splits[i]:self._row_splits[i + 1]]
        for i in range(len(self._row_splits) - 1)
    ]

  def value_rowids(self, name=None):
    del name
    row_lengths = self._row_splits[1:] - self._row_splits[:-1]
    nrows = self._row_splits.shape[-1] - 1
    indices = np.arange(nrows)
    return np.repeat(indices, repeats=row_lengths, axis=0)
<|endoftext|>


<commit_before>import falcon

# pylint:disable=R0201,W0613,E0602

class HelloWorldResource:
    def _handle_request(self, _, resp):
        resp.status = falcon.HTTP_201
        resp.body = "Hello World"

    def on_get(self, req, resp):
        self._handle_request(req, resp)

    def on_put(self, req, resp):
        self._handle_request(req, resp)

    def on_patch(self, req, resp):
        self._handle_request(req, resp)

    def on_post(self, req, resp):
        self._handle_request(req, resp)

    def on_delete(self, req, resp):
        self._handle_request(req, resp)

    def on_head(self, req, resp):
        self._handle_request(req, resp)

class ErrorResource:
    def on_get(self, req, resp):
        print(non_existent_var)  # noqa

def make_app():
    app = falcon.API()
    app.add_route("/hello", HelloWorldResource())
    app.add_route("/ping", HelloWorldResource())
    app.add_route("/error", ErrorResource())
    return app
<commit_msg>Make SpanProcessor.on_start accept parent Context (#1251)<commit_after>import falcon

# pylint:disable=R0201,W0613,E0602

class HelloWorldResource:
    def _handle_request(self, _, resp):
        # pylint: disable=no-member
        resp.status = falcon.HTTP_201
        resp.body = "Hello World"

    def on_get(self, req, resp):
        self._handle_request(req, resp)

    def on_put(self, req, resp):
        self._handle_request(req, resp)

    def on_patch(self, req, resp):
        self._handle_request(req, resp)

    def on_post(self, req, resp):
        self._handle_request(req, resp)

    def on_delete(self, req, resp):
        self._handle_request(req, resp)

    def on_head(self, req, resp):
        self._handle_request(req, resp)

class ErrorResource:
    def on_get(self, req, resp):
        print(non_existent_var)  # noqa

def make_app():
    app = falcon.API()
    app.add_route("/hello", HelloWorldResource())
    app.add_route("/ping", HelloWorldResource())
    app.add_route("/error", ErrorResource())
    return app
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2016-10-10 13:55
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('iati', '0050_auto_20160622_1650'),
    ]

    operations = [
        migrations.AddField(
            model_name='activity',
            name='published',
            field=models.BooleanField(db_index=True, default=False),
        ),
        migrations.AlterField(
            model_name='activity',
            name='default_lang',
            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='iati_codelists.Language'),
        ),
    ]
<commit_msg>migration update<commit_after># -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2016-10-10 13:55
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('iati', '0051_default_lang_fk_clean'),
    ]

    operations = [
        migrations.AddField(
            model_name='activity',
            name='published',
            field=models.BooleanField(db_index=True, default=False),
        ),
        migrations.AlterField(
            model_name='activity',
            name='default_lang',
            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='iati_codelists.Language'),
        ),
    ]
<|endoftext|>