Skip to content
Snippets Groups Projects
main.py 4.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jarrod Pas's avatar
    Jarrod Pas committed
    from argparse import ArgumentParser
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    from datetime import datetime
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    import random
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    import sys
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
    import simpy
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    import yaml
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    from pydtn import Network, NodeFactory
    from pydtn.traces import types as traces
    from pydtn.routers import types as routers
    from pydtn.communities import types as communities
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
    def parse_args(args):
        parser = ArgumentParser()
    
        parser.add_argument('--seed', '-s', metavar='seed', type=int,
                            default=42)
    
        parser.add_argument('--trace', '-t', metavar='type', default='random',
                            choices=[t for t in traces])
        parser.add_argument('--trace-args', '-ta', metavar='arg', nargs='+')
    
        parser.add_argument('--router', '-r', metavar='type', default='direct',
                            choices=[t for t in routers])
        parser.add_argument('--router-args', '-ra', metavar='arg', nargs='+')
    
        parser.add_argument('--community', '-c', metavar='type', default='none',
                            choices=[t for t in communities])
        parser.add_argument('--community-args', '-ca', metavar='arg', nargs='+')
    
        parser.add_argument('--node-args', '-na', metavar='arg', nargs='+')
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
        parser.add_argument('--packet-args', '-pa', metavar='arg', nargs='+')
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
        def list_to_args(args):
            if args is None:
                return {}
            else:
                args = '\n'.join(args).replace('=',': ')
                return yaml.safe_load(args)
    
        args = parser.parse_args(args)
    
        args.trace_args = list_to_args(args.trace_args)
        args.router_args = list_to_args(args.router_args)
        args.community_args = list_to_args(args.community_args)
        args.node_args = list_to_args(args.node_args)
    
    Jarrod Pas's avatar
    Jarrod Pas committed
        args.packet_args = list_to_args(args.packet_args)
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
        return args
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    class Progress:
        def __init__(self, length, ticks, alpha):
            self.length = length
            self.alpha = alpha
    
            self.tick = 0
            self.ticks = ticks
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
            self.average = 0
    
    Jarrod Pas's avatar
    Jarrod Pas committed
            self.__start = None
    
            self.__last_print_len = 0
    
        @property
        def bar(self):
            progress = round(self.tick / self.ticks * self.length)
            return '[' + '='*progress + ' '*(self.length - progress) + ']'
    
        @property
        def time(self):
    
    Jarrod Pas's avatar
    Jarrod Pas committed
            remains = (self.ticks - self.tick) * self.average
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
            ranges = [
                ('day', 24*60*60),
                ('hour', 60*60),
                ('minute', 60),
                ('second', 1),
            ]
    
            for unit, weight in ranges:
                if remains >= weight:
                    remains = round(remains / weight)
                    plural = 's' if remains != 1 else ''
                    return f'{remains} {unit}{plural}'
    
            return '0 seconds'
    
        def __next__(self):
            now = datetime.now().timestamp()
            if self.__start is not None:
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                dt = now - self.__start
                self.average = self.average + self.alpha * (dt - self.average)
    
    Jarrod Pas's avatar
    Jarrod Pas committed
            self.__start = now
    
            self.tick += 1
            if self.tick > self.ticks:
                raise StopIteration
    
    
            print('\r' + ' '*self.__last_print_len, end='\r')
            line = f'{self.bar} {self.time} to go...'
            print(line, end=' ', flush=True)
            self.__last_print_len = len(line)
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
            return self.tick
    
        def __iter__(self):
            return self
    
    Jarrod Pas's avatar
    Jarrod Pas committed
    
    def main(args):
        args = parse_args(args)
        print(args)
    
        random.seed(args.seed)
        env = simpy.Environment()
    
        trace = traces[args.trace](**args.trace_args)
        router = routers[args.router]
        community = communities[args.community](**args.community_args)
    
        node_factory = NodeFactory(router, **args.node_args)
    
        network = Network(env,
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                          packets=args.packet_args,
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                          node_factory=node_factory,
                          community=community,
                          trace=trace)
    
    
    Jarrod Pas's avatar
    Jarrod Pas committed
        progress = Progress(50, 500, 0.75)
    
    Jarrod Pas's avatar
    Jarrod Pas committed
        while True:
            try:
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                for tick in progress:
                    until = tick / progress.ticks * trace.duration
                    env.run(until=until)
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                print(' Done!')
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                print(str(network.packets))
    
    Jarrod Pas's avatar
    Jarrod Pas committed
                return 0
            except KeyboardInterrupt:
                print('\nBye!')
                return 0
    
    if __name__ == '__main__':
        exit(main(sys.argv[1:]))