From bbd1983c4747518d8e1ac44478569d639af9710b Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Fri, 3 Nov 2023 15:09:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0openlitespeed=E3=80=81ca?= =?UTF-8?q?libre-web=E7=AD=89=E5=8D=81=E5=87=A0=E4=B8=AA=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=88=B0=E5=88=97=E8=A1=A8=20(#340)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- answer/1.1.1/data.yml | 10 + answer/1.1.1/docker-compose.yml | 18 + answer/README.md | 39 ++ answer/data.yml | 20 + answer/logo.png | Bin 0 -> 3419 bytes audiobookshelf/2.3.3/data.yml | 38 + audiobookshelf/2.3.3/docker-compose.yml | 21 + audiobookshelf/README.md | 308 ++++++++ audiobookshelf/data.yml | 20 + audiobookshelf/logo.png | Bin 0 -> 16254 bytes calibre-web/0.6.20/data.yml | 24 + calibre-web/0.6.20/docker-compose.yml | 25 + calibre-web/README.md | 133 ++++ calibre-web/data.yml | 20 + calibre-web/logo.png | Bin 0 -> 8719 bytes changedetectionio/0.44/data.yml | 10 + changedetectionio/0.44/docker-compose.yml | 18 + changedetectionio/README.md | 260 +++++++ changedetectionio/data.yml | 20 + changedetectionio/logo.png | Bin 0 -> 22507 bytes focalboard/7.11.2/data.yml | 10 + focalboard/7.11.2/data/config.json | 16 + focalboard/7.11.2/data/postgres-config.json | 17 + focalboard/7.11.2/docker-compose.yml | 23 + focalboard/README.md | 149 ++++ focalboard/data.yml | 20 + focalboard/logo.png | Bin 0 -> 4069 bytes heimdall/2.5.6/data.yml | 18 + heimdall/2.5.6/docker-compose.yml | 23 + heimdall/README.md | 219 ++++++ heimdall/data.yml | 20 + heimdall/logo.png | Bin 0 -> 15799 bytes hertzbeat/1.4.0/data.yml | 10 + hertzbeat/1.4.0/docker-compose.yml | 22 + hertzbeat/README.md | 390 +++++++++++ hertzbeat/data.yml | 20 + hertzbeat/logo.png | Bin 0 -> 12501 bytes it-tools/2023.5.14-77f2efc/data.yml | 10 + it-tools/2023.5.14-77f2efc/docker-compose.yml | 16 + it-tools/README.md | 120 ++++ it-tools/data.yml | 20 + it-tools/logo.png | Bin 0 -> 5551 bytes kodbox/1.4104/data.yml | 10 + kodbox/1.4104/docker-compose.yml | 18 + navidrome/README.md | 93 +++ navidrome/data.yml | 20 + navidrome/logo.png | Bin 0 -> 17522 bytes navidrome/pr-2295/data.yml | 17 + navidrome/pr-2295/docker-compose.yml | 25 + next-terminal/1.3.9/data.yml | 32 + next-terminal/1.3.9/docker-compose.yml | 37 + next-terminal/1.3.9/ssh/id_rsa | 49 ++ next-terminal/README.md | 73 ++ next-terminal/data.yml | 20 + next-terminal/logo.png | Bin 0 -> 5592 bytes onedev/8.6.12/data.yml | 18 + onedev/8.6.12/docker-compose.yml | 20 + onedev/README.md | 140 ++++ onedev/data.yml | 20 + onedev/logo.png | Bin 0 -> 5285 bytes openlitespeed/1.7.18-lsphp74/data.yml | 33 + .../data/bin/container/appinstallctl.sh | 660 ++++++++++++++++++ .../data/bin/container/certhookctl.sh | 18 + .../data/bin/container/domainctl.sh | 160 +++++ .../data/bin/container/owaspctl.sh | 236 +++++++ .../data/bin/container/serialctl.sh | 84 +++ .../1.7.18-lsphp74/data/sites/.gitignore | 2 + .../1.7.18-lsphp74/docker-compose.yml | 30 + openlitespeed/1.7.18-lsphp81/data.yml | 33 + .../data/bin/container/appinstallctl.sh | 660 ++++++++++++++++++ .../data/bin/container/certhookctl.sh | 18 + .../data/bin/container/domainctl.sh | 160 +++++ .../data/bin/container/owaspctl.sh | 236 +++++++ .../data/bin/container/serialctl.sh | 84 +++ .../1.7.18-lsphp81/data/sites/.gitignore | 2 + .../1.7.18-lsphp81/docker-compose.yml | 30 + openlitespeed/README.md | 43 ++ openlitespeed/data.yml | 20 + openlitespeed/logo.png | Bin 0 -> 7056 bytes pingvin-share/0.17.4/data.yml | 10 + pingvin-share/0.17.4/docker-compose.yml | 19 + pingvin-share/README.md | 126 ++++ pingvin-share/data.yml | 20 + pingvin-share/logo.png | Bin 0 -> 8522 bytes searxng/2023.7.1-5720844f/data.yml | 17 + searxng/2023.7.1-5720844f/docker-compose.yml | 20 + searxng/README.md | 82 +++ searxng/data.yml | 20 + searxng/logo.png | Bin 0 -> 4532 bytes vocechat/0.3.36/data.yml | 10 + vocechat/0.3.36/docker-compose.yml | 18 + vocechat/README.md | 77 ++ vocechat/data.yml | 20 + vocechat/logo.png | Bin 0 -> 22787 bytes yesplaymusic/0.4.7/data.yml | 10 + yesplaymusic/0.4.7/docker-compose.yml | 16 + yesplaymusic/README.md | 260 +++++++ yesplaymusic/data.yml | 20 + yesplaymusic/logo.png | Bin 0 -> 23731 bytes yourls/1.9.2/data.yml | 87 +++ yourls/1.9.2/docker-compose.yml | 27 + yourls/README.md | 116 +++ yourls/data.yml | 20 + yourls/logo.png | Bin 0 -> 5534 bytes 104 files changed, 6203 insertions(+) create mode 100644 answer/1.1.1/data.yml create mode 100644 answer/1.1.1/docker-compose.yml create mode 100644 answer/README.md create mode 100644 answer/data.yml create mode 100644 answer/logo.png create mode 100644 audiobookshelf/2.3.3/data.yml create mode 100644 audiobookshelf/2.3.3/docker-compose.yml create mode 100644 audiobookshelf/README.md create mode 100644 audiobookshelf/data.yml create mode 100644 audiobookshelf/logo.png create mode 100644 calibre-web/0.6.20/data.yml create mode 100644 calibre-web/0.6.20/docker-compose.yml create mode 100644 calibre-web/README.md create mode 100644 calibre-web/data.yml create mode 100644 calibre-web/logo.png create mode 100644 changedetectionio/0.44/data.yml create mode 100644 changedetectionio/0.44/docker-compose.yml create mode 100644 changedetectionio/README.md create mode 100644 changedetectionio/data.yml create mode 100644 changedetectionio/logo.png create mode 100644 focalboard/7.11.2/data.yml create mode 100644 focalboard/7.11.2/data/config.json create mode 100644 focalboard/7.11.2/data/postgres-config.json create mode 100644 focalboard/7.11.2/docker-compose.yml create mode 100644 focalboard/README.md create mode 100644 focalboard/data.yml create mode 100644 focalboard/logo.png create mode 100644 heimdall/2.5.6/data.yml create mode 100644 heimdall/2.5.6/docker-compose.yml create mode 100644 heimdall/README.md create mode 100644 heimdall/data.yml create mode 100644 heimdall/logo.png create mode 100644 hertzbeat/1.4.0/data.yml create mode 100644 hertzbeat/1.4.0/docker-compose.yml create mode 100644 hertzbeat/README.md create mode 100644 hertzbeat/data.yml create mode 100644 hertzbeat/logo.png create mode 100644 it-tools/2023.5.14-77f2efc/data.yml create mode 100644 it-tools/2023.5.14-77f2efc/docker-compose.yml create mode 100644 it-tools/README.md create mode 100644 it-tools/data.yml create mode 100644 it-tools/logo.png create mode 100755 kodbox/1.4104/data.yml create mode 100644 kodbox/1.4104/docker-compose.yml create mode 100644 navidrome/README.md create mode 100644 navidrome/data.yml create mode 100644 navidrome/logo.png create mode 100644 navidrome/pr-2295/data.yml create mode 100644 navidrome/pr-2295/docker-compose.yml create mode 100644 next-terminal/1.3.9/data.yml create mode 100644 next-terminal/1.3.9/docker-compose.yml create mode 100644 next-terminal/1.3.9/ssh/id_rsa create mode 100644 next-terminal/README.md create mode 100644 next-terminal/data.yml create mode 100644 next-terminal/logo.png create mode 100644 onedev/8.6.12/data.yml create mode 100644 onedev/8.6.12/docker-compose.yml create mode 100644 onedev/README.md create mode 100644 onedev/data.yml create mode 100644 onedev/logo.png create mode 100644 openlitespeed/1.7.18-lsphp74/data.yml create mode 100644 openlitespeed/1.7.18-lsphp74/data/bin/container/appinstallctl.sh create mode 100644 openlitespeed/1.7.18-lsphp74/data/bin/container/certhookctl.sh create mode 100644 openlitespeed/1.7.18-lsphp74/data/bin/container/domainctl.sh create mode 100644 openlitespeed/1.7.18-lsphp74/data/bin/container/owaspctl.sh create mode 100644 openlitespeed/1.7.18-lsphp74/data/bin/container/serialctl.sh create mode 100644 openlitespeed/1.7.18-lsphp74/data/sites/.gitignore create mode 100644 openlitespeed/1.7.18-lsphp74/docker-compose.yml create mode 100644 openlitespeed/1.7.18-lsphp81/data.yml create mode 100644 openlitespeed/1.7.18-lsphp81/data/bin/container/appinstallctl.sh create mode 100644 openlitespeed/1.7.18-lsphp81/data/bin/container/certhookctl.sh create mode 100644 openlitespeed/1.7.18-lsphp81/data/bin/container/domainctl.sh create mode 100644 openlitespeed/1.7.18-lsphp81/data/bin/container/owaspctl.sh create mode 100644 openlitespeed/1.7.18-lsphp81/data/bin/container/serialctl.sh create mode 100644 openlitespeed/1.7.18-lsphp81/data/sites/.gitignore create mode 100644 openlitespeed/1.7.18-lsphp81/docker-compose.yml create mode 100644 openlitespeed/README.md create mode 100644 openlitespeed/data.yml create mode 100644 openlitespeed/logo.png create mode 100644 pingvin-share/0.17.4/data.yml create mode 100644 pingvin-share/0.17.4/docker-compose.yml create mode 100644 pingvin-share/README.md create mode 100644 pingvin-share/data.yml create mode 100644 pingvin-share/logo.png create mode 100644 searxng/2023.7.1-5720844f/data.yml create mode 100644 searxng/2023.7.1-5720844f/docker-compose.yml create mode 100644 searxng/README.md create mode 100644 searxng/data.yml create mode 100644 searxng/logo.png create mode 100644 vocechat/0.3.36/data.yml create mode 100644 vocechat/0.3.36/docker-compose.yml create mode 100644 vocechat/README.md create mode 100644 vocechat/data.yml create mode 100644 vocechat/logo.png create mode 100644 yesplaymusic/0.4.7/data.yml create mode 100644 yesplaymusic/0.4.7/docker-compose.yml create mode 100644 yesplaymusic/README.md create mode 100644 yesplaymusic/data.yml create mode 100644 yesplaymusic/logo.png create mode 100644 yourls/1.9.2/data.yml create mode 100644 yourls/1.9.2/docker-compose.yml create mode 100644 yourls/README.md create mode 100644 yourls/data.yml create mode 100644 yourls/logo.png diff --git a/answer/1.1.1/data.yml b/answer/1.1.1/data.yml new file mode 100644 index 000000000..93818f863 --- /dev/null +++ b/answer/1.1.1/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40065 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/answer/1.1.1/docker-compose.yml b/answer/1.1.1/docker-compose.yml new file mode 100644 index 000000000..e17d0e499 --- /dev/null +++ b/answer/1.1.1/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + answer: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:80" + volumes: + - "./data:/data" + image: answerdev/answer:1.1.1 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/answer/README.md b/answer/README.md new file mode 100644 index 000000000..8fdafe948 --- /dev/null +++ b/answer/README.md @@ -0,0 +1,39 @@ + + logo + + +# Answer - 构建问答社区 + +一款问答形式的知识社区开源软件,你可以使用它快速建立你的问答社区,用于产品技术支持、客户支持、用户交流等。 + +了解更多关于该项目的内容,请访问 [answer.dev](https://answer.dev). + +[![LICENSE](https://img.shields.io/github/license/answerdev/answer)](https://github.com/answerdev/answer/blob/main/LICENSE) +[![Language](https://img.shields.io/badge/language-go-blue.svg)](https://golang.org/) +[![Language](https://img.shields.io/badge/language-react-blue.svg)](https://reactjs.org/) +[![Go Report Card](https://goreportcard.com/badge/github.com/answerdev/answer)](https://goreportcard.com/report/github.com/answerdev/answer) +[![Discord](https://img.shields.io/badge/discord-chat-5865f2?logo=discord&logoColor=f5f5f5)](https://discord.gg/Jm7Y4cbUej) + +## 截图 + +![screenshot](https://github.com/answerdev/answer/raw/main/docs/img/screenshot.png) + +## 快速开始 + +### 使用 docker 快速搭建 + +```bash +docker run -d -p 9080:80 -v answer-data:/data --name answer answerdev/answer:latest +``` + +其他安装配置细节请参考 [Installation](https://answer.dev/docs/installation) + +## 贡献 + +我们随时欢迎你的贡献! + +参考 [CONTRIBUTING](https://answer.dev/docs/development/contributing/) 开始贡献。 + +## License + +[Apache License 2.0](https://github.com/answerdev/answer/blob/main/LICENSE) \ No newline at end of file diff --git a/answer/data.yml b/answer/data.yml new file mode 100644 index 000000000..6c4df6e16 --- /dev/null +++ b/answer/data.yml @@ -0,0 +1,20 @@ +name: Answer +tags: + - 建站 +title: 一款适合任何团队的问答平台软件 +type: 建站 +description: 一款适合任何团队的问答平台软件 +additionalProperties: + key: answer + name: Answer + tags: + - WebSite + shortDescZh: 一款适合任何团队的问答平台软件 + shortDescEn: A Q&A platform software for teams at any scales + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://answer.dev/ + github: https://github.com/answerdev/answer + document: https://answer.dev/zh-CN/docs diff --git a/answer/logo.png b/answer/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..444ad16b8b04c871c2e806ce2954e63b11f6311b GIT binary patch literal 3419 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 h_KPb*Me*jj{SjYeX literal 0 HcmV?d00001 diff --git a/audiobookshelf/2.3.3/data.yml b/audiobookshelf/2.3.3/data.yml new file mode 100644 index 000000000..18535d14b --- /dev/null +++ b/audiobookshelf/2.3.3/data.yml @@ -0,0 +1,38 @@ +additionalProperties: + formFields: + - default: 40096 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: ./data/config + edit: true + envKey: DATA_PATH + labelEn: Data folder path + labelZh: 数据文件夹路径 + required: true + type: text + - default: ./data/audiobooks + edit: true + envKey: DATA_PATH1 + labelEn: audiobooks folder path + labelZh: audiobooks 文件夹路径 + required: true + type: text + - default: ./data/podcasts + edit: true + envKey: DATA_PATH2 + labelEn: podcasts folder path + labelZh: podcasts 文件夹路径 + required: true + type: text + - default: ./data/metadata + edit: true + envKey: DATA_PATH3 + labelEn: metadata folder path + labelZh: metadata 文件夹路径 + required: true + type: text diff --git a/audiobookshelf/2.3.3/docker-compose.yml b/audiobookshelf/2.3.3/docker-compose.yml new file mode 100644 index 000000000..347c2408a --- /dev/null +++ b/audiobookshelf/2.3.3/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' +services: + audiobookshelf: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:80" + volumes: + - "${DATA_PATH1}:/audiobooks" + - "${DATA_PATH2}:/podcasts" + - "${DATA_PATH}:/config" + - "${DATA_PATH3}:/metadata" + image: advplyr/audiobookshelf:2.3.3 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/audiobookshelf/README.md b/audiobookshelf/README.md new file mode 100644 index 000000000..87fdfec72 --- /dev/null +++ b/audiobookshelf/README.md @@ -0,0 +1,308 @@ +
+
+ Audiobookshelf Banner + +

+
+ Documentation + · + User Guides + · + Support +

+
+ +# About + +Audiobookshelf is a self-hosted audiobook and podcast server. + +### Features + +* Fully **open-source**, including the [android & iOS app](https://github.com/advplyr/audiobookshelf-app) *(in beta)* +* Stream all audio formats on the fly +* Search and add podcasts to download episodes w/ auto-download +* Multi-user support w/ custom permissions +* Keeps progress per user and syncs across devices +* Auto-detects library updates, no need to re-scan +* Upload books and podcasts w/ bulk upload drag and drop folders +* Backup your metadata + automated daily backups +* Progressive Web App (PWA) +* Chromecast support on the web app and android app +* Fetch metadata and cover art from several sources +* Chapter editor and chapter lookup (using [Audnexus API](https://audnex.us/)) +* Merge your audio files into a single m4b +* Embed metadata and cover image into your audio files (using [Tone](https://github.com/sandreas/tone)) +* Basic ebook support and ereader + * Epub, pdf, cbr, cbz + * Send ebook to device (i.e. Kindle) +* Open RSS feeds for podcasts and audiobooks + +Is there a feature you are looking for? [Suggest it](https://github.com/advplyr/audiobookshelf/issues/new/choose) + +Join us on [Discord](https://discord.gg/pJsjuNCKRq) or [Matrix](https://matrix.to/#/#audiobookshelf:matrix.org) + +### Android App (beta) +Try it out on the [Google Play Store](https://play.google.com/store/apps/details?id=com.audiobookshelf.app) + +### iOS App (beta) +Available using Test Flight: https://testflight.apple.com/join/wiic7QIW - [Join the discussion](https://github.com/advplyr/audiobookshelf-app/discussions/60) + +### Build your own tools & clients +Check out the [API documentation](https://api.audiobookshelf.org/) + +
+ +Library Screenshot + +
+ +# Organizing your audiobooks + +#### Directory structure and folder names are important to Audiobookshelf! + + See [documentation](https://audiobookshelf.org/docs#book-directory-structure) for supported directory structure, folder naming conventions, and audio file metadata usage. + +
+ +# Installation + +See [install docs](https://www.audiobookshelf.org/docs) + +
+ +# Reverse Proxy Set Up + +#### Important! Audiobookshelf requires a websocket connection. + +#### Note: Subfolder paths (e.g. /audiobooks) are not supported yet. See [issue](https://github.com/advplyr/audiobookshelf/issues/385) + +### NGINX Proxy Manager + +Toggle websockets support. + +NGINX Web socket + +### NGINX Reverse Proxy + +Add this to the site config file on your nginx server after you have changed the relevant parts in the <> brackets, and inserted your certificate paths. + + +```bash +server +{ + listen 443 ssl; + server_name ..; + + access_log /var/log/nginx/audiobookshelf.access.log; + error_log /var/log/nginx/audiobookshelf.error.log; + + ssl_certificate /path/to/certificate; + ssl_certificate_key /path/to/key; + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_http_version 1.1; + + proxy_pass http://; + proxy_redirect http:// https://; + } +} +``` + +### Apache Reverse Proxy + +Add this to the site config file on your Apache server after you have changed the relevant parts in the <> brackets, and inserted your certificate paths. + +For this to work you must enable at least the following mods using `a2enmod`: + - `ssl` + - `proxy` + - `proxy_http` + - `proxy_balancer` + - `proxy_wstunnel` + - `rewrite` + +```bash + + + ServerName .. + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + ProxyPreserveHost On + ProxyPass / http://localhost:/ + RewriteEngine on + RewriteCond %{HTTP:Upgrade} websocket [NC] + RewriteCond %{HTTP:Connection} upgrade [NC] + RewriteRule ^/?(.*) "ws://localhost:/$1" [P,L] + + # unless you're doing something special this should be generated by a + # tool like certbot by let's encrypt + SSLCertificateFile /path/to/cert/file + SSLCertificateKeyFile /path/to/key/file + + +``` + +Some SSL certificates like those signed by Let's Encrypt require ACME validation. To allow Let's Encrypt to write and confirm +the ACME challenge, edit your VirtualHost definition to prevent proxying traffic that queries `/.well-known` and instead +serve that directly: +```bash + + # ... + + # create the directory structure /.well-known/acme-challenges + # within DocumentRoot and give the HTTP user recursive write + # access to it. + DocumentRoot /path/to/local/directory + + ProxyPreserveHost On + ProxyPass /.well-known ! + ProxyPass / http://localhost:/ + + # ... + +``` + + +### SWAG Reverse Proxy + +[See LinuxServer.io config sample](https://github.com/linuxserver/reverse-proxy-confs/blob/master/audiobookshelf.subdomain.conf.sample) + +### Synology Reverse Proxy + +1. Open Control Panel > Application Portal +2. Change to the Reverse Proxy tab +3. Select the proxy rule for which you want to enable Websockets and click on Edit +4. Change to the "Custom Header" tab +5. Click Create > WebSocket +6. Click Save + +[from @silentArtifact](https://github.com/advplyr/audiobookshelf/issues/241#issuecomment-1036732329) + +### [Traefik Reverse Proxy](https://doc.traefik.io/traefik/) + +Middleware relating to CORS will cause the app to report Unknown Error when logging in. To prevent this don't apply any of the following headers to the router for this site: + +
    +
  • accessControlAllowMethods
  • +
  • accessControlAllowOriginList
  • +
  • accessControlMaxAge
  • +
+ +From [@Dondochaka](https://discord.com/channels/942908292873723984/942914154254176257/945074590374318170) and [@BeastleeUK](https://discord.com/channels/942908292873723984/942914154254176257/970366039294611506) +
+ +### Example Caddyfile - [Caddy Reverse Proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy) + +``` +subdomain.domain.com { + encode gzip zstd + reverse_proxy : +} +``` + + +# Run from source + +# Contributing + +This application is built using [NodeJs](https://nodejs.org/). + +### Dev Container Setup +The easiest way to begin developing this project is to use a dev container. An introduction to dev containers in VSCode can be found [here](https://code.visualstudio.com/docs/devcontainers/containers). + +Required Software: +* [Docker Desktop](https://www.docker.com/products/docker-desktop/) +* [VSCode](https://code.visualstudio.com/download) + +*Note, it is possible to use other container software than Docker and IDEs other than VSCode. However, this setup is more complicated and not covered here.* + +
+
+Install the required software on Windows with winget + +

+Note: This requires a PowerShell prompt with winget installed. You should be able to copy and paste the code block to install. If you use an elevated PowerShell prompt, UAC will not pop up during the installs. + +```PowerShell +winget install -e --id Docker.DockerDesktop; ` +winget install -e --id Microsoft.VisualStudioCode +``` + +

+
+
+ +
+
+Install the required software on MacOS with homebrew + +

+ +```sh +brew install --cask docker visual-studio-code +``` + +

+
+
+ +
+
+Install the required software on Linux with snap + +

+ +```sh +sudo snap install docker; \ +sudo snap install code --classic +``` + +

+
+
+ +After installing these packages, you can now install the [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension for VSCode. After installing this extension open the command pallet (`ctrl+shift+p` or `cmd+shift+p`) and select the command `>Dev Containers: Rebuild and Reopen in Container`. This will cause the development environment container to be built and launched. + +You are now ready to start development! + +### Manual Environment Setup + +If you don't want to use the dev container, you can still develop this project. First, you will need to install [NodeJs](https://nodejs.org/) (version 16) and [FFmpeg](https://ffmpeg.org/). + +Next you will need to create a `dev.js` file in the project's root directory. This contains configuration information and paths unique to your development environment. You can find an example of this file in `.devcontainer/dev.js`. + +You are now ready to build the client: + +```sh +npm ci +cd client +npm ci +npm run generate +cd .. +``` + +### Development Commands + +After setting up your development environment, either using the dev container or using your own custom environment, the following commands will help you run the server and client. + +To run the server, you can use the command `npm run dev`. This will use the client that was built when you ran `npm run generate` in the client directory or when you started the dev container. If you make changes to the server, you will need to restart the server. If you make changes to the client, you will need to run the command `(cd client; npm run generate)` and then restart the server. By default the client runs at `localhost:3333`, though the port can be configured in `dev.js`. + +You can also build a version of the client that supports live reloading. To do this, start the server, then run the command `(cd client; npm run dev)`. This will run a separate instance of the client at `localhost:3000` that will be automatically updated as you make changes to the client. + +If you are using VSCode, this project includes a couple of pre-defined targets to speed up this process. First, if you build the project (`ctrl+shift+b` or `cmd+shift+b`) it will automatically generate the client. Next, there are debug commands for running the server and client. You can view these targets using the debug panel (bring it up with (`ctrl+shift+d` or `cmd+shift+d`): + +* `Debug server`—Run the server. +* `Debug client (nuxt)`—Run the client with live reload. +* `Debug server and client (nuxt)`—Runs both the preceding two debug targets. + + +# How to Support + +[See the incomplete "How to Support" page](https://www.audiobookshelf.org/support) \ No newline at end of file diff --git a/audiobookshelf/data.yml b/audiobookshelf/data.yml new file mode 100644 index 000000000..e10194ec4 --- /dev/null +++ b/audiobookshelf/data.yml @@ -0,0 +1,20 @@ +name: Audiobookshelf +tags: + - 工具 +title: 一个自托管有声读物和播客服务器 +type: 工具 +description: 一个自托管有声读物和播客服务器 +additionalProperties: + key: audiobookshelf + name: Audiobookshelf + tags: + - Tool + shortDescZh: 一个自托管有声读物和播客服务器 + shortDescEn: A Self-hosted audiobook and podcast server + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://www.audiobookshelf.org/ + github: https://github.com/advplyr/audiobookshelf + document: https://www.audiobookshelf.org/docs diff --git a/audiobookshelf/logo.png b/audiobookshelf/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b52c2cd20aa7b7d1ddc9f801eac9bea235c989 GIT binary patch literal 16254 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 Wib7wj*N6l40A+bKxmuY|VgCUvX=c^{ literal 0 HcmV?d00001 diff --git a/calibre-web/0.6.20/data.yml b/calibre-web/0.6.20/data.yml new file mode 100644 index 000000000..9b517e139 --- /dev/null +++ b/calibre-web/0.6.20/data.yml @@ -0,0 +1,24 @@ +additionalProperties: + formFields: + - default: 40109 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: ./data/books + edit: true + envKey: DATA_PATH + labelEn: Books folder path + labelZh: 书本文件夹路径 + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TIME_ZONE + labelEn: Time zone + labelZh: 时区 + required: true + type: text diff --git a/calibre-web/0.6.20/docker-compose.yml b/calibre-web/0.6.20/docker-compose.yml new file mode 100644 index 000000000..3690f4e55 --- /dev/null +++ b/calibre-web/0.6.20/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3' +services: + calibre-web: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:8083" + volumes: + - "./data/config:/config" + - "${DATA_PATH}:/books" + environment: + - PUID=1000 + - PGID=1000 + - TZ=${TIME_ZONE} + - DOCKER_MODS=linuxserver/mods:universal-calibre #optional + - OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional + image: linuxserver/calibre-web:0.6.20 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/calibre-web/README.md b/calibre-web/README.md new file mode 100644 index 000000000..bcd0de98e --- /dev/null +++ b/calibre-web/README.md @@ -0,0 +1,133 @@ +# 使用说明 + +- 默认账户密码 + +``` +username:admin +password:admin123 +``` + +# 原始相关 + +# Calibre-Web + +Calibre-Web is a web app that offers a clean and intuitive interface for browsing, reading, and downloading eBooks using a valid [Calibre](https://calibre-ebook.com) database. + +[![License](https://img.shields.io/github/license/janeczku/calibre-web?style=flat-square)](https://github.com/janeczku/calibre-web/blob/master/LICENSE) +![Commit Activity](https://img.shields.io/github/commit-activity/w/janeczku/calibre-web?logo=github&style=flat-square&label=commits) +[![All Releases](https://img.shields.io/github/downloads/janeczku/calibre-web/total?logo=github&style=flat-square)](https://github.com/janeczku/calibre-web/releases) +[![PyPI](https://img.shields.io/pypi/v/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/) +[![PyPI - Downloads](https://img.shields.io/pypi/dm/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/) +[![Discord](https://img.shields.io/discord/838810113564344381?label=Discord&logo=discord&style=flat-square)](https://discord.gg/h2VsJ2NEfB) + +
+Table of Contents (click to expand) + +- [使用说明](#使用说明) +- [原始相关](#原始相关) +- [Calibre-Web](#calibre-web) + - [Features](#features) + - [Installation](#installation) + - [Installation via pip (recommended)](#installation-via-pip-recommended) + - [Quick Start](#quick-start) + - [Default Admin Login:](#default-admin-login) + - [Requirements](#requirements) + - [Docker Images](#docker-images) + - [**LinuxServer - x64, aarch64**](#linuxserver---x64-aarch64) + - [Contributor Recognition](#contributor-recognition) + - [Contact](#contact) + - [Contributing to Calibre-Web](#contributing-to-calibre-web) + +
+ + +*This software is a fork of [library](https://github.com/mutschler/calibreserver) and licensed under the GPL v3 License.* + +![Main screen](https://github.com/janeczku/calibre-web/wiki/images/main_screen.png) + +## Features + +- Modern and responsive Bootstrap 3 HTML5 interface +- Full graphical setup +- Comprehensive user management with fine-grained per-user permissions +- Admin interface +- Multilingual user interface supporting 20+ languages ([supported languages](https://github.com/janeczku/calibre-web/wiki/Translation-Status)) +- OPDS feed for eBook reader apps +- Advanced search and filtering options +- Custom book collection (shelves) creation +- eBook metadata editing and deletion support +- Metadata download from various sources (extensible via plugins) +- eBook conversion through Calibre binaries +- eBook download restriction to logged-in users +- Public user registration support +- Send eBooks to E-Readers with a single click +- Sync Kobo devices with your Calibre library +- In-browser eBook reading support for multiple formats +- Upload new books in various formats, including audio formats +- Calibre Custom Columns support +- Content hiding based on categories and Custom Column content per user +- Self-update capability +- "Magic Link" login for easy access on eReaders +- LDAP, Google/GitHub OAuth, and proxy authentication support + +## Installation + +#### Installation via pip (recommended) +1. Create a virtual environment for Calibre-Web to avoid conflicts with existing Python dependencies +2. Install Calibre-Web via pip: `pip install calibreweb` (or `pip3` depending on your OS/distro) +3. Install optional features via pip as needed, see [this page](https://github.com/janeczku/calibre-web/wiki/Dependencies-in-Calibre-Web-Linux-and-Windows) for details +4. Start Calibre-Web by typing `cps` + +*Note: Raspberry Pi OS users may encounter issues during installation. If so, please update pip (`./venv/bin/python3 -m pip install --upgrade pip`) and/or install cargo (`sudo apt install cargo`) before retrying the installation.* + +Refer to the Wiki for additional installation examples: [manual installation](https://github.com/janeczku/calibre-web/wiki/Manual-installation), [Linux Mint](https://github.com/janeczku/calibre-web/wiki/How-To:Install-Calibre-Web-in-Linux-Mint-19-or-20), [Cloud Provider](https://github.com/janeczku/calibre-web/wiki/How-To:-Install-Calibre-Web-on-a-Cloud-Provider). + +## Quick Start + +1. Open your browser and navigate to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog +2. Log in with the default admin credentials +3. If you don't have a Calibre database, you can use [this database](https://github.com/janeczku/calibre-web/raw/master/library/metadata.db) (move it out of the Calibre-Web folder to prevent overwriting during updates) +4. Set `Location of Calibre database` to the path of the folder containing your Calibre library (metadata.db) and click "Save" +5. Optionally, use Google Drive to host your Calibre library by following the [Google Drive integration guide](https://github.com/janeczku/calibre-web/wiki/G-Drive-Setup#using-google-drive-integration) +6. Configure your Calibre-Web instance via the admin page, referring to the [Basic Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#basic-configuration) and [UI Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#ui-configuration) guides + +#### Default Admin Login: +- **Username:** admin +- **Password:** admin123 + +## Requirements + +- Python 3.5+ +- [Imagemagick](https://imagemagick.org/script/download.php) for cover extraction from EPUBs (Windows users may need to install [Ghostscript](https://ghostscript.com/releases/gsdnld.html) for PDF cover extraction) +- Optional: [Calibre desktop program](https://calibre-ebook.com/download) for on-the-fly conversion and metadata editing (set "calibre's converter tool" path on the setup page) +- Optional: [Kepubify tool](https://github.com/pgaskin/kepubify/releases/latest) for Kobo device support (place the binary in `/opt/kepubify` on Linux or `C:\Program Files\kepubify` on Windows) + +## Docker Images + +Pre-built Docker images are available in the following Docker Hub repositories (maintained by the LinuxServer team): + +#### **LinuxServer - x64, aarch64** +- [Docker Hub](https://hub.docker.com/r/linuxserver/calibre-web) +- [GitHub](https://github.com/linuxserver/docker-calibre-web) +- [GitHub - Optional Calibre layer](https://github.com/linuxserver/docker-mods/tree/universal-calibre) + + Include the environment variable `DOCKER_MODS=linuxserver/mods:universal-calibre` in your Docker run/compose file to add the Calibre `ebook-convert` binary (x64 only). Omit this variable for a lightweight image. + + Both the Calibre-Web and Calibre-Mod images are automatically rebuilt on new releases and updates. + + - Set "path to convertertool" to `/usr/bin/ebook-convert` + - Set "path to unrar" to `/usr/bin/unrar` + +## Contributor Recognition + +We would like to thank all the [contributors](https://github.com/janeczku/calibre-web/graphs/contributors) and maintainers of Calibre-Web for their valuable input and dedication to the project. Your contributions are greatly appreciated. + +## Contact + +Join us on [Discord](https://discord.gg/h2VsJ2NEfB) + +For more information, How To's, and FAQs, please visit the [Wiki](https://github.com/janeczku/calibre-web/wiki) + +## Contributing to Calibre-Web + +Check out our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md) diff --git a/calibre-web/data.yml b/calibre-web/data.yml new file mode 100644 index 000000000..ff1c69266 --- /dev/null +++ b/calibre-web/data.yml @@ -0,0 +1,20 @@ +name: Calibre-Web +tags: + - 工具 +title: 用于浏览、阅读和下载存储在 Calibre 数据库中的电子书的 Web 应用程序 +type: 工具 +description: 用于浏览、阅读和下载存储在 Calibre 数据库中的电子书的 Web 应用程序 +additionalProperties: + key: calibre-web + name: Calibre-Web + tags: + - Tool + shortDescZh: 用于浏览、阅读和下载存储在 Calibre 数据库中的电子书的 Web 应用程序 + shortDescEn: Web app for browsing, reading and downloading eBooks stored in a Calibre database + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://calibre-ebook.com + github: https://github.com/janeczku/calibre-web + document: https://calibre-ebook.com/help \ No newline at end of file diff --git a/calibre-web/logo.png b/calibre-web/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e98cc134ab88b26dd2a594dd734b9d2fc2fdc8 GIT binary patch literal 8719 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 literal 0 HcmV?d00001 diff --git a/changedetectionio/0.44/data.yml b/changedetectionio/0.44/data.yml new file mode 100644 index 000000000..68a3cbf37 --- /dev/null +++ b/changedetectionio/0.44/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40097 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/changedetectionio/0.44/docker-compose.yml b/changedetectionio/0.44/docker-compose.yml new file mode 100644 index 000000000..757d262ad --- /dev/null +++ b/changedetectionio/0.44/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + changedetection: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:5000" + volumes: + - "./data:/datastore" + image: dgtlmoon/changedetection.io:0.44 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/changedetectionio/README.md b/changedetectionio/README.md new file mode 100644 index 000000000..ea93e7424 --- /dev/null +++ b/changedetectionio/README.md @@ -0,0 +1,260 @@ +## Web Site Change Detection, Restock monitoring and notifications. + +**_Detect website content changes and perform meaningful actions - trigger notifications via Discord, Email, Slack, Telegram, API calls and many more._** + +_Live your data-life pro-actively._ + + +[Self-hosted web page change monitoring](https://changedetection.io?src=github) + +[![Release Version][release-shield]][release-link] [![Docker Pulls][docker-pulls]][docker-link] [![License][license-shield]](https://github.com/dgtlmoon/changedetection.io/blob/master/LICENSE.md) + +![changedetection.io](https://github.com/dgtlmoon/changedetection.io/actions/workflows/test-only.yml/badge.svg?branch=master) + +[**Don't have time? Let us host it for you! try our $8.99/month subscription - use our proxies and support!**](https://changedetection.io) , _half the price of other website change monitoring services!_ + +- Chrome browser included. +- Super fast, no registration needed setup. +- Get started watching and receiving website change notifications straight away. + + +### Target specific parts of the webpage using the Visual Selector tool. + +Available when connected to a
playwright content fetcher (included as part of our subscription service) + +[Self-hosted web page change monitoring context difference ](https://changedetection.io?src=github) + +### Easily see what changed, examine by word, line, or individual character. + +[Self-hosted web page change monitoring context difference ](https://changedetection.io?src=github) + + +### Perform interactive browser steps + +Fill in text boxes, click buttons and more, setup your changedetection scenario. + +Using the **Browser Steps** configuration, add basic steps before performing change detection, such as logging into websites, adding a product to a cart, accept cookie logins, entering dates and refining searches. + +[Self-hosted web page change monitoring context difference ](https://changedetection.io?src=github) + +After **Browser Steps** have been run, then visit the **Visual Selector** tab to refine the content you're interested in. +Requires Playwright to be enabled. + + +### Example use cases + +- Products and services have a change in pricing +- _Out of stock notification_ and _Back In stock notification_ +- Monitor and track PDF file changes, know when a PDF file has text changes. +- Governmental department updates (changes are often only on their websites) +- New software releases, security advisories when you're not on their mailing list. +- Festivals with changes +- Discogs restock alerts and monitoring +- Realestate listing changes +- Know when your favourite whiskey is on sale, or other special deals are announced before anyone else +- COVID related news from government websites +- University/organisation news from their website +- Detect and monitor changes in JSON API responses +- JSON API monitoring and alerting +- Changes in legal and other documents +- Trigger API calls via notifications when text appears on a website +- Glue together APIs using the JSON filter and JSON notifications +- Create RSS feeds based on changes in web content +- Monitor HTML source code for unexpected changes, strengthen your PCI compliance +- You have a very sensitive list of URLs to watch and you do _not_ want to use the paid alternatives. (Remember, _you_ are the product) +- Get notified when certain keywords appear in Twitter search results +- Proactively search for jobs, get notified when companies update their careers page, search job portals for keywords. +- Get alerts when new job positions are open on Bamboo HR and other job platforms +- Website defacement monitoring +- Pokémon Card Restock Tracker / Pokémon TCG Tracker + +_Need an actual Chrome runner with Javascript support? We support fetching via WebDriver and Playwright!_ + +#### Key Features + +- Lots of trigger filters, such as "Trigger on text", "Remove text by selector", "Ignore text", "Extract text", also using regular-expressions! +- Target elements with xPath and CSS Selectors, Easily monitor complex JSON with JSONPath or jq +- Switch between fast non-JS and Chrome JS based "fetchers" +- Track changes in PDF files (Monitor text changed in the PDF, Also monitor PDF filesize and checksums) +- Easily specify how often a site should be checked +- Execute JS before extracting text (Good for logging in, see examples in the UI!) +- Override Request Headers, Specify `POST` or `GET` and other methods +- Use the "Visual Selector" to help target specific elements +- Configurable [proxy per watch](https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration) +- Send a screenshot with the notification when a change is detected in the web page + +We [recommend and use Bright Data](https://brightdata.grsm.io/n0r16zf7eivq) global proxy services, Bright Data will match any first deposit up to $100 using our signup link. + +Please :star: star :star: this project and help it grow! https://github.com/dgtlmoon/changedetection.io/ + +## Installation + +### Docker + +With Docker composer, just clone this repository and.. + +```bash +$ docker-compose up -d +``` + +Docker standalone +```bash +$ docker run -d --restart always -p "127.0.0.1:5000:5000" -v datastore-volume:/datastore --name changedetection.io dgtlmoon/changedetection.io +``` + +`:latest` tag is our latest stable release, `:dev` tag is our bleeding edge `master` branch. + +Alternative docker repository over at ghcr - [ghcr.io/dgtlmoon/changedetection.io](https://ghcr.io/dgtlmoon/changedetection.io) + +### Windows + +See the install instructions at the wiki https://github.com/dgtlmoon/changedetection.io/wiki/Microsoft-Windows + +### Python Pip + +Check out our pypi page https://pypi.org/project/changedetection.io/ + +```bash +$ pip3 install changedetection.io +$ changedetection.io -d /path/to/empty/data/dir -p 5000 +``` + +Then visit http://127.0.0.1:5000 , You should now be able to access the UI. + +_Now with per-site configurable support for using a fast built in HTTP fetcher or use a Chrome based fetcher for monitoring of JavaScript websites!_ + +## Updating changedetection.io + +### Docker +``` +docker pull dgtlmoon/changedetection.io +docker kill $(docker ps -a -f name=changedetection.io -q) +docker rm $(docker ps -a -f name=changedetection.io -q) +docker run -d --restart always -p "127.0.0.1:5000:5000" -v datastore-volume:/datastore --name changedetection.io dgtlmoon/changedetection.io +``` + +### docker-compose + +```bash +docker-compose pull && docker-compose up -d +``` + +See the wiki for more information https://github.com/dgtlmoon/changedetection.io/wiki + + +## Filters + +XPath, JSONPath, jq, and CSS support comes baked in! You can be as specific as you need, use XPath exported from various XPath element query creation tools. +(We support LXML `re:test`, `re:match` and `re:replace`.) + +## Notifications + +ChangeDetection.io supports a massive amount of notifications (including email, office365, custom APIs, etc) when a web-page has a change detected thanks to the apprise library. +Simply set one or more notification URL's in the _[edit]_ tab of that watch. + +Just some examples + + discord://webhook_id/webhook_token + flock://app_token/g:channel_id + gitter://token/room + gchat://workspace/key/token + msteams://TokenA/TokenB/TokenC/ + o365://TenantID:AccountEmail/ClientID/ClientSecret/TargetEmail + rocket://user:password@hostname/#Channel + mailto://user:pass@example.com?to=receivingAddress@example.com + json://someserver.com/custom-api + syslog:// + +And everything else in this list! + +Self-hosted web page change monitoring notifications + +Now you can also customise your notification content and use Jinja2 templating for their title and body! + +## JSON API Monitoring + +Detect changes and monitor data in JSON API's by using either JSONPath or jq to filter, parse, and restructure JSON as needed. + +![image](https://raw.githubusercontent.com/dgtlmoon/changedetection.io/master/docs/json-filter-field-example.png) + +This will re-parse the JSON and apply formatting to the text, making it super easy to monitor and detect changes in JSON API results + +![image](https://raw.githubusercontent.com/dgtlmoon/changedetection.io/master/docs/json-diff-example.png) + +### JSONPath or jq? + +For more complex parsing, filtering, and modifying of JSON data, jq is recommended due to the built-in operators and functions. Refer to the [documentation](https://stedolan.github.io/jq/manual/) for more specifc information on jq. + +One big advantage of `jq` is that you can use logic in your JSON filter, such as filters to only show items that have a value greater than/less than etc. + +See the wiki https://github.com/dgtlmoon/changedetection.io/wiki/JSON-Selector-Filter-help for more information and examples + +### Parse JSON embedded in HTML! + +When you enable a `json:` or `jq:` filter, you can even automatically extract and parse embedded JSON inside a HTML page! Amazingly handy for sites that build content based on JSON, such as many e-commerce websites. + +``` + +... + +``` + +`json:$..price` or `jq:..price` would give `3949.99`, or you can extract the whole structure (use a JSONpath test website to validate with) + +The application also supports notifying you that it can follow this information automatically + + +## Proxy Configuration + +See the wiki https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration , we also support using [BrightData proxy services where possible]( https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration#brightdata-proxy-support) + +## Raspberry Pi support? + +Raspberry Pi and linux/arm/v6 linux/arm/v7 arm64 devices are supported! See the wiki for [details](https://github.com/dgtlmoon/changedetection.io/wiki/Fetching-pages-with-WebDriver) + +## API Support + +Supports managing the website watch list [via our API](https://changedetection.io/docs/api_v1/index.html) + +## Support us + +Do you use changedetection.io to make money? does it save you time or money? Does it make your life easier? less stressful? Remember, we write this software when we should be doing actual paid work, we have to buy food and pay rent just like you. + + +Firstly, consider taking out a [change detection monthly subscription - unlimited checks and watches](https://changedetection.io?src=github) , even if you don't use it, you still get the warm fuzzy feeling of helping out the project. (And who knows, you might just use it!) + +Or directly donate an amount PayPal [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?hosted_button_id=7CP6HR9ZCNDYJ) + +Or BTC `1PLFN327GyUarpJd7nVe7Reqg9qHx5frNn` + +Support us! + +## Commercial Support + +I offer commercial support, this software is depended on by network security, aerospace , data-science and data-journalist professionals just to name a few, please reach out at dgtlmoon@gmail.com for any enquiries, I am more than glad to work with your organisation to further the possibilities of what can be done with changedetection.io + + +[release-shield]: https://img.shields.io:/github/v/release/dgtlmoon/changedetection.io?style=for-the-badge +[docker-pulls]: https://img.shields.io/docker/pulls/dgtlmoon/changedetection.io?style=for-the-badge +[test-shield]: https://github.com/dgtlmoon/changedetection.io/actions/workflows/test-only.yml/badge.svg?branch=master + +[license-shield]: https://img.shields.io/github/license/dgtlmoon/changedetection.io.svg?style=for-the-badge +[release-link]: https://github.com/dgtlmoon/changedetection.io/releases +[docker-link]: https://hub.docker.com/r/dgtlmoon/changedetection.io \ No newline at end of file diff --git a/changedetectionio/data.yml b/changedetectionio/data.yml new file mode 100644 index 000000000..c0e74ac28 --- /dev/null +++ b/changedetectionio/data.yml @@ -0,0 +1,20 @@ +name: Changedetection.io +tags: + - 工具 +title: 网站更改检测、补货监控和通知。 +type: 工具 +description: 网站更改检测、补货监控和通知。 +additionalProperties: + key: changedetectionio + name: Changedetection.io + tags: + - Tool + shortDescZh: 网站更改检测、补货监控和通知。 + shortDescEn: Web Site Change Detection, Restock monitoring and notifications + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://changedetection.io/ + github: https://github.com/dgtlmoon/changedetection.io + document: https://github.com/dgtlmoon/changedetection.io/wiki diff --git a/changedetectionio/logo.png b/changedetectionio/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..80290161e6c1de3e4ebbf5817d793594e3872ea3 GIT binary patch literal 22507 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

;)Ef5_Op{Y`Q#eP%jI+Hp-`MPs}Jz_qdPg! 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 i*|yVx@}E=U*Z-=C3#@X3;MaT4sH +Translation status + + +Like what you see? :eyes: Give us a GitHub Star! :star: + +![Focalboard](https://github.com/mattermost/focalboard/raw/main/website/site/static/img/hero.jpg) + +Focalboard is an open source, multilingual, self-hosted project management tool that's an alternative to Trello, Notion, and Asana. + +It helps define, organize, track and manage work across individuals and teams. Focalboard comes in three editions: + +* **[Mattermost Boards](https://mattermost.com/boards/)**: Integrated with the Mattermost platform for your team to plan and collaborate. + +* **[Personal Desktop](https://www.focalboard.com/docs/personal-edition/desktop/)**: A standalone, single-user [macOS](https://apps.apple.com/app/apple-store/id1556908618?pt=2114704&ct=website&mt=8), [Windows](https://www.microsoft.com/store/apps/9NLN2T0SX9VF?cid=website), or [Linux](https://www.focalboard.com/download/personal-edition/desktop/#linux-desktop) desktop app for your own todos and personal projects. + +* **[Personal Server](https://www.focalboard.com/download/personal-edition/ubuntu/)**: A standalone, multi-user server for development and personal use. + +## Try Focalboard + +### Mattermost Boards + +**Mattermost Boards** combines project management tools with messaging and collaboration for teams of all sizes. To access and use **Mattermost Boards**, install or upgrade to Mattermost v6.0 or later as a [self-hosted server](https://docs.mattermost.com/guides/deployment.html?utm_source=github&utm_campaign=focalboard). After logging into Mattermost, select the menu in the top left corner and select **Boards**. + +### Personal Desktop (Windows, Mac or Linux Desktop) + +* **Windows**: Download from the [Windows App Store](https://www.microsoft.com/store/productId/9NLN2T0SX9VF) or download `focalboard-win.zip` from the [latest release](https://github.com/mattermost/focalboard/releases), unpack, and run `Focalboard.exe`. +* **Mac**: Download from the [Mac App Store](https://apps.apple.com/us/app/focalboard-insiders/id1556908618?mt=12). +* **Linux Desktop**: Download `focalboard-linux.tar.gz` from the [latest release](https://github.com/mattermost/focalboard/releases), unpack, and open `focalboard-app`. + +### Personal Server + +**Ubuntu**: You can download and run the compiled Focalboard **Personal Server** on Ubuntu by following [our latest install guide](https://www.focalboard.com/download/personal-edition/ubuntu/). + +### API Docs + +Boards API docs can be found over at https://htmlpreview.github.io/?https://github.com/mattermost/focalboard/blob/main/server/swagger/docs/html/index.html + +## Contribute to Focalboard + +For anyone interested in being an official maintainer of the Focalboard repository, please reach out to us on our [Focalboard Community Channel](https://community.mattermost.com/core/channels/focalboard). If there are no maintainers, and you’re still interested in adding your own improvements to the Focalboard Personal Editions, we encourage you to fork and maintain the repository. + +### Getting started + +Our [developer guide](https://developers.mattermost.com/contribute/focalboard/personal-server-setup-guide) has detailed instructions on how to set up your development environment for the **Personal Server**. It also provides more information about contributing to our open source community. + +Clone [mattermost-server](https://github.com/mattermost/mattermost-server) into sibling directory. + +Create an `.env` file in the focalboard directory that contains: + +``` +EXCLUDE_ENTERPRISE="1" +``` + +To build the server: + +``` +make prebuild +make +``` + +To run the server: + +``` + ./bin/focalboard-server +``` + +Then navigate your browser to [`http://localhost:8000`](http://localhost:8000) to access your Focalboard server. The port is configured in `config.json`. + +Once the server is running, you can rebuild just the web app via `make webapp` in a separate terminal window. Reload your browser to see the changes. + +### Building and running standalone desktop apps + +You can build standalone apps that package the server to run locally against SQLite: + +* **Windows**: + * *Requires Windows 10, [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/) 10.0.19041.0, and .NET 4.8 developer pack* + * Open a `git-bash` prompt. + * Run `make prebuild` + * The above prebuild step needs to be run only when you make changes to or want to install your npm dependencies, etc. + * Once the prebuild is completed, you can keep repeating the below steps to build the app & see the changes. + * Run `make win-wpf-app` + * Run `cd win-wpf/msix && focalboard.exe` +* **Mac**: + * *Requires macOS 11.3+ and Xcode 13.2.1+* + * Run `make prebuild` + * The above prebuild step needs to be run only when you make changes to or want to install your npm dependencies, etc. + * Once the prebuild is completed, you can keep repeating the below steps to build the app & see the changes. + * Run `make mac-app` + * Run `open mac/dist/Focalboard.app` +* **Linux**: + * *Tested on Ubuntu 18.04* + * Install `webgtk` dependencies + * Run `sudo apt-get install libgtk-3-dev` + * Run `sudo apt-get install libwebkit2gtk-4.0-dev` + * Run `make prebuild` + * The above prebuild step needs to be run only when you make changes to or want to install your npm dependencies, etc. + * Once the prebuild is completed, you can keep repeating the below steps to build the app & see the changes. + * Run `make linux-app` + * Uncompress `linux/dist/focalboard-linux.tar.gz` to a directory of your choice + * Run `focalboard-app` from the directory you have chosen +* **Docker**: + * To run it locally from offical image: + * `docker run -it -p 80:8000 mattermost/focalboard` + * To build it for your current architecture: + * `docker build -f docker/Dockerfile .` + * To build it for a custom architecture (experimental): + * `docker build -f docker/Dockerfile --platform linux/arm64 .` + +Cross-compilation currently isn't fully supported, so please build on the appropriate platform. Refer to the GitHub Actions workflows (`build-mac.yml`, `build-win.yml`, `build-ubuntu.yml`) for the detailed list of steps on each platform. + +### Unit testing + +Before checking in commits, run `make ci`, which is similar to the `.gitlab-ci.yml` workflow and includes: + +* **Server unit tests**: `make server-test` +* **Web app ESLint**: `cd webapp; npm run check` +* **Web app unit tests**: `cd webapp; npm run test` +* **Web app UI tests**: `cd webapp; npm run cypress:ci` + +### Translating + +Help translate Focalboard! The app is already translated into several languages. We welcome corrections and new language translations! You can add new languages or improve existing translations at [Weblate](https://translate.mattermost.com/engage/focalboard/). + +### Staying informed + +* **Changes**: See the [CHANGELOG](CHANGELOG.md) for the latest updates +* **GitHub Discussions**: Join the [Developer Discussion](https://github.com/mattermost/focalboard/discussions) board +* **Bug Reports**: [File a bug report](https://github.com/mattermost/focalboard/issues/new?assignees=&labels=bug&template=bug_report.md&title=) +* **Chat**: Join the [Focalboard community channel](https://community.mattermost.com/core/channels/focalboard) \ No newline at end of file diff --git a/focalboard/data.yml b/focalboard/data.yml new file mode 100644 index 000000000..b2b3b0910 --- /dev/null +++ b/focalboard/data.yml @@ -0,0 +1,20 @@ +name: Focalboard +tags: + - 工具 +title: Trello,Notion和Asana的开源自托管替代方案 +type: 工具 +description: Trello,Notion和Asana的开源自托管替代方案 +additionalProperties: + key: focalboard + name: Focalboard + tags: + - Tool + shortDescZh: Trello,Notion和Asana的开源自托管替代方案 + shortDescEn: An open source, self-hosted alternative to Trello, Notion, and Asana + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://www.focalboard.com/ + github: https://github.com/mattermost/focalboard + document: https://docs.mattermost.com/guides/boards.html diff --git a/focalboard/logo.png b/focalboard/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f8489e8f2f3c8b0d46874c3c9b299752dc4b433c GIT binary patch literal 4069 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 7.4.32, BCMath PHP Extension, INTL PHP Extension, Ctype PHP Extension, Fileinfo PHP extension, JSON PHP Extension, Mbstring PHP Extension, OpenSSL PHP Extension, PDO PHP Extension, Tokenizer PHP Extension, XML PHP Extension, the only other thing Heimdall needs is sqlite support and zip support (php-zip). + +If you find you can't change the background make sure `php_fileinfo` is enabled in your php.ini. I believe it should be by default, but one user came across the issue on a windows system. + +Installation is as simple as cloning the repository somewhere, or downloading and extracting the zip/tar and pointing your httpd document root to the `/public` folder then creating the .env file and generating an encryption key (this is all taken care of for you with the docker). + +``` +cd /path/to/heimdall +cp .env.example .env +php artisan key:generate +``` + +For simple testing you could just go to the folder and type `php artisan serve` + +There is also a multi-arch Docker which supports x86-64, armhf and arm64, instructions on how to use them at + +- https://hub.docker.com/r/linuxserver/heimdall/ + +## Updating +To update your instance, simply clone this repository or download the zip/tar file with the new version and copy it over the old installation. + +## Search Providers +v2.3.0 added the ability for users to customise the search options. + +Options are stored in `/storage/app/searchproviders.yaml` (`/config/www/searchproviders.yaml` on docker installs), feel free to rearrange the options, add new ones, delete ones you don't use, etc. + +Consider contributing to https://github.com/linuxserver/Heimdall/discussions/categories/search-providers to help others add new ones. + +The item at the top of the list `Tiles` allows you to search for apps on your dashboard by name, helpful when you have lots of icons. + +## New background image not being set +If you are using the docker image or a default php install you may find images over 2MB wont get set as the background image, you just need to change the `upload_max_filesize` in the php.ini. + +If you are using the linuxserver.io docker image simply edit `/path/to/config/php/php-local.ini` and add `upload_max_filesize = 30M` to the end. + +## Docker and enhanced apps +If you are running the docker and the EnhancedApps you are using are also in dockers, you may need to use the docker networking addresses to communicate with them. + +You can do this by using `http(s)://docker_name:port` in the config section. Instead of the name you can use the internal docker ip, this usually starts with `172.` + +## Languages +The app has been translated into several languages; however, the quality of the translations could do with work. If you would like to improve them, or help with other translations, they are stored in `/resources/lang/`. + +To create a new language translation, make a new folder with the ISO 3166-1 alpha-2 code as the name, copy `app.php` from `/resources/lang/en/app.php` into your new folder and replace the English strings. + +When you are finished, create a pull request. + +Currently added languages are + +- Breton +- Chinese +- Danish +- Dutch +- English +- Finnish +- French +- German +- Greek +- Hungarian +- Italian +- Japanese +- Korean +- Lombard +- Norwegian +- Polish +- Portuguese +- Russian +- Slovenian +- Spanish +- Swedish +- Turkish + +## Web Server Configuration + +### Apache +A `.htaccess` file ships with the app, however, a lot of apache installations disallow `.htaccess` files by default. +You will notice this due to some links not working like `/settings`. +In addition mod-rewrite needs to be enabled if it isn't already. + +#### Fixes & work around options +##### - Apache global allow .htaccess +Find the `AllowOverride None` line in your apache configuration and change this to `AllowOverride All` + +##### - Apache vhost configuration allow .htaccess +In the apache vhost configuration in the `` block add `AllowOverride All` + +##### - Add .htaccess content in apache configuration +You can add the full `.htaccess` into your apache configuration, this way you do not need to allow `.htaccess` files. +You can even shorten the content of the `.htaccess` when inserting it into the apache configuration to: +``` +Options +FollowSymLinks +RewriteEngine On + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^ index.php [L] +``` +#### More info +More info about `AllowOverride` can be found here: +https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride + + + +### Nginx +If you are using Nginx, the following directive in your site configuration will direct all requests to the `index.php` front controller: + +``` +location / { + try_files $uri $uri/ /index.php?$query_string; +} +``` +Someone was using the same nginx setup to both run this and reverse proxy Plex, Plex is served from `/web` so their location was interfering with the `/webfonts`. + +Therefore, if your fonts aren't showing because you have a location for `/web`, add the following +``` +location /webfonts { + try_files $uri $uri/; +} +``` +If there are any other locations which might interfere with any of the folders in the `/public` folder, you might have to do the same for those as well, but it's a super fringe case. + +### Reverse proxy +If you'd like to reverse proxy this app, we recommend using our letsencrypt/nginx docker image: [SWAG - Secure Web Application Gateway](https://hub.docker.com/r/linuxserver/swag) +You can either reverse proxy from the root location, or from a subdomain (subfolder method is currently not supported). For HTTPS proxy, make sure you use the HTTPS port of Heimdall webserver, otherwise some links may break. You can add security through `.htpasswd` + +``` +location / { + auth_basic "Restricted"; + auth_basic_user_file /config/nginx/.htpasswd; + include /config/nginx/proxy.conf; + proxy_set_header X-Forwarded-Proto https; + proxy_pass http://heimdall; +} +``` + +### Self-signed certificates and local CAs +Per default Heimdall uses the standard certificate bundle file (`ca-certificates.crt`) to verify HTTPS sites and will ignore additional certificates placed in `/etc/ssl/certs`. If you wish to use enhanced apps with HTTPS sites that use a self-signed certificate or certs signed with your own local CA, you can override the default bundle: + +- Create a unified certificate `.pem` file that contains all CAs and certificates that Heimdall has to verify. For example, if you use both LetsEncrypt and a local CA for your internal apps, concatenate the LetsEncrypt intermediate CA (export via browser) and your local CA `cert.pem` (or any number of self-signed certs) into one `heimdall.pem` file. +- Place the `heimdall.pem` into the container (if you use Docker), for example by placing it in the path that you mapped to `/config`. Make sure that the Heimdall user has read access (`chmod a+r`). +- Set the `openssl.cafile` setting in `/config/php/php-local.ini` to your cert bundle: + +``` +# /config/php/php-local.ini +openssl.cafile = /config/heimdall.pem +``` + +Restart the container and the enhanced apps should now be able to access your local HTTP websites. This configuration will survive updating or recreating the Heimdall container. + +## Running offline +The apps list is hosted on github, you have a couple of options if you want to run without a connection to the outside world: +1) Clone the repository and host it yourself, look at the .github actions file to see how to generate the apps list. +2) Download the apps list and store it as a json accessible to heimdall named `list.json` + +With both options all you need to do is add the following to your `.env` +`APP_SOURCE=http://localhost/` Where `http://localhost/` is the path to the apps list without the name of the file, so if your file is stored at `https://heimdall.local/list.json` you would put `APP_SOURCE=https://heimdall.local/` + +## Support +https://discord.gg/CCjHKn4 or through GitHub issues + +## Donate +If you would like to show your appreciation, feel free to use the link below. + +[![PayPal](https://heimdall.site/img/paypaldonate.svg)](https://www.paypal.me/heimdall) + +## Credits +- PHP Framework - [Laravel](https://laravel.com/) +- Icons - [FontAwesome 5](https://fontawesome.com/) +- JavaScript - [jQuery](https://jquery.com/) +- Colour picker - [Huebee](http://huebee.buzz/) +- Background image - [pexels](https://www.pexels.com) +- Trianglify library - [Trianglify](https://github.com/qrohlf/trianglify) +- Everyone at Linuxserver.io that has helped with the app and let's not forget IronicBadger for the following question that started it all: +``` +you know, i would love something like this landing page for all my servers apps +that gives me the ability to pin favourites +and / or search +@Stark @Kode do either of you think you'd be able to rustle something like this up ? +``` + +## License + +This app is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/heimdall/data.yml b/heimdall/data.yml new file mode 100644 index 000000000..781cc193e --- /dev/null +++ b/heimdall/data.yml @@ -0,0 +1,20 @@ +name: Heimdall +tags: + - 工具 +title: 应用程序仪表板和启动器 +type: 工具 +description: 应用程序仪表板和启动器 +additionalProperties: + key: heimdall + name: Heimdall + tags: + - Tool + shortDescZh: 应用程序仪表板和启动器 + shortDescEn: An Application dashboard and launcher + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://heimdall.site/ + github: https://github.com/linuxserver/Heimdall + document: https://github.com/linuxserver/Heimdall \ No newline at end of file diff --git a/heimdall/logo.png b/heimdall/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8f907346106699b755985572682870a4346f594a GIT binary patch literal 15799 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 literal 0 HcmV?d00001 diff --git a/hertzbeat/1.4.0/data.yml b/hertzbeat/1.4.0/data.yml new file mode 100644 index 000000000..c509746cc --- /dev/null +++ b/hertzbeat/1.4.0/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40066 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/hertzbeat/1.4.0/docker-compose.yml b/hertzbeat/1.4.0/docker-compose.yml new file mode 100644 index 000000000..30db8614d --- /dev/null +++ b/hertzbeat/1.4.0/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3' +services: + hertzbeat: + container_name: ${CONTAINER_NAME} + restart: always + environment: + - TZ=Asia/Shanghai + - LANG=zh_CN.UTF-8 + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:1157" + volumes: + - "./data/data:/opt/hertzbeat/data" + - "./data/logs:/opt/hertzbeat/logs" + image: tancloud/hertzbeat:v1.4.0 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/hertzbeat/README.md b/hertzbeat/README.md new file mode 100644 index 000000000..a4357978d --- /dev/null +++ b/hertzbeat/README.md @@ -0,0 +1,390 @@ +# 使用说明 + +- 默认账户密码 +``` +username:admin +password:hertzbeat +`````` +# 原始相关 + +

+ + hertzbeat + +

+ +> 默认账户密码 admin/hertzbeat + +[comment]: <> (sureness) + +## HertzBeat 赫兹跳动 + +> 易用友好的开源实时监控告警系统,无需Agent,强大自定义监控能力。 + +[![discord](https://img.shields.io/badge/chat-on%20discord-brightgreen)](https://discord.gg/Fb6M73htGr) +[![Gitter](https://badges.gitter.im/hertzbeat/community.svg)](https://gitter.im/hertzbeat/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![QQ](https://img.shields.io/badge/qq-236915833-orange)](https://jq.qq.com/?_wv=1027&k=aVIVB2K9) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/web-monitor.svg) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/ping-connect.svg) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/port-available.svg) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/database-monitor.svg) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/os-monitor.svg) +![hertzbeat](https://img.shields.io/badge/monitor-cloud%20native-brightgreen) +![hertzbeat](https://img.shields.io/badge/monitor-middleware-blueviolet) +![hertzbeat](https://img.shields.io/badge/monitor-network-red) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/custom-monitor.svg) +![hertzbeat](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/alert.svg) + +**官网: [hertzbeat.dromara.org](https://hertzbeat.dromara.org) | [hertzbeat.com](https://hertzbeat.com)** + +**云服务: [tancloud.cn](https://tancloud.cn)** + +## 🎡 介绍 + +> [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是一个拥有强大自定义监控能力,无需 Agent 的开源实时监控告警系统。 +> 集 **监控+告警+通知** 为一体,支持对应用服务,数据库,操作系统,中间件,云原生,网络等监控,阈值告警通知一步到位。 +> 易用友好,全 WEB 页面操作,鼠标点一点就能监控告警,零上手学习成本。 +> 更自由化的阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` 等方式及时送达。 + +> 我们将`Http,Jmx,Ssh,Snmp,Jdbc`等协议规范可配置化,您只需在浏览器配置`YML`就能使用这些协议去自定义采集任何您想要的指标。 +> 您相信只需配置下就能立刻适配一款`K8s`或`Docker`等新的监控类型吗? + +> `HertzBeat`的强大自定义,多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。 +> 当然我们也提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署学习一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。 + +---- + +[![hertzbeat](https://github.com/dromara/hertzbeat/raw/master/home/static/img/home/1.png)](https://www.bilibili.com/video/BV1LY4y1m7rH/) + +[![hertzbeat](https://github.com/dromara/hertzbeat/raw/master/home/static/img/home/9.png)](https://www.bilibili.com/video/BV1LY4y1m7rH/) + +---- + +## 🥐 模块 + +![hertzBeat](https://github.com/dromara/hertzbeat/raw/master/home/static/img/docs/hertzbeat-arch.png) + +## ⛄ 已支持 + +> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模版,用户可以导入这些模版来支持对应类型的监控! +> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模版。 + +- [Website](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-port.yml), + [Http Api](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-ping.yml), + [Jvm](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-jvm.yml), [SiteMap](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-fullsite.yml), + [Ssl Certificate](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-ssl_cert.yml), [SpringBoot2](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-springboot2.yml), + [FTP Server](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-ftp.yml), [SpringBoot3](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-springboot3.yml) +- [Mysql](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-postgresql.yml), + [MariaDB](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-redis.yml), + [ElasticSearch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-sqlserver.yml), + [Oracle](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-mongodb.yml), + [DM](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-opengauss.yml), + [ClickHouse](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-iotdb.yml), + [Redis Cluster](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-redis_sentinel.yml) +- [Linux](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-ubuntu.yml), + [CentOS](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-windows.yml), + [EulerOS](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-coreos.yml), + [OpenSUSE](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-rockylinux.yml), + [Red Hat](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-freebsd.yml), + [AlmaLinux](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-debian.yml) +- [Tomcat](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-nacos.yml), + [Zookeeper](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-rabbitmq.yml), + [Flink](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-kafka.yml), + [ShenYu](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-dynamic_tp.yml), + [Jetty](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-activemq.yml) +- [Kubernetes](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-docker.yml) +- [CiscoSwitch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-hpe_switch.yml), + [HuaweiSwitch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-tplink_switch.yml), + [H3cSwitch](https://raw.githubusercontent.com/dromara/hertzbeat/master/manager/src/main/resources/define/app-h3c_switch.yml) +- 和更多自定义监控模版。 +- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook`。 + +## 🐕 快速开始 + +- 如果您不想部署而是直接使用,我们提供SAAS监控云-[TanCloud探云](https://console.tancloud.cn),即刻 **[登录注册](https://console.tancloud.cn)** 免费使用。 +- 如果您是想将HertzBeat部署到内网环境搭建监控系统,请参考下面的部署文档进行操作。 + +### 🍞 HertzBeat安装 +> HertzBeat支持通过源码安装启动,Docker容器运行和安装包方式安装部署,CPU架构支持X86/ARM64。 + +##### 方式一:Docker方式快速安装 + +1. `docker` 环境仅需一条命令即可开始 + +```docker run -d -p 1157:1157 --name hertzbeat tancloud/hertzbeat``` + +```或者使用 quay.io (若 dockerhub 网络链接超时)``` + +```docker run -d -p 1157:1157 --name hertzbeat quay.io/tancloud/hertzbeat``` + +2. 浏览器访问 `localhost:1157` 即可开始,默认账号密码 `admin/hertzbeat` + +更多配置详细步骤参考 [通过Docker方式安装HertzBeat](https://hertzbeat.com/docs/start/docker-deploy) + +##### 方式二:通过安装包安装 +1. 下载您系统环境对应的安装包 [GITEE Release](https://gitee.com/dromara/hertzbeat/releases) [GITHUB Release](https://github.com/dromara/hertzbeat/releases) +2. 需要已安装`java11`环境 +3. 配置 HertzBeat 的配置文件 `hertzbeat/config/application.yml`(可选) +4. 部署启动 `$ ./startup.sh ` 或 `startup.bat` +5. 浏览器访问 `localhost:1157` 即可开始,默认账号密码 `admin/hertzbeat` + +更多配置详细步骤参考 [通过安装包安装HertzBeat](https://hertzbeat.com/docs/start/package-deploy) + +##### 方式三:本地代码启动 +1. 此为前后端分离项目,本地代码调试需要分别启动后端工程`manager`和前端工程`web-app` +2. 后端:需要`maven3+`, `java11`和`lombok`环境,修改`YML`配置信息并启动`manager`服务 +3. 前端:需要`nodejs npm angular-cli`环境,待本地后端启动后,在`web-app`目录下启动 `ng serve --open` +4. 浏览器访问 `localhost:4200` 即可开始,默认账号密码 `admin/hertzbeat` + +详细步骤参考 [参与贡献之本地代码启动](https://github.com/dromara/hertzbeat/blob/master/CONTRIBUTING.md) + +##### 方式四:Docker-Compose 统一安装 hertzbeat+mysql+iotdb/tdengine + +通过 [Docker-Compose 部署脚本](https://github.com/dromara/hertzbeat/blob/master/script/docker-compose) 一次性把 mysql 数据库, iotdb/tdengine 时序数据库和 hertzbeat 安装部署。 + +详细步骤参考 [通过Docker-Compose安装HertzBeat](https://github.com/dromara/hertzbeat/blob/master/script/docker-compose/README.md) + +**HAVE FUN** + +## 🥐 路线图 + +![hertzBeat](https://github.com/dromara/hertzbeat/raw/master/home/static/img/docs/hertzbeat-roadmap.png) + +## ✨ Contributors + +Thanks these wonderful people, welcome to join us: +[贡献者指南](https://github.com/dromara/hertzbeat/blob/master/CONTRIBUTING.md) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tomsun28
tomsun28

💻 📖 🎨
会编程的王学长
会编程的王学长

💻 📖 🎨
MaxKey
MaxKey

💻 🎨 🤔
观沧海
观沧海

💻 🎨 🐛
yuye
yuye

💻 📖
jx10086
jx10086

💻 🐛
winnerTimer
winnerTimer

💻 🐛
goo-kits
goo-kits

💻 🐛
brave4Time
brave4Time

💻 🐛
WalkerLee
WalkerLee

💻 🐛
jianghang
jianghang

💻 🐛
ChineseTony
ChineseTony

💻 🐛
wyt199905
wyt199905

💻
卫傅庆
卫傅庆

💻 🐛
zklmcookle
zklmcookle

💻
DevilX5
DevilX5

📖 💻
tea
tea

💻
yangshihui
yangshihui

💻 🐛
DreamGirl524
DreamGirl524

💻 📖
gzwlly
gzwlly

📖
cuipiheqiuqiu
cuipiheqiuqiu

💻 ⚠️ 🎨
lambert
lambert

💻
mroldx
mroldx

📖
woshiniusange
woshiniusange

📖
VampireAchao
VampireAchao

💻
zcx
zcx

💻 🐛 🎨
CharlieXCL
CharlieXCL

📖
Privauto
Privauto

💻 📖
emrys
emrys

📖
SxLiuYu
SxLiuYu

🐛
All Contributors
All Contributors

📖
铁甲小宝
铁甲小宝

💻 📖
click33
click33

📖
蒋小小
蒋小小

📖
Kevin Huang
Kevin Huang

📖
铁甲小宝
铁甲小宝

🐛 💻 📖
Captain Jack
Captain Jack

📖
haibo.duan
haibo.duan

⚠️ 💻
assassin
assassin

🐛 💻
Reverse wind
Reverse wind

⚠️ 💻
luxx
luxx

💻
Ikko Ashimine
Ikko Ashimine

📖
leizenan
leizenan

💻
BKing
BKing

📖
xingshuaiLi
xingshuaiLi

📖
wangke6666
wangke6666

📖
刺猬
刺猬

🐛 💻
Haste
Haste

💻
zhongshi.yi
zhongshi.yi

📖
Qi Zhang
Qi Zhang

📖
MrAndyMing
MrAndyMing

📖
idongliming
idongliming

💻
Zichao Lin
Zichao Lin

💻 📖
liudonghua
liudonghua

💻 🤔
Jerry
Jerry

💻 ⚠️ 🤔
yanhom
yanhom

📖
fsl
fsl

💻
xttttv
xttttv

📖
NavinKumarBarnwal
NavinKumarBarnwal

💻
Zakkary
Zakkary

📖
sunxinbo
sunxinbo

💻 ⚠️
ldzbook
ldzbook

📖 🐛
余与雨
余与雨

💻 ⚠️
MysticalDream
MysticalDream

💻 ⚠️
zhouyoulin12
zhouyoulin12

💻 ⚠️
jerjjj
jerjjj

💻
wjl110
wjl110

💻
Sean
Sean

📖
chenyiqin
chenyiqin

💻 ⚠️
hudongdong129
hudongdong129

💻 ⚠️ 📖
TherChenYang
TherChenYang

💻 ⚠️
HattoriHenzo
HattoriHenzo

💻 ⚠️
ycilry
ycilry

📖
aoshiguchen
aoshiguchen

📖 💻
蔡本祥
蔡本祥

💻
浮游
浮游

💻
Grass-Life
Grass-Life

💻
xiaohe428
xiaohe428

💻 📖
TableRow
TableRow

📖 💻
ByteIDance
ByteIDance

💻
Jangfe
Jangfe

💻
zqr10159
zqr10159

📖 💻
vinci
vinci

💻
js110
js110

💻
CrazyLionLi
CrazyLionLi

📖
banmajio
banmajio

💻
topsuder
topsuder

💻
richar2022
richar2022

💻
fcb-xiaobo
fcb-xiaobo

💻
wenkyzhang
wenkyzhang

📖
ZangJuxy
ZangJuxy

📖
l646505418
l646505418

💻
Carpe-Wang
Carpe-Wang

💻
莫枢
莫枢

💻
huangcanda
huangcanda

💻
世纪末的架构师
世纪末的架构师

💻
ShuningWan
ShuningWan

📖
MrYZhou
MrYZhou

📖
suncqujsj
suncqujsj

📖
sunqinbo
sunqinbo

💻
haoww
haoww

📖
i-mayuan
i-mayuan

📖
fengruge
fengruge

📖
zhanghuan
zhanghuan

💻
shenymin
shenymin

💻
Dhruva Chandra
Dhruva Chandra

💻
miss_z
miss_z

📖
wyt990
wyt990

💻
licocon
licocon

💻
Mi Na
Mi Na

💻
Kylin-Guo
Kylin-Guo

📖
Mr灬Dong先生
Mr灬Dong先生

💻
Pratyay Banerjee
Pratyay Banerjee

📖 💻
yujianzhong520
yujianzhong520

💻
SPPan
SPPan

💻
ZhangJiashu
ZhangJiashu

💻
impress
impress

💻
凌晨一点半
凌晨一点半

📖
Eeshaan Sawant
Eeshaan Sawant

💻
nandofromthebando
nandofromthebando

💻
caiboking
caiboking

💻
baixing99
baixing99

💻
Yang Chuang
Yang Chuang

💻
wlin20
wlin20

💻
guojing1983
guojing1983

💻
moxi
moxi

📖
qq471754603
qq471754603

💻
渭雨
渭雨

💻
liuxuezhuo
liuxuezhuo

💻
lisongning
lisongning

💻
YutingNie
YutingNie

💻
Mike Zhou
Mike Zhou

💻
小笨蛋
小笨蛋

💻
littlezhongzer
littlezhongzer

💻
ChenXiangxxxxx
ChenXiangxxxxx

💻
+ + + + + + +## 💬 社区交流 + +HertzBeat 赫兹跳动是 [Dromara开源社区](https://dromara.org/) 下顶级项目。Gitee GVP。 + +##### 微信交流群 + +加微信号 tan-cloud 或 扫描下面账号二维码拉您进微信群。 +tan-cloud + +##### QQ交流群 + +加QQ群号 236915833 或 扫描下面的群二维码进群 + +tan-cloud + +##### Channel + +[Gitter Channel](https://gitter.im/hertzbeat/community) + +[Github Discussion](https://github.com/dromara/hertzbeat/discussions) + +[User Club](https://support.qq.com/products/379369) + +##### 公众号与星球 + +tan-cloud + +
+ +planet + +##### 友情链接 + +- [DynamicTp](https://github.com/dromara/dynamic-tp) : 轻量级动态线程池,内置监控告警功能,集成三方中间件线程池管理,基于主流配置中心 +- [Hippo4j](https://github.com/opengoofy/hippo4j/) : 强大的动态线程池框架,附带监控报警功能 +- [Jpom](https://gitee.com/dromara/Jpom) : 简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件 +- [ArgusDBM](https://github.com/zmops/ArgusDBM) : 开源数据库一体化监控平台,致力于监控所有数据库 + +##### 赞助 +- Postcat [开源 API 管理工具 ](https://datayi.cn/w/xRxVBBko) 简单可拓展,支持 API 测试、文档、Mock、团队协作等核心功能 +- 感谢 [吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) 赞助服务器采集节点 +- 感谢 [蓝易云(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) 赞助服务器采集节点 + +## 🛡️ License +[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html) \ No newline at end of file diff --git a/hertzbeat/data.yml b/hertzbeat/data.yml new file mode 100644 index 000000000..3b0402512 --- /dev/null +++ b/hertzbeat/data.yml @@ -0,0 +1,20 @@ +name: HertzBeat +tags: + - 工具 +title: 一个易用友好的开源实时监控告警系统 +type: 工具 +description: 一个易用友好的开源实时监控告警系统 +additionalProperties: + key: hertzbeat + name: HertzBeat + tags: + - Tool + shortDescZh: 一个易用友好的开源实时监控告警系统 + shortDescEn: An open source, real-time monitoring system with custom-monitoring + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://hertzbeat.com/ + github: https://github.com/dromara/hertzbeat + document: https://hertzbeat.com/docs/ diff --git a/hertzbeat/logo.png b/hertzbeat/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..abaf6cf1967d1c61040c4d59842bc291552a72c4 GIT binary patch literal 12501 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 literal 0 HcmV?d00001 diff --git a/it-tools/2023.5.14-77f2efc/data.yml b/it-tools/2023.5.14-77f2efc/data.yml new file mode 100644 index 000000000..3d4bb50ef --- /dev/null +++ b/it-tools/2023.5.14-77f2efc/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40116 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/it-tools/2023.5.14-77f2efc/docker-compose.yml b/it-tools/2023.5.14-77f2efc/docker-compose.yml new file mode 100644 index 000000000..ed79a50eb --- /dev/null +++ b/it-tools/2023.5.14-77f2efc/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3' +services: + it-tools: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:80" + image: corentinth/it-tools:2023.5.14-77f2efc + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/it-tools/README.md b/it-tools/README.md new file mode 100644 index 000000000..828f8309b --- /dev/null +++ b/it-tools/README.md @@ -0,0 +1,120 @@ +![logo](https://github.com/CorentinTh/it-tools/raw/main/.github/logo.png) + +Useful tools for developer and people working in IT. [Have a look !](https://it-tools.tech). + +## Functionalities and roadmap + +Please check the [issues](https://github.com/CorentinTh/it-tools/issues) to see if some feature listed to be implemented. + +You have an idea of a tool? Submit a [feature request](https://github.com/CorentinTh/it-tools/issues/new/choose)! + +## Self host + +Self host solutions for your homelab + +**From docker hub:** + +```sh +docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-tools:latest +``` + +**From github packages:** + +```sh +docker run -d --name it-tools --restart unless-stopped -p 8080:80 ghcr.io/corentinth/it-tools:latest +``` + +**Other solutions:** + +- [Tipi](https://www.runtipi.io/docs/apps-available) +- [Unraid](https://unraid.net/community/apps?q=it-tools) + +## Contribute + +### Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) with the following extensions: +- [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) +- [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) +- [i18n Ally](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) + +with the following settings: + +```json5 +{ + "editor.formatOnSave": false, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "i18n-ally.localesPaths": [ + "locales", + "src/tools/*/locales" + ], + "i18n-ally.keystyle": "nested" +} +``` + +### Type Support for `.vue` Imports in TS + +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. + +If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: + +1. Disable the built-in TypeScript Extension + 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette + 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` +2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. + +### Project Setup + +```sh +pnpm install +``` + +### Compile and Hot-Reload for Development + +```sh +pnpm dev +``` + +### Type-Check, Compile and Minify for Production + +```sh +pnpm build +``` + +### Run Unit Tests with [Vitest](https://vitest.dev/) + +```sh +pnpm test +``` + +### Lint with [ESLint](https://eslint.org/) + +```sh +pnpm lint +``` + +### Create a new tool + +To create a new tool, there is a script that generate the boilerplate of the new tool, simply run: + +```sh +pnpm run script:create-new-tool my-tool-name +``` + +It will create a directory in `src/tools` with the correct files, and a the import in `src/tools/index.ts`. You will just need to add the imported tool in the proper category and develop the tool. + +## Credits + +Coded with ❤️ by [Corentin Thomasset](https://corentin-thomasset.fr/). + +This project is continuously deployed using [vercel.com](https://vercel.com). + +IT Tools - Collection of handy online tools for devs, with great UX | Product Hunt +IT Tools - Collection of handy online tools for devs, with great UX | Product Hunt + +## License + +This project is under the [GNU GPLv3](https://github.com/CorentinTh/it-tools/blob/main/LICENSE). diff --git a/it-tools/data.yml b/it-tools/data.yml new file mode 100644 index 000000000..36f8b73d9 --- /dev/null +++ b/it-tools/data.yml @@ -0,0 +1,20 @@ +name: IT-Tools +tags: + - 工具 +title: 为开发人员提供方便的在线工具集合,具有出色的用户体验 +type: 工具 +description: 为开发人员提供方便的在线工具集合,具有出色的用户体验 +additionalProperties: + key: it-tools + name: IT-Tools + tags: + - Tool + shortDescZh: 为开发人员提供方便的在线工具集合,具有出色的用户体验 + shortDescEn: Collection of handy online tools for developers, with great UX + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://it-tools.tech + github: https://github.com/CorentinTh/it-tools + document: https://github.com/CorentinTh/it-tools diff --git a/it-tools/logo.png b/it-tools/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac104d0e418364bda188d3a2fe13d4dea3e279e GIT binary patch literal 5551 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 literal 0 HcmV?d00001 diff --git a/kodbox/1.4104/data.yml b/kodbox/1.4104/data.yml new file mode 100755 index 000000000..fef861e2a --- /dev/null +++ b/kodbox/1.4104/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 8081 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/kodbox/1.4104/docker-compose.yml b/kodbox/1.4104/docker-compose.yml new file mode 100644 index 000000000..7fb59f708 --- /dev/null +++ b/kodbox/1.4104/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3.5" + +services: + kodbox: + image: kodcloud/kodbox:v1.4104 + container_name: ${CONTAINER_NAME} + ports: + - ${PANEL_APP_PORT_HTTP}:80 + volumes: + - "./site:/var/www/html" + restart: always + labels: + createdBy: "Apps" + networks: + - 1panel-network +networks: + 1panel-network: + external: true diff --git a/navidrome/README.md b/navidrome/README.md new file mode 100644 index 000000000..43b2ff0d1 --- /dev/null +++ b/navidrome/README.md @@ -0,0 +1,93 @@ +# 使用说明 + +容器以普通用户身份运行的, + +但是默认面板创建应用时,可能会将所需的数据文件夹设定身份为`root`,导致首次运行异常。 + +不用在意,执行以下命令,将文件夹改成普通用户身份,再重建应用即可。 + +- 路径注意按需修改 +``` +chown -R 1000:1000 /opt/1panel/apps/local/navidrome/navidrome/data +``` + +# 原始相关 + +Navidrome logo + +# Navidrome Music Server  [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Tired%20of%20paying%20for%20music%20subscriptions%2C%20and%20not%20finding%20what%20you%20really%20like%3F%20Roll%20your%20own%20streaming%20service%21&url=https://navidrome.org&via=navidrome) + +[![Last Release](https://img.shields.io/github/v/release/navidrome/navidrome?logo=github&label=latest&style=flat-square)](https://github.com/navidrome/navidrome/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/navidrome/navidrome/pipeline.yml?branch=master&logo=github&style=flat-square)](https://nightly.link/navidrome/navidrome/workflows/pipeline/master) +[![Downloads](https://img.shields.io/github/downloads/navidrome/navidrome/total?logo=github&style=flat-square)](https://github.com/navidrome/navidrome/releases/latest) +[![Docker Pulls](https://img.shields.io/docker/pulls/deluan/navidrome?logo=docker&label=pulls&style=flat-square)](https://hub.docker.com/r/deluan/navidrome) +[![Dev Chat](https://img.shields.io/discord/671335427726114836?logo=discord&label=discord&style=flat-square)](https://discord.gg/xh7j7yF) +[![Subreddit](https://img.shields.io/reddit/subreddit-subscribers/navidrome?logo=reddit&label=/r/navidrome&style=flat-square)](https://www.reddit.com/r/navidrome/) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0-ff69b4.svg?style=flat-square)](CODE_OF_CONDUCT.md) + +Navidrome is an open source web-based music collection server and streamer. It gives you freedom to listen to your +music collection from any browser or mobile device. It's like your personal Spotify! + + +**Note**: The `master` branch may be in an unstable or even broken state during development. +Please use [releases](https://github.com/navidrome/navidrome/releases) instead of +the `master` branch in order to get a stable set of binaries. + +## [Check out our Live Demo!](https://www.navidrome.org/demo/) + +__Any feedback is welcome!__ If you need/want a new feature, find a bug or think of any way to improve Navidrome, +please file a [GitHub issue](https://github.com/navidrome/navidrome/issues) or join the discussion in our +[Subreddit](https://www.reddit.com/r/navidrome/). If you want to contribute to the project in any other way +([ui/backend dev](https://www.navidrome.org/docs/developers/), +[translations](https://www.navidrome.org/docs/developers/translations/), +[themes](https://www.navidrome.org/docs/developers/creating-themes)), please join the chat in our +[Discord server](https://discord.gg/xh7j7yF). + +## Installation + +See instructions on the [project's website](https://www.navidrome.org/docs/installation/) + +## Cloud Hosting + +[PikaPods](https://www.pikapods.com) has partnered with us to offer you an +[officially supported, cloud-hosted solution](https://www.navidrome.org/docs/installation/managed/#pikapods). +A share of the revenue helps fund the development of Navidrome at no additional cost for you. + +[![PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=navidrome) + +## Features + + - Handles very **large music collections** + - Streams virtually **any audio format** available + - Reads and uses all your beautifully curated **metadata** + - Great support for **compilations** (Various Artists albums) and **box sets** (multi-disc albums) + - **Multi-user**, each user has their own play counts, playlists, favourites, etc... + - Very **low resource usage** + - **Multi-platform**, runs on macOS, Linux and Windows. **Docker** images are also provided + - Ready to use binaries for all major platforms, including **Raspberry Pi** + - Automatically **monitors your library** for changes, importing new files and reloading new metadata + - **Themeable**, modern and responsive **Web interface** based on [Material UI](https://material-ui.com) + - **Compatible** with all Subsonic/Madsonic/Airsonic [clients](https://www.navidrome.org/docs/overview/#apps) + - **Transcoding** on the fly. Can be set per user/player. **Opus encoding is supported** + - Translated to **various languages** + +## Documentation +All documentation can be found in the project's website: https://www.navidrome.org/docs. +Here are some useful direct links: + +- [Overview](https://www.navidrome.org/docs/overview/) +- [Installation](https://www.navidrome.org/docs/installation/) + - [Docker](https://www.navidrome.org/docs/installation/docker/) + - [Binaries](https://www.navidrome.org/docs/installation/pre-built-binaries/) + - [Build from source](https://www.navidrome.org/docs/installation/build-from-source/) +- [Development](https://www.navidrome.org/docs/developers/) +- [Subsonic API Compatibility](https://www.navidrome.org/docs/developers/subsonic-api/) + +## Screenshots + +

+ + + + +

diff --git a/navidrome/data.yml b/navidrome/data.yml new file mode 100644 index 000000000..90c2b8c35 --- /dev/null +++ b/navidrome/data.yml @@ -0,0 +1,20 @@ +name: Navidrome Music Server +tags: + - 工具 +title: 基于 Web 的开源音乐收藏服务器和流媒体 +type: 工具 +description: 基于 Web 的开源音乐收藏服务器和流媒体 +additionalProperties: + key: navidrome + name: Navidrome Music Server + tags: + - Tool + shortDescZh: 基于 Web 的开源音乐收藏服务器和流媒体 + shortDescEn: An open source web-based music collection server and streamer + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://www.navidrome.org + github: https://github.com/navidrome/navidrome + document: https://www.navidrome.org/docs \ No newline at end of file diff --git a/navidrome/logo.png b/navidrome/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7abd45d407296135879b92ec724f175006c196bc GIT binary patch literal 17522 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 N002ovPDHLkV1jcUcI*HE literal 0 HcmV?d00001 diff --git a/navidrome/pr-2295/data.yml b/navidrome/pr-2295/data.yml new file mode 100644 index 000000000..6d42f51ff --- /dev/null +++ b/navidrome/pr-2295/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 40108 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: ./data/music + edit: true + envKey: MUSIC_PATH + labelEn: Music folder path + labelZh: 音乐文件夹路径 + required: true + type: text diff --git a/navidrome/pr-2295/docker-compose.yml b/navidrome/pr-2295/docker-compose.yml new file mode 100644 index 000000000..946325e0b --- /dev/null +++ b/navidrome/pr-2295/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3' +services: + navidrome: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:4533" + volumes: + - "./data/data:/data" + - "${MUSIC_PATH}:/music:ro" + environment: + ND_SCANSCHEDULE: 1h + ND_LOGLEVEL: info + ND_SESSIONTIMEOUT: 24h + ND_BASEURL: "" + user: 1000:1000 + image: deluan/navidrome:pr-2295 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/next-terminal/1.3.9/data.yml b/next-terminal/1.3.9/data.yml new file mode 100644 index 000000000..56966e4f8 --- /dev/null +++ b/next-terminal/1.3.9/data.yml @@ -0,0 +1,32 @@ +additionalProperties: + formFields: + - default: 40058 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: '' + edit: true + envKey: PANEL_APP_PORT_SSH + labelEn: SSH Port + labelZh: SSH端口 + required: false + rule: paramPort + type: number + - default: "false" + edit: true + envKey: SSHD_SWITCH + labelEn: Enable SSH (true or false) + labelZh: 启用SSH (true/false) + required: true + type: text + - default: ./ssh/id_rsa + edit: true + envKey: SSH_KEY_PATH + labelEn: SSH key file(/root/.ssh/id_rsa) + labelZh: SSH 私钥文件(/root/.ssh/id_rsa) + required: true + type: text diff --git a/next-terminal/1.3.9/docker-compose.yml b/next-terminal/1.3.9/docker-compose.yml new file mode 100644 index 000000000..0500edf9b --- /dev/null +++ b/next-terminal/1.3.9/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3' +services: + nt-guacd: + container_name: ${CONTAINER_NAME}-guacd + restart: always + networks: + - 1panel-network + volumes: + - "./data:/usr/local/next-terminal/data" + image: dushixiang/guacd:1.5.2 + labels: + createdBy: "Apps" + + next-terminal: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:8088" + - "${PANEL_APP_PORT_SSH}:8089" + volumes: + - "./data:/usr/local/next-terminal/data" + - "/etc/localtime:/etc/localtime" + - "${SSH_KEY_PATH}:/root/.ssh/id_rsa" + environment: + DB: sqlite + GUACD_HOSTNAME: nt-guacd + GUACD_PORT: 4822 + SSHD_ENABLE: ${SSHD_SWITCH} + image: dushixiang/next-terminal:v1.3.9 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true \ No newline at end of file diff --git a/next-terminal/1.3.9/ssh/id_rsa b/next-terminal/1.3.9/ssh/id_rsa new file mode 100644 index 000000000..fe7575508 --- /dev/null +++ b/next-terminal/1.3.9/ssh/id_rsa @@ -0,0 +1,49 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +-----END OPENSSH PRIVATE KEY----- diff --git a/next-terminal/README.md b/next-terminal/README.md new file mode 100644 index 000000000..040a9d3d2 --- /dev/null +++ b/next-terminal/README.md @@ -0,0 +1,73 @@ +# Next Terminal + +[![Docker guacd build](https://github.com/dushixiang/next-terminal/actions/workflows/docker-guacd.yml/badge.svg)](https://github.com/dushixiang/next-terminal/actions/workflows/docker-guacd.yml) +[![Docker next-terminal build](https://github.com/dushixiang/next-terminal/actions/workflows/docker-next-terminal.yml/badge.svg)](https://github.com/dushixiang/next-terminal/actions/workflows/docker-next-terminal.yml) + +## 快速了解 + +Next Terminal是一个简单好用安全的开源交互审计系统,支持RDP、SSH、VNC、Telnet、Kubernetes协议。 + +目前支持的功能有: + +- 授权凭证管理 +- 资产管理(支持RDP、SSH、VNC、TELNET协议) +- 指令管理 +- 批量执行命令 +- 在线会话管理(监控、强制断开) +- 离线会话管理(查看录屏) +- 双因素认证 +- 资产标签 +- 资产授权 +- 多用户&用户分组 +- 计划任务 +- ssh server +- 登录策略 +- 系统监控 + +## 在线体验 + +**web** + +https://next.typesafe.cn/ 账号:test 密码:test + +**ssh server** + +主机:next.typesafe.cn +端口:2022 +账号:test 密码:test + +## 协议与条款 + +如您需要在企业网络中使用 next-terminal,建议先征求 IT 管理员的同意。下载、使用或分发 next-terminal 前,您必须同意 [协议](./LICENSE) 条款与限制。本项目不提供任何担保,亦不承担任何责任。 + +## 快速安装 + +- [安装文档](https://next-terminal.typesafe.cn) + +默认账号密码为 admin/admin 。 + +## 手动编译 + +1. 找一台Linux 机器或者Mac +2. 安装 go 1.18 或以上版本 +3. 安装 nodejs 16,安装 npm 或 yarn +4. 进入 web 目录 执行 yarn 或 npm install +5. 返回上级目录,也就是项目根目录,执行 sh build.sh + +## 问题反馈 + +- Issues +- 微信群 加我微信拉你进群 (请备注 next-terminal) + + + +- QQ群 938145268 +- Telegram https://t.me/next_terminal + +## 安全问题 + +如果您在使用过程中发现了安全问题,请发送邮件至 helloworld1024@foxmail.com 联系我,谢谢。 + +## License + +Next Terminal 使用 [AGPL-3.0](./LICENSE) 开源协议,请自觉遵守。 \ No newline at end of file diff --git a/next-terminal/data.yml b/next-terminal/data.yml new file mode 100644 index 000000000..9eaa7223a --- /dev/null +++ b/next-terminal/data.yml @@ -0,0 +1,20 @@ +name: Next Terminal +tags: + - 工具 +title: 一个简单好用安全的开源交互审计系统,支持RDP、SSH、VNC、Telnet、Kubernetes协议 +type: 工具 +description: 一个简单好用安全的开源交互审计系统,支持RDP、SSH、VNC、Telnet、Kubernetes协议 +additionalProperties: + key: next-terminal + name: Next Terminal + tags: + - Tool + shortDescZh: 一个简单好用安全的开源交互审计系统,支持RDP、SSH、VNC、Telnet、Kubernetes协议 + shortDescEn: A simple, easy-to-use and secure open source interactive audit system that supports RDP, SSH, VNC, Telnet, and Kubernetes protocols + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://next-terminal.typesafe.cn/ + github: https://github.com/dushixiang/next-terminal + document: https://next-terminal.typesafe.cn/docs/ diff --git a/next-terminal/logo.png b/next-terminal/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a67631280f2f69e1a871434bba4792ba5c34e52 GIT binary patch literal 5592 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 literal 0 HcmV?d00001 diff --git a/onedev/8.6.12/data.yml b/onedev/8.6.12/data.yml new file mode 100644 index 000000000..00f263aab --- /dev/null +++ b/onedev/8.6.12/data.yml @@ -0,0 +1,18 @@ +additionalProperties: + formFields: + - default: 40085 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: 40086 + edit: true + envKey: PANEL_APP_PORT_SSH + labelEn: SSH Port + labelZh: SSH端口 + required: true + rule: paramPort + type: number diff --git a/onedev/8.6.12/docker-compose.yml b/onedev/8.6.12/docker-compose.yml new file mode 100644 index 000000000..fc991f1e8 --- /dev/null +++ b/onedev/8.6.12/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3' +services: + onedev: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:6610" + - "${PANEL_APP_PORT_SSH}:6611" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - "./data:/opt/onedev" + image: 1dev/server:8.6.12 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/onedev/README.md b/onedev/README.md new file mode 100644 index 000000000..b74c10d15 --- /dev/null +++ b/onedev/README.md @@ -0,0 +1,140 @@ +
+ +> **Note** +> 1. Do not worry about security advisories above. They are fixed as soon as discovered and published to notify users +> 2. We develop OneDev at code.onedev.io for sake of dogfooding. All issues and pull requests should be submitted there + +
+ +
+

Self-hosted Git Server with Kanban and CI/CD

+ +

+Quickstart +| Installation Guide +| All Documentation +

+ +

+

+ +## Out-of-box Symbol Search and Navigation + +Of course IDE is good at doing this, but often we need to search in old commits (investigate issues in release versions etc), and switching commits in IDE can be troublesome and slow.  + +It works by analyzing source code with ANTLR, extracting symbols for storage incrementally, fast and space efficient. Now supports Java, JavaScript, C, C++, CSharp, Go, PHP, Python, CSS, SCSS, LESS and R. GitHub adds this feature several years ago, but seems that it only works for main branch, and GitLab has to configure CI job to generate and upload LSIF which is troublesome and can occupy considerable space if you do it for each commit. + +You can also jump to symbol definition in diff while reviewing commits or pull requests. + +![searchsymbol](https://github.com/theonedev/onedev/raw/main/doc/images/search-symbol.gif) + +![jumpsymbol](https://github.com/theonedev/onedev/raw/main/doc/images/symbol.gif) + +## Code Search with Regular Expression + +You may switch to any commit, and search code with regular expression. OneDev under the hood indexes the code with Lucene incrementally. At search time, literal tri-grams in the regular expression are extracted for a coarse search, followed by exact match in the result. This makes the regex search blazing fast, even for large repositories like Linux. + +![regex](https://github.com/theonedev/onedev/raw/main/doc/images/regex-search.gif) + +## Annotate Source/Diff with Static Analysis Result to Facilitate Code Review + +Of course this can be done by many third party applications at GitHub, however they display the result on their own applications, and this makes review activities such as adding comment over analysis result difficult. Not to mention that you need to pay for these services. + +![annotation](https://github.com/theonedev/onedev/raw/main/doc/images/annotation.png) + +## Customizable Issue State and Field, with Deep CI/CD Integration + +The simple open/close state of GitHub/GitLab issues does not work well for many workflows. Considering issues submitted by customers: + +1. If developer closes issue upon committing the code, customer will be notified and may ask for the release fixing the issue. +2. If developer closes the issue at release time, QA might be confused at what issues to test as they all remain open at test time.  + +With customizable issue states, we may address the issue with four states: open, committed, test ready and released: + +1. When code is committed, issue transits to committed state automatically +2. When a test build is created and deployed, the issue transits to test ready state automatically. QA will be notified and can check issue detail to know which environment the test build is deployed into. +3. When test passes, and a release build is created, customers submitting the issue will be notified and they can check issue detail to see which release contains the fix. + +![boards](https://github.com/theonedev/onedev/raw/main/doc/images/boards.png) + +![fixing-build](https://github.com/theonedev/onedev/raw/main/doc/images/fixing-build.png) + +## Service Desk to Create/Discuss Issues via Email + +Service desk allows your users to submit tickets via email without the need to have a OneDev account. These tickets can then be created in desired projects, and assigned to appropriate members in your team. All further discussions over the tickets can take place completely in email, with discussion contents posted to ticket as comments. User will also get notifications when there are any ticket activities, for instance, when a relevant release is created or deployed + +![service-desk.png](https://github.com/theonedev/onedev/raw/main/doc/images/service-desk.png) + +## A powerful and Intuitive Query Language + +Thanks to ANTLR again, OneDev ships sophisticated query languages for projects, commits, issues, builds, and pull requests, with intuitive auto-completions and hints. For instance, it enables our customers finding fixed issues between their running release and latest release, and enables us to find all commits submitted by someone touching specified modules, etc.  + +Queries can be saved and subscribed, so that you won't miss anything interested. + +![query](https://github.com/theonedev/onedev/raw/main/doc/images/query.gif) + +## A Full-fledge CI/CD Engine without Writing Yaml + +OneDev ships with GUI to generate CI/CD Yaml. No need to google around for Yaml grammars. A one-liner docker command to start OneDev server and you have a local CI/CD runner automatically. Concerns about server capability to run massive jobs? Another one-liner to connect self-updating agent from any machine. Want auto-scale CI/CD farm? A helm one-liner to deploy OneDev into k8s cluster.  + +Build pipeline, matrix jobs, typed parameters, parameter chaining, step templates, build promotions… too many neat features to elaborate… + +![job-def](https://github.com/theonedev/onedev/raw/main/doc/images/job-command.gif) + +![run-job](https://github.com/theonedev/onedev/raw/main/doc/images/build-option.gif) + +![pipeline.gif](https://github.com/theonedev/onedev/raw/main/doc/images/pipeline.gif) + +## Flexible Pull Request Review Policy and Reviewer Suggestion + +Specify pull request review policy based on author, branch, and changed files. OneDev can leverage git change history to suggest most appropriate reviewers for pull requests touching certain files. + +![review-policy](https://github.com/theonedev/onedev/raw/main/doc/images/review-policy.gif) + +## Lightweight Review without Pull Request + +Comment on any part of code or diff to start a lightweight review without opening pull request. Review comments live through code modification and even file rename to serve as documentation.  + +Each discussion is threaded so that you can easily know discussions with new comments/updates. + +![file-comment](https://github.com/theonedev/onedev/raw/main/doc/images/file-comment.gif) + +![thread-comments](https://github.com/theonedev/onedev/raw/main/doc/images/threaded-comments.png) + +## Command Palette to Access Features Quickly + +Press cmd/ctrl-k to bring up command palette from anywhere. Search projects, files, issues, pull requests, builds, and various settings and jump to them without leaving your keyboard + +![command-palette.gif](https://github.com/theonedev/onedev/raw/main/doc/images/command-palette.gif) + +## Write Markdown Pleasantly With a Smart Editor + +When embedding an image in a markdown file in GitHub/GitLab, you need to upload the image in a separate page, and then figure out the relative path to reference that image. With OneDev, you simply upload the image to desired folder in same editor, and the link will be generated automatically.  + +OneDev tracks your cursor in edit window and scrolls the preview window as necessary so that you can always preview what you are typing. + +![markdown](https://github.com/theonedev/onedev/raw/main/doc/images/markdown.gif) + +## SLOC Trend By Language + +OneDev inspects git history of main branch to calculate trend of source lines of code by language efficiently. + +![stats](https://github.com/theonedev/onedev/raw/main/doc/images/stats.png) + +## Project Hierarchy to Facilitate Setting Inheritance + +Organization is ideal for public service. However for self-hosted internal use, we feel that a hierarchical structure is more practical to organize projects. Child projects can inherit settings from parent project and can selectively override some of them if necessary. This reduces a lot of overhead to manage a lot of projects in the company. + +## Fast and Reliable with Moderate Resource Usage + +OneDev is carefully designed with performance in mind. With a 2 core 2GB box, you will get all features above for medium sized projects. +It has been intensively used for more than 5 years, with battle-proven reliability. Fixing bugs is our highest priority, and there is +normally few to no known bugs in the wild. + +---- + +# Special Thanks + +![yourkit](https://www.yourkit.com/images/yklogo.png) + +[YourKit](https://yourkit.com) supports this project by providing a free open source license of their excellent Java profiler \ No newline at end of file diff --git a/onedev/data.yml b/onedev/data.yml new file mode 100644 index 000000000..d188a74ad --- /dev/null +++ b/onedev/data.yml @@ -0,0 +1,20 @@ +name: OneDev +tags: + - CI/CD +title: 具有 CI/CD 和Kanban的自托管 Git 服务器 +type: CI/CD +description: 具有 CI/CD 和Kanban的自托管 Git 服务器 +additionalProperties: + key: onedev + name: OneDev + tags: + - CI/CD + shortDescZh: 具有 CI/CD 和Kanban的自托管 Git 服务器 + shortDescEn: Self-hosted Git Server with CI/CD and Kanban + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://onedev.io + github: https://github.com/theonedev/onedev + document: https://docs.onedev.io \ No newline at end of file diff --git a/onedev/logo.png b/onedev/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e63903103a16e022ef1c8f2b7f4d4f589fffd0f3 GIT binary patch literal 5285 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 TTK%8xh=-@AZKzeJ;Q;v`;hi%E literal 0 HcmV?d00001 diff --git a/openlitespeed/1.7.18-lsphp74/data.yml b/openlitespeed/1.7.18-lsphp74/data.yml new file mode 100644 index 000000000..98939c0e1 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data.yml @@ -0,0 +1,33 @@ +additionalProperties: + formFields: + - default: 80 + disabled: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: 443 + disabled: true + envKey: PANEL_APP_PORT_HTTPS + labelEn: HTTPS Port + labelZh: HTTPS端口 + required: true + rule: paramPort + type: number + - default: 40113 + edit: true + envKey: PANEL_APP_PORT_CONSOLE + labelEn: Console Port + labelZh: 控制台端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TIME_ZONE + labelEn: Time zone + labelZh: 时区 + required: true + type: text diff --git a/openlitespeed/1.7.18-lsphp74/data/bin/container/appinstallctl.sh b/openlitespeed/1.7.18-lsphp74/data/bin/container/appinstallctl.sh new file mode 100644 index 000000000..d79c63f11 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/bin/container/appinstallctl.sh @@ -0,0 +1,660 @@ +#!/bin/bash +DEFAULT_VH_ROOT='/var/www/vhosts' +VH_DOC_ROOT='' +VHNAME='' +APP_NAME='' +DOMAIN='' +WWW_UID='' +WWW_GID='' +WP_CONST_CONF='' +PUB_IP=$(curl -s http://checkip.amazonaws.com) +DB_HOST='mysql' +PLUGINLIST="litespeed-cache.zip" +THEME='twentytwenty' +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-A, -app [wordpress] -D, --domain [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Example: appinstallctl.sh --app wordpress --domain example.com" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +linechange(){ + LINENUM=$(grep -n "${1}" ${2} | cut -d: -f 1) + if [ -n "${LINENUM}" ] && [ "${LINENUM}" -eq "${LINENUM}" ] 2>/dev/null; then + sed -i "${LINENUM}d" ${2} + sed -i "${LINENUM}i${3}" ${2} + fi +} + +ck_ed(){ + if [ ! -f /bin/ed ]; then + echo "Install ed package.." + apt-get install ed -y > /dev/null 2>&1 + fi +} + +ck_unzip(){ + if [ ! -f /usr/bin/unzip ]; then + echo "Install unzip package.." + apt-get install unzip -y > /dev/null 2>&1 + fi +} + +get_owner(){ + WWW_UID=$(stat -c "%u" ${DEFAULT_VH_ROOT}) + WWW_GID=$(stat -c "%g" ${DEFAULT_VH_ROOT}) + if [ ${WWW_UID} -eq 0 ] || [ ${WWW_GID} -eq 0 ]; then + WWW_UID=1000 + WWW_GID=1000 + echo "Set owner to ${WWW_UID}" + fi +} + +get_db_pass(){ + if [ -f ${DEFAULT_VH_ROOT}/${1}/.db_pass ]; then + SQL_DB=$(grep -i Database ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + SQL_USER=$(grep -i Username ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + SQL_PASS=$(grep -i Password ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + else + echo 'db pass file can not locate, skip wp-config pre-config.' + fi +} + +set_vh_docroot(){ + if [ "${VHNAME}" != '' ]; then + VH_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}" + VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}/html" + WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini" + elif [ -d ${DEFAULT_VH_ROOT}/${1}/html ]; then + VH_ROOT="${DEFAULT_VH_ROOT}/${1}" + VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${1}/html" + WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini" + else + echo "${DEFAULT_VH_ROOT}/${1}/html does not exist, please add domain first! Abort!" + exit 1 + fi +} + +check_sql_native(){ + local COUNTER=0 + local LIMIT_NUM=100 + until [ "$(curl -v mysql:3306 2>&1 | grep -i 'native\|Connected')" ]; do + echo "Counter: ${COUNTER}/${LIMIT_NUM}" + COUNTER=$((COUNTER+1)) + if [ ${COUNTER} = 10 ]; then + echo '--- MySQL is starting, please wait... ---' + elif [ ${COUNTER} = ${LIMIT_NUM} ]; then + echo '--- MySQL is timeout, exit! ---' + exit 1 + fi + sleep 1 + done +} + +install_wp_plugin(){ + for PLUGIN in ${PLUGINLIST}; do + wget -q -P ${VH_DOC_ROOT}/wp-content/plugins/ https://downloads.wordpress.org/plugin/${PLUGIN} + if [ ${?} = 0 ]; then + ck_unzip + unzip -qq -o ${VH_DOC_ROOT}/wp-content/plugins/${PLUGIN} -d ${VH_DOC_ROOT}/wp-content/plugins/ + else + echo "${PLUGINLIST} FAILED to download" + fi + done + rm -f ${VH_DOC_ROOT}/wp-content/plugins/*.zip +} + +set_htaccess(){ + if [ ! -f ${VH_DOC_ROOT}/.htaccess ]; then + touch ${VH_DOC_ROOT}/.htaccess + fi + cat << EOM > ${VH_DOC_ROOT}/.htaccess +# BEGIN WordPress + +RewriteEngine On +RewriteBase / +RewriteRule ^index\.php$ - [L] +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . /index.php [L] + +# END WordPress +EOM +} + +get_theme_name(){ + THEME_NAME=$(grep WP_DEFAULT_THEME ${VH_DOC_ROOT}/wp-includes/default-constants.php | grep -v '!' | awk -F "'" '{print $4}') + echo "${THEME_NAME}" | grep 'twenty' >/dev/null 2>&1 + if [ ${?} = 0 ]; then + THEME="${THEME_NAME}" + fi +} + +set_lscache(){ + cat << EOM > "${WP_CONST_CONF}" +; +; This is the predefined default LSCWP configuration file +; +; All the keys and values please refer \`src/const.cls.php\` +; +; Comments start with \`;\` +; +;; -------------------------------------------------- ;; +;; -------------- General ----------------- ;; +;; -------------------------------------------------- ;; +; O_AUTO_UPGRADE +auto_upgrade = false +; O_API_KEY +api_key = '' +; O_SERVER_IP +server_ip = '' +; O_NEWS +news = false +;; -------------------------------------------------- ;; +;; -------------- Cache ----------------- ;; +;; -------------------------------------------------- ;; +cache-priv = true +cache-commenter = true +cache-rest = true +cache-page_login = true +cache-favicon = true +cache-resources = true +cache-browser = false +cache-mobile = false +cache-mobile_rules = 'Mobile +Android +Silk/ +Kindle +BlackBerry +Opera Mini +Opera Mobi' +cache-exc_useragents = '' +cache-exc_cookies = '' +cache-exc_qs = '' +cache-exc_cat = '' +cache-exc_tag = '' +cache-force_uri = '' +cache-force_pub_uri = '' +cache-priv_uri = '' +cache-exc = '' +cache-exc_roles = '' +cache-drop_qs = 'fbclid +gclid +utm* +_ga' +cache-ttl_pub = 604800 +cache-ttl_priv = 1800 +cache-ttl_frontpage = 604800 +cache-ttl_feed = 604800 +; O_CACHE_TTL_REST +cache-ttl_rest = 604800 +cache-ttl_browser = 31557600 +cache-login_cookie = '' +cache-vary_group = '' +cache-ttl_status = '403 3600 +404 3600 +500 3600' +;; -------------------------------------------------- ;; +;; -------------- Purge ----------------- ;; +;; -------------------------------------------------- ;; +; O_PURGE_ON_UPGRADE +purge-upgrade = true +; O_PURGE_STALE +purge-stale = true +purge-post_all = false +purge-post_f = true +purge-post_h = true +purge-post_p = true +purge-post_pwrp = true +purge-post_a = true +purge-post_y = false +purge-post_m = true +purge-post_d = false +purge-post_t = true +purge-post_pt = true +purge-timed_urls = '' +purge-timed_urls_time = '' +purge-hook_all = 'switch_theme +wp_create_nav_menu +wp_update_nav_menu +wp_delete_nav_menu +create_term +edit_terms +delete_term +add_link +edit_link +delete_link' +;; -------------------------------------------------- ;; +;; -------------- ESI ----------------- ;; +;; -------------------------------------------------- ;; +; O_ESI +esi = false +; O_ESI_CACHE_ADMBAR +esi-cache_admbar = true +; O_ESI_CACHE_COMMFORM +esi-cache_commform = true +; O_ESI_NONCE +esi-nonce = 'stats_nonce +subscribe_nonce' +;; -------------------------------------------------- ;; +;; -------------- Utilities ----------------- ;; +;; -------------------------------------------------- ;; +util-heartbeat = true +util-instant_click = false +util-check_advcache = true +util-no_https_vary = false +;; -------------------------------------------------- ;; +;; -------------- Debug ----------------- ;; +;; -------------------------------------------------- ;; +; O_DEBUG_DISABLE_ALL +debug-disable_all = false +; O_DEBUG +debug = false +; O_DEBUG_IPS +debug-ips = '127.0.0.1' +; O_DEBUG_LEVEL +debug-level = false +; O_DEBUG_FILESIZE +debug-filesize = 3 +; O_DEBUG_COOKIE +debug-cookie = false +; O_DEBUG_COLLAPS_QS +debug-collaps_qs = false +; O_DEBUG_INC +debug-inc = '' +; O_DEBUG_EXC +debug-exc = '' +;; -------------------------------------------------- ;; +;; -------------- DB Optm ----------------- ;; +;; -------------------------------------------------- ;; +; O_DB_OPTM_REVISIONS_MAX +db_optm-revisions_max = 0 +; O_DB_OPTM_REVISIONS_AGE +db_optm-revisions_age = 0 +;; -------------------------------------------------- ;; +;; -------------- HTML Optm ----------------- ;; +;; -------------------------------------------------- ;; +; O_OPTM_CSS_MIN +optm-css_min = false +optm-css_inline_min = false +; O_OPTM_CSS_COMB +optm-css_comb = false +optm-css_comb_priority = false +; O_OPTM_CSS_HTTP2 +optm-css_http2 = false +optm-css_exc = '' +; O_OPTM_JS_MIN +optm-js_min = false +optm-js_inline_min = false +; O_OPTM_JS_COMB +optm-js_comb = false +optm-js_comb_priority = false +; O_OPTM_JS_HTTP2 +optm-js_http2 = false +; O_OPTM_EXC_JQ +optm-js_exc = '' +optm-ttl = 604800 +optm-html_min = false +optm-qs_rm = false +optm-ggfonts_rm = false +; O_OPTM_CSS_ASYNC +optm-css_async = false +; O_OPTM_CCSS_GEN +optm-ccss_gen = true +; O_OPTM_CCSS_ASYNC +optm-ccss_async = true +; O_OPTM_CSS_ASYNC_INLINE +optm-css_async_inline = true +; O_OPTM_CSS_FONT_DISPLAY +optm-css_font_display = false +; O_OPTM_JS_DEFER +optm-js_defer = false +; O_OPTM_JS_INLINE_DEFER +optm-js_inline_defer = false +optm-emoji_rm = false +optm-exc_jq = true +optm-ggfonts_async = false +optm-max_size = 2 +optm-rm_comment = false +optm-exc_roles = '' +optm-ccss_con = '' +optm-js_defer_exc = '' +; O_OPTM_DNS_PREFETCH +optm-dns_prefetch = '' +; O_OPTM_DNS_PREFETCH_CTRL +optm-dns_prefetch_ctrl = false +optm-exc = '' +; O_OPTM_CCSS_SEP_POSTTYPE +optm-ccss_sep_posttype = '' +; O_OPTM_CCSS_SEP_URI +optm-ccss_sep_uri = '' +;; -------------------------------------------------- ;; +;; -------------- Object Cache ----------------- ;; +;; -------------------------------------------------- ;; +object = true +object-kind = false +;object-host = 'localhost' +object-host = '/var/www/memcached.sock' +;object-port = 11211 +cache_object_port = '' +object-life = 360 +object-persistent = true +object-admin = true +object-transients = true +object-db_id = 0 +object-user = '' +object-pswd = '' +object-global_groups = 'users +userlogins +usermeta +user_meta +site-transient +site-options +site-lookup +blog-lookup +blog-details +rss +global-posts +blog-id-cache' +object-non_persistent_groups = 'comment +counts +plugins +wc_session_id' +;; -------------------------------------------------- ;; +;; -------------- Discussion ----------------- ;; +;; -------------------------------------------------- ;; +; O_DISCUSS_AVATAR_CACHE +discuss-avatar_cache = false +; O_DISCUSS_AVATAR_CRON +discuss-avatar_cron = false +; O_DISCUSS_AVATAR_CACHE_TTL +discuss-avatar_cache_ttl = 604800 +;; -------------------------------------------------- ;; +;; -------------- Media ----------------- ;; +;; -------------------------------------------------- ;; +; O_MEDIA_LAZY +media-lazy = false +; O_MEDIA_LAZY_PLACEHOLDER +media-lazy_placeholder = '' +; O_MEDIA_PLACEHOLDER_RESP +media-placeholder_resp = false +; O_MEDIA_PLACEHOLDER_RESP_COLOR +media-placeholder_resp_color = '#cfd4db' +; O_MEDIA_PLACEHOLDER_RESP_GENERATOR +media-placeholder_resp_generator = false +; O_MEDIA_PLACEHOLDER_RESP_SVG +media-placeholder_resp_svg = '' +; O_MEDIA_PLACEHOLDER_LQIP +media-placeholder_lqip = false +; O_MEDIA_PLACEHOLDER_LQIP_QUAL +media-placeholder_lqip_qual = 4 +; O_MEDIA_PLACEHOLDER_RESP_ASYNC +media-placeholder_resp_async = true +; O_MEDIA_IFRAME_LAZY +media-iframe_lazy = false +; O_MEDIA_LAZYJS_INLINE +media-lazyjs_inline = false +; O_MEDIA_LAZY_EXC +media-lazy_exc = '' +; O_MEDIA_LAZY_CLS_EXC +media-lazy_cls_exc = '' +; O_MEDIA_LAZY_PARENT_CLS_EXC +media-lazy_parent_cls_exc = '' +; O_MEDIA_IFRAME_LAZY_CLS_EXC +media-iframe_lazy_cls_exc = '' +; O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC +media-iframe_lazy_parent_cls_exc = '' +; O_MEDIA_LAZY_URI_EXC +media-lazy_uri_exc = '' +;; -------------------------------------------------- ;; +;; -------------- Image Optm ----------------- ;; +;; -------------------------------------------------- ;; +img_optm-auto = false +img_optm-cron = true +img_optm-ori = true +img_optm-rm_bkup = false +img_optm-webp = false +img_optm-lossless = false +img_optm-exif = false +img_optm-webp_replace = false +img_optm-webp_attr = 'img.src +div.data-thumb +img.data-src +div.data-large_image +img.retina_logo_url +div.data-parallax-image +video.poster' +img_optm-webp_replace_srcset = false +img_optm-jpg_quality = 82 +;; -------------------------------------------------- ;; +;; -------------- Crawler ----------------- ;; +;; -------------------------------------------------- ;; +crawler = false +crawler-inc_posts = true +crawler-inc_pages = true +crawler-inc_cats = true +crawler-inc_tags = true +crawler-exc_cpt = '' +crawler-order_links = 'date_desc' +crawler-usleep = 500 +crawler-run_duration = 400 +crawler-run_interval = 600 +crawler-crawl_interval = 302400 +crawler-threads = 3 +crawler-timeout = 30 +crawler-load_limit = 1 +; O_CRAWLER_SITEMAP +crawler-sitemap = '' +; O_CRAWLER_DROP_DOMAIN +crawler-drop_domain = true +crawler-roles = '' +crawler-cookies = '' +;; -------------------------------------------------- ;; +;; -------------- Misc ----------------- ;; +;; -------------------------------------------------- ;; +; O_MISC_HTACCESS_FRONT +misc-htaccess_front = '' +; O_MISC_HTACCESS_BACK +misc-htaccess_back = '' +; O_MISC_HEARTBEAT_FRONT +misc-heartbeat_front = false +; O_MISC_HEARTBEAT_FRONT_TTL +misc-heartbeat_front_ttl = 60 +; O_MISC_HEARTBEAT_BACK +misc-heartbeat_back = false +; O_MISC_HEARTBEAT_BACK_TTL +misc-heartbeat_back_ttl = 60 +; O_MISC_HEARTBEAT_EDITOR +misc-heartbeat_editor = false +; O_MISC_HEARTBEAT_EDITOR_TTL +misc-heartbeat_editor_ttl = 15 +;; -------------------------------------------------- ;; +;; -------------- CDN ----------------- ;; +;; -------------------------------------------------- ;; +cdn = false +cdn-ori = '' +cdn-ori_dir = '' +cdn-exc = '' +cdn-remote_jq = false +cdn-quic = false +cdn-quic_email = '' +cdn-quic_key = '' +cdn-cloudflare = false +cdn-cloudflare_email = '' +cdn-cloudflare_key = '' +cdn-cloudflare_name = '' +cdn-cloudflare_zone = '' +; \`cdn-mapping\` needs to be put in the end with a section tag +;; -------------------------------------------------- ;; +;; -------------- CDN 2 ----------------- ;; +;; -------------------------------------------------- ;; +; <------------ CDN Mapping Example BEGIN --------------------> +; Need to keep the section tag \`[cdn-mapping]\` before list. +; +; NOTE 1) Need to set all child options to make all resources to be replaced without missing. +; NOTE 2) \`url[n]\` option must have to enable the row setting of \`n\`. +; NOTE 3) This section needs to be put in the end of this .ini file +; +; To enable the 2nd mapping record by default, please remove the \`;;\` in the related lines. +[cdn-mapping] +url[0] = '' +inc_js[0] = true +inc_css[0] = true +inc_img[0] = true +filetype[0] = '.aac +.css +.eot +.gif +.jpeg +.js +.jpg +.less +.mp3 +.mp4 +.ogg +.otf +.pdf +.png +.svg +.ttf +.woff' +;;url[1] = 'https://2nd_CDN_url.com/' +;;filetype[1] = '.webm' +; <------------ CDN Mapping Example END ------------------> +EOM + + THEME_PATH="${VH_DOC_ROOT}/wp-content/themes/${THEME}" + if [ ! -f ${THEME_PATH}/functions.php ]; then + cat >> "${THEME_PATH}/functions.php" <>/dev/null 2>&1 +2i +require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' ); +\$path = 'litespeed-cache/litespeed-cache.php' ; +if (!is_plugin_active( \$path )) { + activate_plugin( \$path ) ; + rename( __FILE__ . '.bk', __FILE__ ); +} +. +w +q +END + fi +} + +preinstall_wordpress(){ + if [ "${VHNAME}" != '' ]; then + get_db_pass ${VHNAME} + else + get_db_pass ${DOMAIN} + fi + if [ ! -f ${VH_DOC_ROOT}/wp-config.php ] && [ -f ${VH_DOC_ROOT}/wp-config-sample.php ]; then + cp ${VH_DOC_ROOT}/wp-config-sample.php ${VH_DOC_ROOT}/wp-config.php + NEWDBPWD="define('DB_PASSWORD', '${SQL_PASS}');" + linechange 'DB_PASSWORD' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + NEWDBPWD="define('DB_USER', '${SQL_USER}');" + linechange 'DB_USER' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + NEWDBPWD="define('DB_NAME', '${SQL_DB}');" + linechange 'DB_NAME' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + #NEWDBPWD="define('DB_HOST', '${PUB_IP}');" + NEWDBPWD="define('DB_HOST', '${DB_HOST}');" + linechange 'DB_HOST' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + elif [ -f ${VH_DOC_ROOT}/wp-config.php ]; then + echo "${VH_DOC_ROOT}/wp-config.php already exist, exit !" + exit 1 + else + echo 'Skip!' + exit 2 + fi +} + +app_wordpress_dl(){ + if [ ! -f "${VH_DOC_ROOT}/wp-config.php" ] && [ ! -f "${VH_DOC_ROOT}/wp-config-sample.php" ]; then + wp core download \ + --allow-root \ + --quiet + else + echo 'wordpress already exist, abort!' + exit 1 + fi +} + +change_owner(){ + if [ "${VHNAME}" != '' ]; then + chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${VHNAME} + else + chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${DOMAIN} + fi +} + +main(){ + set_vh_docroot ${DOMAIN} + get_owner + cd ${VH_DOC_ROOT} + if [ "${APP_NAME}" = 'wordpress' ] || [ "${APP_NAME}" = 'wp' ]; then + check_sql_native + app_wordpress_dl + preinstall_wordpress + install_wp_plugin + set_htaccess + get_theme_name + set_lscache + change_owner + exit 0 + else + echo "APP: ${APP_NAME} not support, exit!" + exit 1 + fi +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[aA] | -app | --app) shift + check_input "${1}" + APP_NAME="${1}" + ;; + -[dD] | -domain | --domain) shift + check_input "${1}" + DOMAIN="${1}" + ;; + -vhname | --vhname) shift + VHNAME="${1}" + ;; + *) + help_message + ;; + esac + shift +done +main diff --git a/openlitespeed/1.7.18-lsphp74/data/bin/container/certhookctl.sh b/openlitespeed/1.7.18-lsphp74/data/bin/container/certhookctl.sh new file mode 100644 index 000000000..18be0965e --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/bin/container/certhookctl.sh @@ -0,0 +1,18 @@ +#!/bin/bash +BOTCRON='/var/spool/cron/crontabs/root' + +cert_hook(){ + grep 'acme' ${BOTCRON} >/dev/null + if [ ${?} = 0 ]; then + grep 'lswsctrl' ${BOTCRON} >/dev/null + if [ ${?} = 0 ]; then + echo 'Hook already exist, skip!' + else + sed -i 's/--cron/--cron --renew-hook "\/usr\/local\/lsws\/bin\/lswsctrl restart"/g' ${BOTCRON} + fi + else + echo "[X] ${BOTCRON} does not exist, please check it later!" + fi +} + +cert_hook \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp74/data/bin/container/domainctl.sh b/openlitespeed/1.7.18-lsphp74/data/bin/container/domainctl.sh new file mode 100644 index 000000000..75539ef01 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/bin/container/domainctl.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +CK_RESULT='' +LSDIR='/usr/local/lsws' +LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml" +OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf" +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-A, --add [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Will add domain to listener and creat a virtual host from template" + echow '-D, --del [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Will delete domain from listener" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help." +} + +check_lsv(){ + if [ -f ${LSDIR}/bin/openlitespeed ]; then + LSV='openlitespeed' + elif [ -f ${LSDIR}/bin/litespeed ]; then + LSV='lsws' + else + echo 'Version not exist, abort!' + exit 1 + fi +} + +dot_escape(){ + ESCAPE=$(echo ${1} | sed 's/\./\\./g') +} + +check_duplicate(){ + CK_RESULT=$(grep -E "${1}" ${2}) +} + +fst_match_line(){ + FIRST_LINE_NUM=$(grep -n -m 1 ${1} ${2} | awk -F ':' '{print $1}') +} +fst_match_after(){ + FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}') +} +lst_match_line(){ + fst_match_after ${1} ${2} ${3} + LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1)) +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +check_www(){ + CHECK_WWW=$(echo ${1} | cut -c1-4) + if [[ ${CHECK_WWW} == www. ]] ; then + echo 'www domain shoudnt be passed!' + exit 1 + fi +} + +www_domain(){ + check_www ${1} + WWW_DOMAIN=$(echo www.${1}) +} + +add_ls_domain(){ + fst_match_line 'docker.xml' ${LS_HTTPD_CONF} + NEWNUM=$((FIRST_LINE_NUM+2)) + sed -i "${NEWNUM}i \ \ \ \ \ \ \n \ \ \ \ \ \ \ ${DOMAIN}\n \ \ \ \ \ \ \ ${DOMAIN},${WWW_DOMAIN}\n \ \ \ \ \ \ " ${LS_HTTPD_CONF} +} + +add_ols_domain(){ + perl -0777 -p -i -e 's/(vhTemplate docker \{[^}]+)\}*(^.*listeners.*$)/\1$2 + member '${DOMAIN}' { + vhDomain '${DOMAIN},${WWW_DOMAIN}' + }/gmi' ${OLS_HTTPD_CONF} +} + +add_domain(){ + check_lsv + dot_escape ${1} + DOMAIN=${ESCAPE} + www_domain ${1} + if [ "${LSV}" = 'lsws' ]; then + check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF} + if [ "${CK_RESULT}" != '' ]; then + echo "# It appears the domain already exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + elif [ "${LSV}" = 'openlitespeed' ]; then + check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF} + if [ "${CK_RESULT}" != '' ]; then + echo "# It appears the domain already exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + fi + add_ls_domain + add_ols_domain +} + +del_ls_domain(){ + fst_match_line "*${1}" ${LS_HTTPD_CONF} + FIRST_LINE_NUM=$((FIRST_LINE_NUM-1)) + lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF} +} + +del_ols_domain(){ + fst_match_line ${1} ${OLS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF} +} + +del_domain(){ + check_lsv + dot_escape ${1} + DOMAIN=${ESCAPE} + if [ "${LSV}" = 'lsws' ]; then + check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF} + if [ "${CK_RESULT}" = '' ]; then + echo "# Domain non-exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + elif [ "${LSV}" = 'openlitespeed' ]; then + check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF} + if [ "${CK_RESULT}" = '' ]; then + echo "# Domain non-exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + fi + del_ls_domain ${1} + del_ols_domain ${1} +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[aA] | -add | --add) shift + add_domain ${1} + ;; + -[dD] | -del | --del | --delete) shift + del_domain ${1} + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp74/data/bin/container/owaspctl.sh b/openlitespeed/1.7.18-lsphp74/data/bin/container/owaspctl.sh new file mode 100644 index 000000000..72fd8e59c --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/bin/container/owaspctl.sh @@ -0,0 +1,236 @@ +#!/bin/bash +LSDIR='/usr/local/lsws' +OWASP_DIR="${LSDIR}/conf/owasp" +RULE_FILE='modsec_includes.conf' +LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml" +OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf" +EPACE=' ' +OWASP_V='3.3.4' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-E, --enable' + echo "${EPACE}${EPACE}Will Enable mod_secure module with latest OWASP version of rules" + echow '-D, --disable' + echo "${EPACE}${EPACE}Will Disable mod_secure module with latest OWASP version of rules" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_lsv(){ + if [ -f ${LSDIR}/bin/openlitespeed ]; then + LSV='openlitespeed' + elif [ -f ${LSDIR}/bin/litespeed ]; then + LSV='lsws' + else + echo 'Version not exist, abort!' + exit 1 + fi +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +mk_owasp_dir(){ + if [ -d ${OWASP_DIR} ] ; then + rm -rf ${OWASP_DIR} + fi + mkdir -p ${OWASP_DIR} + if [ ${?} -ne 0 ] ; then + echo "Unable to create directory: ${OWASP_DIR}, exit!" + exit 1 + fi +} + +fst_match_line(){ + FIRST_LINE_NUM=$(grep -n -m 1 "${1}" ${2} | awk -F ':' '{print $1}') +} +fst_match_after(){ + FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}') +} +lst_match_line(){ + fst_match_after ${1} ${2} ${3} + LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1)) +} + +enable_ols_modsec(){ + grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo "Already configured for modsecurity." + else + echo 'Enable modsecurity' + sed -i "s=module cache=module mod_security {\nmodsecurity on\ + \nmodsecurity_rules \`\nSecRuleEngine On\n\`\nmodsecurity_rules_file \ + ${OWASP_DIR}/${RULE_FILE}\n ls_enabled 1\n}\ + \n\nmodule cache=" ${OLS_HTTPD_CONF} + fi +} + +enable_ls_modsec(){ + grep '1' ${LS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo "LSWS already configured for modsecurity" + else + echo 'Enable modsecurity' + sed -i \ + "s=0=1=" ${LS_HTTPD_CONF} + sed -i \ + "s==\n\ + \n\ + ModSec\n\ + 1\n\ + include ${OWASP_DIR}/modsec_includes.conf\n\ + =" ${LS_HTTPD_CONF} + fi +} + +enable_modsec(){ + if [ "${LSV}" = 'lsws' ]; then + enable_ls_modsec + elif [ "${LSV}" = 'openlitespeed' ]; then + enable_ols_modsec + fi +} + +disable_ols_modesec(){ + grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo 'Disable modsecurity' + fst_match_line 'module mod_security' ${OLS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF} + else + echo 'Already disabled for modsecurity' + fi +} + +disable_ls_modesec(){ + grep '0' ${LS_HTTPD_CONF} + if [ ${?} -eq 0 ] ; then + echo 'Already disabled for modsecurity' + else + echo 'Disable modsecurity' + sed -i \ + "s=1=0=" ${LS_HTTPD_CONF} + fst_match_line 'censorshipRuleSet' ${LS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '/censorshipRuleSet' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF} + fi +} + +disable_modsec(){ + check_lsv + if [ "${LSV}" = 'lsws' ]; then + disable_ls_modesec + elif [ "${LSV}" = 'openlitespeed' ]; then + disable_ols_modesec + fi +} + +install_unzip(){ + if [ ! -f /usr/bin/unzip ]; then + echo 'Install Unzip' + apt update >/dev/null 2>&1 + apt-get install unzip -y >/dev/null 2>&1 + fi +} + +install_owasp(){ + cd ${OWASP_DIR} + echo 'Download OWASP rules' + wget -q https://github.com/coreruleset/coreruleset/archive/refs/tags/v${OWASP_V}.zip + unzip -qq v${OWASP_V}.zip + rm -f v${OWASP_V}.zip + mv coreruleset-* owasp-modsecurity-crs +} + +configure_owasp(){ + echo 'Config OWASP rules.' + cd ${OWASP_DIR} + echo "include modsecurity.conf +include owasp-modsecurity-crs/crs-setup.conf +include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf +include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf +include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf +include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf +include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf +include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf +include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf +include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf +include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf +include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf +include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf +include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf +include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf +include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf +include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf +include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf +include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf +include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf +include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf +include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf +include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf +include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf">modsec_includes.conf + echo "SecRuleEngine On">modsecurity.conf + cd ${OWASP_DIR}/owasp-modsecurity-crs + if [ -f crs-setup.conf.example ]; then + mv crs-setup.conf.example crs-setup.conf + fi + cd ${OWASP_DIR}/owasp-modsecurity-crs/rules + if [ -f REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example ]; then + mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf + fi + if [ -f RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example ]; then + mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf + fi +} + +main_owasp(){ + mk_owasp_dir + install_unzip + install_owasp + configure_owasp + check_lsv + enable_modsec +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[eE] | -enable | --enable) + main_owasp + ;; + -[dD] | -disable | --disable) + disable_modsec + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp74/data/bin/container/serialctl.sh b/openlitespeed/1.7.18-lsphp74/data/bin/container/serialctl.sh new file mode 100644 index 000000000..42e312dc1 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/bin/container/serialctl.sh @@ -0,0 +1,84 @@ +#!/bin/bash +LSDIR='/usr/local/lsws' +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-S, --serial [YOUR_SERIAL|TRIAL]' + echo "${EPACE}${EPACE}Will apply and register the serial to LSWS." + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +backup_old(){ + if [ -f ${1} ] && [ ! -f ${1}_old ]; then + mv ${1} ${1}_old + fi +} + +detect_ols(){ + if [ -e ${LSDIR}/bin/openlitespeed ]; then + echo '[X] Detect OpenLiteSpeed, abort!' + exit 1 + fi +} + +apply_serial(){ + detect_ols + check_input ${1} + echo ${1} | grep -i 'trial' >/dev/null + if [ ${?} = 0 ]; then + echo 'Apply Trial License' + if [ ! -e ${LSDIR}/conf/serial.no ] && [ ! -e ${LSDIR}/conf/license.key ]; then + rm -f ${LSDIR}/conf/trial.key* + wget -P ${LSDIR}/conf -q http://license.litespeedtech.com/reseller/trial.key + echo 'Apply trial finished' + else + echo "Please backup and remove your existing license, apply abort!" + exit 1 + fi + else + echo "Apply Serial number: ${1}" + backup_old ${LSDIR}/conf/serial.no + backup_old ${LSDIR}/conf/license.key + backup_old ${LSDIR}/conf/trial.key + echo "${1}" > ${LSDIR}/conf/serial.no + ${LSDIR}/bin/lshttpd -r + if [ -f ${LSDIR}/conf/license.key ]; then + echo '[O] Apply success' + else + echo '[X] Apply failed, please check!' + exit 1 + fi + fi +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[sS] | -serial | --serial) shift + apply_serial "${1}" + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp74/data/sites/.gitignore b/openlitespeed/1.7.18-lsphp74/data/sites/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/data/sites/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/openlitespeed/1.7.18-lsphp74/docker-compose.yml b/openlitespeed/1.7.18-lsphp74/docker-compose.yml new file mode 100644 index 000000000..73349894e --- /dev/null +++ b/openlitespeed/1.7.18-lsphp74/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3' +services: + litespeed: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + logging: + driver: none + volumes: + - ./data/lsws/conf:/usr/local/lsws/conf + - ./data/lsws/admin-conf:/usr/local/lsws/admin/conf + - ./data/bin/container:/usr/local/bin + - ./data/sites:/var/www/vhosts/ + - ./data/acme:/root/.acme.sh/ + - ./data/logs:/usr/local/lsws/logs/ + ports: + - "${PANEL_APP_PORT_HTTP}:80" + - "${PANEL_APP_PORT_HTTPS}:443" + - "${PANEL_APP_PORT_HTTPS}:443/udp" + - "${PANEL_APP_PORT_CONSOLE}:7080" + environment: + - TZ=${TIME_ZONE} + image: litespeedtech/openlitespeed:1.7.18-lsphp74 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/openlitespeed/1.7.18-lsphp81/data.yml b/openlitespeed/1.7.18-lsphp81/data.yml new file mode 100644 index 000000000..98939c0e1 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data.yml @@ -0,0 +1,33 @@ +additionalProperties: + formFields: + - default: 80 + disabled: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: 443 + disabled: true + envKey: PANEL_APP_PORT_HTTPS + labelEn: HTTPS Port + labelZh: HTTPS端口 + required: true + rule: paramPort + type: number + - default: 40113 + edit: true + envKey: PANEL_APP_PORT_CONSOLE + labelEn: Console Port + labelZh: 控制台端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TIME_ZONE + labelEn: Time zone + labelZh: 时区 + required: true + type: text diff --git a/openlitespeed/1.7.18-lsphp81/data/bin/container/appinstallctl.sh b/openlitespeed/1.7.18-lsphp81/data/bin/container/appinstallctl.sh new file mode 100644 index 000000000..d79c63f11 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/bin/container/appinstallctl.sh @@ -0,0 +1,660 @@ +#!/bin/bash +DEFAULT_VH_ROOT='/var/www/vhosts' +VH_DOC_ROOT='' +VHNAME='' +APP_NAME='' +DOMAIN='' +WWW_UID='' +WWW_GID='' +WP_CONST_CONF='' +PUB_IP=$(curl -s http://checkip.amazonaws.com) +DB_HOST='mysql' +PLUGINLIST="litespeed-cache.zip" +THEME='twentytwenty' +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-A, -app [wordpress] -D, --domain [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Example: appinstallctl.sh --app wordpress --domain example.com" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +linechange(){ + LINENUM=$(grep -n "${1}" ${2} | cut -d: -f 1) + if [ -n "${LINENUM}" ] && [ "${LINENUM}" -eq "${LINENUM}" ] 2>/dev/null; then + sed -i "${LINENUM}d" ${2} + sed -i "${LINENUM}i${3}" ${2} + fi +} + +ck_ed(){ + if [ ! -f /bin/ed ]; then + echo "Install ed package.." + apt-get install ed -y > /dev/null 2>&1 + fi +} + +ck_unzip(){ + if [ ! -f /usr/bin/unzip ]; then + echo "Install unzip package.." + apt-get install unzip -y > /dev/null 2>&1 + fi +} + +get_owner(){ + WWW_UID=$(stat -c "%u" ${DEFAULT_VH_ROOT}) + WWW_GID=$(stat -c "%g" ${DEFAULT_VH_ROOT}) + if [ ${WWW_UID} -eq 0 ] || [ ${WWW_GID} -eq 0 ]; then + WWW_UID=1000 + WWW_GID=1000 + echo "Set owner to ${WWW_UID}" + fi +} + +get_db_pass(){ + if [ -f ${DEFAULT_VH_ROOT}/${1}/.db_pass ]; then + SQL_DB=$(grep -i Database ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + SQL_USER=$(grep -i Username ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + SQL_PASS=$(grep -i Password ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"') + else + echo 'db pass file can not locate, skip wp-config pre-config.' + fi +} + +set_vh_docroot(){ + if [ "${VHNAME}" != '' ]; then + VH_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}" + VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}/html" + WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini" + elif [ -d ${DEFAULT_VH_ROOT}/${1}/html ]; then + VH_ROOT="${DEFAULT_VH_ROOT}/${1}" + VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${1}/html" + WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini" + else + echo "${DEFAULT_VH_ROOT}/${1}/html does not exist, please add domain first! Abort!" + exit 1 + fi +} + +check_sql_native(){ + local COUNTER=0 + local LIMIT_NUM=100 + until [ "$(curl -v mysql:3306 2>&1 | grep -i 'native\|Connected')" ]; do + echo "Counter: ${COUNTER}/${LIMIT_NUM}" + COUNTER=$((COUNTER+1)) + if [ ${COUNTER} = 10 ]; then + echo '--- MySQL is starting, please wait... ---' + elif [ ${COUNTER} = ${LIMIT_NUM} ]; then + echo '--- MySQL is timeout, exit! ---' + exit 1 + fi + sleep 1 + done +} + +install_wp_plugin(){ + for PLUGIN in ${PLUGINLIST}; do + wget -q -P ${VH_DOC_ROOT}/wp-content/plugins/ https://downloads.wordpress.org/plugin/${PLUGIN} + if [ ${?} = 0 ]; then + ck_unzip + unzip -qq -o ${VH_DOC_ROOT}/wp-content/plugins/${PLUGIN} -d ${VH_DOC_ROOT}/wp-content/plugins/ + else + echo "${PLUGINLIST} FAILED to download" + fi + done + rm -f ${VH_DOC_ROOT}/wp-content/plugins/*.zip +} + +set_htaccess(){ + if [ ! -f ${VH_DOC_ROOT}/.htaccess ]; then + touch ${VH_DOC_ROOT}/.htaccess + fi + cat << EOM > ${VH_DOC_ROOT}/.htaccess +# BEGIN WordPress + +RewriteEngine On +RewriteBase / +RewriteRule ^index\.php$ - [L] +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . /index.php [L] + +# END WordPress +EOM +} + +get_theme_name(){ + THEME_NAME=$(grep WP_DEFAULT_THEME ${VH_DOC_ROOT}/wp-includes/default-constants.php | grep -v '!' | awk -F "'" '{print $4}') + echo "${THEME_NAME}" | grep 'twenty' >/dev/null 2>&1 + if [ ${?} = 0 ]; then + THEME="${THEME_NAME}" + fi +} + +set_lscache(){ + cat << EOM > "${WP_CONST_CONF}" +; +; This is the predefined default LSCWP configuration file +; +; All the keys and values please refer \`src/const.cls.php\` +; +; Comments start with \`;\` +; +;; -------------------------------------------------- ;; +;; -------------- General ----------------- ;; +;; -------------------------------------------------- ;; +; O_AUTO_UPGRADE +auto_upgrade = false +; O_API_KEY +api_key = '' +; O_SERVER_IP +server_ip = '' +; O_NEWS +news = false +;; -------------------------------------------------- ;; +;; -------------- Cache ----------------- ;; +;; -------------------------------------------------- ;; +cache-priv = true +cache-commenter = true +cache-rest = true +cache-page_login = true +cache-favicon = true +cache-resources = true +cache-browser = false +cache-mobile = false +cache-mobile_rules = 'Mobile +Android +Silk/ +Kindle +BlackBerry +Opera Mini +Opera Mobi' +cache-exc_useragents = '' +cache-exc_cookies = '' +cache-exc_qs = '' +cache-exc_cat = '' +cache-exc_tag = '' +cache-force_uri = '' +cache-force_pub_uri = '' +cache-priv_uri = '' +cache-exc = '' +cache-exc_roles = '' +cache-drop_qs = 'fbclid +gclid +utm* +_ga' +cache-ttl_pub = 604800 +cache-ttl_priv = 1800 +cache-ttl_frontpage = 604800 +cache-ttl_feed = 604800 +; O_CACHE_TTL_REST +cache-ttl_rest = 604800 +cache-ttl_browser = 31557600 +cache-login_cookie = '' +cache-vary_group = '' +cache-ttl_status = '403 3600 +404 3600 +500 3600' +;; -------------------------------------------------- ;; +;; -------------- Purge ----------------- ;; +;; -------------------------------------------------- ;; +; O_PURGE_ON_UPGRADE +purge-upgrade = true +; O_PURGE_STALE +purge-stale = true +purge-post_all = false +purge-post_f = true +purge-post_h = true +purge-post_p = true +purge-post_pwrp = true +purge-post_a = true +purge-post_y = false +purge-post_m = true +purge-post_d = false +purge-post_t = true +purge-post_pt = true +purge-timed_urls = '' +purge-timed_urls_time = '' +purge-hook_all = 'switch_theme +wp_create_nav_menu +wp_update_nav_menu +wp_delete_nav_menu +create_term +edit_terms +delete_term +add_link +edit_link +delete_link' +;; -------------------------------------------------- ;; +;; -------------- ESI ----------------- ;; +;; -------------------------------------------------- ;; +; O_ESI +esi = false +; O_ESI_CACHE_ADMBAR +esi-cache_admbar = true +; O_ESI_CACHE_COMMFORM +esi-cache_commform = true +; O_ESI_NONCE +esi-nonce = 'stats_nonce +subscribe_nonce' +;; -------------------------------------------------- ;; +;; -------------- Utilities ----------------- ;; +;; -------------------------------------------------- ;; +util-heartbeat = true +util-instant_click = false +util-check_advcache = true +util-no_https_vary = false +;; -------------------------------------------------- ;; +;; -------------- Debug ----------------- ;; +;; -------------------------------------------------- ;; +; O_DEBUG_DISABLE_ALL +debug-disable_all = false +; O_DEBUG +debug = false +; O_DEBUG_IPS +debug-ips = '127.0.0.1' +; O_DEBUG_LEVEL +debug-level = false +; O_DEBUG_FILESIZE +debug-filesize = 3 +; O_DEBUG_COOKIE +debug-cookie = false +; O_DEBUG_COLLAPS_QS +debug-collaps_qs = false +; O_DEBUG_INC +debug-inc = '' +; O_DEBUG_EXC +debug-exc = '' +;; -------------------------------------------------- ;; +;; -------------- DB Optm ----------------- ;; +;; -------------------------------------------------- ;; +; O_DB_OPTM_REVISIONS_MAX +db_optm-revisions_max = 0 +; O_DB_OPTM_REVISIONS_AGE +db_optm-revisions_age = 0 +;; -------------------------------------------------- ;; +;; -------------- HTML Optm ----------------- ;; +;; -------------------------------------------------- ;; +; O_OPTM_CSS_MIN +optm-css_min = false +optm-css_inline_min = false +; O_OPTM_CSS_COMB +optm-css_comb = false +optm-css_comb_priority = false +; O_OPTM_CSS_HTTP2 +optm-css_http2 = false +optm-css_exc = '' +; O_OPTM_JS_MIN +optm-js_min = false +optm-js_inline_min = false +; O_OPTM_JS_COMB +optm-js_comb = false +optm-js_comb_priority = false +; O_OPTM_JS_HTTP2 +optm-js_http2 = false +; O_OPTM_EXC_JQ +optm-js_exc = '' +optm-ttl = 604800 +optm-html_min = false +optm-qs_rm = false +optm-ggfonts_rm = false +; O_OPTM_CSS_ASYNC +optm-css_async = false +; O_OPTM_CCSS_GEN +optm-ccss_gen = true +; O_OPTM_CCSS_ASYNC +optm-ccss_async = true +; O_OPTM_CSS_ASYNC_INLINE +optm-css_async_inline = true +; O_OPTM_CSS_FONT_DISPLAY +optm-css_font_display = false +; O_OPTM_JS_DEFER +optm-js_defer = false +; O_OPTM_JS_INLINE_DEFER +optm-js_inline_defer = false +optm-emoji_rm = false +optm-exc_jq = true +optm-ggfonts_async = false +optm-max_size = 2 +optm-rm_comment = false +optm-exc_roles = '' +optm-ccss_con = '' +optm-js_defer_exc = '' +; O_OPTM_DNS_PREFETCH +optm-dns_prefetch = '' +; O_OPTM_DNS_PREFETCH_CTRL +optm-dns_prefetch_ctrl = false +optm-exc = '' +; O_OPTM_CCSS_SEP_POSTTYPE +optm-ccss_sep_posttype = '' +; O_OPTM_CCSS_SEP_URI +optm-ccss_sep_uri = '' +;; -------------------------------------------------- ;; +;; -------------- Object Cache ----------------- ;; +;; -------------------------------------------------- ;; +object = true +object-kind = false +;object-host = 'localhost' +object-host = '/var/www/memcached.sock' +;object-port = 11211 +cache_object_port = '' +object-life = 360 +object-persistent = true +object-admin = true +object-transients = true +object-db_id = 0 +object-user = '' +object-pswd = '' +object-global_groups = 'users +userlogins +usermeta +user_meta +site-transient +site-options +site-lookup +blog-lookup +blog-details +rss +global-posts +blog-id-cache' +object-non_persistent_groups = 'comment +counts +plugins +wc_session_id' +;; -------------------------------------------------- ;; +;; -------------- Discussion ----------------- ;; +;; -------------------------------------------------- ;; +; O_DISCUSS_AVATAR_CACHE +discuss-avatar_cache = false +; O_DISCUSS_AVATAR_CRON +discuss-avatar_cron = false +; O_DISCUSS_AVATAR_CACHE_TTL +discuss-avatar_cache_ttl = 604800 +;; -------------------------------------------------- ;; +;; -------------- Media ----------------- ;; +;; -------------------------------------------------- ;; +; O_MEDIA_LAZY +media-lazy = false +; O_MEDIA_LAZY_PLACEHOLDER +media-lazy_placeholder = '' +; O_MEDIA_PLACEHOLDER_RESP +media-placeholder_resp = false +; O_MEDIA_PLACEHOLDER_RESP_COLOR +media-placeholder_resp_color = '#cfd4db' +; O_MEDIA_PLACEHOLDER_RESP_GENERATOR +media-placeholder_resp_generator = false +; O_MEDIA_PLACEHOLDER_RESP_SVG +media-placeholder_resp_svg = '' +; O_MEDIA_PLACEHOLDER_LQIP +media-placeholder_lqip = false +; O_MEDIA_PLACEHOLDER_LQIP_QUAL +media-placeholder_lqip_qual = 4 +; O_MEDIA_PLACEHOLDER_RESP_ASYNC +media-placeholder_resp_async = true +; O_MEDIA_IFRAME_LAZY +media-iframe_lazy = false +; O_MEDIA_LAZYJS_INLINE +media-lazyjs_inline = false +; O_MEDIA_LAZY_EXC +media-lazy_exc = '' +; O_MEDIA_LAZY_CLS_EXC +media-lazy_cls_exc = '' +; O_MEDIA_LAZY_PARENT_CLS_EXC +media-lazy_parent_cls_exc = '' +; O_MEDIA_IFRAME_LAZY_CLS_EXC +media-iframe_lazy_cls_exc = '' +; O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC +media-iframe_lazy_parent_cls_exc = '' +; O_MEDIA_LAZY_URI_EXC +media-lazy_uri_exc = '' +;; -------------------------------------------------- ;; +;; -------------- Image Optm ----------------- ;; +;; -------------------------------------------------- ;; +img_optm-auto = false +img_optm-cron = true +img_optm-ori = true +img_optm-rm_bkup = false +img_optm-webp = false +img_optm-lossless = false +img_optm-exif = false +img_optm-webp_replace = false +img_optm-webp_attr = 'img.src +div.data-thumb +img.data-src +div.data-large_image +img.retina_logo_url +div.data-parallax-image +video.poster' +img_optm-webp_replace_srcset = false +img_optm-jpg_quality = 82 +;; -------------------------------------------------- ;; +;; -------------- Crawler ----------------- ;; +;; -------------------------------------------------- ;; +crawler = false +crawler-inc_posts = true +crawler-inc_pages = true +crawler-inc_cats = true +crawler-inc_tags = true +crawler-exc_cpt = '' +crawler-order_links = 'date_desc' +crawler-usleep = 500 +crawler-run_duration = 400 +crawler-run_interval = 600 +crawler-crawl_interval = 302400 +crawler-threads = 3 +crawler-timeout = 30 +crawler-load_limit = 1 +; O_CRAWLER_SITEMAP +crawler-sitemap = '' +; O_CRAWLER_DROP_DOMAIN +crawler-drop_domain = true +crawler-roles = '' +crawler-cookies = '' +;; -------------------------------------------------- ;; +;; -------------- Misc ----------------- ;; +;; -------------------------------------------------- ;; +; O_MISC_HTACCESS_FRONT +misc-htaccess_front = '' +; O_MISC_HTACCESS_BACK +misc-htaccess_back = '' +; O_MISC_HEARTBEAT_FRONT +misc-heartbeat_front = false +; O_MISC_HEARTBEAT_FRONT_TTL +misc-heartbeat_front_ttl = 60 +; O_MISC_HEARTBEAT_BACK +misc-heartbeat_back = false +; O_MISC_HEARTBEAT_BACK_TTL +misc-heartbeat_back_ttl = 60 +; O_MISC_HEARTBEAT_EDITOR +misc-heartbeat_editor = false +; O_MISC_HEARTBEAT_EDITOR_TTL +misc-heartbeat_editor_ttl = 15 +;; -------------------------------------------------- ;; +;; -------------- CDN ----------------- ;; +;; -------------------------------------------------- ;; +cdn = false +cdn-ori = '' +cdn-ori_dir = '' +cdn-exc = '' +cdn-remote_jq = false +cdn-quic = false +cdn-quic_email = '' +cdn-quic_key = '' +cdn-cloudflare = false +cdn-cloudflare_email = '' +cdn-cloudflare_key = '' +cdn-cloudflare_name = '' +cdn-cloudflare_zone = '' +; \`cdn-mapping\` needs to be put in the end with a section tag +;; -------------------------------------------------- ;; +;; -------------- CDN 2 ----------------- ;; +;; -------------------------------------------------- ;; +; <------------ CDN Mapping Example BEGIN --------------------> +; Need to keep the section tag \`[cdn-mapping]\` before list. +; +; NOTE 1) Need to set all child options to make all resources to be replaced without missing. +; NOTE 2) \`url[n]\` option must have to enable the row setting of \`n\`. +; NOTE 3) This section needs to be put in the end of this .ini file +; +; To enable the 2nd mapping record by default, please remove the \`;;\` in the related lines. +[cdn-mapping] +url[0] = '' +inc_js[0] = true +inc_css[0] = true +inc_img[0] = true +filetype[0] = '.aac +.css +.eot +.gif +.jpeg +.js +.jpg +.less +.mp3 +.mp4 +.ogg +.otf +.pdf +.png +.svg +.ttf +.woff' +;;url[1] = 'https://2nd_CDN_url.com/' +;;filetype[1] = '.webm' +; <------------ CDN Mapping Example END ------------------> +EOM + + THEME_PATH="${VH_DOC_ROOT}/wp-content/themes/${THEME}" + if [ ! -f ${THEME_PATH}/functions.php ]; then + cat >> "${THEME_PATH}/functions.php" <>/dev/null 2>&1 +2i +require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' ); +\$path = 'litespeed-cache/litespeed-cache.php' ; +if (!is_plugin_active( \$path )) { + activate_plugin( \$path ) ; + rename( __FILE__ . '.bk', __FILE__ ); +} +. +w +q +END + fi +} + +preinstall_wordpress(){ + if [ "${VHNAME}" != '' ]; then + get_db_pass ${VHNAME} + else + get_db_pass ${DOMAIN} + fi + if [ ! -f ${VH_DOC_ROOT}/wp-config.php ] && [ -f ${VH_DOC_ROOT}/wp-config-sample.php ]; then + cp ${VH_DOC_ROOT}/wp-config-sample.php ${VH_DOC_ROOT}/wp-config.php + NEWDBPWD="define('DB_PASSWORD', '${SQL_PASS}');" + linechange 'DB_PASSWORD' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + NEWDBPWD="define('DB_USER', '${SQL_USER}');" + linechange 'DB_USER' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + NEWDBPWD="define('DB_NAME', '${SQL_DB}');" + linechange 'DB_NAME' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + #NEWDBPWD="define('DB_HOST', '${PUB_IP}');" + NEWDBPWD="define('DB_HOST', '${DB_HOST}');" + linechange 'DB_HOST' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}" + elif [ -f ${VH_DOC_ROOT}/wp-config.php ]; then + echo "${VH_DOC_ROOT}/wp-config.php already exist, exit !" + exit 1 + else + echo 'Skip!' + exit 2 + fi +} + +app_wordpress_dl(){ + if [ ! -f "${VH_DOC_ROOT}/wp-config.php" ] && [ ! -f "${VH_DOC_ROOT}/wp-config-sample.php" ]; then + wp core download \ + --allow-root \ + --quiet + else + echo 'wordpress already exist, abort!' + exit 1 + fi +} + +change_owner(){ + if [ "${VHNAME}" != '' ]; then + chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${VHNAME} + else + chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${DOMAIN} + fi +} + +main(){ + set_vh_docroot ${DOMAIN} + get_owner + cd ${VH_DOC_ROOT} + if [ "${APP_NAME}" = 'wordpress' ] || [ "${APP_NAME}" = 'wp' ]; then + check_sql_native + app_wordpress_dl + preinstall_wordpress + install_wp_plugin + set_htaccess + get_theme_name + set_lscache + change_owner + exit 0 + else + echo "APP: ${APP_NAME} not support, exit!" + exit 1 + fi +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[aA] | -app | --app) shift + check_input "${1}" + APP_NAME="${1}" + ;; + -[dD] | -domain | --domain) shift + check_input "${1}" + DOMAIN="${1}" + ;; + -vhname | --vhname) shift + VHNAME="${1}" + ;; + *) + help_message + ;; + esac + shift +done +main diff --git a/openlitespeed/1.7.18-lsphp81/data/bin/container/certhookctl.sh b/openlitespeed/1.7.18-lsphp81/data/bin/container/certhookctl.sh new file mode 100644 index 000000000..18be0965e --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/bin/container/certhookctl.sh @@ -0,0 +1,18 @@ +#!/bin/bash +BOTCRON='/var/spool/cron/crontabs/root' + +cert_hook(){ + grep 'acme' ${BOTCRON} >/dev/null + if [ ${?} = 0 ]; then + grep 'lswsctrl' ${BOTCRON} >/dev/null + if [ ${?} = 0 ]; then + echo 'Hook already exist, skip!' + else + sed -i 's/--cron/--cron --renew-hook "\/usr\/local\/lsws\/bin\/lswsctrl restart"/g' ${BOTCRON} + fi + else + echo "[X] ${BOTCRON} does not exist, please check it later!" + fi +} + +cert_hook \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp81/data/bin/container/domainctl.sh b/openlitespeed/1.7.18-lsphp81/data/bin/container/domainctl.sh new file mode 100644 index 000000000..75539ef01 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/bin/container/domainctl.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +CK_RESULT='' +LSDIR='/usr/local/lsws' +LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml" +OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf" +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-A, --add [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Will add domain to listener and creat a virtual host from template" + echow '-D, --del [DOMAIN_NAME]' + echo "${EPACE}${EPACE}Will delete domain from listener" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help." +} + +check_lsv(){ + if [ -f ${LSDIR}/bin/openlitespeed ]; then + LSV='openlitespeed' + elif [ -f ${LSDIR}/bin/litespeed ]; then + LSV='lsws' + else + echo 'Version not exist, abort!' + exit 1 + fi +} + +dot_escape(){ + ESCAPE=$(echo ${1} | sed 's/\./\\./g') +} + +check_duplicate(){ + CK_RESULT=$(grep -E "${1}" ${2}) +} + +fst_match_line(){ + FIRST_LINE_NUM=$(grep -n -m 1 ${1} ${2} | awk -F ':' '{print $1}') +} +fst_match_after(){ + FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}') +} +lst_match_line(){ + fst_match_after ${1} ${2} ${3} + LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1)) +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +check_www(){ + CHECK_WWW=$(echo ${1} | cut -c1-4) + if [[ ${CHECK_WWW} == www. ]] ; then + echo 'www domain shoudnt be passed!' + exit 1 + fi +} + +www_domain(){ + check_www ${1} + WWW_DOMAIN=$(echo www.${1}) +} + +add_ls_domain(){ + fst_match_line 'docker.xml' ${LS_HTTPD_CONF} + NEWNUM=$((FIRST_LINE_NUM+2)) + sed -i "${NEWNUM}i \ \ \ \ \ \ \n \ \ \ \ \ \ \ ${DOMAIN}\n \ \ \ \ \ \ \ ${DOMAIN},${WWW_DOMAIN}\n \ \ \ \ \ \ " ${LS_HTTPD_CONF} +} + +add_ols_domain(){ + perl -0777 -p -i -e 's/(vhTemplate docker \{[^}]+)\}*(^.*listeners.*$)/\1$2 + member '${DOMAIN}' { + vhDomain '${DOMAIN},${WWW_DOMAIN}' + }/gmi' ${OLS_HTTPD_CONF} +} + +add_domain(){ + check_lsv + dot_escape ${1} + DOMAIN=${ESCAPE} + www_domain ${1} + if [ "${LSV}" = 'lsws' ]; then + check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF} + if [ "${CK_RESULT}" != '' ]; then + echo "# It appears the domain already exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + elif [ "${LSV}" = 'openlitespeed' ]; then + check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF} + if [ "${CK_RESULT}" != '' ]; then + echo "# It appears the domain already exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + fi + add_ls_domain + add_ols_domain +} + +del_ls_domain(){ + fst_match_line "*${1}" ${LS_HTTPD_CONF} + FIRST_LINE_NUM=$((FIRST_LINE_NUM-1)) + lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF} +} + +del_ols_domain(){ + fst_match_line ${1} ${OLS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF} +} + +del_domain(){ + check_lsv + dot_escape ${1} + DOMAIN=${ESCAPE} + if [ "${LSV}" = 'lsws' ]; then + check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF} + if [ "${CK_RESULT}" = '' ]; then + echo "# Domain non-exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + elif [ "${LSV}" = 'openlitespeed' ]; then + check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF} + if [ "${CK_RESULT}" = '' ]; then + echo "# Domain non-exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!" + exit 1 + fi + fi + del_ls_domain ${1} + del_ols_domain ${1} +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[aA] | -add | --add) shift + add_domain ${1} + ;; + -[dD] | -del | --del | --delete) shift + del_domain ${1} + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp81/data/bin/container/owaspctl.sh b/openlitespeed/1.7.18-lsphp81/data/bin/container/owaspctl.sh new file mode 100644 index 000000000..72fd8e59c --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/bin/container/owaspctl.sh @@ -0,0 +1,236 @@ +#!/bin/bash +LSDIR='/usr/local/lsws' +OWASP_DIR="${LSDIR}/conf/owasp" +RULE_FILE='modsec_includes.conf' +LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml" +OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf" +EPACE=' ' +OWASP_V='3.3.4' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-E, --enable' + echo "${EPACE}${EPACE}Will Enable mod_secure module with latest OWASP version of rules" + echow '-D, --disable' + echo "${EPACE}${EPACE}Will Disable mod_secure module with latest OWASP version of rules" + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_lsv(){ + if [ -f ${LSDIR}/bin/openlitespeed ]; then + LSV='openlitespeed' + elif [ -f ${LSDIR}/bin/litespeed ]; then + LSV='lsws' + else + echo 'Version not exist, abort!' + exit 1 + fi +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +mk_owasp_dir(){ + if [ -d ${OWASP_DIR} ] ; then + rm -rf ${OWASP_DIR} + fi + mkdir -p ${OWASP_DIR} + if [ ${?} -ne 0 ] ; then + echo "Unable to create directory: ${OWASP_DIR}, exit!" + exit 1 + fi +} + +fst_match_line(){ + FIRST_LINE_NUM=$(grep -n -m 1 "${1}" ${2} | awk -F ':' '{print $1}') +} +fst_match_after(){ + FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}') +} +lst_match_line(){ + fst_match_after ${1} ${2} ${3} + LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1)) +} + +enable_ols_modsec(){ + grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo "Already configured for modsecurity." + else + echo 'Enable modsecurity' + sed -i "s=module cache=module mod_security {\nmodsecurity on\ + \nmodsecurity_rules \`\nSecRuleEngine On\n\`\nmodsecurity_rules_file \ + ${OWASP_DIR}/${RULE_FILE}\n ls_enabled 1\n}\ + \n\nmodule cache=" ${OLS_HTTPD_CONF} + fi +} + +enable_ls_modsec(){ + grep '1' ${LS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo "LSWS already configured for modsecurity" + else + echo 'Enable modsecurity' + sed -i \ + "s=0=1=" ${LS_HTTPD_CONF} + sed -i \ + "s==\n\ + \n\ + ModSec\n\ + 1\n\ + include ${OWASP_DIR}/modsec_includes.conf\n\ + =" ${LS_HTTPD_CONF} + fi +} + +enable_modsec(){ + if [ "${LSV}" = 'lsws' ]; then + enable_ls_modsec + elif [ "${LSV}" = 'openlitespeed' ]; then + enable_ols_modsec + fi +} + +disable_ols_modesec(){ + grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1 + if [ ${?} -eq 0 ] ; then + echo 'Disable modsecurity' + fst_match_line 'module mod_security' ${OLS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF} + else + echo 'Already disabled for modsecurity' + fi +} + +disable_ls_modesec(){ + grep '0' ${LS_HTTPD_CONF} + if [ ${?} -eq 0 ] ; then + echo 'Already disabled for modsecurity' + else + echo 'Disable modsecurity' + sed -i \ + "s=1=0=" ${LS_HTTPD_CONF} + fst_match_line 'censorshipRuleSet' ${LS_HTTPD_CONF} + lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '/censorshipRuleSet' + sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF} + fi +} + +disable_modsec(){ + check_lsv + if [ "${LSV}" = 'lsws' ]; then + disable_ls_modesec + elif [ "${LSV}" = 'openlitespeed' ]; then + disable_ols_modesec + fi +} + +install_unzip(){ + if [ ! -f /usr/bin/unzip ]; then + echo 'Install Unzip' + apt update >/dev/null 2>&1 + apt-get install unzip -y >/dev/null 2>&1 + fi +} + +install_owasp(){ + cd ${OWASP_DIR} + echo 'Download OWASP rules' + wget -q https://github.com/coreruleset/coreruleset/archive/refs/tags/v${OWASP_V}.zip + unzip -qq v${OWASP_V}.zip + rm -f v${OWASP_V}.zip + mv coreruleset-* owasp-modsecurity-crs +} + +configure_owasp(){ + echo 'Config OWASP rules.' + cd ${OWASP_DIR} + echo "include modsecurity.conf +include owasp-modsecurity-crs/crs-setup.conf +include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf +include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf +include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf +include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf +include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf +include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf +include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf +include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf +include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf +include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf +include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf +include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf +include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf +include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf +include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf +include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf +include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf +include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf +include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf +include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf +include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf +include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf +include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf +include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf">modsec_includes.conf + echo "SecRuleEngine On">modsecurity.conf + cd ${OWASP_DIR}/owasp-modsecurity-crs + if [ -f crs-setup.conf.example ]; then + mv crs-setup.conf.example crs-setup.conf + fi + cd ${OWASP_DIR}/owasp-modsecurity-crs/rules + if [ -f REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example ]; then + mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf + fi + if [ -f RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example ]; then + mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf + fi +} + +main_owasp(){ + mk_owasp_dir + install_unzip + install_owasp + configure_owasp + check_lsv + enable_modsec +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[eE] | -enable | --enable) + main_owasp + ;; + -[dD] | -disable | --disable) + disable_modsec + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp81/data/bin/container/serialctl.sh b/openlitespeed/1.7.18-lsphp81/data/bin/container/serialctl.sh new file mode 100644 index 000000000..42e312dc1 --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/bin/container/serialctl.sh @@ -0,0 +1,84 @@ +#!/bin/bash +LSDIR='/usr/local/lsws' +EPACE=' ' + +echow(){ + FLAG=${1} + shift + echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}" +} + +help_message(){ + echo -e "\033[1mOPTIONS\033[0m" + echow '-S, --serial [YOUR_SERIAL|TRIAL]' + echo "${EPACE}${EPACE}Will apply and register the serial to LSWS." + echow '-H, --help' + echo "${EPACE}${EPACE}Display help and exit." + exit 0 +} + +check_input(){ + if [ -z "${1}" ]; then + help_message + exit 1 + fi +} + +backup_old(){ + if [ -f ${1} ] && [ ! -f ${1}_old ]; then + mv ${1} ${1}_old + fi +} + +detect_ols(){ + if [ -e ${LSDIR}/bin/openlitespeed ]; then + echo '[X] Detect OpenLiteSpeed, abort!' + exit 1 + fi +} + +apply_serial(){ + detect_ols + check_input ${1} + echo ${1} | grep -i 'trial' >/dev/null + if [ ${?} = 0 ]; then + echo 'Apply Trial License' + if [ ! -e ${LSDIR}/conf/serial.no ] && [ ! -e ${LSDIR}/conf/license.key ]; then + rm -f ${LSDIR}/conf/trial.key* + wget -P ${LSDIR}/conf -q http://license.litespeedtech.com/reseller/trial.key + echo 'Apply trial finished' + else + echo "Please backup and remove your existing license, apply abort!" + exit 1 + fi + else + echo "Apply Serial number: ${1}" + backup_old ${LSDIR}/conf/serial.no + backup_old ${LSDIR}/conf/license.key + backup_old ${LSDIR}/conf/trial.key + echo "${1}" > ${LSDIR}/conf/serial.no + ${LSDIR}/bin/lshttpd -r + if [ -f ${LSDIR}/conf/license.key ]; then + echo '[O] Apply success' + else + echo '[X] Apply failed, please check!' + exit 1 + fi + fi +} + +check_input ${1} +while [ ! -z "${1}" ]; do + case ${1} in + -[hH] | -help | --help) + help_message + ;; + -[sS] | -serial | --serial) shift + apply_serial "${1}" + ;; + *) + help_message + ;; + esac + shift +done \ No newline at end of file diff --git a/openlitespeed/1.7.18-lsphp81/data/sites/.gitignore b/openlitespeed/1.7.18-lsphp81/data/sites/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/data/sites/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/openlitespeed/1.7.18-lsphp81/docker-compose.yml b/openlitespeed/1.7.18-lsphp81/docker-compose.yml new file mode 100644 index 000000000..182283e2e --- /dev/null +++ b/openlitespeed/1.7.18-lsphp81/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3' +services: + litespeed: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + logging: + driver: none + volumes: + - ./data/lsws/conf:/usr/local/lsws/conf + - ./data/lsws/admin-conf:/usr/local/lsws/admin/conf + - ./data/bin/container:/usr/local/bin + - ./data/sites:/var/www/vhosts/ + - ./data/acme:/root/.acme.sh/ + - ./data/logs:/usr/local/lsws/logs/ + ports: + - "${PANEL_APP_PORT_HTTP}:80" + - "${PANEL_APP_PORT_HTTPS}:443" + - "${PANEL_APP_PORT_HTTPS}:443/udp" + - "${PANEL_APP_PORT_CONSOLE}:7080" + environment: + - TZ=${TIME_ZONE} + image: litespeedtech/openlitespeed:1.7.18-lsphp81 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/openlitespeed/README.md b/openlitespeed/README.md new file mode 100644 index 000000000..53c7ffab0 --- /dev/null +++ b/openlitespeed/README.md @@ -0,0 +1,43 @@ +# 使用说明 + +安装完成后,在容器功能界面,连接容器终端,执行以下命令创建管理员账户密码 + +``` +/usr/local/lsws/admin/misc/admpass.sh +``` + +# 原始相关 + +OpenLiteSpeed Web Server +======== + +Description +-------- + +OpenLiteSpeed is a high-performance, lightweight, open source HTTP server developed and copyrighted by +LiteSpeed Technologies. Users are free to download, use, distribute, and modify OpenLiteSpeed and its +source code in accordance with the precepts of the GPLv3 license. + +This is the official repository for OpenLiteSpeed's source code. It is maintained by LiteSpeed +Technologies. + +Documentation +-------- + +Users can find all OpenLiteSpeed documentation on the [OpenLiteSpeed site](https://openlitespeed.org), +but here are some quick links to important parts of the site: + +[Installation](https://openlitespeed.org/kb/category/installation/) + +[Configuration](https://openlitespeed.org/kb/category/configuration/) + +[Road map](https://openlitespeed.org/mediawiki/index.php/Road_Map) + +[Release log](https://openlitespeed.org/release-log/) + +Get in Touch +-------- + +OpenLiteSpeed has a [Google Group](https://groups.google.com/forum/#!forum/openlitespeed-development). If +you find a bug, want to request new features, or just want to talk about OpenLiteSpeed, this is the place +to do it. diff --git a/openlitespeed/data.yml b/openlitespeed/data.yml new file mode 100644 index 000000000..caf5142bb --- /dev/null +++ b/openlitespeed/data.yml @@ -0,0 +1,20 @@ +name: OpenLiteSpeed +tags: + - Web 服务器 +title: 一个高性能、轻量级、开源 的HTTP 服务器 +type: Web 服务器 +description: 一个高性能、轻量级、开源 的HTTP 服务器 +additionalProperties: + key: openlitespeed + name: OpenLiteSpeed + tags: + - Server + shortDescZh: 一个高性能、轻量级、开源 的HTTP 服务器 + shortDescEn: A high-performance, lightweight, open source HTTP server + type: runtime + crossVersionUpdate: true + limit: 1 + recommend: 0 + website: https://openlitespeed.org + github: https://github.com/litespeedtech/openlitespeed + document: https://openlitespeed.org/#install \ No newline at end of file diff --git a/openlitespeed/logo.png b/openlitespeed/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dba1cecc087b4415379343dc4f3abf3d62c1da78 GIT binary patch literal 7056 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 Z7b!Q{{eD-1`zNshwAJ;VRjArV{|6H2wqXDO literal 0 HcmV?d00001 diff --git a/pingvin-share/0.17.4/data.yml b/pingvin-share/0.17.4/data.yml new file mode 100644 index 000000000..9477002f0 --- /dev/null +++ b/pingvin-share/0.17.4/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40068 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/pingvin-share/0.17.4/docker-compose.yml b/pingvin-share/0.17.4/docker-compose.yml new file mode 100644 index 000000000..a0bb5cee6 --- /dev/null +++ b/pingvin-share/0.17.4/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3' +services: + pingvin-share: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + volumes: + - "./data/data:/opt/app/backend/data" + - "./data/images:/opt/app/frontend/public/img" + image: stonith404/pingvin-share:v0.17.4 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/pingvin-share/README.md b/pingvin-share/README.md new file mode 100644 index 000000000..be90c4e34 --- /dev/null +++ b/pingvin-share/README.md @@ -0,0 +1,126 @@ +#

Pingvin Share
+ +--- + +_选择合适的语言阅读: [西班牙语](https://github.com/stonith404/pingvin-share/blob/main/docs/README.es.md), [英语](https://github.com/stonith404/pingvin-share/blob/main/README.md), [简体中文](https://github.com/stonith404/pingvin-share/blob/main/docs/README.zh-cn.md)_ + +--- + +Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品 + +## ✨ 特性 + +- 通过可自定义后缀的链接分享文件 +- 可自定义任意大小的文件上传限制 (受制于托管所在的硬盘大小) +- 对共享链接设置有效期限 +- 对共享链接设置访问次数和访问密码 +- 通过邮件自动发送共享链接 +- 整合 ClamAV 进行反病毒检查 + +## 🐧 了解一下 Pingvin Share + +- [示例网站](https://pingvin-share.dev.eliasschneider.com) +- [DB Tech 推荐视频](https://www.youtube.com/watch?v=rWwNeZCOPJA) + + + +## ⌨️ 自建指南 + +> 注意:Pingvin Share 仍处于开发阶段并且可能存在 bugs + +### Docker 部署 (推荐) + +1. 下载 `docker-compose.yml` +2. 运行命令 `docker-compose up -d` + +现在网站运行在 `http://localhost:3000`,尝试一下你本地的 Pingvin Share 🐧! + +### Stand-alone 部署 + +必须的依赖: + +- [Node.js](https://nodejs.org/en/download/) >= 16 +- [Git](https://git-scm.com/downloads) +- [pm2](https://pm2.keymetrics.io/) 用于后台运行 Pingvin Share + +```bash +git clone https://github.com/stonith404/pingvin-share +cd pingvin-share + +# 获取最新的版本 +git fetch --tags && git checkout $(git describe --tags `git rev-list --tags --max-count=1`) + +# 启动后端 backend +cd backend +npm install +npm run build +pm2 start --name="pingvin-share-backend" npm -- run prod + +# 启动前端 frontend +cd ../frontend +npm install +npm run build +pm2 start --name="pingvin-share-frontend" npm -- run start +``` + +现在网站运行在 `http://localhost:3000`,尝试一下你本地的 Pingvin Share 🐧! + +### 整合组件 + +#### ClamAV (仅限 Docker 部署) + +扫描上传文件中是否存在可疑文件,如果存在 ClamAV 会自动移除 + +1. 在 docker-compose 配置中添加 ClamAV 容器 (见 `docker-compose.yml` 注释部分) 并启动容器 +2. Docker 会在启动 Pingvin Share 前启动 ClamAV,也许会花费 1-2 分钟 +3. Pingvin Share 日志中应该有 "ClamAV is active" + +请注意 ClamAV 会消耗很多 [系统资源(特别是内存)](https://docs.clamav.net/manual/Installing/Docker.html#memory-ram-requirements) + +### 更多资源 + +- [群晖 NAS 配置](https://mariushosting.com/how-to-install-pingvin-share-on-your-synology-nas/) + +### 升级 + +因为 Pingvin Share 仍处在开发阶段,在升级前请务必阅读 release notes 避免不可逆的改变 + +#### Docker 升级 + +```bash +docker compose pull +docker compose up -d +``` + +#### Stand-alone 升级 + +1. 停止正在运行的 app + ```bash + pm2 stop pingvin-share-backend pingvin-share-frontend + ``` +2. 重复 [installation guide](#stand-alone-installation) 中的步骤,除了 `git clone` 这一步 + + ```bash + cd pingvin-share + + # 获取最新的版本 + git fetch --tags && git checkout $(git describe --tags `git rev-list --tags --max-count=1`) + + # 启动后端 backend + cd backend + npm run build + pm2 restart pingvin-share-backend + + # 启动前端 frontend + cd ../frontend + npm run build + pm2 restart pingvin-share-frontend + ``` + +### 自定义品牌 + +你可以在管理员配置页面改变网站的名字和 logo + +## 🖤 提交贡献 + +非常欢迎向 Pingvin Share 提交贡献! 请阅读 [contribution guide](https://github.com/stonith404/pingvin-share/blob/main/CONTRIBUTING.md) 来提交你的贡献 diff --git a/pingvin-share/data.yml b/pingvin-share/data.yml new file mode 100644 index 000000000..5cc2c2344 --- /dev/null +++ b/pingvin-share/data.yml @@ -0,0 +1,20 @@ +name: Pingvin Share +tags: + - 工具 +title: 一个可自建的文件分享平台 +type: 工具 +description: 一个可自建的文件分享平台 +additionalProperties: + key: pingvin-share + name: Pingvin Share + tags: + - Tool + shortDescZh: 一个可自建的文件分享平台 + shortDescEn: s self-hosted file sharing platform + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/stonith404/pingvin-share + github: https://github.com/stonith404/pingvin-share + document: https://github.com/stonith404/pingvin-share diff --git a/pingvin-share/logo.png b/pingvin-share/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c49c2b689ada4d8d0cb5b55d2432dc863d84cfd4 GIT binary patch literal 8522 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 Eg4VjMuK)l5 literal 0 HcmV?d00001 diff --git a/searxng/2023.7.1-5720844f/data.yml b/searxng/2023.7.1-5720844f/data.yml new file mode 100644 index 000000000..943d3461b --- /dev/null +++ b/searxng/2023.7.1-5720844f/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 40032 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: http://localhost:40032 + edit: true + envKey: SEARXNG_EXTERNAL_URL + labelEn: External URL + labelZh: 外部访问地址 + required: true + type: text \ No newline at end of file diff --git a/searxng/2023.7.1-5720844f/docker-compose.yml b/searxng/2023.7.1-5720844f/docker-compose.yml new file mode 100644 index 000000000..103383873 --- /dev/null +++ b/searxng/2023.7.1-5720844f/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3' +services: + searxng: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:8080" + volumes: + - "./data:/etc/searxng" + environment: + - BASE_URL=${SEARXNG_EXTERNAL_URL} + image: searxng/searxng:2023.7.1-5720844f + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/searxng/README.md b/searxng/README.md new file mode 100644 index 000000000..5cc63a147 --- /dev/null +++ b/searxng/README.md @@ -0,0 +1,82 @@ +------------------------------------------------------------------------ + +SearXNGlogo + +------------------------------------------------------------------------ + +Privacy-respecting, hackable [meta search engine](https://en.wikipedia.org/wiki/Metasearch_engine) + +[Searx.space](https://searx.space) lists ready-to-use running instances. + +A [user](https://docs.searxng.org/user),[admin](https://docs.searxng.org/admin) and[developer](https://docs.searxng.org/dev) handbook is available on the[homepage](https://docs.searxng.org/). + +[![SearXNG +install](https://img.shields.io/badge/-install-blue)](https://docs.searxng.org/admin/installation.html) [![SearXNG +homepage](https://img.shields.io/badge/-homepage-blue)](https://docs.searxng.org/) [![SearXNGwiki](https://img.shields.io/badge/-wiki-blue)](https://github.com/searxng/searxng/wiki) [![AGPLLicense](https://img.shields.io/badge/license-AGPL-blue.svg)](https://github.com/searxng/searxng/blob/master/LICENSE) [![Issues](https://img.shields.io/github/issues/searxng/searxng?color=yellow&label=issues)](https://github.com/searxng/searxng/issues) [![commits](https://img.shields.io/github/commit-activity/y/searxng/searxng?color=yellow&label=commits)](https://github.com/searxng/searxng/commits/master) [![weblate](https://translate.codeberg.org/widgets/searxng/-/searxng/svg-badge.svg)](https://translate.codeberg.org/projects/searxng/) SearXNGlogo + + +------------------------------------------------------------------------ + +# Contact + +Ask questions or just chat about SearXNG on + +IRC + + [#searxng on libera.chat](https://web.libera.chat/?channel=#searxng) which is bridged to Matrix. + +Matrix + + [#searxng:matrix.org](https://matrix.to/#/#searxng:matrix.org) + +# Differences to searx + +SearXNG is a fork of [searx](https://github.com/searx/searx), with notable changes: + +## User experience + +- Reworked (and still simple) theme: + - Usable on desktop, tablet and mobile. + - Light and dark versions (available in the preferences). + - Right-to-left language support. + - [Screenshots](https://dev.searxng.org/screenshots.html) +- The translations are up to date, you can contribute on [Weblate](https://translate.codeberg.org/projects/searxng/searxng/) +- The preferences page has been updated: + - Browse which engines are reliable or not. + - Engines are grouped inside each tab. + - Each engine has a description. +- Thanks to the anonymous metrics, it is easier to report malfunctioning engines, so they get fixed quicker + - [Turn off metrics on the server](https://docs.searxng.org/admin/engines/settings.html#general)if you don\'t want them recorded. +- Administrators can [block and/or replace the URLs in the search results](https://github.com/searxng/searxng/blob/5c1c0817c3996c5670a545d05831d234d21e6217/searx/settings.yml#L191-L199) + +## Setup + +- No need for [Morty](https://github.com/asciimoo/morty) to proxy images, even on a public instance. +- No need for [Filtron](https://github.com/searxng/filtron) to block bots, as there is now a built-in [limiter](https://docs.searxng.org/src/searx.plugins.limiter.html). +- A well maintained [Dockerimage](https://github.com/searxng/searxng-docker), now also built for ARM64 and ARM/v7 architectures. (Alternatively there are up to date installation scripts.) + +## Contributing + +- Readable debug log. +- Contributing is easier, thanks to the [Development Quickstart](https://docs.searxng.org/dev/quickstart.html) guide. +- A lot of code cleanup and bugfixes. +- Up to date list dependencies. + +# Translations + +Help translate SearXNG at [Weblate](https://translate.codeberg.org/projects/searxng/searxng/) + +![](https://translate.codeberg.org/widgets/searxng/-/multi-auto.svg) + +# Codespaces + +You can contribute from your browser using [GitHub Codespaces](https://docs.github.com/en/codespaces/overview): + +- Fork the repository +- Click on the `<> Code` green button +- Click on the `Codespaces` tab instead of `Local` +- Click on `Create codespace on master` +- VSCode is going to start in the browser +- Wait for `git pull && make install` to appears and then to disapear +- You have [120 hours per month](https://github.com/settings/billing)(see also your [list of existing Codespaces](https://github.com/codespaces)) +- You can start SearXNG using `make run` in the terminal or by pressing `Ctrl+Shift+B`. diff --git a/searxng/data.yml b/searxng/data.yml new file mode 100644 index 000000000..c8a3b5bb0 --- /dev/null +++ b/searxng/data.yml @@ -0,0 +1,20 @@ +name: SearXNG +tags: + - 建站 +title: 一个免费的互联网元聚合搜索引擎 +type: 建站 +description: 一个免费的互联网元聚合搜索引擎 +additionalProperties: + key: searxng + name: SearXNG + tags: + - WebSite + shortDescZh: 一个免费的互联网元聚合搜索引擎 + shortDescEn: A free internet meta-aggregator search engine + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/searxng/searxng + github: https://github.com/searxng/searxng + document: https://docs.searxng.org/ diff --git a/searxng/logo.png b/searxng/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3eeefdc8384f9469a274d7742ab24bdad54dbd95 GIT binary patch literal 4532 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 W(r0P&bFGUt4B)PzIiyM7Bk{jbXRFKr literal 0 HcmV?d00001 diff --git a/vocechat/0.3.36/data.yml b/vocechat/0.3.36/data.yml new file mode 100644 index 000000000..618edfbfb --- /dev/null +++ b/vocechat/0.3.36/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40067 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/vocechat/0.3.36/docker-compose.yml b/vocechat/0.3.36/docker-compose.yml new file mode 100644 index 000000000..e8f74d5c3 --- /dev/null +++ b/vocechat/0.3.36/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + vocechat: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + volumes: + - "./data:/home/vocechat-server/data" + image: privoce/vocechat-server:v0.3.36 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/vocechat/README.md b/vocechat/README.md new file mode 100644 index 000000000..50bab46df --- /dev/null +++ b/vocechat/README.md @@ -0,0 +1,77 @@ +# Web Client of VoceChat + +
+ +
+

+

+ +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/privoce/vocechat-web/issues) +![GitHub issues](https://img.shields.io/github/issues-raw/Privoce/vocechat-web) ![GitHub](https://img.shields.io/github/license/privoce/vocechat-web) ![GitHub top language](https://img.shields.io/github/languages/top/privoce/vocechat-web) ![Docker Pulls](https://img.shields.io/docker/pulls/privoce/vocechat-server) + +
+ +- 🎉 Powered by React & Redux Toolkit +- ✅ Typescript +- 📦 PWA +- 📢 Notification + +## Host your server! Or use our test server + +- Host your own Voce server ([docker image](https://hub.docker.com/r/privoce/vocechat-server/tags)): + Run on x86_64 platform: + +```bash +docker run -d --restart=always \ + -p 3000:3000 \ + --name vocechat-server \ + privoce/vocechat-server:latest +``` + +For more server hosting instructions, see our documentation: https://doc.voce.chat/ + +## Preview + +- official site: https://voce.chat +- live demo: https://privoce.voce.chat/ +- demo API Docs (Swagger): https://dev.voce.chat/api/swagger + +- design: https://www.figma.com/file/EHnNr53kNmDWgUT86It6CH/UI +- text editor: https://plate.udecode.io/docs/installation +- markdown editor: https://nhn.github.io/tui.editor/latest/ +- redux: [@reduxjs/toolkit](https://redux-toolkit.js.org/introduction/getting-started) +- indexDB wrapper: https://github.com/localForage/localForage + +## Local Development + +- `git clone https://github.com/Privoce/vocechat-web vocechat-web` + +- `cd vocechat-web & yarn install` + +- `yarn start` + +- Open `localhost:3009` + +### Tools Recommended + +- [VS Code](https://code.visualstudio.com/) Editor Recommended +- VS Code plugins: + - [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint): ESLint + - [esbenp.prettier-vscode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode): Prettier + - [dsznajder.es7-react-js-snippets](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets): Extensions for React, React-Native and Redux in JS/TS with ES7+ syntax + +## License + +[GPL v3](https://github.com/Privoce/vocechat-web/blob/main/LICENSE) + +## Thanks all the contributors + + + + + +Discuss collaboration: han@privoce.com or https://bridger.chat/han + +Telegram group: https://t.me/opencfdchannel VoceChat: https://voce.chat + +Telegram channel: https://t.me/vocechat_group VoceChat Channel: https://privoce.voce.chat diff --git a/vocechat/data.yml b/vocechat/data.yml new file mode 100644 index 000000000..43e6af522 --- /dev/null +++ b/vocechat/data.yml @@ -0,0 +1,20 @@ +name: VoceChat +tags: + - 工具 +title: 一款支持独立部署的个人云社交媒体聊天服务 +type: 工具 +description: 一款支持独立部署的个人云社交媒体聊天服务 +additionalProperties: + key: vocechat + name: VoceChat + tags: + - Tool + shortDescZh: 一款支持独立部署的个人云社交媒体聊天服务 + shortDescEn: a secure chat software that supports independent deployment + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://voce.chat + github: https://github.com/Privoce/vocechat-web + document: https://doc.voce.chat diff --git a/vocechat/logo.png b/vocechat/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3843cc1f790d30d8beb0a1212422a4c17ed37b02 GIT binary patch literal 22787 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 z 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 +

+ + Logo + +

YesPlayMusic

+ +

+ 高颜值的第三方网易云播放器 +
+ 🌎 访问DEMO  |   + 📦️ 下载安装包  |   + 💬 加入交流群 +
+
+

+

+ +[![Library][library-screenshot]](https://music.qier222.com) + + +## 全新版本 +全新2.0 Alpha测试版已发布,欢迎前往 [Releases](https://github.com/qier222/YesPlayMusic/releases) 页面下载。 +当前版本将会进入维护模式,除重大bug修复外,不会再更新新功能。 + +## ✨ 特性 + +- ✅ 使用 Vue.js 全家桶开发 +- 🔴 网易云账号登录(扫码/手机/邮箱登录) +- 📺 支持 MV 播放 +- 📃 支持歌词显示 +- 📻 支持私人 FM / 每日推荐歌曲 +- 🚫🤝 无任何社交功能 +- 🌎️ 海外用户可直接播放(需要登录网易云账号) +- 🔐 支持 [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server#音源清单),自动使用[各类音源](https://github.com/UnblockNeteaseMusic/server#音源清单)替换变灰歌曲链接 (网页版不支持) + - 「各类音源」指默认启用的音源。 + - YouTube 音源需自行安装 `yt-dlp`。 +- ✔️ 每日自动签到(手机端和电脑端同时签到) +- 🌚 Light/Dark Mode 自动切换 +- 👆 支持 Touch Bar +- 🖥️ 支持 PWA,可在 Chrome/Edge 里点击地址栏右边的 ➕ 安装到电脑 +- 🟥 支持 Last.fm Scrobble +- ☁️ 支持音乐云盘 +- ⌨️ 自定义快捷键和全局快捷键 +- 🎧 支持 Mpris +- 🛠 更多特性开发中 + +## 📦️ 安装 + +Electron 版本由 [@hawtim](https://github.com/hawtim) 和 [@qier222](https://github.com/qier222) 适配并维护,支持 macOS、Windows、Linux。 + +访问本项目的 [Releases](https://github.com/qier222/YesPlayMusic/releases) +页面下载安装包。 + +- macOS 用户可以通过 Homebrew 来安装:`brew install --cask yesplaymusic` + +- Windows 用户可以通过 Scoop 来安装:`scoop install extras/yesplaymusic` + +## ⚙️ 部署至 Vercel + +除了下载安装包使用,你还可以将本项目部署到 Vercel 或你的服务器上。下面是部署到 Vercel 的方法。 + +本项目的 Demo (https://music.qier222.com) 就是部署在 Vercel 上的网站。 + +[![Powered by Vercel](https://www.datocms-assets.com/31049/1618983297-powered-by-vercel.svg)](https://vercel.com/?utm_source=ohmusic&utm_campaign=oss) + +1. 部署网易云 API,详情参见 [Binaryify/NeteaseCloudMusicApi](https://neteasecloudmusicapi.vercel.app/#/?id=%e5%ae%89%e8%a3%85) + 。你也可以将 API 部署到 Vercel。 + +2. 点击本仓库右上角的 Fork,复制本仓库到你的 GitHub 账号。 + +3. 点击仓库的 Add File,选择 Create new file,输入 `vercel.json`,将下面的内容复制粘贴到文件中,并将 `https://your-netease-api.example.com` 替换为你刚刚部署的网易云 API 地址: + +```json +{ + "rewrites": [ + { + "source": "/api/:match*", + "destination": "https://your-netease-api.example.com/:match*" + } + ] +} +``` + +4. 打开 [Vercel.com](https://vercel.com),使用 GitHub 登录。 + +5. 点击 Import Git Repository 并选择你刚刚复制的仓库并点击 Import。 + +6. 点击 PERSONAL ACCOUNT 旁边的 Select。 + +7. 点击 Environment Variables,填写 Name 为 `VUE_APP_NETEASE_API_URL`,Value 为 `/api`,点击 Add。最后点击底部的 Deploy 就可以部署到 + Vercel 了。 + +## ⚙️ 部署到自己的服务器 + +除了部署到 Vercel,你还可以部署到自己的服务器上 + +1. 部署网易云 API,详情参见 [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) +2. 克隆本仓库 + +```sh +git clone --recursive https://github.com/qier222/YesPlayMusic.git +``` + +3. 安装依赖 + +```sh +yarn install + +``` + +4. (可选)使用 Nginx 反向代理 API,将 API 路径映射为 `/api`,如果 API 和网页不在同一个域名下的话(跨域),会有一些 bug。 + +5. 复制 `/.env.example` 文件为 `/.env`,修改里面 `VUE_APP_NETEASE_API_URL` 的值为网易云 API 地址。本地开发的话可以填写 API 地址为 `http://localhost:3000`,YesPlayMusic 地址为 `http://localhost:8080`。如果你使用了反向代理 API,可以填写 API 地址为 `/api`。 + +``` +VUE_APP_NETEASE_API_URL=http://localhost:3000 +``` + +6. 编译打包 + +```sh +yarn run build +``` + +7. 将 `/dist` 目录下的文件上传到你的 Web 服务器 + +## ⚙️ Docker 部署 + +1. 构建 Docker Image + +```sh +docker build -t yesplaymusic . +``` + +2. 启动 Docker Container + +```sh +docker run -d --name YesPlayMusic -p 80:80 yesplaymusic +``` + +3. Docker Compose 启动 + +```sh +docker-compose up -d +``` + +YesPlayMusic 地址为 `http://localhost` + +## ⚙️ 部署至 Replit + +1. 新建 Repl,选择 Bash 模板 + +2. 在 Replit shell 中运行以下命令 + +```sh +bash <(curl -s -L https://raw.githubusercontent.com/qier222/YesPlayMusic/main/install-replit.sh) +``` + +3. 首次运行成功后,只需点击绿色按钮 `Run` 即可再次运行 + +4. 由于 replit 个人版限制内存为 1G(教育版为 3G),构建过程中可能会失败,请再次运行上述命令或运行以下命令: + +```sh +cd /home/runner/${REPL_SLUG}/music && yarn installl && yarn run build +``` + +## 👷‍♂️ 打包客户端 + +如果在 Release 页面没有找到适合你的设备的安装包的话,你可以根据下面的步骤来打包自己的客户端。 + +1. 打包 Electron 需要用到 Node.js 和 Yarn。可前往 [Node.js 官网](https://nodejs.org/zh-cn/) 下载安装包。安装 Node.js + 后可在终端里执行 `npm install -g yarn` 来安装 Yarn。 + +2. 使用 `git clone --recursive https://github.com/qier222/YesPlayMusic.git` 克隆本仓库到本地。 + +3. 使用 `yarn install` 安装项目依赖。 + +4. 复制 `/.env.example` 文件为 `/.env` 。 + +5. 选择下列表格的命令来打包适合的你的安装包,打包出来的文件在 `/dist_electron` 目录下。了解更多信息可访问 [electron-builder 文档](https://www.electron.build/cli) + +| 命令 | 说明 | +| ------------------------------------------ | ------------------------- | +| `yarn electron:build --windows nsis:ia32` | Windows 32 位 | +| `yarn electron:build --windows nsis:arm64` | Windows ARM | +| `yarn electron:build --linux deb:armv7l` | Debian armv7l(树莓派等) | +| `yarn electron:build --macos dir:arm64` | macOS ARM | + +## :computer: 配置开发环境 + +本项目由 [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 提供 API。 + +运行本项目 + +```shell +# 安装依赖 +yarn install + +# 创建本地环境变量 +cp .env.example .env + +# 运行(网页端) +yarn serve + +# 运行(electron) +yarn electron:serve +``` + +本地运行 NeteaseCloudMusicApi,或者将 API [部署至 Vercel](#%EF%B8%8F-部署至-vercel) + +```shell +# 运行 API (默认 3000 端口) +yarn netease_api:run +``` + +## ☑️ Todo + +查看 Todo 请访问本项目的 [Projects](https://github.com/qier222/YesPlayMusic/projects/1) + +欢迎提 Issue 和 Pull request。 + +## 📜 开源许可 + +本项目仅供个人学习研究使用,禁止用于商业及非法用途。 + +基于 [MIT license](https://opensource.org/licenses/MIT) 许可进行开源。 + +## 灵感来源 + +API 源代码来自 [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) + +- [Apple Music](https://music.apple.com) +- [YouTube Music](https://music.youtube.com) +- [Spotify](https://www.spotify.com) +- [网易云音乐](https://music.163.com) + +## 🖼️ 截图 + +![lyrics][lyrics-screenshot] +![library-dark][library-dark-screenshot] +![album][album-screenshot] +![home-2][home-2-screenshot] +![artist][artist-screenshot] +![search][search-screenshot] +![home][home-screenshot] +![explore][explore-screenshot] + + + + +[album-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/album.png +[artist-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/artist.png +[explore-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/explore.png +[home-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/home.png +[home-2-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/home-2.png +[lyrics-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/lyrics.png +[library-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/library.png +[library-dark-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/library-dark.png +[search-screenshot]: https://github.com/qier222/YesPlayMusic/raw/master/images/search.png \ No newline at end of file diff --git a/yesplaymusic/data.yml b/yesplaymusic/data.yml new file mode 100644 index 000000000..0185ff28e --- /dev/null +++ b/yesplaymusic/data.yml @@ -0,0 +1,20 @@ +name: YesPlayMusic +tags: + - 工具 +title: 一款高颜值的第三方网易云播放器 +type: 工具 +description: 一款高颜值的第三方网易云播放器 +additionalProperties: + key: yesplaymusic + name: YesPlayMusic + tags: + - Tool + shortDescZh: 一款高颜值的第三方网易云播放器 + shortDescEn: A high-end third-party NetEase cloud player + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://music.qier222.com/ + github: https://github.com/qier222/YesPlayMusic + document: https://github.com/qier222/YesPlayMusic diff --git a/yesplaymusic/logo.png b/yesplaymusic/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3313cb37647e1fa2fea8d7d74d3b22c2d53f34ba GIT binary patch literal 23731 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 i$5oHTGa~NspZ^~fZ-&YufCzE`0000 + + YOURLS + + + +> Your Own URL Shortener + +![CI](https://github.com/YOURLS/YOURLS/workflows/CI/badge.svg) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/YOURLS/YOURLS/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/YOURLS/YOURLS/?branch=master) ![PHP Version Support](https://img.shields.io/packagist/php-v/yourls/yourls) [![Packagist](https://img.shields.io/packagist/v/yourls/yourls.svg)](https://packagist.org/packages/yourls/yourls) [![OpenCollective](https://opencollective.com/yourls/backers/badge.svg)](https://opencollective.com/yourls#contributors) +[![OpenCollective](https://opencollective.com/yourls/sponsors/badge.svg)](#sponsors) + +**YOURLS** is a set of PHP scripts that will allow you to run Your Own URL Shortener, on **your** server. You'll have full control over your data, detailed stats, analytics, plugins, and more. It's free and open-source. + +## Quick Start + +Get YOURLS : +* Download the latest [release](https://github.com/YOURLS/YOURLS/releases) +* Using Composer? You can simply `composer create-project yourls/yourls .` in an empty directory. + +Install YOURLS: +* Read [yourls.org](https://yourls.org) for starters +* The complete documentation is on [docs.yourls.org](https://docs.yourls.org) and contains everything from beginners to experts. + +## Community news, tips and tricks + +* Read and subscribe to the [The Official YOURLS Blog](http://blog.yourls.org) +* Check what the user community makes: plugins, tools, guides and more on [Awesome YOURLS](https://github.com/YOURLS/awesome-yourls) +* Engage users and ask for help in our [community discussions](https://github.com/YOURLS/YOURLS/discussions) +* Keep track of development: "Star" and "Watch" this project, follow [commit messages](https://github.com/YOURLS/YOURLS/commits/master) + +## Contributing + +Feature suggestion? Bug to report? + +__Before opening any issue, please search for existing [issues](https://github.com/YOURLS/YOURLS/issues) (open and closed) and read the [Contributing Guidelines](https://github.com/YOURLS/.github/blob/master/CONTRIBUTING.md).__ + + +## Backers + +Do you use and enjoy YOURLS? [Become a backer](https://opencollective.com/yourls#backer) and show your support to our open source project. + +[![](https://opencollective.com/yourls/backer/0/avatar.svg)](https://opencollective.com/yourls/backer/0/website) +[![](https://opencollective.com/yourls/backer/1/avatar.svg)](https://opencollective.com/yourls/backer/1/website) +[![](https://opencollective.com/yourls/backer/2/avatar.svg)](https://opencollective.com/yourls/backer/2/website) +[![](https://opencollective.com/yourls/backer/3/avatar.svg)](https://opencollective.com/yourls/backer/3/website) +[![](https://opencollective.com/yourls/backer/4/avatar.svg)](https://opencollective.com/yourls/backer/4/website) +[![](https://opencollective.com/yourls/backer/5/avatar.svg)](https://opencollective.com/yourls/backer/5/website) +[![](https://opencollective.com/yourls/backer/6/avatar.svg)](https://opencollective.com/yourls/backer/6/website) +[![](https://opencollective.com/yourls/backer/7/avatar.svg)](https://opencollective.com/yourls/backer/7/website) +[![](https://opencollective.com/yourls/backer/8/avatar.svg)](https://opencollective.com/yourls/backer/8/website) +[![](https://opencollective.com/yourls/backer/9/avatar.svg)](https://opencollective.com/yourls/backer/9/website) +[![](https://opencollective.com/yourls/backer/10/avatar.svg)](https://opencollective.com/yourls/backer/10/website) +[![](https://opencollective.com/yourls/backer/11/avatar.svg)](https://opencollective.com/yourls/backer/11/website) +[![](https://opencollective.com/yourls/backer/12/avatar.svg)](https://opencollective.com/yourls/backer/12/website) +[![](https://opencollective.com/yourls/backer/13/avatar.svg)](https://opencollective.com/yourls/backer/13/website) +[![](https://opencollective.com/yourls/backer/14/avatar.svg)](https://opencollective.com/yourls/backer/14/website) +[![](https://opencollective.com/yourls/backer/15/avatar.svg)](https://opencollective.com/yourls/backer/15/website) +[![](https://opencollective.com/yourls/backer/16/avatar.svg)](https://opencollective.com/yourls/backer/16/website) +[![](https://opencollective.com/yourls/backer/17/avatar.svg)](https://opencollective.com/yourls/backer/17/website) +[![](https://opencollective.com/yourls/backer/18/avatar.svg)](https://opencollective.com/yourls/backer/18/website) +[![](https://opencollective.com/yourls/backer/19/avatar.svg)](https://opencollective.com/yourls/backer/19/website) +[![](https://opencollective.com/yourls/backer/20/avatar.svg)](https://opencollective.com/yourls/backer/20/website) +[![](https://opencollective.com/yourls/backer/21/avatar.svg)](https://opencollective.com/yourls/backer/21/website) +[![](https://opencollective.com/yourls/backer/22/avatar.svg)](https://opencollective.com/yourls/backer/22/website) +[![](https://opencollective.com/yourls/backer/23/avatar.svg)](https://opencollective.com/yourls/backer/23/website) +[![](https://opencollective.com/yourls/backer/24/avatar.svg)](https://opencollective.com/yourls/backer/24/website) +[![](https://opencollective.com/yourls/backer/25/avatar.svg)](https://opencollective.com/yourls/backer/25/website) +[![](https://opencollective.com/yourls/backer/26/avatar.svg)](https://opencollective.com/yourls/backer/26/website) +[![](https://opencollective.com/yourls/backer/27/avatar.svg)](https://opencollective.com/yourls/backer/27/website) +[![](https://opencollective.com/yourls/backer/28/avatar.svg)](https://opencollective.com/yourls/backer/28/website) +[![](https://opencollective.com/yourls/backer/29/avatar.svg)](https://opencollective.com/yourls/backer/29/website) + + +## Sponsors + +Does your company use YOURLS? Ask your manager or marketing team if your company would be interested in supporting our project. Your company logo will show here. Help support our open-source development efforts by [becoming a sponsor](https://opencollective.com/yourls). + +[![](https://opencollective.com/yourls/sponsor/0/avatar.svg)](https://opencollective.com/yourls/sponsor/0/website) +[![](https://opencollective.com/yourls/sponsor/1/avatar.svg)](https://opencollective.com/yourls/sponsor/1/website) +[![](https://opencollective.com/yourls/sponsor/2/avatar.svg)](https://opencollective.com/yourls/sponsor/2/website) +[![](https://opencollective.com/yourls/sponsor/3/avatar.svg)](https://opencollective.com/yourls/sponsor/3/website) +[![](https://opencollective.com/yourls/sponsor/4/avatar.svg)](https://opencollective.com/yourls/sponsor/4/website) +[![](https://opencollective.com/yourls/sponsor/5/avatar.svg)](https://opencollective.com/yourls/sponsor/5/website) +[![](https://opencollective.com/yourls/sponsor/6/avatar.svg)](https://opencollective.com/yourls/sponsor/6/website) +[![](https://opencollective.com/yourls/sponsor/7/avatar.svg)](https://opencollective.com/yourls/sponsor/7/website) +[![](https://opencollective.com/yourls/sponsor/8/avatar.svg)](https://opencollective.com/yourls/sponsor/8/website) +[![](https://opencollective.com/yourls/sponsor/9/avatar.svg)](https://opencollective.com/yourls/sponsor/9/website) +[![](https://opencollective.com/yourls/sponsor/10/avatar.svg)](https://opencollective.com/yourls/sponsor/10/website) +[![](https://opencollective.com/yourls/sponsor/11/avatar.svg)](https://opencollective.com/yourls/sponsor/11/website) +[![](https://opencollective.com/yourls/sponsor/12/avatar.svg)](https://opencollective.com/yourls/sponsor/12/website) +[![](https://opencollective.com/yourls/sponsor/13/avatar.svg)](https://opencollective.com/yourls/sponsor/13/website) +[![](https://opencollective.com/yourls/sponsor/14/avatar.svg)](https://opencollective.com/yourls/sponsor/14/website) +[![](https://opencollective.com/yourls/sponsor/15/avatar.svg)](https://opencollective.com/yourls/sponsor/15/website) +[![](https://opencollective.com/yourls/sponsor/16/avatar.svg)](https://opencollective.com/yourls/sponsor/16/website) +[![](https://opencollective.com/yourls/sponsor/17/avatar.svg)](https://opencollective.com/yourls/sponsor/17/website) +[![](https://opencollective.com/yourls/sponsor/18/avatar.svg)](https://opencollective.com/yourls/sponsor/18/website) +[![](https://opencollective.com/yourls/sponsor/19/avatar.svg)](https://opencollective.com/yourls/sponsor/19/website) + + +## License + +Free software. Do whatever the hell you want with it. +YOURLS is released under the [MIT license](LICENSE). diff --git a/yourls/data.yml b/yourls/data.yml new file mode 100644 index 000000000..d7e27ad53 --- /dev/null +++ b/yourls/data.yml @@ -0,0 +1,20 @@ +name: YOURLS +tags: + - 工具 +title: PHP驱动的标准自托管URL缩短器 +type: 工具 +description: PHP驱动的标准自托管URL缩短器 +additionalProperties: + key: yourls + name: YOURLS + tags: + - Tool + shortDescZh: PHP驱动的标准自托管URL缩短器 + shortDescEn: The de facto standard self hosted URL shortener in PHP + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://yourls.org/ + github: https://github.com/YOURLS/YOURLS + document: https://yourls.org/docs diff --git a/yourls/logo.png b/yourls/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8fecff3e261dd6e52eec8a1b9da531ffcab2cf76 GIT binary patch literal 5534 zcmds*_dgVlAIHzu5!q+g8Oc7B6Oke_vbT$~$zF*wO2(aWNysdc?3o>kBje8A$6dxH zdvCrz|Hk)+_xt_J`?vS|@qRtuuefJ=8rOkbKmY)6T}xBV@T%7S7qrw@`N06S%vHJO zt!d#007we_7i7U-R0072wr5&us>Z=t>)9{;P1L`~v;irZZ`#q)3X{v+O?k|En>F*v z4THfaRIWE>EcO(XQv-w72g?E#^Pr`O1QCX^sL6Xp5wV|XV=2f*Q=)W5?F?_~X8cBk zXJxkB@GZ=I_4{dKTU|A~yt7$$FEMDCKDSYhXhfC^v|n9#HL8t7;<9&iq_>s|n(y zZtdwSLdpA*Kmu@3IFk?9hrFKLk&vbc9s<==7jiE|$2yQtkeQLkOnCeK+@X?YNOwWq zi8uMObe|o)lM6DPvsSwh1!oonRzFmGi`+HU0(HJDhpQJ<3iIosCI!K1NZDCbSB;OH zIE1w}wgB044z4aK%rQh++yTE@l)uyPY-fMF5vUUpl!p*9(1SN+017 zcqI2iKoVsk0OW?s;44fv4oZEjhNTi_@%{Z`A+c5W(ur3m{3O~-ex1<0{%SH6)>GaB z)`mkNWxCqFyu(JTBhWg&Y|Fb}tej-^R^MyQdzQJHt0;H`z$i#u@Ozl1Y_K7tbF2?y zvRdd==hz<4u57+7&?oQdJhsfc)-UD|gkU-aBH{Q^3YXzL<&|&yE*WzXo)(-A^{yT5 z@R=cEC1%L@HuP}|2L(q_VxIblcZC-glrfM_1tJF~?8D`8}vfTN`G=W?C zvonY1N;r?j)5oXSa#;+D&K^{kr|v+x1tjZic@e}H)Uti8BJ6dq=5z_tnYa(jk^13yspRX{iHE~9G0FKASjcGMN2b!#&rYf>mtcgcrHOoGJNN z(}^-ka1tOKXy3d+vdOv}mHR;QsK83NQ^EyBTQ)E~-dP z4T4Tq1HcS1`y=Ke=_&EFtWlLKbI>|4L>>bhPrHBdEBP=&6_b8GG^?TZmfY)Tnk)%x z-ub{txs1(ANy@U|i_F4!#~yU2^5(K)geNAw%#->Pr383CGP)gN8+7iyq@Q)TIK#@S zv48n7*&o;Yd;|a3bvo}y?n)~ro#yAb6xaglBXqrWEnZu@k&xlqZ{2ijO@f&nPT)_= z>L^mypn>FG-;>7}A3tRfbD5tYcH+!@e%EYLxtf>dt6Pfd@bmn(Te;rSuN{$tNmo~0 zO+aOm0IjWSz<3=f@j@%K*;Qk(*qtpOx6$#7V;^WAQU+O`Dwd>VuZ`U!U;YER7J7~x zvsUtSN~RvOl*eYrf*}nF0+h7w!Qr9QOKK3_MH= zT5vQHeRSDfXfEXxaeL0{=TTDHX~q~0->%G7=DIb|q1oolQC~TX?;;5%PGM>*L_42TXw%zeQbyJ*ZJ-dax*ML3k1@Ub^Gm9(96JY6xQ7RwV z9J<4rIw?y=|FgwJ0hL?R-zUi1(B1b?O(tTd#bdbwYnOExR$4GGaCxh3azbHoTBkYj z(>W#x7rJ$~UN?)o;nO`k`bDLecO~$*e?-}jd-Ms(S5!_1TvzxckW#__*Li#lv}-d(gVVBeIB2E+ zYishfc^BE!fUvfPOEG67@YB-nwayJ)xd{-ORw8&~UE-lpeN_H!94YSbgW6bmla>~J zzh`$(j?Leh*1HKtVQJj(-j6RDTTTb4Z7&>zV3$XJqx<4v-h%iVnHF7JIgGWzL5Kce zSVYpSThnsaly16NYnh!EMtY}K@{Cx3_3v|g^6TWc;6xmbnu)1LN|KoN;5f7qA$ED@ z?V4QmQA+1RCJH`N>)o71Q47KF5JcI~bdmCS;CajKTvPdkq~Zr{DnBTat}8y6j>t=w zT`vhhl|~>oOOngK?F{xWzW_#xomKTf`b$wPLxgfRK zoy?-x^|W1e@<)9{RSmoB%I=uK1RDRH>ax);IqkRRbJZ{NPXSnOF>l;^{fwij;%Doc zTIIjyV-EhbEKJ9U28r}Yi4vD5mSya6Hh~yb@ryp%YP=$S1QC-y(eZc?{EptEYbo`J zph(x~Rs7WopSt_Xe{syfnQEUX#=hNyQlC9{TH5?B--<~2J=^>?B%@yrlSMJNI@tD0 zz5feX=?Kg5iOU2N_FA7fz)fA89{yz(vPHSU& z3fKOF9;;=l-&2vSJpWkM$QrC@i7h_*v=j0DL1Nq4%>!1}Dmbh`eV6#vzc8RiPNgQh zUHmzP-jW4JSa$UCkyO zkhR9x`%My?p-T$NlFr+VGcA;O8Q*zkXfQo~sBH9OGIF6T^UF|`Ba2iDO#-AIW7*H- z8TUB*y8$DJy$_fG5yGTbwF@D>lbmQ^vX>_``bltRwqX}z_FDJP>1>%l*I|mSHKa_E z72)C;8?~C6C1JbJfT7(FEpLf}q<9BbG!NInw|G*>zzlr>Ru+ThGZFVTXeZD)|L_E# zp^Y}Whk;rD>d^27^Fx&u$v}@O!N1s(o4@eBcvJS;ReDKzsX<|suciEMf5#21BWt2s zKRT~ZPG0GEsnXT$QD z-l)KVq4B#TeuwR<{Z@5D?ixB`geA=)H{CcC{xj0+d>;bQ+rQu?$w`_iTkwYNdf^f? z5W<;#7X}uC^UbL){JtEW*sy3s>)vs@2h+8UNk%M-PtnLd-$>W0(r0SZ>hI>04r;>O zx2N0pPbiN$j6MmJE4c(cz0Q48c;V&-!jFu9UZJyZvA&&|$%5b2SUd*!vgmXMnHza1 z6nOf`irgj&R6bpuqW?oh#0({-e7xz4f*2kI8ME){Lt}39jq-jKoFMiruXr3e1}*87 z_rp?uIlJGZ*#_1j&qQJp^+uC5_K7Pn=H*wTm}XfU%k5uej}v>C6H7)Grj>IVxk?s) zIv1WsU*2g0v%i?^Ey+cYygqPDpKbVoP8r~OPKd!JcVW)3Q~qdguLOsn++i>&IuV@V+Rsl4BG0T z{pS1^pJDdO2!$pQv-jKV$lB3&SL*Xg6cdGTGsy=X+HCI}BnE z3Rqb;o%L1s_)4zWsU>i6kt{X8>Er8HO>qDpIvVr`!=(3%M@~|NJB5oE%faZSx!BI&wy=XbqGv4V+U+d!^ri(99>oO!TWTT$RFY;!}Ue_?7igP zS};^%*iaLQAUAP|*Ey*1obhy$m~TgUjdwffw)w1?@XU4I{S%l0SWfSI#diiNbO5i2M1VN^NBG~Q%SdOp@ z9DU)A7f(Ry{p-xY&-m(QF57Ae!JmAiT}8}w{j9SJ4qBlul(aP}%h&p@6qW$^^-XS{c&O*q2@z-EL3%93}6Oii=L zzWrE#T^V8TH6OV(snqm9Pe$v(lxAGOQ)Pgjx!VVblhu?|6zw!2OE!Dmbag8nyODOgU{7HgcPLC4qrl5AeR88b;lbkjU`$BX+upGTsRmXPGqK2 zK&X*{AFt4<-`~}qiyE%x2PsG&rSIlEVpQnb?JbgR(Q-dNRgWoJYWEPz_(M z62}$Tn1^1{atTgyxs*b`JQh=KbxwyVuku30xFa=M(RYn;4l@|gTm#}}TGsSkm%6(6 z`&w^+{5K8e}~_(pTlpMANdi;?whgcwSW?+~mg2L4O$aAwB{tw(30zerhzIBtJ@ljPtrCz3iu+9P0OYrgS^lHFqb>xeq;#YwxVY5;Qq{he_< zbe(5o3aHCqg-xl`NZ5fec6Fzyl%CqLe&GZ$Wj8UZ0-)~J?stssfo&@^)X2O7#-~dM zQF)154}89E#Ugy5B=Lo>Z8d~)Vo&*FO`<0^bl>ca5`iABn`Nl}*IT!x-r@ z*5{7cz#rCasY~4TDK&ml&2;fSN#F<}@dTsQp{p_7=NW&KpVUJb)yqI^lY6#MTic=H zbfl57vyr%+_uNial+PqkRsc<0YAD3!^7Ia|O4qHVxVsCf4Na z_=e4gvpM1dlOC-~XKXcy)|T=9{_~L0r1GGezkwxKsei{>F1Cl3AVjXqDgl3xnEoJJ zFLgU0jOLc_-sTi^YKO&{hl$^mh$3M+t@;6&^tkprQ0}yFi54n{7&brkV%`W3)SbH+ zrE5H|HL|=U3PDHQ-lY&>$&9zN(irg$g`DZTGC1Y~BJ>OP>ifgR-2yMER6SIqj_tAk zcK$xLM+f|8bqmTGtLepLVVbWmcC^VAA5!wN&k@>);BW|kjxxp2PUD2_L^lV2%RX0}9xxv`K zyWYd)8<=Z?Ck*Cf;_{d`Dh6_@H_)cg&wLRz(~GNH_d83e=DM_KcU4>NBe|GrnPHt; z@EJa5@D%TD!X4h*byh9%?8|@r*&CrgbA6GinDpS~Jjt)xs$$wNZX;e&uzsQb|8xAh bF3DnkeoE)Wr~J4wTmf3@dTQm5o=5!;Z=bks literal 0 HcmV?d00001