Skip to content

Commit 6316291

Browse files
committed
chore: 优化 Docker 镜像
1 parent e1768f9 commit 6316291

File tree

9 files changed

+419
-136
lines changed

9 files changed

+419
-136
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.12
1+
FROM docker.1ms.run/library/python:3.12
22

33
LABEL org.opencontainers.image.url https://python-openbmclapi.ttb-network.top/
44
LABEL org.opencontainers.image.source https://github.com/TTB-Network/python-openbmclapi

assets/js/common.js

Lines changed: 159 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -519,24 +519,66 @@ function createElement(object) {
519519
return new Element(object);
520520
}
521521
class RouteEvent {
522-
constructor(instance, before_route, current_route, params = {}) {
522+
constructor(manager, instance, before_route, current_route, params = {}) {
523+
this.manager = manager
523524
this.instance = instance;
524525
this.current_route = current_route
525526
this.before_route = before_route
526527
this.params = params
527528
}
528529
}
529530
class Router {
530-
constructor(route_prefix = "/") {
531+
constructor(
532+
route_prefix = "/",
533+
) {
531534
this._route_prefix = route_prefix.replace(/\/+$/, "")
532-
this._before_handlers = []
533-
this._after_handlers = []
534-
this._current_path = null; //this._get_current_path()
535535
this._routes = []
536+
this._beforeHandlers = []
537+
this._afterHandlers = []
538+
this._current_path = null
539+
}
540+
get _getCurrentPath() {
541+
return window.location.pathname.replace(this._route_prefix, "") || "/"
542+
}
543+
on(path, handler) {
544+
// path {xxx}
545+
// replace to like python (?P<xxx>*.+)
546+
var params = (path.match(/\{((\w+)|(\:(url)\:))\}/g) || []).map(x => x.replaceAll("{", "").replaceAll("}", "").replaceAll(":", ""))
547+
var regexp_path = path.replace(/\{\:(url)\:\}/g, "(.*)").replace(/\{(\w+)\}/g, "([^/]*)")
548+
var config = {
549+
raw_path: path,
550+
path: new RegExp(`^${regexp_path}$`),
551+
params: params,
552+
handler
553+
}
554+
this._routes.push(config)
555+
// sort path length
556+
this._routes.sort((a, b) => b.path.length - a.path.length)
557+
return this
558+
}
559+
beforeHandler(handler) {
560+
if (handler == null) this;
561+
this._beforeHandlers.push(handler)
562+
return this
563+
}
564+
afterHandler(handler) {
565+
if (handler == null) this;
566+
this._afterHandlers.push(handler)
567+
return this
568+
}
569+
570+
}
571+
class RouterManager {
572+
constructor(
573+
route_prefix = "/",
574+
) {
575+
this._routes = [
576+
new Router(route_prefix)
577+
]
536578
}
537579
init() {
538580
window.addEventListener("popstate", () => {
539-
this._popstate_handler()
581+
this._popstateHandler()
540582
})
541583
window.addEventListener("click", (e) => {
542584
if (e.target.tagName == "A") {
@@ -545,86 +587,134 @@ class Router {
545587
if (url.origin != window.location.origin) return;
546588
e.preventDefault()
547589
if (url.pathname.startsWith(this._route_prefix)) {
548-
this._popstate_handler(url.pathname)
590+
this._popstateHandler(url.pathname)
549591
}
550592
}
551593
})
552-
this._popstate_handler()
553-
}
554-
page(path) {
555-
this._popstate_handler(path)
594+
this._popstateHandler()
556595
}
557-
_get_current_path() {
596+
get _getCurrentPath() {
558597
return window.location.pathname
559598
}
560-
async _popstate_handler(path) {
561-
const new_path = (path ?? this._get_current_path()).replace(this._route_prefix, "") || "/"
562-
const old_path = this._current_path
563-
if (old_path == new_path) return;
564-
window.history.pushState(null, '', this._route_prefix + new_path)
565-
this._current_path = new_path
566-
this._before_handlers.forEach(handler => {
567-
try {
568-
handler(new RouteEvent(this, old_path, new_path))
569-
} catch (e) {
570-
console.log(e)
599+
_popstateHandler(path) {
600+
path = path || this._getCurrentPath
601+
const matchRoutes = []
602+
for (const router of this._routes) {
603+
if (path.startsWith(router._route_prefix)) {
604+
matchRoutes.push(router)
571605
}
606+
}
607+
if (!matchRoutes.length) matchRoutes.push(this._routes[0])
608+
const handlers = {
609+
before: [],
610+
route: [],
611+
after: []
612+
};
613+
var router = null;
614+
for (const r of matchRoutes) {
615+
let new_path = path.replace(r._route_prefix, "") || "/"
616+
var match_routes = r._routes.filter(x => x.path.test(new_path))
617+
if (match_routes.length) {
618+
router = r
619+
break
620+
}
621+
}
622+
router = router || matchRoutes[0]
623+
const old_path = router._current_path
624+
const new_path = path.replace(router._route_prefix, "") || "/"
625+
if (new_path == router._current_path) return;
626+
router._current_path = new_path
627+
window.history.pushState(null, '', router._route_prefix + new_path)
628+
for (const handler of router._beforeHandlers) {
629+
handlers.before.push(handler)
630+
}
631+
632+
// route
633+
for (const route of router._routes.filter(x => x.path.test(new_path))) {
634+
handlers.route.push(route)
635+
}
636+
// after
637+
for (const handler of router._afterHandlers) {
638+
handlers.after.push(handler)
639+
}
640+
this._run(handlers, {
641+
manager: this,
642+
router,
643+
old_path: old_path,
644+
new_path: new_path,
572645
})
646+
}
647+
_run(handlers = {
648+
before: [],
649+
route: [],
650+
after: []
651+
}, options = {
652+
manager: this,
653+
router: null,
654+
old_path: null,
655+
new_path: null,
656+
}) {
657+
var preHandle = (
658+
preHandlers
659+
) => {
660+
preHandlers.forEach(handler => {
661+
try {
662+
handler(new RouteEvent(
663+
options.manager,
664+
options.router,
665+
options.old_path,
666+
options.new_path,
667+
))
668+
} catch (e) {
669+
console.error(e)
670+
}
671+
})
672+
}
673+
preHandle(handlers.before)
573674
try {
574-
// get route
575-
var routes = this._routes.filter(x => x.path.test(new_path))
576-
if (routes) {
577-
routes.forEach(route => {
578-
var params = route.path.exec(new_path).slice(1).reduce((acc, cur, i) => {
579-
acc[route.params[i]] = cur
580-
return acc
581-
}, {})
582-
var handler = route ? route.handler : null
583-
if (handler) {
584-
try {
585-
handler(new RouteEvent(this, old_path, new_path, params))
586-
} catch (e) {
587-
console.log(e)
588-
}
675+
handlers.route.forEach(route => {
676+
var params = route.path.exec(options.new_path).slice(1).reduce((acc, cur, i) => {
677+
acc[route.params[i]] = cur
678+
return acc
679+
}, {})
680+
var handler = route ? route.handler : null
681+
if (handler) {
682+
try {
683+
handler(new RouteEvent(
684+
options.manager,
685+
options.router,
686+
options.old_path,
687+
options.new_path,
688+
params
689+
))
690+
} catch (e) {
691+
console.log(e)
589692
}
590-
})
591-
592-
}
693+
}
694+
})
593695
} catch (e) {
594-
console.log(e)
696+
console.error(e)
697+
595698
}
596-
this._after_handlers.forEach(handler => {
597-
try {
598-
handler(new RouteEvent(this, old_path, new_path))
599-
} catch (e) {
600-
console.log(e)
601-
}
602-
})
699+
preHandle(handlers.after)
700+
return true
603701
}
604702
on(path, handler) {
605-
// path {xxx}
606-
// replace to like python (?P<xxx>*.+)
607-
var params = (path.match(/\{((\w+)|(\:(url)\:))\}/g) || []).map(x => x.replaceAll("{", "").replaceAll("}", "").replaceAll(":", ""))
608-
var regexp_path = path.replace(/\{\:(url)\:\}/g, "(.*)").replace(/\{(\w+)\}/g, "([^/]*)")
609-
var config = {
610-
raw_path: path,
611-
path: new RegExp(`^${regexp_path}$`),
612-
params: params,
613-
handler
614-
}
615-
this._routes.push(config)
616-
// sort path length
617-
this._routes.sort((a, b) => b.path.length - a.path.length)
703+
this._routes[0].on(path, handler)
618704
return this
619705
}
620-
before_handler(handler) {
621-
if (handler == null) this;
622-
this._before_handlers.push(handler)
706+
beforeHandler(handler) {
707+
this._routes[0].beforeHandler(handler)
623708
return this
624709
}
625-
after_handler(handler) {
626-
if (handler == null) this;
627-
this._after_handlers.push(handler)
710+
afterHandler(handler) {
711+
this._routes[0].afterHandler(handler)
712+
return this
713+
}
714+
page(path) {
715+
this._popstateHandler(
716+
this._routes[0]._route_prefix + path
717+
)
628718
return this
629719
}
630720
}
@@ -1077,6 +1167,7 @@ export {
10771167
createElement,
10781168
Configuration,
10791169
Router,
1170+
RouterManager,
10801171
ElementManager,
10811172
I18NManager,
10821173
Style,

assets/js/index.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
Utils,
1313
ObjectID,
1414
ref,
15-
THEMECHANGEEVENT
15+
THEMECHANGEEVENT,
16+
RouterManager,
1617
} from './common.js'
1718

1819
import './config.js'
@@ -129,7 +130,7 @@ class Menu extends Element {
129130
this._render()
130131
})
131132
var cur_key, cur_sub;
132-
$router.before_handler(async (event) => {
133+
$router.beforeHandler(async (event) => {
133134
if (this._render_task) await new Promise((resolve) => {
134135
this.route_handler_lock = resolve
135136
})
@@ -200,12 +201,18 @@ class Channel {
200201
current: 0,
201202
};
202203
this.timeout = 10000
204+
this._event_source_init()
203205
if (!this.support_websocket) return;
204206
this._ws_init();
205207
this._ws_initizalized = false;
206208
this._ws_callbacks = {};
207209
this._ws_timeouts = {}
208210
}
211+
// event source
212+
_event_source_init() {
213+
this._event_source = new EventSource(this.url + "_event");
214+
215+
}
209216
// websocket
210217
_ws_init() {
211218
this._ws = new WebSocket("ws" + this.url.slice(4));
@@ -714,7 +721,7 @@ const $configuration = new Configuration();
714721
const $ElementManager = new ElementManager();
715722
const $style = new Style($configuration);
716723
const $i18n = new I18NManager();
717-
const $router = new Router("/pages");
724+
const $router = new RouterManager("/pages");
718725
globalThis.$channel = new Channel();
719726
$i18n.addLanguageTable("zh_CN", {
720727
"footer.powered_by": "由 %name% 提供服务支持",
@@ -1051,6 +1058,16 @@ class Tools {
10511058
return `${d.getFullYear().toString().padStart(4, "0")}-${(d.getMonth() + 1).toString().padStart(2, "0")}-${d.getDate().toString().padStart(2, "0")}`
10521059
}
10531060
}
1061+
class UserAuth {
1062+
constructor() {
1063+
$router.on("/auth", () => {
1064+
// ...
1065+
})
1066+
}
1067+
}
1068+
1069+
const $userAuth = new UserAuth();
1070+
10541071
async function load() {
10551072
const $dom_body = new Element(document.body);
10561073
const $theme = {
@@ -1822,7 +1839,7 @@ async function load() {
18221839
clearInterval($dashboard_locals.qps_task)
18231840
}
18241841

1825-
$router.before_handler(() => {
1842+
$router.beforeHandler(() => {
18261843
while ($main.firstChild != null) {
18271844
$main.removeChild($main.firstChild)
18281845
}

assets/js/pwa.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class ProgressiveWebApp {
2+
constructor() {
3+
if (!this.supportPWA()) {
4+
return;
5+
}
6+
this.register()
7+
}
8+
9+
register() {
10+
navigator.serviceWorker.register('/service-worker.js').then(e => {
11+
console.log('Service Worker registered successfully', e);
12+
}).catch(e => {
13+
console.log('Service Worker registration failed', e);
14+
});
15+
}
16+
17+
supportPWA() {
18+
return 'serviceWorker' in navigator;
19+
}
20+
}
21+
22+
export const pwa = new ProgressiveWebApp();

assets/js/service-worker.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
self.addEventListener('install', function(event) {
2+
})
3+
self.addEventListener('push', function (event) {
4+
event.waitUntil(
5+
self.registration.showNotification('新消息', {
6+
body: '你有一条新消息,请查看!',
7+
icon: 'icon.png',
8+
vibrate: [200, 100, 200],
9+
data: {
10+
url: 'https://your-website.com/message'
11+
}
12+
})
13+
);
14+
});

0 commit comments

Comments
 (0)