mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-02-18 21:14:01 +08:00
good updater experience (#25724)
* good updater experience
* set params on startup
* no fetch on first loop
* little type hinting
* little more
* update translations
* always set params with valid overlay
* wrap check
* use the param
* more wrapping
* vanish
* cleanup
* remove that
old-commit-hash: c4e63d14ab
This commit is contained in:
@@ -154,18 +154,24 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"PrimeType", PERSISTENT},
|
||||
{"RecordFront", PERSISTENT},
|
||||
{"RecordFrontLock", PERSISTENT}, // for the internal fleet
|
||||
{"ReleaseNotes", PERSISTENT},
|
||||
{"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ShouldDoUpdate", CLEAR_ON_MANAGER_START},
|
||||
{"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"SshEnabled", PERSISTENT},
|
||||
{"SubscriberInfo", PERSISTENT},
|
||||
{"SwitchToBranch", CLEAR_ON_MANAGER_START},
|
||||
{"TermsVersion", PERSISTENT},
|
||||
{"Timezone", PERSISTENT},
|
||||
{"TrainingVersion", PERSISTENT},
|
||||
{"UpdateAvailable", CLEAR_ON_MANAGER_START},
|
||||
{"UpdateFailedCount", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterState", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterFetchAvailable", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterAvailableBranches", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterCurrentDescription", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterCurrentReleaseNotes", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterNewDescription", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterNewReleaseNotes", CLEAR_ON_MANAGER_START},
|
||||
{"Version", PERSISTENT},
|
||||
{"VisionRadarToggle", PERSISTENT},
|
||||
{"WideCameraOnly", PERSISTENT},
|
||||
|
||||
2
selfdrive/ui/.gitignore
vendored
2
selfdrive/ui/.gitignore
vendored
@@ -1,6 +1,8 @@
|
||||
moc_*
|
||||
*.moc
|
||||
|
||||
translations/main_test_en.*
|
||||
|
||||
_mui
|
||||
watch3
|
||||
installer/installers/*
|
||||
|
||||
@@ -56,7 +56,8 @@ qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs)
|
||||
# build main UI
|
||||
qt_src = ["main.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc",
|
||||
"qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc",
|
||||
"qt/offroad/onboarding.cc", "qt/offroad/driverview.cc"]
|
||||
"qt/offroad/software_settings.cc", "qt/offroad/onboarding.cc",
|
||||
"qt/offroad/driverview.cc"]
|
||||
qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs)
|
||||
if GetOption('test'):
|
||||
qt_src.remove("main.cc") # replaced by test_runner
|
||||
|
||||
@@ -159,7 +159,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
addItem(dcamBtn);
|
||||
|
||||
auto resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), "");
|
||||
connect(resetCalibBtn, &ButtonControl::showDescription, this, &DevicePanel::updateCalibDescription);
|
||||
connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription);
|
||||
connect(resetCalibBtn, &ButtonControl::clicked, [&]() {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to reset calibration?"), this)) {
|
||||
params.remove("CalibrationParams");
|
||||
@@ -282,85 +282,6 @@ void DevicePanel::poweroff() {
|
||||
}
|
||||
}
|
||||
|
||||
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
gitBranchLbl = new LabelControl(tr("Git Branch"));
|
||||
gitCommitLbl = new LabelControl(tr("Git Commit"));
|
||||
osVersionLbl = new LabelControl(tr("OS Version"));
|
||||
versionLbl = new LabelControl(tr("Version"), "", QString::fromStdString(params.get("ReleaseNotes")).trimmed());
|
||||
lastUpdateLbl = new LabelControl(tr("Last Update Check"), "", tr("The last time openpilot successfully checked for an update. The updater only runs while the car is off."));
|
||||
updateBtn = new ButtonControl(tr("Check for Update"), "");
|
||||
connect(updateBtn, &ButtonControl::clicked, [=]() {
|
||||
if (params.getBool("IsOffroad")) {
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("LastUpdateTime")));
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateFailedCount")));
|
||||
updateBtn->setText(tr("CHECKING"));
|
||||
updateBtn->setEnabled(false);
|
||||
}
|
||||
std::system("pkill -1 -f selfdrive.updated");
|
||||
});
|
||||
connect(uiState(), &UIState::offroadTransition, updateBtn, &QPushButton::setEnabled);
|
||||
|
||||
branchSwitcherBtn = new ButtonControl(tr("Switch Branch"), tr("ENTER"), tr("The new branch will be pulled the next time the updater runs."));
|
||||
connect(branchSwitcherBtn, &ButtonControl::clicked, [=]() {
|
||||
QString branch = InputDialog::getText(tr("Enter branch name"), this, tr("The new branch will be pulled the next time the updater runs."),
|
||||
false, -1, QString::fromStdString(params.get("SwitchToBranch")));
|
||||
if (branch.isEmpty()) {
|
||||
params.remove("SwitchToBranch");
|
||||
} else {
|
||||
params.put("SwitchToBranch", branch.toStdString());
|
||||
}
|
||||
std::system("pkill -1 -f selfdrive.updated");
|
||||
});
|
||||
connect(uiState(), &UIState::offroadTransition, branchSwitcherBtn, &QPushButton::setEnabled);
|
||||
|
||||
auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL"));
|
||||
connect(uninstallBtn, &ButtonControl::clicked, [&]() {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) {
|
||||
params.putBool("DoUninstall", true);
|
||||
}
|
||||
});
|
||||
connect(uiState(), &UIState::offroadTransition, uninstallBtn, &QPushButton::setEnabled);
|
||||
|
||||
QWidget *widgets[] = {versionLbl, lastUpdateLbl, updateBtn, branchSwitcherBtn, gitBranchLbl, gitCommitLbl, osVersionLbl, uninstallBtn};
|
||||
for (QWidget* w : widgets) {
|
||||
if (w == branchSwitcherBtn && params.getBool("IsTestedBranch")) {
|
||||
continue;
|
||||
}
|
||||
addItem(w);
|
||||
}
|
||||
|
||||
fs_watch = new QFileSystemWatcher(this);
|
||||
QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) {
|
||||
if (path.contains("UpdateFailedCount") && std::atoi(params.get("UpdateFailedCount").c_str()) > 0) {
|
||||
lastUpdateLbl->setText(tr("failed to fetch update"));
|
||||
updateBtn->setText(tr("CHECK"));
|
||||
updateBtn->setEnabled(true);
|
||||
} else if (path.contains("LastUpdateTime")) {
|
||||
updateLabels();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SoftwarePanel::showEvent(QShowEvent *event) {
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void SoftwarePanel::updateLabels() {
|
||||
QString lastUpdate = "";
|
||||
auto tm = params.get("LastUpdateTime");
|
||||
if (!tm.empty()) {
|
||||
lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate));
|
||||
}
|
||||
|
||||
versionLbl->setText(getBrandVersion());
|
||||
lastUpdateLbl->setText(lastUpdate);
|
||||
updateBtn->setText(tr("CHECK"));
|
||||
updateBtn->setEnabled(true);
|
||||
gitBranchLbl->setText(QString::fromStdString(params.get("GitBranch")));
|
||||
gitCommitLbl->setText(QString::fromStdString(params.get("GitCommit")).left(10));
|
||||
osVersionLbl->setText(QString::fromStdString(Hardware::get_os_version()).trimmed());
|
||||
}
|
||||
|
||||
void SettingsWindow::showEvent(QShowEvent *event) {
|
||||
panel_widget->setCurrentIndex(0);
|
||||
nav_btns->buttons()[0]->setChecked(true);
|
||||
|
||||
@@ -71,14 +71,15 @@ public:
|
||||
private:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void updateLabels();
|
||||
void checkForUpdates();
|
||||
|
||||
LabelControl *gitBranchLbl;
|
||||
LabelControl *gitCommitLbl;
|
||||
LabelControl *osVersionLbl;
|
||||
bool is_onroad = false;
|
||||
|
||||
QLabel *onroadLbl;
|
||||
LabelControl *versionLbl;
|
||||
LabelControl *lastUpdateLbl;
|
||||
ButtonControl *updateBtn;
|
||||
ButtonControl *branchSwitcherBtn;
|
||||
ButtonControl *installBtn;
|
||||
ButtonControl *downloadBtn;
|
||||
ButtonControl *targetBranchBtn;
|
||||
|
||||
Params params;
|
||||
QFileSystemWatcher *fs_watch;
|
||||
|
||||
156
selfdrive/ui/qt/offroad/software_settings.cc
Normal file
156
selfdrive/ui/qt/offroad/software_settings.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "selfdrive/ui/qt/offroad/settings.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLabel>
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/util.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
#include "system/hardware/hw.h"
|
||||
|
||||
|
||||
void SoftwarePanel::checkForUpdates() {
|
||||
std::system("pkill -SIGUSR1 -f selfdrive.updated");
|
||||
}
|
||||
|
||||
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off."));
|
||||
onroadLbl->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; padding-top: 30px; padding-bottom: 30px;");
|
||||
addItem(onroadLbl);
|
||||
|
||||
// current version
|
||||
versionLbl = new LabelControl(tr("Current Version"), "");
|
||||
addItem(versionLbl);
|
||||
|
||||
// download update btn
|
||||
downloadBtn = new ButtonControl(tr("Download"), tr("CHECK"));
|
||||
connect(downloadBtn, &ButtonControl::clicked, [=]() {
|
||||
downloadBtn->setEnabled(false);
|
||||
if (downloadBtn->text() == tr("CHECK")) {
|
||||
checkForUpdates();
|
||||
} else {
|
||||
std::system("pkill -SIGHUP -f selfdrive.updated");
|
||||
}
|
||||
});
|
||||
addItem(downloadBtn);
|
||||
|
||||
// install update btn
|
||||
installBtn = new ButtonControl(tr("Install Update"), tr("INSTALL"));
|
||||
connect(installBtn, &ButtonControl::clicked, [=]() {
|
||||
installBtn->setEnabled(false);
|
||||
params.putBool("DoShutdown", true);
|
||||
});
|
||||
addItem(installBtn);
|
||||
|
||||
// branch selecting
|
||||
targetBranchBtn = new ButtonControl(tr("Target Branch"), tr("SELECT"));
|
||||
connect(targetBranchBtn, &ButtonControl::clicked, [=]() {
|
||||
auto current = params.get("GitBranch");
|
||||
QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(",");
|
||||
for (QString b : {current.c_str(), "devel-staging", "devel", "master-ci", "master"}) {
|
||||
auto i = branches.indexOf(b);
|
||||
if (i >= 0) {
|
||||
branches.removeAt(i);
|
||||
branches.insert(0, b);
|
||||
}
|
||||
}
|
||||
|
||||
QString cur = QString::fromStdString(params.get("UpdaterTargetBranch"));
|
||||
QString selection = MultiOptionDialog::getSelection(tr("Select a branch"), branches, cur, this);
|
||||
if (!selection.isEmpty()) {
|
||||
params.put("UpdaterTargetBranch", selection.toStdString());
|
||||
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch")));
|
||||
checkForUpdates();
|
||||
}
|
||||
});
|
||||
if (!params.getBool("IsTestedBranch")) {
|
||||
addItem(targetBranchBtn);
|
||||
}
|
||||
|
||||
// uninstall button
|
||||
auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL"));
|
||||
connect(uninstallBtn, &ButtonControl::clicked, [&]() {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) {
|
||||
params.putBool("DoUninstall", true);
|
||||
}
|
||||
});
|
||||
addItem(uninstallBtn);
|
||||
|
||||
fs_watch = new QFileSystemWatcher(this);
|
||||
QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) {
|
||||
updateLabels();
|
||||
});
|
||||
|
||||
connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
|
||||
is_onroad = !offroad;
|
||||
updateLabels();
|
||||
});
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void SoftwarePanel::showEvent(QShowEvent *event) {
|
||||
// nice for testing on PC
|
||||
installBtn->setEnabled(true);
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void SoftwarePanel::updateLabels() {
|
||||
// add these back in case the files got removed
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("LastUpdateTime")));
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateFailedCount")));
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdaterState")));
|
||||
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateAvailable")));
|
||||
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// updater only runs offroad
|
||||
onroadLbl->setVisible(is_onroad);
|
||||
downloadBtn->setVisible(!is_onroad);
|
||||
|
||||
// download update
|
||||
QString updater_state = QString::fromStdString(params.get("UpdaterState"));
|
||||
bool failed = std::atoi(params.get("UpdateFailedCount").c_str()) > 0;
|
||||
if (updater_state != "idle") {
|
||||
downloadBtn->setEnabled(false);
|
||||
downloadBtn->setValue(updater_state);
|
||||
} else {
|
||||
if (failed) {
|
||||
downloadBtn->setText("CHECK");
|
||||
downloadBtn->setValue("failed to check for update");
|
||||
} else if (params.getBool("UpdaterFetchAvailable")) {
|
||||
downloadBtn->setText("DOWNLOAD");
|
||||
downloadBtn->setValue("update available");
|
||||
} else {
|
||||
QString lastUpdate = "never";
|
||||
auto tm = params.get("LastUpdateTime");
|
||||
if (!tm.empty()) {
|
||||
lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate));
|
||||
}
|
||||
downloadBtn->setText("CHECK");
|
||||
downloadBtn->setValue("up to date, last checked " + lastUpdate);
|
||||
}
|
||||
downloadBtn->setEnabled(true);
|
||||
}
|
||||
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch")));
|
||||
|
||||
// current + new versions
|
||||
versionLbl->setText(QString::fromStdString(params.get("UpdaterCurrentDescription")).left(40));
|
||||
versionLbl->setDescription(QString::fromStdString(params.get("UpdaterCurrentReleaseNotes")));
|
||||
|
||||
installBtn->setVisible(!is_onroad && params.getBool("UpdateAvailable"));
|
||||
installBtn->setValue(QString::fromStdString(params.get("UpdaterNewDescription")).left(35));
|
||||
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes")));
|
||||
|
||||
update();
|
||||
}
|
||||
@@ -42,6 +42,12 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons
|
||||
title_label->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left");
|
||||
hlayout->addWidget(title_label);
|
||||
|
||||
// value next to control button
|
||||
value = new QLabel();
|
||||
value->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
value->setStyleSheet("color: #aaaaaa");
|
||||
hlayout->addWidget(value);
|
||||
|
||||
main_layout->addLayout(hlayout);
|
||||
|
||||
// description
|
||||
@@ -54,7 +60,7 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons
|
||||
|
||||
connect(title_label, &QPushButton::clicked, [=]() {
|
||||
if (!description->isVisible()) {
|
||||
emit showDescription();
|
||||
emit showDescriptionEvent();
|
||||
}
|
||||
|
||||
if (!description->text().isEmpty()) {
|
||||
|
||||
@@ -45,8 +45,17 @@ public:
|
||||
title_label->setText(title);
|
||||
}
|
||||
|
||||
void setValue(const QString &val) {
|
||||
value->setText(val);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void showDescription() {
|
||||
description->setVisible(true);
|
||||
};
|
||||
|
||||
signals:
|
||||
void showDescription();
|
||||
void showDescriptionEvent();
|
||||
|
||||
protected:
|
||||
AbstractControl(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr);
|
||||
@@ -54,6 +63,9 @@ protected:
|
||||
|
||||
QHBoxLayout *hlayout;
|
||||
QPushButton *title_label;
|
||||
|
||||
private:
|
||||
QLabel *value;
|
||||
QLabel *description = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ UpdateAlert::UpdateAlert(QWidget *parent) : AbstractAlert(true, parent) {
|
||||
bool UpdateAlert::refresh() {
|
||||
bool updateAvailable = params.getBool("UpdateAvailable");
|
||||
if (updateAvailable) {
|
||||
releaseNotes->setText(params.get("ReleaseNotes").c_str());
|
||||
releaseNotes->setText(params.get("UpdaterNewReleaseNotes").c_str());
|
||||
}
|
||||
return updateAvailable;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
|
||||
SshControl::SshControl() : ButtonControl(tr("SSH Keys"), "", tr("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.")) {
|
||||
username_label.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
username_label.setStyleSheet("color: #aaaaaa");
|
||||
hlayout->insertWidget(1, &username_label);
|
||||
|
||||
QObject::connect(this, &ButtonControl::clicked, [=]() {
|
||||
if (text() == tr("ADD")) {
|
||||
QString username = InputDialog::getText(tr("Enter your GitHub username"), this);
|
||||
@@ -30,10 +26,10 @@ SshControl::SshControl() : ButtonControl(tr("SSH Keys"), "", tr("Warning: This g
|
||||
void SshControl::refresh() {
|
||||
QString param = QString::fromStdString(params.get("GithubSshKeys"));
|
||||
if (param.length()) {
|
||||
username_label.setText(QString::fromStdString(params.get("GithubUsername")));
|
||||
setValue(QString::fromStdString(params.get("GithubUsername")));
|
||||
setText(tr("REMOVE"));
|
||||
} else {
|
||||
username_label.setText("");
|
||||
setValue("");
|
||||
setText(tr("ADD"));
|
||||
}
|
||||
setEnabled(true);
|
||||
|
||||
@@ -27,8 +27,6 @@ public:
|
||||
private:
|
||||
Params params;
|
||||
|
||||
QLabel username_label;
|
||||
|
||||
void refresh();
|
||||
void getUserKeys(const QString &username);
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ if __name__ == "__main__":
|
||||
params.put_bool("UpdateAvailable", True)
|
||||
r = open(os.path.join(BASEDIR, "RELEASES.md")).read()
|
||||
r = r[:r.find('\n\n')] # Slice latest release notes
|
||||
params.put("ReleaseNotes", r + "\n")
|
||||
params.put("UpdaterNewReleaseNotes", r + "\n")
|
||||
|
||||
time.sleep(t)
|
||||
params.put_bool("UpdateAvailable", False)
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
<translation>変更</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<location line="+3"/>
|
||||
<source>Select a language</source>
|
||||
<translation>言語を選択</translation>
|
||||
</message>
|
||||
@@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai</source>
|
||||
詳しくはこちら:https://connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+57"/>
|
||||
<location line="+58"/>
|
||||
<source>No home
|
||||
location set</source>
|
||||
<translation>自宅の住所はまだ
|
||||
@@ -432,7 +432,7 @@ location set</source>
|
||||
設定されていません</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+113"/>
|
||||
<location line="+120"/>
|
||||
<source>no recent destinations</source>
|
||||
<translation>最近の目的地履歴がありません</translation>
|
||||
</message>
|
||||
@@ -718,7 +718,7 @@ location set</source>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="+101"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="+22"/>
|
||||
<source>×</source>
|
||||
<translation>×</translation>
|
||||
</message>
|
||||
@@ -983,68 +983,47 @@ location set</source>
|
||||
<context>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-130"/>
|
||||
<source>Git Branch</source>
|
||||
<translation>Git ブランチ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Git Commit</source>
|
||||
<translation>Git コミット</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>OS Version</source>
|
||||
<translation>OS バージョン</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Version</source>
|
||||
<translation>バージョン</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Last Update Check</source>
|
||||
<translation>最終更新確認</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>The last time openpilot successfully checked for an update. The updater only runs while the car is off.</source>
|
||||
<translation>openpilotが最後にアップデートの確認に成功してからの時間です。アップデート処理は、車の電源が切れているときのみ実行されます。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Check for Update</source>
|
||||
<translation>更新プログラムをチェック</translation>
|
||||
<location filename="../qt/offroad/software_settings.cc" line="+24"/>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>CHECKING</source>
|
||||
<translation>確認中</translation>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+7"/>
|
||||
<source>Switch Branch</source>
|
||||
<translation>ブランチの切り替え</translation>
|
||||
<location line="+4"/>
|
||||
<source>Download</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Install Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>ENTER</source>
|
||||
<translation>切替</translation>
|
||||
<source>INSTALL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+8"/>
|
||||
<source>Target Branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<location line="+2"/>
|
||||
<source>The new branch will be pulled the next time the updater runs.</source>
|
||||
<translation>updater を実行する時にブランチを切り替えます。</translation>
|
||||
<source>SELECT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Enter branch name</source>
|
||||
<translation>ブランチ名を入力</translation>
|
||||
<location line="+13"/>
|
||||
<source>Select a branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+12"/>
|
||||
<source>UNINSTALL</source>
|
||||
<translation>アンインストール</translation>
|
||||
</message>
|
||||
@@ -1059,13 +1038,8 @@ location set</source>
|
||||
<translation>アンインストールしてもよろしいですか?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<source>failed to fetch update</source>
|
||||
<translation>更新のダウンロードにエラーが発生しました</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<location line="+21"/>
|
||||
<location line="-47"/>
|
||||
<location line="+3"/>
|
||||
<source>CHECK</source>
|
||||
<translation>確認</translation>
|
||||
</message>
|
||||
@@ -1083,7 +1057,7 @@ location set</source>
|
||||
<translation>警告: これは、GitHub の設定にあるすべての公開鍵への SSH アクセスを許可するものです。自分以外の GitHub のユーザー名を入力しないでください。コンマのスタッフが GitHub のユーザー名を追加するようお願いすることはありません。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+2"/>
|
||||
<location line="+24"/>
|
||||
<source>ADD</source>
|
||||
<translation>追加</translation>
|
||||
@@ -1153,7 +1127,7 @@ location set</source>
|
||||
<context>
|
||||
<name>TogglesPanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-324"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="-303"/>
|
||||
<source>Enable openpilot</source>
|
||||
<translation>openpilot を有効化</translation>
|
||||
</message>
|
||||
@@ -1290,12 +1264,11 @@ location set</source>
|
||||
<name>WifiUI</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/networking.cc" line="+113"/>
|
||||
<location line="+53"/>
|
||||
<source>Scanning for networks...</source>
|
||||
<translation>ネットワークをスキャン中...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+26"/>
|
||||
<location line="+80"/>
|
||||
<source>CONNECTING...</source>
|
||||
<translation>接続中...</translation>
|
||||
</message>
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
<translation>변경</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<location line="+3"/>
|
||||
<source>Select a language</source>
|
||||
<translation>언어를 선택하세요</translation>
|
||||
</message>
|
||||
@@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai</source>
|
||||
등록:https://connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+57"/>
|
||||
<location line="+58"/>
|
||||
<source>No home
|
||||
location set</source>
|
||||
<translation>집
|
||||
@@ -432,7 +432,7 @@ location set</source>
|
||||
설정되지않음</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+113"/>
|
||||
<location line="+120"/>
|
||||
<source>no recent destinations</source>
|
||||
<translation>최근 목적지 없음</translation>
|
||||
</message>
|
||||
@@ -718,7 +718,7 @@ location set</source>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="+101"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="+22"/>
|
||||
<source>×</source>
|
||||
<translation>×</translation>
|
||||
</message>
|
||||
@@ -983,68 +983,47 @@ location set</source>
|
||||
<context>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-130"/>
|
||||
<source>Git Branch</source>
|
||||
<translation>Git 브렌치</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Git Commit</source>
|
||||
<translation>Git 커밋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>OS Version</source>
|
||||
<translation>OS 버전</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Version</source>
|
||||
<translation>버전</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Last Update Check</source>
|
||||
<translation>최신 업데이트 검사</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>The last time openpilot successfully checked for an update. The updater only runs while the car is off.</source>
|
||||
<translation>최근에 openpilot이 업데이트를 성공적으로 확인했습니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Check for Update</source>
|
||||
<translation>업데이트 확인</translation>
|
||||
<location filename="../qt/offroad/software_settings.cc" line="+24"/>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>CHECKING</source>
|
||||
<translation>확인중</translation>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+7"/>
|
||||
<source>Switch Branch</source>
|
||||
<translation>브랜치 변경</translation>
|
||||
<location line="+4"/>
|
||||
<source>Download</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Install Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>ENTER</source>
|
||||
<translation>입력하세요</translation>
|
||||
<source>INSTALL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+8"/>
|
||||
<source>Target Branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<location line="+2"/>
|
||||
<source>The new branch will be pulled the next time the updater runs.</source>
|
||||
<translation>다음 업데이트 프로그램이 실행될 때 새 브랜치가 적용됩니다.</translation>
|
||||
<source>SELECT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Enter branch name</source>
|
||||
<translation>브랜치명 입력</translation>
|
||||
<location line="+13"/>
|
||||
<source>Select a branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+12"/>
|
||||
<source>UNINSTALL</source>
|
||||
<translation>제거</translation>
|
||||
</message>
|
||||
@@ -1059,13 +1038,8 @@ location set</source>
|
||||
<translation>제거하시겠습니까?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<source>failed to fetch update</source>
|
||||
<translation>업데이트를 가져올수없습니다</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<location line="+21"/>
|
||||
<location line="-47"/>
|
||||
<location line="+3"/>
|
||||
<source>CHECK</source>
|
||||
<translation>확인</translation>
|
||||
</message>
|
||||
@@ -1083,7 +1057,7 @@ location set</source>
|
||||
<translation>경고: 허용으로 설정하면 GitHub 설정의 모든 공용 키에 대한 SSH 액세스 권한이 부여됩니다. GitHub 사용자 ID 이외에는 입력하지 마십시오. comma에서는 GitHub ID를 추가하라는 요청을 하지 않습니다.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+2"/>
|
||||
<location line="+24"/>
|
||||
<source>ADD</source>
|
||||
<translation>추가</translation>
|
||||
@@ -1153,7 +1127,7 @@ location set</source>
|
||||
<context>
|
||||
<name>TogglesPanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-324"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="-303"/>
|
||||
<source>Enable openpilot</source>
|
||||
<translation>openpilot 사용</translation>
|
||||
</message>
|
||||
@@ -1290,12 +1264,11 @@ location set</source>
|
||||
<name>WifiUI</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/networking.cc" line="+113"/>
|
||||
<location line="+53"/>
|
||||
<source>Scanning for networks...</source>
|
||||
<translation>네트워크 검색 중...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+26"/>
|
||||
<location line="+80"/>
|
||||
<source>CONNECTING...</source>
|
||||
<translation>연결중...</translation>
|
||||
</message>
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
<translation>ALTERAR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<location line="+3"/>
|
||||
<source>Select a language</source>
|
||||
<translation>Selecione o Idioma</translation>
|
||||
</message>
|
||||
@@ -419,7 +419,7 @@ prime subscription. Sign up now: https://connect.comma.ai</source>
|
||||
uma assinatura prime Inscreva-se agora: https://connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+57"/>
|
||||
<location line="+58"/>
|
||||
<source>No home
|
||||
location set</source>
|
||||
<translation>Sem local
|
||||
@@ -433,7 +433,7 @@ location set</source>
|
||||
trabalho definido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+113"/>
|
||||
<location line="+120"/>
|
||||
<source>no recent destinations</source>
|
||||
<translation>sem destinos recentes</translation>
|
||||
</message>
|
||||
@@ -722,7 +722,7 @@ trabalho definido</translation>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="+101"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="+22"/>
|
||||
<source>×</source>
|
||||
<translation>×</translation>
|
||||
</message>
|
||||
@@ -987,68 +987,47 @@ trabalho definido</translation>
|
||||
<context>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-130"/>
|
||||
<source>Git Branch</source>
|
||||
<translation>Git Branch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Git Commit</source>
|
||||
<translation>Último Commit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>OS Version</source>
|
||||
<translation>Versão do Sistema</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Version</source>
|
||||
<translation>Versão</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Last Update Check</source>
|
||||
<translation>Verificação da última atualização</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>The last time openpilot successfully checked for an update. The updater only runs while the car is off.</source>
|
||||
<translation>A última vez que o openpilot verificou com sucesso uma atualização. O atualizador só funciona com o carro desligado.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Check for Update</source>
|
||||
<translation>Verifique atualizações</translation>
|
||||
<location filename="../qt/offroad/software_settings.cc" line="+24"/>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>CHECKING</source>
|
||||
<translation>VERIFICANDO</translation>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+7"/>
|
||||
<source>Switch Branch</source>
|
||||
<translation>Alterar Branch</translation>
|
||||
<location line="+4"/>
|
||||
<source>Download</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Install Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>ENTER</source>
|
||||
<translation>INSERIR</translation>
|
||||
<source>INSTALL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+8"/>
|
||||
<source>Target Branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<location line="+2"/>
|
||||
<source>The new branch will be pulled the next time the updater runs.</source>
|
||||
<translation>A nova branch será aplicada ao verificar atualizações.</translation>
|
||||
<source>SELECT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Enter branch name</source>
|
||||
<translation>Inserir o nome da branch</translation>
|
||||
<location line="+13"/>
|
||||
<source>Select a branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+12"/>
|
||||
<source>UNINSTALL</source>
|
||||
<translation>DESINSTALAR</translation>
|
||||
</message>
|
||||
@@ -1063,13 +1042,8 @@ trabalho definido</translation>
|
||||
<translation>Tem certeza que quer desinstalar?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<source>failed to fetch update</source>
|
||||
<translation>falha ao buscar atualização</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<location line="+21"/>
|
||||
<location line="-47"/>
|
||||
<location line="+3"/>
|
||||
<source>CHECK</source>
|
||||
<translation>VERIFICAR</translation>
|
||||
</message>
|
||||
@@ -1087,7 +1061,7 @@ trabalho definido</translation>
|
||||
<translation>Aviso: isso concede acesso SSH a todas as chaves públicas nas configurações do GitHub. Nunca insira um nome de usuário do GitHub que não seja o seu. Um funcionário da comma NUNCA pedirá que você adicione seu nome de usuário do GitHub.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+2"/>
|
||||
<location line="+24"/>
|
||||
<source>ADD</source>
|
||||
<translation>ADICIONAR</translation>
|
||||
@@ -1157,7 +1131,7 @@ trabalho definido</translation>
|
||||
<context>
|
||||
<name>TogglesPanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-324"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="-303"/>
|
||||
<source>Enable openpilot</source>
|
||||
<translation>Ativar openpilot</translation>
|
||||
</message>
|
||||
@@ -1294,12 +1268,11 @@ trabalho definido</translation>
|
||||
<name>WifiUI</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/networking.cc" line="+113"/>
|
||||
<location line="+53"/>
|
||||
<source>Scanning for networks...</source>
|
||||
<translation>Procurando redes...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+26"/>
|
||||
<location line="+80"/>
|
||||
<source>CONNECTING...</source>
|
||||
<translation>CONECTANDO...</translation>
|
||||
</message>
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
<translation>切换</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<location line="+3"/>
|
||||
<source>Select a language</source>
|
||||
<translation>选择语言</translation>
|
||||
</message>
|
||||
@@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai</source>
|
||||
立即注册:https://connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+57"/>
|
||||
<location line="+58"/>
|
||||
<source>No home
|
||||
location set</source>
|
||||
<translation>家:未设定</translation>
|
||||
@@ -430,7 +430,7 @@ location set</source>
|
||||
<translation>工作:未设定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+113"/>
|
||||
<location line="+120"/>
|
||||
<source>no recent destinations</source>
|
||||
<translation>无最近目的地</translation>
|
||||
</message>
|
||||
@@ -716,7 +716,7 @@ location set</source>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="+101"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="+22"/>
|
||||
<source>×</source>
|
||||
<translation>×</translation>
|
||||
</message>
|
||||
@@ -981,68 +981,47 @@ location set</source>
|
||||
<context>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-130"/>
|
||||
<source>Git Branch</source>
|
||||
<translation>Git Branch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Git Commit</source>
|
||||
<translation>Git Commit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>OS Version</source>
|
||||
<translation>系统版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Version</source>
|
||||
<translation>软件版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Last Update Check</source>
|
||||
<translation>上次检查更新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>The last time openpilot successfully checked for an update. The updater only runs while the car is off.</source>
|
||||
<translation>上一次成功检查更新的时间。更新程序仅在汽车熄火时运行。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Check for Update</source>
|
||||
<translation>检查更新</translation>
|
||||
<location filename="../qt/offroad/software_settings.cc" line="+24"/>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>CHECKING</source>
|
||||
<translation>正在检查更新</translation>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+7"/>
|
||||
<source>Switch Branch</source>
|
||||
<translation>切换分支</translation>
|
||||
<location line="+4"/>
|
||||
<source>Download</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Install Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>ENTER</source>
|
||||
<translation>输入</translation>
|
||||
<source>INSTALL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+8"/>
|
||||
<source>Target Branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<location line="+2"/>
|
||||
<source>The new branch will be pulled the next time the updater runs.</source>
|
||||
<translation>分支将在更新服务下次启动时自动切换。</translation>
|
||||
<source>SELECT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Enter branch name</source>
|
||||
<translation>输入分支名称</translation>
|
||||
<location line="+13"/>
|
||||
<source>Select a branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+12"/>
|
||||
<source>UNINSTALL</source>
|
||||
<translation>卸载</translation>
|
||||
</message>
|
||||
@@ -1057,13 +1036,8 @@ location set</source>
|
||||
<translation>您确定要卸载吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<source>failed to fetch update</source>
|
||||
<translation>获取更新失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<location line="+21"/>
|
||||
<location line="-47"/>
|
||||
<location line="+3"/>
|
||||
<source>CHECK</source>
|
||||
<translation>查看</translation>
|
||||
</message>
|
||||
@@ -1081,7 +1055,7 @@ location set</source>
|
||||
<translation>警告:这将授予SSH访问权限给您GitHub设置中的所有公钥。切勿输入您自己以外的GitHub用户名。comma员工永远不会要求您添加他们的GitHub用户名。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+2"/>
|
||||
<location line="+24"/>
|
||||
<source>ADD</source>
|
||||
<translation>添加</translation>
|
||||
@@ -1151,7 +1125,7 @@ location set</source>
|
||||
<context>
|
||||
<name>TogglesPanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-324"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="-303"/>
|
||||
<source>Enable openpilot</source>
|
||||
<translation>启用openpilot</translation>
|
||||
</message>
|
||||
@@ -1288,12 +1262,11 @@ location set</source>
|
||||
<name>WifiUI</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/networking.cc" line="+113"/>
|
||||
<location line="+53"/>
|
||||
<source>Scanning for networks...</source>
|
||||
<translation>正在扫描网络……</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+26"/>
|
||||
<location line="+80"/>
|
||||
<source>CONNECTING...</source>
|
||||
<translation>正在连接……</translation>
|
||||
</message>
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
<translation>更改</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+4"/>
|
||||
<location line="+3"/>
|
||||
<source>Select a language</source>
|
||||
<translation>選擇語言</translation>
|
||||
</message>
|
||||
@@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai</source>
|
||||
立即註冊:https://connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+57"/>
|
||||
<location line="+58"/>
|
||||
<source>No home
|
||||
location set</source>
|
||||
<translation>未設定
|
||||
@@ -432,7 +432,7 @@ location set</source>
|
||||
工作位置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+113"/>
|
||||
<location line="+120"/>
|
||||
<source>no recent destinations</source>
|
||||
<translation>沒有最近的導航記錄</translation>
|
||||
</message>
|
||||
@@ -718,7 +718,7 @@ location set</source>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="+101"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="+22"/>
|
||||
<source>×</source>
|
||||
<translation>×</translation>
|
||||
</message>
|
||||
@@ -983,68 +983,47 @@ location set</source>
|
||||
<context>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-130"/>
|
||||
<source>Git Branch</source>
|
||||
<translation>Git 分支</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Git Commit</source>
|
||||
<translation>Git 提交</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>OS Version</source>
|
||||
<translation>系統版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Version</source>
|
||||
<translation>版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Last Update Check</source>
|
||||
<translation>上次檢查時間</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>The last time openpilot successfully checked for an update. The updater only runs while the car is off.</source>
|
||||
<translation>上次成功檢查更新的時間。更新系統只會在車子熄火時執行。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Check for Update</source>
|
||||
<translation>檢查更新</translation>
|
||||
<location filename="../qt/offroad/software_settings.cc" line="+24"/>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>CHECKING</source>
|
||||
<translation>檢查中</translation>
|
||||
<source>Current Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+7"/>
|
||||
<source>Switch Branch</source>
|
||||
<translation>切換分支</translation>
|
||||
<location line="+4"/>
|
||||
<source>Download</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Install Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>ENTER</source>
|
||||
<translation>切換</translation>
|
||||
<source>INSTALL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+8"/>
|
||||
<source>Target Branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<location line="+2"/>
|
||||
<source>The new branch will be pulled the next time the updater runs.</source>
|
||||
<translation>新的分支將會在下次檢查更新時切換過去。</translation>
|
||||
<source>SELECT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+0"/>
|
||||
<source>Enter branch name</source>
|
||||
<translation>輸入分支名稱</translation>
|
||||
<location line="+13"/>
|
||||
<source>Select a branch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+12"/>
|
||||
<source>UNINSTALL</source>
|
||||
<translation>卸載</translation>
|
||||
</message>
|
||||
@@ -1059,13 +1038,8 @@ location set</source>
|
||||
<translation>您確定您要卸載嗎?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<source>failed to fetch update</source>
|
||||
<translation>下載更新失敗</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<location line="+21"/>
|
||||
<location line="-47"/>
|
||||
<location line="+3"/>
|
||||
<source>CHECK</source>
|
||||
<translation>檢查</translation>
|
||||
</message>
|
||||
@@ -1083,7 +1057,7 @@ location set</source>
|
||||
<translation>警告:這將授權給 GitHub 帳號中所有公鑰 SSH 訪問權限。切勿輸入非您自己的 GitHub 用戶名。comma 員工「永遠不會」要求您添加他們的 GitHub 用戶名。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+2"/>
|
||||
<location line="+24"/>
|
||||
<source>ADD</source>
|
||||
<translation>新增</translation>
|
||||
@@ -1153,7 +1127,7 @@ location set</source>
|
||||
<context>
|
||||
<name>TogglesPanel</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/settings.cc" line="-324"/>
|
||||
<location filename="../qt/offroad/settings.cc" line="-303"/>
|
||||
<source>Enable openpilot</source>
|
||||
<translation>啟用 openpilot</translation>
|
||||
</message>
|
||||
@@ -1290,12 +1264,11 @@ location set</source>
|
||||
<name>WifiUI</name>
|
||||
<message>
|
||||
<location filename="../qt/offroad/networking.cc" line="+113"/>
|
||||
<location line="+53"/>
|
||||
<source>Scanning for networks...</source>
|
||||
<translation>掃描無線網路中...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+26"/>
|
||||
<location line="+80"/>
|
||||
<source>CONNECTING...</source>
|
||||
<translation>連線中...</translation>
|
||||
</message>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
# disable this service.
|
||||
|
||||
import os
|
||||
import re
|
||||
import datetime
|
||||
import subprocess
|
||||
import psutil
|
||||
@@ -31,8 +32,9 @@ import signal
|
||||
import fcntl
|
||||
import time
|
||||
import threading
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple, Optional
|
||||
from typing import List, Union, Optional
|
||||
from markdown_it import MarkdownIt
|
||||
|
||||
from common.basedir import BASEDIR
|
||||
@@ -54,20 +56,27 @@ DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
|
||||
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
|
||||
|
||||
class WaitTimeHelper:
|
||||
def __init__(self, proc):
|
||||
self.proc = proc
|
||||
def __init__(self):
|
||||
self.ready_event = threading.Event()
|
||||
self.only_check_for_update = False
|
||||
signal.signal(signal.SIGHUP, self.update_now)
|
||||
signal.signal(signal.SIGUSR1, self.check_now)
|
||||
|
||||
def update_now(self, signum: int, frame) -> None:
|
||||
cloudlog.info("caught SIGHUP, running update check immediately")
|
||||
cloudlog.info("caught SIGHUP, attempting to downloading update")
|
||||
self.only_check_for_update = False
|
||||
self.ready_event.set()
|
||||
|
||||
def check_now(self, signum: int, frame) -> None:
|
||||
cloudlog.info("caught SIGUSR1, checking for updates")
|
||||
self.only_check_for_update = True
|
||||
self.ready_event.set()
|
||||
|
||||
def sleep(self, t: float) -> None:
|
||||
self.ready_event.wait(timeout=t)
|
||||
|
||||
|
||||
def run(cmd: List[str], cwd: Optional[str] = None):
|
||||
def run(cmd: List[str], cwd: Optional[str] = None) -> str:
|
||||
return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
|
||||
|
||||
@@ -80,59 +89,19 @@ def set_consistent_flag(consistent: bool) -> None:
|
||||
consistent_file.unlink(missing_ok=True)
|
||||
os.sync()
|
||||
|
||||
|
||||
def set_params(new_version: bool, failed_count: int, exception: Optional[str]) -> None:
|
||||
params = Params()
|
||||
|
||||
params.put("UpdateFailedCount", str(failed_count))
|
||||
|
||||
last_update = datetime.datetime.utcnow()
|
||||
if failed_count == 0:
|
||||
t = last_update.isoformat()
|
||||
params.put("LastUpdateTime", t.encode('utf8'))
|
||||
else:
|
||||
def parse_release_notes(basedir: str) -> bytes:
|
||||
try:
|
||||
with open(os.path.join(basedir, "RELEASES.md"), "rb") as f:
|
||||
r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes
|
||||
try:
|
||||
t = params.get("LastUpdateTime", encoding='utf8')
|
||||
last_update = datetime.datetime.fromisoformat(t)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
if exception is None:
|
||||
params.remove("LastUpdateException")
|
||||
else:
|
||||
params.put("LastUpdateException", exception)
|
||||
|
||||
# Write out release notes for new versions
|
||||
if new_version:
|
||||
try:
|
||||
with open(os.path.join(FINALIZED, "RELEASES.md"), "rb") as f:
|
||||
r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes
|
||||
try:
|
||||
params.put("ReleaseNotes", MarkdownIt().render(r.decode("utf-8")))
|
||||
except Exception:
|
||||
params.put("ReleaseNotes", r + b"\n")
|
||||
return bytes(MarkdownIt().render(r.decode("utf-8")), encoding="utf-8")
|
||||
except Exception:
|
||||
params.put("ReleaseNotes", "")
|
||||
params.put_bool("UpdateAvailable", True)
|
||||
|
||||
# Handle user prompt
|
||||
for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"):
|
||||
set_offroad_alert(alert, False)
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
dt = now - last_update
|
||||
if failed_count > 15 and exception is not None:
|
||||
if is_tested_branch():
|
||||
extra_text = "Ensure the software is correctly installed"
|
||||
else:
|
||||
extra_text = exception
|
||||
set_offroad_alert("Offroad_UpdateFailed", True, extra_text=extra_text)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_MAX and failed_count > 1:
|
||||
set_offroad_alert("Offroad_ConnectivityNeeded", True)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT:
|
||||
remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1)
|
||||
set_offroad_alert("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.")
|
||||
|
||||
return r + b"\n"
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except Exception:
|
||||
cloudlog.exception("failed to parse release notes")
|
||||
return b""
|
||||
|
||||
def setup_git_options(cwd: str) -> None:
|
||||
# We sync FS object atimes (which NEOS doesn't use) and mtimes, but ctimes
|
||||
@@ -267,65 +236,161 @@ def handle_agnos_update() -> None:
|
||||
set_offroad_alert("Offroad_NeosUpdate", False)
|
||||
|
||||
|
||||
def check_git_fetch_result(fetch_txt: str) -> bool:
|
||||
err_msg = "Failed to add the host to the list of known hosts (/data/data/com.termux/files/home/.ssh/known_hosts).\n"
|
||||
return len(fetch_txt) > 0 and (fetch_txt != err_msg)
|
||||
|
||||
class Updater:
|
||||
def __init__(self):
|
||||
self.params = Params()
|
||||
self.branches = defaultdict(lambda: None)
|
||||
|
||||
def check_for_update() -> Tuple[bool, bool]:
|
||||
setup_git_options(OVERLAY_MERGED)
|
||||
try:
|
||||
git_fetch_output = run(["git", "fetch", "--dry-run"], OVERLAY_MERGED)
|
||||
return True, check_git_fetch_result(git_fetch_output)
|
||||
except subprocess.CalledProcessError:
|
||||
return False, False
|
||||
@property
|
||||
def target_branch(self) -> str:
|
||||
b: Union[str, None] = self.params.get("UpdaterTargetBranch", encoding='utf-8')
|
||||
if b is None:
|
||||
b = self.get_branch(BASEDIR)
|
||||
self.params.put("UpdaterTargetBranch", b)
|
||||
return b
|
||||
|
||||
@property
|
||||
def update_ready(self) -> bool:
|
||||
consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent"))
|
||||
if consistent_file.is_file():
|
||||
hash_mismatch = self.get_commit_hash(BASEDIR) != self.branches[self.target_branch]
|
||||
branch_mismatch = self.get_branch(BASEDIR) != self.target_branch
|
||||
on_target_branch = self.get_branch(FINALIZED) == self.target_branch
|
||||
return ((hash_mismatch or branch_mismatch) and on_target_branch)
|
||||
return False
|
||||
|
||||
def fetch_update() -> bool:
|
||||
cloudlog.info("attempting git fetch inside staging overlay")
|
||||
@property
|
||||
def update_available(self) -> bool:
|
||||
if os.path.isdir(OVERLAY_MERGED):
|
||||
hash_mismatch = self.get_commit_hash(OVERLAY_MERGED) != self.branches[self.target_branch]
|
||||
branch_mismatch = self.get_branch(OVERLAY_MERGED) != self.target_branch
|
||||
return hash_mismatch or branch_mismatch
|
||||
return False
|
||||
|
||||
setup_git_options(OVERLAY_MERGED)
|
||||
def get_branch(self, path: str) -> str:
|
||||
return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], path).rstrip()
|
||||
|
||||
git_fetch_output = run(["git", "fetch"], OVERLAY_MERGED)
|
||||
cloudlog.info("git fetch success: %s", git_fetch_output)
|
||||
def get_commit_hash(self, path: str = OVERLAY_MERGED) -> str:
|
||||
return run(["git", "rev-parse", "HEAD"], path).rstrip()
|
||||
|
||||
cur_hash = run(["git", "rev-parse", "HEAD"], OVERLAY_MERGED).rstrip()
|
||||
upstream_hash = run(["git", "rev-parse", "@{u}"], OVERLAY_MERGED).rstrip()
|
||||
new_version: bool = cur_hash != upstream_hash
|
||||
git_fetch_result = check_git_fetch_result(git_fetch_output)
|
||||
def set_params(self, failed_count: int, exception: Optional[str]) -> None:
|
||||
self.params.put("UpdateFailedCount", str(failed_count))
|
||||
|
||||
new_branch = Params().get("SwitchToBranch", encoding='utf8')
|
||||
if new_branch is not None:
|
||||
new_version = True
|
||||
self.params.put_bool("UpdaterFetchAvailable", self.update_available)
|
||||
self.params.put("UpdaterAvailableBranches", ','.join(self.branches.keys()))
|
||||
|
||||
cloudlog.info(f"comparing {cur_hash} to {upstream_hash}")
|
||||
if new_version or git_fetch_result:
|
||||
cloudlog.info("Running update")
|
||||
last_update = datetime.datetime.utcnow()
|
||||
if failed_count == 0:
|
||||
t = last_update.isoformat()
|
||||
self.params.put("LastUpdateTime", t.encode('utf8'))
|
||||
else:
|
||||
try:
|
||||
t = self.params.get("LastUpdateTime", encoding='utf8')
|
||||
last_update = datetime.datetime.fromisoformat(t)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
if new_version:
|
||||
cloudlog.info("git reset in progress")
|
||||
cmds = [
|
||||
["git", "reset", "--hard", "@{u}"],
|
||||
["git", "clean", "-xdf"],
|
||||
["git", "submodule", "init"],
|
||||
["git", "submodule", "update"],
|
||||
]
|
||||
if new_branch is not None:
|
||||
cloudlog.info(f"switching to branch {repr(new_branch)}")
|
||||
cmds.insert(0, ["git", "checkout", "-f", new_branch])
|
||||
r = [run(cmd, OVERLAY_MERGED) for cmd in cmds]
|
||||
cloudlog.info("git reset success: %s", '\n'.join(r))
|
||||
if exception is None:
|
||||
self.params.remove("LastUpdateException")
|
||||
else:
|
||||
self.params.put("LastUpdateException", exception)
|
||||
|
||||
if AGNOS:
|
||||
handle_agnos_update()
|
||||
# Write out current and new version info
|
||||
def get_description(basedir: str) -> str:
|
||||
version = ""
|
||||
branch = ""
|
||||
commit = ""
|
||||
try:
|
||||
branch = self.get_branch(basedir)
|
||||
commit = self.get_commit_hash(basedir)
|
||||
with open(os.path.join(basedir, "common", "version.h")) as f:
|
||||
version = f.read().split('"')[1]
|
||||
except Exception:
|
||||
pass
|
||||
return f"{version} / {branch} / {commit[:7]}"
|
||||
self.params.put("UpdaterCurrentDescription", get_description(BASEDIR))
|
||||
self.params.put("UpdaterCurrentReleaseNotes", parse_release_notes(BASEDIR))
|
||||
self.params.put("UpdaterNewDescription", get_description(FINALIZED))
|
||||
self.params.put("UpdaterNewReleaseNotes", parse_release_notes(FINALIZED))
|
||||
self.params.put_bool("UpdateAvailable", self.update_ready)
|
||||
|
||||
# Handle user prompt
|
||||
for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"):
|
||||
set_offroad_alert(alert, False)
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
dt = now - last_update
|
||||
if failed_count > 15 and exception is not None:
|
||||
if is_tested_branch():
|
||||
extra_text = "Ensure the software is correctly installed. Uninstall and re-install if this error persists."
|
||||
else:
|
||||
extra_text = exception
|
||||
set_offroad_alert("Offroad_UpdateFailed", True, extra_text=extra_text)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_MAX and failed_count > 1:
|
||||
set_offroad_alert("Offroad_ConnectivityNeeded", True)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT:
|
||||
remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1)
|
||||
set_offroad_alert("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.")
|
||||
|
||||
def check_for_update(self) -> None:
|
||||
cloudlog.info("checking for updates")
|
||||
|
||||
excluded_branches = ('release2', 'release2-staging', 'dashcam', 'dashcam-staging')
|
||||
|
||||
setup_git_options(OVERLAY_MERGED)
|
||||
output = run(["git", "ls-remote", "--heads"], OVERLAY_MERGED)
|
||||
|
||||
self.branches = defaultdict(lambda: None)
|
||||
for line in output.split('\n'):
|
||||
ls_remotes_re = r'(?P<commit_sha>\b[0-9a-f]{5,40}\b)(\s+)(refs\/heads\/)(?P<branch_name>.*$)'
|
||||
x = re.fullmatch(ls_remotes_re, line.strip())
|
||||
if x is not None and x.group('branch_name') not in excluded_branches:
|
||||
self.branches[x.group('branch_name')] = x.group('commit_sha')
|
||||
|
||||
cur_branch = self.get_branch(OVERLAY_MERGED)
|
||||
cur_commit = self.get_commit_hash(OVERLAY_MERGED)
|
||||
new_branch = self.target_branch
|
||||
new_commit = self.branches[new_branch]
|
||||
if (cur_branch, cur_commit) != (new_branch, new_commit):
|
||||
cloudlog.info(f"update available, {cur_branch} ({cur_commit[:7]}) -> {new_branch} ({new_commit[:7]})")
|
||||
else:
|
||||
cloudlog.info(f"up to date on {cur_branch} ({cur_commit[:7]})")
|
||||
|
||||
def fetch_update(self) -> None:
|
||||
cloudlog.info("attempting git fetch inside staging overlay")
|
||||
|
||||
self.params.put("UpdaterState", "downloading...")
|
||||
|
||||
# TODO: cleanly interrupt this and invalidate old update
|
||||
set_consistent_flag(False)
|
||||
self.params.put_bool("UpdateAvailable", False)
|
||||
|
||||
setup_git_options(OVERLAY_MERGED)
|
||||
|
||||
branch = self.target_branch
|
||||
git_fetch_output = run(["git", "fetch", "origin", branch], OVERLAY_MERGED)
|
||||
cloudlog.info("git fetch success: %s", git_fetch_output)
|
||||
|
||||
cloudlog.info("git reset in progress")
|
||||
cmds = [
|
||||
["git", "checkout", "--force", "--no-recurse-submodules", branch],
|
||||
["git", "reset", "--hard", f"origin/{branch}"],
|
||||
["git", "clean", "-xdf"],
|
||||
["git", "submodule", "init"],
|
||||
["git", "submodule", "update"],
|
||||
]
|
||||
r = [run(cmd, OVERLAY_MERGED) for cmd in cmds]
|
||||
cloudlog.info("git reset success: %s", '\n'.join(r))
|
||||
|
||||
# TODO: show agnos download progress
|
||||
if AGNOS:
|
||||
handle_agnos_update()
|
||||
|
||||
# Create the finalized, ready-to-swap update
|
||||
self.params.put("UpdaterState", "finalizing update...")
|
||||
finalize_update()
|
||||
cloudlog.info("openpilot update successful!")
|
||||
else:
|
||||
cloudlog.info("nothing new from git at this time")
|
||||
|
||||
return new_version
|
||||
cloudlog.info("finalize success!")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -357,8 +422,12 @@ def main() -> None:
|
||||
overlay_init = Path(os.path.join(BASEDIR, ".overlay_init"))
|
||||
overlay_init.unlink(missing_ok=True)
|
||||
|
||||
updater = Updater()
|
||||
update_failed_count = 0 # TODO: Load from param?
|
||||
wait_helper = WaitTimeHelper(proc)
|
||||
|
||||
# no fetch on the first time
|
||||
wait_helper = WaitTimeHelper()
|
||||
wait_helper.only_check_for_update = True
|
||||
|
||||
# Run the update loop
|
||||
while True:
|
||||
@@ -366,21 +435,24 @@ def main() -> None:
|
||||
|
||||
# Attempt an update
|
||||
exception = None
|
||||
new_version = False
|
||||
update_failed_count += 1
|
||||
try:
|
||||
# TODO: reuse overlay from previous updated instance if it looks clean
|
||||
init_overlay()
|
||||
|
||||
# TODO: still needed? skip this and just fetch?
|
||||
# Lightweight internt check
|
||||
internet_ok, update_available = check_for_update()
|
||||
if internet_ok and not update_available:
|
||||
update_failed_count = 0
|
||||
# ensure we have some params written soon after startup
|
||||
updater.set_params(update_failed_count, exception)
|
||||
update_failed_count += 1
|
||||
|
||||
# Fetch update
|
||||
if internet_ok:
|
||||
new_version = fetch_update()
|
||||
update_failed_count = 0
|
||||
# check for update
|
||||
params.put("UpdaterState", "checking...")
|
||||
updater.check_for_update()
|
||||
|
||||
# download update
|
||||
if wait_helper.only_check_for_update:
|
||||
cloudlog.info("skipping fetch this cycle")
|
||||
else:
|
||||
updater.fetch_update()
|
||||
update_failed_count = 0
|
||||
except subprocess.CalledProcessError as e:
|
||||
cloudlog.event(
|
||||
"update process failed",
|
||||
@@ -396,12 +468,14 @@ def main() -> None:
|
||||
overlay_init.unlink(missing_ok=True)
|
||||
|
||||
try:
|
||||
set_params(new_version, update_failed_count, exception)
|
||||
params.put("UpdaterState", "idle")
|
||||
updater.set_params(update_failed_count, exception)
|
||||
except Exception:
|
||||
cloudlog.exception("uncaught updated exception while setting params, shouldn't happen")
|
||||
|
||||
# infrequent attempts if we successfully updated recently
|
||||
wait_helper.sleep(5*60 if update_failed_count > 0 else 90*60)
|
||||
wait_helper.only_check_for_update = False
|
||||
wait_helper.sleep(5*60 if update_failed_count > 0 else 1.5*60*60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user