Merge branch 'dev' into 'main'

Merging dev into main

See merge request mx-moment/moment!19
This commit is contained in:
Maze 2022-09-08 18:10:52 +00:00
commit 4c3a8444c6
7 changed files with 52 additions and 143 deletions

View File

@ -507,33 +507,6 @@ class Backend:
ping=sum(times) // len(times), status=PingStatus.Done, ping=sum(times) // len(times), status=PingStatus.Done,
) )
def _get_homeserver_stability(
self, logs: List[Dict[str, Any]],
) -> Tuple[float, List[timedelta]]:
"""Return server stability % and a list of downtime durations."""
stability = 100.0
durations = []
for period in logs:
started_at = datetime.fromtimestamp(period["datetime"])
time_since_now = datetime.now() - started_at
if time_since_now.days > 30 or period["type"] != 1: # 1 = downtime
continue
lasted_minutes = period["duration"] / 60
durations.append(timedelta(seconds=period["duration"]))
stability -= (
(lasted_minutes * stability / 1000) /
max(1, time_since_now.days / 3)
)
return (stability, durations)
async def fetch_homeservers(self) -> None: async def fetch_homeservers(self) -> None:
"""Retrieve a list of public homeservers and add them to our model.""" """Retrieve a list of public homeservers and add them to our model."""
@ -557,7 +530,7 @@ class Backend:
connector = session.connector, connector = session.connector,
) )
api_list = "https://publiclist.anchel.nl/publiclist.json" api_list = "https://joinmatrix.org/servers.json"
try: try:
response = await session.get(api_list) response = await session.get(api_list)
except: except:
@ -568,27 +541,19 @@ class Backend:
coros = [] coros = []
for server in (await response.json()): for server in (await response.json()):
homeserver_url = server["homeserver"] homeserver_url = "https://" + server["domain"]
if homeserver_url.startswith("http://"): # insecure server if not server["open"]: # ignore closed servers
continue continue
if not re.match(r"^https?://.+", homeserver_url):
homeserver_url = f"https://{homeserver_url}"
if server["country"] == "USA":
server["country"] = "United States"
stability, durations = \
self._get_homeserver_stability(server["monitor"]["logs"])
self.models["homeservers"][homeserver_url] = Homeserver( self.models["homeservers"][homeserver_url] = Homeserver(
id = homeserver_url, id = homeserver_url,
name = server["name"], name = server["name"],
site_url = server["url"], site_url = server["domain"],
country = server["country"], country = server["jurisdiction"],
stability = stability, stability = 0,
downtimes_ms = [d.total_seconds() * 1000 for d in durations], downtimes_ms = 0,
# austin's list doesn't have stability/downtime
) )
coros.append(self._ping_homeserver(session, homeserver_url)) coros.append(self._ping_homeserver(session, homeserver_url))

View File

@ -1,59 +0,0 @@
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
// and Moment contributors <https://gitlab.com/mx-moment/moment>
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma Singleton
import QtQuick 2.12
QtObject {
property bool startInTray: false
property string loadQml: ""
readonly property string help: `Usage: ${Qt.application.name} [options]
Options:
-t, --start-in-tray Start in the system tray, without a visible window
-l, --load-qml PATH Override the file to be loaded as src/gui/UI.qml
-V, --version Show the application's version and exit
-h, --help Show this help and exit
Environment variables:
MOMENT_CONFIG_DIR Override the default configuration folder
MOMENT_DATA_DIR Override the default application data folder
MOMENT_CACHE_DIR Override the default cache and downloads folder
http_proxy Override the General.proxy setting, see settings.py
`
readonly property bool ready: {
const passedArguments = Qt.application.arguments.slice(1)
while (passedArguments.length) {
switch (passedArguments.shift()) {
case "-h":
case "--help":
print("\n\n" + help.replace(/^ {4}/gm, ""))
Qt.quit()
break
case "-v":
case "--version":
print(Qt.application.version)
Qt.quit()
break
case "-t":
case "--start-in-tray":
startInTray = true
break
case "-l":
case "--load-qml":
loadQml = passedArguments.shift()
break
}
}
return true
}
}

View File

@ -115,7 +115,6 @@ HBox {
model: [ model: [
qsTr("Ping"), qsTr("Ping"),
qsTr("Name & location"), qsTr("Name & location"),
qsTr("Stability"),
qsTr("Site"), qsTr("Site"),
] ]

View File

@ -66,44 +66,10 @@ HTile {
} }
} }
TitleRightInfoLabel {
tile: root
font.pixelSize: theme.fontSize.normal
text:
model.stability === -1 ?
"" :
qsTr("%1%").arg(Math.max(0, parseInt(model.stability, 10)))
color:
model.stability >= 95 ? theme.colors.positiveText :
model.stability >= 85 ? theme.colors.warningText :
theme.colors.errorText
HoverHandler { id: rightInfoHover }
HToolTip {
readonly property var times: JSON.parse(model.downtimes_ms)
readonly property real total: utils.sum(times)
visible: model.stability !== -1 && rightInfoHover.hovered
text:
total === 0 ?
qsTr("No downtimes in the last 30 days") :
qsTr(
"Last 30 days downtimes: %1, average: %2, " +
"longest: %3, total: %4"
).arg(times.length)
.arg(utils.formatRelativeTime(total / times.length))
.arg(utils.formatRelativeTime(Math.max.apply(Math,times)))
.arg(utils.formatRelativeTime(total))
}
}
HButton { HButton {
icon.name: "server-visit-website" icon.name: "server-visit-website"
backgroundColor: "transparent" backgroundColor: "transparent"
onClicked: Qt.openUrlExternally(model.site_url) onClicked: Qt.openUrlExternally("https://"+model.site_url)
Layout.fillHeight: true Layout.fillHeight: true
} }

View File

@ -28,6 +28,8 @@ ApplicationWindow {
property var theme: null property var theme: null
property var themeRules: null property var themeRules: null
property string settingsFolder property string settingsFolder
property bool startInTray
property string loadQml
readonly property var visibleMenus: ({}) readonly property var visibleMenus: ({})
readonly property var visiblePopups: ({}) readonly property var visiblePopups: ({})
@ -98,7 +100,7 @@ ApplicationWindow {
minimumHeight: theme ? theme.minimumSupportedHeight : 120 minimumHeight: theme ? theme.minimumSupportedHeight : 120
width: Math.min(screen.width, 1152) width: Math.min(screen.width, 1152)
height: Math.min(screen.height, 768) height: Math.min(screen.height, 768)
visible: ArgumentParser.ready && ! ArgumentParser.startInTray visible: ! startInTray
color: "transparent" color: "transparent"
onClosing: if (py.ready && settings.General.close_to_tray) { onClosing: if (py.ready && settings.General.close_to_tray) {
@ -123,8 +125,8 @@ ApplicationWindow {
focus: true focus: true
scale: py.ready ? 1 : 0.5 scale: py.ready ? 1 : 0.5
source: source:
ArgumentParser.ready && py.ready ? py.ready ?
(ArgumentParser.loadQml || "UI.qml") : (loadQml || "UI.qml") :
"" ""
Behavior on scale { HNumberAnimation { overshoot: 3; factor: 1.2 } } Behavior on scale { HNumberAnimation { overshoot: 3; factor: 1.2 } }

View File

@ -1,2 +1 @@
singleton ModelStore 0.1 ModelStore.qml singleton ModelStore 0.1 ModelStore.qml
singleton ArgumentParser 0.1 ArgumentParser.qml

View File

@ -19,6 +19,8 @@
#include <QFile> #include <QFile>
#include <QLockFile> #include <QLockFile>
#include <QMessageBox> #include <QMessageBox>
#include <QCommandLineParser>
#include <iostream>
#include <signal.h> #include <signal.h>
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
@ -372,6 +374,38 @@ int main(int argc, char *argv[]) {
// because migrate displays a popup dialog // because migrate displays a popup dialog
QApplication app(argc, argv); QApplication app(argc, argv);
QCommandLineParser args;
QCommandLineOption startInTrayOption(QStringList() << "t" << "start-in-tray",
"Start in the system tray, without a visible window.");
args.addOption(startInTrayOption);
QCommandLineOption loadQmlOption(QStringList() << "l" << "load-qml",
"Override the file to be loaded as src/gui/UI.qml", "PATH");
args.addOption(loadQmlOption);
QCommandLineOption helpOption(QStringList() << "h" << "help",
"Displays help on commandline options.");
args.addOption(helpOption);
args.addVersionOption();
args.process(app);
if (args.isSet(helpOption)) {
std::cout << args.helpText().toStdString() << std::endl
<< "Environment variables:" << std::endl
<< " MOMENT_CONFIG_DIR Override the configuration folder"
<< std::endl
<< " MOMENT_DATA_DIR Override the application data folder"
<< std::endl
<< " MOMENT_CACHE_DIR Override the cache and downloads folder"
<< std::endl
<< " http_proxy Override the General.proxy setting, see "
<< "settings.py" << std::endl;
exit(EXIT_SUCCESS);
}
if (shouldMigrateFromMirage()) tryMigrateFromMirage(); if (shouldMigrateFromMirage()) tryMigrateFromMirage();
QString customConfigDir(qEnvironmentVariable("MOMENT_CONFIG_DIR")); QString customConfigDir(qEnvironmentVariable("MOMENT_CONFIG_DIR"));
@ -489,7 +523,10 @@ int main(int argc, char *argv[]) {
app.exit(EXIT_FAILURE); app.exit(EXIT_FAILURE);
} }
component.create(objectContext)->setProperty("settingsFolder", settingsFolder); QObject *comp = component.create(objectContext);
comp->setProperty("settingsFolder", "file://"+settingsFolder);
comp->setProperty("startInTray", args.isSet(startInTrayOption));
comp->setProperty("loadQml", args.value(loadQmlOption));
// Finally, execute the app. Return its exit code after clearing the lock. // Finally, execute the app. Return its exit code after clearing the lock.
int exit_code = app.exec(); int exit_code = app.exec();