|
| 1 | +#!/usr/bin/env python |
| 2 | +"""Connect to an Odoo server, either from runbot.odoo.com or demo.odoo.com. |
| 3 | +
|
| 4 | +These are the supported environments: |
| 5 | + - 'demo' - Spawn a demo server on https:/demo.odoo.com |
| 6 | + (Last stable version, with Enterprise add-ons) |
| 7 | + - 'test'/'test+e' - Connect to a Nightly build server on Runbot |
| 8 | + - 'saas'/'saas+e' - Connect to a Saas server on Runbot |
| 9 | + - '19.0'/'19.0+e' - Connect to newest '19.0' server on Runbot |
| 10 | + - etc... |
| 11 | +
|
| 12 | +Suffix '+e' means Enterprise. Otherwise, it is Community edition. |
| 13 | +Each Runbot server proposes a database selector: with more or less modules installed |
| 14 | +
|
| 15 | +To connect to the same server in the browser, URL can be printed:: |
| 16 | +
|
| 17 | + >>> client |
| 18 | + <Client 'https://4567-saas-18-3.runbot109.odoo.com/web?db=4567-saas-18-3-base'> |
| 19 | + >>> client.server_version |
| 20 | + 'saas~18.3+e' |
| 21 | +
|
| 22 | +""" |
| 23 | +import collections |
| 24 | +import optparse |
| 25 | +import re |
| 26 | + |
| 27 | +import odooly |
| 28 | +import requests |
| 29 | + |
| 30 | +RUNBOT_HOST = "runbot.odoo.com" |
| 31 | +RUNBOT_URL = f"https://{RUNBOT_HOST}/runbot/submit?update_triggers=1&trigger_1=on&trigger_122=on" |
| 32 | +RUNBOT_REGEX = ( |
| 33 | + # (<Community or Enterprise>, <URL without http>, <build number>, <Odoo version>) |
| 34 | + r"<span>(\w+) Run</span>.*?" |
| 35 | + r"href=.https?:(//(\d+)-([^.]+).runbot\d+.odoo.com/web)/database/selector." |
| 36 | +) |
| 37 | +ODOO_SERVERS = {"demo": "https://demo.odoo.com/"} |
| 38 | +DEFAULT_USER = "demo" |
| 39 | + |
| 40 | + |
| 41 | +def _retrieve_servers(url=RUNBOT_URL, regex=RUNBOT_REGEX, user=DEFAULT_USER): |
| 42 | + test_servers = collections.defaultdict(set) |
| 43 | + overview = requests.get(url) |
| 44 | + builds = re.findall(regex, overview.text, re.DOTALL) |
| 45 | + for edition, odoo_url, build, ver in builds: |
| 46 | + suffix = "+e" if edition == "Enterprise" else "" |
| 47 | + if "saas" in ver: |
| 48 | + test_servers[f"saas{suffix}"].add((int(build), f"https:{odoo_url}")) |
| 49 | + elif "master" in ver: |
| 50 | + test_servers[f"test{suffix}"].add((int(build), f"https:{odoo_url}")) |
| 51 | + ver = ver.replace("saas-", "").replace("-", ".") + suffix |
| 52 | + # Get the newest for each Odoo version |
| 53 | + if ver not in ODOO_SERVERS: |
| 54 | + ODOO_SERVERS[ver] = f"https:{odoo_url}" |
| 55 | + # For test servers, get the oldest |
| 56 | + for ver in test_servers: |
| 57 | + ODOO_SERVERS[ver] = min(test_servers[ver])[1] |
| 58 | + # Inject into Odooly known configs |
| 59 | + odooly.Client._saved_config.update( |
| 60 | + {name: (server, None, user, user, None) |
| 61 | + for name, server in ODOO_SERVERS.items()} |
| 62 | + ) |
| 63 | + print(f"Found {len(set(builds))} builds on {RUNBOT_HOST}") |
| 64 | + |
| 65 | + |
| 66 | +def main(): |
| 67 | + description = "Connect to runbot.odoo.com or demo.odoo.com." |
| 68 | + parser = optparse.OptionParser(usage='%prog [options] ENV', description=description) |
| 69 | + parser.add_option('-u', '--user', default=DEFAULT_USER, help='\'demo\' or \'admin\'') |
| 70 | + parser.add_option('-v', '--verbose', default=0, action='count', help='verbose') |
| 71 | + |
| 72 | + [opts, args] = parser.parse_args() |
| 73 | + [version] = args or ['demo'] |
| 74 | + |
| 75 | + _retrieve_servers(user=opts.user) |
| 76 | + |
| 77 | + print("Available Odoo builds: " + ", ".join(ODOO_SERVERS)) |
| 78 | + try: |
| 79 | + while version not in ODOO_SERVERS: |
| 80 | + version = input("Choose one: ") |
| 81 | + except KeyboardInterrupt: |
| 82 | + raise SystemExit("") |
| 83 | + |
| 84 | + print(f"Connect to Odoo {version} ...") |
| 85 | + global_vars = odooly.Client._set_interactive({'__doc__': __doc__}) |
| 86 | + odooly.Client.from_config(version, user=opts.user, verbose=opts.verbose) |
| 87 | + odooly._interact(global_vars) |
| 88 | + |
| 89 | + |
| 90 | +if __name__ == "__main__": |
| 91 | + main() |
0 commit comments