diff --git a/.gitea/workflows/devstar-studio-dev-ci.yaml b/.gitea/workflows/devstar-studio-dev-ci.yaml new file mode 100644 index 0000000000..10d3bb07d6 --- /dev/null +++ b/.gitea/workflows/devstar-studio-dev-ci.yaml @@ -0,0 +1,93 @@ +# devstar-studio-dev-ci.yaml +# DevStar 测试并构建制品 CI 工作流定义 +# +# Artifact命名规则: +# 1. ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:latest +# e.g., devstar.cn/devstar/devstar-studio:latest +# 2. ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:rootless-dev-${{ gitea.sha }} +# e.g., devstar.cn/devstar/devstar-studio:rootless-dev-0047d315a3f73cca0c18c641d24b0347456618d5 +# 其中, +# - rootless 表示非 root 权限容器 +# - dev 表示开发版本 +# - ${{ gitea.sha }} 表示触发 CI Workflow 的 commit SHA +# +# 构建参数设置 +# 点击仓库 > 设置 > Actions > 密钥: +# - ${{ secrets.DOCKER_REGISTRY_USERNAME }}: Docker Registry 用户名 +# - ${{ secrets.DOCKER_REGISTRY_PASSWORD }}: Docker Registry 密码 +# 点击仓库 > 设置 > Actions > 变量: +# - ${{ vars.DOCKER_REGISTRY_ADDRESS }}: Docker Registry 域名, e.g., `devstar.cn` +# - ${{ vars.DOCKER_REPOSITORY_ARTIFACT}}: 制品名称, e.g., `devstar/devstar-studio` +# + +name: DevStar Studio CI Pipeline +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build-and-push-x86-64-docker-image: + # Actual runs-on image: docker.io/library/gitea/runner_image:ubuntu-latest + runs-on: ubuntu-latest + steps: + - name: 🔍 Check out repository code + uses: https://devstar.cn/actions/checkout@v4 + with: + ref: dev + - name: 🔧 Test Codes and Build an Artifact + run: | + echo "Prepare to build repository code ${{ gitea.repository }}:${{ gitea.ref }}." + make docker + - name: 🚀 Push Artifact to devstar.cn and docker.io Registry + run: | + docker tag gitea/gitea:latest ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:rootless-dev-${{ gitea.sha }} + docker tag gitea/gitea:latest ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:latest + echo "${{ secrets.DOCKER_REGISTRY_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_REGISTRY_USERNAME }} ${{ vars.DOCKER_REGISTRY_ADDRESS }} --password-stdin + docker push ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:rootless-dev-${{ gitea.sha }} + docker push ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:latest + GITHUB_TOKEN="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"; REPO="mengning/DevStar"; WORKFLOW_FILE="PushDevStarImage2DockerHub.yml"; BRANCH="main"; URL="https://api.github.com/repos/$REPO/actions/workflows/$WORKFLOW_FILE/dispatches"; response=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$URL" -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" -d "{\"ref\":\"$BRANCH\"}"); if [ "$response" -eq 204 ]; then echo "将devstar-studio:latest同步到docker.io的Github工作流触发成功!"; else echo "将devstar-studio:latest同步到docker.io的Github工作流触发失败:HTTP 状态码 $response"; fi + # docker tag devstar-controller-manager:latest ${{ vars.DOCKER_REGISTRY_ADDRESS }}/devstar/devstar-controller-manager:rootless-dev-${{ gitea.sha }} + # docker tag devstar-controller-manager:latest ${{ vars.DOCKER_REGISTRY_ADDRESS }}/devstar/devstar-controller-manager:latest + # echo "${{ secrets.DOCKER_REGISTRY_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_REGISTRY_USERNAME }} ${{ vars.DOCKER_REGISTRY_ADDRESS }} --password-stdin + # docker push ${{ vars.DOCKER_REGISTRY_ADDRESS }}/devstar/devstar-controller-manager:rootless-dev-${{ gitea.sha }} + # docker push ${{ vars.DOCKER_REGISTRY_ADDRESS }}/devstar/devstar-controller-manager:latest + - name: 🍏 Job Status Report + run: | + echo "🍏 This job's status is ${{ job.status }}." + echo "Output Artifact: ${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:rootless-dev-${{ gitea.sha }}" + echo "=> Artifact Tag: latest" + echo "=> Artifact Tag: rootless-dev-${{ gitea.sha }}" + # echo "Output Artifact: ${{ vars.DOCKER_REGISTRY_ADDRESS }}/devstar/devstar-controller-manager:rootless-dev-${{ gitea.sha }}" + # echo "=> Artifact Tag: latest" + # echo "=> Artifact Tag: rootless-dev-${{ gitea.sha }}" + - name: 📝 Update dev.devstar.cn + run: | + curl -LO https://mirrors.ustc.edu.cn/kubernetes/core%3A/stable%3A/v1.28/deb/amd64/kubectl_1.28.0-1.1_amd64.deb + sudo dpkg -i kubectl_1.28.0-1.1_amd64.deb + kubectl config set-cluster remote-cluster --server=${{ secrets.K8S_URL }} --insecure-skip-tls-verify=true + kubectl config set-credentials token-user --token=${{ secrets.K8S_TOKEN }} + kubectl config set-context remote-context --cluster=remote-cluster --user=token-user + kubectl config use-context remote-context + kubectl set image deployment/dev-devstar-studio-gitea gitea=${{ vars.DOCKER_REGISTRY_ADDRESS }}/${{ vars.DOCKER_REPOSITORY_ARTIFACT}}:rootless-dev-${{ gitea.sha }} -n devstar-studio-ns + + +# +# P.S.: +################################################################################ +# 1. How to config runner: +# $ docker run \ +# --name gitea-act-runner-repo-devstar-studio \ +# -d \ +# -e GITEA_INSTANCE_URL=https://www.devstar.cn \ +# -e GITEA_RUNNER_REGISTRATION_TOKEN=${YOUR_GITEA_RUNNER_REGISTRATION_TOKEN} \ +# -v /var/run/docker.sock:/var/run/docker.sock \ +# gitea/act_runner:latest +# +# 2. To clean the docker cache: +# $ docker builder prune --force +# $ if [ "$(docker volume ls -qf dangling=true)" ]; then docker volume rm $(docker volume ls -qf dangling=true); fi +# diff --git a/README.md b/README.md index aa2c6010fa..dbb291e64d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# Gitea +# DevStar -[![](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main)](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain "Release Nightly") +[![](https://github.com/mengning/DevStar/actions/workflows/release-nightly.yml/badge.svg?branch=main)](https://github.com/mengning/DevStar/actions/workflows/release-nightly.yml?query=branch%3Amain "Release Nightly") [![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea") [![](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea "Go Report Card") [![](https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg)](https://pkg.go.dev/code.gitea.io/gitea "GoDoc") -[![](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest "GitHub release") +[![](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/mengning/DevStar/releases/latest "GitHub release") [![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source") [![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea") [![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT") -[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea) +[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/mengning/DevStar) [![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin") [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md) @@ -25,7 +25,7 @@ This project has been [forked](https://blog.gitea.com/welcome-to-gitea/) from [Gogs](https://gogs.io) since November of 2016, but a lot has changed. -For online demonstrations, you can visit [demo.gitea.com](https://demo.gitea.com). +For online demonstrations, you can visit [DevStar.cn](https://DevStar.cn). For accessing free Gitea service (with a limited number of repositories), you can visit [gitea.com](https://gitea.com/user/login). @@ -47,7 +47,7 @@ From the root of the source tree, run: or if SQLite support is required: - TAGS="bindata sqlite sqlite_unlock_notify" make build + TAGS="bindata timetzdata sqlite sqlite_unlock_notify" make build The `build` target is split into two sub-targets: @@ -67,10 +67,72 @@ After building, a binary file named `gitea` will be generated in the root of the > [!NOTE] > If you're interested in using our APIs, we have experimental support with [documentation](https://docs.gitea.com/api). +Start from Container Image: + +``` +make docker +public/assets/install.sh start --image=gitea/gitea:latest + +# 查看日志 +public/assets/install.sh logs +# 停止并删除devstar-studio容器 +public/assets/install.sh clean +# 删除所有容器 +sudo docker stop $(docker ps -aq) && sudo docker rm -f $(docker ps -aq) +``` + ## Contributing Expected workflow is: Fork -> Patch -> Push -> Pull Request +如果您是在Windows环境下,请在cmd命令行下先运行如下命令: + +``` +wsl --install -d Ubuntu-20.04 && wsl --setdefault Ubuntu-20.04 +``` + +在Ubuntu-20.04下完成安装: + +```bash +# download and install go +wget -c https://go.dev/dl/go1.23.3.linux-amd64.tar.gz +sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.3.linux-amd64.tar.gz +export PATH=$PATH:/usr/local/go/bin +go version + +# download and install Node.js +wget -c https://nodejs.org/dist/v22.11.0/node-v22.11.0-linux-x64.tar.xz +sudo tar -xf node-v22.11.0-linux-x64.tar.xz -C /usr/local/ +echo 'export PATH=/usr/local/node-v22.11.0-linux-x64/bin:$PATH' >> ~/.bashrc +source ~/.bashrc +node -v # should print `v22.11.0` +npm -v # should print `10.9.0` +``` + +在DevStar Git仓库创建分支 +``` +git clone https://gitee.com/devstar/devstar.git +git checkout -b YOUR_BRANCH +code devstar + +# in VS Code Terminal +TAGS="timetzdata sqlite sqlite_unlock_notify" make watch # for debuging +make test # testing +TAGS="bindata timetzdata sqlite sqlite_unlock_notify" make build # 生成可执行文件 +./gitea + +# 提交代码 +git add FILES +git commit -m "commit log" +git push +``` + +在DevStar Git仓库发起Pull Request,合并代码后会自动触发CI流水线完成容器镜像的构建并上传到devstar.cn/devstar/devstar-studio:latest + +``` +public/assets/install.sh start +``` + > [!NOTE] > > 1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.** @@ -101,7 +163,7 @@ If you have questions that are not covered by the [documentation](https://docs.g ## Authors - [Maintainers](https://github.com/orgs/go-gitea/people) -- [Contributors](https://github.com/go-gitea/gitea/graphs/contributors) +- [Contributors](https://github.com/mengning/DevStar/graphs/contributors) - [Translators](options/locale/TRANSLATORS) ## Backers @@ -133,16 +195,16 @@ Gitea is pronounced [/ɡɪ’ti:/](https://youtu.be/EM71-2uDAoY) as in "gi-tea" **Why is this not hosted on a Gitea instance?** -We're [working on it](https://github.com/go-gitea/gitea/issues/1029). +We're [working on it](https://github.com/mengning/DevStar/issues/1029). **Where can I find the security patches?** -In the [release log](https://github.com/go-gitea/gitea/releases) or the [change log](https://github.com/go-gitea/gitea/blob/main/CHANGELOG.md), search for the keyword `SECURITY` to find the security patches. +In the [release log](https://github.com/mengning/DevStar/releases) or the [change log](https://github.com/mengning/DevStar/blob/main/CHANGELOG.md), search for the keyword `SECURITY` to find the security patches. ## License This project is licensed under the MIT License. -See the [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) file +See the [LICENSE](https://github.com/mengning/DevStar/blob/main/LICENSE) file for the full license text. ## Further information diff --git a/assets/favicon.svg b/assets/favicon.svg index 9df6b83b56..19ed46028c 100644 --- a/assets/favicon.svg +++ b/assets/favicon.svg @@ -1,31 +1,20 @@ - - - - - - - - - - - + + + + + + + + + + + + diff --git a/assets/logo.svg b/assets/logo.svg index 9df6b83b56..110dc295be 100644 --- a/assets/logo.svg +++ b/assets/logo.svg @@ -1,31 +1,22 @@ - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/models/system/setting.go b/models/system/setting.go index 4472b4c228..d737589e2b 100644 --- a/models/system/setting.go +++ b/models/system/setting.go @@ -99,6 +99,21 @@ func SetSettings(ctx context.Context, settings map[string]string) error { }) } +func SetSetting(ctx context.Context, key, value string) error { + return SetSettings(ctx, map[string]string{key: value}) +} + +func GetSetting(ctx context.Context, key string) (string, error) { + setting, exist, err := db.Get[Setting](ctx, builder.Eq{"setting_key": key}) + if err != nil { + return "", err + } + if !exist { + return "", nil + } + return setting.SettingValue, nil +} + type dbConfigCachedGetter struct { mu sync.RWMutex diff --git a/modules/setting/server.go b/modules/setting/server.go index 38e166e02a..7933e718f7 100644 --- a/modules/setting/server.go +++ b/modules/setting/server.go @@ -120,6 +120,9 @@ var ( AbsoluteAssetURL string ManifestData string + + BeianNumber string // 网站备案号, e.g. 苏ICP备88888888888号-1 + ) // MakeManifestData generates web app manifest JSON @@ -183,11 +186,12 @@ func MakeAbsoluteAssetURL(appURL, staticURLPrefix string) string { func loadServerFrom(rootCfg ConfigProvider) { sec := rootCfg.Section("server") - AppName = rootCfg.Section("").Key("APP_NAME").MustString("Gitea: Git with a cup of tea") - + AppName = rootCfg.Section("").Key("APP_NAME").MustString("DevStar Studio") + Domain = sec.Key("DOMAIN").MustString("localhost") HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") HTTPPort = sec.Key("HTTP_PORT").MustString("3000") + BeianNumber = sec.Key("BEIAN_NUMBER").MustString("") // DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // if these are removed, the warning will not be shown diff --git a/modules/templates/helper.go b/modules/templates/helper.go index e454bce4bd..9c55512ece 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -158,6 +158,9 @@ func NewFuncMap() template.FuncMap { "FilenameIsImage": filenameIsImage, "TabSizeClass": tabSizeClass, + "BeianNumber": func() string { + return setting.BeianNumber + }, } } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ff32c94ff9..bc3107897b 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3411,6 +3411,10 @@ config.session_life_time = Session Life Time config.https_only = HTTPS Only config.cookie_life_time = Cookie Life Time +config.app_logo_config = Application Logo Configuration +config.choose_new_logo = Choose New Logo +config.update_logo = Update Logo + config.picture_config = Picture and Avatar Configuration config.picture_service = Picture Service config.disable_gravatar = Disable Gravatar diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 0be185cd4f..2289c9cf48 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -3400,6 +3400,10 @@ config.session_life_time=Session 生命周期 config.https_only=仅限 HTTPS config.cookie_life_time=Cookie 生命周期 +config.app_logo_config = Logo图标设置 +config.choose_new_logo = 选择新的Logo图标 +config.update_logo = 更新Logo图标 + config.picture_config=图片和头像配置 config.picture_service=图片服务 config.disable_gravatar=禁用 Gravatar 头像 diff --git a/public/assets/img/apple-touch-icon.png b/public/assets/img/apple-touch-icon.png index 0c803d35dc..6366d395c7 100644 Binary files a/public/assets/img/apple-touch-icon.png and b/public/assets/img/apple-touch-icon.png differ diff --git a/public/assets/img/avatar_default.png b/public/assets/img/avatar_default.png index 129967112d..f65c024163 100644 Binary files a/public/assets/img/avatar_default.png and b/public/assets/img/avatar_default.png differ diff --git a/public/assets/img/favicon.png b/public/assets/img/favicon.png index dcd4edb1a3..f65c024163 100644 Binary files a/public/assets/img/favicon.png and b/public/assets/img/favicon.png differ diff --git a/public/assets/img/favicon.svg b/public/assets/img/favicon.svg index 43291345df..19ed46028c 100644 --- a/public/assets/img/favicon.svg +++ b/public/assets/img/favicon.svg @@ -1 +1,20 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/public/assets/img/logo.png b/public/assets/img/logo.png index c7971f9183..f98894ce8f 100644 Binary files a/public/assets/img/logo.png and b/public/assets/img/logo.png differ diff --git a/public/assets/img/logo.svg b/public/assets/img/logo.svg index 43291345df..110dc295be 100644 --- a/public/assets/img/logo.svg +++ b/public/assets/img/logo.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + + + + + diff --git a/public/assets/install.sh b/public/assets/install.sh new file mode 100755 index 0000000000..252f7904c3 --- /dev/null +++ b/public/assets/install.sh @@ -0,0 +1,230 @@ +#!/bin/bash +# Copyright 2024 Mengning Software All rights reserved. + +# 默认值 +NAME=DevStar-Studio +IMAGE_REGISTRY_USER=mengning997 +IMAGE_NAME=devstar-studio +VERSION=latest # DevStar Studio的默认版本为最新版本 +PORT=80 # 设置端口默认值为 80 +SSH_PORT=2222 # 设置ssh默认端口号2222 +DATA_DIR=${HOME}/devstar_data +APP_INI=${DATA_DIR}/app.ini + +# 错误处理函数 +error_handler() { + devstar help + exit 1 +} + +# 捕获错误信号 +trap 'error_handler' ERR + +# Exit immediately if a command exits with a non-zero status +set -e + +# Colors for output +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Function to display success message +function success { + echo -e "${GREEN}$1${NC}" +} + +# Function to display failure message +function failure { + echo -e "${RED}$1${NC}" +} + +# Detect the OS type and install dependencies +function install_dependencies { + # Install dependencies based on the OS type + success "dependencies install begin: " + OS_ID=$(grep '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"') + + case $OS_ID in + ubuntu|debian) + # 检查 Docker 是否已安装 + if ! command -v docker &> /dev/null + then + echo "Installing Docker..." + # 更新包索引 + sudo apt-get update + # 安装 Docker + sudo apt-get install -y docker.io + echo "Docker Installed!" + else + echo "Docker Installed, $(docker --version)" + fi + ;; + centos) + # sudo yum update -y + # sudo yum install -y epel-release + # sudo yum groupinstall -y "Development Tools" + # sudo yum install -y yaml-cpp yaml-cpp-devel + ;; + fedora) + # sudo dnf update -y + # sudo dnf group install -y "Development Tools" + # sudo dnf install -y yaml-cpp yaml-cpp-devel + ;; + *) + failure "Unsupported OS: $OS_ID" + exit 1 + ;; + esac +} + +# Function to install +function install { + install_dependencies + if sudo docker pull mengning997/$IMAGE_NAME:$VERSION; then + success "Successfully pulled mengning997/$IMAGE_NAME:$VERSION" + else + sudo docker pull devstar.cn/devstar/$IMAGE_NAME:$VERSION + IMAGE_REGISTRY_USER=devstar.cn/devstar + fi +} + +# Function to start +function start { + if [[ -z "$IMAGE_STR" ]]; then + install + fi + # 创建devstar_data目录用于持久化存储DevStar相关的配置和用户数据 + mkdir -p $DATA_DIR + sudo chown 1000:1000 $DATA_DIR + sudo chmod 666 /var/run/docker.sock + if [ ! -f "$APP_INI" ]; then + DOMAIN_NAME=$(hostname -I | awk '{print $1}') + echo "DOMAIN_NAME=$DOMAIN_NAME" + else + # 读取 DOMAIN 值 + DOMAIN_NAME=$(grep -E '^\s*DOMAIN\s*=' "$APP_INI" | cut -d'=' -f2 | xargs) + # 检查是否成功读取到值 + if [[ -z "$DOMAIN_NAME" ]]; then + DOMAIN_NAME="localhost" + fi + echo "DOMAIN_NAME=$DOMAIN_NAME" + fi + # 启动devstar-studio容器 + stop + if [[ -z "$IMAGE_STR" ]]; then + IMAGE_STR="$IMAGE_REGISTRY_USER/$IMAGE_NAME:$VERSION" + fi + echo "image=$IMAGE_STR" + sudo docker run --restart=always --name $NAME -d -p $PORT:3000 -p $SSH_PORT:$SSH_PORT -v /var/run/docker.sock:/var/run/docker.sock -v ~/devstar_data:/var/lib/gitea -v ~/devstar_data:/etc/gitea $IMAGE_STR + # 打开 `http://localhost:8080` 完成安装。 + success "-------------------------------------------------------" + success "DevStar started in http://$DOMAIN_NAME:$PORT successfully!" + success "-------------------------------------------------------" + exit 0 +} + +# Function to stop +function stop { + if [ $(docker ps -a --filter "name=^/${NAME}$" -q | wc -l) -gt 0 ]; then + sudo docker stop $NAME && sudo docker rm -f $NAME + fi + if [ $(docker ps -a --filter "name=^/devstar-studio$" -q | wc -l) -gt 0 ]; then + sudo docker stop devstar-studio && sudo docker rm -f devstar-studio + fi +} + +# Function to logs +function logs { + # 查看devstar-studio容器的运行日志 + sudo docker logs $NAME +} + +# Function to clean +function clean { + stop + rm -rf $DATA_DIR +} + +# Function to usage help +function usage { + success "------------------------------------------------------------------------" + success "DevStar usage help:" + success " help, -h, --help, Help information" + success " start Start DevStar Studio" + success " --port= Specify the port number (default port is 80)" + success " --ssh-port= Specify the ssh-port number (default ssh-port is 2222)" + success " --version= Specify the DevStar Studio Image Version (default verson is latest)" + success " --image= Specify the DevStar Studio Image example: devstar-studio:latest " + success " stop Stop the running DevStar Studio" + success " logs View the logs of the devstar-studio container" + failure " clean Clean up the running DevStar Studio, including deleting user data. Please use with caution." + success "------------------------------------------------------------------------" + exit 0 +} + +# Main script +case "$1" in + -h|--help|help) + usage + ;; + start) + ARGS=$(getopt --long port::,ssh-port::,version::,image:: -- "$@") + if [ $? -ne 0 ]; then + failure "ARGS ERROR!" + exit 1 + fi + eval set -- "${ARGS}" + # 处理选项 + while true; do + case "$1" in + --port) + PORT="$2" + echo "The Port is: $PORT" + shift 2 ;; + --ssh-port) + SSH_PORT="$2" + echo "The SSH_Port is: $SSH_PORT" + shift 2 ;; + --version) + VERSION="$2" + echo "The DevStar Studio Image Version is: $VERSION" + shift 2 ;; + --image) + IMAGE_STR="$2" + echo "The DevStar Studio Image: $IMAGE_STR" + shift 2 ;; + --) + shift + break ;; + *) + failure "Unrecognized option: $1" + exit 1 ;; + esac + done + start + ;; + stop) + stop + ;; + logs) + logs + ;; + clean) + clean + ;; + *) + # 获取当前脚本的文件名 + script_name=$(basename "$0") + # 判断脚本名是否为 devstar + if [ "$script_name" != "devstar" ]; then + sudo mv ./install.sh /usr/bin/devstar + rm -rf install.sh + success "--------------------------------------" + success "DevStar Studio installed successfully!" + success "--------------------------------------" + success "Copyright 2024 Mengning Software All rights reserved." + devstar help + fi + ;; +esac + diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index 0e5b23db6d..3a78f052dc 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -9,7 +9,12 @@ import ( "net/url" "strconv" "strings" - + "io" + "os" + "path/filepath" + "time" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" @@ -253,3 +258,47 @@ func ChangeConfig(ctx *context.Context) { config.GetDynGetter().InvalidateCache() ctx.JSONOK() } + +func LogoPost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.AvatarForm) + if form.Avatar == nil || form.Avatar.Filename == "" { + ctx.Flash.Error("No file uploaded") + ctx.Redirect(setting.AppSubURL + "/-/admin/config/settings") + return + } + + ext := filepath.Ext(form.Avatar.Filename) + if ext != ".png" && ext != ".jpg" && ext != ".jpeg" && ext != ".gif" && ext != ".webp" { + ctx.Flash.Error("Invalid file type") + ctx.Redirect(setting.AppSubURL + "/-/admin/config/settings") + return + } + + // 生成唯一文件名 + filename := "logo_" + strconv.FormatInt(time.Now().Unix(), 10) + ext + savePath := filepath.Join(setting.CustomPath, "public", "assets", "img", filename) + os.MkdirAll(filepath.Dir(savePath), os.ModePerm) + out, err := os.Create(savePath) + if err != nil { + ctx.Flash.Error("Failed to save file") + ctx.Redirect(setting.AppSubURL + "/-/admin/config/settings") + return + } + defer out.Close() + fr, _ := form.Avatar.Open() + defer fr.Close() + io.Copy(out, fr) + + // 保存路径到数据库 + relPath := "/assets/img/" + filename + err = system_model.SetSetting(ctx, "custom_logo_path", relPath) + if err != nil { + ctx.Flash.Error("Failed to update database") + ctx.Redirect(setting.AppSubURL + "/-/admin/config/settings") + return + } + + ctx.Flash.Success("Logo updated successfully") + ctx.Redirect(setting.AppSubURL + "/-/admin/config/settings") +} + diff --git a/routers/web/web.go b/routers/web/web.go index b9c7013f63..bfafb75184 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -726,6 +726,7 @@ func registerWebRoutes(m *web.Router) { m.Post("/test_mail", admin.SendTestMail) m.Post("/test_cache", admin.TestCache) m.Get("/settings", admin.ConfigSettings) + m.Post("/logo", web.Bind(forms.AvatarForm{}), admin.LogoPost) }) m.Group("/monitor", func() { diff --git a/services/context/context.go b/services/context/context.go index 32ec260aab..e843e1c6d3 100644 --- a/services/context/context.go +++ b/services/context/context.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" + system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/session" @@ -207,6 +208,12 @@ func Contexter() func(next http.Handler) http.Handler { ctx.Data["ManifestData"] = setting.ManifestData ctx.Data["AllLangs"] = translation.AllLangs() + if logoPath, _ := system_model.GetSetting(ctx, "custom_logo_path"); logoPath != "" { + ctx.Data["CustomLogoPath"] = logoPath + } else { + ctx.Data["CustomLogoPath"] = "" + } + next.ServeHTTP(ctx.Resp, ctx.Req) }) } diff --git a/templates/admin/config_settings.tmpl b/templates/admin/config_settings.tmpl index 6b9bb8275c..2dadd0d265 100644 --- a/templates/admin/config_settings.tmpl +++ b/templates/admin/config_settings.tmpl @@ -1,4 +1,36 @@ {{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin config")}} + +

+ {{ctx.Locale.Tr "admin.config.app_logo_config"}} +

+
+
+ {{.CsrfTokenHtml}} +
+ + +
+ +
+ +
+
+
+

{{ctx.Locale.Tr "admin.config.picture_config"}}

diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl index 60eb2fe1f8..4cd87bdb05 100644 --- a/templates/base/footer_content.tmpl +++ b/templates/base/footer_content.tmpl @@ -1,7 +1,7 @@