|
| 1 | +from parser_utils import make_soup |
| 2 | +from markdownify import markdownify as md |
| 3 | +from urllib.parse import urljoin |
| 4 | + |
| 5 | +## Language-specific resource name overrides: |
| 6 | +typescript_resource_overrides = { |
| 7 | + "generic_component": "GenericComponent", |
| 8 | + "generic_service": "GenericService", |
| 9 | + "movement_sensor": "MovementSensor", |
| 10 | + "power_sensor": "PowerSensor", |
| 11 | + "vision": "Vision", |
| 12 | + "robot": "Robot", |
| 13 | + "data": "Data", |
| 14 | + "dataset": "Data", |
| 15 | + "data_sync": "Data", |
| 16 | + "data_manager": "DataManager", |
| 17 | + "mltraining": "MlTraining" |
| 18 | +} |
| 19 | + |
| 20 | +## Ignore these specific APIs if they error, are deprecated, etc: |
| 21 | +typescript_ignore_apis = [ |
| 22 | + 'getRoverRentalRobots' # internal use |
| 23 | +] |
| 24 | + |
| 25 | +## Use these URLs for data types that are built-in to the language: |
| 26 | +typescript_datatype_links = {} |
| 27 | + |
| 28 | +class TypeScriptParser: |
| 29 | + def __init__(self, proto_map_file, typescript_staging_url = None): |
| 30 | + self.proto_map_file = proto_map_file |
| 31 | + self.sdk_url = "https://ts.viam.dev" |
| 32 | + |
| 33 | + if typescript_staging_url: |
| 34 | + self.scrape_url = typescript_staging_url |
| 35 | + self.staging = True |
| 36 | + else: |
| 37 | + self.scrape_url = "https://ts.viam.dev" |
| 38 | + self.staging = False |
| 39 | + self.typescript_methods = {} |
| 40 | + |
| 41 | + |
| 42 | + def parse(self, type, viam_resources, args): |
| 43 | + self.typescript_methods[type] = {} |
| 44 | + |
| 45 | + # Skip resources not supported in TypeScript |
| 46 | + unsupported_resources = [ |
| 47 | + "base_remote_control", "input_controller", "pose_tracker", |
| 48 | + "mlmodel" |
| 49 | + ] |
| 50 | + |
| 51 | + for resource in viam_resources: |
| 52 | + |
| 53 | + ## Determine URL form for TypeScript depending on type (like 'component'). |
| 54 | + ## TEMP: Manually exclude Base Remote Control Service (Go only): |
| 55 | + ## TODO: Handle resources with 0 implemented methods for this SDK better. |
| 56 | + |
| 57 | + # Initialize TypeScript methods dictionary if it doesn't exist |
| 58 | + self.typescript_methods[type][resource] = {} |
| 59 | + |
| 60 | + if resource in unsupported_resources: |
| 61 | + if args.verbose: |
| 62 | + print(f'DEBUG: Skipping unsupported TypeScript resource: {resource}') |
| 63 | + continue |
| 64 | + |
| 65 | + url = f"{self.scrape_url}/classes/{resource.capitalize()}Client.html" |
| 66 | + if resource in typescript_resource_overrides: |
| 67 | + url = f"{self.scrape_url}/classes/{typescript_resource_overrides[resource]}Client.html" |
| 68 | + |
| 69 | + if args.verbose: |
| 70 | + print(f'DEBUG: Parsing TypeScript URL: {url}') |
| 71 | + |
| 72 | + ## Scrape each parent method tag and all contained child tags for TypeScript by resource. |
| 73 | + ## TEMP: Manually exclude Base Remote Control Service (Go only). |
| 74 | + ## TODO: Handle resources with 0 implemented methods for this SDK better. |
| 75 | + soup = make_soup(url) |
| 76 | + for a in soup.find_all('a'): |
| 77 | + if a.get('href') and not a.get('href').startswith('http'): |
| 78 | + a['href'] = urljoin(url, a.get('href')) |
| 79 | + |
| 80 | + top_level_sections = soup.find_all('section', class_='tsd-panel-group tsd-member-group') |
| 81 | + methods = [] |
| 82 | + |
| 83 | + for section in top_level_sections: |
| 84 | + if section.find('h2').text == 'Methods': |
| 85 | + methods = section.find_all('section', class_='tsd-panel tsd-member') |
| 86 | + if resource == 'robot': |
| 87 | + if section.find('h2').text in ['App/Cloud', 'ComponentConfig', 'Discovery', "Frame System", "Operations", "Resources", "Sessions"]: |
| 88 | + methods.extend(section.find_all('section', class_='tsd-panel tsd-member')) |
| 89 | + |
| 90 | + |
| 91 | + for method in methods: |
| 92 | + # print(method) |
| 93 | + method_name = method.find('h3').text |
| 94 | + |
| 95 | + param_object = {} |
| 96 | + if method.find('div', class_="tsd-parameters"): |
| 97 | + parameters = method.find('div', class_="tsd-parameters").find_all('li') |
| 98 | + for param in parameters: |
| 99 | + param_name = param.find('span', class_="tsd-kind-parameter").text |
| 100 | + param_description = '' |
| 101 | + if param.find('div', class_="tsd-comment"): |
| 102 | + param_description = param.find('div', class_="tsd-comment").text |
| 103 | + signature = method.find(class_='tsd-signature').text |
| 104 | + param_type = md(str(param.find(class_="tsd-signature-type"))).strip() |
| 105 | + |
| 106 | + if param_description: |
| 107 | + param_usage = "%s (%s) - %s" % (param_name, param_type, param_description) |
| 108 | + else: |
| 109 | + param_usage = "%s (%s)" % (param_name, param_type) |
| 110 | + |
| 111 | + param_object[param_name] = { |
| 112 | + 'optional': param_name + '?' in signature, # todo |
| 113 | + 'param_description': param_description, |
| 114 | + 'param_type':param_type, |
| 115 | + 'param_usage': param_usage |
| 116 | + } |
| 117 | + |
| 118 | + returns = md(str(method.find('h4', class_="tsd-returns-title"))).replace("#### Returns ", "").strip().replace('\\', '') |
| 119 | + |
| 120 | + return_object = { |
| 121 | + 'return_description': '', |
| 122 | + 'return_type': returns, |
| 123 | + 'return_usage': returns |
| 124 | + } |
| 125 | + |
| 126 | + method_description = "" |
| 127 | + if method.find('li', class_="tsd-description").find('div', class_="tsd-comment"): |
| 128 | + method_description = method.find('li', class_="tsd-description").find('div', class_="tsd-comment").text.strip() |
| 129 | + |
| 130 | + self.typescript_methods[type][resource][method_name] = { |
| 131 | + 'method_description': method_description, |
| 132 | + 'method_link': method.find('a', class_='tsd-anchor-icon')["href"], |
| 133 | + 'parameters': param_object, |
| 134 | + 'proto': '', # method_name ? |
| 135 | + 'return': return_object |
| 136 | + } |
| 137 | + # 'code_sample': "", # No code samples yet method.find('pre').text |
| 138 | + # print(self.typescript_methods[type][resource][method_name]) |
| 139 | + # print() |
| 140 | + |
| 141 | + |
| 142 | + return self.typescript_methods |
0 commit comments