diff --git a/.github/workflows/openwrt-package.yml b/.github/workflows/openwrt-package.yml new file mode 100644 index 0000000..0273990 --- /dev/null +++ b/.github/workflows/openwrt-package.yml @@ -0,0 +1,242 @@ +name: Build OpenWrt Package + +on: + workflow_dispatch: + inputs: + openwrt_version: + description: "OpenWrt version" + required: true + default: "23.05.4" + type: choice + options: + - "23.05.4" + - "23.05.3" + - "22.03.7" + target: + description: "Target architecture" + required: true + default: "x86_64" + type: choice + options: + - "x86_64" + - "aarch64_generic" + - "arm_cortex-a9" + - "mips_24kc" + - "mipsel_24kc" + push: + paths: + - 'docs/openwrt/**' + branches: + - main + - master + pull_request: + paths: + - 'docs/openwrt/**' + +env: + OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version || '23.05.4' }} + TARGET_ARCH: ${{ github.event.inputs.target || 'x86_64' }} + +jobs: + build: + name: Build ${{ matrix.target }} + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + target: + - x86_64 + - aarch64_generic + - arm_cortex-a9 + - mips_24kc + - mipsel_24kc + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up environment + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential clang flex bison g++ gawk \ + gcc-multilib g++-multilib gettext git libncurses5-dev \ + libssl-dev python3-distutils rsync unzip zlib1g-dev \ + file wget curl + + - name: Setup variables + run: | + echo "OPENWRT_VERSION=${OPENWRT_VERSION}" >> $GITHUB_ENV + echo "TARGET_ARCH=${{ matrix.target }}" >> $GITHUB_ENV + echo "WORK_DIR=${{ github.workspace }}/openwrt" >> $GITHUB_ENV + echo "PACKAGE_DIR=${{ github.workspace }}/openwrt/bin/packages" >> $GITHUB_ENV + + case "${{ matrix.target }}" in + x86_64) + echo "SDK_URL_PATH=releases/${OPENWRT_VERSION}/targets/x86/64" >> $GITHUB_ENV + echo "SDK_NAME=openwrt-sdk-${OPENWRT_VERSION}-x86-64_gcc-11.2.0_musl.Linux-x86_64" >> $GITHUB_ENV + ;; + aarch64_generic) + echo "SDK_URL_PATH=releases/${OPENWRT_VERSION}/targets/armvirt/64" >> $GITHUB_ENV + echo "SDK_NAME=openwrt-sdk-${OPENWRT_VERSION}-armvirt-64_gcc-11.2.0_musl.Linux-x86_64" >> $GITHUB_ENV + ;; + arm_cortex-a9) + echo "SDK_URL_PATH=releases/${OPENWRT_VERSION}/targets/bcm53xx/generic" >> $GITHUB_ENV + echo "SDK_NAME=openwrt-sdk-${OPENWRT_VERSION}-bcm53xx-generic_gcc-11.2.0_musl_eabi.Linux-x86_64" >> $GITHUB_ENV + ;; + mips_24kc) + echo "SDK_URL_PATH=releases/${OPENWRT_VERSION}/targets/ath79/generic" >> $GITHUB_ENV + echo "SDK_NAME=openwrt-sdk-${OPENWRT_VERSION}-ath79-generic_gcc-11.2.0_musl.Linux-x86_64" >> $GITHUB_ENV + ;; + mipsel_24kc) + echo "SDK_URL_PATH=releases/${OPENWRT_VERSION}/targets/ramips/mt7621" >> $GITHUB_ENV + echo "SDK_NAME=openwrt-sdk-${OPENWRT_VERSION}-ramips-mt7621_gcc-11.2.0_musl.Linux-x86_64" >> $GITHUB_ENV + ;; + esac + + - name: Cache OpenWrt SDK + id: cache-sdk + uses: actions/cache@v4 + with: + path: ${{ env.WORK_DIR }} + key: ${{ runner.os }}-openwrt-sdk-${{ env.OPENWRT_VERSION }}-${{ matrix.target }} + + - name: Download and extract OpenWrt SDK + if: steps.cache-sdk.outputs.cache-hit != 'true' + run: | + mkdir -p ${{ env.WORK_DIR }} + cd ${{ env.WORK_DIR }} + wget -q https://downloads.openwrt.org/${{ env.SDK_URL_PATH }}/${{ env.SDK_NAME }}.tar.xz + tar -xf ${{ env.SDK_NAME }}.tar.xz --strip-components=1 + rm ${{ env.SDK_NAME }}.tar.xz + + - name: Update and install feeds + run: | + cd ${{ env.WORK_DIR }} + ./scripts/feeds update -a + ./scripts/feeds install -a + + - name: Setup Go build environment + run: | + cd ${{ env.WORK_DIR }} + + # Add golang feed if not exists + if ! grep -q "src-git golang" feeds.conf.default; then + echo "src-git golang https://github.com/openwrt/packages.git;master" >> feeds.conf.default + ./scripts/feeds update golang + ./scripts/feeds install -a -p golang + fi + + - name: Copy go-drive package + run: | + mkdir -p ${{ env.WORK_DIR }}/package/go-drive + cp -r docs/openwrt/* ${{ env.WORK_DIR }}/package/go-drive/ + + # Create symbolic link for easier access + ln -sf ${{ github.workspace }} ${{ env.WORK_DIR }}/package/go-drive/go-drive-src + + - name: Configure package + run: | + cd ${{ env.WORK_DIR }} + + # Enable go-drive packages + echo "CONFIG_PACKAGE_go-drive=m" >> .config + echo "CONFIG_PACKAGE_luci-app-go-drive=m" >> .config + + # Enable required dependencies + echo "CONFIG_PACKAGE_golang=y" >> .config + echo "CONFIG_PACKAGE_node=y" >> .config + echo "CONFIG_PACKAGE_npm=y" >> .config + + make defconfig + + - name: Build package + run: | + cd ${{ env.WORK_DIR }} + make package/go-drive/compile V=s + + - name: Organize build artifacts + run: | + mkdir -p ${{ github.workspace }}/artifacts/${{ matrix.target }} + find ${{ env.PACKAGE_DIR }} -name "*go-drive*.ipk" -exec cp {} ${{ github.workspace }}/artifacts/${{ matrix.target }}/ \; + + # Create build info + echo "Build Information" > ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + echo "===================" >> ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + echo "Target: ${{ matrix.target }}" >> ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + echo "OpenWrt Version: ${{ env.OPENWRT_VERSION }}" >> ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + echo "Build Date: $(date)" >> ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + echo "Commit: ${{ github.sha }}" >> ${{ github.workspace }}/artifacts/${{ matrix.target }}/build-info.txt + + ls -la ${{ github.workspace }}/artifacts/${{ matrix.target }}/ + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: go-drive-openwrt-${{ matrix.target }} + path: ${{ github.workspace }}/artifacts/${{ matrix.target }}/* + retention-days: 30 + + release: + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && contains(github.ref, 'refs/tags/')) + needs: build + runs-on: ubuntu-22.04 + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create release assets + run: | + mkdir -p release + for target in x86_64 aarch64_generic arm_cortex-a9 mips_24kc mipsel_24kc; do + if [ -d "artifacts/go-drive-openwrt-${target}" ]; then + cd "artifacts/go-drive-openwrt-${target}" + tar -czf "../../release/go-drive-openwrt-${target}.tar.gz" *.ipk build-info.txt + cd ../.. + fi + done + + ls -la release/ + + - name: Generate release notes + run: | + echo "# Go-Drive OpenWrt Packages" > release-notes.md + echo "" >> release-notes.md + echo "Auto-generated OpenWrt packages for Go-Drive." >> release-notes.md + echo "" >> release-notes.md + echo "## Supported Architectures" >> release-notes.md + echo "" >> release-notes.md + for target in x86_64 aarch64_generic arm_cortex-a9 mips_24kc mipsel_24kc; do + if [ -f "release/go-drive-openwrt-${target}.tar.gz" ]; then + echo "- ${target}" >> release-notes.md + fi + done + echo "" >> release-notes.md + echo "## Installation" >> release-notes.md + echo "" >> release-notes.md + echo "1. Download the appropriate package for your router architecture" >> release-notes.md + echo "2. Extract the tar.gz file to get the .ipk files" >> release-notes.md + echo "3. Upload and install the .ipk files via LuCI or opkg" >> release-notes.md + echo "" >> release-notes.md + echo "## Build Information" >> release-notes.md + echo "" >> release-notes.md + echo "- OpenWrt Version: ${{ env.OPENWRT_VERSION }}" >> release-notes.md + echo "- Build Date: $(date)" >> release-notes.md + echo "- Commit: ${{ github.sha }}" >> release-notes.md + + - name: Create Release + if: github.event_name == 'workflow_dispatch' + uses: softprops/action-gh-release@v1 + with: + tag_name: openwrt-${{ github.run_number }} + name: OpenWrt Packages - Build ${{ github.run_number }} + body_path: release-notes.md + files: release/*.tar.gz + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/docs/openwrt/Makefile b/docs/openwrt/Makefile new file mode 100644 index 0000000..2993e53 --- /dev/null +++ b/docs/openwrt/Makefile @@ -0,0 +1,107 @@ +# +# Copyright (C) 2024 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:=go-drive +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/devld/go-drive.git +PKG_SOURCE_VERSION:=HEAD +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz + +PKG_MAINTAINER:=Go-Drive Team +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host node/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=go-drive +GO_PKG_EXCLUDES:=vendor +GO_PKG_BUILD_PKG:=go-drive + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/go-drive + SECTION:=net + CATEGORY:=Network + SUBMENU:=Cloud Manager + TITLE:=A powerful cloud drive service + URL:=https://github.com/devld/go-drive + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/go-drive/description + Go-Drive is a powerful cloud drive service that supports multiple storage + backends including local storage, OneDrive, Google Drive, and more. + It provides a modern web interface and RESTful API for file management. +endef + +define Package/go-drive/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/go-drive $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/go-drive $(1)/etc/config/ + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/go-drive $(1)/etc/init.d/ + + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/etc/uci-defaults/go-drive $(1)/etc/uci-defaults/ + + $(INSTALL_DIR) $(1)/usr/share/go-drive/web + $(CP) $(PKG_BUILD_DIR)/web/dist/* $(1)/usr/share/go-drive/web/ + + $(INSTALL_DIR) $(1)/usr/share/go-drive/lang + $(CP) $(PKG_BUILD_DIR)/docs/lang/* $(1)/usr/share/go-drive/lang/ + + $(INSTALL_DIR) $(1)/etc/go-drive + $(INSTALL_CONF) $(PKG_BUILD_DIR)/docs/config.yml $(1)/etc/go-drive/config.yml.example +endef + +define Package/luci-app-go-drive + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI Support for Go-Drive + DEPENDS:=+go-drive +luci-base +endef + +define Package/luci-app-go-drive/description + LuCI web interface for Go-Drive cloud storage service. + Allows configuration and management of Go-Drive through OpenWrt's web interface. +endef + +define Package/luci-app-go-drive/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller + $(INSTALL_DATA) ./luci-app-go-drive/luasrc/controller/go-drive.lua $(1)/usr/lib/lua/luci/controller/ + + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi + $(INSTALL_DATA) ./luci-app-go-drive/luasrc/model/cbi/go-drive.lua $(1)/usr/lib/lua/luci/model/cbi/ + + $(INSTALL_DIR) $(1)/www/luci-static/resources/view + $(INSTALL_DATA) ./luci-app-go-drive/htdocs/luci-static/resources/view/go-drive.js $(1)/www/luci-static/resources/view/ + + $(INSTALL_DIR) $(1)/usr/share/luci/menu.d + $(INSTALL_DATA) ./luci-app-go-drive/root/usr/share/luci/menu.d/luci-app-go-drive.json $(1)/usr/share/luci/menu.d/ +endef + +define Build/Compile + cd $(PKG_BUILD_DIR)/web && npm install && npm run build + $(call GoPackage/Build/Compile) +endef + +$(eval $(call GoBinPackage,go-drive)) +$(eval $(call BuildPackage,go-drive)) +$(eval $(call BuildPackage,luci-app-go-drive)) \ No newline at end of file diff --git a/docs/openwrt/README.md b/docs/openwrt/README.md new file mode 100644 index 0000000..314cdcf --- /dev/null +++ b/docs/openwrt/README.md @@ -0,0 +1,217 @@ +# Go-Drive OpenWrt 包 + +这个目录包含了为 OpenWrt 系统构建 Go-Drive 云盘服务的所有必要文件。 + +## 功能特性 + +- ✅ 通过 OpenWrt 服务管理 Go-Drive (启动/停止/重启) +- ✅ 现代化的 LuCI Web 界面配置 +- ✅ UCI 配置系统集成 +- ✅ 支持所有 Go-Drive 配置选项 +- ✅ 多语言支持 (英文/中文) +- ✅ 自动包构建 (GitHub Actions) + +## 文件结构 + +``` +docs/openwrt/ +├── Makefile # OpenWrt 包构建配置 +├── README.md # 说明文档 +├── files/ # 系统文件 +│ ├── etc/ +│ │ ├── config/go-drive # UCI 配置文件 +│ │ ├── init.d/go-drive # 系统初始化脚本 +│ │ └── uci-defaults/go-drive # 默认配置脚本 +└── luci-app-go-drive/ # LuCI 应用 + ├── htdocs/luci-static/resources/view/ + │ └── go-drive.js # 现代 LuCI JS 视图 + ├── luasrc/ + │ ├── controller/go-drive.lua # LuCI 控制器 + │ └── model/cbi/go-drive.lua # CBI 模型 (兼容性) + ├── po/zh_Hans/go-drive.po # 中文语言包 + └── root/usr/share/luci/menu.d/ + └── luci-app-go-drive.json # LuCI 菜单配置 +``` + +## 安装方法 + +### 方法一:使用预构建包 + +1. 从 [Releases](https://github.com/devld/go-drive/releases) 下载适合你路由器架构的包 +2. 解压 tar.gz 文件获得 .ipk 文件 +3. 通过 LuCI 界面或 SSH 安装: + +```bash +# 通过 opkg 安装 +opkg install go-drive_*.ipk +opkg install luci-app-go-drive_*.ipk + +# 或通过 LuCI 界面:系统 -> 软件包 -> 上传软件包 +``` + +### 方法二:从源码构建 + +1. 准备 OpenWrt 构建环境 +2. 克隆此仓库到 OpenWrt 的 package 目录: + +```bash +cd openwrt/package +git clone https://github.com/devld/go-drive.git +ln -sf go-drive/docs/openwrt go-drive-pkg +``` + +3. 配置并构建: + +```bash +make menuconfig +# 选择: Network -> Cloud Manager -> go-drive +# 选择: LuCI -> Applications -> luci-app-go-drive + +make package/go-drive-pkg/compile V=s +``` + +## 配置说明 + +安装完成后,你可以通过以下方式配置 Go-Drive: + +### LuCI Web 界面 + +1. 登录到 OpenWrt 管理界面 +2. 导航到:服务 (Services) -> Go-Drive +3. 配置各项参数: + +#### 基本设置 +- **启用**: 开启/关闭 Go-Drive 服务 +- **监听地址**: 服务监听的地址和端口 (默认: :8089) +- **数据目录**: 存储应用数据的目录 (默认: /opt/go-drive) +- **默认语言**: 界面默认语言 + +#### 数据库设置 +- **数据库类型**: SQLite 或 MySQL +- **数据库名称**: 数据库名或文件名 +- **连接参数**: MySQL 连接参数 (仅 MySQL) + +#### 高级设置 +- **缩略图设置**: 缩略图缓存配置 +- **认证设置**: 会话和认证配置 +- **搜索设置**: 文件搜索功能 +- **WebDAV设置**: WebDAV 服务配置 + +### 命令行配置 + +你也可以通过 UCI 命令行配置: + +```bash +# 启用服务 +uci set go-drive.config.enabled='1' +uci commit go-drive + +# 修改监听端口 +uci set go-drive.config.listen=':9000' +uci commit go-drive + +# 启动服务 +/etc/init.d/go-drive start +``` + +## 服务管理 + +```bash +# 启动服务 +/etc/init.d/go-drive start + +# 停止服务 +/etc/init.d/go-drive stop + +# 重启服务 +/etc/init.d/go-drive restart + +# 重载配置 +/etc/init.d/go-drive reload + +# 查看状态 +/etc/init.d/go-drive status + +# 开机自启 +/etc/init.d/go-drive enable + +# 禁用自启 +/etc/init.d/go-drive disable +``` + +## 访问 Go-Drive + +服务启动后,你可以通过以下地址访问 Go-Drive: + +``` +http://路由器IP:8089 +``` + +例如:`http://192.168.1.1:8089` + +## 故障排除 + +### 检查服务状态 + +```bash +# 检查进程是否运行 +ps | grep go-drive + +# 检查日志 +logread | grep go-drive + +# 检查配置文件 +cat /opt/go-drive/config.yml +``` + +### 常见问题 + +1. **服务无法启动** + - 检查端口是否被占用 + - 确保数据目录权限正确 + - 查看系统日志确定错误原因 + +2. **无法访问 Web 界面** + - 确认防火墙设置 + - 检查监听地址配置 + - 验证服务是否正常运行 + +3. **配置更改不生效** + - 重启 go-drive 服务 + - 检查 UCI 配置是否正确提交 + +## 开发说明 + +### 修改配置文件 + +如需修改配置项,请编辑以下文件: + +- `files/etc/config/go-drive`: UCI 配置模板 +- `files/etc/init.d/go-drive`: 初始化脚本 +- `luci-app-go-drive/htdocs/luci-static/resources/view/go-drive.js`: LuCI 界面 + +### 添加语言支持 + +1. 在 `luci-app-go-drive/po/` 目录下创建新的语言目录 +2. 翻译 `go-drive.po` 文件 +3. 更新 LuCI 视图文件中的语言选项 + +## 自动构建 + +项目配置了 GitHub Actions 自动构建,支持以下架构: + +- x86_64 (PC/虚拟机) +- aarch64_generic (64位ARM) +- arm_cortex-a9 (32位ARM) +- mips_24kc (MIPS大端) +- mipsel_24kc (MIPS小端) + +构建包会自动发布到 GitHub Releases。 + +## 许可证 + +本项目与 Go-Drive 主项目使用相同的许可证。 + +## 支持 + +如有问题,请在 [GitHub Issues](https://github.com/devld/go-drive/issues) 中反馈。 \ No newline at end of file diff --git a/docs/openwrt/files/etc/config/go-drive b/docs/openwrt/files/etc/config/go-drive new file mode 100644 index 0000000..3051139 --- /dev/null +++ b/docs/openwrt/files/etc/config/go-drive @@ -0,0 +1,38 @@ +config go-drive 'config' + option enabled '0' + option listen ':8089' + option data_dir '/opt/go-drive' + option web_dir '/usr/share/go-drive/web' + option lang_dir '/usr/share/go-drive/lang' + option default_lang 'en-US' + option temp_dir '' + option max_concurrent_task '100' + option free_fs '0' + option api_path '' + option web_path '' + +config database 'db' + option type 'sqlite' + option name 'data.db' + option host '' + option port '' + option user '' + option password '' + +config thumbnail 'thumbnail' + option ttl '720h' + option concurrent '4' + +config auth 'auth' + option validity '2h' + option auto_refresh '1' + +config search 'search' + option enabled '0' + option type 'sqlite' + +config webdav 'webdav' + option enabled '0' + option prefix '/dav' + option allow_anonymous '0' + option max_cache_items '1000' \ No newline at end of file diff --git a/docs/openwrt/files/etc/init.d/go-drive b/docs/openwrt/files/etc/init.d/go-drive new file mode 100755 index 0000000..f8de410 --- /dev/null +++ b/docs/openwrt/files/etc/init.d/go-drive @@ -0,0 +1,195 @@ +#!/bin/sh /etc/rc.common + +START=90 +STOP=10 + +USE_PROCD=1 + +PROG=/usr/bin/go-drive +CONFFILE=/opt/go-drive/config.yml + +validate_go_drive_section() { + uci_load_validate go-drive go-drive "$1" "$2" \ + 'enabled:bool:0' \ + 'listen:string::8089' \ + 'data_dir:string:/opt/go-drive' \ + 'web_dir:string:/usr/share/go-drive/web' \ + 'lang_dir:string:/usr/share/go-drive/lang' \ + 'default_lang:string:en-US' \ + 'temp_dir:string:' \ + 'max_concurrent_task:uinteger:100' \ + 'free_fs:bool:0' \ + 'api_path:string:' \ + 'web_path:string:' +} + +validate_db_section() { + uci_load_validate go-drive db "$1" "$2" \ + 'type:string:sqlite' \ + 'name:string:data.db' \ + 'host:string:' \ + 'port:string:' \ + 'user:string:' \ + 'password:string:' +} + +validate_thumbnail_section() { + uci_load_validate go-drive thumbnail "$1" "$2" \ + 'ttl:string:720h' \ + 'concurrent:uinteger:4' +} + +validate_auth_section() { + uci_load_validate go-drive auth "$1" "$2" \ + 'validity:string:2h' \ + 'auto_refresh:bool:1' +} + +validate_search_section() { + uci_load_validate go-drive search "$1" "$2" \ + 'enabled:bool:0' \ + 'type:string:sqlite' +} + +validate_webdav_section() { + uci_load_validate go-drive webdav "$1" "$2" \ + 'enabled:bool:0' \ + 'prefix:string:/dav' \ + 'allow_anonymous:bool:0' \ + 'max_cache_items:uinteger:1000' +} + +generate_config() { + local enabled listen data_dir web_dir lang_dir default_lang temp_dir + local max_concurrent_task free_fs api_path web_path + local db_type db_name db_host db_port db_user db_password + local thumb_ttl thumb_concurrent + local auth_validity auth_auto_refresh + local search_enabled search_type + local webdav_enabled webdav_prefix webdav_allow_anonymous webdav_max_cache_items + + validate_go_drive_section config || return 1 + validate_db_section db || return 1 + validate_thumbnail_section thumbnail || return 1 + validate_auth_section auth || return 1 + validate_search_section search || return 1 + validate_webdav_section webdav || return 1 + + mkdir -p $(dirname $CONFFILE) + mkdir -p $data_dir + [ -n "$temp_dir" ] && mkdir -p $temp_dir + + cat > $CONFFILE <<-EOF +# The application will listen at this address +listen: $listen + +db: + # database type: currently supports sqlite, mysql + type: $db_type + # database name + name: $db_name +EOF + + if [ "$db_type" = "mysql" ]; then + cat >> $CONFFILE <<-EOF + # database host + host: $db_host + # database port + port: $db_port + # database username + user: $db_user + # database password + password: $db_password +EOF + fi + + cat >> $CONFFILE <<-EOF + +# Data dir. All application data will be stored in this dir +data-dir: $data_dir + +# Temp dir. Default is data-dir/temp +temp-dir: $temp_dir + +# Web static files dir. +web-dir: $web_dir + +# i18n languages +lang-dir: $lang_dir +# If the client's language is not supported, then this language will be used +default-lang: $default_lang + +# Concurrent task. eg. copy, move, delete +max-concurrent-task: $max_concurrent_task + +# Disable 'Local Drive' file path limitation. +free-fs: $([ "$free_fs" = "1" ] && echo "true" || echo "false") + +thumbnail: + # Thumbnails cache validity period + ttl: $thumb_ttl + # Concurrent task for generating thumbnails + concurrent: $thumb_concurrent + + handlers: + - type: image + tags: + file-types: jpg,jpeg,png,gif + - type: text + tags: + file-types: txt,md,xml,html,css,scss,js,json,jsx,properties,yml,yaml,ini,c,h,cpp,go,java,kt,gradle,ps1 + +auth: + # User session validity + validity: $auth_validity + # Auto refresh the token when the user is active + auto-refresh: $([ "$auth_auto_refresh" = "1" ] && echo "true" || echo "false") + +search: + enabled: $([ "$search_enabled" = "1" ] && echo "true" || echo "false") + type: $search_type + +# API path. +api-path: $api_path + +# Static files will be served here +web-path: $web_path +EOF + + if [ "$webdav_enabled" = "1" ]; then + cat >> $CONFFILE <<-EOF + +# WebDAV access configuration +web-dav: + enabled: true + prefix: $webdav_prefix + allow-anonymous: $([ "$webdav_allow_anonymous" = "1" ] && echo "true" || echo "false") + max-cache-items: $webdav_max_cache_items +EOF + fi +} + +start_service() { + local enabled + + validate_go_drive_section config || { + echo "validation failed" + return 1 + } + + [ "$enabled" = "1" ] || return 1 + + generate_config || return 1 + + procd_open_instance + procd_set_param command $PROG -c $CONFFILE + procd_set_param file $CONFFILE + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param respawn + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "go-drive" +} \ No newline at end of file diff --git a/docs/openwrt/files/etc/uci-defaults/go-drive b/docs/openwrt/files/etc/uci-defaults/go-drive new file mode 100755 index 0000000..20463e2 --- /dev/null +++ b/docs/openwrt/files/etc/uci-defaults/go-drive @@ -0,0 +1,24 @@ +#!/bin/sh + +# Create data directory if it doesn't exist +mkdir -p /opt/go-drive + +# Create config file if it doesn't exist +if [ ! -f /opt/go-drive/config.yml ]; then + cp /etc/go-drive/config.yml.example /opt/go-drive/config.yml + + # Update paths in config file for OpenWrt + sed -i 's|data-dir: \./|data-dir: /opt/go-drive|g' /opt/go-drive/config.yml + sed -i 's|web-dir: \./web|web-dir: /usr/share/go-drive/web|g' /opt/go-drive/config.yml + sed -i 's|lang-dir: \./lang|lang-dir: /usr/share/go-drive/lang|g' /opt/go-drive/config.yml + sed -i 's|temp-dir: ""|temp-dir: /tmp/go-drive|g' /opt/go-drive/config.yml +fi + +# Set proper permissions +chown -R root:root /opt/go-drive +chmod -R 755 /opt/go-drive + +# Create temp directory +mkdir -p /tmp/go-drive + +exit 0 \ No newline at end of file diff --git a/docs/openwrt/luci-app-go-drive/htdocs/luci-static/resources/view/go-drive.js b/docs/openwrt/luci-app-go-drive/htdocs/luci-static/resources/view/go-drive.js new file mode 100644 index 0000000..b311cfd --- /dev/null +++ b/docs/openwrt/luci-app-go-drive/htdocs/luci-static/resources/view/go-drive.js @@ -0,0 +1,211 @@ +'use strict'; +'require view'; +'require form'; +'require fs'; +'require uci'; +'require ui'; +'require rpc'; +'require poll'; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +function getServiceStatus() { + return L.resolveDefault(callServiceList('go-drive'), {}).then(function(res) { + var isRunning = false; + try { + isRunning = res['go-drive']['instances']['instance1']['running']; + } catch (e) { } + return isRunning; + }); +} + +function renderStatus(isRunning) { + var spanTemp = '%s %s'; + var renderHTML; + if (isRunning) { + renderHTML = String.format(spanTemp, 'green', _('Go-Drive'), _('RUNNING')); + } else { + renderHTML = String.format(spanTemp, 'red', _('Go-Drive'), _('NOT RUNNING')); + } + return renderHTML; +} + +return view.extend({ + load: function() { + return Promise.all([ + uci.load('go-drive') + ]); + }, + + render: function(data) { + var m, s, o; + + m = new form.Map('go-drive', _('Go-Drive'), _('Go-Drive is a powerful cloud drive service that supports multiple storage backends.')); + + s = m.section(form.NamedSection, 'config', 'go-drive'); + + o = s.option(form.DummyValue, '_status', _('Service Status')); + o.rawhtml = true; + o.render = function(option_index, section_id, in_table) { + return E('div', { class: 'cbi-value' }, [ + E('label', { class: 'cbi-value-title' }, _('Service Status')), + E('div', { class: 'cbi-value-field', id: 'service_status' }, E('em', _('Collecting data...'))) + ]); + }; + + o = s.option(form.Flag, 'enabled', _('Enable')); + o.default = '0'; + + o = s.option(form.Value, 'listen', _('Listen Address')); + o.default = ':8089'; + o.placeholder = ':8089'; + + o = s.option(form.Value, 'data_dir', _('Data Directory')); + o.default = '/opt/go-drive'; + o.placeholder = '/opt/go-drive'; + + o = s.option(form.Value, 'web_dir', _('Web Directory')); + o.default = '/usr/share/go-drive/web'; + o.readonly = true; + + o = s.option(form.Value, 'lang_dir', _('Language Directory')); + o.default = '/usr/share/go-drive/lang'; + o.readonly = true; + + o = s.option(form.ListValue, 'default_lang', _('Default Language')); + o.value('en-US', _('English (US)')); + o.value('zh-CN', _('简体中文')); + o.value('zh-TW', _('繁體中文')); + o.default = 'en-US'; + + o = s.option(form.Value, 'temp_dir', _('Temporary Directory')); + o.placeholder = '/tmp/go-drive'; + + o = s.option(form.Value, 'max_concurrent_task', _('Max Concurrent Tasks')); + o.datatype = 'uinteger'; + o.default = '100'; + o.placeholder = '100'; + + o = s.option(form.Flag, 'free_fs', _('Free Filesystem')); + o.default = '0'; + o.description = _('Allow absolute paths for Local Drive. WARNING: Admin users can access all system files!'); + + o = s.option(form.Value, 'api_path', _('API Path')); + o.placeholder = '/api'; + o.description = _('API path for reverse proxy setups'); + + o = s.option(form.Value, 'web_path', _('Web Path')); + o.placeholder = '/'; + o.description = _('Web path for reverse proxy setups'); + + // Database section + s = m.section(form.NamedSection, 'db', 'database', _('Database Settings')); + + o = s.option(form.ListValue, 'type', _('Database Type')); + o.value('sqlite', 'SQLite'); + o.value('mysql', 'MySQL'); + o.default = 'sqlite'; + + o = s.option(form.Value, 'name', _('Database Name')); + o.default = 'data.db'; + o.depends('type', 'sqlite'); + o.depends('type', 'mysql'); + + o = s.option(form.Value, 'host', _('Database Host')); + o.depends('type', 'mysql'); + o.placeholder = '127.0.0.1'; + + o = s.option(form.Value, 'port', _('Database Port')); + o.depends('type', 'mysql'); + o.datatype = 'port'; + o.placeholder = '3306'; + + o = s.option(form.Value, 'user', _('Database User')); + o.depends('type', 'mysql'); + + o = s.option(form.Value, 'password', _('Database Password')); + o.depends('type', 'mysql'); + o.password = true; + + // Thumbnail section + s = m.section(form.NamedSection, 'thumbnail', 'thumbnail', _('Thumbnail Settings')); + + o = s.option(form.Value, 'ttl', _('Cache TTL')); + o.default = '720h'; + o.placeholder = '720h'; + o.description = _('Thumbnail cache validity period'); + + o = s.option(form.Value, 'concurrent', _('Concurrent Tasks')); + o.datatype = 'uinteger'; + o.default = '4'; + o.placeholder = '4'; + o.description = _('Concurrent thumbnail generation tasks'); + + // Auth section + s = m.section(form.NamedSection, 'auth', 'auth', _('Authentication Settings')); + + o = s.option(form.Value, 'validity', _('Session Validity')); + o.default = '2h'; + o.placeholder = '2h'; + o.description = _('User session validity period'); + + o = s.option(form.Flag, 'auto_refresh', _('Auto Refresh')); + o.default = '1'; + o.description = _('Auto refresh token when user is active'); + + // Search section + s = m.section(form.NamedSection, 'search', 'search', _('Search Settings')); + + o = s.option(form.Flag, 'enabled', _('Enable Search')); + o.default = '0'; + + o = s.option(form.ListValue, 'type', _('Search Type')); + o.value('sqlite', 'SQLite'); + o.depends('enabled', '1'); + o.default = 'sqlite'; + + // WebDAV section + s = m.section(form.NamedSection, 'webdav', 'webdav', _('WebDAV Settings')); + + o = s.option(form.Flag, 'enabled', _('Enable WebDAV')); + o.default = '0'; + + o = s.option(form.Value, 'prefix', _('WebDAV Prefix')); + o.depends('enabled', '1'); + o.default = '/dav'; + o.placeholder = '/dav'; + + o = s.option(form.Flag, 'allow_anonymous', _('Allow Anonymous')); + o.depends('enabled', '1'); + o.default = '0'; + o.description = _('Allow anonymous WebDAV access'); + + o = s.option(form.Value, 'max_cache_items', _('Max Cache Items')); + o.depends('enabled', '1'); + o.datatype = 'uinteger'; + o.default = '1000'; + o.placeholder = '1000'; + + return m.render().then(function(mapEl) { + poll.add(function() { + return getServiceStatus().then(function(res) { + var view = document.getElementById('service_status'); + if (view) { + view.innerHTML = renderStatus(res); + } + }); + }, 5); + + return mapEl; + }); + }, + + handleSave: null, + handleSaveApply: null, + handleReset: null +}); \ No newline at end of file diff --git a/docs/openwrt/luci-app-go-drive/luasrc/controller/go-drive.lua b/docs/openwrt/luci-app-go-drive/luasrc/controller/go-drive.lua new file mode 100644 index 0000000..8fdbd2b --- /dev/null +++ b/docs/openwrt/luci-app-go-drive/luasrc/controller/go-drive.lua @@ -0,0 +1,56 @@ +-- Copyright 2024 OpenWrt +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.go-drive", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/go-drive") then + return + end + + local page + + page = entry({"admin", "services", "go-drive"}, template("go-drive"), _("Go-Drive"), 60) + page.dependent = true + page.acl_depends = { "luci-app-go-drive" } + + page = entry({"admin", "services", "go-drive", "status"}, call("act_status")) + page.leaf = true + + page = entry({"admin", "services", "go-drive", "action"}, call("act_action")) + page.leaf = true +end + +function act_status() + local sys = require "luci.sys" + local util = require "luci.util" + local result = {} + + local status = sys.call("pgrep go-drive >/dev/null") == 0 + + result.running = status + if status then + result.pid = util.trim(sys.exec("pgrep go-drive")) + end + + luci.http.prepare_content("application/json") + luci.http.write_json(result) +end + +function act_action() + local action = luci.http.formvalue("action") + local result = { success = false } + + if action == "start" then + result.success = os.execute("/etc/init.d/go-drive start") == 0 + elseif action == "stop" then + result.success = os.execute("/etc/init.d/go-drive stop") == 0 + elseif action == "restart" then + result.success = os.execute("/etc/init.d/go-drive restart") == 0 + elseif action == "reload" then + result.success = os.execute("/etc/init.d/go-drive reload") == 0 + end + + luci.http.prepare_content("application/json") + luci.http.write_json(result) +end \ No newline at end of file diff --git a/docs/openwrt/luci-app-go-drive/luasrc/model/cbi/go-drive.lua b/docs/openwrt/luci-app-go-drive/luasrc/model/cbi/go-drive.lua new file mode 100644 index 0000000..a326f69 --- /dev/null +++ b/docs/openwrt/luci-app-go-drive/luasrc/model/cbi/go-drive.lua @@ -0,0 +1,154 @@ +-- Copyright 2024 OpenWrt +-- Licensed to the public under the Apache License 2.0. + +local m, s, o +local sys = require "luci.sys" + +m = Map("go-drive", translate("Go-Drive"), translate("Go-Drive is a powerful cloud drive service that supports multiple storage backends.")) + +-- Service Status +s = m:section(TypedSection, "go-drive", translate("Service Status")) +s.anonymous = true + +local status = sys.call("pgrep go-drive >/dev/null") == 0 +local status_text = status and translate("RUNNING") or translate("NOT RUNNING") +local status_color = status and "green" or "red" + +s:option(DummyValue, "status", translate("Status")).value = + string.format('%s', status_color, status_text) + +-- Basic Settings +s = m:section(NamedSection, "config", "go-drive", translate("Basic Settings")) + +o = s:option(Flag, "enabled", translate("Enable")) +o.default = "0" + +o = s:option(Value, "listen", translate("Listen Address")) +o.default = ":8089" +o.placeholder = ":8089" + +o = s:option(Value, "data_dir", translate("Data Directory")) +o.default = "/opt/go-drive" +o.placeholder = "/opt/go-drive" + +o = s:option(Value, "web_dir", translate("Web Directory")) +o.default = "/usr/share/go-drive/web" +o.readonly = true + +o = s:option(Value, "lang_dir", translate("Language Directory")) +o.default = "/usr/share/go-drive/lang" +o.readonly = true + +o = s:option(ListValue, "default_lang", translate("Default Language")) +o:value("en-US", translate("English (US)")) +o:value("zh-CN", translate("Simplified Chinese")) +o:value("zh-TW", translate("Traditional Chinese")) +o.default = "en-US" + +o = s:option(Value, "temp_dir", translate("Temporary Directory")) +o.placeholder = "/tmp/go-drive" + +o = s:option(Value, "max_concurrent_task", translate("Max Concurrent Tasks")) +o.datatype = "uinteger" +o.default = "100" +o.placeholder = "100" + +o = s:option(Flag, "free_fs", translate("Free Filesystem")) +o.default = "0" +o.description = translate("Allow absolute paths for Local Drive. WARNING: Admin users can access all system files!") + +o = s:option(Value, "api_path", translate("API Path")) +o.placeholder = "/api" +o.description = translate("API path for reverse proxy setups") + +o = s:option(Value, "web_path", translate("Web Path")) +o.placeholder = "/" +o.description = translate("Web path for reverse proxy setups") + +-- Database Settings +s = m:section(NamedSection, "db", "database", translate("Database Settings")) + +o = s:option(ListValue, "type", translate("Database Type")) +o:value("sqlite", "SQLite") +o:value("mysql", "MySQL") +o.default = "sqlite" + +o = s:option(Value, "name", translate("Database Name")) +o.default = "data.db" + +o = s:option(Value, "host", translate("Database Host")) +o:depends("type", "mysql") +o.placeholder = "127.0.0.1" + +o = s:option(Value, "port", translate("Database Port")) +o:depends("type", "mysql") +o.datatype = "port" +o.placeholder = "3306" + +o = s:option(Value, "user", translate("Database User")) +o:depends("type", "mysql") + +o = s:option(Value, "password", translate("Database Password")) +o:depends("type", "mysql") +o.password = true + +-- Thumbnail Settings +s = m:section(NamedSection, "thumbnail", "thumbnail", translate("Thumbnail Settings")) + +o = s:option(Value, "ttl", translate("Cache TTL")) +o.default = "720h" +o.placeholder = "720h" +o.description = translate("Thumbnail cache validity period") + +o = s:option(Value, "concurrent", translate("Concurrent Tasks")) +o.datatype = "uinteger" +o.default = "4" +o.placeholder = "4" +o.description = translate("Concurrent thumbnail generation tasks") + +-- Authentication Settings +s = m:section(NamedSection, "auth", "auth", translate("Authentication Settings")) + +o = s:option(Value, "validity", translate("Session Validity")) +o.default = "2h" +o.placeholder = "2h" +o.description = translate("User session validity period") + +o = s:option(Flag, "auto_refresh", translate("Auto Refresh")) +o.default = "1" +o.description = translate("Auto refresh token when user is active") + +-- Search Settings +s = m:section(NamedSection, "search", "search", translate("Search Settings")) + +o = s:option(Flag, "enabled", translate("Enable Search")) +o.default = "0" + +o = s:option(ListValue, "type", translate("Search Type")) +o:value("sqlite", "SQLite") +o:depends("enabled", "1") +o.default = "sqlite" + +-- WebDAV Settings +s = m:section(NamedSection, "webdav", "webdav", translate("WebDAV Settings")) + +o = s:option(Flag, "enabled", translate("Enable WebDAV")) +o.default = "0" + +o = s:option(Value, "prefix", translate("WebDAV Prefix")) +o:depends("enabled", "1") +o.default = "/dav" +o.placeholder = "/dav" + +o = s:option(Flag, "allow_anonymous", translate("Allow Anonymous")) +o:depends("enabled", "1") +o.default = "0" +o.description = translate("Allow anonymous WebDAV access") + +o = s:option(Value, "max_cache_items", translate("Max Cache Items")) +o:depends("enabled", "1") +o.datatype = "uinteger" +o.default = "1000" +o.placeholder = "1000" + +return m \ No newline at end of file diff --git a/docs/openwrt/luci-app-go-drive/po/zh_Hans/go-drive.po b/docs/openwrt/luci-app-go-drive/po/zh_Hans/go-drive.po new file mode 100644 index 0000000..f4c844b --- /dev/null +++ b/docs/openwrt/luci-app-go-drive/po/zh_Hans/go-drive.po @@ -0,0 +1,162 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2024-01-01 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_Hans\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 3.0\n" + +msgid "Go-Drive" +msgstr "Go-Drive" + +msgid "Go-Drive is a powerful cloud drive service that supports multiple storage backends." +msgstr "Go-Drive 是一个强大的云盘服务,支持多种存储后端。" + +msgid "Service Status" +msgstr "服务状态" + +msgid "RUNNING" +msgstr "运行中" + +msgid "NOT RUNNING" +msgstr "未运行" + +msgid "Status" +msgstr "状态" + +msgid "Enable" +msgstr "启用" + +msgid "Basic Settings" +msgstr "基本设置" + +msgid "Listen Address" +msgstr "监听地址" + +msgid "Data Directory" +msgstr "数据目录" + +msgid "Web Directory" +msgstr "Web目录" + +msgid "Language Directory" +msgstr "语言目录" + +msgid "Default Language" +msgstr "默认语言" + +msgid "English (US)" +msgstr "英语(美国)" + +msgid "Simplified Chinese" +msgstr "简体中文" + +msgid "Traditional Chinese" +msgstr "繁体中文" + +msgid "Temporary Directory" +msgstr "临时目录" + +msgid "Max Concurrent Tasks" +msgstr "最大并发任务数" + +msgid "Free Filesystem" +msgstr "自由文件系统" + +msgid "Allow absolute paths for Local Drive. WARNING: Admin users can access all system files!" +msgstr "允许本地驱动器使用绝对路径。警告:管理员用户可以访问所有系统文件!" + +msgid "API Path" +msgstr "API路径" + +msgid "API path for reverse proxy setups" +msgstr "反向代理设置的API路径" + +msgid "Web Path" +msgstr "Web路径" + +msgid "Web path for reverse proxy setups" +msgstr "反向代理设置的Web路径" + +msgid "Database Settings" +msgstr "数据库设置" + +msgid "Database Type" +msgstr "数据库类型" + +msgid "Database Name" +msgstr "数据库名称" + +msgid "Database Host" +msgstr "数据库主机" + +msgid "Database Port" +msgstr "数据库端口" + +msgid "Database User" +msgstr "数据库用户" + +msgid "Database Password" +msgstr "数据库密码" + +msgid "Thumbnail Settings" +msgstr "缩略图设置" + +msgid "Cache TTL" +msgstr "缓存有效期" + +msgid "Thumbnail cache validity period" +msgstr "缩略图缓存有效期" + +msgid "Concurrent Tasks" +msgstr "并发任务数" + +msgid "Concurrent thumbnail generation tasks" +msgstr "并发缩略图生成任务数" + +msgid "Authentication Settings" +msgstr "认证设置" + +msgid "Session Validity" +msgstr "会话有效期" + +msgid "User session validity period" +msgstr "用户会话有效期" + +msgid "Auto Refresh" +msgstr "自动刷新" + +msgid "Auto refresh token when user is active" +msgstr "用户活动时自动刷新令牌" + +msgid "Search Settings" +msgstr "搜索设置" + +msgid "Enable Search" +msgstr "启用搜索" + +msgid "Search Type" +msgstr "搜索类型" + +msgid "WebDAV Settings" +msgstr "WebDAV设置" + +msgid "Enable WebDAV" +msgstr "启用WebDAV" + +msgid "WebDAV Prefix" +msgstr "WebDAV前缀" + +msgid "Allow Anonymous" +msgstr "允许匿名访问" + +msgid "Allow anonymous WebDAV access" +msgstr "允许匿名WebDAV访问" + +msgid "Max Cache Items" +msgstr "最大缓存项目数" \ No newline at end of file diff --git a/docs/openwrt/luci-app-go-drive/root/usr/share/luci/menu.d/luci-app-go-drive.json b/docs/openwrt/luci-app-go-drive/root/usr/share/luci/menu.d/luci-app-go-drive.json new file mode 100644 index 0000000..58848b9 --- /dev/null +++ b/docs/openwrt/luci-app-go-drive/root/usr/share/luci/menu.d/luci-app-go-drive.json @@ -0,0 +1,13 @@ +{ + "admin/services/go-drive": { + "title": "Go-Drive", + "order": 60, + "action": { + "type": "view", + "path": "go-drive" + }, + "depends": { + "acl": [ "luci-app-go-drive" ] + } + } +} \ No newline at end of file