mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Generated by com2ann (slightly patched to avoid also converting assignment type annotations, which require Python 3.6), followed by some manual whitespace adjustment, and six fixes for runtime issues: - def __init__(self, token: Token, parent: Optional[Node]) -> None: + def __init__(self, token: Token, parent: "Optional[Node]") -> None: -def main(options: argparse.Namespace) -> NoReturn: +def main(options: argparse.Namespace) -> "NoReturn": -def fetch_request(url: str, callback: Any, **kwargs: Any) -> Generator[Callable[..., Any], Any, None]: +def fetch_request(url: str, callback: Any, **kwargs: Any) -> "Generator[Callable[..., Any], Any, None]": -def assert_server_running(server: subprocess.Popen[bytes], log_file: Optional[str]) -> None: +def assert_server_running(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> None: -def server_is_up(server: subprocess.Popen[bytes], log_file: Optional[str]) -> bool: +def server_is_up(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> bool: - method_kwarg_pairs: List[FuncKwargPair], + method_kwarg_pairs: "List[FuncKwargPair]", Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
		
			
				
	
	
		
			150 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
# check for the venv
 | 
						|
from lib import sanity_check
 | 
						|
sanity_check.check_venv(__file__)
 | 
						|
 | 
						|
from collections import defaultdict
 | 
						|
from typing import Any, Dict, List, Set
 | 
						|
 | 
						|
import html
 | 
						|
import os
 | 
						|
import pprint
 | 
						|
import ujson
 | 
						|
 | 
						|
Call = Dict[str, Any]
 | 
						|
 | 
						|
def clean_up_pattern(s: str) -> str:
 | 
						|
    paren_level = 0
 | 
						|
    in_braces = False
 | 
						|
    result = ''
 | 
						|
    prior_char = None
 | 
						|
    for c in s:
 | 
						|
        if c == '(':
 | 
						|
            paren_level += 1
 | 
						|
        if c == '<' and prior_char == 'P':
 | 
						|
            in_braces = True
 | 
						|
        if in_braces or (paren_level == 0):
 | 
						|
            if c != '?':
 | 
						|
                result += c
 | 
						|
        if c == ')':
 | 
						|
            paren_level -= 1
 | 
						|
        if c == '>':
 | 
						|
            in_braces = False
 | 
						|
        prior_char = c
 | 
						|
    return result
 | 
						|
 | 
						|
def encode_info(info: Any) -> str:
 | 
						|
    try:
 | 
						|
        result = ''
 | 
						|
        try:
 | 
						|
            info = ujson.loads(info)
 | 
						|
            result = '(stringified)\n'
 | 
						|
        except Exception:
 | 
						|
            pass
 | 
						|
        result += html.escape(pprint.pformat(info, indent=4))
 | 
						|
        return '<pre>' + result + '</pre>'
 | 
						|
    except Exception:
 | 
						|
        pass
 | 
						|
    try:
 | 
						|
        return html.escape(str(info))
 | 
						|
    except Exception:
 | 
						|
        pass
 | 
						|
    return 'NOT ENCODABLE'
 | 
						|
 | 
						|
def fix_test_name(s: str) -> str:
 | 
						|
    return s.replace('zerver.tests.', '')
 | 
						|
 | 
						|
def create_single_page(pattern: str, out_dir: str, href: str, calls: List[Call]) -> None:
 | 
						|
    fn = out_dir + '/' + href
 | 
						|
    with open(fn, 'w') as f:
 | 
						|
        f.write('''
 | 
						|
            <style>
 | 
						|
            .test {
 | 
						|
                margin: 20px;
 | 
						|
            }
 | 
						|
            </style>
 | 
						|
            ''')
 | 
						|
        f.write('<h3>%s</h3>\n' % (html.escape(pattern),))
 | 
						|
        calls.sort(key=lambda call: call['status_code'])
 | 
						|
        for call in calls:
 | 
						|
            f.write('<hr>')
 | 
						|
            f.write('\n%s' % (fix_test_name(call['test_name']),))
 | 
						|
            f.write('<div class="test">')
 | 
						|
            try:
 | 
						|
                f.write(call['url'])
 | 
						|
            except Exception:
 | 
						|
                f.write(call['url'].encode('utf8'))
 | 
						|
            f.write('<br>\n')
 | 
						|
            f.write(call['method'] + '<br>\n')
 | 
						|
            f.write('status code: %s<br>\n' % (call['status_code'],))
 | 
						|
            f.write('<br>')
 | 
						|
            f.write('</div>')
 | 
						|
 | 
						|
def create_user_docs() -> None:
 | 
						|
    fn = 'var/url_coverage.txt'  # TODO: make path more robust, maybe use json suffix
 | 
						|
 | 
						|
    out_dir = 'var/api_docs'
 | 
						|
    try:
 | 
						|
        os.mkdir(out_dir)
 | 
						|
    except OSError:
 | 
						|
        pass
 | 
						|
 | 
						|
    main_page = out_dir + '/index.html'
 | 
						|
 | 
						|
    with open(main_page, 'w') as f:
 | 
						|
        f.write('''
 | 
						|
            <style>
 | 
						|
            li {
 | 
						|
                list-style-type: none;
 | 
						|
            }
 | 
						|
 | 
						|
            a {
 | 
						|
                text-decoration: none;
 | 
						|
            }
 | 
						|
            </style>
 | 
						|
            ''')
 | 
						|
 | 
						|
        calls = []
 | 
						|
        for line in open(fn):
 | 
						|
            calls.append(ujson.loads(line))
 | 
						|
 | 
						|
        pattern_dict = defaultdict(list)  # type: Dict[str, List[Call]]
 | 
						|
        for call in calls:
 | 
						|
            if 'pattern' in call:
 | 
						|
                pattern = clean_up_pattern(call['pattern'])
 | 
						|
                if pattern:
 | 
						|
                    pattern_dict[pattern].append(call)
 | 
						|
 | 
						|
        patterns = set(pattern_dict.keys())
 | 
						|
 | 
						|
        tups = [
 | 
						|
            ('api/v1/external', 'webhooks'),
 | 
						|
            ('api/v1', 'api'),
 | 
						|
            ('json', 'legacy'),
 | 
						|
        ]
 | 
						|
 | 
						|
        groups = dict()  # type: Dict[str, Set[str]]
 | 
						|
        for prefix, name in tups:
 | 
						|
            groups[name] = {p for p in patterns if p.startswith(prefix)}
 | 
						|
            patterns -= groups[name]
 | 
						|
 | 
						|
        groups['other'] = patterns
 | 
						|
 | 
						|
        for name in ['api', 'legacy', 'webhooks', 'other']:
 | 
						|
            f.write(name + ' endpoints:\n\n')
 | 
						|
            f.write('<ul>\n')
 | 
						|
            for pattern in sorted(groups[name]):
 | 
						|
                href = pattern.replace('/', '-') + '.html'
 | 
						|
                link = '<a href="%s">%s</a>' % (href, html.escape(pattern))
 | 
						|
                f.write('<li>' + link + '</li>\n')
 | 
						|
                create_single_page(pattern, out_dir, href, pattern_dict[pattern])
 | 
						|
            f.write('</ul>')
 | 
						|
            f.write('\n')
 | 
						|
 | 
						|
    print('open %s' % (main_page,))
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    create_user_docs()
 |