def copy_src_tree(): import filecmp import shutil source_files = {} for _, component, _ in iter_components(CORE.config): source_files.update(component.source_files) # Convert to list and sort source_files_l = [it for it in source_files.items()] source_files_l.sort() # Build #include list for esphome.h include_l = [] for target, path in source_files_l: if os.path.splitext(path)[1] in HEADER_FILE_EXTENSIONS: include_l.append(u'#include "{}"'.format(target)) include_l.append(u'') include_s = u'\n'.join(include_l) source_files_copy = source_files.copy() source_files_copy.pop(DEFINES_H_TARGET) for path in walk_files(CORE.relative_src_path('esphome')): if os.path.splitext(path)[1] not in SOURCE_FILE_EXTENSIONS: # Not a source file, ignore continue # Transform path to target path name target = os.path.relpath(path, CORE.relative_src_path()).replace( os.path.sep, '/') if target == DEFINES_H_TARGET: # Ignore defines.h, will be dealt with later continue if target not in source_files_copy: # Source file removed, delete target os.remove(path) else: src_path = source_files_copy.pop(target) if not filecmp.cmp(path, src_path): # Files are not same, copy shutil.copy(src_path, path) # Now copy new files for target, src_path in source_files_copy.items(): dst_path = CORE.relative_src_path(*target.split('/')) mkdir_p(os.path.dirname(dst_path)) shutil.copy(src_path, dst_path) # Finally copy defines write_file_if_changed( generate_defines_h(), CORE.relative_src_path('esphome', 'core', 'defines.h')) write_file_if_changed(ESPHOME_README_TXT, CORE.relative_src_path('esphome', 'README.txt')) write_file_if_changed(ESPHOME_H_FORMAT.format(include_s), CORE.relative_src_path('esphome.h')) write_file_if_changed( VERSION_H_FORMAT.format(__version__), CORE.relative_src_path('esphome' 'core', 'version.h'))
def write_platformio_project(): mkdir_p(CORE.build_path) content = get_ini_content() if not get_bool_env(ENV_NOGITIGNORE): write_gitignore() write_platformio_ini(content)
def write_cpp(code_s): path = CORE.relative_build_path('src', 'main.cpp') if os.path.isfile(path): try: with codecs.open(path, 'r', encoding='utf-8') as f_handle: text = f_handle.read() except OSError: raise EsphomeError(u"Could not read C++ file at {}".format(path)) prev_file = text code_format = find_begin_end(text, CPP_AUTO_GENERATE_BEGIN, CPP_AUTO_GENERATE_END) code_format_ = find_begin_end(code_format[0], CPP_INCLUDE_BEGIN, CPP_INCLUDE_END) code_format = (code_format_[0], code_format_[1], code_format[1]) else: prev_file = None mkdir_p(os.path.dirname(path)) code_format = CPP_BASE_FORMAT include_s = get_include_text() full_file = code_format[ 0] + CPP_INCLUDE_BEGIN + u'\n' + include_s + CPP_INCLUDE_END full_file += code_format[ 1] + CPP_AUTO_GENERATE_BEGIN + u'\n' + code_s + CPP_AUTO_GENERATE_END full_file += code_format[2] if prev_file == full_file: return with codecs.open(path, 'w+', encoding='utf-8') as f_handle: f_handle.write(full_file)
def write_platformio_project(): mkdir_p(CORE.build_path) platformio_ini = CORE.relative_build_path('platformio.ini') content = get_ini_content() write_gitignore() write_platformio_ini(content, platformio_ini)
def start_web_server(args): settings.parse_args(args) mkdir_p(settings.rel_path(".esphome")) if settings.using_auth: path = esphome_storage_path(settings.config_dir) storage = EsphomeStorageJSON.load(path) if storage is None: storage = EsphomeStorageJSON.get_default() storage.save(path) settings.cookie_secret = storage.cookie_secret app = make_app(args.verbose) if args.socket is not None: _LOGGER.info( "Starting dashboard web server on unix socket %s and configuration dir %s...", args.socket, settings.config_dir, ) server = tornado.httpserver.HTTPServer(app) socket = tornado.netutil.bind_unix_socket(args.socket, mode=0o666) server.add_socket(socket) else: _LOGGER.info( "Starting dashboard web server on http://%s:%s and configuration dir %s...", args.address, args.port, settings.config_dir, ) app.listen(args.port, args.address) if args.open_ui: import webbrowser webbrowser.open(f"http://{args.address}:{args.port}") if settings.status_use_ping: status_thread = PingStatusThread() else: status_thread = MDNSStatusThread() status_thread.start() try: tornado.ioloop.IOLoop.current().start() except KeyboardInterrupt: _LOGGER.info("Shutting down...") STOP_EVENT.set() PING_REQUEST.set() status_thread.join() if args.socket is not None: os.remove(args.socket)
def post(self, configuration=None): config_file = settings.rel_path(configuration) storage_path = ext_storage_path(settings.config_dir, configuration) trash_path = trash_storage_path(settings.config_dir) mkdir_p(trash_path) shutil.move(config_file, os.path.join(trash_path, configuration)) storage_json = StorageJSON.load(storage_path) if storage_json is not None: # Delete build folder (if exists) name = storage_json.name build_folder = os.path.join(settings.config_dir, name) if build_folder is not None: shutil.rmtree(build_folder, os.path.join(trash_path, name))
def post(self, configuration=None): config_file = os.path.join(CONFIG_DIR, configuration) storage_path = ext_storage_path(CONFIG_DIR, configuration) storage_json = StorageJSON.load(storage_path) if storage_json is None: self.set_status(500) return name = storage_json.name trash_path = trash_storage_path(CONFIG_DIR) mkdir_p(trash_path) shutil.move(config_file, os.path.join(trash_path, configuration)) # Delete build folder (if exists) build_folder = os.path.join(CONFIG_DIR, name) if build_folder is not None: shutil.rmtree(build_folder, os.path.join(trash_path, name))
def symlink_esphome_core_version(esphome_core_version): lib_path = CORE.relative_build_path('lib') dst_path = CORE.relative_build_path('lib', 'esphome-core') if CORE.is_local_esphome_core_copy: src_path = CORE.relative_path(esphome_core_version[CONF_LOCAL]) do_write = True if os.path.islink(dst_path): old_path = os.path.join(os.readlink(dst_path), lib_path) if old_path != lib_path: os.unlink(dst_path) else: do_write = False if do_write: mkdir_p(lib_path) symlink(src_path, dst_path) else: # Remove symlink when changing back from local version if os.path.islink(dst_path): os.unlink(dst_path)
def start_web_server(args): global CONFIG_DIR global PASSWORD_DIGEST global USING_PASSWORD global ON_HASSIO global USING_HASSIO_AUTH global COOKIE_SECRET CONFIG_DIR = args.configuration mkdir_p(CONFIG_DIR) mkdir_p(os.path.join(CONFIG_DIR, ".esphome")) ON_HASSIO = args.hassio if ON_HASSIO: USING_HASSIO_AUTH = not get_bool_env('DISABLE_HA_AUTHENTICATION') USING_PASSWORD = False else: USING_HASSIO_AUTH = False USING_PASSWORD = args.password if USING_PASSWORD: if IS_PY2: PASSWORD_DIGEST = hmac.new(args.password).digest() else: PASSWORD_DIGEST = hmac.new(args.password.encode()).digest() if USING_HASSIO_AUTH or USING_PASSWORD: path = esphome_storage_path(CONFIG_DIR) storage = EsphomeStorageJSON.load(path) if storage is None: storage = EsphomeStorageJSON.get_default() storage.save(path) COOKIE_SECRET = storage.cookie_secret app = make_app(args.verbose) if args.socket is not None: _LOGGER.info( "Starting dashboard web server on unix socket %s and configuration dir %s...", args.socket, CONFIG_DIR) server = tornado.httpserver.HTTPServer(app) socket = tornado.netutil.bind_unix_socket(args.socket, mode=0o666) server.add_socket(socket) else: _LOGGER.info( "Starting dashboard web server on port %s and configuration dir %s...", args.port, CONFIG_DIR) app.listen(args.port) if args.open_ui: import webbrowser webbrowser.open('localhost:{}'.format(args.port)) if STATUS_USE_PING: status_thread = PingStatusThread() else: status_thread = MDNSStatusThread() status_thread.start() try: tornado.ioloop.IOLoop.current().start() except KeyboardInterrupt: _LOGGER.info("Shutting down...") STOP_EVENT.set() PING_REQUEST.set() status_thread.join() if args.socket is not None: os.remove(args.socket)
def write_platformio_project(): mkdir_p(CORE.build_path) content = get_ini_content() write_gitignore() write_platformio_ini(content)
def save(self, path): mkdir_p(os.path.dirname(path)) with codecs.open(path, 'w', encoding='utf-8') as f_handle: f_handle.write(self.to_json())