Ejemplo n.º 1
0
    def __init__(self, local_node):
        VisitorRoute.__init__(self)

        self.__local_node = local_node
        self.__router = Router(local_node)
        self.__reflector = RouterReflect()
        self.debugging = 0
Ejemplo n.º 2
0
class RouterVisitor(VisitorRoute):
    def __init__(self, local_node):
        VisitorRoute.__init__(self)

        self.__local_node = local_node
        self.__router = Router(local_node)
        self.__reflector = RouterReflect()
        self.debugging = 0

    # Every method in this class should return a list of pair (destination, message)
    # The destination is a class 'Node' and the message is a (sub)class of 'RouteMessage'.

    def visit_RouteDirect(self, message):
        if (self.debugging & 1):
            import pdb
            pdb.set_trace()
        return self.__router.route_directly(message)

    def visit_RouteByNameID(self, message):
        if (self.debugging & 2):
            import pdb
            pdb.set_trace()
        return self.__router.route_by_name(message)

    def visit_RouteByNumericID(self, message):
        if (self.debugging & 4):
            import pdb
            pdb.set_trace()
        return self.__router.route_by_numeric(message)

    def visit_RouteByPayload(self, message):
        if (self.debugging & 8):
            import pdb
            pdb.set_trace()
        return message.route(self.__local_node)

    def visit_RouteByCPE(self, message):
        # message ISA RouteByCPE
        # payload ISA ApplicationMessage
        assert (message.space_part.first_component().value != None), (
            "message %s has invalid spacepart (no component value for %s)" %
            (repr(message), repr(message.space_part.first_component())))
        if (self.debugging & 16):
            import pdb
            pdb.set_trace()
        if (not message.forking):
            return self.__reflector.by_cpe_get_next_hop_insertion(
                self.__local_node, message)
        else:
            return self.__reflector.by_cpe_get_next_hop_forking(
                self.__local_node, message)
        # MessageDispatcher.dispatch() will be happy with a list of <neighbour, message>

    def __repr__(self):
        return "<RouterVisitor:" + repr(self.__reflector.trace) + ">"

    @property
    def trace(self):
        return self.__reflector.trace
Ejemplo n.º 3
0
def test_route(begin, end):
    network = load_network()
    router = Router(network)
    path = router.enroute(network.node(begin), network.node(end))
    if path is None:
        print 'Cannot find path between %s and %s' % (begin, end)
    else:
        print path
Ejemplo n.º 4
0
 def get(self):
     origin = self.request.get('origin')
     destination = self.request.get('destination')
     if origin is None or destination is None:
         self.send_json({'status': 'fail'})
     else:
         router = Router(test_routing.load_network())
         path = Path.as_geojson(router.enroute(origin, destination))
         self.send_json(path)
Ejemplo n.º 5
0
def getSafestRoutes():
    tolat = float(request.args["tolat"])
    tolon = float(request.args["tolon"])
    fromlat = float(request.args["fromlat"])
    fromlon = float(request.args["fromlon"])
    fromLoc = {'lat': fromlat, 'lng': fromlon}
    toLoc = {'lat': tolat, 'lng': tolon}

    r = Router(fromLoc, toLoc)
    print(json.dumps(r.getRoutes()))
    return json.dumps(r.getRoutes())
Ejemplo n.º 6
0
class RouterVisitor(VisitorRoute):

    def __init__(self, local_node):
        VisitorRoute.__init__(self)

        self.__local_node = local_node
        self.__router = Router(local_node)
        self.__reflector = RouterReflect()
        self.debugging=0

    # Every method in this class should return a list of pair (destination, message)
    # The destination is a class 'Node' and the message is a (sub)class of 'RouteMessage'.

    def visit_RouteDirect(self, message):
        if (self.debugging&1):
            import pdb; pdb.set_trace()
        return self.__router.route_directly(message)

    def visit_RouteByNameID(self, message):
        if (self.debugging&2):
            import pdb; pdb.set_trace()
        return self.__router.route_by_name(message)

    def visit_RouteByNumericID(self, message):
        if (self.debugging&4):
            import pdb; pdb.set_trace()
        return self.__router.route_by_numeric(message)

    def visit_RouteByPayload(self, message):
        if (self.debugging&8):
            import pdb; pdb.set_trace()
        return message.route(self.__local_node)

    def visit_RouteByCPE(self, message):
        # message ISA RouteByCPE
        # payload ISA ApplicationMessage
        assert (message.space_part.first_component().value != None),(
           "message %s has invalid spacepart (no component value for %s)"%
           (repr(message),repr(message.space_part.first_component())))
        if (self.debugging&16):
            import pdb; pdb.set_trace()
        if (not message.forking):
            return self.__reflector.by_cpe_get_next_hop_insertion(self.__local_node, message)
        else:
            return self.__reflector.by_cpe_get_next_hop_forking(self.__local_node, message)
        # MessageDispatcher.dispatch() will be happy with a list of <neighbour, message>

    def __repr__(self):
        return "<RouterVisitor:"+repr(self.__reflector.trace)+">"
    @property
    def trace(self):
        return self.__reflector.trace
Ejemplo n.º 7
0
    def decide_side_join(self, message):
        ln = self.__local_node
        nb    = ln.neighbourhood
        lname = ln.name_id
        jname = message.joining_node.name_id
        side  = Router.by_name_get_direction(lname, jname)
        nextn = nb.get_neighbour(side,0,jname)
        othern= nb.get_neighbour(not side,0,jname)
        wrapf = nb.can_wrap(side,jname) # wrap forwards
        wrapb = nb.can_wrap(not side,jname) # wrap backwards

        if (nextn.name_id == jname):
            hring = nb.get_ring(0).get_side(side)
            if hring.size<2:
                return side,ln # there isn't enough neighbours yet.
            nextn=hring.get_neighbours()[1] # skip new-comer

        if (not NodeID.lies_between_direction(side, lname, jname, nextn.name_id, wrapf)):
            ln.sign("need to reverse side %s-%s-%s %s!"%(lname, jname, nextn.name_id,repr(wrapf)))
            if (othern.name_id==jname):
                hring = nb.get_ring(0).get_side(not side)
                if hring.size<2:
                    return not side, ln
                othern=hring.get_neighbours()[1] #skip new-comer
            
            if(not NodeID.lies_between_direction(not side, lname, jname, othern.name_id, wrapb)):
                LOGGER.debug("?_? node %s shouldn't have received %s (%s ; %s)?_?"%(
                    ln,message.trace,othern.pname,repr(wrapb)))
                print(">_< debugging")
                import pdb; pdb.set_trace()
                print("<_> resuming")
        
            side = not side
            nextn= othern
        return side, nextn
Ejemplo n.º 8
0
    def __init__(self, local_node):
        VisitorRoute.__init__(self)

        self.__local_node = local_node
        self.__router = Router(local_node)
        self.__reflector = RouterReflect()
        self.debugging=0
Ejemplo n.º 9
0
    def __init__(self, **kwargs):
        #: A :class:`ConfigDict` for app specific configuration.
        self.config = self._global_config._make_overlay()
        self.config._add_change_listener(
            functools.partial(self.trigger_hook, 'config'))

        self.config.update({
            "catchall": True
        })

        if kwargs.get('catchall') is False:
            depr(0, 13, "Bottle(catchall) keyword argument.",
                        "The 'catchall' setting is now part of the app "
                        "configuration. Fix: `app.config['catchall'] = False`")
            self.config['catchall'] = False
        if kwargs.get('autojson') is False:
            depr(0, 13, "Bottle(autojson) keyword argument.",
                 "The 'autojson' setting is now part of the app "
                 "configuration. Fix: `app.config['json.enable'] = False`")
            self.config['json.disable'] = True

        self._mounts = []

        #: A :class:`ResourceManager` for application files
        self.resources = ResourceManager()

        self.routes = []  # List of installed :class:`Route` instances.
        self.router = Router()  # Maps requests to :class:`Route` instances.
        self.error_handler = {}

        # Core plugins
        self.plugins = []  # List of installed plugins.
        self.install(JSONPlugin())
        self.install(TemplatePlugin())
Ejemplo n.º 10
0
    def test_routing_cases(self):
        router = Router('tests/data/test_case_1.csv')
        cases = [('A', 'A', 0, 0), ('A', 'B', 0, 5), ('A', 'C', 1, 10),
                 ('E', 'J', 2, 30), ('A', 'D', 0, 15), ('H', 'I', 0, 10),
                 ('A', 'J', None), ('C', 'G', None)]

        for case in cases:
            self._test_routing_case(case, router, self)
Ejemplo n.º 11
0
def main(args) -> int:
    try:
        print("TrainRoutes CLI Started")

        print(f'Loading routes from {args.routes_file}')
        router = Router(args.routes_file)
        print('Routes loaded')
        # Support non-interactive origin/dest args
        origin = args.origin
        dest = args.dest
        start_cli_loop(router, origin, dest)
    except Exception as ex:
        print(ex, file=sys.stderr)
        return 1
Ejemplo n.º 12
0
def start_cli_loop(router: Router, origin: str = None, dest: str = None):
    interactive = not origin and not dest
    first_time = True

    while interactive or first_time:
        first_time = False

        # block until origin is valid
        while not router.has_station(origin):
            if origin:
                print(f'Station "{origin}" not found')
            origin = input('Enter Origin Station: ')

        # block until dest is valid
        while not router.has_station(dest):
            if dest:
                print(f'Station "{dest}" not found')
            dest = input('Enter Destination Station: ')

        print('Routing...')
        try:
            route = router.find_route(origin, dest)
            if route is None:
                print(f'Result: No routes from {origin} to {dest}')
            else:
                print(
                    f'Result: {route.stop_count} stop(s), {route.total_time} minute(s)'
                )
                print(
                    f'Details: {", ".join([str(seg) for seg in route.path])}')
        except Exception as ex:
            print(ex, file=sys.stderr)

        origin = dest = None

    return 0
Ejemplo n.º 13
0
    def decide_side_join(self, message):
        ln = self.__local_node
        nb = ln.neighbourhood
        lname = ln.name_id
        jname = message.joining_node.name_id
        side = Router.by_name_get_direction(lname, jname)
        nextn = nb.get_neighbour(side, 0, jname)
        othern = nb.get_neighbour(not side, 0, jname)
        wrapf = nb.can_wrap(side, jname)  # wrap forwards
        wrapb = nb.can_wrap(not side, jname)  # wrap backwards

        if (nextn.name_id == jname):
            hring = nb.get_ring(0).get_side(side)
            if hring.size < 2:
                return side, ln  # there isn't enough neighbours yet.
            nextn = hring.get_neighbours()[1]  # skip new-comer

        if (not NodeID.lies_between_direction(side, lname, jname,
                                              nextn.name_id, wrapf)):
            ln.sign("need to reverse side %s-%s-%s %s!" %
                    (lname, jname, nextn.name_id, repr(wrapf)))
            if (othern.name_id == jname):
                hring = nb.get_ring(0).get_side(not side)
                if hring.size < 2:
                    return not side, ln
                othern = hring.get_neighbours()[1]  #skip new-comer

            if (not NodeID.lies_between_direction(not side, lname, jname,
                                                  othern.name_id, wrapb)):
                LOGGER.debug(
                    "?_? node %s shouldn't have received %s (%s ; %s)?_?" %
                    (ln, message.trace, othern.pname, repr(wrapb)))
                print(">_< debugging")
                import pdb
                pdb.set_trace()
                print("<_> resuming")

            side = not side
            nextn = othern
        return side, nextn
Ejemplo n.º 14
0
def getRandomLocation():
    return {
        'lat': uniform(52.42252295423907, 54.00776876193478),
        'lng': uniform(-9.041748046875002, -6.470947265625)
    }


sumdecrease = 0
counter = 0
sumLength = 0
sumTime = 0

for index in range(50):
    location1 = getRandomLocation()
    location2 = getRandomLocation()
    router = Router(location1, location2)
    routes = []
    response = router.routeApi()
    locationObjects = response['response']['route'][0]['leg'][0]['maneuver']
    lengthFastest = response['response']['route'][0]['leg'][0]['length']
    travelTimeFastest = response['response']['route'][0]['leg'][0][
        'travelTime']

    router.names = getLocNames(locationObjects)
    locationJson = router.locationsToJsonRoute(locationObjects)

    routes.append(locationJson)
    average1 = router.getAverageCovid(locationObjects)
    bboxstr = router.getBboxString(locationObjects)
    response1 = router.routeApi(bboxstr=bboxstr)
    secondRoute = response1['response']['route'][0]['leg'][0]['maneuver']
 def setUp(self):
     self._sink = TestSink()
     self._router = Router(default_sink=self._sink)
     self._faucet = TestFaucet()
     self._router.add_faucet(self._faucet, name="test")
class RouterTest(unittest.TestCase):

    _router = None
    _sink = None
    _faucet = None

    def setUp(self):
        self._sink = TestSink()
        self._router = Router(default_sink=self._sink)
        self._faucet = TestFaucet()
        self._router.add_faucet(self._faucet, name="test")

    def test_tick(self):
        self._router.tick()

    def test_default_sink(self):
        message = {"from": {"media": "test"}, "message": "test"}

        self._faucet.create_message(message)

        self._router.tick()

        self.assertEquals(self._sink.messages, [message])

    def test_no_message(self):
        faucet = TestFaucet()

        self._router.add_faucet(faucet, name="empty")

        self._router.tick()
        # most important is that this doesn't raise any exceptions

        self.assertEquals(self._sink.messages, [])

    def test_add_sink(self):
        rule = Rule(target="sink", media="telegram", user="******")
        sink = TestSink()
        message1 = {"from": {"media": "test"}, "message": "test"}
        message2 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message3 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message4 = {"from": {"media": "test"}, "to": "sink", "message": "test"}

        self._router.add_sink(sink, name="sink")

        self._router.add_rule(rule, faucet_name="test")
        for message in (message1, message2, message3, message4):
            self._faucet.create_message(message)

        self._router.tick()

        self.assertEqual(self._sink.messages, [message1, message3])
        self.assertEqual(sink.messages, [message2, message4])

    def test_message_with_to_but_sink_not_present(self):
        message = {
            "from": {
                "media": "test"
            },
            "to": "inexistent",
            "message": "test"
        }

        self._faucet.create_message(message)
        self._router.tick()

        self.assertEqual(self._sink.messages, [message])

    def test_more_specific_rule_has_priority(self):
        rule1 = Rule(target="sink1", media="telegram", user="******")
        rule2 = Rule(target="sink2", media="telegram")
        rule3 = Rule(target="sink3", media="telegram", user="******")

        for rule in (rule1, rule2, rule3):
            self._router.add_rule(rule, faucet_name="test")

        sinks = []
        for name in ("sink1", "sink2", "sink3"):
            sinks.append(TestSink())
            self._router.add_sink(sinks[-1], name=name)

        message1 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message2 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message3 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }

        for message in (message1, message2, message3):
            self._faucet.create_message(message)

        self._router.tick()

        self.assertEqual(sinks[0].messages, [message1])
        self.assertEqual(sinks[1].messages, [message2])
        self.assertEqual(sinks[2].messages, [message3])

    def test_remove_faucet(self):
        self._router.remove_faucet("test")

        self._faucet.create_message({
            "from": {
                "media": "test"
            },
            "message": "test"
        })
        self._router.tick()

        self.assertEqual(self._sink.messages, [])

    def test_remove_faucet_object(self):
        self._router.remove_faucet(self._faucet)

        self._faucet.create_message({
            "from": {
                "media": "test"
            },
            "message": "test"
        })
        self._router.tick()

        self.assertEqual(self._sink.messages, [])

    def test_remove_sink(self):
        self._router.add_sink(TestSink(), "sink")
        self._router.add_rule(Rule(target="sink", media="test"),
                              faucet_name="test")

        self._router.remove_sink("sink")

        message = {"from": {"media": "test"}, "message": "test"}
        self._faucet.create_message(message)
        self._router.tick()

        self.assertEqual(self._sink.messages, [message])

    def test_remove_sink_object(self):
        sink = TestSink()
        self._router.add_sink(sink, "sink")
        self._router.add_rule(Rule(target="sink", media="test"),
                              faucet_name="test")

        self._router.remove_sink(sink)

        message = {"from": {"media": "test"}, "message": "test"}
        self._faucet.create_message(message)
        self._router.tick()

        self.assertEqual(self._sink.messages, [message])

    def test_choice_rule(self):
        sink1 = TestSink()
        sink2 = TestSink()

        self._router.add_sink(sink1, "sink1")
        self._router.add_sink(sink2, "sink2")

        self._router.add_rule(TestChoiceRule("sink"), faucet_name="test")

        message1 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message2 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }
        message3 = {
            "from": {
                "media": "telegram",
                "user": "******"
            },
            "message": "test"
        }

        for message in (message1, message2, message3):
            self._faucet.create_message(message)

        self._router.tick()

        self.assertEqual(sink1.messages, [message1])
        self.assertEqual(sink2.messages, [message2])
        self.assertEqual(self._sink.messages, [message3])

    def test_sink_factory(self):
        from unittest.mock import MagicMock
        self._router.add_rule(Rule(target="sink"), faucet_name="test")

        sink = TestSink()

        def callback(router, name):
            router.add_sink(sink, name)
            router.add_faucet(TestFaucet(), name)

        factory = MagicMock(side_effect=callback)

        self._router.add_sink_factory(factory)
        message = {"from": {"media": "test"}, "message": "test"}

        self._faucet.create_message(message)
        self._router.tick()

        self.assertEqual(self._sink.messages, [])
        self.assertEqual(sink.messages, [message])
        factory.assert_called_once_with(self._router, "sink")
Ejemplo n.º 17
0
 def __init__(self, request, client_address, server):
     self.router = Router()
     self.router.register_routes(routes)
     super().__init__(request, client_address, server)
Ejemplo n.º 18
0
class Handler(BaseHTTPRequestHandler):
    def __init__(self, request, client_address, server):
        self.router = Router()
        self.router.register_routes(routes)
        super().__init__(request, client_address, server)

    def do_GET(self):
        self.router.handle(request=self)
        return

    def do_POST(self):
        self.router.handle(request=self)
        return

    def do_PUT(self):
        self.router.handle(request=self)
        return

    def do_PATCH(self):
        self.router.handle(request=self)
        return

    def do_DELETE(self):
        self.router.handle(request=self)
        return

    def do_OPTIONS(self):
        self.router.handle(request=self)
        return

    def do_HEAD(self):
        self.router.handle(request=self)
        return
Ejemplo n.º 19
0
 def test_error_handling(self):
     router = Router('tests/data/test_case_1.csv')
     self.assertRaises(InvalidStationError,
                       lambda: router.find_route('A', 'Z'))
     self.assertRaises(InvalidStationError,
                       lambda: router.find_route(None, ''))
Ejemplo n.º 20
0
class Handler(BaseHTTPRequestHandler):

    def __init__(self, request, client_address, server):
        self.router = Router()
        self.router.register_routes(routes)
        super().__init__(request, client_address, server)

    def do_GET(self):
        self.router.handle(request=self)
        return

    def do_POST(self):
        self.router.handle(request=self)
        return

    def do_PUT(self):
        self.router.handle(request=self)
        return

    def do_PATCH(self):
        self.router.handle(request=self)
        return

    def do_DELETE(self):
        self.router.handle(request=self)
        return

    def do_OPTIONS(self):
        self.router.handle(request=self)
        return

    def do_HEAD(self):
        self.router.handle(request=self)
        return
Ejemplo n.º 21
0
 def test_initialization(self):
     self.assertRaises(FileNotFoundError,
                       lambda: Router('non_existent_file.csv'))
     self.assertRaises(IsADirectoryError, lambda: Router('tests/data'))
     self.assertRaises(InvalidRecordError,
                       lambda: Router('tests/data/invalid_file.csv'))
Ejemplo n.º 22
0
def geojson_test(begin='Cuatro Caminos', end='Juanacatlan'):
    network = load_network()
    router = Router(network)
    path = router.enroute(network.node(begin), network.node(end))
    print Path.as_geojson(path)
Ejemplo n.º 23
0
from routing import Router

router = Router()

router.fromPicture("./img4s.jpg")
router.build()
router.simulation()
Ejemplo n.º 24
0
class Bottle(object):
    """ Each Bottle object represents a single, distinct web application and
        consists of routes, callbacks, plugins, resources and configuration.
        Instances are callable WSGI applications.
        :param catchall: If true (default), handle all exceptions. Turn off to
                         let debugging middleware handle exceptions.
    """

    @lazy_attribute
    def _global_config(cls):
        cfg = ConfigDict()
        cfg.meta_set('catchall', 'validate', bool)
        return cfg

    def __init__(self, **kwargs):
        #: A :class:`ConfigDict` for app specific configuration.
        self.config = self._global_config._make_overlay()
        self.config._add_change_listener(
            functools.partial(self.trigger_hook, 'config'))

        self.config.update({
            "catchall": True
        })

        if kwargs.get('catchall') is False:
            depr(0, 13, "Bottle(catchall) keyword argument.",
                        "The 'catchall' setting is now part of the app "
                        "configuration. Fix: `app.config['catchall'] = False`")
            self.config['catchall'] = False
        if kwargs.get('autojson') is False:
            depr(0, 13, "Bottle(autojson) keyword argument.",
                 "The 'autojson' setting is now part of the app "
                 "configuration. Fix: `app.config['json.enable'] = False`")
            self.config['json.disable'] = True

        self._mounts = []

        #: A :class:`ResourceManager` for application files
        self.resources = ResourceManager()

        self.routes = []  # List of installed :class:`Route` instances.
        self.router = Router()  # Maps requests to :class:`Route` instances.
        self.error_handler = {}

        # Core plugins
        self.plugins = []  # List of installed plugins.
        self.install(JSONPlugin())
        self.install(TemplatePlugin())

    #: If true, most exceptions are caught and returned as :exc:`HTTPError`
    catchall = DictProperty('config', 'catchall')

    __hook_names = 'before_request', 'after_request', 'app_reset', 'config'
    __hook_reversed = {'after_request'}

    @cached_property
    def _hooks(self):
        return dict((name, []) for name in self.__hook_names)

    def add_hook(self, name, func):
        """ Attach a callback to a hook. Three hooks are currently implemented:
            before_request
                Executed once before each request. The request context is
                available, but no routing has happened yet.
            after_request
                Executed once after each request regardless of its outcome.
            app_reset
                Called whenever :meth:`Bottle.reset` is called.
        """
        if name in self.__hook_reversed:
            self._hooks[name].insert(0, func)
        else:
            self._hooks[name].append(func)

    def remove_hook(self, name, func):
        """ Remove a callback from a hook. """
        if name in self._hooks and func in self._hooks[name]:
            self._hooks[name].remove(func)
            return True

    def trigger_hook(self, __name, *args, **kwargs):
        """ Trigger a hook and return a list of results. """
        return [hook(*args, **kwargs) for hook in self._hooks[__name][:]]

    def hook(self, name):
        """ Return a decorator that attaches a callback to a hook. See
            :meth:`add_hook` for details."""

        def decorator(func):
            self.add_hook(name, func)
            return func

        return decorator

    def _mount_wsgi(self, prefix, app, **options):
        segments = [p for p in prefix.split('/') if p]
        if not segments:
            raise ValueError('WSGI applications cannot be mounted to "/".')
        path_depth = len(segments)

        def mountpoint_wrapper():
            try:
                request.path_shift(path_depth)
                rs = HTTPResponse([])

                def start_response(status, headerlist, exc_info=None):
                    if exc_info:
                        _raise(*exc_info)
                    rs.status = status
                    for name, value in headerlist:
                        rs.add_header(name, value)
                    return rs.body.append

                body = app(request.environ, start_response)
                rs.body = itertools.chain(rs.body, body) if rs.body else body
                return rs
            finally:
                request.path_shift(-path_depth)

        options.setdefault('skip', True)
        options.setdefault('method', 'PROXY')
        options.setdefault('mountpoint', {'prefix': prefix, 'target': app})
        options['callback'] = mountpoint_wrapper

        self.route('/%s/<:re:.*>' % '/'.join(segments), **options)
        if not prefix.endswith('/'):
            self.route('/' + '/'.join(segments), **options)

    def _mount_app(self, prefix, app, **options):
        if app in self._mounts or '_mount.app' in app.config:
            depr(0, 13, "Application mounted multiple times. Falling back to WSGI mount.",
                 "Clone application before mounting to a different location.")
            return self._mount_wsgi(prefix, app, **options)

        if options:
            depr(0, 13, "Unsupported mount options. Falling back to WSGI mount.",
                 "Do not specify any route options when mounting bottle application.")
            return self._mount_wsgi(prefix, app, **options)

        if not prefix.endswith("/"):
            depr(0, 13, "Prefix must end in '/'. Falling back to WSGI mount.",
                 "Consider adding an explicit redirect from '/prefix' to '/prefix/' in the parent application.")
            return self._mount_wsgi(prefix, app, **options)

        self._mounts.append(app)
        app.config['_mount.prefix'] = prefix
        app.config['_mount.app'] = self
        for route in app.routes:
            route.rule = prefix + route.rule.lstrip('/')
            self.add_route(route)

    def mount(self, prefix, app, **options):
        """ Mount an application (:class:`Bottle` or plain WSGI) to a specific
            URL prefix. Example::
                parent_app.mount('/prefix/', child_app)
            :param prefix: path prefix or `mount-point`.
            :param app: an instance of :class:`Bottle` or a WSGI application.
            Plugins from the parent application are not applied to the routes
            of the mounted child application. If you need plugins in the child
            application, install them separately.
            While it is possible to use path wildcards within the prefix path
            (:class:`Bottle` childs only), it is highly discouraged.
            The prefix path must end with a slash. If you want to access the
            root of the child application via `/prefix` in addition to
            `/prefix/`, consider adding a route with a 307 redirect to the
            parent application.
        """

        if not prefix.startswith('/'):
            raise ValueError("Prefix must start with '/'")

        if isinstance(app, Bottle):
            return self._mount_app(prefix, app, **options)
        else:
            return self._mount_wsgi(prefix, app, **options)

    def merge(self, routes):
        """ Merge the routes of another :class:`Bottle` application or a list of
            :class:`Route` objects into this application. The routes keep their
            'owner', meaning that the :data:`Route.app` attribute is not
            changed. """
        if isinstance(routes, Bottle):
            routes = routes.routes
        for route in routes:
            self.add_route(route)

    def install(self, plugin):
        """ Add a plugin to the list of plugins and prepare it for being
            applied to all routes of this application. A plugin may be a simple
            decorator or an object that implements the :class:`Plugin` API.
        """
        if hasattr(plugin, 'setup'): plugin.setup(self)
        if not callable(plugin) and not hasattr(plugin, 'apply'):
            raise TypeError("Plugins must be callable or implement .apply()")
        self.plugins.append(plugin)
        self.reset()
        return plugin

    def uninstall(self, plugin):
        """ Uninstall plugins. Pass an instance to remove a specific plugin, a type
            object to remove all plugins that match that type, a string to remove
            all plugins with a matching ``name`` attribute or ``True`` to remove all
            plugins. Return the list of removed plugins. """
        removed, remove = [], plugin
        for i, plugin in list(enumerate(self.plugins))[::-1]:
            if remove is True or remove is plugin or remove is type(plugin) \
            or getattr(plugin, 'name', True) == remove:
                removed.append(plugin)
                del self.plugins[i]
                if hasattr(plugin, 'close'): plugin.close()
        if removed: self.reset()
        return removed

    def reset(self, route=None):
        """ Reset all routes (force plugins to be re-applied) and clear all
            caches. If an ID or route object is given, only that specific route
            is affected. """
        if route is None: routes = self.routes
        elif isinstance(route, Route): routes = [route]
        else: routes = [self.routes[route]]
        for route in routes:
            route.reset()
        if DEBUG:
            for route in routes:
                route.prepare()
        self.trigger_hook('app_reset')

    def close(self):
        """ Close the application and all installed plugins. """
        for plugin in self.plugins:
            if hasattr(plugin, 'close'): plugin.close()

    def run(self, **kwargs):
        """ Calls :func:`run` with the same parameters. """
        run(self, **kwargs)

    def match(self, environ):
        """ Search for a matching route and return a (:class:`Route` , urlargs)
            tuple. The second value is a dictionary with parameters extracted
            from the URL. Raise :exc:`HTTPError` (404/405) on a non-match."""
        return self.router.match(environ)

    def get_url(self, routename, **kargs):
        """ Return a string that matches a named route """
        scriptname = request.environ.get('SCRIPT_NAME', '').strip('/') + '/'
        location = self.router.build(routename, **kargs).lstrip('/')
        return urljoin(urljoin('/', scriptname), location)

    def add_route(self, route):
        """ Add a route object, but do not change the :data:`Route.app`
            attribute."""
        self.routes.append(route)
        self.router.add(route.rule, route.method, route, name=route.name)
        if DEBUG: route.prepare()

    def route(self,
              path=None,
              method='GET',
              callback=None,
              name=None,
              apply=None,
              skip=None, **config):
        """ A decorator to bind a function to a request URL. Example::
                @app.route('/hello/<name>')
                def hello(name):
                    return 'Hello %s' % name
            The ``<name>`` part is a wildcard. See :class:`Router` for syntax
            details.
            :param path: Request path or a list of paths to listen to. If no
              path is specified, it is automatically generated from the
              signature of the function.
            :param method: HTTP method (`GET`, `POST`, `PUT`, ...) or a list of
              methods to listen to. (default: `GET`)
            :param callback: An optional shortcut to avoid the decorator
              syntax. ``route(..., callback=func)`` equals ``route(...)(func)``
            :param name: The name for this route. (default: None)
            :param apply: A decorator or plugin or a list of plugins. These are
              applied to the route callback in addition to installed plugins.
            :param skip: A list of plugins, plugin classes or names. Matching
              plugins are not installed to this route. ``True`` skips all.
            Any additional keyword arguments are stored as route-specific
            configuration and passed to plugins (see :meth:`Plugin.apply`).
        """
        if callable(path): path, callback = None, path
        plugins = makelist(apply)
        skiplist = makelist(skip)

        def decorator(callback):
            if isinstance(callback, str): callback = load(callback)
            for rule in makelist(path) or yieldroutes(callback):
                for verb in makelist(method):
                    verb = verb.upper()
                    route = Route(self, rule, verb, callback,
                                  name=name,
                                  plugins=plugins,
                                  skiplist=skiplist, **config)
                    self.add_route(route)
            return callback

        return decorator(callback) if callback else decorator

    def get(self, path=None, method='GET', **options):
        """ Equals :meth:`route`. """
        return self.route(path, method, **options)

    def post(self, path=None, method='POST', **options):
        """ Equals :meth:`route` with a ``POST`` method parameter. """
        return self.route(path, method, **options)

    def put(self, path=None, method='PUT', **options):
        """ Equals :meth:`route` with a ``PUT`` method parameter. """
        return self.route(path, method, **options)

    def delete(self, path=None, method='DELETE', **options):
        """ Equals :meth:`route` with a ``DELETE`` method parameter. """
        return self.route(path, method, **options)

    def patch(self, path=None, method='PATCH', **options):
        """ Equals :meth:`route` with a ``PATCH`` method parameter. """
        return self.route(path, method, **options)

    def error(self, code=500, callback=None):
        """ Register an output handler for a HTTP error code. Can
            be used as a decorator or called directly ::
                def error_handler_500(error):
                    return 'error_handler_500'
                app.error(code=500, callback=error_handler_500)
                @app.error(404)
                def error_handler_404(error):
                    return 'error_handler_404'
        """

        def decorator(callback):
            if isinstance(callback, str): callback = load(callback)
            self.error_handler[int(code)] = callback
            return callback

        return decorator(callback) if callback else decorator

    def default_error_handler(self, res):
        return bytes(template(ERROR_PAGE_TEMPLATE, e=res, template_settings=dict(name='__ERROR_PAGE_TEMPLATE')))

    def _handle(self, environ):
        path = environ['bottle.raw_path'] = environ['PATH_INFO']
        environ['PATH_INFO'] = path.encode('latin1').decode('utf8', 'ignore')

        environ['bottle.app'] = self
        request.bind(environ)
        response.bind()

        try:
            while True: # Remove in 0.14 together with RouteReset
                out = None
                try:
                    self.trigger_hook('before_request')
                    route, args = self.router.match(environ)
                    environ['route.handle'] = route
                    environ['bottle.route'] = route
                    environ['route.url_args'] = args
                    out = route.call(**args)
                    break
                except HTTPResponse as E:
                    out = E
                    break
                except RouteReset:
                    depr(0, 13, "RouteReset exception deprecated",
                                "Call route.call() after route.reset() and "
                                "return the result.")
                    route.reset()
                    continue
                finally:
                    if isinstance(out, HTTPResponse):
                        out.apply(response)
                    try:
                        self.trigger_hook('after_request')
                    except HTTPResponse as E:
                        out = E
                        out.apply(response)
        except (KeyboardInterrupt, SystemExit, MemoryError):
            raise
        except Exception as E:
            if not self.catchall: raise
            stacktrace = format_exc()
            environ['wsgi.errors'].write(stacktrace)
            environ['wsgi.errors'].flush()
            out = HTTPError(500, "Internal Server Error", E, stacktrace)
            out.apply(response)

        return out

    def _cast(self, out, peek=None):
        """ Try to convert the parameter into something WSGI compatible and set
        correct HTTP headers when possible.
        Support: False, str, unicode, dict, HTTPResponse, HTTPError, file-like,
        iterable of strings and iterable of unicodes
        """

        # Empty output is done here
        if not out:
            if 'Content-Length' not in response:
                response['Content-Length'] = 0
            return []
        # Join lists of byte or unicode strings. Mixed lists are NOT supported
        if isinstance(out, (tuple, list))\
        and isinstance(out[0], (bytes, str)):
            out = out[0][0:0].join(out)  # b'abc'[0:0] -> b''
        # Encode unicode strings
        if isinstance(out, str):
            out = out.encode(response.charset)
        # Byte Strings are just returned
        if isinstance(out, bytes):
            if 'Content-Length' not in response:
                response['Content-Length'] = len(out)
            return [out]
        # HTTPError or HTTPException (recursive, because they may wrap anything)
        # TODO: Handle these explicitly in handle() or make them iterable.
        if isinstance(out, HTTPError):
            out.apply(response)
            out = self.error_handler.get(out.status_code,
                                         self.default_error_handler)(out)
            return self._cast(out)
        if isinstance(out, HTTPResponse):
            out.apply(response)
            return self._cast(out.body)

        # File-like objects.
        if hasattr(out, 'read'):
            if 'wsgi.file_wrapper' in request.environ:
                return request.environ['wsgi.file_wrapper'](out)
            elif hasattr(out, 'close') or not hasattr(out, '__iter__'):
                return WSGIFileWrapper(out)

        # Handle Iterables. We peek into them to detect their inner type.
        try:
            iout = iter(out)
            first = next(iout)
            while not first:
                first = next(iout)
        except StopIteration:
            return self._cast('')
        except HTTPResponse as E:
            first = E
        except (KeyboardInterrupt, SystemExit, MemoryError):
            raise
        except Exception as error:
            if not self.catchall: raise
            first = HTTPError(500, 'Unhandled exception', error, format_exc())

        # These are the inner types allowed in iterator or generator objects.
        if isinstance(first, HTTPResponse):
            return self._cast(first)
        elif isinstance(first, bytes):
            new_iter = itertools.chain([first], iout)
        elif isinstance(first, str):
            encoder = lambda x: x.encode(response.charset)
            new_iter = map(encoder, itertools.chain([first], iout))
        else:
            msg = 'Unsupported response type: %s' % type(first)
            return self._cast(HTTPError(500, msg))
        if hasattr(out, 'close'):
            new_iter = _closeiter(new_iter, out.close)
        return new_iter

    def wsgi(self, environ, start_response):
        """ The bottle WSGI-interface. """
        try:
            out = self._cast(self._handle(environ))
            # rfc2616 section 4.3
            if response._status_code in (100, 101, 204, 304)\
            or environ['REQUEST_METHOD'] == 'HEAD':
                if hasattr(out, 'close'): out.close()
                out = []
            start_response(response._status_line, response.headerlist)
            return out
        except (KeyboardInterrupt, SystemExit, MemoryError):
            raise
        except Exception as E:
            if not self.catchall: raise
            err = '<h1>Critical error while processing request: %s</h1>' \
                  % html_escape(environ.get('PATH_INFO', '/'))
            if DEBUG:
                err += '<h2>Error:</h2>\n<pre>\n%s\n</pre>\n' \
                       '<h2>Traceback:</h2>\n<pre>\n%s\n</pre>\n' \
                       % (html_escape(repr(E)), html_escape(format_exc()))
            environ['wsgi.errors'].write(err)
            environ['wsgi.errors'].flush()
            headers = [('Content-Type', 'text/html; charset=UTF-8')]
            start_response('500 INTERNAL SERVER ERROR', headers, sys.exc_info())
            return [bytes(err)]

    def __call__(self, environ, start_response):
        """ Each instance of :class:'Bottle' is a WSGI application. """
        return self.wsgi(environ, start_response)

    def __enter__(self):
        """ Use this application as default for all module-level shortcuts. """
        default_app.push(self)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        default_app.pop()

    def __setattr__(self, name, value):
        if name in self.__dict__:
            raise AttributeError("Attribute %s already defined. Plugin conflict?" % name)
        self.__dict__[name] = value
Ejemplo n.º 25
0
import ujson
from state import State
import util
from routing import Router, Route
import network
import sensor

from state import State

router = Router()


@Route(endpoint='/setup', methods=['GET'])
def get_setup_page(request):
    response = open('static\\setup.html', 'r').read()
    return response


@Route(endpoint='/sensor', methods=['GET'])
def get_sensor_page(request):
    response = open('static\\sensor.html', 'r').read()
    return response


@Route(endpoint='/', methods=['GET'])
def get_index(request):
    response = open('static\\index.html', 'r').read()
    return response


@Route(endpoint='/api/accesspoints', methods=['GET'])
Ejemplo n.º 26
0
 def __init__(self, request, client_address, server):
     self.router = Router()
     self.router.register_routes(routes)
     super().__init__(request, client_address, server)
Ejemplo n.º 27
0
"""
Lambda example with external dependency
"""
import sys
sys.path.insert(0, "./lib")
import logging
from parsing import EventParser
from routing import Router

logger = logging.getLogger()
logger.setLevel(logging.INFO)

parser = EventParser()
router = Router()


def handle(event, context):
    file = parser.parse(event, 's3')
    logger.info(f'Routing {file.full_path}...')

    try:
        router.route(file)
    except Exception as e:
        return logger.error(f'Failed routing {file.full_path}. Exception: {e}')

    return logger.info(f'Successfully routed {file.full_path}')
Ejemplo n.º 28
0
from routing import Router

all_benchmarks = [
	'example', 
	'impossible', 
	'impossible2',
	'kuma', 
	'misty',
	'oswald',
	'rusty',
	'stanley',
	'stdcell',
	'sydney',
	'temp',
	'wavy'
]

if __name__ == '__main__':
	for benchmark in all_benchmarks:
		router = Router('benchmarks/'+benchmark+'.infile')
		router.routeAll()
		print('benchmark {}: {} / {} segments routed!'.format(benchmark, router.best_total_segments, router.total_possible_segments))