def installer(): """ Create an installer for your app """ require_existing_project() if not exists(path('${freeze_dir}')): raise FbsError( 'It seems your app has not yet been frozen. Please run:\n' ' fbs freeze') linux_distribution_not_supported_msg = \ "Your Linux distribution is not supported, sorry. " \ "You can run `fbs buildvm` followed by `fbs runvm` to start a Docker " \ "VM of a supported distribution." try: installer_fname = SETTINGS['installer'] except KeyError: if is_linux(): raise FbsError(linux_distribution_not_supported_msg) raise out_file = join('target', installer_fname) msg_parts = ['Created %s.' % out_file] if is_windows(): from fbs.installer.windows import create_installer_windows create_installer_windows() elif is_mac(): from fbs.installer.mac import create_installer_mac create_installer_mac() elif is_linux(): app_name = SETTINGS['app_name'] if is_ubuntu(): from fbs.installer.ubuntu import create_installer_ubuntu create_installer_ubuntu() install_cmd = 'sudo dpkg -i ' + out_file remove_cmd = 'sudo dpkg --purge ' + app_name elif is_arch_linux(): from fbs.installer.arch import create_installer_arch create_installer_arch() install_cmd = 'sudo pacman -U ' + out_file remove_cmd = 'sudo pacman -R ' + app_name elif is_fedora(): from fbs.installer.fedora import create_installer_fedora create_installer_fedora() install_cmd = 'sudo dnf install ' + out_file remove_cmd = 'sudo dnf remove ' + app_name else: raise FbsError(linux_distribution_not_supported_msg) msg_parts.append( 'You can for instance install it via the following command:\n' ' %s\n' 'This places it in /opt/%s. To uninstall it again, you can use:\n' ' %s' % (install_cmd, app_name, remove_cmd)) else: raise FbsError('Unsupported OS') _LOG.info(' '.join(msg_parts))
def freeze(debug=False): """ Compile your application to a standalone executable """ # Import respective functions late to avoid circular import # fbs <-> fbs.freeze.X. app_name = SETTINGS['app_name'] if is_mac(): from fbs.freeze.mac import freeze_mac freeze_mac(debug=debug) executable = 'target/%s.app/Contents/MacOS/%s' % (app_name, app_name) else: executable = join('target', app_name, app_name) if is_windows(): from fbs.freeze.windows import freeze_windows freeze_windows(debug=debug) executable += '.exe' elif is_linux(): if is_ubuntu(): from fbs.freeze.ubuntu import freeze_ubuntu freeze_ubuntu(debug=debug) elif is_arch_linux(): from fbs.freeze.arch import freeze_arch freeze_arch(debug=debug) elif is_fedora(): from fbs.freeze.fedora import freeze_fedora freeze_fedora(debug=debug) else: from fbs.freeze.linux import freeze_linux freeze_linux(debug=debug) else: raise RuntimeError('Unsupported OS') _LOG.info( "Done. You can now run `%s`. If that doesn't work, see " "https://build-system.fman.io/troubleshooting.", executable)
def freeze(debug=False): """ Compile your application to a standalone executable """ # Import respective functions late to avoid circular import # fbs <-> fbs.freeze.X: if is_windows(): from fbs.freeze.windows import freeze_windows freeze_windows(debug=debug) elif is_mac(): from fbs.freeze.mac import freeze_mac freeze_mac(debug=debug) elif is_linux(): if is_ubuntu(): from fbs.freeze.ubuntu import freeze_ubuntu freeze_ubuntu(debug=debug) elif is_arch_linux(): from fbs.freeze.arch import freeze_arch freeze_arch(debug=debug) elif is_fedora(): from fbs.freeze.fedora import freeze_fedora freeze_fedora(debug=debug) else: from fbs.freeze.linux import freeze_linux freeze_linux(debug=debug) else: raise RuntimeError('Unsupported OS')
def init(project_dir): """ Call this if you are not invoking `python -m fbs` or fbs.cmdline.main(). """ SETTINGS['project_dir'] = abspath(project_dir) activate_profile('base') activate_profile(platform.name().lower()) if is_linux(): if is_ubuntu(): activate_profile('ubuntu') elif is_arch_linux(): activate_profile('arch') elif is_fedora(): activate_profile('fedora')
def get_default_profiles(): result = ['base'] # The "secret" profile lets the user store sensitive settings such as # passwords in src/build/settings/secret.json. When using Git, the user can # exploit this by adding secret.json to .gitignore, thus preventing it from # being uploaded to services such as GitHub. result.append('secret') result.append(platform.name().lower()) if is_linux(): if is_ubuntu(): result.append('ubuntu') elif is_arch_linux(): result.append('arch') elif is_fedora(): result.append('fedora') return result
def test_freeze_installer(self): freeze() if is_mac(): executable = path('${freeze_dir}/Contents/MacOS/${app_name}') elif is_windows(): executable = path('${freeze_dir}/${app_name}.exe') else: executable = path('${freeze_dir}/${app_name}') self.assertTrue(exists(executable), executable + ' does not exist') installer() self.assertTrue(exists(path('target/${installer}'))) if is_linux(): applications_dir = path('target/installer/usr/share/applications') self.assertEqual(['MyApp.desktop'], listdir(applications_dir)) with open(join(applications_dir, 'MyApp.desktop')) as f: self.assertIn('MyApp', f.read())
def freeze(debug=False): """ Compile your code to a standalone executable """ require_existing_project() if not _has_module('PyInstaller'): raise FbsError("Could not find PyInstaller. Maybe you need to:\n" " pip install PyInstaller==3.4") version = SETTINGS['version'] if not is_valid_version(version): raise FbsError( 'Invalid version detected in settings. It should be three\n' 'numbers separated by dots, such as "1.2.3". You have:\n\t"%s".\n' 'Usually, this can be fixed in src/build/settings/base.json.' % version) # Import respective functions late to avoid circular import # fbs <-> fbs.freeze.X. app_name = SETTINGS['app_name'] if is_mac(): from fbs.freeze.mac import freeze_mac freeze_mac(debug=debug) executable = 'target/%s.app/Contents/MacOS/%s' % (app_name, app_name) else: executable = join('target', app_name, app_name) if is_windows(): from fbs.freeze.windows import freeze_windows freeze_windows(debug=debug) executable += '.exe' elif is_linux(): if is_ubuntu(): from fbs.freeze.ubuntu import freeze_ubuntu freeze_ubuntu(debug=debug) elif is_arch_linux(): from fbs.freeze.arch import freeze_arch freeze_arch(debug=debug) elif is_fedora(): from fbs.freeze.fedora import freeze_fedora freeze_fedora(debug=debug) else: from fbs.freeze.linux import freeze_linux freeze_linux(debug=debug) else: raise FbsError('Unsupported OS') _LOG.info( "Done. You can now run `%s`. If that doesn't work, see " "https://build-system.fman.io/troubleshooting.", executable)
def freeze(debug=False): """ Compile your code to a standalone executable """ require_existing_project() if not _has_module('PyInstaller'): raise FbsError( "Could not find PyInstaller. Maybe you need to:\n" " pip install PyInstaller==3.4" ) # Import respective functions late to avoid circular import # fbs <-> fbs.freeze.X. app_name = SETTINGS['app_name'] if is_mac(): from fbs.freeze.mac import freeze_mac freeze_mac(debug=debug) executable = 'target/%s.app/Contents/MacOS/%s' % (app_name, app_name) else: executable = join('target', app_name, app_name) if is_windows(): from fbs.freeze.windows import freeze_windows freeze_windows(debug=debug) executable += '.exe' elif is_linux(): if is_ubuntu(): from fbs.freeze.ubuntu import freeze_ubuntu freeze_ubuntu(debug=debug) elif is_arch_linux(): from fbs.freeze.arch import freeze_arch freeze_arch(debug=debug) elif is_fedora(): from fbs.freeze.fedora import freeze_fedora freeze_fedora(debug=debug) else: from fbs.freeze.linux import freeze_linux freeze_linux(debug=debug) else: raise FbsError('Unsupported OS') _LOG.info( "Done. You can now run `%s`. If that doesn't work, see " "https://build-system.fman.io/troubleshooting.", executable )
def installer(): """ Create an installer for your app """ require_existing_project() out_file = join('target', SETTINGS['installer']) msg_parts = ['Created %s.' % out_file] if is_windows(): from fbs.installer.windows import create_installer_windows create_installer_windows() elif is_mac(): from fbs.installer.mac import create_installer_mac create_installer_mac() elif is_linux(): app_name = SETTINGS['app_name'] if is_ubuntu(): from fbs.installer.ubuntu import create_installer_ubuntu create_installer_ubuntu() install_cmd = 'sudo dpkg -i ' + out_file remove_cmd = 'sudo dpkg --purge ' + app_name elif is_arch_linux(): from fbs.installer.arch import create_installer_arch create_installer_arch() install_cmd = 'sudo pacman -U ' + out_file remove_cmd = 'sudo pacman -R ' + app_name elif is_fedora(): from fbs.installer.fedora import create_installer_fedora create_installer_fedora() install_cmd = 'sudo dnf install ' + out_file remove_cmd = 'sudo dnf remove ' + app_name else: raise FbsError('Unsupported Linux distribution') msg_parts.append( 'You can for instance install it via the following command:\n' ' %s\n' 'This places it in /opt/%s. To uninstall it again, you can use:\n' ' %s' % (install_cmd, app_name, remove_cmd)) else: raise FbsError('Unsupported OS') _LOG.info(' '.join(msg_parts))
def _upload_repo(username, password): status, response = _server.post_json('start_upload', { 'username': username, 'password': password }) unexpected_response = lambda: FbsError( 'Received unexpected server response %d:\n%s' % (status, response)) if status // 2 != 100: raise unexpected_response() try: data = json.loads(response) except ValueError: raise unexpected_response() try: credentials = data['bucket'], data['key'], data['secret'] except KeyError: raise unexpected_response() dest_path = lambda p: username + '/' + SETTINGS['app_name'] + '/' + p installer = path('target/${installer}') installer_dest = dest_path(basename(installer)) upload_file(installer, installer_dest, *credentials) uploaded = [installer_dest] if is_linux(): repo_dest = dest_path(SETTINGS['repo_subdir']) uploaded.extend( upload_folder_contents(path('target/repo'), repo_dest, *credentials)) pubkey_dest = dest_path('public-key.gpg') upload_file(path('src/sign/linux/public-key.gpg'), pubkey_dest, *credentials) uploaded.append(pubkey_dest) status, response = _server.post_json('complete_upload', { 'username': username, 'password': password, 'files': uploaded }) if status != 201: raise unexpected_response()
def installer(): """ Create an installer for your app """ if is_windows(): from fbs.installer.windows import create_installer_windows create_installer_windows() elif is_mac(): from fbs.installer.mac import create_installer_mac create_installer_mac() elif is_linux(): if is_ubuntu(): from fbs.installer.ubuntu import create_installer_ubuntu create_installer_ubuntu() elif is_arch_linux(): from fbs.installer.arch import create_installer_arch create_installer_arch() elif is_fedora(): from fbs.installer.fedora import create_installer_fedora create_installer_fedora() else: raise RuntimeError('Unsupported Linux distribution') else: raise RuntimeError('Unsupported OS')
def upload(): """ Upload installer and repository to fbs.sh """ require_existing_project() try: username = SETTINGS['fbs_user'] password = SETTINGS['fbs_pass'] except KeyError as e: raise FbsError( 'Could not find setting "%s". You may want to invoke one of the ' 'following:\n' ' * fbs register\n' ' * fbs login' % (e.args[0],) ) from None _upload_repo(username, password) app_name = SETTINGS['app_name'] url = lambda p: 'https://fbs.sh/%s/%s/%s' % (username, app_name, p) message = 'Done! ' pkg_name = app_name.lower() installer_url = url(SETTINGS['installer']) if is_linux(): message += 'Your users can now install your app via the following ' \ 'commands:\n' format_commands = lambda *cmds: '\n'.join(' ' + c for c in cmds) repo_url = url(SETTINGS['repo_subdir']) if is_ubuntu(): message += format_commands( "sudo apt-get install apt-transport-https", "wget -qO - %s | sudo apt-key add -" % url('public-key.gpg'), "echo 'deb [arch=amd64] %s stable main' | " % repo_url + "sudo tee /etc/apt/sources.list.d/%s.list" % pkg_name, "sudo apt-get update", "sudo apt-get install " + pkg_name ) message += '\nIf they already have your app installed, they can ' \ 'force an immediate update via:\n' message += format_commands( 'sudo apt-get update ' '-o Dir::Etc::sourcelist="/etc/apt/sources.list.d/%s.list" ' '-o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0"' % pkg_name, 'sudo apt-get install --only-upgrade ' + pkg_name ) elif is_arch_linux(): message += format_commands( "curl -O %s && " % url('public-key.gpg') + "sudo pacman-key --add public-key.gpg && " + "sudo pacman-key --lsign-key %s && " % SETTINGS['gpg_key'] + "rm public-key.gpg", "echo -e '\\n[%s]\\nServer = %s' | sudo tee -a /etc/pacman.conf" % (app_name, repo_url), "sudo pacman -Syu " + pkg_name ) message += '\nIf they already have your app installed, they can ' \ 'force an immediate update via:\n' message += format_commands('sudo pacman -Syu --needed ' + pkg_name) elif is_fedora(): message += format_commands( "sudo rpm -v --import " + url('public-key.gpg'), "sudo dnf config-manager --add-repo %s/%s.repo" % (repo_url, app_name), "sudo dnf install " + pkg_name ) message += "\n(On CentOS, replace 'dnf' by 'yum' and " \ "'dnf config-manager' by 'yum-config-manager'.)" message += '\nIf they already have your app installed, they can ' \ 'force an immediate update via:\n' message += \ format_commands('sudo dnf upgrade %s --refresh' % pkg_name) message += '\nThis is for Fedora. For CentOS, use:\n' message += format_commands( 'sudo yum clean all && sudo yum upgrade ' + pkg_name ) else: raise FbsError('This Linux distribution is not supported.') message += '\nFinally, your users can also install without automatic ' \ 'updates by downloading:\n ' + installer_url extra = {'wrap': False} else: message += 'Your users can now download and install %s.' % installer_url extra = None _LOG.info(message, extra=extra)
def createConfigFile() -> str: """ Creates config file and returns its location. Expects that the config file does not exist """ userDirPath = pathlib.Path.home() if platform.is_windows(): defautlDataPath = userDirPath.joinpath("AppData", "Local") elif platform.is_linux(): defautlDataPath = userDirPath.joinpath(".config") else: from utils.DialogCollection import errorOccured errorOccured("Platform is not known. App is not supported on your" "platform") raise RuntimeError( "Platform is not known. App is not supported on your" "platform") if os.path.exists(defautlDataPath): # creating folder and empty config file defautlDataPath = defautlDataPath.joinpath("STManager") configPath = defautlDataPath else: # creating folder and empty config file altDataPath = userDirPath.joinpath(".stmanager") configPath = altDataPath try: os.mkdir(configPath) except FileExistsError: pass configPath = configPath.joinpath(ConfigPaths.CONFIG_FILE_FILENAME) try: from utils.DialogCollection import getFolderPath, askNewUser photoDirectory = getFolderPath() newLogin, newPassword = askNewUser() while newLogin is None or newPassword is None: newLogin, newPassword = askNewUser() newConfigFileContent = { "configuration": { "loggedUser": newLogin, "scanner_mode": False, "savePath": photoDirectory, }, "userData": [{ "username": newLogin, "password": newPassword, "created": time.strftime("%d-%m-%Y-%H_%M_%S"), "items": [], }], } with open(configPath, "w") as configFile: configFile.write(json.dumps(newConfigFileContent)) return configPath except PermissionError: from utils.DialogCollection import errorOccured errorOccured("Cannot create config file!! Check the permissions " "for the application") return None
# look for config file in appData if os.path.exists(found := p.joinpath( "AppData", "Local", "STManager", ConfigPaths.CONFIG_FILE_FILENAME, )): ConfigPaths.CONFIG_FILE_PATH = found return found elif os.path.exists(found := p.joinpath( ".stmanager", ConfigPaths.CONFIG_FILE_FILENAME)): ConfigPaths.CONFIG_FILE_PATH = found return found return None # config file not found -> returning None elif platform.is_linux(): if os.path.exists(found := p.joinpath( ".config", "STManager", ConfigPaths.CONFIG_FILE_FILENAME)): ConfigPaths.CONFIG_FILE_PATH = found return found elif os.path.exists(found := p.joinpath( ".stmanager", ConfigPaths.CONFIG_FILE_FILENAME)): ConfigPaths.CONFIG_FILE_PATH = found return found return None from utils.DialogCollection import errorOccured errorOccured("Platform is not known. App is not supported on your" "platform")