mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-06 22:54:16 +02:00
[web] installing, removing and reading
This commit is contained in:
@@ -3,3 +3,4 @@ from pathlib import Path
|
||||
HOME_PATH = Path.home()
|
||||
CACHE_PATH = '{}/.cache/bauh'.format(HOME_PATH)
|
||||
CONFIG_PATH = '{}/.config/bauh'.format(HOME_PATH)
|
||||
DESKTOP_ENTRIES_DIR = '{}/.local/share/applications'.format(HOME_PATH)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import os
|
||||
|
||||
from bauh.api.constants import HOME_PATH
|
||||
from bauh.api.constants import HOME_PATH, DESKTOP_ENTRIES_DIR
|
||||
|
||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
BIN_PATH = '{}/.local/share/bauh/web'.format(HOME_PATH)
|
||||
INSTALLED_PATH = '{}/installed'.format(BIN_PATH)
|
||||
NODE_DIR_PATH = '{}/node'.format(BIN_PATH)
|
||||
NODE_BIN_PATH = '{}/bin/node'.format(NODE_DIR_PATH)
|
||||
NPM_BIN_PATH = '{}/bin/npm'.format(NODE_DIR_PATH)
|
||||
@@ -13,3 +14,4 @@ ELECTRON_PATH = '{}/.cache/electron'.format(HOME_PATH)
|
||||
ELECTRON_DOWNLOAD_URL = 'https://github.com/electron/electron/releases/download/v{version}/electron-v{version}-linux-{arch}.zip'
|
||||
ELECTRON_SHA256_URL = 'https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt'
|
||||
URL_ENVIRONMENT_SETTINGS = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/web/environment.yml'
|
||||
DESKTOP_ENTRY_PATH_PATTERN = DESKTOP_ENTRIES_DIR + '/bauh.web.{name}.desktop'
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
from typing import List, Type, Set
|
||||
|
||||
@@ -8,8 +14,10 @@ from bauh.api.abstract.disk import DiskCacheLoader
|
||||
from bauh.api.abstract.handler import ProcessWatcher
|
||||
from bauh.api.abstract.model import SoftwarePackage, PackageAction, PackageSuggestion, PackageUpdate, PackageHistory
|
||||
from bauh.api.abstract.view import MessageType
|
||||
from bauh.commons import system
|
||||
from bauh.commons.html import bold
|
||||
from bauh.commons.system import ProcessHandler
|
||||
from bauh.gems.web import INSTALLED_PATH, nativefier, DESKTOP_ENTRY_PATH_PATTERN
|
||||
from bauh.gems.web.environment import EnvironmentUpdater
|
||||
from bauh.gems.web.model import WebApplication
|
||||
|
||||
@@ -37,6 +45,8 @@ class WebApplicationManager(SoftwareManager):
|
||||
self.enabled = True
|
||||
self.i18n = context.i18n
|
||||
self.env_updater = env_updater
|
||||
self.env_settings = {}
|
||||
self.logger = context.logger
|
||||
|
||||
def search(self, words: str, disk_loader: DiskCacheLoader, limit: int = -1, is_url: bool = False) -> SearchResult:
|
||||
res = SearchResult([], [], 0)
|
||||
@@ -56,7 +66,13 @@ class WebApplicationManager(SoftwareManager):
|
||||
icon_tag = soup.head.find('link', attrs={"rel": "icon"})
|
||||
icon_url = icon_tag.get('href') if icon_tag else None
|
||||
|
||||
res.new = [WebApplication(url=words, name=name, description=desc, icon_url=icon_url)]
|
||||
app = WebApplication(url=words, name=name, description=desc, icon_url=icon_url)
|
||||
|
||||
if self.env_settings.get('electron') and self.env_settings['electron'].get('version'):
|
||||
app.version = self.env_settings['electron']['version']
|
||||
app.latest_version = app.version
|
||||
|
||||
res.new = [app]
|
||||
res.total = 1
|
||||
else:
|
||||
# TODO
|
||||
@@ -65,8 +81,15 @@ class WebApplicationManager(SoftwareManager):
|
||||
return res
|
||||
|
||||
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = True) -> SearchResult:
|
||||
# TODO
|
||||
return SearchResult([], [], 0)
|
||||
res = SearchResult([], [], 0)
|
||||
|
||||
if os.path.exists(INSTALLED_PATH):
|
||||
for data_path in glob.glob('{}/*/*data.json'.format(INSTALLED_PATH)):
|
||||
with open(data_path, 'r') as f:
|
||||
res.installed.append(WebApplication(installed=True, **json.loads(f.read())))
|
||||
res.total += 1
|
||||
|
||||
return res
|
||||
|
||||
def downgrade(self, pkg: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool:
|
||||
pass
|
||||
@@ -74,14 +97,47 @@ class WebApplicationManager(SoftwareManager):
|
||||
def update(self, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
pass
|
||||
|
||||
def uninstall(self, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
pass
|
||||
def uninstall(self, pkg: WebApplication, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
self.logger.info("Checking if {} installation directory {} exists".format(pkg.name, pkg.installation_dir))
|
||||
|
||||
if not os.path.exists(pkg.installation_dir):
|
||||
watcher.show_message(title=self.i18n['error'],
|
||||
body=self.i18n['web.uninstall.error.install_dir.not_found'].format(bold(pkg.installation_dir)),
|
||||
type_=MessageType.ERROR)
|
||||
return False
|
||||
|
||||
self.logger.info("Removing {} installation directory {}".format(pkg.name, pkg.installation_dir))
|
||||
try:
|
||||
shutil.rmtree(pkg.installation_dir)
|
||||
except:
|
||||
watcher.show_message(title=self.i18n['error'],
|
||||
body=self.i18n['web.uninstall.error.remove'].format(bold(pkg.installation_dir)),
|
||||
type_=MessageType.ERROR)
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
self.logger.info("Checking if {} desktop entry file {} exists".format(pkg.name, pkg.desktop_entry))
|
||||
if os.path.exists(pkg.desktop_entry):
|
||||
try:
|
||||
os.remove(pkg.desktop_entry)
|
||||
except:
|
||||
watcher.show_message(title=self.i18n['error'],
|
||||
body=self.i18n['web.uninstall.error.remove'].format(bold(pkg.desktop_entry)),
|
||||
type_=MessageType.ERROR)
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_managed_types(self) -> Set[Type[SoftwarePackage]]:
|
||||
return {WebApplication}
|
||||
|
||||
def get_info(self, pkg: SoftwarePackage) -> dict:
|
||||
pass
|
||||
def get_info(self, pkg: WebApplication) -> dict:
|
||||
if pkg.installed:
|
||||
info = {'{}_{}'.format(idx + 1, att): getattr(pkg, att) for idx, att in enumerate(('url', 'description', 'version', 'installation_dir', 'desktop_entry'))}
|
||||
info['6_exec_file'] = pkg.get_exec_path()
|
||||
info['7_icon_path'] = pkg.get_disk_icon_path()
|
||||
return info
|
||||
|
||||
def get_history(self, pkg: SoftwarePackage) -> PackageHistory:
|
||||
pass
|
||||
@@ -97,8 +153,78 @@ class WebApplicationManager(SoftwareManager):
|
||||
watcher.show_message(title=self.i18n['error'], body=self.i18n['web.env.error'].format(bold(pkg.name)), type_=MessageType.ERROR)
|
||||
return False
|
||||
|
||||
Path(INSTALLED_PATH).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
pkg_name = pkg.name.lower()
|
||||
|
||||
app_name_id, app_dir = pkg_name, '{}/{}'.format(INSTALLED_PATH, pkg_name)
|
||||
|
||||
counter = 1
|
||||
while True:
|
||||
if not os.path.exists(app_dir):
|
||||
break
|
||||
else:
|
||||
app_name_id += str(counter)
|
||||
app_dir = '{}/{}'.format(INSTALLED_PATH, app_name_id)
|
||||
counter += 1
|
||||
|
||||
installed = handler.handle_simple(nativefier.install(url=pkg.url, name=pkg_name, output_dir=app_dir,
|
||||
electron_version=self.env_settings['electron']['version'], cwd=INSTALLED_PATH))
|
||||
|
||||
if not installed:
|
||||
msg = '{}.{}.'.format(self.i18n['wen.install.error'].format(bold(pkg.name)),
|
||||
self.i18n['web.install.nativefier.error.unknown'].format(bold(self.i18n['details'].capitalize())))
|
||||
watcher.show_message(title=self.i18n['error'], body=msg, type_=MessageType.ERROR)
|
||||
return False
|
||||
|
||||
inner_dir = os.listdir(app_dir)
|
||||
|
||||
if not inner_dir:
|
||||
msg = '{}.{}.'.format(self.i18n['wen.install.error'].format(bold(pkg.name)),
|
||||
self.i18n['web.install.nativefier.error.inner_dir'].format(bold(app_dir)))
|
||||
watcher.show_message(title=self.i18n['error'], body=msg, type_=MessageType.ERROR)
|
||||
return False
|
||||
|
||||
# bringing the inner app folder to the 'installed' folder level:
|
||||
inner_dir = '{}/{}'.format(app_dir, inner_dir[0])
|
||||
temp_dir = '{}/tmp_{}'.format(INSTALLED_PATH, app_name_id)
|
||||
os.rename(inner_dir, temp_dir)
|
||||
shutil.rmtree(app_dir)
|
||||
os.rename(temp_dir, app_dir)
|
||||
|
||||
pkg.installation_dir = app_dir
|
||||
|
||||
version_path = '{}/version'.format(app_dir)
|
||||
|
||||
if os.path.exists(version_path):
|
||||
with open(version_path, 'r') as f:
|
||||
pkg.version = f.read().strip()
|
||||
pkg.latest_version = pkg.version
|
||||
|
||||
desktop_entry = DESKTOP_ENTRY_PATH_PATTERN.format(name=app_name_id)
|
||||
entry_content = self._gen_desktop_entry_content(pkg)
|
||||
|
||||
# TODO check if the desktop entry exists
|
||||
|
||||
with open(desktop_entry, 'w+') as f:
|
||||
f.write(entry_content)
|
||||
|
||||
pkg.desktop_entry = desktop_entry
|
||||
|
||||
return True
|
||||
|
||||
def _gen_desktop_entry_content(self, pkg: WebApplication) -> str:
|
||||
return """
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name={name} ( web )
|
||||
Categories=Applications;
|
||||
Comment={desc}
|
||||
Icon={icon}
|
||||
Exec={exec_path}
|
||||
""".format(name=pkg.name, exec_path=pkg.get_exec_path(),
|
||||
desc=pkg.description or pkg.url, icon=pkg.get_disk_icon_path())
|
||||
|
||||
def is_enabled(self) -> bool:
|
||||
return self.enabled
|
||||
|
||||
@@ -112,7 +238,13 @@ class WebApplicationManager(SoftwareManager):
|
||||
return False
|
||||
|
||||
def _update_environment(self, handler: ProcessHandler = None) -> bool:
|
||||
return self.node_updater.update_environment(self.context.is_system_x86_64(), handler=handler)
|
||||
updated_settings = self.node_updater.update_environment(self.context.is_system_x86_64(), handler=handler)
|
||||
|
||||
if updated_settings is not None:
|
||||
self.env_settings = updated_settings
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def prepare(self):
|
||||
if bool(int(os.getenv('BAUH_WEB_UPDATE_NODE', 1))):
|
||||
@@ -134,8 +266,8 @@ class WebApplicationManager(SoftwareManager):
|
||||
def is_default_enabled(self) -> bool:
|
||||
return True
|
||||
|
||||
def launch(self, pkg: SoftwarePackage):
|
||||
pass
|
||||
def launch(self, pkg: WebApplication):
|
||||
subprocess.Popen(pkg.get_exec_path())
|
||||
|
||||
def get_screenshots(self, pkg: SoftwarePackage) -> List[str]:
|
||||
pass
|
||||
|
||||
@@ -163,12 +163,11 @@ class EnvironmentUpdater:
|
||||
if self._download_electron(version=version, is_x86_x64_arch=is_x86_x64_arch, watcher=watcher):
|
||||
return self._download_electron_sha256(version=version, watcher=watcher)
|
||||
else:
|
||||
files = run_cmd('ls', print_error=False, cwd=ELECTRON_PATH)
|
||||
files = os.listdir(ELECTRON_PATH)
|
||||
|
||||
if files:
|
||||
file_list = files.split('\n')
|
||||
file_name = ELECTRON_DOWNLOAD_URL.format(version=version, arch='x64' if is_x86_x64_arch else 'ia32').split('/')[-1]
|
||||
electron_file = [f for f in file_list if f == file_name]
|
||||
electron_file = [f for f in files if f == file_name]
|
||||
|
||||
if electron_file:
|
||||
self.logger.info("Electron {} already downloaded".format(version))
|
||||
@@ -177,7 +176,7 @@ class EnvironmentUpdater:
|
||||
return False
|
||||
|
||||
file_name = ELECTRON_SHA256_URL.split('/')[-1]
|
||||
sha256_file = [f for f in file_list if f == file_name]
|
||||
sha256_file = [f for f in files if f == file_name]
|
||||
|
||||
if sha256_file:
|
||||
self.logger.info("Electron {} sha256 already downloaded".format(version))
|
||||
@@ -191,37 +190,44 @@ class EnvironmentUpdater:
|
||||
|
||||
return False
|
||||
|
||||
def update_environment(self, is_x86_x64_arch: bool, handler: ProcessHandler = None) -> bool:
|
||||
def get_environment(self) -> dict:
|
||||
try:
|
||||
res = self.http_client.get(URL_ENVIRONMENT_SETTINGS)
|
||||
|
||||
if not res:
|
||||
self.logger.warning('Could not retrieve the environments settings from the cloud')
|
||||
return False
|
||||
return
|
||||
|
||||
try:
|
||||
settings = yaml.safe_load(res.content)
|
||||
return yaml.safe_load(res.content)
|
||||
except yaml.YAMLError:
|
||||
self.logger.error('Could not parse environment settings: {}'.format(res.text))
|
||||
return False
|
||||
|
||||
if not self.update_node(version=settings['nodejs']['version'], version_url=settings['nodejs']['url'],
|
||||
watcher=handler.watcher if handler else None):
|
||||
self.logger.warning('Could not install / update NodeJS')
|
||||
return False
|
||||
|
||||
if not self.install_nativefier(version=settings['nativefier']['version'], handler=handler):
|
||||
self.logger.warning('Could not install / update nativefier')
|
||||
return False
|
||||
|
||||
res = self.install_electron(version=settings['electron']['version'], is_x86_x64_arch=is_x86_x64_arch,
|
||||
watcher=handler.watcher if handler else None)
|
||||
|
||||
if res:
|
||||
self.logger.info('Environment updated')
|
||||
else:
|
||||
self.logger.warning('Could not update the environment')
|
||||
|
||||
return res
|
||||
return
|
||||
except requests.exceptions.ConnectionError:
|
||||
return False
|
||||
return
|
||||
|
||||
def update_environment(self, is_x86_x64_arch: bool, handler: ProcessHandler = None) -> dict:
|
||||
|
||||
settings = self.get_environment()
|
||||
|
||||
if settings is None:
|
||||
return
|
||||
|
||||
if not self.update_node(version=settings['nodejs']['version'], version_url=settings['nodejs']['url'],
|
||||
watcher=handler.watcher if handler else None):
|
||||
self.logger.warning('Could not install / update NodeJS')
|
||||
return
|
||||
|
||||
if not self.install_nativefier(version=settings['nativefier']['version'], handler=handler):
|
||||
self.logger.warning('Could not install / update nativefier')
|
||||
return
|
||||
|
||||
res = self.install_electron(version=settings['electron']['version'], is_x86_x64_arch=is_x86_x64_arch,
|
||||
watcher=handler.watcher if handler else None)
|
||||
|
||||
if res:
|
||||
self.logger.info('Environment updated')
|
||||
else:
|
||||
self.logger.warning('Could not update the environment')
|
||||
|
||||
return settings
|
||||
|
||||
@@ -6,19 +6,31 @@ from bauh.gems.web import ROOT_DIR
|
||||
|
||||
class WebApplication(SoftwarePackage):
|
||||
|
||||
def __init__(self, url: str, name: str, description: str, icon_url: str):
|
||||
super(WebApplication, self).__init__(id=url, name=name, description=description, icon_url=icon_url)
|
||||
def __init__(self, url: str = None, name: str = None, description: str = None, icon_url: str = None,
|
||||
installation_dir: str = None, desktop_entry: str = None, installed: bool = False, version: str = None):
|
||||
super(WebApplication, self).__init__(id=url, name=name, description=description,
|
||||
icon_url=icon_url, installed=installed, version=version)
|
||||
self.url = url
|
||||
self.installation_dir = installation_dir
|
||||
self.desktop_entry = desktop_entry
|
||||
|
||||
def has_history(self):
|
||||
return False
|
||||
|
||||
def has_info(self):
|
||||
return False
|
||||
return self.installed
|
||||
|
||||
@staticmethod
|
||||
def _get_cached_attrs() -> tuple:
|
||||
return 'name', 'version', 'url', 'description', 'icon_url', 'installation_dir', 'desktop_entry'
|
||||
|
||||
def can_be_downgraded(self):
|
||||
return False
|
||||
|
||||
def get_exec_path(self) -> str:
|
||||
if self.installation_dir:
|
||||
return '{}/{}'.format(self.installation_dir, self.installation_dir.split('/')[-1])
|
||||
|
||||
def get_type(self):
|
||||
return 'web'
|
||||
|
||||
@@ -32,22 +44,32 @@ class WebApplication(SoftwarePackage):
|
||||
return True
|
||||
|
||||
def supports_disk_cache(self):
|
||||
return self.installed and self.is_application()
|
||||
return self.installed
|
||||
|
||||
def get_disk_cache_path(self):
|
||||
return CACHE_PATH + '/' + self.get_type()
|
||||
return self.installation_dir
|
||||
|
||||
def get_data_to_cache(self) -> dict:
|
||||
"""
|
||||
:return: the application data that should be cached in disk / memory for quick access
|
||||
"""
|
||||
pass
|
||||
data = {}
|
||||
|
||||
for attr in self._get_cached_attrs():
|
||||
if hasattr(self, attr):
|
||||
val = getattr(self, attr)
|
||||
|
||||
if val is not None:
|
||||
data[attr] = val
|
||||
|
||||
return data
|
||||
|
||||
def fill_cached_data(self, data: dict):
|
||||
pass
|
||||
for attr in self._get_cached_attrs():
|
||||
val = data.get(attr)
|
||||
|
||||
if val and hasattr(self, attr):
|
||||
setattr(self, attr, val)
|
||||
|
||||
def can_be_run(self) -> bool:
|
||||
return self.installed
|
||||
return self.installed and self.installation_dir
|
||||
|
||||
def is_trustable(self) -> bool:
|
||||
return False
|
||||
|
||||
6
bauh/gems/web/nativefier.py
Normal file
6
bauh/gems/web/nativefier.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from bauh.commons.system import SimpleProcess
|
||||
from bauh.gems.web import NATIVEFIER_BIN_PATH
|
||||
|
||||
|
||||
def install(url: str, name: str, output_dir: str, electron_version: str, cwd: str) -> SimpleProcess:
|
||||
return SimpleProcess([NATIVEFIER_BIN_PATH, url, '--name', name, '-e', electron_version, output_dir], cwd=cwd)
|
||||
@@ -1,5 +1,17 @@
|
||||
gem.web.info=It allows to install Web applications on your system
|
||||
web.environment.install=Installing {}
|
||||
web.waiting.env_updater=Updating environment
|
||||
web.env.checking=Checking the Web application installation environment
|
||||
web.env.error=It seems there are issues with the Web application installation environment. It wil not be possible to install {}.
|
||||
web.env.checking=Checking the Web installation environment
|
||||
web.env.error=It seems there are issues with the Web installation environment. It wil not be possible to install {}.
|
||||
web.install.error=An error has happened during the {} installation
|
||||
web.install.nativefier.error.unknown=Have a look at the {} to identify the reason
|
||||
web.install.nativefier.error.inner_dir=The app installation directory was not found in {}
|
||||
web.uninstall.error.install_dir.not_found=The installation directory {} was not found
|
||||
web.uninstall.error.remove_dir=It was not possible to remove {}
|
||||
web.info.1_url=URL
|
||||
web.info.2_description=description
|
||||
web.info.3_version=version
|
||||
web.info.4_installation_dir=installation dir
|
||||
web.info.5_desktop_entry=shortcut
|
||||
web.info.6_exec_file=executable
|
||||
web.info.7_icon_path=icon
|
||||
@@ -1,5 +1,17 @@
|
||||
gem.web.info=Permite instalar aplicações Web no seu sistema
|
||||
web.environment.nativefier=Instalando {}
|
||||
web.waiting.env_updater=Atualizando ambiente
|
||||
web.env.checking=Verificando o ambiente de instalação para aplicativos Web
|
||||
web.env.error=Parece haver problemas com o ambiente de instalação para aplicativos Web. Não sera possível instalar {}.
|
||||
web.env.checking=Verificando o ambiente de instalação Web
|
||||
web.env.error=Parce que existem problemas com o ambiente de instalação Web. Não será possível instalar {}.
|
||||
wen.install.error=Ocorreu um erro durante a instalação de {}
|
||||
web.install.nativefier.error.unknown=Dê uma olhada em {} para identificar o motivo
|
||||
web.install.nativefier.error.inner_dir=O diretório de instalação do aplicativo não foi encontrado em {}
|
||||
web.uninstall.error.install_dir.not_found=O diretório de instalação {} não foi encontrado
|
||||
web.uninstall.error.remove=Não foi possível remover {}
|
||||
web.info.1_url=URL
|
||||
web.info.2_description=descrição
|
||||
web.info.3_version=versão
|
||||
web.info.4_installation_dir=diretório de instalação
|
||||
web.info.5_desktop_entry=atalho
|
||||
web.info.6_exec_file=executável
|
||||
web.info.7_icon_path=ícone
|
||||
@@ -201,4 +201,5 @@ publisher.verified=verificat
|
||||
mirror=mirall
|
||||
emulator=emulador
|
||||
do_not.install=no instal·leu
|
||||
repository=dipòsit
|
||||
repository=dipòsit
|
||||
details=detalls
|
||||
@@ -155,4 +155,5 @@ close=Schließen
|
||||
publisher.verified=Verifiziert
|
||||
emulator=emulator
|
||||
do_not.install=nicht installieren
|
||||
repository=repository
|
||||
repository=repository
|
||||
details=details
|
||||
@@ -157,3 +157,4 @@ mirror=mirror
|
||||
emulator=emulator
|
||||
do_not.install=don't install
|
||||
repository=repository
|
||||
details=details
|
||||
@@ -200,4 +200,5 @@ publisher.verified=verificado
|
||||
mirror=espejo
|
||||
emulator=emulador
|
||||
do_not.install=no instalar
|
||||
repository=repositorio
|
||||
repository=repositorio
|
||||
details=detalles
|
||||
@@ -156,4 +156,5 @@ publisher.verified=verificato
|
||||
mirror=specchio
|
||||
emulator=emulatore
|
||||
do_not.install=non installare
|
||||
repository=deposito
|
||||
repository=deposito
|
||||
details=dettagli
|
||||
@@ -203,4 +203,5 @@ publisher.verified=verificado
|
||||
mirror=espelho
|
||||
emulator=emulador
|
||||
do_not.install=não instalar
|
||||
repository=repositório
|
||||
repository=repositório
|
||||
details=detalhes
|
||||
6
setup.py
6
setup.py
@@ -3,11 +3,11 @@ import os
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
DESCRIPTION = (
|
||||
"Graphical interface to manage Flatpak, Snap, AppImage and AUR packages"
|
||||
"Graphical interface to manage Flatpak, Snap, AppImage, AUR and Web applications"
|
||||
)
|
||||
|
||||
AUTHOR = "Vinicius Moreira"
|
||||
AUTHOR_EMAIL = "vinicius_fmoreira@hotmail.com"
|
||||
AUTHOR = "bauh developers"
|
||||
AUTHOR_EMAIL = "bauh4linux@gmail.com"
|
||||
NAME = 'bauh'
|
||||
URL = "https://github.com/vinifmor/" + NAME
|
||||
|
||||
|
||||
Reference in New Issue
Block a user