|
37 | 37 | 'robot.Logger' # robot method
|
38 | 38 | ]
|
39 | 39 |
|
| 40 | +go_ignore_app_apis = [ |
| 41 | + 'GetBillingServiceConfig', |
| 42 | + 'EnableBillingService', |
| 43 | + 'DisableBillingService', |
| 44 | + 'UpdateBillingService', |
| 45 | + 'OrganizationGetLogo', |
| 46 | + 'OrganizationSetLogo', |
| 47 | + 'OrganizationGetSupportEmail', |
| 48 | + 'OrganizationSetSupportEmail', |
| 49 | + 'RenameKey', |
| 50 | + 'TransferRegistryItem', |
| 51 | + 'ListOAuthApps', |
| 52 | + 'NextPage', |
| 53 | + 'Next', |
| 54 | + 'AppClient', |
| 55 | + 'BillingClient', |
| 56 | + 'DataClient', |
| 57 | + 'MLTrainingClient', |
| 58 | + 'ProvisioningClient', |
| 59 | + 'CreateKeyFromExistingKeyAuthorizations', |
| 60 | + 'GetOrganizationsWithAccessToLocation', |
| 61 | + 'GetRoverRentalRobots', |
| 62 | + 'SendPaymentRequiredEmail', |
| 63 | + 'DisableDataPipeline', |
| 64 | + 'EnableDataPipeline', |
| 65 | + 'FileUploadFromBytes', |
| 66 | + 'UpdateBoundingBox', |
| 67 | + 'GetTrainingJobLogs', |
| 68 | + 'GetNetworkList', |
| 69 | + 'GetSmartMachineStatus', |
| 70 | + 'SetNetworkCredentials', |
| 71 | + 'SetSmartMachineCredentials' |
| 72 | +] |
| 73 | + |
| 74 | + |
| 75 | + |
40 | 76 | ## Use these URLs for data types (for params, returns, and errors raised) that are
|
41 | 77 | ## built-in to the language or provided by a non-Viam third-party package:
|
42 | 78 | ## TODO: Not currently using these in parse(), but could do a simple replace()
|
@@ -85,16 +121,17 @@ def parse(self, type, viam_resources):
|
85 | 121 | elif type == "robot":
|
86 | 122 | url = f"{self.scrape_url}/go.viam.com/rdk/{type}"
|
87 | 123 | elif type == "app":
|
88 |
| - continue |
89 |
| - |
90 |
| - self.go_methods[type][resource] = {} |
| 124 | + url = f"{self.scrape_url}/go.viam.com/rdk/{type}" |
91 | 125 |
|
| 126 | + # Only initialize if it doesn't exist |
| 127 | + if resource not in self.go_methods[type]: |
| 128 | + self.go_methods[type][resource] = {} |
92 | 129 |
|
93 | 130 | ## Scrape each parent method tag and all contained child tags for Go by resource:
|
94 | 131 | ## Skip Go: App (Go has no App client) and the generic component and service, which
|
95 | 132 | ## require explicit in-script workaround (DoCommand neither inherited (from resource.Resource)
|
96 | 133 | ## nor explicitly defined in-interface (not in Go docs, only in un-doc'd code):
|
97 |
| - if resource != "generic_component" and resource != "generic_service": |
| 134 | + if resource != "generic_component" and resource != "generic_service" and resource != "app": |
98 | 135 |
|
99 | 136 | soup = make_soup(url)
|
100 | 137 |
|
@@ -201,6 +238,7 @@ def parse(self, type, viam_resources):
|
201 | 238 | ## We have finished collecting all data for this method. Write the this_method_dict dictionary
|
202 | 239 | ## in its entirety to the go_methods dictionary by type (like 'component'), by resource (like 'arm'),
|
203 | 240 | ## using the method_name as key:
|
| 241 | + |
204 | 242 | self.go_methods[type][resource][method_name] = this_method_dict
|
205 | 243 |
|
206 | 244 | ## If this Go interface inherits from another interface, also fetch data for those inherited methods:
|
@@ -347,9 +385,87 @@ def parse(self, type, viam_resources):
|
347 | 385 | if resource == "generic_service":
|
348 | 386 | self.go_methods[type][resource]['DoCommand']['code_sample'] = 'myGenericService, err := generic.FromRobot(machine, "my_generic_service")\n\ncommand := map[string]interface{}{"cmd": "test", "data1": 500}\nresult, err := myGenericService.DoCommand(context.Background(), command)\n'
|
349 | 387 |
|
350 |
| - # elif type == "app": |
351 |
| - # ##Go SDK has no APP API! |
352 |
| - # pass |
| 388 | + elif type == "app": |
| 389 | + soup = make_soup(url) |
| 390 | + |
| 391 | + ## Get a raw dump of all go app methods: |
| 392 | + go_methods_raw = soup.find_all( |
| 393 | + lambda tag: tag.name == 'div' |
| 394 | + and tag.get('class') == ['Documentation-typeMethod'] |
| 395 | + and tag.pre.text.startswith('func (')) |
| 396 | + |
| 397 | + for method in go_methods_raw: |
| 398 | + this_method_dict = {} |
| 399 | + method_name = method.find('a', class_='Documentation-source').text |
| 400 | + method_id = method.find('a', class_='Documentation-idLink')['href'] |
| 401 | + method_link = "https://pkg.go.dev/go.viam.com/rdk/app" + method_id |
| 402 | + |
| 403 | + # Get all text after the Documentation-declaration div |
| 404 | + declaration_div = method.find('div', class_='Documentation-declaration') |
| 405 | + if declaration_div: |
| 406 | + # Find all p elements that come after the declaration div |
| 407 | + description_elements = declaration_div.find_next_siblings('p') |
| 408 | + method_description = " ".join([elem.get_text().strip() for elem in description_elements]) |
| 409 | + |
| 410 | + # Extract the method usage/signature from the pre tag |
| 411 | + pre_tag = declaration_div.find('pre') |
| 412 | + if pre_tag: |
| 413 | + # Convert the pre tag to string to preserve HTML links |
| 414 | + usage_html = str(pre_tag) |
| 415 | + # Remove the <pre> and </pre> tags |
| 416 | + usage_html = usage_html.replace('<pre>', '').replace('</pre>', '') |
| 417 | + # Remove "func " prefix if it exists |
| 418 | + if usage_html.startswith('func '): |
| 419 | + usage_html = usage_html[5:] # Remove "func " (5 characters) |
| 420 | + |
| 421 | + # Remove the receiver part (everything between first ( and first )) |
| 422 | + if usage_html.startswith('('): |
| 423 | + # Find the closing parenthesis of the receiver |
| 424 | + paren_count = 0 |
| 425 | + end_pos = 0 |
| 426 | + for i, char in enumerate(usage_html): |
| 427 | + if char == '(': |
| 428 | + paren_count += 1 |
| 429 | + elif char == ')': |
| 430 | + paren_count -= 1 |
| 431 | + if paren_count == 0: |
| 432 | + end_pos = i |
| 433 | + break |
| 434 | + |
| 435 | + if end_pos > 0: |
| 436 | + # Remove the receiver and any leading whitespace |
| 437 | + usage_html = usage_html[end_pos + 1:].lstrip() |
| 438 | + |
| 439 | + method_usage = usage_html |
| 440 | + else: |
| 441 | + method_usage = "" |
| 442 | + else: |
| 443 | + method_description = "" |
| 444 | + method_usage = "" |
| 445 | + |
| 446 | + resource_override = resource |
| 447 | + |
| 448 | + ## Look up method_name in proto_map file, and return matching resource: |
| 449 | + with open(self.proto_map_file, 'r') as f: |
| 450 | + for row in f: |
| 451 | + if not row.startswith('#') and not row == "\n": |
| 452 | + row_items = row.split(',') |
| 453 | + if row_items[1] == method_name: |
| 454 | + resource_override = row_items[0] |
| 455 | + |
| 456 | + this_method_dict = { |
| 457 | + "proto": method_name, |
| 458 | + "usage": method_usage, |
| 459 | + # "code_sample": code_sample, |
| 460 | + "description": method_description, |
| 461 | + "method_link": method_link, |
| 462 | + # "usage": "" |
| 463 | + } |
| 464 | + if resource_override not in self.go_methods[type]: |
| 465 | + self.go_methods[type][resource_override] = {} |
| 466 | + if method_name in go_ignore_app_apis: |
| 467 | + continue |
| 468 | + self.go_methods[type][resource_override][method_name] = this_method_dict |
353 | 469 |
|
354 | 470 | return self.go_methods
|
355 | 471 |
|
0 commit comments