| 78 | |
| 79 | @classmethod |
| 80 | def from_uri(cls, uri: str, opts: Optional[dict] = None) -> ScanOutputBase: |
| 81 | if opts is None: |
| 82 | opts = {} |
| 83 | |
| 84 | parsed = parse.urlparse(uri) |
| 85 | parsed_qs = dict(parse.parse_qsl(parsed.query, keep_blank_values=True)) |
| 86 | |
| 87 | if set(opts.keys()) & set(parsed_qs.keys()): |
| 88 | raise exceptions.InvalidOutput("You can't specify the same options both via uri and command line options at the same time") |
| 89 | |
| 90 | fmt_class = cls.get_format(uri, parsed) |
| 91 | |
| 92 | # TODO: add support for tags from uri |
| 93 | |
| 94 | if parsed.netloc and parsed.path: |
| 95 | opts["output_location"] = os.path.join(parsed.netloc, parsed.path) |
| 96 | elif uri != fmt_class.protocol(): |
| 97 | opts["output_location"] = parsed.netloc or parsed.path |
| 98 | |
| 99 | tags = opts.pop("tags", []) |
| 100 | |
| 101 | for opt in (): # TODO |
| 102 | if opt in parsed_qs: |
| 103 | opts[opt] = qs_to_bool(parsed_qs[opt]) |
| 104 | |
| 105 | for opt in ("min_score", "verbosity"): |
| 106 | if opt in parsed_qs: |
| 107 | opts[opt] = int(parsed_qs[opt]) |
| 108 | |
| 109 | obj: ScanOutputBase = fmt_class(**opts) |
| 110 | obj.compile_filter_tags(tags) |
| 111 | return obj |
| 112 | |
| 113 | def compile_filter_tags(self, tags: Iterable[str]): |
| 114 | """ |