mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Updater rework
This commit is contained in:
parent
ec6f79a56a
commit
77935c8761
26 changed files with 101 additions and 84 deletions
|
@ -4,6 +4,8 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
import io.xpipe.app.util.JsonConfigHelper;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -13,9 +15,9 @@ import java.util.function.Supplier;
|
|||
|
||||
public class AppCache {
|
||||
|
||||
private static Path getBasePath() {
|
||||
return AppProperties.get().getDataDir().resolve("cache");
|
||||
}
|
||||
@Getter
|
||||
@Setter
|
||||
private static Path basePath;
|
||||
|
||||
private static Path getPath(String key) {
|
||||
var name = key + ".cache";
|
||||
|
|
|
@ -44,6 +44,8 @@ public class AppProperties {
|
|||
boolean locatorVersionCheck;
|
||||
boolean isTest;
|
||||
boolean autoAcceptEula;
|
||||
UUID uuid;
|
||||
boolean initialLaunch;
|
||||
|
||||
public AppProperties() {
|
||||
var appDir = Path.of(System.getProperty("user.dir")).resolve("app");
|
||||
|
@ -113,6 +115,15 @@ public class AppProperties {
|
|||
autoAcceptEula = Optional.ofNullable(System.getProperty("io.xpipe.app.acceptEula"))
|
||||
.map(Boolean::parseBoolean)
|
||||
.orElse(false);
|
||||
AppCache.setBasePath(dataDir.resolve("cache"));
|
||||
UUID id = AppCache.getNonNull("uuid", UUID.class, null);
|
||||
if (id == null) {
|
||||
uuid = UUID.randomUUID();
|
||||
AppCache.update("uuid", uuid);
|
||||
} else {
|
||||
uuid = id;
|
||||
}
|
||||
initialLaunch = AppCache.getNonNull("lastBuild", String.class, () -> null) == null;
|
||||
}
|
||||
|
||||
private static boolean isJUnitTest() {
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Value
|
||||
public class AppState {
|
||||
|
||||
private static AppState INSTANCE;
|
||||
|
||||
UUID userId;
|
||||
boolean initialLaunch;
|
||||
|
||||
@NonFinal
|
||||
@Setter
|
||||
String userName;
|
||||
|
||||
@NonFinal
|
||||
@Setter
|
||||
String userEmail;
|
||||
|
||||
public AppState() {
|
||||
UUID id = AppCache.getNonNull("userId", UUID.class, null);
|
||||
if (id == null) {
|
||||
initialLaunch = AppCache.getNonNull("lastBuild", String.class, () -> null) == null;
|
||||
userId = UUID.randomUUID();
|
||||
AppCache.update("userId", userId);
|
||||
} else {
|
||||
userId = id;
|
||||
initialLaunch = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
if (INSTANCE != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
INSTANCE = new AppState();
|
||||
}
|
||||
|
||||
public static AppState get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.core.check;
|
|||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.core.AppStyle;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
|
@ -35,7 +34,7 @@ public class AppAvCheck {
|
|||
|
||||
public static void check() throws Throwable {
|
||||
// Only show this on first launch on windows
|
||||
if (OsType.getLocal() != OsType.WINDOWS || !AppState.get().isInitialLaunch()) {
|
||||
if (OsType.getLocal() != OsType.WINDOWS || !AppProperties.get().isInitialLaunch()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,12 +105,17 @@ public abstract class OperationMode {
|
|||
return;
|
||||
}
|
||||
|
||||
// Handle any startup uncaught errors
|
||||
if (OperationMode.isInStartup() && thread.threadId() == 1) {
|
||||
ex.printStackTrace();
|
||||
OperationMode.halt(1);
|
||||
}
|
||||
|
||||
ErrorEvent.fromThrowable(ex).unhandled(true).build().handle();
|
||||
});
|
||||
|
||||
TrackEvent.info("Initial setup");
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
XPipeSession.init(AppProperties.get().getBuildUuid());
|
||||
AppUserDirectoryCheck.check();
|
||||
AppTempCheck.check();
|
||||
|
|
|
@ -56,7 +56,7 @@ public abstract class PlatformMode extends OperationMode {
|
|||
|
||||
// If we downloaded an update, and decided to no longer automatically update, don't remind us!
|
||||
// You can still update manually in the about tab
|
||||
if (AppPrefs.get().automaticallyUpdate().get()) {
|
||||
if (AppPrefs.get().automaticallyUpdate().get() || AppPrefs.get().checkForSecurityUpdates().get()) {
|
||||
UpdateAvailableAlert.showIfNeeded();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ public class GuiErrorHandlerBase {
|
|||
try {
|
||||
PlatformState.initPlatformOrThrow();
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
AppExtensionManager.init(false);
|
||||
AppI18n.init();
|
||||
AppStyle.init();
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.app.issue;
|
|||
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.update.XPipeDistributionType;
|
||||
|
@ -145,6 +144,11 @@ public class SentryErrorHandler implements ErrorHandler {
|
|||
AppPrefs.get() != null
|
||||
? AppPrefs.get().automaticallyUpdate().getValue().toString()
|
||||
: "unknown");
|
||||
s.setTag(
|
||||
"securityUpdatesEnabled",
|
||||
AppPrefs.get() != null
|
||||
? AppPrefs.get().checkForSecurityUpdates().getValue().toString()
|
||||
: "unknown");
|
||||
s.setTag("initError", String.valueOf(OperationMode.isInStartup()));
|
||||
s.setTag(
|
||||
"developerMode",
|
||||
|
@ -177,11 +181,7 @@ public class SentryErrorHandler implements ErrorHandler {
|
|||
}
|
||||
|
||||
var user = new User();
|
||||
user.setId(AppState.get().getUserId().toString());
|
||||
if (ee.isShouldSendDiagnostics()) {
|
||||
user.setEmail(AppState.get().getUserEmail());
|
||||
user.setUsername(AppState.get().getUserName());
|
||||
}
|
||||
user.setId(AppProperties.get().getUuid().toString());
|
||||
s.setUser(user);
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,6 @@ public class SentryErrorHandler implements ErrorHandler {
|
|||
// Assume that this object is wrapped by a synchronous error handler
|
||||
if (!init) {
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
if (AppProperties.get().getSentryUrl() != null) {
|
||||
Sentry.init(options -> {
|
||||
options.setDsn(AppProperties.get().getSentryUrl());
|
||||
|
|
|
@ -40,7 +40,6 @@ public class TerminalErrorHandler extends GuiErrorHandlerBase implements ErrorHa
|
|||
private void handleGui(ErrorEvent event) {
|
||||
try {
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
AppExtensionManager.init(false);
|
||||
AppI18n.init();
|
||||
AppStyle.init();
|
||||
|
|
|
@ -107,6 +107,8 @@ public class AppPrefs {
|
|||
.property(new SimpleBooleanProperty(false)).key("enableTerminalLogging").valueClass(Boolean.class).licenseFeatureId("logging").build());
|
||||
final BooleanProperty enforceWindowModality =
|
||||
mapLocal(new SimpleBooleanProperty(false), "enforceWindowModality", Boolean.class, false);
|
||||
final BooleanProperty checkForSecurityUpdates =
|
||||
mapLocal(new SimpleBooleanProperty(true), "checkForSecurityUpdates", Boolean.class, false);
|
||||
final BooleanProperty condenseConnectionDisplay =
|
||||
mapLocal(new SimpleBooleanProperty(false), "condenseConnectionDisplay", Boolean.class, false);
|
||||
final BooleanProperty showChildCategoriesInParentCategory =
|
||||
|
@ -153,6 +155,10 @@ public class AppPrefs {
|
|||
final BooleanProperty disableApiAuthentication =
|
||||
mapLocal(new SimpleBooleanProperty(false), "disableApiAuthentication", Boolean.class, false);
|
||||
|
||||
public ObservableBooleanValue checkForSecurityUpdates() {
|
||||
return checkForSecurityUpdates;
|
||||
}
|
||||
|
||||
public ObservableBooleanValue enableTerminalLogging() {
|
||||
return enableTerminalLogging;
|
||||
}
|
||||
|
@ -510,7 +516,7 @@ public class AppPrefs {
|
|||
if (rdpClientType.get() == null) {
|
||||
rdpClientType.setValue(ExternalRdpClientType.determineDefault());
|
||||
}
|
||||
if (AppState.get().isInitialLaunch()) {
|
||||
if (AppProperties.get().isInitialLaunch()) {
|
||||
performanceMode.setValue(XPipeDistributionType.get() == XPipeDistributionType.WEBTOP);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ public class SecurityCategory extends AppPrefsCategory {
|
|||
var builder = new OptionsBuilder();
|
||||
builder.addTitle("securityPolicy")
|
||||
.sub(new OptionsBuilder()
|
||||
.pref(prefs.checkForSecurityUpdates)
|
||||
.addToggle(prefs.checkForSecurityUpdates)
|
||||
.nameAndDescription("alwaysConfirmElevation")
|
||||
.addToggle(prefs.alwaysConfirmElevation)
|
||||
.nameAndDescription("dontCachePasswords")
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package io.xpipe.app.update;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.HttpHelper;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
@ -15,6 +18,9 @@ import org.kohsuke.github.authorization.AuthorizationProvider;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -112,30 +118,42 @@ public class AppDownloads {
|
|||
}
|
||||
}
|
||||
|
||||
public static Optional<GHRelease> getTopReleaseIncludingPreRelease() throws IOException {
|
||||
var repo = getRepository();
|
||||
return Optional.ofNullable(repo.listReleases().iterator().next());
|
||||
private static String queryLatestVersion() throws Exception {
|
||||
var req = JsonNodeFactory.instance.objectNode();
|
||||
req.put("securityOnly", !AppPrefs.get().automaticallyUpdate().get());
|
||||
req.put("ptb", AppProperties.get().isStaging());
|
||||
req.put("os", OsType.getLocal().getId());
|
||||
req.put("arch", AppProperties.get().getArch());
|
||||
req.put("uuid", AppProperties.get().getUuid().toString());
|
||||
req.put("version", AppProperties.get().getVersion());
|
||||
var url = URI.create("https://api.xpipe.io/version");
|
||||
|
||||
var builder = HttpRequest.newBuilder();
|
||||
var httpRequest = builder.uri(url)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(req.toPrettyString()))
|
||||
.build();
|
||||
var client = HttpClient.newHttpClient();
|
||||
var response = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() != 200) {
|
||||
throw new IOException(response.body());
|
||||
}
|
||||
|
||||
var json = JacksonMapper.getDefault().readTree(response.body());
|
||||
var ver = json.required("version").asText();
|
||||
return ver;
|
||||
}
|
||||
|
||||
public static Optional<GHRelease> getMarkedLatestRelease() throws IOException {
|
||||
public static Optional<GHRelease> getLatestRelease() throws Exception {
|
||||
var ver = queryLatestVersion();
|
||||
var repo = getRepository();
|
||||
return Optional.ofNullable(repo.getLatestRelease());
|
||||
var rel = repo.getReleaseByTagName(ver);
|
||||
return Optional.ofNullable(rel);
|
||||
}
|
||||
|
||||
public static Optional<GHRelease> getLatestSuitableRelease() throws IOException {
|
||||
public static Optional<GHRelease> getLatestSuitableRelease() throws Exception {
|
||||
try {
|
||||
var preIncluding = getTopReleaseIncludingPreRelease();
|
||||
// If we are currently running a prerelease, always return this as the suitable release!
|
||||
if (preIncluding.isPresent()
|
||||
&& preIncluding.get().isPrerelease()
|
||||
&& AppProperties.get()
|
||||
.getVersion()
|
||||
.equals(preIncluding.get().getTagName())) {
|
||||
return preIncluding;
|
||||
}
|
||||
|
||||
return getMarkedLatestRelease();
|
||||
} catch (IOException e) {
|
||||
return getLatestRelease();
|
||||
} catch (Exception e) {
|
||||
throw ErrorEvent.expected(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ public abstract class UpdateHandler {
|
|||
ThreadHelper.sleep(Duration.ofMinutes(5).toMillis());
|
||||
event("Starting background updater thread");
|
||||
while (true) {
|
||||
if (AppPrefs.get().automaticallyUpdate().get()) {
|
||||
if (AppPrefs.get().automaticallyUpdate().get() || AppPrefs.get().checkForSecurityUpdates().get()) {
|
||||
event("Performing background update");
|
||||
refreshUpdateCheckSilent();
|
||||
prepareUpdate();
|
||||
|
|
|
@ -94,6 +94,7 @@ open module io.xpipe.app {
|
|||
|
||||
// For debugging
|
||||
requires jdk.jdwp.agent;
|
||||
requires java.net.http;
|
||||
|
||||
uses TerminalLauncher;
|
||||
uses io.xpipe.app.ext.ActionProvider;
|
||||
|
|
|
@ -545,3 +545,5 @@ scriptsIntroText=Du kan køre scripts ved shell-init, i filbrowseren og efter be
|
|||
scriptsIntroBottomTitle=Brug af scripts
|
||||
scriptsIntroBottomText=Der er en række eksempler på scripts til at starte med. Du kan klikke på redigeringsknappen for de enkelte scripts for at se, hvordan de er implementeret. Scripts skal aktiveres for at køre og dukke op i menuer, der er et skifte på hvert script til det.
|
||||
scriptsIntroStart=Kom godt i gang
|
||||
checkForSecurityUpdates=Tjek for sikkerhedsopdateringer
|
||||
checkForSecurityUpdatesDescription=XPipe kan tjekke for potentielle sikkerhedsopdateringer separat fra normale funktionsopdateringer. Når dette er aktiveret, vil i det mindste vigtige sikkerhedsopdateringer blive anbefalet til installation, selv om den normale opdateringskontrol er deaktiveret.\n\nHvis du deaktiverer denne indstilling, vil der ikke blive udført nogen ekstern versionsanmodning, og hun vil ikke få besked om nogen sikkerhedsopdateringer.
|
||||
|
|
|
@ -539,3 +539,5 @@ scriptsIntroText=Du kannst Skripte bei Shell-Init, im Dateibrowser und bei Bedar
|
|||
scriptsIntroBottomTitle=Skripte verwenden
|
||||
scriptsIntroBottomText=Für den Anfang gibt es eine Reihe von Beispielskripten. Du kannst auf die Bearbeitungsschaltfläche der einzelnen Skripte klicken, um zu sehen, wie sie implementiert sind. Skripte müssen aktiviert werden, damit sie ausgeführt und in Menüs angezeigt werden.
|
||||
scriptsIntroStart=Anfangen
|
||||
checkForSecurityUpdates=Nach Sicherheitsupdates suchen
|
||||
checkForSecurityUpdatesDescription=XPipe kann getrennt von den normalen Funktionsupdates auf mögliche Sicherheitsupdates prüfen. Wenn dies aktiviert ist, werden zumindest wichtige Sicherheitsupdates zur Installation empfohlen, auch wenn die normale Updateprüfung deaktiviert ist.\n\nWenn du diese Einstellung deaktivierst, wird keine externe Versionsabfrage durchgeführt und du wirst nicht über Sicherheitsaktualisierungen benachrichtigt.
|
||||
|
|
|
@ -545,3 +545,5 @@ scriptsIntroText=You can run scripts on shell init, in the file browser, and on
|
|||
scriptsIntroBottomTitle=Using scripts
|
||||
scriptsIntroBottomText=There are a variety of sample scripts to start out. You can click on the edit button of the individual scripts to see how they are implemented. Scripts have to be enabled to run and show up in menus, there is a toggle on every script for that.
|
||||
scriptsIntroStart=Get started
|
||||
checkForSecurityUpdates=Check for security updates
|
||||
checkForSecurityUpdatesDescription=XPipe can check for potential security updates separately from normal feature updates. When this is enabled, at least important security updates will be recommended for installation even is the normal update check is disabled.\n\nDisabling this setting will result in no external version request being performed, and she won't be notified about any security updates.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Puedes ejecutar scripts en shell init, en el explorador de arch
|
|||
scriptsIntroBottomTitle=Utilizar guiones
|
||||
scriptsIntroBottomText=Hay una variedad de scripts de ejemplo para empezar. Puedes hacer clic en el botón de edición de los scripts individuales para ver cómo se implementan. Los scripts tienen que estar habilitados para ejecutarse y aparecer en los menús, hay un conmutador en cada script para ello.
|
||||
scriptsIntroStart=Empezar
|
||||
checkForSecurityUpdates=Buscar actualizaciones de seguridad
|
||||
checkForSecurityUpdatesDescription=XPipe puede buscar posibles actualizaciones de seguridad separadamente de las actualizaciones normales de funciones. Cuando esta opción está activada, se recomendará la instalación de al menos las actualizaciones de seguridad importantes, aunque la comprobación de actualizaciones normales esté desactivada.\n\nSi desactivas esta opción, no se realizará ninguna solicitud de versión externa y no se le notificará ninguna actualización de seguridad.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Tu peux exécuter des scripts sur le shell init, dans le naviga
|
|||
scriptsIntroBottomTitle=Utilisation de scripts
|
||||
scriptsIntroBottomText=Il existe une variété d'exemples de scripts pour commencer. Tu peux cliquer sur le bouton d'édition des scripts individuels pour voir comment ils sont mis en œuvre. Les scripts doivent être activés pour être exécutés et apparaître dans les menus.
|
||||
scriptsIntroStart=Commence
|
||||
checkForSecurityUpdates=Vérifier les mises à jour de sécurité
|
||||
checkForSecurityUpdatesDescription=XPipe peut vérifier les mises à jour de sécurité potentielles séparément des mises à jour normales des fonctionnalités. Lorsque cette fonction est activée, il est recommandé d'installer au moins les mises à jour de sécurité importantes, même si la vérification normale des mises à jour est désactivée.\n\nEn désactivant ce paramètre, aucune demande de version externe ne sera effectuée, et elle ne sera pas informée des mises à jour de sécurité.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Puoi eseguire gli script all'avvio della shell, nel browser dei
|
|||
scriptsIntroBottomTitle=Utilizzo di script
|
||||
scriptsIntroBottomText=Ci sono diversi esempi di script per iniziare. Puoi cliccare sul pulsante di modifica dei singoli script per vedere come sono stati implementati. Gli script devono essere abilitati per essere eseguiti e visualizzati nei menu; in ogni script è presente una levetta per questo scopo.
|
||||
scriptsIntroStart=Iniziare
|
||||
checkForSecurityUpdates=Controlla gli aggiornamenti di sicurezza
|
||||
checkForSecurityUpdatesDescription=XPipe può verificare la presenza di potenziali aggiornamenti di sicurezza separatamente dai normali aggiornamenti delle funzioni. Se questa opzione è attivata, l'installazione degli aggiornamenti di sicurezza più importanti viene consigliata anche se il normale controllo degli aggiornamenti è disattivato.\n\nDisattivando questa impostazione, non verrà effettuata alcuna richiesta di versione esterna e non verranno notificati gli aggiornamenti di sicurezza.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=シェルinit、ファイルブラウザ、オンデマンド
|
|||
scriptsIntroBottomTitle=スクリプトを使用する
|
||||
scriptsIntroBottomText=スクリプトには様々なサンプルが用意されている。個々のスクリプトの編集ボタンをクリックして、どのように実装されているかを見ることができる。スクリプトを実行してメニューに表示するには、スクリプトを有効にする必要がある。
|
||||
scriptsIntroStart=始める
|
||||
checkForSecurityUpdates=セキュリティアップデートを確認する
|
||||
checkForSecurityUpdatesDescription=XPipeは、通常の機能アップデートとは別に、潜在的なセキュリティアップデートをチェックすることができる。これを有効にすると、通常のアップデートチェックが無効になっている場合でも、少なくとも重要なセキュリティアップデートのインストールが推奨される。\n\nこの設定を無効にすると、外部バージョン要求が実行されなくなり、セキュリティアップデートが通知されなくなる。
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Je kunt scripts uitvoeren op shell init, in de bestandsbrowser
|
|||
scriptsIntroBottomTitle=Scripts gebruiken
|
||||
scriptsIntroBottomText=Er zijn verschillende voorbeeldscripts om mee te beginnen. Je kunt op de bewerkknop van de individuele scripts klikken om te zien hoe ze zijn geïmplementeerd. Scripts moeten worden ingeschakeld om te worden uitgevoerd en om te worden weergegeven in menu's. Elk script heeft daarvoor een schakelaartje.
|
||||
scriptsIntroStart=Aan de slag
|
||||
checkForSecurityUpdates=Controleren op beveiligingsupdates
|
||||
checkForSecurityUpdatesDescription=XPipe kan apart van normale functie-updates controleren op mogelijke beveiligingsupdates. Als dit is ingeschakeld, worden ten minste belangrijke beveiligingsupdates aanbevolen voor installatie, zelfs als de normale updatecontrole is uitgeschakeld.\n\nAls je deze instelling uitschakelt, wordt er geen externe versie opgevraagd en krijg je geen melding van beveiligingsupdates.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Podes executar scripts no shell init, no navegador de ficheiros
|
|||
scriptsIntroBottomTitle=Utilizar scripts
|
||||
scriptsIntroBottomText=Há uma variedade de exemplos de scripts para começares. Podes clicar no botão de edição dos scripts individuais para veres como são implementados. Os scripts têm de ser activados para serem executados e aparecerem nos menus; para isso, há uma opção em cada script.
|
||||
scriptsIntroStart=Começa a trabalhar
|
||||
checkForSecurityUpdates=Verifica se existem actualizações de segurança
|
||||
checkForSecurityUpdatesDescription=O XPipe pode verificar potenciais actualizações de segurança separadamente das actualizações de funcionalidades normais. Quando esta opção está activada, pelo menos as actualizações de segurança importantes serão recomendadas para instalação, mesmo que a verificação de atualização normal esteja desactivada.\n\nSe desativar esta definição, não será efectuado qualquer pedido de versão externa e não será notificado sobre quaisquer actualizações de segurança.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=Ты можешь запускать скрипты в shell in
|
|||
scriptsIntroBottomTitle=Использование скриптов
|
||||
scriptsIntroBottomText=Для начала есть множество примеров скриптов. Ты можешь нажать на кнопку редактирования отдельных скриптов, чтобы посмотреть, как они реализованы. Скрипты должны быть включены, чтобы запускаться и отображаться в меню, для этого в каждом скрипте есть тумблер.
|
||||
scriptsIntroStart=Приступай к работе
|
||||
checkForSecurityUpdates=Проверьте наличие обновлений безопасности
|
||||
checkForSecurityUpdatesDescription=XPipe может проверять потенциальные обновления безопасности отдельно от обычных обновлений функций. Когда эта функция включена, по крайней мере важные обновления безопасности будут рекомендованы к установке, даже если обычная проверка обновлений отключена.\n\nОтключение этой настройки приведет к тому, что внешний запрос версии не будет выполняться, и она не будет получать уведомления о каких-либо обновлениях безопасности.
|
||||
|
|
|
@ -527,3 +527,5 @@ scriptsIntroText=Komut dosyalarını kabuk başlangıcında, dosya tarayıcısı
|
|||
scriptsIntroBottomTitle=Komut dosyalarını kullanma
|
||||
scriptsIntroBottomText=Başlangıç için çeşitli örnek komut dosyaları vardır. Nasıl uygulandıklarını görmek için tek tek komut dosyalarının düzenleme düğmesine tıklayabilirsiniz. Komut dosyalarının çalışması ve menülerde görünmesi için etkinleştirilmesi gerekir, bunun için her komut dosyasında bir geçiş vardır.
|
||||
scriptsIntroStart=Başlayın
|
||||
checkForSecurityUpdates=Güvenlik güncellemelerini kontrol edin
|
||||
checkForSecurityUpdatesDescription=XPipe olası güvenlik güncellemelerini normal özellik güncellemelerinden ayrı olarak kontrol edebilir. Bu etkinleştirildiğinde, normal güncelleme denetimi devre dışı bırakılsa bile en azından önemli güvenlik güncellemeleri yükleme için önerilecektir.\n\nBu ayarın devre dışı bırakılması, harici sürüm talebinin gerçekleştirilmemesine ve herhangi bir güvenlik güncellemesi hakkında bilgilendirilmemesine neden olacaktır.
|
||||
|
|
|
@ -526,3 +526,5 @@ scriptsIntroText=您可以在 shell init、文件浏览器和按需运行脚本
|
|||
scriptsIntroBottomTitle=使用脚本
|
||||
scriptsIntroBottomText=这里有各种示例脚本供您开始使用。你可以点击各个脚本的编辑按钮,查看它们是如何实现的。脚本必须启用才能运行并显示在菜单中,每个脚本上都有一个切换按钮。
|
||||
scriptsIntroStart=开始使用
|
||||
checkForSecurityUpdates=检查安全更新
|
||||
checkForSecurityUpdatesDescription=XPipe 可与正常功能更新分开检查潜在的安全更新。启用此功能后,即使正常的更新检查被禁用,至少也会推荐安装重要的安全更新。\n\n禁用此设置将导致不执行外部版本请求,也不会通知她任何安全更新。
|
||||
|
|
Loading…
Reference in a new issue