tangram-system 0.2.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <div class="system-widget">
3
+ <div
4
+ class="clock"
5
+ @mouseover="state.hovered = true"
6
+ @mouseleave="state.hovered = false"
7
+ >
8
+ <span id="info_time">{{ state.hovered ? local_time : utc_time }}</span>
9
+ </div>
10
+ <span id="uptime">{{ state.uptime }}</span>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { reactive, computed, inject, onMounted, onUnmounted } from "vue";
16
+ import type { TangramApi, Disposable } from "@open-aviation/tangram-core/api";
17
+
18
+ const tangramApi = inject<TangramApi>("tangramApi");
19
+ if (!tangramApi) {
20
+ throw new Error("assert: tangram api not provided");
21
+ }
22
+
23
+ const state = reactive({
24
+ hovered: false,
25
+ uptime: "",
26
+ info_utc: new Date().getTime()
27
+ });
28
+
29
+ let subscription: Disposable | null = null;
30
+
31
+ onMounted(async () => {
32
+ try {
33
+ subscription = await tangramApi.realtime.subscribe(
34
+ "system:update-node",
35
+ (payload: { el: string; value: any }) => {
36
+ if (payload.el === "uptime") state.uptime = payload.value;
37
+ if (payload.el === "info_utc") state.info_utc = payload.value;
38
+ }
39
+ );
40
+ } catch (e) {
41
+ console.error("failed to subscribe to system:update-node", e);
42
+ }
43
+ });
44
+
45
+ onUnmounted(() => {
46
+ subscription?.dispose();
47
+ });
48
+
49
+ const utc_time = computed(() => {
50
+ const date = new Date(state.info_utc);
51
+ const hours = date.getUTCHours().toString().padStart(2, "0");
52
+ const minutes = date.getUTCMinutes().toString().padStart(2, "0");
53
+ const seconds = date.getUTCSeconds().toString().padStart(2, "0");
54
+ return `${hours}:${minutes}:${seconds} Z`;
55
+ });
56
+
57
+ const local_time = computed(() => {
58
+ const date = new Date(state.info_utc);
59
+ return date.toLocaleTimeString([], {
60
+ hour: "2-digit",
61
+ minute: "2-digit",
62
+ second: "2-digit",
63
+ hour12: false,
64
+ timeZoneName: "shortOffset"
65
+ });
66
+ });
67
+ </script>
68
+
69
+ <style scoped>
70
+ #uptime {
71
+ color: #79706e;
72
+ font-size: 9pt;
73
+ text-align: center;
74
+ }
75
+
76
+ .system-widget {
77
+ display: flex;
78
+ flex-direction: column;
79
+ align-items: center;
80
+ padding: 1px;
81
+ border-bottom: 1px solid #ddd;
82
+ }
83
+ </style>
@@ -0,0 +1,65 @@
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ from datetime import datetime, timedelta, timezone
5
+ from typing import NoReturn
6
+
7
+ import psutil
8
+ import redis.asyncio as redis
9
+ import tangram_core
10
+
11
+ log = logging.getLogger(__name__)
12
+
13
+
14
+ def uptime(counter: int) -> dict[str, str]:
15
+ return {
16
+ "el": "uptime",
17
+ "value": f"{timedelta(seconds=counter)}",
18
+ }
19
+
20
+
21
+ def info_utc() -> dict[str, str | int]:
22
+ return {
23
+ "el": "info_utc",
24
+ "value": 1000 * int(datetime.now(timezone.utc).timestamp()),
25
+ }
26
+
27
+
28
+ def cpu_load() -> dict[str, str]:
29
+ try:
30
+ load1, _load5, _load15 = psutil.getloadavg()
31
+ cpu_count = psutil.cpu_count(logical=True) or 1
32
+ load_percent = (load1 / cpu_count) * 100
33
+ return {"el": "cpu_load", "value": f"{load_percent:.2f}%"}
34
+ except Exception:
35
+ return {"el": "cpu_load", "value": "Unavailable"}
36
+
37
+
38
+ def ram_usage() -> dict[str, str]:
39
+ try:
40
+ mem = psutil.virtual_memory()
41
+ return {"el": "ram_usage", "value": f"{mem.percent:.2f}%"}
42
+ except Exception:
43
+ return {"el": "ram_usage", "value": "Unavailable"}
44
+
45
+
46
+ async def server_events(redis_client: redis.Redis) -> NoReturn:
47
+ counter = 0
48
+ log.info("serving system events...")
49
+
50
+ while True:
51
+ await redis_client.publish("to:system:update-node", json.dumps(uptime(counter)))
52
+ await redis_client.publish("to:system:update-node", json.dumps(info_utc()))
53
+ await redis_client.publish("to:system:update-node", json.dumps(cpu_load()))
54
+ await redis_client.publish("to:system:update-node", json.dumps(ram_usage()))
55
+ counter += 1
56
+
57
+ await asyncio.sleep(1)
58
+
59
+
60
+ plugin = tangram_core.Plugin(frontend_path="dist-frontend")
61
+
62
+
63
+ @plugin.register_service()
64
+ async def run_system(backend_state: tangram_core.BackendState) -> None:
65
+ await server_events(backend_state.redis_client)
@@ -0,0 +1 @@
1
+ #uptime[data-v-6f95989c]{color:#79706e;font-size:9pt;text-align:center}.system-widget[data-v-6f95989c]{display:flex;flex-direction:column;align-items:center;padding:1px;border-bottom:1px solid #ddd}
@@ -0,0 +1,61 @@
1
+ import { defineComponent as l, inject as _, reactive as f, onMounted as g, onUnmounted as v, computed as u, createElementBlock as S, openBlock as h, createElementVNode as c, toDisplayString as d } from "vue";
2
+ const w = { class: "system-widget" }, y = { id: "info_time" }, T = { id: "uptime" }, b = /* @__PURE__ */ l({
3
+ __name: "SystemWidget",
4
+ setup(n) {
5
+ const s = _("tangramApi");
6
+ if (!s)
7
+ throw new Error("assert: tangram api not provided");
8
+ const e = f({
9
+ hovered: !1,
10
+ uptime: "",
11
+ info_utc: (/* @__PURE__ */ new Date()).getTime()
12
+ });
13
+ let i = null;
14
+ g(async () => {
15
+ try {
16
+ i = await s.realtime.subscribe(
17
+ "system:update-node",
18
+ (t) => {
19
+ t.el === "uptime" && (e.uptime = t.value), t.el === "info_utc" && (e.info_utc = t.value);
20
+ }
21
+ );
22
+ } catch (t) {
23
+ console.error("failed to subscribe to system:update-node", t);
24
+ }
25
+ }), v(() => {
26
+ i?.dispose();
27
+ });
28
+ const r = u(() => {
29
+ const t = new Date(e.info_utc), o = t.getUTCHours().toString().padStart(2, "0"), a = t.getUTCMinutes().toString().padStart(2, "0"), p = t.getUTCSeconds().toString().padStart(2, "0");
30
+ return `${o}:${a}:${p} Z`;
31
+ }), m = u(() => new Date(e.info_utc).toLocaleTimeString([], {
32
+ hour: "2-digit",
33
+ minute: "2-digit",
34
+ second: "2-digit",
35
+ hour12: !1,
36
+ timeZoneName: "shortOffset"
37
+ }));
38
+ return (t, o) => (h(), S("div", w, [
39
+ c("div", {
40
+ class: "clock",
41
+ onMouseover: o[0] || (o[0] = (a) => e.hovered = !0),
42
+ onMouseleave: o[1] || (o[1] = (a) => e.hovered = !1)
43
+ }, [
44
+ c("span", y, d(e.hovered ? m.value : r.value), 1)
45
+ ], 32),
46
+ c("span", T, d(e.uptime), 1)
47
+ ]));
48
+ }
49
+ }), $ = (n, s) => {
50
+ const e = n.__vccOpts || n;
51
+ for (const [i, r] of s)
52
+ e[i] = r;
53
+ return e;
54
+ }, k = /* @__PURE__ */ $(b, [["__scopeId", "data-v-6f95989c"]]);
55
+ function D(n) {
56
+ n.ui.registerWidget("system-widget", "TopBar", k);
57
+ }
58
+ export {
59
+ D as install
60
+ };
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/tangram_system/SystemWidget.vue","../src/tangram_system/index.ts"],"sourcesContent":["<template>\n <div class=\"system-widget\">\n <div\n class=\"clock\"\n @mouseover=\"state.hovered = true\"\n @mouseleave=\"state.hovered = false\"\n >\n <span id=\"info_time\">{{ state.hovered ? local_time : utc_time }}</span>\n </div>\n <span id=\"uptime\">{{ state.uptime }}</span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { reactive, computed, inject, onMounted, onUnmounted } from \"vue\";\nimport type { TangramApi, Disposable } from \"@open-aviation/tangram-core/api\";\n\nconst tangramApi = inject<TangramApi>(\"tangramApi\");\nif (!tangramApi) {\n throw new Error(\"assert: tangram api not provided\");\n}\n\nconst state = reactive({\n hovered: false,\n uptime: \"\",\n info_utc: new Date().getTime()\n});\n\nlet subscription: Disposable | null = null;\n\nonMounted(async () => {\n try {\n subscription = await tangramApi.realtime.subscribe(\n \"system:update-node\",\n (payload: { el: string; value: any }) => {\n if (payload.el === \"uptime\") state.uptime = payload.value;\n if (payload.el === \"info_utc\") state.info_utc = payload.value;\n }\n );\n } catch (e) {\n console.error(\"failed to subscribe to system:update-node\", e);\n }\n});\n\nonUnmounted(() => {\n subscription?.dispose();\n});\n\nconst utc_time = computed(() => {\n const date = new Date(state.info_utc);\n const hours = date.getUTCHours().toString().padStart(2, \"0\");\n const minutes = date.getUTCMinutes().toString().padStart(2, \"0\");\n const seconds = date.getUTCSeconds().toString().padStart(2, \"0\");\n return `${hours}:${minutes}:${seconds} Z`;\n});\n\nconst local_time = computed(() => {\n const date = new Date(state.info_utc);\n return date.toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n timeZoneName: \"shortOffset\"\n });\n});\n</script>\n\n<style scoped>\n#uptime {\n color: #79706e;\n font-size: 9pt;\n text-align: center;\n}\n\n.system-widget {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 1px;\n border-bottom: 1px solid #ddd;\n}\n</style>\n","import type { TangramApi } from \"@open-aviation/tangram-core/api\";\nimport SystemWidget from \"./SystemWidget.vue\";\n\nexport function install(api: TangramApi) {\n api.ui.registerWidget(\"system-widget\", \"TopBar\", SystemWidget);\n}\n"],"names":["tangramApi","inject","state","reactive","subscription","onMounted","payload","e","onUnmounted","utc_time","computed","date","hours","minutes","seconds","local_time","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_cache","$event","_hoisted_2","_toDisplayString","_hoisted_3","install","api","SystemWidget"],"mappings":";;;;AAiBA,UAAMA,IAAaC,EAAmB,YAAY;AAClD,QAAI,CAACD;AACH,YAAM,IAAI,MAAM,kCAAkC;AAGpD,UAAME,IAAQC,EAAS;AAAA,MACrB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAU,oBAAI,KAAA,GAAO,QAAA;AAAA,IAAQ,CAC9B;AAED,QAAIC,IAAkC;AAEtC,IAAAC,EAAU,YAAY;AACpB,UAAI;AACF,QAAAD,IAAe,MAAMJ,EAAW,SAAS;AAAA,UACvC;AAAA,UACA,CAACM,MAAwC;AACvC,YAAIA,EAAQ,OAAO,aAAUJ,EAAM,SAASI,EAAQ,QAChDA,EAAQ,OAAO,eAAYJ,EAAM,WAAWI,EAAQ;AAAA,UAC1D;AAAA,QAAA;AAAA,MAEJ,SAASC,GAAG;AACV,gBAAQ,MAAM,6CAA6CA,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC,GAEDC,EAAY,MAAM;AAChB,MAAAJ,GAAc,QAAA;AAAA,IAChB,CAAC;AAED,UAAMK,IAAWC,EAAS,MAAM;AAC9B,YAAMC,IAAO,IAAI,KAAKT,EAAM,QAAQ,GAC9BU,IAAQD,EAAK,YAAA,EAAc,WAAW,SAAS,GAAG,GAAG,GACrDE,IAAUF,EAAK,cAAA,EAAgB,WAAW,SAAS,GAAG,GAAG,GACzDG,IAAUH,EAAK,cAAA,EAAgB,WAAW,SAAS,GAAG,GAAG;AAC/D,aAAO,GAAGC,CAAK,IAAIC,CAAO,IAAIC,CAAO;AAAA,IACvC,CAAC,GAEKC,IAAaL,EAAS,MACb,IAAI,KAAKR,EAAM,QAAQ,EACxB,mBAAmB,IAAI;AAAA,MACjC,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,cAAc;AAAA,IAAA,CACf,CACF;sBAhECc,EAAA,GAAAC,EASM,OATNC,GASM;AAAA,MARJC,EAMM,OAAA;AAAA,QALJ,OAAM;AAAA,QACL,aAASC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEnB,EAAM,UAAO;AAAA,QACxB,cAAUkB,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEnB,EAAM,UAAO;AAAA,MAAA;QAE1BiB,EAAuE,QAAvEG,GAAuEC,EAA/CrB,EAAM,UAAUa,EAAA,QAAaN,EAAA,KAAQ,GAAA,CAAA;AAAA,MAAA;MAE/DU,EAA2C,QAA3CK,GAA2CD,EAAtBrB,EAAM,MAAM,GAAA,CAAA;AAAA,IAAA;;;;;;;;ACN9B,SAASuB,EAAQC,GAAiB;AACvC,EAAAA,EAAI,GAAG,eAAe,iBAAiB,UAAUC,CAAY;AAC/D;"}
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@open-aviation/tangram-system",
3
+ "main": "index.js",
4
+ "style": "index.css"
5
+ }
@@ -0,0 +1,6 @@
1
+ import type { TangramApi } from "@open-aviation/tangram-core/api";
2
+ import SystemWidget from "./SystemWidget.vue";
3
+
4
+ export function install(api: TangramApi) {
5
+ api.ui.registerWidget("system-widget", "TopBar", SystemWidget);
6
+ }
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: tangram_system
3
+ Version: 0.2.0
4
+ Author-email: Xavier Olive <git@xoolive.org>, Junzi Sun <git@junzis.com>
5
+ Requires-Dist: psutil
6
+ Requires-Dist: tangram-core>=0.2.0
7
+ Description-Content-Type: text/markdown
8
+
9
+ # System plugin
10
+
11
+ This plugin does not provide any API endpoints, but it is used to start an async task that will run in the background. This task is used to perform various system-related operations, such as checking the status of the system, performing maintenance tasks, etc.
@@ -0,0 +1,11 @@
1
+ tangram_system/SystemWidget.vue,sha256=dsjhwdmU6xfWDYLSVmY8rzt9Fn_B8DW4hhTcL0gMT44,2037
2
+ tangram_system/__init__.py,sha256=gNrE1ZVfzOxYtPqQbHizxptYPYFUO-A1RnL4uvG76HI,1848
3
+ tangram_system/index.ts,sha256=rLbzLMc9S5ywLhxFbF5swz0JE5vpIpB7FM6yx-d4QNs,226
4
+ tangram_system/dist-frontend/index.css,sha256=6beQc-XgozcxNvMjZ-wBX9OhyNJO00fm0F_tOu0kaD8,199
5
+ tangram_system/dist-frontend/index.js,sha256=du72pO4N1sl65r0YmoiYqo2DkELNJXuxvuwNH6KI8os,2068
6
+ tangram_system/dist-frontend/index.js.map,sha256=5wWy0lCVN-uUxu00tgV-dWpy3es98L2z7VhJHruXA1U,4321
7
+ tangram_system/dist-frontend/plugin.json,sha256=f9ITIfSjnW0OhcoQa6pp3HgxSLxDszLCLiZ6H2coz9A,91
8
+ tangram_system-0.2.0.dist-info/METADATA,sha256=YpMcg-Tr4AXlycIs_PcPFFhAA-JmShzl0UsM3LwnHtM,507
9
+ tangram_system-0.2.0.dist-info/WHEEL,sha256=aha0VrrYvgDJ3Xxl3db_g_MDIW-ZexDdrc_m-Hk8YY4,105
10
+ tangram_system-0.2.0.dist-info/entry_points.txt,sha256=lC7Uu8HPLHLg2ULa0lh2SWTN2qt_LrPFUrcqVL4heZk,62
11
+ tangram_system-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [tangram_core.plugins]
2
+ tangram_system = tangram_system:plugin