mirror of
https://github.com/kenzok8/small-package
synced 2025-01-07 07:06:58 +08:00
update 2022-09-05 17:12:47
This commit is contained in:
parent
6d63157ef8
commit
53dea0465c
86
alist/Makefile
Normal file
86
alist/Makefile
Normal file
@ -0,0 +1,86 @@
|
||||
#
|
||||
# Copyright (C) 2015-2016 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=alist
|
||||
PKG_VERSION:=2.6.4
|
||||
PKG_WEB_VERSION:=2.6.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/alist-org/alist/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=3860f5cec5d809159c55498874c472386cd6142a932a5e7bbfb3b0f569e3e12b
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
PKG_MAINTAINER:=sbwml <admin@cooluc.com>
|
||||
|
||||
define Download/$(PKG_NAME)-web
|
||||
FILE:=$(PKG_NAME)-web-$(PKG_WEB_VERSION).tar.gz
|
||||
URL_FILE:=dist.tar.gz
|
||||
URL:=https://github.com/alist-org/web-v2/releases/download/$(PKG_WEB_VERSION)/
|
||||
HASH:=4189ce3c523e6b8f6bba55faefabc926f6ef793c8755c5c2a2d3f75532fb2243
|
||||
endef
|
||||
|
||||
PKG_CONFIG_DEPENDS:=CONFIG_ALIST_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/Xhofe/alist
|
||||
ALIST_PKG:=github.com/Xhofe/alist/conf
|
||||
GO_PKG_LDFLAGS:=-w -s
|
||||
GO_PKG_LDFLAGS_X:=$(ALIST_PKG).GitTag=v$(PKG_VERSION)-$(ARCH)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/$(PKG_NAME)/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=Alist - Main program
|
||||
URL:=https://alist-doc.nn.ci/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
A file list program that supports multiple storage
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
$(call Package/alist/Default)
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
config ALIST_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
default n
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
$(eval $(call Download,$(PKG_NAME)-web))
|
||||
$(TAR) --strip-components=1 -C $(PKG_BUILD_DIR)/public -xzf $(DL_DIR)/$(PKG_NAME)-web-$(PKG_WEB_VERSION).tar.gz
|
||||
$(CP) ./files/assets/. $(PKG_BUILD_DIR)/public/assets/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifneq ($(CONFIG_ALIST_COMPRESS_UPX),)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/alist
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/alist $(1)/usr/bin
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,$(PKG_NAME)))
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
10
alist/files/assets/circle_center.svg
Normal file
10
alist/files/assets/circle_center.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="640pt" height="640pt" viewBox="0 0 640 640" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="#75c4beff">
|
||||
<path fill="#75c4be" opacity="1.00" d=" M 326.33 53.46 C 332.73 52.13 339.80 52.94 345.24 56.78 C 351.10 60.95 355.42 66.87 359.18 72.91 C 413.13 162.45 466.15 252.54 519.63 342.37 C 533.77 366.22 548.04 389.99 561.98 413.97 C 565.57 420.47 569.65 426.80 572.11 433.85 C 574.71 442.80 575.26 452.42 573.40 461.58 C 571.16 471.91 563.67 480.51 554.58 485.59 C 547.15 489.94 538.61 492.34 529.99 492.34 C 471.66 492.39 413.33 492.32 355.00 492.38 C 347.28 492.31 339.07 491.06 332.84 486.14 C 328.67 482.79 324.78 478.42 323.87 472.98 C 322.65 465.12 324.45 457.05 328.13 450.06 C 332.44 441.85 337.43 434.01 341.95 425.92 C 350.12 411.30 359.31 397.29 367.87 382.90 C 373.02 374.40 381.07 366.99 391.06 365.01 C 405.38 363.19 421.45 374.82 420.76 390.02 C 420.53 403.34 411.28 413.77 406.46 425.58 C 405.37 428.57 403.57 432.32 405.76 435.24 C 409.97 437.89 415.19 437.95 420.00 438.17 C 444.00 438.20 467.99 438.13 491.99 438.21 C 496.40 438.12 501.06 438.21 505.15 436.27 C 506.87 435.57 507.96 433.81 507.89 431.96 C 507.85 428.01 505.68 424.52 503.79 421.19 C 495.41 407.20 487.36 393.02 479.03 379.00 C 435.55 304.25 391.71 229.71 347.81 155.20 C 344.09 149.60 341.53 143.14 336.78 138.28 C 334.65 135.85 330.80 136.63 329.07 139.11 C 324.76 144.59 321.32 150.70 317.65 156.62 C 258.22 256.83 198.68 356.97 139.09 457.08 C 134.67 465.40 129.90 473.61 124.01 480.99 C 118.33 487.59 110.05 492.53 101.18 492.56 C 92.76 491.73 84.50 487.48 79.39 480.65 C 75.14 474.46 74.64 466.37 76.43 459.25 C 78.16 451.11 82.97 444.19 87.22 437.20 C 128.26 367.34 169.88 297.83 211.19 228.13 C 234.01 189.69 256.88 151.28 279.84 112.92 C 287.23 99.22 295.72 86.17 303.81 72.89 C 309.02 64.44 316.29 55.89 326.33 53.46 Z" />
|
||||
</g>
|
||||
<g id="#2c9fd6ff">
|
||||
<path fill="#2c9fd6" opacity="1.00" d=" M 329.35 261.14 C 337.95 260.38 347.26 263.39 353.07 269.98 C 357.77 275.75 360.69 283.43 358.96 290.91 C 357.79 299.89 351.32 306.64 347.61 314.57 C 342.19 323.76 336.45 332.76 331.05 341.96 C 324.62 354.04 316.79 365.31 310.38 377.39 C 305.41 384.56 301.54 392.40 296.78 399.71 C 290.29 410.33 284.30 421.24 277.99 431.97 C 267.62 447.21 259.73 463.97 249.08 479.02 C 244.35 485.33 237.50 490.71 229.49 491.80 C 223.07 492.98 216.60 490.64 210.88 487.89 C 205.68 484.07 200.75 478.79 200.12 472.05 C 199.38 464.91 199.56 456.96 203.97 450.94 C 209.04 444.01 211.63 435.67 216.66 428.72 C 221.89 421.34 225.45 412.96 230.56 405.50 C 236.11 397.24 240.85 388.50 245.75 379.85 C 257.24 361.25 268.04 342.23 279.39 323.55 C 283.37 315.67 288.11 308.22 292.72 300.71 C 299.71 290.30 305.20 278.88 313.07 269.07 C 316.98 264.08 323.33 262.12 329.35 261.14 Z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
10
alist/files/assets/http_can_circle.svg
Normal file
10
alist/files/assets/http_can_circle.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="722" height="722" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
<g>
|
||||
<g id="#70c6beff">
|
||||
<path id="svg_2" d="m372.33,100.27c8.44,-1.08 16.61,3.14 22.53,8.87c6.71,6.94 11.39,15.47 16.32,23.68c62.43,104.06 124.07,208.59 186.17,312.85c14.6,24.75 29.53,49.31 43.56,74.4c6.59,11.45 9.1,25.23 6.54,38.23c-1.67,11.63 -8.97,22.12 -18.86,28.31c-7.78,4.86 -16.58,8.22 -25.73,9.17c-4.61,0.42 -9.24,0.19 -13.86,0.22c-63.67,0 -127.35,-0.01 -191.02,0c-8.07,-0.1 -16.22,-2.41 -22.78,-7.2c-7.16,-4.99 -11.59,-14.05 -10.32,-22.79c0.89,-9.17 4.85,-17.68 9.63,-25.44c10.82,-18.77 21.65,-37.53 33.15,-55.9c5.16,-8.03 9.38,-16.95 16.59,-23.43c4.87,-4.16 10.6,-7.63 16.96,-8.82c9.04,-1.12 18.19,2.51 24.97,8.39c6.95,6.16 9.53,16.17 7.88,25.14c-2.58,14.52 -13.13,25.82 -17.34,39.74c-0.92,2.35 -0.44,5.39 2.07,6.53c4.99,2.51 10.75,2.65 16.22,2.79c27.67,-0.02 55.34,-0.02 83.02,0.01c5.04,-0.14 10.92,-0.42 14.59,-4.38c1.7,-5.94 -2.55,-11.22 -5.1,-16.2c-59.46,-101.8 -118.86,-203.63 -178.93,-305.08c-2.61,-4.29 -4.77,-8.97 -8.31,-12.62c-2.33,-2.69 -7,-2.37 -8.92,0.63c-5.67,7.2 -10.1,15.27 -14.86,23.07c-65.86,110.83 -131.72,221.65 -197.58,332.48c-6.29,10.31 -11.48,21.4 -19.35,30.66c-6.28,7.48 -15.75,12.4 -25.6,12.35c-5.38,0.01 -10.4,-2.27 -15.04,-4.77c-6.95,-3.74 -12.3,-10.62 -13.5,-18.5c-1.49,-9.66 1.55,-19.46 6.41,-27.75c56.45,-95.79 113.47,-191.24 170.19,-286.88c21.72,-36.61 43.75,-73.05 65.19,-109.84c5.5,-9.12 11.24,-18.1 16.77,-27.21c6.13,-10.19 16.01,-19.5 28.34,-20.71z" fill="#70c6be"/>
|
||||
</g>
|
||||
<g id="#1ba0d8ff">
|
||||
<path id="svg_3" d="m368.33,335.39c9.54,-1.82 19.84,0.73 27.41,6.83c5.57,5 9.37,12.21 9.55,19.78c0.61,9.39 -3.76,18.08 -8.42,25.92c-36.12,60.55 -72.06,121.21 -108.18,181.76c-5.34,8.95 -11.1,18.53 -21,23.02c-15,8.41 -36.64,-0.5 -41.29,-17.06c-1.72,-7.86 -1.04,-16.4 2.63,-23.63c7.02,-14.54 15.98,-28.02 23.94,-42.05c31.09,-52.53 62.14,-105.09 93.63,-157.38c4.97,-7.94 12.06,-15.57 21.73,-17.19z" fill="#1ba0d8"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
10
alist/files/assets/logo.svg
Normal file
10
alist/files/assets/logo.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="1252" height="1252" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
<g>
|
||||
<g id="#70c6beff">
|
||||
<path id="svg_2" d="m634.37,138.38c11.88,-1.36 24.25,1.3 34.18,8.09c14.96,9.66 25.55,24.41 34.49,39.51c40.59,68.03 81.45,135.91 122.02,203.96c54.02,90.99 108.06,181.97 161.94,273.06c37.28,63 74.65,125.96 112.18,188.82c24.72,41.99 50.21,83.54 73.84,126.16c10.18,17.84 15.77,38.44 14.93,59.03c-0.59,15.92 -3.48,32.28 -11.84,46.08c-11.73,19.46 -31.39,33.2 -52.71,40.36c-11.37,4.09 -23.3,6.87 -35.43,6.89c-132.32,-0.05 -264.64,0.04 -396.95,0.03c-11.38,-0.29 -22.95,-1.6 -33.63,-5.72c-7.81,-3.33 -15.5,-7.43 -21.61,-13.42c-10.43,-10.32 -17.19,-24.96 -15.38,-39.83c0.94,-10.39 3.48,-20.64 7.76,-30.16c4.15,-9.77 9.99,-18.67 15.06,-27.97c22.13,-39.47 45.31,-78.35 69.42,-116.65c7.72,-12.05 14.44,-25.07 25.12,-34.87c11.35,-10.39 25.6,-18.54 41.21,-19.6c12.55,-0.52 24.89,3.82 35.35,10.55c11.8,6.92 21.09,18.44 24.2,31.88c4.49,17.01 -0.34,34.88 -7.55,50.42c-8.09,17.65 -19.62,33.67 -25.81,52.18c-1.13,4.21 -2.66,9.52 0.48,13.23c3.19,3 7.62,4.18 11.77,5.22c12,2.67 24.38,1.98 36.59,2.06c45,-0.01 90,0 135,0c8.91,-0.15 17.83,0.3 26.74,-0.22c6.43,-0.74 13.44,-1.79 18.44,-6.28c3.3,-2.92 3.71,-7.85 2.46,-11.85c-2.74,-8.86 -7.46,-16.93 -12.12,-24.89c-119.99,-204.91 -239.31,-410.22 -360.56,-614.4c-3.96,-6.56 -7.36,-13.68 -13.03,-18.98c-2.8,-2.69 -6.95,-4.22 -10.77,-3.11c-3.25,1.17 -5.45,4.03 -7.61,6.57c-5.34,6.81 -10.12,14.06 -14.51,21.52c-20.89,33.95 -40.88,68.44 -61.35,102.64c-117.9,198.43 -235.82,396.85 -353.71,595.29c-7.31,13.46 -15.09,26.67 -23.57,39.43c-7.45,10.96 -16.49,21.23 -28.14,27.83c-13.73,7.94 -30.69,11.09 -46.08,6.54c-11.23,-3.47 -22.09,-9.12 -30.13,-17.84c-10.18,-10.08 -14.69,-24.83 -14.17,-38.94c0.52,-14.86 5.49,-29.34 12.98,-42.1c71.58,-121.59 143.62,-242.92 215.93,-364.09c37.2,-62.8 74.23,-125.69 111.64,-188.36c37.84,-63.5 75.77,-126.94 113.44,-190.54c21.02,-35.82 42.19,-71.56 64.28,-106.74c6.79,-11.15 15.58,-21.15 26.16,-28.85c8.68,-5.92 18.42,-11 29.05,-11.94z" fill="#70c6be"/>
|
||||
</g>
|
||||
<g id="#1ba0d8ff">
|
||||
<path id="svg_3" d="m628.35,608.38c17.83,-2.87 36.72,1.39 51.5,11.78c11.22,8.66 19.01,21.64 21.26,35.65c1.53,10.68 0.49,21.75 -3.44,31.84c-3.02,8.73 -7.35,16.94 -12.17,24.81c-68.76,115.58 -137.5,231.17 -206.27,346.75c-8.8,14.47 -16.82,29.47 -26.96,43.07c-7.37,9.11 -16.58,16.85 -27.21,21.89c-22.47,11.97 -51.79,4.67 -68.88,-13.33c-8.66,-8.69 -13.74,-20.63 -14.4,-32.84c-0.98,-12.64 1.81,-25.42 7.53,-36.69c5.03,-10.96 10.98,-21.45 17.19,-31.77c30.22,-50.84 60.17,-101.84 90.3,-152.73c41.24,-69.98 83.16,-139.55 124.66,-209.37c4.41,-7.94 9.91,-15.26 16.09,-21.9c8.33,-8.46 18.9,-15.3 30.8,-17.16z" fill="#1ba0d8"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,38 @@
|
||||
From fdcb81f6ba8b8d7546a6742e9566487e12815499 Mon Sep 17 00:00:00 2001
|
||||
From: sbwml <admin@cooluc.com>
|
||||
Date: Thu, 28 Apr 2022 11:10:53 +0800
|
||||
Subject: [PATCH] Revert "feat: clear temp file while start"
|
||||
|
||||
This reverts commit 24d031d57875d3c6a9624fa7334c6eac1c9111fb.
|
||||
---
|
||||
bootstrap/conf.go | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/bootstrap/conf.go b/bootstrap/conf.go
|
||||
index 5c9a1b3..f4d87d4 100644
|
||||
--- a/bootstrap/conf.go
|
||||
+++ b/bootstrap/conf.go
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
- "path/filepath"
|
||||
)
|
||||
|
||||
// InitConf init config
|
||||
@@ -47,11 +46,7 @@ func InitConf() {
|
||||
if !conf.Conf.Force {
|
||||
confFromEnv()
|
||||
}
|
||||
- err := os.RemoveAll(filepath.Join(conf.Conf.TempDir))
|
||||
- if err != nil {
|
||||
- log.Errorln("failed delete temp file:", err)
|
||||
- }
|
||||
- err = os.MkdirAll(conf.Conf.TempDir, 0700)
|
||||
+ err := os.MkdirAll(conf.Conf.TempDir, 0700)
|
||||
if err != nil {
|
||||
log.Fatalf("create temp dir error: %s", err.Error())
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -1,52 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=app-store-ui
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=10
|
||||
|
||||
PKG_HOST_ONLY=1
|
||||
|
||||
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/app-store-ui
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=App Store UI
|
||||
BUILDONLY:=1
|
||||
endef
|
||||
|
||||
define Package/app-store-ui/description
|
||||
UI for luci-app-store
|
||||
endef
|
||||
|
||||
define Host/Prepare
|
||||
mkdir -p $(HOST_BUILD_DIR)
|
||||
$(CP) ./src/. $(HOST_BUILD_DIR)
|
||||
find $(HOST_BUILD_DIR) -name .svn | $(XARGS) rm -rf
|
||||
endef
|
||||
|
||||
define Host/Configure
|
||||
endef
|
||||
|
||||
define Host/Compile
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
endef
|
||||
|
||||
define Host/Clean
|
||||
rm -f $(HOST_BUILD_DIR)/src/dist
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,app-store-ui))
|
35
app-store-ui/src/dist/index.html
vendored
35
app-store-ui/src/dist/index.html
vendored
@ -1,35 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
<script type="module" crossorigin src="/luci-static/istore/index.js"></script>
|
||||
<link rel="modulepreload" href="/luci-static/istore/vendor.js?v=64c6a109">
|
||||
<link rel="stylesheet" href="/luci-static/istore/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
(function(){
|
||||
var vue_prefix="<%=prefix%>";
|
||||
var myurl = window.location.pathname;
|
||||
window.addEventListener('popstate', () => {
|
||||
if (myurl != window.location.pathname
|
||||
&& window.location.pathname != vue_prefix
|
||||
&& ! window.location.pathname.startsWith(vue_prefix+'/')) {
|
||||
window.location.href = window.location.pathname;
|
||||
}
|
||||
});
|
||||
window.vue_base = vue_prefix + '/';
|
||||
window.vue_lang_data = '/luci-static/istore/i18n/<%=lang%>.json?v=<%=id.version%>';
|
||||
window.vue_lang = '<%=lang%>';
|
||||
window.token = "<%=token%>";
|
||||
window.device_id = {arch:"<%=id.arch%>",uid:"<%=id.uid%>",version:"<%=id.version%>"};
|
||||
})();
|
||||
</script>
|
||||
<h2 name="content">iStore dev</h2>
|
||||
<div id="app"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
{"en":{"%{ num } download":["%{ num } download","%{ num } downloads"],"%{ num } like":["%{ num } like","%{ num } likes"],"all app":"all app","app backup":"app backup","are you sure you want to uninstall %{name}?":"are you sure you want to uninstall %{name}?","author":"author","backup fail":"backup fail","backup fail with error code":"backup fail with error code","backup now":"backup now","backup now backs up installed software (unlimited installation sources) to external storage":"backup now backs up installed software (unlimited installation sources) to external storage","backup now will download a list of iStore installed software":"backup now will download a list of iStore installed software","backup success":"backup success","backuping":"backuping","By download":"By download","By rating":"By rating","checking for latest version":"checking for latest version","choose":"choose","choose backup file":"choose backup file","click to download":"click to download","click to update":"click to update","closed":"closed","customize":"customize","default":"default","Docker is not installed on the system, try to install it?":"Docker is not installed on the system, try to install it?","download":"Download","explain":"explain","external storage directory":"external storage directory","Icon is gone":"Icon is gone","install":"install","installation failed, error code":"installation failed, error code","installed":"installed","last version":"last version","light backup":"light backup","like":"like","liked":"liked","loading data":"loading data","local backup":"local backup","maintain":"maintain","manual install":"manual install","monitor":"Monitor","multimedia":"Multimedia","nas":"NAS","net":"Net","networking":"Networking","no files selected":"no files selected","no internet required for recovery":"no internet required for recovery","offline install":"offline install","offline installation failed with error code":"offline installation failed with error code","open":"open","order":"order","packages installed offline may not appear in iStore":"packages installed offline may not appear in iStore","please enter an absolute path starting with %{name}":"please enter an absolute path starting with %{name}","please enter the path, give up the input, please clear the input box":"please enter the path, give up the input, please clear the input box","please enter the search keyword":"please enter the search keyword","please fill in the external storage directory":"please fill in the external storage directory","please select a backup file to restore":"please select a backup file to restore","restore backup":"restore backup","restore failed with error code":"restore failed with error code","restore now":"restore now","select or drag and drop files":"select or drag and drop files","service":"Service","Stick to the top":"Stick to the top","supports .ipk packages, .run self-extracting packages":"supports .ipk packages, .run self-extracting packages","system":"System","tag":"Tag","the is last version":"the is last version","there are no backup files in this path":"there are no backup files in this path","tool":"Tool","uninstall":"uninstall","uninstall failed, error code":"uninstall failed, error code","update date":"update date","update error":"update error","update failed with error code":"update failed with error code","update success, reloading":"update success, reloading","updateing":"updateing","upgrade":"upgrade","upload software list and install from iStore when restoring backup":"upload software list and install from iStore when restoring backup","uploading":"uploading","website":"website","you have already liked":"you have already liked"}}
|
@ -1 +0,0 @@
|
||||
{"zh-cn":{"%{ num } download":["%{ num } 次下载","%{ num } 次下载"],"%{ num } like":["%{ num } 次点赞","%{ num } 次点赞"],"all app":"全部软件","app backup":"软件备份","are you sure you want to uninstall %{name}?":"确定要卸载 %{name} 吗?","author":"作者","backup fail":"备份失败","backup fail with error code":"备份失败,错误代码","backup now":"立即备份","backup now backs up installed software (unlimited installation sources) to external storage":"立即备份将备份已安装软件(不限安装来源)到外部存储","backup now will download a list of iStore installed software":"立即备份将下载iStore已安装的软件列表","backup success":"备份成功","backuping":"正在备份","By download":"按下载","By rating":"按评分","checking for latest version":"正在检查最新版本","choose":"请选择","choose backup file":"选择备份文件","click to download":"点此下载","click to update":"点我更新","closed":"关闭","customize":"自定义","default":"默认","Docker is not installed on the system, try to install it?":"系统中未安装Docker,是否尝试安装?","download":"下载","explain":"说明","external storage directory":"外部存储目录","Icon is gone":"图标出走啦","in this page, you can upload and install packages":"通过本页面,你可以上传并安装插件包","install":"安装","installation failed, error code":"安装失败,错误码","installed":"已安装","last version":"最新版本","light backup":"轻量备份","like":"点赞","liked":"已点赞","loading data":"正在努力的获取数据","local backup":"本地备份","maintain":"维护","manual install":"手动安装","monitor":"监控","multimedia":"多媒体","nas":"NAS","net":"网络","networking":"组网","no files selected":"未选择任何文件","no internet required for recovery":"恢复时不需要网络","offline install":"离线安装","offline installation failed with error code":"离线安装失败,错误码","open":"打开","order":"排序","packages installed offline may not appear in iStore":"离线安装的插件可能不会出现在iStore中","please enter an absolute path starting with %{name}":"请输入 %{name} 开头的绝对路径","please enter the path, give up the input, please clear the input box":"请输入路径,放弃输入请清空输入框","please enter the search keyword":"请输入搜索关键词","please fill in the external storage directory":"请填写外部存储目录","please select a backup file to restore":"请选择要恢复的备份文件","restore backup":"恢复备份","restore failed with error code":"恢复失败,错误代码","restore now":"立即恢复","select or drag and drop files":"选择或拖放文件","service":"服务","Stick to the top":"置顶","supports .ipk packages, .run self-extracting packages":"支持 .ipk 包,.run 自解压格式","system":"系统","tag":"标签","the is last version":"当前已经是最新版本","there are no backup files in this path":"此路径下没有备份文件","tool":"工具","uninstall":"卸载","uninstall failed, error code":"卸载失败,错误码","update date":"更新日期","update error":"更新失败","update failed with error code":"更新失败,错误代码","update success, reloading":"更新成功,重新加载页面","updateing":"正在更新中","upgrade":"更新","upload software list and install from iStore when restoring backup":"复备份时上传软件列表并从iStore安装","uploading":"上传中","website":"官网","you have already liked":"您已经点赞过啦"}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
223
ffmpeg-remux/Makefile
Normal file
223
ffmpeg-remux/Makefile
Normal file
@ -0,0 +1,223 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Ian Leonard <antonlacon@gmail.com>
|
||||
# Copyright (C) 2018 Ted Hess <thess@kitschensync.net>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ffmpeg-remux
|
||||
PKG_VERSION:=4.3.3
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=ffmpeg-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://ffmpeg.org/releases/
|
||||
PKG_HASH:=9f0a68fbd74feb4e50dc220bddd59d84626774a53687fb737806ae00e5c6e9e6
|
||||
PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>, \
|
||||
Ian Leonard <antonlacon@gmail.com>
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1-or-later GPL-2.0-or-later LGPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=COPYING.GPLv2 COPYING.GPLv3 COPYING.LGPLv2.1 COPYING.LGPLv3
|
||||
PKG_CPE_ID:=cpe:/a:ffmpeg:ffmpeg
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-x/ffmpeg-$(PKG_VERSION)
|
||||
|
||||
FFMPEG_REMUX_DECODERS:= \
|
||||
mpeg1video \
|
||||
mpeg2video \
|
||||
mpeg4 \
|
||||
mpegvideo \
|
||||
h264 \
|
||||
hevc \
|
||||
vc1 \
|
||||
|
||||
FFMPEG_REMUX_MUXERS:= \
|
||||
matroska \
|
||||
h264 \
|
||||
hevc \
|
||||
mp4 \
|
||||
mpeg1video \
|
||||
mpeg2video \
|
||||
mpegts \
|
||||
ogg \
|
||||
|
||||
FFMPEG_REMUX_DEMUXERS:= \
|
||||
avi \
|
||||
h264 \
|
||||
hevc \
|
||||
matroska \
|
||||
mov \
|
||||
mpegps \
|
||||
mpegts \
|
||||
mpegvideo \
|
||||
ogg \
|
||||
rm \
|
||||
vc1 \
|
||||
wv \
|
||||
|
||||
FFMPEG_REMUX_PARSERS:= \
|
||||
aac \
|
||||
flac \
|
||||
ac3 \
|
||||
h264 \
|
||||
hevc \
|
||||
mpegaudio \
|
||||
mpeg4video \
|
||||
mpegvideo \
|
||||
vc1 \
|
||||
|
||||
FFMPEG_REMUX_PROTOCOLS:= \
|
||||
file pipe
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ffmpeg-remux
|
||||
TITLE:=FFmpeg remux
|
||||
SECTION:=multimedia
|
||||
CATEGORY:=Multimedia
|
||||
URL:=https://ffmpeg.org/
|
||||
DEPENDS+= +libpthread +zlib +libbz2
|
||||
endef
|
||||
|
||||
define Package/ffmpeg-remux/description
|
||||
FFmpeg remux only program
|
||||
endef
|
||||
|
||||
# Strip off FPU notation
|
||||
REAL_CPU_TYPE:=$(firstword $(subst +, ,$(CONFIG_CPU_TYPE)))
|
||||
# Fixup cpu types recogized by ffmpeg configure
|
||||
REAL_CPU_TYPE:=$(subst octeonplus,octeon+,$(REAL_CPU_TYPE))
|
||||
|
||||
FFMPEG_CONFIGURE:= \
|
||||
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(FPIC)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||
./configure \
|
||||
--enable-cross-compile \
|
||||
--cross-prefix="$(TARGET_CROSS)" \
|
||||
--arch="$(ARCH)" \
|
||||
$(if $(REAL_CPU_TYPE),--cpu=$(call qstrip,$(REAL_CPU_TYPE)),) \
|
||||
--target-os=linux \
|
||||
--prefix="/usr" \
|
||||
--pkg-config="pkg-config" \
|
||||
--enable-shared \
|
||||
--enable-pthreads \
|
||||
--enable-zlib \
|
||||
--disable-doc \
|
||||
--disable-debug \
|
||||
\
|
||||
--disable-lzma \
|
||||
--disable-vaapi \
|
||||
--disable-vdpau \
|
||||
--disable-outdevs
|
||||
|
||||
ifeq ($(CONFIG_SOFT_FLOAT),y)
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--disable-altivec \
|
||||
--disable-vsx \
|
||||
--disable-power8 \
|
||||
--disable-armv5te \
|
||||
--disable-armv6 \
|
||||
--disable-armv6t2 \
|
||||
--disable-fast-unaligned \
|
||||
--disable-runtime-cpudetect
|
||||
|
||||
else ifneq ($(findstring arm,$(CONFIG_ARCH))$(findstring aarch64,$(CONFIG_ARCH)),)
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--disable-runtime-cpudetect
|
||||
# XXX: GitHub issue 3320 ppc cpu with fpu but no altivec (WNDR4700)
|
||||
else ifneq ($(findstring powerpc,$(CONFIG_ARCH)),)
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--disable-altivec
|
||||
endif
|
||||
|
||||
# selectively disable optimizations according to arch/cpu type
|
||||
ifneq ($(findstring arm,$(CONFIG_ARCH)),)
|
||||
FFMPEG_CONFIGURE+= --enable-lto
|
||||
|
||||
ifneq ($(findstring vfp,$(CONFIG_CPU_TYPE)),)
|
||||
FFMPEG_CONFIGURE+= --enable-vfp
|
||||
else
|
||||
FFMPEG_CONFIGURE+= --disable-vfp
|
||||
endif
|
||||
ifneq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--enable-neon \
|
||||
--enable-vfp
|
||||
else
|
||||
FFMPEG_CONFIGURE+= --disable-neon
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring aarch64,$(CONFIG_ARCH)),)
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--enable-lto \
|
||||
--enable-neon \
|
||||
--enable-vfp
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
FFMPEG_CONFIGURE+= --enable-lto
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FFMPEG_X86ASM),y)
|
||||
FFMPEG_CONFIGURE += --enable-x86asm
|
||||
else
|
||||
FFMPEG_CONFIGURE += --disable-x86asm
|
||||
endif
|
||||
|
||||
|
||||
FFMPEG_ENABLE= \
|
||||
$(foreach c, $(2), \
|
||||
--enable-$(1)="$(c)" \
|
||||
)
|
||||
|
||||
FFMPEG_CONFIGURE+= \
|
||||
--enable-hardcoded-tables \
|
||||
--disable-static \
|
||||
--libdir="/usr/lib/remux" \
|
||||
--enable-rpath \
|
||||
\
|
||||
--disable-ffplay \
|
||||
--disable-alsa \
|
||||
--disable-iconv \
|
||||
--disable-sndio \
|
||||
--disable-schannel \
|
||||
--disable-sdl2 \
|
||||
--disable-securetransport \
|
||||
--disable-xlib \
|
||||
--disable-v4l2-m2m \
|
||||
--disable-avdevice \
|
||||
--disable-postproc \
|
||||
--disable-swresample \
|
||||
--disable-swscale \
|
||||
--disable-everything \
|
||||
$(call FFMPEG_ENABLE,decoder,$(FFMPEG_REMUX_DECODERS)) \
|
||||
$(call FFMPEG_ENABLE,parser,$(FFMPEG_REMUX_PARSERS)) \
|
||||
$(call FFMPEG_ENABLE,demuxer,$(FFMPEG_REMUX_DEMUXERS)) \
|
||||
$(call FFMPEG_ENABLE,muxer,$(FFMPEG_REMUX_MUXERS)) \
|
||||
$(call FFMPEG_ENABLE,protocol,$(FFMPEG_REMUX_PROTOCOLS))
|
||||
|
||||
ifneq ($(CONFIG_TARGET_x86),)
|
||||
TARGET_CFLAGS+= -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
define Build/Configure
|
||||
( cd $(PKG_BUILD_DIR); $(FFMPEG_CONFIGURE) )
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||
all install
|
||||
endef
|
||||
|
||||
define Package/ffmpeg-remux/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/remux
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/remux/lib{avcodec,avfilter,avformat,avutil}.so.* $(1)/usr/lib/remux/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/bin/ffmpeg $(1)/usr/bin/remux
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ffmpeg-remux))
|
29
luci-app-alist/Makefile
Normal file
29
luci-app-alist/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-alist
|
||||
PKG_VERSION:=1.0.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI support for alist
|
||||
LUCI_DEPENDS:=+alist +luci-compat
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/alist
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
[ -n "${IPKG_INSTROOT}" ] || {
|
||||
( . /etc/uci-defaults/luci-alist ) && rm -f /etc/uci-defaults/luci-alist
|
||||
exit 0
|
||||
}
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
25
luci-app-alist/luasrc/controller/alist.lua
Normal file
25
luci-app-alist/luasrc/controller/alist.lua
Normal file
@ -0,0 +1,25 @@
|
||||
module("luci.controller.alist", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/alist") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false
|
||||
entry({"admin", "nas", "alist"}, cbi("alist"), _("Alist"), 20).dependent = true
|
||||
entry({"admin", "nas", "alist_status"}, call("alist_status"))
|
||||
end
|
||||
|
||||
function alist_status()
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local port = tonumber(uci:get_first("alist", "alist", "port"))
|
||||
|
||||
local status = {
|
||||
running = (sys.call("pidof alist >/dev/null") == 0),
|
||||
port = (port or 5244)
|
||||
}
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(status)
|
||||
end
|
53
luci-app-alist/luasrc/model/cbi/alist.lua
Normal file
53
luci-app-alist/luasrc/model/cbi/alist.lua
Normal file
@ -0,0 +1,53 @@
|
||||
local m, s
|
||||
local sys = require "luci.sys"
|
||||
|
||||
if sys.call("pidof alist >/dev/null") == 0 then
|
||||
local password = sys.exec("/usr/bin/alist --conf /etc/alist/config.json -password | awk '{print $3}'")
|
||||
m = Map("alist", translate("Alist"), translate("A file list program that supports multiple storage.") .. " " .. translate("manage password:") .. "<font color=\"green\">" .. password .. "</font>" .. "<br/>" .. [[<a href="https://alist-doc.nn.ci/docs/driver/native" target="_blank">]] .. translate("User Manual") .. [[</a>]])
|
||||
else
|
||||
m = Map("alist", translate("Alist"), translate("A file list program that supports multiple storage.") .. "<br/>" .. [[<a href="https://alist-doc.nn.ci/docs/driver/native" target="_blank">]] .. translate("User Manual") .. [[</a>]])
|
||||
end
|
||||
|
||||
m:section(SimpleSection).template = "alist_status"
|
||||
|
||||
s = m:section(TypedSection, "alist", translate("Global settings"))
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("Port"))
|
||||
o.datatype = "and(port,min(1))"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "ssl", translate("Enable SSL"))
|
||||
o.rmempty=false
|
||||
|
||||
o = s:option(Value,"ssl_cert", translate("SSL cert"), translate("SSL certificate file path"))
|
||||
o:depends("ssl", "1")
|
||||
o.datatype = "string"
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value,"ssl_key", translate("SSL key"), translate("SSL key file path"))
|
||||
o:depends("ssl", "1")
|
||||
o.datatype = "string"
|
||||
o.rmempty = true
|
||||
|
||||
s = m:section(TypedSection, "alist", translate("Cache settings"))
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Value, "expiration", translate("Cache invalidation time (unit: minutes)"))
|
||||
o.datatype = "and(uinteger,min(1))"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "cleanup_interval", translate("Clear the invalidation cache interval (unit: minutes)"))
|
||||
o.datatype = "and(uinteger,min(1))"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "temp_dir", translate("Cache directory"))
|
||||
o.datatype = "string"
|
||||
o.rmempty = false
|
||||
|
||||
return m
|
36
luci-app-alist/luasrc/view/alist_status.htm
Normal file
36
luci-app-alist/luasrc/view/alist_status.htm
Normal file
@ -0,0 +1,36 @@
|
||||
<%
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
ssl = uci:get_first('alist', 'alist', 'ssl')
|
||||
if ssl == '1' then
|
||||
protocol="https://"
|
||||
else
|
||||
protocol="http://"
|
||||
end
|
||||
%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=url("admin/nas/alist_status")%>', null,
|
||||
function(x, st)
|
||||
{
|
||||
var tb = document.getElementById('alist_status');
|
||||
if (st && tb)
|
||||
{
|
||||
if (st.running)
|
||||
{
|
||||
tb.innerHTML = '<em style=\"color:green\"><b><%:The Alist service is running.%></b></em>' + "<input class=\"cbi-button-reload mar-10\" type=\"button\" value=\" <%:Click to open Alist%> \" onclick=\"window.open('<%=protocol%>" + window.location.hostname + ":" + st.port + "/')\"/>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tb.innerHTML = '<em style=\"color:red\"><b><%:The Alist service is not running.%></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="alist_status">
|
||||
<em><b><%:Collecting data...%></b></em>
|
||||
</p>
|
||||
</fieldset>
|
62
luci-app-alist/po/zh-cn/alist.po
Normal file
62
luci-app-alist/po/zh-cn/alist.po
Normal file
@ -0,0 +1,62 @@
|
||||
msgid "Alist"
|
||||
msgstr "Alist 文件列表"
|
||||
|
||||
msgid "Running state"
|
||||
msgstr "运行状态"
|
||||
|
||||
msgid "Click to open Alist"
|
||||
msgstr "点击打开 Alist"
|
||||
|
||||
msgid "A file list program that supports multiple storage."
|
||||
msgstr "一款支持多种存储的目录文件列表程序。"
|
||||
|
||||
msgid "manage password:"
|
||||
msgstr "管理密码:"
|
||||
|
||||
msgid "Global settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Enable SSL"
|
||||
msgstr "启用 SSL"
|
||||
|
||||
msgid "SSL cert"
|
||||
msgstr "SSL 证书"
|
||||
|
||||
msgid "SSL certificate file path"
|
||||
msgstr "SSL 证书文件路径"
|
||||
|
||||
msgid "SSL key"
|
||||
msgstr "SSL 密钥"
|
||||
|
||||
msgid "SSL key file path"
|
||||
msgstr "SSL 密钥文件路径"
|
||||
|
||||
msgid "Cache settings"
|
||||
msgstr "缓存设置"
|
||||
|
||||
msgid "Cache invalidation time (unit: minutes)"
|
||||
msgstr "缓存失效时间(分钟)"
|
||||
|
||||
msgid "Clear the invalidation cache interval (unit: minutes)"
|
||||
msgstr "清理失效缓存间隔(分钟)"
|
||||
|
||||
msgid "Cache directory"
|
||||
msgstr "缓存目录"
|
||||
|
||||
msgid "The Alist service is running."
|
||||
msgstr "Alist 服务已启动"
|
||||
|
||||
msgid "The Alist service is not running."
|
||||
msgstr "Alist 服务未启动"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "收集数据..."
|
||||
|
||||
msgid "NAS"
|
||||
msgstr "网络存储"
|
||||
|
||||
msgid "User Manual"
|
||||
msgstr "用户手册"
|
1
luci-app-alist/po/zh_Hans
Symbolic link
1
luci-app-alist/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
BIN
luci-app-alist/root/etc/alist/data.db
Normal file
BIN
luci-app-alist/root/etc/alist/data.db
Normal file
Binary file not shown.
7
luci-app-alist/root/etc/config/alist
Normal file
7
luci-app-alist/root/etc/config/alist
Normal file
@ -0,0 +1,7 @@
|
||||
config alist
|
||||
option 'enabled' '0'
|
||||
option 'port' '5244'
|
||||
option 'expiration' '60'
|
||||
option 'cleanup_interval' '120'
|
||||
option 'temp_dir' '/tmp'
|
||||
option 'ssl' '0'
|
48
luci-app-alist/root/etc/init.d/alist
Executable file
48
luci-app-alist/root/etc/init.d/alist
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
PROG=/usr/bin/alist
|
||||
CONFIG=/etc/alist/config.json
|
||||
|
||||
get_config() {
|
||||
config_get_bool enabled $1 enabled 1
|
||||
config_get port $1 port 5244
|
||||
config_get expiration $1 expiration 60
|
||||
config_get cleanup_interval $1 cleanup_interval 120
|
||||
config_get temp_dir $1 temp_dir "/tmp"
|
||||
config_get ssl $1 ssl 0
|
||||
config_get ssl_cert $1 ssl_cert ""
|
||||
config_get ssl_key $1 ssl_key ""
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load alist
|
||||
config_foreach get_config alist
|
||||
[ $enabled != 1 ] && return 1
|
||||
mkdir -p $temp_dir
|
||||
if [ "$ssl" -eq 1 ];then
|
||||
SSL=true
|
||||
else
|
||||
SSL=false
|
||||
fi
|
||||
cat > $CONFIG <<EOF
|
||||
{"address":"0.0.0.0","port":$port,"assets":"/","database":{"type":"sqlite3","user":"","password":"","host":"","port":0,"name":"","table_prefix":"x_","db_file":"/etc/alist/data.db","ssl_mode":"disable"},"scheme":{"https":$SSL,"cert_file":"$ssl_cert","key_file":"$ssl_key"},"cache":{"expiration":$expiration,"cleanup_interval":$cleanup_interval},"temp_dir":"$temp_dir"}
|
||||
EOF
|
||||
procd_open_instance alist
|
||||
procd_set_param command $PROG
|
||||
procd_append_param command --conf $CONFIG
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance alist
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "alist"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
11
luci-app-alist/root/etc/uci-defaults/luci-alist
Executable file
11
luci-app-alist/root/etc/uci-defaults/luci-alist
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@alist[-1]
|
||||
add ucitrack alist
|
||||
set ucitrack.@alist[-1].init=alist
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
11
luci-app-alist/root/usr/share/rpcd/acl.d/luci-app-alist.json
Normal file
11
luci-app-alist/root/usr/share/rpcd/acl.d/luci-app-alist.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-alist": {
|
||||
"description": "Grant UCI access for luci-app-alist",
|
||||
"read": {
|
||||
"uci": [ "alist" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "alist" ]
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-amlogic
|
||||
PKG_VERSION:=3.1.121
|
||||
PKG_VERSION:=3.1.122
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0 License
|
||||
|
@ -113,6 +113,12 @@ check_kernel() {
|
||||
# Determine custom kernel filename
|
||||
kernel_boot="$(ls boot-*.tar.gz | head -n 1)"
|
||||
kernel_name="${kernel_boot/boot-/}" && kernel_name="${kernel_name/.tar.gz/}"
|
||||
|
||||
# check if kernel is locked
|
||||
if [[ "${LOCK_KERNEL}" != "${kernel_name}" ]];then
|
||||
error_msg "The kernel version is locked to ${LOCK_KERNEL}. "
|
||||
fi
|
||||
|
||||
KERNEL_VERSION="$(echo ${kernel_name} | grep -oE '^[1-9].[0-9]{1,3}.[0-9]+')"
|
||||
echo -e "Kernel name: ${kernel_name}"
|
||||
|
||||
@ -123,6 +129,7 @@ check_kernel() {
|
||||
[[ -n "${UBOOT_OVERLOAD}" && -f "/boot/${UBOOT_OVERLOAD}" ]] || error_msg "The UBOOT_OVERLOAD file is missing and cannot be update."
|
||||
fi
|
||||
|
||||
|
||||
# Check the sha256sums file
|
||||
sha256sums_file="sha256sums"
|
||||
sha256sums_check="1"
|
||||
|
@ -48,6 +48,13 @@ elif [[ "$(echo ${MYDEVICE_NAME} | grep "FastRhino R68S")" != "" ]]; then
|
||||
MYDTB_FDTFILE="rk3568-fastrhino-r68s.dtb"
|
||||
fi
|
||||
SOC="r68s"
|
||||
elif [[ "$(echo ${MYDEVICE_NAME} | grep "Radxa ROCK 5B")" != "" ]]; then
|
||||
if [ -n "$CURRENT_FDTFILE" ];then
|
||||
MYDTB_FDTFILE="$CURRENT_FDTFILE"
|
||||
else
|
||||
MYDTB_FDTFILE="rk3588-rock-5b.dtb"
|
||||
fi
|
||||
SOC="rock5b"
|
||||
else
|
||||
echo "Unknown device: [ ${MYDEVICE_NAME} ], Not supported."
|
||||
exit 1
|
||||
@ -67,7 +74,12 @@ case ${ROOT_PTNAME} in
|
||||
mmcblk?p[1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="EMMC_"
|
||||
LB_PRE="MMC_"
|
||||
;;
|
||||
nvme?n?p?)
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-2)}')
|
||||
PARTITION_NAME="p"
|
||||
LB_PRE="NVME_"
|
||||
;;
|
||||
[hsv]d[a-z][1-4])
|
||||
EMMC_NAME=$(echo ${ROOT_PTNAME} | awk '{print substr($1, 1, length($1)-1)}')
|
||||
@ -573,6 +585,8 @@ cd ${WORK_DIR}
|
||||
|
||||
echo "Start copy data from ${P2} to /boot ..."
|
||||
cd /boot
|
||||
echo -n "backup armbianEnv.txt ..."
|
||||
cp armbianEnv.txt /tmp/
|
||||
echo -n "remove old boot files ..."
|
||||
rm -rf *
|
||||
echo "done"
|
||||
@ -583,19 +597,27 @@ echo "done"
|
||||
echo
|
||||
|
||||
echo -n "Update boot args ... "
|
||||
cat >armbianEnv.txt <<EOF
|
||||
verbosity=7
|
||||
overlay_prefix=rockchip
|
||||
if [ -f /tmp/armbianEnv.txt ];then
|
||||
cp /tmp/armbianEnv.txt .
|
||||
fi
|
||||
sed -e '/fdtfile=/d' -i armbianEnv.txt
|
||||
sed -e '/rootdev=/d' -i armbianEnv.txt
|
||||
sed -e '/rootfstype=/d' -i armbianEnv.txt
|
||||
sed -e '/rootflags=/d' -i armbianEnv.txt
|
||||
if [ "$SOC" == "rock5b" ];then
|
||||
echo "fdtfile=rockchip/${MYDTB_FDTFILE}" >> armbianEnv.txt
|
||||
else
|
||||
echo "fdtfile=/dtb/rockchip/${MYDTB_FDTFILE}" >> armbianEnv.txt
|
||||
fi
|
||||
cat >> armbianEnv.txt <<EOF
|
||||
rootdev=UUID=${NEW_ROOT_UUID}
|
||||
rootfstype=btrfs
|
||||
rootflags=compress=zstd:${ZSTD_LEVEL}
|
||||
extraargs=usbcore.autosuspend=-1 net.ifnames=0
|
||||
extraboardargs=
|
||||
fdtfile=/dtb/rockchip/${MYDTB_FDTFILE}
|
||||
EOF
|
||||
# 对没有 HDMI 的机型关闭 display tty 让 initrd script 输出到 uart
|
||||
# 参考 https://github.com/raspberrypi/linux/issues/2863
|
||||
if [ "$SOC" == "r68s" ];then
|
||||
sed -e '/console=/d' -i armbianEnv.txt
|
||||
echo console=serial >> armbianEnv.txt
|
||||
fi
|
||||
sync
|
||||
|
201
luci-app-speedtest-web/LICENSE
Normal file
201
luci-app-speedtest-web/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
18
luci-app-speedtest-web/Makefile
Normal file
18
luci-app-speedtest-web/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2021 2021 ZeaKyX
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-speedtest-web
|
||||
LUCI_TITLE:=LuCI support for speedtest-web
|
||||
LUCI_DEPENDS:=+speedtest-web
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=<https://github.com/ZeaKyX/luci-app-speedtest-web>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
26
luci-app-speedtest-web/README.md
Normal file
26
luci-app-speedtest-web/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# luci-app-speedtest-web
|
||||
LuCI support for speedtest-web 内网测速网页版
|
||||
|
||||
# 简介
|
||||
<s>还在为不会iperf命令行测速而担忧吗</s>
|
||||
- **在 OpenWRT/LEDE 上进行网页内网测速的插件**
|
||||
- 一键测速,简单易用
|
||||
- 代码很烂,抛砖引玉,欢迎PR!
|
||||
|
||||
# 使用截图
|
||||
![image](https://github.com/ZeaKyX/luci-app-speedtest-web/blob/main/img/img.gif)
|
||||
|
||||
# 下载
|
||||
- [luci-app-speedtest-web](https://github.com/ZeaKyX/luci-app-speedtest-web/releases)
|
||||
|
||||
# TODO
|
||||
- 加强配置文件:设置端口号、测速时长...
|
||||
- 添加设置页面(?)
|
||||
- 添加启动/关闭开关(?)
|
||||
- 黑暗主题自适应
|
||||
- 定制测速页面
|
||||
- ...
|
||||
|
||||
# 鸣谢
|
||||
- Lean的各种[软件包](https://github.com/coolsnowwolf/lede/tree/master/package/lean),让我缝!
|
||||
- LibreSpeed的Go维护[speedtest-go](https://github.com/librespeed/speedtest-go)
|
BIN
luci-app-speedtest-web/img/img.gif
Normal file
BIN
luci-app-speedtest-web/img/img.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 MiB |
@ -0,0 +1,9 @@
|
||||
module("luci.controller.speedtest-web", package.seeall)
|
||||
|
||||
function index()
|
||||
if not (luci.sys.call("pidof speedtest-web > /dev/null") == 0) then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "network", "speedtest-web"}, template("speedtest-web/speedtest-web"), _("Speedtest Web"), 10).leaf = true
|
||||
end
|
@ -0,0 +1,13 @@
|
||||
<%+header%>
|
||||
<div class="cbi-map">
|
||||
<h2 name="content"><%=translate("Speedtest Web")%></h2>
|
||||
<iframe id="speedtest-web" style="width: 100%; min-height: 500px; border: none; border-radius: 3px;"></iframe>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("speedtest-web").src = window.location.protocol + "//" + window.location.hostname + ":8989";
|
||||
document.getElementById("speedtest-web").height = document.documentElement.clientHeight;
|
||||
window.onresize = function(){
|
||||
document.getElementById("speedtest-web").height = document.documentElement.clientHeight;
|
||||
}
|
||||
</script>
|
||||
<%+footer%>
|
5
luci-app-speedtest-web/po/zh-cn/speedtest-web.po
Normal file
5
luci-app-speedtest-web/po/zh-cn/speedtest-web.po
Normal file
@ -0,0 +1,5 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Speedtest Web"
|
||||
msgstr "内网测速网页版"
|
1
luci-app-speedtest-web/po/zh_Hans
Symbolic link
1
luci-app-speedtest-web/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
4
luci-app-speedtest-web/root/etc/config/speedtest-web
Normal file
4
luci-app-speedtest-web/root/etc/config/speedtest-web
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
config speedtest-web 'config'
|
||||
option enabled '1'
|
||||
option port '8989'
|
19
luci-app-speedtest-web/root/etc/init.d/speedtest-web
Executable file
19
luci-app-speedtest-web/root/etc/init.d/speedtest-web
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=90
|
||||
STOP=10
|
||||
|
||||
enabled="$(uci get speedtest-web.config.enabled)"
|
||||
port="$(uci get speedtest-web.config.port)"
|
||||
|
||||
start() {
|
||||
stop
|
||||
[ "$enabled" == "1" ] || exit 0
|
||||
speedtest-web \
|
||||
--listen_port "${port}" \
|
||||
>/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
stop() {
|
||||
killall speedtest-web >/dev/null 2>&1
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-speedtest-web": {
|
||||
"description": "Grant UCI access for luci-app-speedtest-web",
|
||||
"read": {
|
||||
"uci": [ "speedtest-web" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "speedtest-web" ]
|
||||
}
|
||||
}
|
||||
}
|
20
luci-lib-taskd/Makefile
Normal file
20
luci-lib-taskd/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (C) 2022 jjm2473 <jjm2473@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Task library
|
||||
LUCI_DEPENDS:=+luci-lib-xterm +taskd
|
||||
LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3-1)
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=1.0.17
|
||||
PKG_RELEASE:=
|
||||
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
112
luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.css
Normal file
112
luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.css
Normal file
@ -0,0 +1,112 @@
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#tasks_detail_container {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #0008;
|
||||
}
|
||||
#tasks_dialog {
|
||||
position: absolute;
|
||||
width: 770px;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #000;
|
||||
|
||||
border-radius: 10px;
|
||||
box-shadow: 2px 2px 6px #000a;
|
||||
padding: 20px;
|
||||
|
||||
color: white;
|
||||
}
|
||||
.dialog-title-bar {
|
||||
margin-top: -10px;
|
||||
margin-right: -10px;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
.dialog-title-bar .dialog-title {
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dialog-content {
|
||||
max-height: 500px;
|
||||
overflow-y: scroll;
|
||||
margin-right: -10px;
|
||||
}
|
||||
.dialog-icons {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.dialog-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: white;
|
||||
color: black;
|
||||
border-radius: 50%;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
margin-left: 10px;
|
||||
line-height: 1;
|
||||
font-family: sans-serif;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.dialog-icon.dialog-icon-min {
|
||||
background-color: darkorange;
|
||||
}
|
||||
.dialog-icon.dialog-icon-close {
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
.dialog-icons:hover .dialog-icon.dialog-icon-min:before {
|
||||
content: "_";
|
||||
}
|
||||
.dialog-icons:hover .dialog-icon.dialog-icon-close:before {
|
||||
content: "X";
|
||||
}
|
||||
|
||||
.tasks_stopped .dialog-icon.dialog-icon-close {
|
||||
background-color: #27c840;
|
||||
}
|
||||
.tasks_stopped #tasks_dialog, .tasks_unknown #tasks_dialog {
|
||||
padding: 19px;
|
||||
border: 1px #27c840 solid;
|
||||
|
||||
animation: border-blink 1s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.tasks_failed #tasks_dialog {
|
||||
border-color: #ff0000;
|
||||
}
|
||||
|
||||
.tasks_failed .dialog-icon.dialog-icon-close {
|
||||
background-color: #ff0000;
|
||||
}
|
||||
|
||||
.tasks_unknown #tasks_dialog {
|
||||
border-color: darkorange;
|
||||
}
|
||||
|
||||
@keyframes border-blink { 50% { border-color:#fff ; } }
|
232
luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js
Normal file
232
luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js
Normal file
@ -0,0 +1,232 @@
|
||||
|
||||
(function(){
|
||||
const taskd={};
|
||||
const $gettext = function(str) {
|
||||
return taskd.i18n[str] || str;
|
||||
};
|
||||
const retryPromise = function(fn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const retry = function() {
|
||||
fn(resolve, reject, retry);
|
||||
};
|
||||
retry();
|
||||
});
|
||||
};
|
||||
const retry403XHR = function(url, method, responseType) {
|
||||
return retryPromise((resolve, reject, retry) => {
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.onerror = reject;
|
||||
oReq.open(method || 'GET', url, true);
|
||||
if (responseType) {
|
||||
oReq.responseType = responseType;
|
||||
}
|
||||
oReq.onload = function (oEvent) {
|
||||
if (oReq.status == 403) {
|
||||
alert($gettext("Lost login status"));
|
||||
location.href = location.href;
|
||||
} else if (oReq.status == 404) {
|
||||
reject(oEvent);
|
||||
} else {
|
||||
resolve(oReq);
|
||||
}
|
||||
};
|
||||
if (method=='POST') {
|
||||
oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
}
|
||||
oReq.send(method=='POST'?("token="+taskd.csrfToken):null);
|
||||
});
|
||||
};
|
||||
const request = function(url, method) {
|
||||
return retry403XHR(url, method).then(oReq => oReq.responseText);
|
||||
};
|
||||
const getBin = function(url) {
|
||||
return retry403XHR(url, null, "arraybuffer").then(oReq => {return {status: oReq.status, buffer: new Uint8Array(oReq.response)}});
|
||||
};
|
||||
const getTaskDetail = function(task_id) {
|
||||
return request("/cgi-bin/luci/admin/system/tasks/status?task_id="+task_id).then(data=>JSON.parse(data));
|
||||
};
|
||||
const create_dialog = function(cfg) {
|
||||
const container = document.createElement('div');
|
||||
container.id = "tasks_detail_container";
|
||||
container.innerHTML = taskd.dialog_template;
|
||||
|
||||
document.body.appendChild(container);
|
||||
const title_view = container.querySelector(".dialog-title-bar .dialog-title");
|
||||
title_view.innerText = cfg.title;
|
||||
|
||||
const term = new Terminal({convertEol: cfg.convertEol||false});
|
||||
if (cfg.nohide) {
|
||||
container.querySelector(".dialog-icon-min").hidden = true;
|
||||
} else {
|
||||
container.querySelector(".dialog-icon-min").onclick = function(){
|
||||
container.hidden=true;
|
||||
term.dispose();
|
||||
document.body.removeChild(container);
|
||||
cfg.onhide && cfg.onhide();
|
||||
return false;
|
||||
};
|
||||
}
|
||||
term.open(document.getElementById("tasks_xterm_log"));
|
||||
|
||||
return {term,container};
|
||||
};
|
||||
const show_log_txt = function(title, content, onclose) {
|
||||
const dialog = create_dialog({title, convertEol:true, onhine:onclose});
|
||||
const container = dialog.container;
|
||||
const term = dialog.term;
|
||||
container.querySelector(".dialog-icon-close").hidden = true;
|
||||
term.write(content);
|
||||
};
|
||||
const show_log = function(task_id, nohide) {
|
||||
let showing = true;
|
||||
let running = true;
|
||||
const dialog = create_dialog({title:task_id, nohide, onhide:function(){showing=false;}});
|
||||
const container = dialog.container;
|
||||
const term = dialog.term;
|
||||
|
||||
const title_view = container.querySelector(".dialog-title-bar .dialog-title");
|
||||
container.querySelector(".dialog-icon-close").onclick = function(){
|
||||
if (!running || confirm($gettext("Stop running task?"))) {
|
||||
running=false;
|
||||
showing=false;
|
||||
del_task(task_id).then(()=>{
|
||||
location.href = location.href;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const checkTask = function() {
|
||||
return getTaskDetail(task_id).then(data=>{
|
||||
if (!running) {
|
||||
return false;
|
||||
}
|
||||
running = data.running;
|
||||
let title = task_id;
|
||||
if (!data.running && data.stop) {
|
||||
title += " (" + (data.exit_code?$gettext("Failed at:"):$gettext("Finished at:")) + " " + new Date(data.stop * 1000).toLocaleString() + ")";
|
||||
}
|
||||
title += " > " + (data.command || '');
|
||||
title_view.title = title;
|
||||
title_view.innerText = title;
|
||||
if (!data.running) {
|
||||
container.classList.add('tasks_stopped');
|
||||
if (data.exit_code) {
|
||||
container.classList.add('tasks_failed');
|
||||
}
|
||||
}
|
||||
// last pull
|
||||
return showing;
|
||||
});
|
||||
};
|
||||
let logoffset = 0;
|
||||
const pulllog = function(check) {
|
||||
let starter = Promise.resolve(showing);
|
||||
if (check) {
|
||||
starter = checkTask();
|
||||
}
|
||||
starter.then(again => {
|
||||
if (again)
|
||||
return getBin("/cgi-bin/luci/admin/system/tasks/log?task_id="+task_id+"&offset="+logoffset);
|
||||
else
|
||||
return {status: 204};
|
||||
}).then(function(res){
|
||||
if (!showing) {
|
||||
return false;
|
||||
}
|
||||
switch(res.status){
|
||||
case 205:
|
||||
term.reset();
|
||||
logoffset = 0;
|
||||
return running;
|
||||
break;
|
||||
case 204:
|
||||
return running && checkTask();
|
||||
break;
|
||||
case 200:
|
||||
logoffset += res.buffer.byteLength;
|
||||
term.write(res.buffer);
|
||||
return running;
|
||||
break;
|
||||
}
|
||||
}).then(again => {
|
||||
if (again) {
|
||||
setTimeout(pulllog, 0);
|
||||
}
|
||||
}).catch(err => {
|
||||
if (showing) {
|
||||
if (err.target.status == 0) {
|
||||
title_view.innerText = task_id + ' (' + $gettext("Fetch log failed, retrying...") + ')';
|
||||
setTimeout(()=>pulllog(true), 1000);
|
||||
} else if (err.target.status == 403 || err.target.status == 404) {
|
||||
title_view.innerText = task_id + ' (' + $gettext(err.target.status == 403?"Lost login status":"Task does not exist or has been deleted") + ')';
|
||||
container.querySelector(".dialog-icon-close").hidden = true;
|
||||
container.classList.add('tasks_unknown');
|
||||
} else {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
pulllog(true);
|
||||
};
|
||||
const del_task = function(task_id) {
|
||||
return request("/cgi-bin/luci/admin/system/tasks/stop?task_id="+task_id, "POST");
|
||||
};
|
||||
taskd.show_log = show_log;
|
||||
taskd.remove = del_task;
|
||||
taskd.show_log_txt = show_log_txt;
|
||||
window.taskd=taskd;
|
||||
})();
|
||||
|
||||
(function(){
|
||||
// compat
|
||||
if (typeof(window.findParent) !== 'function') {
|
||||
const elem = function(e) {
|
||||
return (e != null && typeof(e) == 'object' && 'nodeType' in e);
|
||||
};
|
||||
const matches = function(node, selector) {
|
||||
var m = elem(node) ? node.matches || node.msMatchesSelector : null;
|
||||
return m ? m.call(node, selector) : false;
|
||||
};
|
||||
window.findParent = function (node, selector) {
|
||||
if (elem(node) && node.closest)
|
||||
return node.closest(selector);
|
||||
|
||||
while (elem(node))
|
||||
if (matches(node, selector))
|
||||
return node;
|
||||
else
|
||||
node = node.parentNode;
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
if (typeof(window.cbi_submit) !== 'function') {
|
||||
const makeHidden = function(name) {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = name;
|
||||
return input;
|
||||
};
|
||||
window.cbi_submit = function(elem, name, value, action) {
|
||||
var form = elem.form || findParent(elem, 'form');
|
||||
|
||||
if (!form)
|
||||
return false;
|
||||
|
||||
if (action)
|
||||
form.action = action;
|
||||
|
||||
if (name) {
|
||||
var hidden = form.querySelector('input[type="hidden"][name="%s"]'.format(name)) ||
|
||||
makeHidden(name);
|
||||
|
||||
hidden.value = value || '1';
|
||||
form.appendChild(hidden);
|
||||
}
|
||||
|
||||
form.submit();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
})();
|
92
luci-lib-taskd/luasrc/controller/tasks-lib.lua
Executable file
92
luci-lib-taskd/luasrc/controller/tasks-lib.lua
Executable file
@ -0,0 +1,92 @@
|
||||
|
||||
module("luci.controller.tasks-lib", package.seeall)
|
||||
|
||||
|
||||
function index()
|
||||
entry({"admin", "system", "tasks", "status"}, call("tasks_status")).dependent=false
|
||||
entry({"admin", "system", "tasks", "log"}, call("tasks_log")).dependent=false
|
||||
entry({"admin", "system", "tasks", "stop"}, post("tasks_stop")).dependent=false
|
||||
end
|
||||
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
local ltn12 = require "luci.ltn12"
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
|
||||
function tasks_status()
|
||||
local data = taskd.status(luci.http.formvalue("task_id"))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(data)
|
||||
end
|
||||
|
||||
function tasks_log()
|
||||
local wait = 107
|
||||
local task_id = luci.http.formvalue("task_id")
|
||||
local offset = luci.http.formvalue("offset")
|
||||
offset = offset and tonumber(offset) or 0
|
||||
local logpath = "/var/log/tasks/"..task_id..".log"
|
||||
local i
|
||||
local logfd = io.open(logpath, "rb")
|
||||
if logfd == nil then
|
||||
luci.http.status(404)
|
||||
luci.http.write("log not found")
|
||||
return
|
||||
end
|
||||
|
||||
local size = logfd:seek("end")
|
||||
|
||||
if size < offset then
|
||||
luci.http.status(205, "Reset Content")
|
||||
luci.http.write("reset offset")
|
||||
return
|
||||
end
|
||||
|
||||
i = 0
|
||||
while (i < wait)
|
||||
do
|
||||
if size > offset then
|
||||
break
|
||||
end
|
||||
nixio.nanosleep(0, 10000000) -- sleep 10ms
|
||||
size = logfd:seek("end")
|
||||
i = i+1
|
||||
end
|
||||
if i == wait then
|
||||
logfd:close()
|
||||
luci.http.status(204)
|
||||
luci.http.prepare_content("application/octet-stream")
|
||||
return
|
||||
end
|
||||
logfd:seek("set", offset)
|
||||
|
||||
local write_log = function()
|
||||
local buffer = logfd:read(4096)
|
||||
if buffer and #buffer > 0 then
|
||||
return buffer
|
||||
else
|
||||
logfd:close()
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/octet-stream")
|
||||
|
||||
if logfd then
|
||||
ltn12.pump.all(write_log, luci.http.write)
|
||||
end
|
||||
end
|
||||
|
||||
function tasks_stop()
|
||||
local sys = require("luci.sys")
|
||||
local task_id = luci.http.formvalue("task_id") or ""
|
||||
if task_id == "" then
|
||||
luci.http.status(400)
|
||||
luci.http.write("task_id is empty")
|
||||
return
|
||||
end
|
||||
if sys.call("/etc/init.d/tasks task_del "..task_id.." >/dev/null 2>&1") ~= 0 then
|
||||
nixio.nanosleep(2, 10000000)
|
||||
end
|
||||
luci.http.status(204)
|
||||
end
|
100
luci-lib-taskd/luasrc/model/tasks.lua
Normal file
100
luci-lib-taskd/luasrc/model/tasks.lua
Normal file
@ -0,0 +1,100 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local taskd = {}
|
||||
|
||||
local function output(data)
|
||||
local ret={}
|
||||
ret.running=data.running
|
||||
if not data.running then
|
||||
ret.exit_code=data.exit_code
|
||||
if nil == ret.exit_code then
|
||||
if data["data"] and data["data"]["exit_code"] and data["data"]["exit_code"] ~= "" then
|
||||
ret.exit_code=tonumber(data["data"]["exit_code"])
|
||||
else
|
||||
ret.exit_code=143
|
||||
end
|
||||
end
|
||||
end
|
||||
ret.command=data["command"] and data["command"][4] or '#'
|
||||
if data["data"] then
|
||||
ret.start=tonumber(data["data"]["start"])
|
||||
if not data.running and data["data"]["stop"] then
|
||||
ret.stop=tonumber(data["data"]["stop"])
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
taskd.status = function (task_id)
|
||||
task_id = task_id or ""
|
||||
local data = util.trim(util.exec("/etc/init.d/tasks task_status "..task_id.." 2>/dev/null")) or ""
|
||||
if data ~= "" then
|
||||
data = jsonc.parse(data)
|
||||
else
|
||||
if task_id == "" then
|
||||
data = {}
|
||||
else
|
||||
data = {running=false, exit_code=404}
|
||||
end
|
||||
end
|
||||
if task_id ~= "" then
|
||||
return output(data)
|
||||
end
|
||||
local ary={}
|
||||
for k, v in pairs(data) do
|
||||
ary[k] = output(v)
|
||||
end
|
||||
return ary
|
||||
end
|
||||
|
||||
taskd.docker_map = function(config, task_id, script_path, title, desc)
|
||||
require("luci.cbi")
|
||||
require("luci.http")
|
||||
require("luci.sys")
|
||||
local translate = require("luci.i18n").translate
|
||||
local m
|
||||
m = luci.cbi.Map(config, title, desc)
|
||||
m.template = "tasks/docker"
|
||||
-- hide default buttons
|
||||
m.pageaction = false
|
||||
-- we want hook 'on_after_apply' works, 'apply_on_parse' can be true (rollback) or false (no rollback),
|
||||
-- but 'apply_on_parse' must be true for luci 17.01 and below
|
||||
m.apply_on_parse = true
|
||||
m.script_path = script_path
|
||||
m.task_id = task_id
|
||||
m.auto_show_task = true
|
||||
m.on_before_apply = function(self)
|
||||
if self.uci.rollback then
|
||||
-- luci 18.06+ has 'rollback' function
|
||||
-- rollback dialog will show because 'apply_on_parse' is true,
|
||||
-- hide rollback dialog by hook 'apply' function
|
||||
local apply = self.uci.apply
|
||||
self.uci.apply = function(uci, rollback)
|
||||
apply(uci, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
m.on_after_apply = function(self)
|
||||
local cmd
|
||||
local action = luci.http.formvalue("cbi.apply") or "null"
|
||||
if "upgrade" == action or "install" == action
|
||||
or "start" == action or "stop" == action or "restart" == action or "rm" == action then
|
||||
cmd = string.format("\"%s\" %s", script_path, action)
|
||||
end
|
||||
if cmd then
|
||||
if luci.sys.call("/etc/init.d/tasks task_add " .. task_id .. " " .. luci.util.shellquote(cmd) .. " >/dev/null 2>&1") ~= 0 then
|
||||
self.task_start_failed = true
|
||||
self.message = translate("Config saved, but apply failed")
|
||||
end
|
||||
else
|
||||
self.message = translate("Unknown command: ") .. action
|
||||
end
|
||||
if self.message then
|
||||
self.auto_show_task = false
|
||||
end
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
return taskd
|
56
luci-lib-taskd/luasrc/view/tasks/docker.htm
Normal file
56
luci-lib-taskd/luasrc/view/tasks/docker.htm
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
<% if self.task_start_failed then %>
|
||||
<div class="alert-message warning"><%:Another task running, try again later.%> <a href="javascript:void(taskd.show_log('<%=self.task_id%>'))"><%:Click here to check running task%></a></div>
|
||||
<% end %>
|
||||
|
||||
<%+cbi/map%>
|
||||
<%
|
||||
local task_running = false
|
||||
local taskd = require "luci.model.tasks"
|
||||
local status = taskd.status(self.task_id)
|
||||
task_running = status.running
|
||||
-%>
|
||||
<div class="cbi-page-actions control-group">
|
||||
<%
|
||||
if not task_running then
|
||||
%>
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec(self.script_path.." status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
if container_install then
|
||||
-%>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Upgrade%>/<%:Apply%>" onclick="cbi_submit(this, 'cbi.apply', 'upgrade')" />
|
||||
<%
|
||||
if container_running then
|
||||
-%>
|
||||
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Stop%>" onclick="cbi_submit(this, 'cbi.apply', 'stop')" />
|
||||
|
||||
<input class="btn cbi-button cbi-button-reload" type="button" value="<%:Restart%>" onclick="cbi_submit(this, 'cbi.apply', 'restart')" />
|
||||
<% else %>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Start%>" onclick="cbi_submit(this, 'cbi.apply', 'start')" />
|
||||
|
||||
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Remove%>" onclick="cbi_submit(this, 'cbi.apply', 'rm')" />
|
||||
<% end
|
||||
else %>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Install%>" onclick="cbi_submit(this, 'cbi.apply', 'install')" />
|
||||
<% end
|
||||
else
|
||||
%>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Task Running%>…" onclick="taskd.show_log('<%=self.task_id%>')" />
|
||||
<%
|
||||
end
|
||||
%>
|
||||
</div>
|
||||
|
||||
<%+tasks/embed%>
|
||||
<%
|
||||
if self.auto_show_task and task_running then
|
||||
-%>
|
||||
<script>
|
||||
taskd.show_log("<%=self.task_id%>");
|
||||
</script>
|
||||
<%
|
||||
end
|
||||
%>
|
34
luci-lib-taskd/luasrc/view/tasks/embed.htm
Normal file
34
luci-lib-taskd/luasrc/view/tasks/embed.htm
Normal file
@ -0,0 +1,34 @@
|
||||
<%+xterm/embed%>
|
||||
<link rel="stylesheet" href="<%=resource%>/tasks/tasks.css<%# ?v=PKG_VERSION %>">
|
||||
<script src="<%=resource%>/tasks/tasks.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<%
|
||||
local i18n = {}
|
||||
local function tr(str)
|
||||
i18n[str]=translate(str)
|
||||
end
|
||||
tr("Stop running task?")
|
||||
tr("Stopped at:")
|
||||
tr("Finished at:")
|
||||
tr("Failed at:")
|
||||
tr("Lost login status")
|
||||
tr("Fetch log failed, retrying...")
|
||||
tr("Task does not exist or has been deleted")
|
||||
-%>
|
||||
<script>
|
||||
window.taskd.csrfToken="<%=token%>";
|
||||
window.taskd.i18n=<% luci.http.write_json(i18n) %>;
|
||||
window.taskd.dialog_template=`
|
||||
<div id="tasks_dialog">
|
||||
<div class="dialog-title-bar">
|
||||
<span class="dialog-title" id="tasks_id"></span>
|
||||
<span class="dialog-icons">
|
||||
<span class="dialog-icon dialog-icon-close" title="<%:Stop and Remove%>"></span>
|
||||
<span class="dialog-icon dialog-icon-min" title="<%:Hide%>"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="dialog-content">
|
||||
<div id="tasks_xterm_log"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
</script>
|
15
luci-lib-taskd/src/Makefile
Normal file
15
luci-lib-taskd/src/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
clean:
|
||||
compile:
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_NAME:=luci-lib-dummy
|
||||
INCLUDE_DIR:=./dummy
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
install:
|
||||
mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n"
|
||||
$(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \
|
||||
po2lmo $(po) \
|
||||
$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).$(lang).lmo;))
|
2
luci-lib-taskd/src/dummy/package.mk
Normal file
2
luci-lib-taskd/src/dummy/package.mk
Normal file
@ -0,0 +1,2 @@
|
||||
define BuildPackage
|
||||
endef
|
41
luci-lib-taskd/src/po/zh-cn/lib-tasks.po
Normal file
41
luci-lib-taskd/src/po/zh-cn/lib-tasks.po
Normal file
@ -0,0 +1,41 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Stop running task?"
|
||||
msgstr "删除运行中的任务?"
|
||||
|
||||
msgid "Finished at:"
|
||||
msgstr "完成于:"
|
||||
|
||||
msgid "Failed at:"
|
||||
msgstr "失败于:"
|
||||
|
||||
msgid "Lost login status"
|
||||
msgstr "丢失登陆状态"
|
||||
|
||||
msgid "Fetch log failed, retrying..."
|
||||
msgstr "拉取日志失败,正在重试..."
|
||||
|
||||
msgid "Task does not exist or has been deleted"
|
||||
msgstr "任务不存在或已删除"
|
||||
|
||||
msgid "Stop and Remove"
|
||||
msgstr "停止并删除"
|
||||
|
||||
msgid "Hide"
|
||||
msgstr "隐藏"
|
||||
|
||||
msgid "Config saved, but apply failed"
|
||||
msgstr "配置已保存,但应用失败"
|
||||
|
||||
msgid "Unknown command: "
|
||||
msgstr "未知命令:"
|
||||
|
||||
msgid "Another task running, try again later."
|
||||
msgstr "已有后台任务运行中,请稍后重试。"
|
||||
|
||||
msgid "Click here to check running task"
|
||||
msgstr "点此查看运行中的任务"
|
||||
|
||||
msgid "Task Running"
|
||||
msgstr "任务执行中"
|
21
luci-lib-xterm/Makefile
Normal file
21
luci-lib-xterm/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright (c) 2017-2019, The xterm.js authors (MIT License)
|
||||
# Copyright (c) 2014-2017, SourceLair, Private Company (www.sourcelair.com) (MIT License)
|
||||
# Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
#
|
||||
# This is free software, licensed under the MIT License.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Xterm.js library
|
||||
LUCI_DEPENDS:=
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_VERSION:=4.18.0
|
||||
PKG_RELEASE:=
|
||||
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
180
luci-lib-xterm/htdocs/luci-static/resources/xterm/xterm.css
Normal file
180
luci-lib-xterm/htdocs/luci-static/resources/xterm/xterm.css
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
* https://github.com/chjj/term.js
|
||||
* @license MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Originally forked from (with the author's permission):
|
||||
* Fabrice Bellard's javascript vt100 for jslinux:
|
||||
* http://bellard.org/jslinux/
|
||||
* Copyright (c) 2011 Fabrice Bellard
|
||||
* The original design remains. The terminal itself
|
||||
* has been extended to include xterm CSI codes, among
|
||||
* other features.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default styles for xterm.js
|
||||
*/
|
||||
|
||||
.xterm {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.xterm.focus,
|
||||
.xterm:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-helpers {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/**
|
||||
* The z-index of the helpers must be higher than the canvases in order for
|
||||
* IMEs to appear on top.
|
||||
*/
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -5;
|
||||
/** Prevent wrapping so the IME appears against the textarea at the correct position */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.xterm .composition-view {
|
||||
/* TODO: Composition position got messed up somewhere */
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
display: none;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.xterm .composition-view.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-scroll-area {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.xterm-char-measure-element {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999em;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.xterm {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.xterm.enable-mouse-events {
|
||||
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer,
|
||||
.xterm .xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xterm.column-select.focus {
|
||||
/* Column selection mode */
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility,
|
||||
.xterm .xterm-message {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .live-region {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xterm-dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.xterm-underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.xterm-strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.xterm-screen .xterm-decoration-container .xterm-decoration {
|
||||
z-index: 6;
|
||||
position: absolute;
|
||||
}
|
File diff suppressed because one or more lines are too long
3
luci-lib-xterm/luasrc/view/xterm/embed.htm
Normal file
3
luci-lib-xterm/luasrc/view/xterm/embed.htm
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
<link rel="stylesheet" href="<%=resource%>/xterm/xterm.css<%# ?v=PKG_VERSION %>">
|
||||
<script src="<%=resource%>/xterm/xterm.js<%# ?v=PKG_VERSION %>"></script>
|
9
openwrt-app-actions/README.md
Normal file
9
openwrt-app-actions/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Openwrt-actions
|
||||
|
||||
## 使用步骤
|
||||
1. 选择actions标签,选择Build IPKs![image](https://user-images.githubusercontent.com/1214708/153843131-615197e2-4ff4-4c0b-b30a-372e1c513158.png)
|
||||
|
||||
2. 点击run workflow,输入要编译的插件名称,空格隔开,或者填“all”用来编译所有插件,然后开始编译![image](https://user-images.githubusercontent.com/1214708/153843217-0591a7e6-4758-461e-8b2b-9bb830b87fb2.png)
|
||||
|
||||
3. 等待编译完成,点击任务进入详情页
|
||||
4. 在详情页下载插件压缩包![image](https://user-images.githubusercontent.com/1214708/153843272-81843b45-6dc8-4945-871f-a9a467f63c33.png)
|
18
openwrt-app-actions/applications/luci-app-heimdall/Makefile
Normal file
18
openwrt-app-actions/applications/luci-app-heimdall/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.0-20220830
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for heimdall
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-heimdall/conffiles
|
||||
/etc/config/heimdall
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.heimdall", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "heimdall"}, alias("admin", "services", "heimdall", "config"), _("Heimdall"), 30).dependent = true
|
||||
entry({"admin", "services", "heimdall", "config"}, cbi("heimdall"))
|
||||
end
|
@ -0,0 +1,35 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("heimdall", "heimdall", "/usr/libexec/istorec/heimdall.sh",
|
||||
translate("Heimdall"),
|
||||
translate("Heimdall is an elegant solution to organise all your web applications.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://github.com/linuxserver/Heimdall\" target=\"_blank\">https://github.com/linuxserver/Heimdall</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Heimdall status:"))
|
||||
s:append(Template("heimdall/status"))
|
||||
|
||||
s = m:section(TypedSection, "heimdall", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "8088"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "https_port", translate("HTTPS Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "8089"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "/root/heimdall/config"
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
@ -0,0 +1,31 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/heimdall.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Heimdall is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Heimdall is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/heimdall.sh port"))
|
||||
if port == "" then
|
||||
port="8088"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Heimdall%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,44 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Heimdall is an elegant solution to organise all your web applications."
|
||||
msgstr "Heimdall 是组织所有 Web 应用程序的优雅解决方案。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP 端口"
|
||||
|
||||
msgid "HTTPS Port"
|
||||
msgstr "HTTPS 端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Heimdall status:"
|
||||
msgstr "Heimdall 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Heimdall is running"
|
||||
msgstr "Heimdall 运行中"
|
||||
|
||||
msgid "Heimdall is not running"
|
||||
msgstr "Heimdall 未运行"
|
||||
|
||||
msgid "Open Heimdall"
|
||||
msgstr "打开 Heimdall"
|
@ -0,0 +1,4 @@
|
||||
config heimdall
|
||||
option 'http_port' '8088'
|
||||
option 'https_port' '8089'
|
||||
option 'config_path' '/root/heimdall/config'
|
@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME="lscr.io/linuxserver/heimdall:latest"
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f heimdall
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local config=`uci get heimdall.@heimdall[0].config_path 2>/dev/null`
|
||||
local http_port=`uci get heimdall.@heimdall[0].http_port 2>/dev/null`
|
||||
local https_port=`uci get heimdall.@heimdall[0].https_port 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$http_port" ] && http_port=8088
|
||||
[ -z "$https_port" ] && http_port=8089
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
-v \"$config:/config\" \
|
||||
--dns=172.17.0.1 \
|
||||
-p $http_port:80 \
|
||||
-p $https_port:443 "
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd --name heimdall \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the heimdall"
|
||||
echo " upgrade Upgrade the heimdall"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the heimdall"
|
||||
echo " status Heimdall status"
|
||||
echo " port Heimdall port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f heimdall
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} heimdall
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=heimdall' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=heimdall' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.0-20220830
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for homeassistant
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-homeassistant/conffiles
|
||||
/etc/config/homeassistant
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.homeassistant", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "homeassistant"}, alias("admin", "services", "homeassistant", "config"), _("Home Assistant"), 30).dependent = true
|
||||
entry({"admin", "services", "homeassistant", "config"}, cbi("homeassistant"))
|
||||
end
|
@ -0,0 +1,25 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("homeassistant", "homeassistant", "/usr/libexec/istorec/homeassistant.sh",
|
||||
translate("Home Assistant"),
|
||||
translate("Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://www.home-assistant.io/\" target=\"_blank\">https://www.home-assistant.io/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Home Assistant status:"))
|
||||
s:append(Template("homeassistant/status"))
|
||||
|
||||
s = m:section(TypedSection, "homeassistant", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "/root/homeassistant/config"
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
@ -0,0 +1,31 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/homeassistant.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Home Assistant is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Home Assistant is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/homeassistant.sh port"))
|
||||
if port == "" then
|
||||
port="8123"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open the Home Assistant%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,35 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts."
|
||||
msgstr "将本地控制和隐私放在首位的开源家庭自动化,由全世界 DIY 爱好者组成的社区驱动。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Home Assistant status:"
|
||||
msgstr "Home Assistant 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Home Assistant is running"
|
||||
msgstr "Home Assistant 运行中"
|
||||
|
||||
msgid "Home Assistant is not running"
|
||||
msgstr "Home Assistant 未运行"
|
||||
|
||||
msgid "Open the Home Assistant"
|
||||
msgstr "打开 Home Assistant"
|
@ -0,0 +1,2 @@
|
||||
config homeassistant
|
||||
option 'config_path' '/root/homeassistant/config'
|
@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME="homeassistant/home-assistant:latest"
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f homeassistant
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local config=`uci get homeassistant.@homeassistant[0].config_path 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
-v \"$config:/config\" \
|
||||
--privileged \
|
||||
--network=host \
|
||||
--dns=127.0.0.1 "
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd --name homeassistant \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the homeassistant"
|
||||
echo " upgrade Upgrade the homeassistant"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the homeassistant"
|
||||
echo " status Home Assistant status"
|
||||
echo " port Home Assistant port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f homeassistant
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} homeassistant
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=homeassistant' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=homeassistant' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
19
openwrt-app-actions/applications/luci-app-jackett/Makefile
Normal file
19
openwrt-app-actions/applications/luci-app-jackett/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.0-20220718
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for jackett
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-jackett/conffiles
|
||||
/etc/config/jackett
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.jackett", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "jackett"}, alias("admin", "services", "jackett", "config"), _("Jackett"), 30).dependent = true
|
||||
entry({"admin", "services", "jackett", "config"}, cbi("jackett"))
|
||||
end
|
@ -0,0 +1,37 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("jackett", "jackett", "/usr/libexec/istorec/jackett.sh",
|
||||
translate("Jackett"),
|
||||
translate("Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://github.com/Jackett/Jackett\" target=\"_blank\">https://github.com/Jackett/Jackett</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Jackett status:"))
|
||||
s:append(Template("jackett/status"))
|
||||
|
||||
s = m:section(TypedSection, "jackett", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "9117"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "save_path", translate("Torrent save path").."<b>*</b>", translate("Usually use the monitoring folder of the torrent download tool"))
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Flag, "auto_update", translate("Auto update"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
return m
|
@ -0,0 +1,31 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/jackett.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Jackett is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Jackett is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/jackett.sh port"))
|
||||
if port == "" then
|
||||
port="9117"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Jackett%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,47 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps."
|
||||
msgstr "Jackett 是维护索引器抓取和翻译逻辑的单一存储库 - 消除了其他应用程序的负担。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Torrent save path"
|
||||
msgstr "种子保存路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Auto update"
|
||||
msgstr "自动更新"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Jackett status:"
|
||||
msgstr "Jackett 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Jackett is running"
|
||||
msgstr "Jackett 运行中"
|
||||
|
||||
msgid "Jackett is not running"
|
||||
msgstr "Jackett 未运行"
|
||||
|
||||
msgid "Open Jackett"
|
||||
msgstr "打开 Jackett"
|
||||
|
||||
msgid "Usually use the monitoring folder of the torrent download tool"
|
||||
msgstr "通常使用BT下载工具的监控文件夹"
|
@ -0,0 +1,5 @@
|
||||
config jackett
|
||||
option 'auto_update' '1'
|
||||
option 'port' '9117'
|
||||
option 'save_path' ''
|
||||
option 'config_path' '/root/jackett/config'
|
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME="linuxserver/jackett:latest"
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f jackett
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local save_path=`uci get jackett.@jackett[0].save_path 2>/dev/null`
|
||||
local config=`uci get jackett.@jackett[0].config_path 2>/dev/null`
|
||||
local port=`uci get jackett.@jackett[0].port 2>/dev/null`
|
||||
local auto_update=`uci get jackett.@jackett[0].auto_update 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$save_path" ]; then
|
||||
echo "save path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$port" ] && port=9117
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
-v \"$config:/config\" \
|
||||
-v \"$save_path:/downloads\" \
|
||||
--dns=172.17.0.1 \
|
||||
-p $port:9117 "
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
if [ -n "$auto_update" ]; then
|
||||
if [ "$auto_update" = 1 ]; then
|
||||
cmd="$cmd -e AUTO_UPDATE=true"
|
||||
else
|
||||
cmd="$cmd -e AUTO_UPDATE=false"
|
||||
fi
|
||||
fi
|
||||
|
||||
cmd="$cmd --name jackett \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the jackett"
|
||||
echo " upgrade Upgrade the jackett"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the jackett"
|
||||
echo " status Jackett status"
|
||||
echo " port Jackett port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f jackett
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} jackett
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=jackett' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=jackett' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
19
openwrt-app-actions/applications/luci-app-jellyfin/Makefile
Normal file
19
openwrt-app-actions/applications/luci-app-jellyfin/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.5-20220729
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for jellyfin
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-jellyfin/conffiles
|
||||
/etc/config/jellyfin
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.jellyfin", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "jellyfin"}, alias("admin", "services", "jellyfin", "config"), _("Jellyfin"), 30).dependent = true
|
||||
entry({"admin", "services", "jellyfin", "config"}, cbi("jellyfin"))
|
||||
end
|
@ -0,0 +1,39 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("jellyfin", "jellyfin", "/usr/share/jellyfin/install.sh",
|
||||
translate("Jellyfin"),
|
||||
translate("Jellyfin is the volunteer-built media solution that puts you in control of your media. Stream to any device from your own server, with no strings attached. Your media, your server, your way.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://jellyfin.org/\" target=\"_blank\">https://jellyfin.org/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Jellyfin status:"))
|
||||
s:append(Template("jellyfin/status"))
|
||||
|
||||
s = m:section(TypedSection, "jellyfin", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Flag, "hostnet", translate("Host network"), translate("Jellyfin running in host network, for DLNA application, port is always 8096 if enabled"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.default = "8096"
|
||||
o.datatype = "port"
|
||||
o:depends("hostnet", 0)
|
||||
|
||||
o = s:option(Value, "media_path", translate("Media path"))
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "cache_path", translate("Transcode cache path"), translate("Default use 'transcodes' in 'config path' if not set, please make sure there has enough space"))
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
@ -0,0 +1,31 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/share/jellyfin/install.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Jellyfin is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Jellyfin is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/share/jellyfin/install.sh port"))
|
||||
if port == "" then
|
||||
port="8096"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Jellyfin%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,53 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Jellyfin is the volunteer-built media solution that puts you in control of your media. Stream to any device from your own server, with no strings attached. Your media, your server, your way."
|
||||
msgstr "Jellyfin 是志愿者构建的媒体解决方案,可让您控制自己的电影等媒体,并没带任何条件的让您从各种设备去观看您的媒体。"
|
||||
|
||||
msgid "Media path"
|
||||
msgstr "媒体路径"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Transcode cache path"
|
||||
msgstr "转码缓存路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Host network"
|
||||
msgstr "宿主网络"
|
||||
|
||||
msgid "Jellyfin running in host network, for DLNA application, port is always 8096 if enabled"
|
||||
msgstr "在宿主网络运行 Jellyfin,以支持 DLNA 等应用,例如投屏,如果启用则端口固定为8096"
|
||||
|
||||
msgid "Default use 'transcodes' in 'config path' if not set, please make sure there has enough space"
|
||||
msgstr "留空则使用配置文件路径下的 transcodes,请确保有足够空间"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Jellyfin status:"
|
||||
msgstr "Jellyfin 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Jellyfin is running"
|
||||
msgstr "Jellyfin 运行中"
|
||||
|
||||
msgid "Jellyfin is not running"
|
||||
msgstr "Jellyfin 未运行"
|
||||
|
||||
msgid "Open Jellyfin"
|
||||
msgstr "打开 Jellyfin"
|
@ -0,0 +1,7 @@
|
||||
config jellyfin
|
||||
option 'hostnet' '0'
|
||||
option 'port' '8096'
|
||||
option 'image' 'default'
|
||||
option 'media_path' ''
|
||||
option 'config_path' '/root/jellyfin/config'
|
||||
option 'cache_path' ''
|
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
image_name=`uci get jellyfin.@jellyfin[0].image 2>/dev/null`
|
||||
|
||||
if [ "$image_name" == "jjm2473/jellyfin-rtk:latest" ]; then
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set jellyfin.@jellyfin[0].image="default"
|
||||
commit jellyfin
|
||||
EOF
|
||||
fi
|
||||
exit 0
|
@ -0,0 +1,137 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
ARCH="default"
|
||||
IMAGE_NAME='default'
|
||||
|
||||
get_image() {
|
||||
if grep -Eq ',rtd-?129.$' /proc/device-tree/compatible 2>/dev/null; then
|
||||
ARCH="rtd129x"
|
||||
fi
|
||||
IMAGE_NAME=`uci get jellyfin.@jellyfin[0].image 2>/dev/null`
|
||||
if [ -z "$IMAGE_NAME" -o "$IMAGE_NAME" == "default" ]; then
|
||||
if [ "${ARCH}" = "rtd129x" ]; then
|
||||
IMAGE_NAME="jjm2473/jellyfin-rtk:latest"
|
||||
if uname -r | grep -q '^4\.9\.'; then
|
||||
IMAGE_NAME="jjm2473/jellyfin-rtk:4.9-latest"
|
||||
fi
|
||||
else
|
||||
IMAGE_NAME="jellyfin/jellyfin"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f jellyfin
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local hostnet=`uci get jellyfin.@jellyfin[0].hostnet 2>/dev/null`
|
||||
local media=`uci get jellyfin.@jellyfin[0].media_path 2>/dev/null`
|
||||
local config=`uci get jellyfin.@jellyfin[0].config_path 2>/dev/null`
|
||||
local cache=`uci get jellyfin.@jellyfin[0].cache_path 2>/dev/null`
|
||||
local port=`uci get jellyfin.@jellyfin[0].port 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$port" ] && port=8096
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -v \"$config:/config\" "
|
||||
if [ "${ARCH}" = "rtd129x" ]; then
|
||||
cmd="$cmd\
|
||||
--device /dev/rpc0:/dev/rpc0 \
|
||||
--device /dev/rpc1:/dev/rpc1 \
|
||||
--device /dev/rpc2:/dev/rpc2 \
|
||||
--device /dev/rpc3:/dev/rpc3 \
|
||||
--device /dev/rpc4:/dev/rpc4 \
|
||||
--device /dev/rpc5:/dev/rpc5 \
|
||||
--device /dev/rpc6:/dev/rpc6 \
|
||||
--device /dev/rpc7:/dev/rpc7 \
|
||||
--device /dev/rpc100:/dev/rpc100 \
|
||||
--device /dev/uio250:/dev/uio250 \
|
||||
--device /dev/uio251:/dev/uio251 \
|
||||
--device /dev/uio252:/dev/uio252 \
|
||||
--device /dev/uio253:/dev/uio253 \
|
||||
--device /dev/ion:/dev/ion \
|
||||
--device /dev/ve3:/dev/ve3 \
|
||||
--device /dev/vpu:/dev/vpu \
|
||||
--device /dev/memalloc:/dev/memalloc \
|
||||
-v /tmp/shm:/dev/shm \
|
||||
-v /sys/class/uio:/sys/class/uio \
|
||||
-v /var/tmp/vowb:/var/tmp/vowb \
|
||||
--pid=host "
|
||||
elif [ -d /dev/dri ]; then
|
||||
cmd="$cmd\
|
||||
--device /dev/dri:/dev/dri \
|
||||
--privileged "
|
||||
fi
|
||||
if [ "$hostnet" = 1 ]; then
|
||||
cmd="$cmd\
|
||||
--dns=127.0.0.1 \
|
||||
--network=host "
|
||||
else
|
||||
cmd="$cmd\
|
||||
--dns=172.17.0.1 \
|
||||
-p $port:8096 "
|
||||
fi
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
[ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/transcodes\""
|
||||
[ -z "$media" ] || cmd="$cmd -v \"$media:/media\""
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name jellyfin \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the jellyfin"
|
||||
echo " upgrade Upgrade the jellyfin"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the jellyfin"
|
||||
echo " status Jellyfin status"
|
||||
echo " port Jellyfin port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f jellyfin
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} jellyfin
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=jellyfin' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=jellyfin' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.2.0-20220830
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for kodexplorer
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-kodexplorer/conffiles
|
||||
/etc/config/kodexplorer
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.kodexplorer", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "kodexplorer"}, alias("admin", "services", "kodexplorer", "config"), _("KodExplorer"), 30).dependent = true
|
||||
entry({"admin", "services", "kodexplorer", "config"}, cbi("kodexplorer"))
|
||||
end
|
@ -0,0 +1,30 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("kodexplorer", "kodexplorer", "/usr/libexec/istorec/kodexplorer.sh",
|
||||
translate("KodExplorer"),
|
||||
translate("Private cloud online document management solution based on web technology.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://kodcloud.com/\" target=\"_blank\">https://kodcloud.com/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("KodExplorer status:"))
|
||||
s:append(Template("kodexplorer/status"))
|
||||
|
||||
s = m:section(TypedSection, "kodexplorer", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "8081"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "cache_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "/mnt/sda1/kodexplorer"
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
@ -0,0 +1,31 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/kodexplorer.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:KodExplorer is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:KodExplorer is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/kodexplorer.sh port"))
|
||||
if port == "" then
|
||||
port="8081"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open KodExplorer%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,41 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "KodExplorer"
|
||||
msgstr "可道云"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Private cloud online document management solution based on web technology."
|
||||
msgstr "基于Web技术的私有云在线文档管理解决方案。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "KodExplorer status:"
|
||||
msgstr "可道云的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "KodExplorer is running"
|
||||
msgstr "可道云运行中"
|
||||
|
||||
msgid "KodExplorer is not running"
|
||||
msgstr "可道云未运行"
|
||||
|
||||
msgid "Open KodExplorer"
|
||||
msgstr "打开可道云"
|
@ -0,0 +1,3 @@
|
||||
config kodexplorer
|
||||
option 'cache_path' '/mnt/sda1/kodexplorer'
|
||||
option 'port' '8081'
|
@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME="kodcloud/kodbox:latest"
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f kodexplorer
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local config=`uci get kodexplorer.@kodexplorer[0].cache_path 2>/dev/null`
|
||||
local port=`uci get kodexplorer.@kodexplorer[0].port 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$port" ] && port=8081
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
-v \"$config:/var/www/html\" \
|
||||
--dns=172.17.0.1 \
|
||||
-p $port:80 "
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd --name kodexplorer \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the kodexplorer"
|
||||
echo " upgrade Upgrade the kodexplorer"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the kodexplorer"
|
||||
echo " status KodExplorer status"
|
||||
echo " port KodExplorer port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f kodexplorer
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} kodexplorer
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=kodexplorer' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=kodexplorer' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
18
openwrt-app-actions/applications/luci-app-nastools/Makefile
Normal file
18
openwrt-app-actions/applications/luci-app-nastools/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.0-20220903
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for nastools
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-nastools/conffiles
|
||||
/etc/config/nastools
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,7 @@
|
||||
|
||||
module("luci.controller.nastools", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "nastools"}, alias("admin", "services", "nastools", "config"), _("NasTools"), 30).dependent = true
|
||||
entry({"admin", "services", "nastools", "config"}, cbi("nastools"))
|
||||
end
|
@ -0,0 +1,33 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("nastools", "nastools", "/usr/libexec/istorec/nastools.sh",
|
||||
translate("NasTools"),
|
||||
translate("NasTools is a tools for resource aggregation running in NAS.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://github.com/jxxghp/nas-tools\" target=\"_blank\">https://github.com/jxxghp/nas-tools</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("NasTools status:"))
|
||||
s:append(Template("nastools/status"))
|
||||
|
||||
s = m:section(TypedSection, "nastools", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "3003"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Flag, "auto_upgrade", translate("Auto update"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
return m
|
@ -0,0 +1,32 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/nastools.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:NasTools is running%></button>
|
||||
<div class="cbi-value-description"><%:Default username: admin, password: password%></div>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:NasTools is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/nastools.sh port"))
|
||||
if port == "" then
|
||||
port="3003"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open NasTools%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
@ -0,0 +1,44 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "NasTools is a tools for resource aggregation running in NAS."
|
||||
msgstr "NasTools 是汇聚了电影搜索,下载,订阅,观看等等 NAS 功能的工具集合。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Auto update"
|
||||
msgstr "自动更新"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "NasTools status:"
|
||||
msgstr "NasTools 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "NasTools is running"
|
||||
msgstr "NasTools 运行中"
|
||||
|
||||
msgid "Default username: admin, password: password"
|
||||
msgstr "默认用户名:admin,密码:password"
|
||||
|
||||
msgid "NasTools is not running"
|
||||
msgstr "NasTools 未运行"
|
||||
|
||||
msgid "Open NasTools"
|
||||
msgstr "打开 NasTools"
|
@ -0,0 +1,4 @@
|
||||
config nastools
|
||||
option 'config_path' '/root/nastools/config'
|
||||
option 'http_port' '3003'
|
||||
option 'auto_upgrade' '0'
|
@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME="jxxghp/nas-tools"
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker rm -f nastools
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local config=`uci get nastools.@nastools[0].config_path 2>/dev/null`
|
||||
local port=`uci get nastools.@nastools[0].http_port 2>/dev/null`
|
||||
local auto_update=`uci get nastools.@nastools[0].auto_upgrade 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$port" ] && port=3003
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
--hostname nastools \
|
||||
-v \"$config:/config\" \
|
||||
--dns=172.17.0.1 \
|
||||
-p $port:3000 \
|
||||
-e UMASK=000"
|
||||
|
||||
local tz="`cat /tmp/TZ`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
if [ -n "$auto_update" ]; then
|
||||
if [ "$auto_update" = 1 ]; then
|
||||
cmd="$cmd -e NASTOOL_AUTO_UPDATE=true"
|
||||
else
|
||||
cmd="$cmd -e NASTOOL_AUTO_UPDATE=false"
|
||||
fi
|
||||
fi
|
||||
|
||||
cmd="$cmd --name nastools \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the nastools"
|
||||
echo " upgrade Upgrade the nastools"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the nastools"
|
||||
echo " status NasTools status"
|
||||
echo " port NasTools port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f nastools
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} nastools
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=nastools' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=nastools' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
22
openwrt-app-actions/applications/luci-app-netdata/Makefile
Executable file
22
openwrt-app-actions/applications/luci-app-netdata/Makefile
Executable file
@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
# Copyright (C) 2020-2021 sirpdboy <herboy2008@gmail.com>
|
||||
# https://github.com/sirpdboy/luci-app-netdata for v 1.30.1 cn
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for Netdata
|
||||
LUCI_DEPENDS:=+netdata
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=20210610
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
30
openwrt-app-actions/applications/luci-app-netdata/README.md
Executable file
30
openwrt-app-actions/applications/luci-app-netdata/README.md
Executable file
@ -0,0 +1,30 @@
|
||||
luci-app-netdata for OpenWRT/Lede
|
||||
|
||||
|
||||
Install to OpenWRT/LEDE
|
||||
|
||||
git clone https://github.com/sirpdboy/luci-app-netdata
|
||||
|
||||
cp -r luci-app-netdata LEDE_DIR/package/luci-app-netdata
|
||||
|
||||
cd LEDE_DIR
|
||||
|
||||
./scripts/feeds update -a
|
||||
|
||||
./scripts/feeds install -a
|
||||
|
||||
make menuconfig
|
||||
|
||||
LuCI --->
|
||||
|
||||
1. Collections --->
|
||||
|
||||
<*> luci
|
||||
|
||||
3. Applications --->
|
||||
|
||||
<*> luci-app-netdata.........................LuCI support for Netdata
|
||||
|
||||
|
||||
make package/new/luci-app-netdata/compile V=s
|
||||
|
@ -0,0 +1,12 @@
|
||||
module("luci.controller.netdata", package.seeall)
|
||||
|
||||
function index()
|
||||
if not (luci.sys.call("pidof netdata > /dev/null") == 0) then
|
||||
return
|
||||
end
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
entry({"admin","status","netdata"},template("netdata"),_("NetData"),10).leaf=true
|
||||
|
||||
|
||||
end
|
@ -0,0 +1,25 @@
|
||||
-- Copyright 2018 Nick Peng (pymumu@gmail.com)
|
||||
|
||||
function index()
|
||||
|
||||
|
||||
o = Map("netdate", "<font color='green'>" .. translate("实时监控") .."</font>", "<font color='purple'>" .. translate( "强大的实时监控数据,需要中文版请点击:【升级中文版】") .."</font>")
|
||||
|
||||
t = o:section(TypedSection, "netdate")
|
||||
t.anonymous = true
|
||||
t.description = translate(string.format("%s<br /><br />", status))
|
||||
|
||||
t:tab("base",translate("Basic Settings"))
|
||||
|
||||
e = t:taboption("base", Button, "restart", translate("手动更新"))
|
||||
e.inputtitle = translate("升级中文版")
|
||||
e.inputstyle = "reload"
|
||||
e.write = function()
|
||||
luci.sys.call("/usr/share/netdata/netdatacn 2>&1 >/dev/null")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","status","netdata"))
|
||||
end
|
||||
|
||||
t=o:section(TypedSection,"rss_rules",translate("技术支持"))
|
||||
t.anonymous = true
|
||||
t:append(Template("feedback"))
|
||||
return o
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user