Ejemplo n.º 1
0
 def handle_args(self, args):
     MessageDefManager.muted = True  # no messages to stderr
     parser = FileDialplanParser()
     parser.include(args.dialplan)
     dialplan = next(iter(parser))
     print(dialplan.format_as_dialplan_show(
         reverse=args.reverse))
Ejemplo n.º 2
0
    def handle_args(self, args):
        # No messages to stderr, but do collect the E_APP_MISSING and
        # E_FUNC_MISSING errors.
        aggregator = Aggregator()
        MessageDefManager.muted = True

        # Load func_odbc functions if requested.
        load_func_odbc_functions(args.func_odbc, args.dialplan)

        parser = FileDialplanParser()
        parser.include(args.dialplan)
        dialplan = next(iter(parser))
        del dialplan

        apploader = AppLoader()
        funcloader = FuncLoader()

        self.print_modules_used(apploader, funcloader)
        self.print_load_statements(
            set(apploader.used_modules) |
            set(funcloader.used_modules))
        self.print_unknowns(aggregator)

        return int(
            bool(aggregator.unknown_apps) or
            bool(aggregator.unknown_funcs))
Ejemplo n.º 3
0
    def on_post(self, req, resp):
        # Reading POSTed FILEs: https://github.com/falconry/falcon/issues/825
        filename = 'extensions.conf'

        # {"files": {"FILENAME": "FILEDATA"}}
        doc = req.context['doc']
        filedata = doc['files'][filename].encode('utf-8')
        opener = UploadedFileOpener(filename, filedata)

        parser = FileDialplanParser(opener=opener)
        parser.include(filename)
        dialplan = next(iter(parser))
        dialplan.walk_jump_destinations()
        del dialplan

        issues = {filename: []}
        msgs = collect_messages()
        for msg in msgs:
            formatted = msg.message.format(**msg.fmtkwargs)
            issues[msg.where.filename].append({
                'line': msg.where.lineno,
                'class': msg.__class__.__name__,
                'desc': formatted,
            })

        req.context['result'] = {
            'results': issues,
            'asterisklint': {
                'version': version_str
            },
        }
Ejemplo n.º 4
0
    def create_parser(self, filename, data):
        def opener(fn):
            assert fn == filename, (fn, filename)
            return NamedBytesIO(filename, data)

        parser = FileDialplanParser(opener=opener)
        parser.include(filename)
        return parser
Ejemplo n.º 5
0
    def handle_args(self, args):
        # Load func_odbc functions if requested.
        load_func_odbc_functions(args.func_odbc, args.dialplan)

        parser = FileDialplanParser()
        parser.include(args.dialplan)
        dialplan = next(iter(parser))
        dialplan.walk_jump_destinations()
        del dialplan

        # MessageDefManager.raised is a dict of messages ordered by message
        # type. All message types share the same muted flag, so we need only
        # examine the first.
        if any(not i[0].muted for i in MessageDefManager.raised.values()):
            return 1
Ejemplo n.º 6
0
    def handle_args(self, args):
        MessageDefManager.muted = True

        loader = VarLoader()
        parser = FileDialplanParser()
        parser.include(args.dialplan)
        dialplan = next(iter(parser))

        contexts_by_name = list(sorted(
            (context.name for context in dialplan.contexts),
            key=(lambda x: x.lower())))
        # TODO: dialplan.all_labels is not a public interface..
        labels_by_name = list(sorted(
            dialplan.all_labels, key=(lambda x: x.lower())))
        # TODO: loader._variables is *not* a public interface..
        varlist_by_name = list(sorted(
            loader._variables.items(), key=(lambda x: x[0].lower())))

        if args.verbose:
            self.print_contexts(contexts_by_name)
            self.print_labels(labels_by_name)
            self.print_variables(varlist_by_name)

        # Calculate Levenshtein distance if available. Complain if
        # module wasn't loaded and the user did not ask for verbose
        # printing either.
        if editdistance:
            identifiers = (
                set(contexts_by_name) |
                set(labels_by_name) |
                set([i[0] for i in varlist_by_name]))
            ret = self.print_distance(identifiers)
        elif args.verbose:
            ret = 0
        else:
            raise ImportError(
                'Loading editdistance failed. Using this command without '
                'the editdistance and without verbose mode is a no-op.')

        return ret
Ejemplo n.º 7
0
    def on_post(self, req, resp):
        # Reading POSTed FILEs:
        #   https://falcon.readthedocs.io/en/stable/user/faq.html
        #     #how-can-i-access-posted-files
        # Reading JSON:
        #   https://falcon.readthedocs.io/en/stable/api/api.html
        #     #falcon.RequestOptions
        # > A dict-like object that allows you to configure the
        # > media-types that you would like to handle. By default, a
        # > handler is provided for the application/json media type.
        filename = 'extensions.conf'

        # {"files": {"FILENAME": "FILEDATA"}}
        filedata = req.media['files'][filename].encode('utf-8')
        opener = UploadedFileOpener(filename, filedata)

        parser = FileDialplanParser(opener=opener)
        parser.include(filename)
        dialplan = next(iter(parser))
        dialplan.walk_jump_destinations()
        del dialplan

        issues = {filename: []}
        msgs = collect_messages()
        for msg in msgs:
            formatted = msg.message.format(**msg.fmtkwargs)
            issues[msg.where.filename].append({
                'line': msg.where.lineno,
                'class': msg.__class__.__name__,
                'desc': formatted,
            })

        resp.media = {
            'results': issues,
            'asterisklint': {'version': version_str},
        }
Ejemplo n.º 8
0
class MakePatternsCanonicalMutator(FileMutatorBase):
    def process_issue(self, issue, inline, outfile):
        # Split between "exten =>" and the rest.
        linehead, linetail = inline.split(b'=', 1)
        if linetail[0] == b'>':
            linehead += b'>'
            linetail = linetail[1:]

        # We can safely use replace-1 here. If we were able
        # to parse your config, we should not be looking
        # directly at a pattern first.
        linetail = linetail.replace(issue.needle, issue.replacement, 1)
        outline = linehead + b'=' + linetail

        # Write new line.
        outfile.write(outline)


MessageDefManager.muted = True  # no messages to stderr
aggregator = Aggregator()
parser = FileDialplanParser()
parser.include(sys.argv[1])

print('Making dialplan patterns into canonical form.')
print('Parsing current config...')
dialplan = next(iter(parser))
print()

mutator = MakePatternsCanonicalMutator(aggregator.issues_per_file)
mutator.request_permission_and_process()