def _download_update(release): """Faz download e extrai o zip de uma release Parâmetros ---------- release : json JSON da release, retornado pelo `_fetch_latest_release` Retorno ------- O caminho da pasta com os arquivos do `.zip` extraídos """ cli.i_am("Obtendo arquivo zip...") zip_url = release['zipball_url'] res = requests.get(zip_url, stream=True) release_zip_file = zipfile.ZipFile(io.BytesIO(res.content)) cli.success("OK") cli.i_am("Extraindo...") tmp_dir = tempfile.mkdtemp() root_dir = release_zip_file.namelist()[0] release_zip_file.extractall(path=tmp_dir) cli.success("OK") tmp_dir = f"{tmp_dir}/{root_dir}".replace("\\", "/") return tmp_dir
def _install_update(update_dir): """Faz a instalação de uma atualização Isso envolve resolver dependências com pip e mover os arquivos baixados para suas respectivas pastas. """ cli.i_am("Instalando dependências...") requirements_file = f"{update_dir}/requirements.txt" result = os.system( f"pip install --upgrade -r \"{requirements_file}\" >nul 2>nul") if result == 0: cli.success("OK") else: gui.error("Falha na instalação. Abortando atualização...\r\n" + "\r\n" + "Veja o arquivo `error.log' para mais informações.") log.error("update", "Falha na instação das dependências") return cli.i_am("Atualizando código fonte...") sources = _map_update_sources(update_dir) _touch_directories(sources) for fname, dirname in sources: path = fname if dirname == '.' else f"{dirname}/{fname}" copyfile(f"{update_dir}/{path}", f".update/{path}") # O arquivo apply_update.py é especial: ele não pode atualizar ele # mesmo os.system("move /Y .update\\apply_update.py .") cli.success("OK")
def check_updates(): """Executa o procedimento de busca e instalação de atualizações""" cli.i_am("Procurando atualizações...") try: latest_release = _fetch_latest_release() except RuntimeError as ex: gui.error("Falha na atualização." + "Verifique sua conexão com a internet.") log.error("fetch-releases", ex) return cli.info("Encontrado: " + latest_release['tag_name']) if latest_release['tag_name'] == version.current(): cli.success("O god está atualizado.") return cli.error("O god está desatualizado!") if _confirm(latest_release): update_dir = _download_update(latest_release) _install_update(update_dir) version.set_tag(latest_release['tag_name']) with open(".version", "w") as version_file: version_file.write(version.current()) os.system("start python apply_update.py") sys.exit(0) else: cli.warning("Ignorando atualização. " + "Cuidado, isso geralmente dá ruim.")
def load_settings(): """Carrega as configurações do programa""" cli.i_am("Carregando configurações...") config.load() cli.success("OK") cli.print_settings()
def use_inet_phrases(): """Tenta usar frases e autores da internet, se falha usa os locais""" cli.i_am("Pegando umas frases aleatórias...") try: amount = quotes.load_inet() cli.success("{} frases".format(amount)) except RuntimeError: cli.error("Falhou :(") use_stored_phrases()
def load_phrases(): """Carrega informações para citações da fonte mais adequada""" cli.i_am("Checando conexão com a internet...") if god.check_internet(): cli.success("OK") cli.list_begin() use_inet_phrases() cli.list_end() else: cli.error("Internet indisponível") cli.list_begin() use_stored_phrases() cli.list_end()
def main(): """Procedimento principal""" cli.title(f"God {version.current()}") cli.clear() cli.header() updater.check_updates() load_settings() load_phrases() cli.success("Pronto.") print() cli.i_am("Iniciando ambiente interativo. Se divirta!") time.sleep(2) cli.clear() cli.interactive_header() god.start() god.interactive.run()
def use_stored_phrases(): """Carrega frases e autores locais para citações""" cli.i_am("Usando frases aleatórias locais...") amount = quotes.load_local() cli.success("Got {} phrases".format(amount))