def import_pio(project_dir): if not project_dir or not is_platformio_project(project_dir): raise jsonrpc.exceptions.JSONRPCDispatchException( code=4001, message="Not an PlatformIO project: %s" % project_dir) new_project_dir = join( AppRPC.load_state()['storage']['projectsDir'], time.strftime("%y%m%d-%H%M%S-") + basename(project_dir)) shutil.copytree(project_dir, new_project_dir) state = AppRPC.load_state() args = ["init"] if (state['storage']['coreCaller'] and state['storage']['coreCaller'] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state['storage']['coreCaller']]) d = PIOCoreRPC.call(args, options={"cwd": new_project_dir}) d.addCallback(lambda _: new_project_dir) return d
async def import_pio(project_dir): if not project_dir or not is_platformio_project(project_dir): raise JSONRPC20DispatchException( code=4001, message="Not an PlatformIO project: %s" % project_dir) new_project_dir = os.path.join( AppRPC.load_state()["storage"]["projectsDir"], time.strftime("%y%m%d-%H%M%S-") + os.path.basename(project_dir), ) shutil.copytree(project_dir, new_project_dir, symlinks=True) state = AppRPC.load_state() args = ["init"] if (state["storage"]["coreCaller"] and state["storage"]["coreCaller"] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state["storage"]["coreCaller"]]) await PIOCoreRPC.call(args, options={ "cwd": new_project_dir, "force_subprocess": True }) return new_project_dir
def init(self, board, framework, project_dir): assert project_dir state = AppRPC.load_state() if not isdir(project_dir): os.makedirs(project_dir) args = ["init", "--board", board] if framework: args.extend(["--project-option", "framework = %s" % framework]) if (state['storage']['coreCaller'] and state['storage']['coreCaller'] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state['storage']['coreCaller']]) d = PIOCoreRPC.call(args, options={"cwd": project_dir}) d.addCallback(self._generate_project_main, project_dir, framework) return d
async def init(self, board, framework, project_dir): assert project_dir state = AppRPC.load_state() if not os.path.isdir(project_dir): os.makedirs(project_dir) args = ["init", "--board", board] if framework: args.extend(["--project-option", "framework = %s" % framework]) if (state["storage"]["coreCaller"] and state["storage"]["coreCaller"] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state["storage"]["coreCaller"]]) await PIOCoreRPC.call(args, options={ "cwd": project_dir, "force_subprocess": True }) return self._generate_project_main(project_dir, framework)
async def import_arduino(self, board, use_arduino_libs, arduino_project_dir): board = str(board) # don't import PIO Project if is_platformio_project(arduino_project_dir): return arduino_project_dir is_arduino_project = any([ os.path.isfile( os.path.join( arduino_project_dir, "%s.%s" % (os.path.basename(arduino_project_dir), ext), )) for ext in ("ino", "pde") ]) if not is_arduino_project: raise jsonrpc.exceptions.JSONRPCDispatchException( code=4000, message="Not an Arduino project: %s" % arduino_project_dir) state = AppRPC.load_state() project_dir = os.path.join(state["storage"]["projectsDir"], time.strftime("%y%m%d-%H%M%S-") + board) if not os.path.isdir(project_dir): os.makedirs(project_dir) args = ["init", "--board", board] args.extend(["--project-option", "framework = arduino"]) if use_arduino_libs: args.extend([ "--project-option", "lib_extra_dirs = ~/Documents/Arduino/libraries" ]) if (state["storage"]["coreCaller"] and state["storage"]["coreCaller"] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state["storage"]["coreCaller"]]) await PIOCoreRPC.call(args, options={ "cwd": project_dir, "force_subprocess": True }) with fs.cd(project_dir): config = ProjectConfig() src_dir = config.get_optional_dir("src") if os.path.isdir(src_dir): fs.rmtree(src_dir) shutil.copytree(arduino_project_dir, src_dir, symlinks=True) return project_dir
def import_arduino(self, board, use_arduino_libs, arduino_project_dir): board = str(board) if arduino_project_dir and PY2: arduino_project_dir = arduino_project_dir.encode( get_filesystem_encoding()) # don't import PIO Project if is_platformio_project(arduino_project_dir): return arduino_project_dir is_arduino_project = any([ os.path.isfile( os.path.join( arduino_project_dir, "%s.%s" % (os.path.basename(arduino_project_dir), ext), )) for ext in ("ino", "pde") ]) if not is_arduino_project: raise jsonrpc.exceptions.JSONRPCDispatchException( code=4000, message="Not an Arduino project: %s" % arduino_project_dir) state = AppRPC.load_state() project_dir = os.path.join(state["storage"]["projectsDir"], time.strftime("%y%m%d-%H%M%S-") + board) if not os.path.isdir(project_dir): os.makedirs(project_dir) args = ["init", "--board", board] args.extend(["--project-option", "framework = arduino"]) if use_arduino_libs: args.extend([ "--project-option", "lib_extra_dirs = ~/Documents/Arduino/libraries" ]) if (state["storage"]["coreCaller"] and state["storage"]["coreCaller"] in ProjectGenerator.get_supported_ides()): args.extend(["--ide", state["storage"]["coreCaller"]]) d = PIOCoreRPC.call(args, options={ "cwd": project_dir, "force_subprocess": True }) d.addCallback(self._finalize_arduino_import, project_dir, arduino_project_dir) return d
def run_server(host, port, no_open, shutdown_timeout, home_url): contrib_dir = get_core_package_dir("contrib-piohome") if not os.path.isdir(contrib_dir): raise PlatformioException("Invalid path to PIO Home Contrib") ws_rpc_factory = WebSocketJSONRPCServerFactory(shutdown_timeout) ws_rpc_factory.addHandler(AccountRPC(), namespace="account") ws_rpc_factory.addHandler(AppRPC(), namespace="app") ws_rpc_factory.addHandler(IDERPC(), namespace="ide") ws_rpc_factory.addHandler(MiscRPC(), namespace="misc") ws_rpc_factory.addHandler(OSRPC(), namespace="os") ws_rpc_factory.addHandler(PIOCoreRPC(), namespace="core") ws_rpc_factory.addHandler(ProjectRPC(), namespace="project") path = urlparse(home_url).path routes = [ WebSocketRoute(path + "wsrpc", ws_rpc_factory, name="wsrpc"), Route(path + "__shutdown__", shutdown_server, methods=["POST"]), Mount(path, StaticFiles(directory=contrib_dir, html=True), name="static"), ] if path != "/": routes.append(Route("/", protected_page)) uvicorn.run( Starlette( middleware=[Middleware(ShutdownMiddleware)], routes=routes, on_startup=[ lambda: click.echo( "PIO Home has been started. Press Ctrl+C to shutdown."), lambda: None if no_open else click.launch(home_url), ], ), host=host, port=port, log_level="warning", )
def _get_projects(project_dirs=None): def _get_project_data(project_dir): data = {"boards": [], "envLibdepsDirs": [], "libExtraDirs": []} config = ProjectConfig(join(project_dir, "platformio.ini")) libdeps_dir = get_project_libdeps_dir() data['libExtraDirs'].extend( config.get("platformio", "lib_extra_dirs", [])) for section in config.sections(): if not section.startswith("env:"): continue data['envLibdepsDirs'].append(join(libdeps_dir, section[4:])) if config.has_option(section, "board"): data['boards'].append(config.get(section, "board")) data['libExtraDirs'].extend( config.get(section, "lib_extra_dirs", [])) # skip non existing folders and resolve full path for key in ("envLibdepsDirs", "libExtraDirs"): data[key] = [ expanduser(d) if d.startswith("~") else realpath(d) for d in data[key] if isdir(d) ] return data def _path_to_name(path): return (sep).join(path.split(sep)[-2:]) if not project_dirs: project_dirs = AppRPC.load_state()['storage']['recentProjects'] result = [] pm = PlatformManager() for project_dir in project_dirs: data = {} boards = [] try: with util.cd(project_dir): data = _get_project_data(project_dir) except exception.PlatformIOProjectException: continue for board_id in data.get("boards", []): name = board_id try: name = pm.board_config(board_id)['name'] except (exception.UnknownBoard, exception.UnknownPlatform): pass boards.append({"id": board_id, "name": name}) result.append({ "path": project_dir, "name": _path_to_name(project_dir), "modified": int(getmtime(project_dir)), "boards": boards, "envLibStorages": [{ "name": basename(d), "path": d } for d in data.get("envLibdepsDirs", [])], "extraLibStorages": [{ "name": _path_to_name(d), "path": d } for d in data.get("libExtraDirs", [])] }) return result
def get_projects(): def _get_project_data(): data = {"boards": [], "envLibdepsDirs": [], "libExtraDirs": []} config = ProjectConfig() data["envs"] = config.envs() data["description"] = config.get("platformio", "description") data["libExtraDirs"].extend( config.get("platformio", "lib_extra_dirs", [])) libdeps_dir = config.get_optional_dir("libdeps") for section in config.sections(): if not section.startswith("env:"): continue data["envLibdepsDirs"].append( os.path.join(libdeps_dir, section[4:])) if config.has_option(section, "board"): data["boards"].append(config.get(section, "board")) data["libExtraDirs"].extend( config.get(section, "lib_extra_dirs", [])) # skip non existing folders and resolve full path for key in ("envLibdepsDirs", "libExtraDirs"): data[key] = [ fs.expanduser(d) if d.startswith("~") else os.path.realpath(d) for d in data[key] if os.path.isdir(d) ] return data def _path_to_name(path): return (os.path.sep).join(path.split(os.path.sep)[-2:]) result = [] pm = PlatformPackageManager() for project_dir in AppRPC.load_state()["storage"]["recentProjects"]: if not os.path.isdir(project_dir): continue data = {} boards = [] try: with fs.cd(project_dir): data = _get_project_data() except ProjectError: continue for board_id in data.get("boards", []): name = board_id try: name = pm.board_config(board_id)["name"] except exception.PlatformioException: pass boards.append({"id": board_id, "name": name}) result.append({ "path": project_dir, "name": _path_to_name(project_dir), "modified": int(os.path.getmtime(project_dir)), "boards": boards, "description": data.get("description"), "envs": data.get("envs", []), "envLibStorages": [{ "name": os.path.basename(d), "path": d } for d in data.get("envLibdepsDirs", [])], "extraLibStorages": [{ "name": _path_to_name(d), "path": d } for d in data.get("libExtraDirs", [])], }) return result
def cli(port, host, no_open, shutdown_timeout): # pylint: disable=import-error, import-outside-toplevel # import contrib modules inject_contrib_pysite() from autobahn.twisted.resource import WebSocketResource from twisted.internet import reactor from twisted.web import server from platformio.commands.home.rpc.handlers.app import AppRPC from platformio.commands.home.rpc.handlers.ide import IDERPC from platformio.commands.home.rpc.handlers.misc import MiscRPC from platformio.commands.home.rpc.handlers.os import OSRPC from platformio.commands.home.rpc.handlers.piocore import PIOCoreRPC from platformio.commands.home.rpc.handlers.project import ProjectRPC from platformio.commands.home.rpc.server import JSONRPCServerFactory from platformio.commands.home.web import WebRoot factory = JSONRPCServerFactory(shutdown_timeout) factory.addHandler(AppRPC(), namespace="app") factory.addHandler(IDERPC(), namespace="ide") factory.addHandler(MiscRPC(), namespace="misc") factory.addHandler(OSRPC(), namespace="os") factory.addHandler(PIOCoreRPC(), namespace="core") factory.addHandler(ProjectRPC(), namespace="project") contrib_dir = get_core_package_dir("contrib-piohome") if not isdir(contrib_dir): raise exception.PlatformioException("Invalid path to PIO Home Contrib") # Ensure PIO Home mimetypes are known mimetypes.add_type("text/html", ".html") mimetypes.add_type("text/css", ".css") mimetypes.add_type("application/javascript", ".js") root = WebRoot(contrib_dir) root.putChild(b"wsrpc", WebSocketResource(factory)) site = server.Site(root) # hook for `platformio-node-helpers` if host == "__do_not_start__": return # if already started already_started = False socket.setdefaulttimeout(1) try: socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port)) already_started = True except: # pylint: disable=bare-except pass home_url = "http://%s:%d" % (host, port) if not no_open: if already_started: click.launch(home_url) else: reactor.callLater(1, lambda: click.launch(home_url)) click.echo("\n".join([ "", " ___I_", " /\\-_--\\ PlatformIO Home", "/ \\_-__\\", "|[]| [] | %s" % home_url, "|__|____|______________%s" % ("_" * len(host)), ])) click.echo("") click.echo("Open PIO Home in your browser by this URL => %s" % home_url) if already_started: return click.echo("PIO Home has been started. Press Ctrl+C to shutdown.") reactor.listenTCP(port, site, interface=host) reactor.run()