mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 13:04:42 +00:00
Compare commits
49 Commits
v0.4.4-2-a
...
v0.4.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0883f5f3aa | ||
|
|
36dda53e9c | ||
|
|
53c3879907 | ||
|
|
ef57d3348d | ||
|
|
7a76aca022 | ||
|
|
fffdc7fd5e | ||
|
|
29d16d13ba | ||
|
|
54a115ae89 | ||
|
|
17fa7868a4 | ||
|
|
27d6dd86e2 | ||
|
|
ae50a9bb17 | ||
|
|
caf3347da9 | ||
|
|
718a08eab2 | ||
|
|
6f722b3506 | ||
|
|
e722d841a9 | ||
|
|
3ccf58695b | ||
|
|
c52386cef4 | ||
|
|
acac2df40f | ||
|
|
0b507cb7ad | ||
|
|
ac90509c66 | ||
|
|
abf7134710 | ||
|
|
f9a26af93f | ||
|
|
33eacbf4b3 | ||
|
|
262e0d49c8 | ||
|
|
689b0f769a | ||
|
|
8f8a082888 | ||
|
|
9b8c6f4299 | ||
|
|
657cbe5c41 | ||
|
|
b17bff68dd | ||
|
|
7807cfdb01 | ||
|
|
9e5381710f | ||
|
|
fa62c65526 | ||
|
|
3aea945277 | ||
|
|
4d8ca182cb | ||
|
|
b727606a0a | ||
|
|
428be5f2c2 | ||
|
|
995d67543d | ||
|
|
590beac43a | ||
|
|
e7bf227232 | ||
|
|
eedfdde311 | ||
|
|
38c7b5a569 | ||
|
|
8c0b219621 | ||
|
|
23fc677f30 | ||
|
|
a06508783c | ||
|
|
37fee157dd | ||
|
|
3f1c7098bd | ||
|
|
b11d046c52 | ||
|
|
d6a9ba65ed | ||
|
|
5f1df76dbf |
2
.github/workflows/casa.yml
vendored
2
.github/workflows/casa.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
|||||||
# ls
|
# ls
|
||||||
|
|
||||||
|
|
||||||
- name: Set enviroment for github-release
|
- name: Set environment for github-release
|
||||||
run: |
|
run: |
|
||||||
echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
|
echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||||
echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
|
echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||||
|
|||||||
2
.github/workflows/codecov.yml
vendored
2
.github/workflows/codecov.yml
vendored
@@ -20,6 +20,8 @@ jobs:
|
|||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20"
|
go-version: "1.20"
|
||||||
|
- name: generate OPENAPI
|
||||||
|
run: go generate
|
||||||
- name: Run coverage
|
- name: Run coverage
|
||||||
run: go test -race -failfast -coverprofile=coverage.txt -covermode=atomic -v ./...
|
run: go test -race -failfast -coverprofile=coverage.txt -covermode=atomic -v ./...
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
|
|||||||
2
.github/workflows/demo.yml
vendored
2
.github/workflows/demo.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Get old instance and snapshot name, create new instance name
|
- name: Get old instance and snapshot name, create new instance name
|
||||||
run: |
|
run: |
|
||||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=updateto_to_0.4.4-1684926517" >> $GITHUB_ENV
|
echo "OLD_INSTANCE_SNAPSHOT_NAME=CasaOS-v0.4.4-3-Demo-1700132299" >> $GITHUB_ENV
|
||||||
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | tail -1 | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | tail -1 | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||||
# echo "OLD_INSTANCE_NAME=CasaOS-Demo-1687680295" >> $GITHUB_ENV
|
# echo "OLD_INSTANCE_NAME=CasaOS-Demo-1687680295" >> $GITHUB_ENV
|
||||||
echo "NEW_INSTANCE_NAME= CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
echo "NEW_INSTANCE_NAME= CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||||
|
|||||||
6
.github/workflows/push_events_to_discord.yml
vendored
6
.github/workflows/push_events_to_discord.yml
vendored
@@ -40,9 +40,3 @@ jobs:
|
|||||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||||
with:
|
with:
|
||||||
webhook: ${{ secrets.Discord_CasaOS_Bug_Webhook }}
|
webhook: ${{ secrets.Discord_CasaOS_Bug_Webhook }}
|
||||||
|
|
||||||
- name: Alpha Issues & Comments
|
|
||||||
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'alpha') }}
|
|
||||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
|
||||||
with:
|
|
||||||
webhook: ${{ secrets.Discord_CasaOS_Alpha_Webhook }}
|
|
||||||
|
|||||||
8
.github/workflows/push_test_server.yml
vendored
8
.github/workflows/push_test_server.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: git global
|
- name: git global
|
||||||
run: sudo git config --global --add safe.directory '*'
|
run: sudo git config --global --add safe.directory '*'
|
||||||
- name: set version
|
- name: set version
|
||||||
run: sudo git tag v99.99.99-alpha
|
run: sudo git tag v00.00.00-alpha
|
||||||
|
|
||||||
- name: Fetch all tags
|
- name: Fetch all tags
|
||||||
run: sudo git fetch --force --tags
|
run: sudo git fetch --force --tags
|
||||||
@@ -50,6 +50,12 @@ jobs:
|
|||||||
args: release --rm-dist --snapshot
|
args: release --rm-dist --snapshot
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GoogleID: ${{ secrets.GoogleID }}
|
||||||
|
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||||
|
DropboxKey: ${{ secrets.DropboxKey }}
|
||||||
|
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||||
|
OneDriveID: ${{ secrets.OneDriveID }}
|
||||||
|
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
||||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
|
|
||||||
|
|||||||
68
.github/workflows/release.yml
vendored
68
.github/workflows/release.yml
vendored
@@ -7,57 +7,19 @@ on:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
goreleaser:
|
call-workflow-passing-data:
|
||||||
runs-on: ubuntu-22.04
|
uses: IceWhaleTech/github/.github/workflows/go_release.yml@main
|
||||||
steps:
|
with:
|
||||||
- name: Install dependencies for cross-compiling
|
project-name: CasaOS
|
||||||
run: |
|
file-name: casaos
|
||||||
sudo apt update
|
secrets:
|
||||||
sudo apt-get --no-install-recommends --yes install \
|
GoogleID: ${{ secrets.GoogleID }}
|
||||||
upx libc6-dev-amd64-cross \
|
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||||
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
|
DropboxKey: ${{ secrets.DropboxKey }}
|
||||||
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
|
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||||
- name: Checkout
|
OneDriveID: ${{ secrets.OneDriveID }}
|
||||||
uses: actions/checkout@v3
|
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||||
with:
|
OneDrivePublic: ${{ secrets.OneDrivePublic }}
|
||||||
fetch-depth: 0
|
OSS_KEY_ID: ${{ secrets.OSS_KEY_ID }}
|
||||||
- name: Fetch all tags
|
OSS_KEY_SECRET: ${{ secrets.OSS_KEY_SECRET }}
|
||||||
run: git fetch --force --tags
|
|
||||||
|
|
||||||
- name: Get version
|
|
||||||
id: get_version
|
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
with:
|
|
||||||
go-version: "1.20"
|
|
||||||
- name: Run GoReleaser
|
|
||||||
uses: goreleaser/goreleaser-action@v4
|
|
||||||
with:
|
|
||||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
|
||||||
distribution: goreleaser
|
|
||||||
version: latest
|
|
||||||
args: release --rm-dist
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
|
||||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
|
||||||
|
|
||||||
- name: Upload to oss
|
|
||||||
id: upload_to_oss
|
|
||||||
uses: tvrcgo/upload-to-oss@master
|
|
||||||
with:
|
|
||||||
key-id: ${{ secrets.OSS_KEY_ID }}
|
|
||||||
key-secret: ${{ secrets.OSS_KEY_SECRET }}
|
|
||||||
region: oss-cn-shanghai
|
|
||||||
bucket: casaos
|
|
||||||
assets: |
|
|
||||||
dist/checksums.txt:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/checksums.txt
|
|
||||||
dist/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
dist/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
dist/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
dist/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
dist/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
dist/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -37,6 +37,7 @@ github.com
|
|||||||
.all-contributorsrc
|
.all-contributorsrc
|
||||||
dist
|
dist
|
||||||
CasaOS
|
CasaOS
|
||||||
|
/codegen
|
||||||
|
|
||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ builds:
|
|||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -32,14 +38,20 @@ builds:
|
|||||||
- amd64
|
- amd64
|
||||||
- id: casaos-arm64
|
- id: casaos-arm64
|
||||||
binary: build/sysroot/usr/bin/casaos
|
binary: build/sysroot/usr/bin/casaos
|
||||||
hooks:
|
# hooks:
|
||||||
post:
|
# post:
|
||||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
# - upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||||
env:
|
env:
|
||||||
- CC=aarch64-linux-gnu-gcc
|
- CC=aarch64-linux-gnu-gcc
|
||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -61,6 +73,12 @@ builds:
|
|||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -98,9 +116,9 @@ builds:
|
|||||||
- amd64
|
- amd64
|
||||||
- id: casaos-migration-tool-arm64
|
- id: casaos-migration-tool-arm64
|
||||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||||
hooks:
|
# hooks:
|
||||||
post:
|
# post:
|
||||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
# - upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||||
main: ./cmd/migration-tool
|
main: ./cmd/migration-tool
|
||||||
env:
|
env:
|
||||||
- CC=aarch64-linux-gnu-gcc
|
- CC=aarch64-linux-gnu-gcc
|
||||||
@@ -143,7 +161,7 @@ builds:
|
|||||||
goarm:
|
goarm:
|
||||||
- "7"
|
- "7"
|
||||||
archives:
|
archives:
|
||||||
- name_template: >-
|
- name_template: >-
|
||||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||||
id: casaos
|
id: casaos
|
||||||
builds:
|
builds:
|
||||||
|
|||||||
21
README.md
21
README.md
@@ -46,6 +46,11 @@
|
|||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||||
<a href="#credits"><img alt="All Contributors" src="https://img.shields.io/static/v1?label=All%20Contributors&message=15&color=162453&style=flat-square&logo=Handshake&logoColor=fff" /></a>
|
<a href="#credits"><img alt="All Contributors" src="https://img.shields.io/static/v1?label=All%20Contributors&message=15&color=162453&style=flat-square&logo=Handshake&logoColor=fff" /></a>
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||||
|
<br/>
|
||||||
|
<!-- CasaOS YouTube -->
|
||||||
|
<a href="https://www.youtube.com/channel/UC2zMrUYT17AJhIl9XWZzT8g" target="_blank">
|
||||||
|
<img alt="YouTube Tutoial Views" src="https://img.shields.io/youtube/channel/views/UC2zMrUYT17AJhIl9XWZzT8g?style=for-the-badge&logo=youtube&logoColor=red&label=YouTube%20Tutoial%20Views" />
|
||||||
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<!-- CasaOS Links -->
|
<!-- CasaOS Links -->
|
||||||
<a href="https://www.casaos.io" target="_blank">Website</a> |
|
<a href="https://www.casaos.io" target="_blank">Website</a> |
|
||||||
@@ -83,7 +88,7 @@ Furthermore, the personal cloud could combine personal data to train personalize
|
|||||||
- Multiple hardware and base system support
|
- Multiple hardware and base system support
|
||||||
- ZimaBoard, NUC, RPi, old computers, whatever is available.
|
- ZimaBoard, NUC, RPi, old computers, whatever is available.
|
||||||
- Selected apps in the app store, one-click installation
|
- Selected apps in the app store, one-click installation
|
||||||
- Nextcloud, HomeAssiant, AdGuard, Jellyfin, *arr and more!
|
- Nextcloud, HomeAssistant, AdGuard, Jellyfin, *arr and more!
|
||||||
- Easily install numerous Docker apps
|
- Easily install numerous Docker apps
|
||||||
- Over 100,000 apps from the Docker ecosystem can be easily installed
|
- Over 100,000 apps from the Docker ecosystem can be easily installed
|
||||||
- Elegant drive and file management
|
- Elegant drive and file management
|
||||||
@@ -104,7 +109,7 @@ CasaOS fully supports ZimaBoard, Intel NUC, and Raspberry Pi. Also, more compute
|
|||||||
### System Compatibility
|
### System Compatibility
|
||||||
|
|
||||||
Official Support
|
Official Support
|
||||||
- Debian 11 (✅ Tested, Recommended)
|
- Debian 12 (✅ Tested, Recommended)
|
||||||
- Ubuntu Server 20.04 (✅ Tested)
|
- Ubuntu Server 20.04 (✅ Tested)
|
||||||
- Raspberry Pi OS (✅ Tested)
|
- Raspberry Pi OS (✅ Tested)
|
||||||
|
|
||||||
@@ -146,13 +151,13 @@ curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | sudo bash
|
|||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for the crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||||
|
|
||||||
After looking at many systems and software on the market, the team found no server system designed for home scenarios, sadly true.
|
After looking at many systems and software on the market, the team found no server system designed for home scenarios, sadly true.
|
||||||
|
|
||||||
So, we set out to build this open source project to develop CasaOS with our own hands, everyone in the community, and you.
|
So, we set out to build this open-source project to develop CasaOS with our own hands, everyone in the community, and you.
|
||||||
|
|
||||||
We believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
We believe that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||||
|
|
||||||
**A warm welcome for you to get help or share great ideas in the [Discord](https://discord.gg/knqAbbBbeX)!**
|
**A warm welcome for you to get help or share great ideas in the [Discord](https://discord.gg/knqAbbBbeX)!**
|
||||||
|
|
||||||
@@ -162,8 +167,8 @@ We believes that through community-driven collaborative innovation and open comm
|
|||||||
|
|
||||||
CasaOS is a community-driven open source project and the people involved are CasaOS users. That means CasaOS will always need contributions from community members just like you!
|
CasaOS is a community-driven open source project and the people involved are CasaOS users. That means CasaOS will always need contributions from community members just like you!
|
||||||
|
|
||||||
- See <https://wiki.casaos.io/en/contribute> for ways of contribution to CasaOS
|
- See <https://wiki.casaos.io/en/contribute> for ways of contributing to CasaOS
|
||||||
- See <https://wiki.casaos.io/en/contribute/development> if you want to be involved in code contribution specificially
|
- See <https://wiki.casaos.io/en/contribute/development> if you want to be involved in code contribution specifically
|
||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
<p ><a href="https://www.buymeacoffee.com/icewhaletech"> <img align="center" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="bappi2097" target="_blank" /></a></p>
|
<p ><a href="https://www.buymeacoffee.com/icewhaletech"> <img align="center" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="bappi2097" target="_blank" /></a></p>
|
||||||
@@ -209,7 +214,7 @@ Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontribu
|
|||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ servers:
|
|||||||
tags:
|
tags:
|
||||||
- name: Health methods
|
- name: Health methods
|
||||||
description: |-
|
description: |-
|
||||||
(TODO)
|
These methods are used to check the health and status of the CasaOS API and associated services.
|
||||||
- name: File methods
|
|
||||||
|
- name: File methods
|
||||||
description: |-
|
description: |-
|
||||||
(TODO)
|
The File methods allow you to interact with files and directories on the CasaOS system.
|
||||||
|
|
||||||
x-tagGroups:
|
x-tagGroups:
|
||||||
- name: Methods
|
- name: Methods
|
||||||
@@ -89,6 +90,107 @@ paths:
|
|||||||
$ref: "#/components/responses/ResponseOK"
|
$ref: "#/components/responses/ResponseOK"
|
||||||
"500":
|
"500":
|
||||||
$ref: "#/components/responses/ResponseInternalServerError"
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
|
||||||
|
/file/upload:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
|
summary: Check upload chunk
|
||||||
|
parameters:
|
||||||
|
- name: path
|
||||||
|
in: query
|
||||||
|
description: File path
|
||||||
|
required: true
|
||||||
|
example: "/DATA/test.log"
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: relativePath
|
||||||
|
in: query
|
||||||
|
description: File path
|
||||||
|
required: true
|
||||||
|
example: "/DATA/test.log"
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: filename
|
||||||
|
in: query
|
||||||
|
description: File name
|
||||||
|
required: true
|
||||||
|
example: "test.log"
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: chunkNumber
|
||||||
|
in: query
|
||||||
|
description: chunk number
|
||||||
|
required: true
|
||||||
|
example: 1
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: totalChunks
|
||||||
|
in: query
|
||||||
|
description: total chunks
|
||||||
|
example: 2
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
description: Check if the file block has been uploaded (needs to be modified later)
|
||||||
|
operationId: checkUploadChunk
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
$ref: "#/components/responses/ResponseStringOK"
|
||||||
|
"400":
|
||||||
|
$ref: "#/components/responses/ResponseClientError"
|
||||||
|
"500":
|
||||||
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
|
summary: Upload file
|
||||||
|
description: Upload file
|
||||||
|
operationId: postUploadFile
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
relativePath:
|
||||||
|
type: string
|
||||||
|
example: "/DATA/test.log"
|
||||||
|
filename:
|
||||||
|
type: string
|
||||||
|
example: "/DATA/test2.log"
|
||||||
|
totalChunks:
|
||||||
|
type: string
|
||||||
|
example: "2"
|
||||||
|
chunkNumber:
|
||||||
|
type: string
|
||||||
|
example: "20"
|
||||||
|
path:
|
||||||
|
type: string
|
||||||
|
example: "/DATA"
|
||||||
|
file:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
chunkSize:
|
||||||
|
type: string
|
||||||
|
example: "1024"
|
||||||
|
currentChunkSize:
|
||||||
|
type: string
|
||||||
|
example: "1024"
|
||||||
|
totalSize:
|
||||||
|
type: string
|
||||||
|
example: "1024"
|
||||||
|
identifier:
|
||||||
|
type: string
|
||||||
|
example: "test.log"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
$ref: "#/components/responses/ResponseStringOK"
|
||||||
|
"400":
|
||||||
|
$ref: "#/components/responses/ResponseClientError"
|
||||||
|
"500":
|
||||||
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
|
||||||
/zt/info:
|
/zt/info:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -150,6 +252,20 @@ components:
|
|||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/BaseResponse"
|
$ref: "#/components/schemas/BaseResponse"
|
||||||
|
|
||||||
|
ResponseStringOK:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SuccessResponseString"
|
||||||
|
|
||||||
|
ResponseClientError:
|
||||||
|
description: Client Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BaseResponse"
|
||||||
|
|
||||||
ResponseInternalServerError:
|
ResponseInternalServerError:
|
||||||
description: Internal Server Error
|
description: Internal Server Error
|
||||||
content:
|
content:
|
||||||
@@ -194,6 +310,14 @@ components:
|
|||||||
description: message returned by server side if there is any
|
description: message returned by server side if there is any
|
||||||
type: string
|
type: string
|
||||||
example: ""
|
example: ""
|
||||||
|
|
||||||
|
SuccessResponseString:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/BaseResponse"
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
type: string
|
||||||
|
description: When the interface returns success, this field is the specific success information
|
||||||
|
|
||||||
HealthServices:
|
HealthServices:
|
||||||
properties:
|
properties:
|
||||||
@@ -232,4 +356,4 @@ components:
|
|||||||
example: "CasaOS"
|
example: "CasaOS"
|
||||||
status:
|
status:
|
||||||
type: string
|
type: string
|
||||||
example: "online"
|
example: "online"
|
||||||
|
|||||||
28
cmd/message-bus-docgen/main.go
Normal file
28
cmd/message-bus-docgen/main.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/common"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
eventTypes := lo.Map(common.EventTypes, func(item message_bus.EventType, index int) external.EventType {
|
||||||
|
return external.EventType{
|
||||||
|
Name: item.Name,
|
||||||
|
SourceID: item.SourceID,
|
||||||
|
PropertyTypeList: lo.Map(
|
||||||
|
item.PropertyTypeList, func(item message_bus.PropertyType, index int) external.PropertyType {
|
||||||
|
return external.PropertyType{
|
||||||
|
Name: item.Name,
|
||||||
|
Description: item.Description,
|
||||||
|
Example: item.Example,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
external.PrintEventTypesAsMarkdown(common.SERVICENAME, common.VERSION, eventTypes)
|
||||||
|
}
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
// Package codegen provides primitives to interact with the openapi HTTP API.
|
|
||||||
//
|
|
||||||
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
|
||||||
package codegen
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/deepmap/oapi-codegen/pkg/runtime"
|
|
||||||
"github.com/getkin/kin-openapi/openapi3"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Access_tokenScopes = "access_token.Scopes"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Defines values for SetZerotierNetworkStatusJSONBodyStatus.
|
|
||||||
const (
|
|
||||||
Offline SetZerotierNetworkStatusJSONBodyStatus = "offline"
|
|
||||||
Online SetZerotierNetworkStatusJSONBodyStatus = "online"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BaseResponse defines model for BaseResponse.
|
|
||||||
type BaseResponse struct {
|
|
||||||
// Message message returned by server side if there is any
|
|
||||||
Message *string `json:"message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HealthPorts defines model for HealthPorts.
|
|
||||||
type HealthPorts struct {
|
|
||||||
TCP *[]int `json:"tcp,omitempty"`
|
|
||||||
UDP *[]int `json:"udp,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HealthServices defines model for HealthServices.
|
|
||||||
type HealthServices struct {
|
|
||||||
NotRunning *[]string `json:"not_running,omitempty"`
|
|
||||||
Running *[]string `json:"running,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZTInfo defines model for ZTInfo.
|
|
||||||
type ZTInfo struct {
|
|
||||||
Id *string `json:"id,omitempty"`
|
|
||||||
Name *string `json:"name,omitempty"`
|
|
||||||
Status *string `json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHealthPortsOK defines model for GetHealthPortsOK.
|
|
||||||
type GetHealthPortsOK struct {
|
|
||||||
Data *HealthPorts `json:"data,omitempty"`
|
|
||||||
|
|
||||||
// Message message returned by server side if there is any
|
|
||||||
Message *string `json:"message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHealthServicesOK defines model for GetHealthServicesOK.
|
|
||||||
type GetHealthServicesOK struct {
|
|
||||||
Data *HealthServices `json:"data,omitempty"`
|
|
||||||
|
|
||||||
// Message message returned by server side if there is any
|
|
||||||
Message *string `json:"message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetZTInfoOK defines model for GetZTInfoOK.
|
|
||||||
type GetZTInfoOK = ZTInfo
|
|
||||||
|
|
||||||
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
|
||||||
type ResponseInternalServerError = BaseResponse
|
|
||||||
|
|
||||||
// ResponseOK defines model for ResponseOK.
|
|
||||||
type ResponseOK = BaseResponse
|
|
||||||
|
|
||||||
// SetZerotierNetworkStatusJSONBody defines parameters for SetZerotierNetworkStatus.
|
|
||||||
type SetZerotierNetworkStatusJSONBody struct {
|
|
||||||
Status *SetZerotierNetworkStatusJSONBodyStatus `json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetZerotierNetworkStatusJSONBodyStatus defines parameters for SetZerotierNetworkStatus.
|
|
||||||
type SetZerotierNetworkStatusJSONBodyStatus string
|
|
||||||
|
|
||||||
// SetZerotierNetworkStatusJSONRequestBody defines body for SetZerotierNetworkStatus for application/json ContentType.
|
|
||||||
type SetZerotierNetworkStatusJSONRequestBody SetZerotierNetworkStatusJSONBody
|
|
||||||
|
|
||||||
// ServerInterface represents all server handlers.
|
|
||||||
type ServerInterface interface {
|
|
||||||
// Test file methods
|
|
||||||
// (GET /file/test)
|
|
||||||
GetFileTest(ctx echo.Context) error
|
|
||||||
// Get log
|
|
||||||
// (GET /health/logs)
|
|
||||||
GetHealthlogs(ctx echo.Context) error
|
|
||||||
// Get port in use
|
|
||||||
// (GET /health/ports)
|
|
||||||
GetHealthPorts(ctx echo.Context) error
|
|
||||||
// Get service status
|
|
||||||
// (GET /health/services)
|
|
||||||
GetHealthServices(ctx echo.Context) error
|
|
||||||
// Get Zerotier info
|
|
||||||
// (GET /zt/info)
|
|
||||||
GetZerotierInfo(ctx echo.Context) error
|
|
||||||
// Set Zerotier network status
|
|
||||||
// (PUT /zt/{network_id}/status)
|
|
||||||
SetZerotierNetworkStatus(ctx echo.Context, networkId string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
|
||||||
type ServerInterfaceWrapper struct {
|
|
||||||
Handler ServerInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileTest converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) GetFileTest(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.GetFileTest(ctx)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHealthlogs converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) GetHealthlogs(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.GetHealthlogs(ctx)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHealthPorts converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) GetHealthPorts(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.GetHealthPorts(ctx)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHealthServices converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) GetHealthServices(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.GetHealthServices(ctx)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetZerotierInfo converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) GetZerotierInfo(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.GetZerotierInfo(ctx)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetZerotierNetworkStatus converts echo context to params.
|
|
||||||
func (w *ServerInterfaceWrapper) SetZerotierNetworkStatus(ctx echo.Context) error {
|
|
||||||
var err error
|
|
||||||
// ------------- Path parameter "network_id" -------------
|
|
||||||
var networkId string
|
|
||||||
|
|
||||||
err = runtime.BindStyledParameterWithLocation("simple", false, "network_id", runtime.ParamLocationPath, ctx.Param("network_id"), &networkId)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter network_id: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Set(Access_tokenScopes, []string{""})
|
|
||||||
|
|
||||||
// Invoke the callback with all the unmarshalled arguments
|
|
||||||
err = w.Handler.SetZerotierNetworkStatus(ctx, networkId)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a simple interface which specifies echo.Route addition functions which
|
|
||||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
|
||||||
// either of them for path registration
|
|
||||||
type EchoRouter interface {
|
|
||||||
CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterHandlers adds each server route to the EchoRouter.
|
|
||||||
func RegisterHandlers(router EchoRouter, si ServerInterface) {
|
|
||||||
RegisterHandlersWithBaseURL(router, si, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers handlers, and prepends BaseURL to the paths, so that the paths
|
|
||||||
// can be served under a prefix.
|
|
||||||
func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {
|
|
||||||
|
|
||||||
wrapper := ServerInterfaceWrapper{
|
|
||||||
Handler: si,
|
|
||||||
}
|
|
||||||
|
|
||||||
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
|
||||||
router.GET(baseURL+"/health/logs", wrapper.GetHealthlogs)
|
|
||||||
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
|
||||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
|
||||||
router.GET(baseURL+"/zt/info", wrapper.GetZerotierInfo)
|
|
||||||
router.PUT(baseURL+"/zt/:network_id/status", wrapper.SetZerotierNetworkStatus)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
|
||||||
var swaggerSpec = []string{
|
|
||||||
|
|
||||||
"H4sIAAAAAAAC/8xX72/bNhD9VwhuH5pBsbxk3ToB/dAfaxoUW4Ilw4bGhktLZ4mNRKp3pyRuoP99oCjb",
|
|
||||||
"sq386pqhn2xRp7v3Hnnk47WMbVFaA4ZJRtcSgUprCJqHA+C3oHLOji0yHb1zY7E1DIbdX1WWuY4Va2vC",
|
|
||||||
"j2SNG6M4g0I1b/P8aCajs2v5PcJMRvK7cFUq9HEUvlQEf7Y1ZR1cyxJtCcjaI0gUN8luS9GBKOu6Htd1",
|
|
||||||
"HcgEKEZdOmwykkfvZB2s6JwAXugYvnFGC5R3knp/emhm9oFkbqvvE8obay7oHRoGNCp3SAF/Q7T41TCs",
|
|
||||||
"y7iNZFFb+OLCV++A+4p63IXFqVIHbbJmlte+iDbXQAFEKm1erCdqXwgErtBAIqZzQZ4f6QSEngnOAEFo",
|
|
||||||
"EsrMZSDhShVlDjKSMpAIKjky+VxGjBUEkuele0OM2qQeeLdZtnBxXLofzVA0z8vkz4bLZNowpNAo3Y4o",
|
|
||||||
"ROWgXO2mdteowo2dvjp2EVVyQ8Kn+w9M+Nfr4y6BZW9scTCWJ1gZ4xj3lpaxImVpQD6F3JJpA0cdyPvk",
|
|
||||||
"200Vw6Wa3z+vY9N22hYLnazX+HFv/6enP//y7NdhX16vUTf+lSJ1dNIXS6y42mBgTa5ND+IGIkFcoeb5",
|
|
||||||
"iVvdHp2KYyCasD2Hpou0W7sZqARQLtDIFxVnFvXnpuFWuVWp30HLXrfc15tgVA2H+3GpY64QmgcYGSGE",
|
|
||||||
"8C/IVhiDKCDR6vlIPikRZoC0G9vc4m7TgxCJROH5zkgKwpiAn49kxlxSFIaoLgep5qyaVgTYbg+D2Bbh",
|
|
||||||
"YQx/ZyqHU4izMLepDQulTeint/2ZTJUxgBOXfmJ0mvHk2XBYXg1Kk47kl4LNXaJHRMuXuikxmeYV3A5Y",
|
|
||||||
"F6lQuYPgl5AH9f8j8mjCjVUwMh6VeHF8KEq0FzoBEoWmGPJcGbAViQI4swmJmUWR6NkMEAwLisEo1JYG",
|
|
||||||
"Lssbi0ITVeC20UQkmuKKSFtDgShzUATiQpNmt9uKswPNb6upQCgtabY4Hz9ZqOGV2KbvYe4Ii+Kj1Uac",
|
|
||||||
"2QrFa02xxWT1deIHBmkanptPL6bTl1P4Z2cwatpFc6eTHWEZyAtA8k1yseea2ZZgVKllJPcHw8G+DGSp",
|
|
||||||
"OGt6NJzpHEIGas6+FHi70U6BWLiwhWYD2aTEpmUPExk5d/FGO07EzfnSMYd7w+FN5+YyLuwcxnUgnz7k",
|
|
||||||
"kz5z0exHVVEonPfhd7KplGR0Jt90h8fuuzBrTg63MqkjyRZff8A0Uf2Mb7AUNmbgXWIEVaxbi5nFQrGM",
|
|
||||||
"5FQbh7z3YO7zWV9ZrwNgkdu0o5Ln2q9TufAItwvlrcSXrI2t28XjMHY8hDaiIrgnc+qYi97GcWlbTyD8",
|
|
||||||
"eSrsTICKM/GhdQM/fBBtmt6m2nAx/0m+zm3mcRRsibRU7xLxM4eLc/1G8d4DWtaAwkX2CrSIaOzRF8qz",
|
|
||||||
"vBc9jixrJDqqLMe3dLk2wJcWzyc6qcOVESurHplOuhXa79oZ2BbsZCXYHz70ZDFXpUJVAANSc3NdL7LI",
|
|
||||||
"qxMZeBfnzo+Vh1vhbebgU6URksXtYrXBbW5nYx8MxC9tMn/QNWzdBnfMqqkKJ+7SqtrZrPk3Du5jZJcj",
|
|
||||||
"dvoRYm6t7be2qm6Z8zvWV8enN9O87tDPxm5K/EXSL4MKcxnJ8GKv9WXSBbQFNhfJk9Oj10c7q0Wx0fV1",
|
|
||||||
"cNcHa2exK3S1yyo9QFuVvl4b9/vWKb61wYzrfwMAAP//9tkexLESAAA=",
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSwagger returns the content of the embedded swagger specification file
|
|
||||||
// or error if failed to decode
|
|
||||||
func decodeSpec() ([]byte, error) {
|
|
||||||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error base64 decoding spec: %s", err)
|
|
||||||
}
|
|
||||||
zr, err := gzip.NewReader(bytes.NewReader(zipped))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
_, err = buf.ReadFrom(zr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var rawSpec = decodeSpecCached()
|
|
||||||
|
|
||||||
// a naive cached of a decoded swagger spec
|
|
||||||
func decodeSpecCached() func() ([]byte, error) {
|
|
||||||
data, err := decodeSpec()
|
|
||||||
return func() ([]byte, error) {
|
|
||||||
return data, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
|
|
||||||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) {
|
|
||||||
var res = make(map[string]func() ([]byte, error))
|
|
||||||
if len(pathToFile) > 0 {
|
|
||||||
res[pathToFile] = rawSpec
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSwagger returns the Swagger specification corresponding to the generated code
|
|
||||||
// in this file. The external references of Swagger specification are resolved.
|
|
||||||
// The logic of resolving external references is tightly connected to "import-mapping" feature.
|
|
||||||
// Externally referenced files must be embedded in the corresponding golang packages.
|
|
||||||
// Urls can be supported but this task was out of the scope.
|
|
||||||
func GetSwagger() (swagger *openapi3.T, err error) {
|
|
||||||
var resolvePath = PathToRawSpec("")
|
|
||||||
|
|
||||||
loader := openapi3.NewLoader()
|
|
||||||
loader.IsExternalRefsAllowed = true
|
|
||||||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) {
|
|
||||||
var pathToFile = url.String()
|
|
||||||
pathToFile = path.Clean(pathToFile)
|
|
||||||
getSpec, ok := resolvePath[pathToFile]
|
|
||||||
if !ok {
|
|
||||||
err1 := fmt.Errorf("path not found: %s", pathToFile)
|
|
||||||
return nil, err1
|
|
||||||
}
|
|
||||||
return getSpec()
|
|
||||||
}
|
|
||||||
var specData []byte
|
|
||||||
specData, err = rawSpec()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
swagger, err = loader.LoadFromData(specData)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ package common
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
SERVICENAME = "casaos"
|
SERVICENAME = "casaos"
|
||||||
VERSION = "0.4.4"
|
VERSION = "0.4.9"
|
||||||
BODY = ""
|
BODY = " "
|
||||||
RANW_NAME = "IceWhale-RemoteAccess"
|
RANW_NAME = "IceWhale-RemoteAccess"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,23 +1,12 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// devtype -> action -> event
|
||||||
// devtype -> action -> event
|
var EventTypes = []message_bus.EventType{
|
||||||
EventTypes map[string]map[string]message_bus.EventType
|
{Name: "casaos:system:utilization", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||||
|
{Name: "casaos:file:recover", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||||
PropertyNameLookupMaps = map[string]map[string]string{
|
{Name: "casaos:file:operate", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||||
"system": {
|
}
|
||||||
fmt.Sprintf("%s:%s", SERVICENAME, "utilization"): "ID_BUS",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionPastTense = map[string]string{
|
|
||||||
"add": "added",
|
|
||||||
"remove": "removed",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package drivers
|
|||||||
import (
|
import (
|
||||||
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
_ "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
)
|
)
|
||||||
|
|
||||||
// All do nothing,just for import
|
// All do nothing,just for import
|
||||||
|
|||||||
@@ -96,5 +96,8 @@ func (d *Dropbox) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (d *Dropbox) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
return "", "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
var _ driver.Driver = (*Dropbox)(nil)
|
var _ driver.Driver = (*Dropbox)(nil)
|
||||||
|
|||||||
@@ -2,12 +2,9 @@ package dropbox
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ICONURL = "./img/driver/Dropbox.svg"
|
const ICONURL = "./img/driver/Dropbox.svg"
|
||||||
const APPKEY = "tciqajyazzdygt9"
|
|
||||||
const APPSECRET = "e7gtmv441cwdf0n"
|
|
||||||
|
|
||||||
type Addition struct {
|
type Addition struct {
|
||||||
driver.RootID
|
driver.RootID
|
||||||
@@ -15,7 +12,7 @@ type Addition struct {
|
|||||||
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
||||||
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
||||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||||
AuthUrl string `json:"auth_url" type:"string" default:"https://www.dropbox.com/oauth2/authorize?client_id=tciqajyazzdygt9&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"`
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
||||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
}
|
}
|
||||||
@@ -25,9 +22,3 @@ var config = driver.Config{
|
|||||||
OnlyProxy: true,
|
OnlyProxy: true,
|
||||||
DefaultRoot: "root",
|
DefaultRoot: "root",
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
op.RegisterDriver(func() driver.Driver {
|
|
||||||
return &Dropbox{}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
app_key = "private build"
|
||||||
|
app_secret = "private build"
|
||||||
|
)
|
||||||
|
|
||||||
func (d *Dropbox) getRefreshToken() error {
|
func (d *Dropbox) getRefreshToken() error {
|
||||||
url := "https://api.dropbox.com/oauth2/token"
|
url := "https://api.dropbox.com/oauth2/token"
|
||||||
var resp base.TokenResp
|
var resp base.TokenResp
|
||||||
@@ -100,3 +105,12 @@ func (d *Dropbox) getFiles(path string) ([]File, error) {
|
|||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
func GetConfig() Dropbox {
|
||||||
|
dp := Dropbox{}
|
||||||
|
dp.RootFolderID = ""
|
||||||
|
dp.AuthUrl = "https://www.dropbox.com/oauth2/authorize?client_id=" + app_key + "&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"
|
||||||
|
dp.AppKey = app_key
|
||||||
|
dp.AppSecret = app_secret
|
||||||
|
dp.Icon = "./img/driver/Dropbox.svg"
|
||||||
|
return dp
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ func (d *GoogleDrive) GetUserInfo(ctx context.Context) (string, error) {
|
|||||||
return user.User.EmailAddress, nil
|
return user.User.EmailAddress, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *GoogleDrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
return "", "", "", nil
|
||||||
|
}
|
||||||
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
data := base.Json{
|
data := base.Json{
|
||||||
"name": dirName,
|
"name": dirName,
|
||||||
|
|||||||
@@ -2,22 +2,19 @@ package google_drive
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ICONURL = "./img/driver/GoogleDrive.svg"
|
const ICONURL = "./img/driver/GoogleDrive.svg"
|
||||||
const CLIENTID = "921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com"
|
|
||||||
const CLIENTSECRET = "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"
|
|
||||||
|
|
||||||
type Addition struct {
|
type Addition struct {
|
||||||
driver.RootID
|
driver.RootID
|
||||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||||
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
||||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||||
ClientID string `json:"client_id" required:"true" default:"921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com" omit:"true"`
|
ClientID string `json:"client_id" required:"true" default:"" omit:"true"`
|
||||||
ClientSecret string `json:"client_secret" required:"true" default:"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" omit:"true"`
|
ClientSecret string `json:"client_secret" required:"true" default:"" omit:"true"`
|
||||||
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
||||||
AuthUrl string `json:"auth_url" type:"string" default:"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"`
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
||||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
}
|
}
|
||||||
@@ -27,9 +24,3 @@ var config = driver.Config{
|
|||||||
OnlyProxy: true,
|
OnlyProxy: true,
|
||||||
DefaultRoot: "root",
|
DefaultRoot: "root",
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
op.RegisterDriver(func() driver.Driver {
|
|
||||||
return &GoogleDrive{}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
client_id = "private build"
|
||||||
|
client_secret = "private build"
|
||||||
|
)
|
||||||
|
|
||||||
// do others that not defined in Driver interface
|
// do others that not defined in Driver interface
|
||||||
|
|
||||||
func (d *GoogleDrive) getRefreshToken() error {
|
func (d *GoogleDrive) getRefreshToken() error {
|
||||||
@@ -150,3 +155,13 @@ func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func GetConfig() GoogleDrive {
|
||||||
|
config := GoogleDrive{}
|
||||||
|
config.ClientID = client_id
|
||||||
|
config.ClientSecret = client_secret
|
||||||
|
config.RootFolderID = "root"
|
||||||
|
config.AuthUrl = "https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=" + client_id + "&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"
|
||||||
|
config.Icon = "./img/driver/GoogleDrive.svg"
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|||||||
70
drivers/onedrive/drive.go
Normal file
70
drivers/onedrive/drive.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Onedrive struct {
|
||||||
|
model.StorageA
|
||||||
|
Addition
|
||||||
|
AccessToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) Config() driver.Config {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) GetAddition() driver.Additional {
|
||||||
|
return &d.Addition
|
||||||
|
}
|
||||||
|
func (d *Onedrive) Init(ctx context.Context) error {
|
||||||
|
if d.ChunkSize < 1 {
|
||||||
|
d.ChunkSize = 5
|
||||||
|
}
|
||||||
|
if len(d.RefreshToken) == 0 {
|
||||||
|
return d.getRefreshToken()
|
||||||
|
}
|
||||||
|
return d.refreshToken()
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
url := d.GetMetaUrl(false, "/")
|
||||||
|
user := Info{}
|
||||||
|
resp, err := d.Request(url, http.MethodGet, nil, &user)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("resp", zap.Any("resp", resp))
|
||||||
|
return user.LastModifiedBy.User.DisplayName, user.ParentReference.DriveID, user.ParentReference.DriveType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) GetSpaceSize(ctx context.Context) (used string, total string, err error) {
|
||||||
|
host := onedriveHostMap[d.Region]
|
||||||
|
url := fmt.Sprintf("%s/v1.0/me/drive/quota", host.Api)
|
||||||
|
size := About{}
|
||||||
|
resp, err := d.Request(url, http.MethodGet, nil, &size)
|
||||||
|
if err != nil {
|
||||||
|
return used, total, err
|
||||||
|
}
|
||||||
|
logger.Info("resp", zap.Any("resp", resp))
|
||||||
|
used = strconv.Itoa(size.Used)
|
||||||
|
total = strconv.Itoa(size.Total)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (d *Onedrive) Drop(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ driver.Driver = (*Onedrive)(nil)
|
||||||
69
drivers/onedrive/meta.go
Normal file
69
drivers/onedrive/meta.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ICONURL = "./img/driver/OneDrive.svg"
|
||||||
|
|
||||||
|
type Host struct {
|
||||||
|
Oauth string
|
||||||
|
Api string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenErr struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
ErrorDescription string `json:"error_description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RespErr struct {
|
||||||
|
Error struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `json:"error"`
|
||||||
|
}
|
||||||
|
type Addition struct {
|
||||||
|
Region string `json:"region" type:"select" required:"true" options:"global,cn,us,de" default:"global"`
|
||||||
|
IsSharepoint bool `json:"is_sharepoint"`
|
||||||
|
ClientID string `json:"client_id" required:"true"`
|
||||||
|
ClientSecret string `json:"client_secret" required:"true"`
|
||||||
|
RedirectUri string `json:"redirect_uri" required:"true" default:""`
|
||||||
|
RefreshToken string `json:"refresh_token" required:"true"`
|
||||||
|
SiteId string `json:"site_id"`
|
||||||
|
ChunkSize int64 `json:"chunk_size" type:"number" default:"5"`
|
||||||
|
RootFolderID string `json:"root_folder_id"`
|
||||||
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
|
Icon string `json:"icon" type:"string" default:""`
|
||||||
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
|
}
|
||||||
|
type About struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Used int `json:"used"`
|
||||||
|
State string `json:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
LastModifiedBy struct {
|
||||||
|
Application struct {
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"application"`
|
||||||
|
Device struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"device"`
|
||||||
|
User struct {
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"user"`
|
||||||
|
} `json:"lastModifiedBy"`
|
||||||
|
ParentReference struct {
|
||||||
|
DriveID string `json:"driveId"`
|
||||||
|
DriveType string `json:"driveType"`
|
||||||
|
} `json:"parentReference"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = driver.Config{
|
||||||
|
Name: "Onedrive",
|
||||||
|
LocalSort: true,
|
||||||
|
DefaultRoot: "/",
|
||||||
|
}
|
||||||
182
drivers/onedrive/util.go
Normal file
182
drivers/onedrive/util.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
client_id = "private build"
|
||||||
|
client_secret = "private build"
|
||||||
|
)
|
||||||
|
var onedriveHostMap = map[string]Host{
|
||||||
|
"global": {
|
||||||
|
Oauth: "https://login.microsoftonline.com",
|
||||||
|
Api: "https://graph.microsoft.com",
|
||||||
|
},
|
||||||
|
"cn": {
|
||||||
|
Oauth: "https://login.chinacloudapi.cn",
|
||||||
|
Api: "https://microsoftgraph.chinacloudapi.cn",
|
||||||
|
},
|
||||||
|
"us": {
|
||||||
|
Oauth: "https://login.microsoftonline.us",
|
||||||
|
Api: "https://graph.microsoft.us",
|
||||||
|
},
|
||||||
|
"de": {
|
||||||
|
Oauth: "https://login.microsoftonline.de",
|
||||||
|
Api: "https://graph.microsoft.de",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodePath(path string, all ...bool) string {
|
||||||
|
seg := strings.Split(path, "/")
|
||||||
|
toReplace := []struct {
|
||||||
|
Src string
|
||||||
|
Dst string
|
||||||
|
}{
|
||||||
|
{Src: "%", Dst: "%25"},
|
||||||
|
{"%", "%25"},
|
||||||
|
{"?", "%3F"},
|
||||||
|
{"#", "%23"},
|
||||||
|
}
|
||||||
|
for i := range seg {
|
||||||
|
if len(all) > 0 && all[0] {
|
||||||
|
seg[i] = url.PathEscape(seg[i])
|
||||||
|
} else {
|
||||||
|
for j := range toReplace {
|
||||||
|
seg[i] = strings.ReplaceAll(seg[i], toReplace[j].Src, toReplace[j].Dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(seg, "/")
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetMetaUrl(auth bool, path string) string {
|
||||||
|
host := onedriveHostMap[d.Region]
|
||||||
|
path = EncodePath(path, true)
|
||||||
|
if auth {
|
||||||
|
return host.Oauth
|
||||||
|
}
|
||||||
|
if d.IsSharepoint {
|
||||||
|
if path == "/" || path == "\\" {
|
||||||
|
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, d.SiteId)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, d.SiteId, path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if path == "/" || path == "\\" {
|
||||||
|
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) refreshToken() error {
|
||||||
|
var err error
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
err = d._refreshToken()
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) getRefreshToken() error {
|
||||||
|
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||||
|
var resp base.TokenResp
|
||||||
|
var e TokenErr
|
||||||
|
|
||||||
|
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
"client_id": d.ClientID,
|
||||||
|
"client_secret": d.ClientSecret,
|
||||||
|
"code": d.Code,
|
||||||
|
"redirect_uri": d.RedirectUri,
|
||||||
|
}).Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||||
|
if e.Error != "" {
|
||||||
|
return fmt.Errorf("%s", e.ErrorDescription)
|
||||||
|
}
|
||||||
|
if resp.RefreshToken == "" {
|
||||||
|
return errors.New("refresh token is empty")
|
||||||
|
}
|
||||||
|
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) _refreshToken() error {
|
||||||
|
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||||
|
var resp base.TokenResp
|
||||||
|
var e TokenErr
|
||||||
|
|
||||||
|
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||||
|
"grant_type": "refresh_token",
|
||||||
|
"client_id": d.ClientID,
|
||||||
|
"client_secret": d.ClientSecret,
|
||||||
|
"redirect_uri": d.RedirectUri,
|
||||||
|
"refresh_token": d.RefreshToken,
|
||||||
|
}).Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||||
|
if e.Error != "" {
|
||||||
|
return fmt.Errorf("%s", e.ErrorDescription)
|
||||||
|
}
|
||||||
|
if resp.RefreshToken == "" {
|
||||||
|
return errors.New("refresh token is empty")
|
||||||
|
}
|
||||||
|
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||||
|
req := base.RestyClient.R()
|
||||||
|
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||||
|
if callback != nil {
|
||||||
|
callback(req)
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
req.SetResult(resp)
|
||||||
|
}
|
||||||
|
var e RespErr
|
||||||
|
req.SetError(&e)
|
||||||
|
res, err := req.Execute(method, url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if e.Error.Code != "" {
|
||||||
|
if e.Error.Code == "InvalidAuthenticationToken" {
|
||||||
|
err = d.refreshToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return d.Request(url, method, callback, resp)
|
||||||
|
}
|
||||||
|
return nil, errors.New(e.Error.Message)
|
||||||
|
}
|
||||||
|
return res.Body(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfig() Onedrive {
|
||||||
|
config := Onedrive{}
|
||||||
|
config.ClientID = client_id
|
||||||
|
config.ClientSecret = client_secret
|
||||||
|
config.RootFolderID = "/"
|
||||||
|
config.AuthUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + client_id + "&response_type=code&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=offline_access+files.readwrite.all&state=${HOST}%2Fv1%2Frecover%2FOnedrive"
|
||||||
|
config.Icon = "./img/driver/OneDrive.svg"
|
||||||
|
config.Region = "global"
|
||||||
|
config.RedirectUri = "https://cloudoauth.files.casaos.app"
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
57
go.mod
57
go.mod
@@ -4,21 +4,22 @@ go 1.20
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
||||||
github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha8
|
github.com/IceWhaleTech/CasaOS-Common v0.4.8-alpha3
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||||
github.com/deckarep/golang-set/v2 v2.3.0
|
github.com/deckarep/golang-set/v2 v2.3.0
|
||||||
github.com/deepmap/oapi-codegen v1.12.4
|
github.com/deepmap/oapi-codegen v1.12.4
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85
|
github.com/dsoprea/go-exif/v3 v3.0.1
|
||||||
github.com/getkin/kin-openapi v0.115.0
|
github.com/getkin/kin-openapi v0.117.0
|
||||||
github.com/gin-contrib/gzip v0.0.6
|
github.com/gin-contrib/gzip v0.0.6
|
||||||
github.com/gin-gonic/gin v1.9.0
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/glebarez/sqlite v1.7.0
|
github.com/glebarez/sqlite v1.8.0
|
||||||
github.com/go-ini/ini v1.67.0
|
github.com/go-ini/ini v1.67.0
|
||||||
github.com/go-resty/resty/v2 v2.7.0
|
github.com/go-resty/resty/v2 v2.7.0
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/gomodule/redigo v1.8.9
|
github.com/gomodule/redigo v1.8.9
|
||||||
github.com/google/go-github/v36 v36.0.0
|
github.com/google/go-github/v36 v36.0.0
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
github.com/googollee/go-socket.io v1.7.0
|
github.com/googollee/go-socket.io v1.7.0
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/h2non/filetype v1.1.3
|
github.com/h2non/filetype v1.1.3
|
||||||
@@ -33,26 +34,26 @@ require (
|
|||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/samber/lo v1.38.1
|
||||||
github.com/shirou/gopsutil/v3 v3.23.2
|
github.com/shirou/gopsutil/v3 v3.23.2
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/tidwall/gjson v1.14.4
|
github.com/tidwall/gjson v1.14.4
|
||||||
go.uber.org/goleak v1.2.1
|
go.uber.org/goleak v1.2.1
|
||||||
go.uber.org/zap v1.24.0
|
go.uber.org/zap v1.24.0
|
||||||
golang.org/x/crypto v0.8.0
|
golang.org/x/crypto v0.14.0
|
||||||
golang.org/x/oauth2 v0.6.0
|
golang.org/x/oauth2 v0.7.0
|
||||||
golang.org/x/sync v0.1.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/sys v0.7.0
|
golang.org/x/sys v0.14.0
|
||||||
gorm.io/gorm v1.24.6
|
gorm.io/gorm v1.25.0
|
||||||
gotest.tools v2.2.0+incompatible
|
gotest.tools v2.2.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
github.com/benbjohnson/clock v1.3.1 // indirect
|
||||||
github.com/bytedance/sonic v1.8.5 // indirect
|
github.com/bytedance/sonic v1.9.1 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
@@ -60,16 +61,17 @@ require (
|
|||||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
github.com/geoffgarside/ber v1.1.0 // indirect
|
github.com/geoffgarside/ber v1.1.0 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/glebarez/go-sqlite v1.21.0 // indirect
|
github.com/glebarez/go-sqlite v1.21.1 // indirect
|
||||||
github.com/go-errors/errors v1.4.2 // indirect
|
github.com/go-errors/errors v1.4.2 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||||
github.com/go-openapi/swag v0.22.3 // indirect
|
github.com/go-openapi/swag v0.22.3 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.12.0 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||||
@@ -78,9 +80,8 @@ require (
|
|||||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/invopop/yaml v0.2.0 // indirect
|
github.com/invopop/yaml v0.2.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
@@ -91,22 +92,22 @@ require (
|
|||||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/labstack/gommon v0.4.0 // indirect
|
github.com/labstack/gommon v0.4.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.3 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
|
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/samber/lo v1.38.1 // indirect
|
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||||
@@ -121,18 +122,18 @@ require (
|
|||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||||
golang.org/x/image v0.6.0 // indirect
|
golang.org/x/image v0.6.0 // indirect
|
||||||
golang.org/x/net v0.9.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
modernc.org/libc v1.22.3 // indirect
|
modernc.org/libc v1.22.4 // indirect
|
||||||
modernc.org/mathutil v1.5.0 // indirect
|
modernc.org/mathutil v1.5.0 // indirect
|
||||||
modernc.org/memory v1.5.0 // indirect
|
modernc.org/memory v1.5.0 // indirect
|
||||||
modernc.org/sqlite v1.21.0 // indirect
|
modernc.org/sqlite v1.21.2 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
107
go.sum
107
go.sum
@@ -1,19 +1,19 @@
|
|||||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
|
||||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
|
||||||
github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha8 h1:UhCg3d9Cxhx7KVmqh8oUrUl1qFmFdcHee3Zkk4+P2JA=
|
github.com/IceWhaleTech/CasaOS-Common v0.4.8-alpha3 h1:5E5LAqi2uXpOZqcPOgQ4m6d9MagYyfhKIFXnzd8s3W4=
|
||||||
github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha8/go.mod h1:2IuYyy5qW1BE6jqC6M+tOU+WtUec1K565rLATBJ9p/0=
|
github.com/IceWhaleTech/CasaOS-Common v0.4.8-alpha3/go.mod h1:2IuYyy5qW1BE6jqC6M+tOU+WtUec1K565rLATBJ9p/0=
|
||||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
github.com/benbjohnson/clock v1.3.1 h1:Heo0FGXzOxUHquZbraxt+tT7UXVDhesUQH5ISbsOkCQ=
|
||||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.3.1/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.8.5 h1:kjX0/vo5acEQ/sinD/18SkA/lDDUk23F0RcaHvI7omc=
|
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||||
github.com/bytedance/sonic v1.8.5/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
@@ -39,8 +39,8 @@ github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1
|
|||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221003160559-cf5cd88aa559/go.mod h1:rW6DMEv25U9zCtE5ukC7ttBRllXj7g7TAHl7tQrT5No=
|
github.com/dsoprea/go-exif/v3 v3.0.0-20221003160559-cf5cd88aa559/go.mod h1:rW6DMEv25U9zCtE5ukC7ttBRllXj7g7TAHl7tQrT5No=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221003171958-de6cb6e380a8/go.mod h1:akyZEJZ/k5bmbC9gA612ZLQkcED8enS9vuTiuAkENr0=
|
github.com/dsoprea/go-exif/v3 v3.0.0-20221003171958-de6cb6e380a8/go.mod h1:akyZEJZ/k5bmbC9gA612ZLQkcED8enS9vuTiuAkENr0=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85 h1:vZkWA0Lduu9QB6qRBtsLy7m5uO/RFNCDH2pzMLTxGts=
|
github.com/dsoprea/go-exif/v3 v3.0.1 h1:/IE4iW7gvY7BablV1XY0unqhMv26EYpOquVMwoBo/wc=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85/go.mod h1:10HkA1Wz3h398cDP66L+Is9kKDmlqlIJGPv8pk4EWvc=
|
github.com/dsoprea/go-exif/v3 v3.0.1/go.mod h1:10HkA1Wz3h398cDP66L+Is9kKDmlqlIJGPv8pk4EWvc=
|
||||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
||||||
@@ -53,21 +53,23 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje
|
|||||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||||
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
||||||
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
||||||
github.com/getkin/kin-openapi v0.115.0 h1:c8WHRLVY3G8m9jQTy0/DnIuljgRwTCB5twZytQS4JyU=
|
github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDcUFE8A=
|
||||||
github.com/getkin/kin-openapi v0.115.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
||||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||||
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||||
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||||
github.com/glebarez/go-sqlite v1.21.0 h1:b8MHPtBagkSD2gntImZPsG3o3QEXgMDxguW/GLUonHQ=
|
github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY=
|
||||||
github.com/glebarez/go-sqlite v1.21.0/go.mod h1:GodsA6yGSa3eKbvpr7dS+JaqazzVfMcjIXvx6KHhW/c=
|
github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E=
|
||||||
github.com/glebarez/sqlite v1.7.0 h1:A7Xj/KN2Lvie4Z4rrgQHY8MsbebX3NyWsL3n2i82MVI=
|
github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc=
|
||||||
github.com/glebarez/sqlite v1.7.0/go.mod h1:PkeevrRlF/1BhQBCnzcMWzgrIk7IOop+qS2jUYLfHhk=
|
github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
@@ -92,8 +94,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
|||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI=
|
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||||
github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA=
|
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||||
@@ -131,8 +133,9 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0
|
|||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
||||||
github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk=
|
github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
@@ -191,8 +194,8 @@ github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO
|
|||||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
|
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||||
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de h1:V53FWzU6KAZVi1tPp5UIsMoUWJ2/PNwYIDXnu7QuBCE=
|
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de h1:V53FWzU6KAZVi1tPp5UIsMoUWJ2/PNwYIDXnu7QuBCE=
|
||||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||||
@@ -207,8 +210,8 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec
|
|||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||||
github.com/mileusna/useragent v1.2.1 h1:p3RJWhi3LfuI6BHdddojREyK3p6qX67vIfOVMnUIVr0=
|
github.com/mileusna/useragent v1.2.1 h1:p3RJWhi3LfuI6BHdddojREyK3p6qX67vIfOVMnUIVr0=
|
||||||
@@ -230,8 +233,8 @@ github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWk
|
|||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
|
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||||
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
||||||
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
@@ -252,16 +255,15 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
|||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
||||||
github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU=
|
github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU=
|
||||||
github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M=
|
github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M=
|
||||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
@@ -273,8 +275,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
@@ -323,10 +327,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
||||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4=
|
golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4=
|
||||||
golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0=
|
golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0=
|
||||||
@@ -347,16 +351,17 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -382,12 +387,12 @@ golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
|
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@@ -395,8 +400,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -434,16 +439,16 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s=
|
gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU=
|
||||||
gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
|
modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ=
|
||||||
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
|
modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||||
modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow=
|
modernc.org/sqlite v1.21.2 h1:ixuUG0QS413Vfzyx6FWx6PYTmHaOegTY+hjzhn7L+a0=
|
||||||
modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
|
modernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
@@ -34,14 +34,16 @@ type Reader interface {
|
|||||||
// List files in the path
|
// List files in the path
|
||||||
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
||||||
// if identify files by id, need to set ID with corresponding id
|
// if identify files by id, need to set ID with corresponding id
|
||||||
List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
// List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
||||||
// Link get url/filepath/reader of file
|
// Link get url/filepath/reader of file
|
||||||
Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
// Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
||||||
}
|
}
|
||||||
type User interface {
|
type User interface {
|
||||||
// GetRoot get root directory of user
|
// GetRoot get root directory of user
|
||||||
GetUserInfo(ctx context.Context) (string, error)
|
GetUserInfo(ctx context.Context) (string, error)
|
||||||
|
GetInfo(ctx context.Context) (string, string, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Getter interface {
|
type Getter interface {
|
||||||
GetRoot(ctx context.Context) (model.Obj, error)
|
GetRoot(ctx context.Context) (model.Obj, error)
|
||||||
}
|
}
|
||||||
|
|||||||
11
main.go
11
main.go
@@ -18,7 +18,6 @@ import (
|
|||||||
|
|
||||||
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/common"
|
"github.com/IceWhaleTech/CasaOS/common"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/cache"
|
"github.com/IceWhaleTech/CasaOS/pkg/cache"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
@@ -109,10 +108,12 @@ func main() {
|
|||||||
|
|
||||||
v2Router := route.InitV2Router()
|
v2Router := route.InitV2Router()
|
||||||
v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML)
|
v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML)
|
||||||
|
v3File := route.InitFile()
|
||||||
mux := &util_http.HandlerMultiplexer{
|
mux := &util_http.HandlerMultiplexer{
|
||||||
HandlerMap: map[string]http.Handler{
|
HandlerMap: map[string]http.Handler{
|
||||||
"v1": v1Router,
|
"v1": v1Router,
|
||||||
"v2": v2Router,
|
"v2": v2Router,
|
||||||
|
"v3": v3File,
|
||||||
"doc": v2DocRouter,
|
"doc": v2DocRouter,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -146,6 +147,7 @@ func main() {
|
|||||||
"/v1/test",
|
"/v1/test",
|
||||||
route.V2APIPath,
|
route.V2APIPath,
|
||||||
route.V2DocPath,
|
route.V2DocPath,
|
||||||
|
route.V3FilePath,
|
||||||
}
|
}
|
||||||
for _, apiPath := range routers {
|
for _, apiPath := range routers {
|
||||||
err = service.MyService.Gateway().CreateRoute(&model.Route{
|
err = service.MyService.Gateway().CreateRoute(&model.Route{
|
||||||
@@ -158,13 +160,10 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var events []message_bus.EventType
|
|
||||||
events = append(events, message_bus.EventType{Name: "casaos:system:utilization", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
|
||||||
events = append(events, message_bus.EventType{Name: "casaos:file:recover", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
|
||||||
events = append(events, message_bus.EventType{Name: "casaos:file:operate", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
|
||||||
// register at message bus
|
// register at message bus
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), events)
|
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), common.EventTypes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.Error(err))
|
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|||||||
7
model/drive.go
Normal file
7
model/drive.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Drive struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
AuthUrl string `json:"auth_url"`
|
||||||
|
}
|
||||||
@@ -77,6 +77,22 @@ func RMDir(src string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RemoveAll(dir string) error {
|
||||||
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return os.Remove(path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.Remove(dir)
|
||||||
|
}
|
||||||
|
|
||||||
// Open a file according to a specific mode
|
// Open a file according to a specific mode
|
||||||
func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
|
func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
|
||||||
f, err := os.OpenFile(name, flag, perm)
|
f, err := os.OpenFile(name, flag, perm)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
func InitFunction() {
|
func InitFunction() {
|
||||||
go InitNetworkMount()
|
go InitNetworkMount()
|
||||||
go InitInfo()
|
go InitInfo()
|
||||||
go InitZerotier()
|
//go InitZerotier()
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitInfo() {
|
func InitInfo() {
|
||||||
|
|||||||
128
route/v1.go
128
route/v1.go
@@ -87,78 +87,78 @@ func InitV1Router() *gin.Engine {
|
|||||||
v1PortGroup.GET("/", v1.GetPort) // app/port
|
v1PortGroup.GET("/", v1.GetPort) // app/port
|
||||||
v1PortGroup.GET("/state/:port", v1.PortCheck) // app/check/:port
|
v1PortGroup.GET("/state/:port", v1.PortCheck) // app/check/:port
|
||||||
}
|
}
|
||||||
// v1FileGroup := v1Group.Group("/file")
|
v1FileGroup := v1Group.Group("/file")
|
||||||
// v1FileGroup.Use()
|
v1FileGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1FileGroup.GET("", v1.GetDownloadSingleFile) // download/:path
|
v1FileGroup.GET("", v1.GetDownloadSingleFile) // download/:path
|
||||||
// v1FileGroup.POST("", v1.PostCreateFile)
|
v1FileGroup.POST("", v1.PostCreateFile)
|
||||||
// v1FileGroup.PUT("", v1.PutFileContent)
|
v1FileGroup.PUT("", v1.PutFileContent)
|
||||||
// v1FileGroup.PUT("/name", v1.RenamePath)
|
v1FileGroup.PUT("/name", v1.RenamePath)
|
||||||
// // file/rename
|
// file/rename
|
||||||
// v1FileGroup.GET("/content", v1.GetFilerContent) // file/read
|
v1FileGroup.GET("/content", v1.GetFilerContent) // file/read
|
||||||
|
|
||||||
// // File uploads need to be handled separately, and will not be modified here
|
// File uploads need to be handled separately, and will not be modified here
|
||||||
// //v1FileGroup.POST("/upload", v1.PostFileUpload)
|
//v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||||
// v1FileGroup.POST("/upload", v1.PostFileUpload)
|
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||||
// v1FileGroup.GET("/upload", v1.GetFileUpload)
|
v1FileGroup.GET("/upload", v1.GetFileUpload)
|
||||||
// // v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
// v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
||||||
// v1FileGroup.GET("/ws", v1.ConnectWebSocket)
|
v1FileGroup.GET("/ws", v1.ConnectWebSocket)
|
||||||
// v1FileGroup.GET("/peers", v1.GetPeers)
|
v1FileGroup.GET("/peers", v1.GetPeers)
|
||||||
// }
|
}
|
||||||
// v1CloudGroup := v1Group.Group("/cloud")
|
v1CloudGroup := v1Group.Group("/cloud")
|
||||||
// v1CloudGroup.Use()
|
v1CloudGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1CloudGroup.GET("", v1.ListStorages)
|
v1CloudGroup.GET("", v1.ListStorages)
|
||||||
// v1CloudGroup.DELETE("", v1.UmountStorage)
|
v1CloudGroup.DELETE("", v1.UmountStorage)
|
||||||
// }
|
}
|
||||||
// v1DriverGroup := v1Group.Group("/driver")
|
v1DriverGroup := v1Group.Group("/driver")
|
||||||
// v1DriverGroup.Use()
|
v1DriverGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1DriverGroup.GET("", v1.ListDriverInfo)
|
v1DriverGroup.GET("", v1.ListDriverInfo)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// v1FolderGroup := v1Group.Group("/folder")
|
v1FolderGroup := v1Group.Group("/folder")
|
||||||
// v1FolderGroup.Use()
|
v1FolderGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1FolderGroup.PUT("/name", v1.RenamePath)
|
v1FolderGroup.PUT("/name", v1.RenamePath)
|
||||||
// v1FolderGroup.GET("", v1.DirPath) ///file/dirpath
|
v1FolderGroup.GET("", v1.DirPath) ///file/dirpath
|
||||||
// v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir
|
v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir
|
||||||
// v1FolderGroup.GET("/size", v1.GetSize)
|
v1FolderGroup.GET("/size", v1.GetSize)
|
||||||
// v1FolderGroup.GET("/count", v1.GetFileCount)
|
v1FolderGroup.GET("/count", v1.GetFileCount)
|
||||||
// }
|
}
|
||||||
// v1BatchGroup := v1Group.Group("/batch")
|
v1BatchGroup := v1Group.Group("/batch")
|
||||||
// v1BatchGroup.Use()
|
v1BatchGroup.Use()
|
||||||
// {
|
{
|
||||||
|
|
||||||
// v1BatchGroup.DELETE("", v1.DeleteFile) // file/delete
|
v1BatchGroup.DELETE("", v1.DeleteFile) // file/delete
|
||||||
// v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir)
|
v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir)
|
||||||
// v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) // file/operate
|
v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) // file/operate
|
||||||
// v1BatchGroup.GET("", v1.GetDownloadFile)
|
v1BatchGroup.GET("", v1.GetDownloadFile)
|
||||||
// }
|
}
|
||||||
v1ImageGroup := v1Group.Group("/image")
|
v1ImageGroup := v1Group.Group("/image")
|
||||||
v1ImageGroup.Use()
|
v1ImageGroup.Use()
|
||||||
{
|
{
|
||||||
v1ImageGroup.GET("", v1.GetFileImage)
|
v1ImageGroup.GET("", v1.GetFileImage)
|
||||||
}
|
}
|
||||||
// v1SambaGroup := v1Group.Group("/samba")
|
v1SambaGroup := v1Group.Group("/samba")
|
||||||
// v1SambaGroup.Use()
|
v1SambaGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1ConnectionsGroup := v1SambaGroup.Group("/connections")
|
v1ConnectionsGroup := v1SambaGroup.Group("/connections")
|
||||||
// v1ConnectionsGroup.Use()
|
v1ConnectionsGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList)
|
v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList)
|
||||||
// v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate)
|
v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate)
|
||||||
// v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections)
|
v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections)
|
||||||
// }
|
}
|
||||||
// v1SharesGroup := v1SambaGroup.Group("/shares")
|
v1SharesGroup := v1SambaGroup.Group("/shares")
|
||||||
// v1SharesGroup.Use()
|
v1SharesGroup.Use()
|
||||||
// {
|
{
|
||||||
// v1SharesGroup.GET("", v1.GetSambaSharesList)
|
v1SharesGroup.GET("", v1.GetSambaSharesList)
|
||||||
// v1SharesGroup.POST("", v1.PostSambaSharesCreate)
|
v1SharesGroup.POST("", v1.PostSambaSharesCreate)
|
||||||
// v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares)
|
v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares)
|
||||||
// v1SharesGroup.GET("/status", v1.GetSambaStatus)
|
v1SharesGroup.GET("/status", v1.GetSambaStatus)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
v1NotifyGroup := v1Group.Group("/notify")
|
v1NotifyGroup := v1Group.Group("/notify")
|
||||||
v1NotifyGroup.Use()
|
v1NotifyGroup.Use()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
@@ -51,6 +52,10 @@ func ListStorages(c *gin.Context) {
|
|||||||
if dataMap["type"] == "dropbox" {
|
if dataMap["type"] == "dropbox" {
|
||||||
r.MountPoints[i].Icon = dropbox.ICONURL
|
r.MountPoints[i].Icon = dropbox.ICONURL
|
||||||
}
|
}
|
||||||
|
if dataMap["type"] == "onedrive" {
|
||||||
|
|
||||||
|
r.MountPoints[i].Icon = onedrive.ICONURL
|
||||||
|
}
|
||||||
r.MountPoints[i].Name = dataMap["username"]
|
r.MountPoints[i].Name = dataMap["username"]
|
||||||
}
|
}
|
||||||
list := []httper.MountPoint{}
|
list := []httper.MountPoint{}
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ListDriverInfo(c *gin.Context) {
|
func ListDriverInfo(c *gin.Context) {
|
||||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: op.GetDriverInfoMap()})
|
list := []model.Drive{}
|
||||||
|
|
||||||
|
google := google_drive.GetConfig()
|
||||||
|
list = append(list, model.Drive{
|
||||||
|
Name: "Google Drive",
|
||||||
|
Icon: google.Icon,
|
||||||
|
AuthUrl: google.AuthUrl,
|
||||||
|
})
|
||||||
|
dp := dropbox.GetConfig()
|
||||||
|
list = append(list, model.Drive{
|
||||||
|
Name: "Dropbox",
|
||||||
|
Icon: dp.Icon,
|
||||||
|
AuthUrl: dp.AuthUrl,
|
||||||
|
})
|
||||||
|
od := onedrive.GetConfig()
|
||||||
|
list = append(list, model.Drive{
|
||||||
|
Name: "OneDrive",
|
||||||
|
Icon: od.Icon,
|
||||||
|
AuthUrl: od.AuthUrl,
|
||||||
|
})
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import (
|
|||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
uuid "github.com/satori/go.uuid"
|
"github.com/google/uuid"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/h2non/filetype"
|
"github.com/h2non/filetype"
|
||||||
@@ -480,6 +480,10 @@ func GetFileUpload(c *gin.Context) {
|
|||||||
path := c.Query("path")
|
path := c.Query("path")
|
||||||
dirPath := ""
|
dirPath := ""
|
||||||
hash := file.GetHashByContent([]byte(fileName))
|
hash := file.GetHashByContent([]byte(fileName))
|
||||||
|
if file.Exists(path + "/" + relative) {
|
||||||
|
c.JSON(http.StatusConflict, model.Result{Success: http.StatusConflict, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
|
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
|
||||||
if fileName != relative {
|
if fileName != relative {
|
||||||
dirPath = strings.TrimSuffix(relative, fileName)
|
dirPath = strings.TrimSuffix(relative, fileName)
|
||||||
@@ -577,12 +581,13 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
|
||||||
if err := file.RMDir(tempDir); err != nil {
|
time.Sleep(11 * time.Second)
|
||||||
logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
|
if err := file.RMDir(tempDir); err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
|
||||||
return
|
}
|
||||||
}
|
}()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)
|
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)
|
||||||
@@ -710,7 +715,7 @@ func PostOperateFileOrDir(c *gin.Context) {
|
|||||||
list.TotalSize = total
|
list.TotalSize = total
|
||||||
list.ProcessedSize = 0
|
list.ProcessedSize = 0
|
||||||
|
|
||||||
uid := uuid.NewV4().String()
|
uid := uuid.NewString()
|
||||||
service.FileQueue.Store(uid, list)
|
service.FileQueue.Store(uid, list)
|
||||||
service.OpStrArr = append(service.OpStrArr, uid)
|
service.OpStrArr = append(service.OpStrArr, uid)
|
||||||
if len(service.OpStrArr) == 1 {
|
if len(service.OpStrArr) == 1 {
|
||||||
@@ -918,7 +923,7 @@ func ConnectWebSocket(c *gin.Context) {
|
|||||||
peerId := c.Query("peer")
|
peerId := c.Query("peer")
|
||||||
writer := c.Writer
|
writer := c.Writer
|
||||||
request := c.Request
|
request := c.Request
|
||||||
key := uuid.NewV4().String()
|
key := uuid.NewString()
|
||||||
//peerModel := service.MyService.Peer().GetPeerByUserAgent(c.Request.UserAgent())
|
//peerModel := service.MyService.Peer().GetPeerByUserAgent(c.Request.UserAgent())
|
||||||
peerModel := model2.PeerDriveDBModel{}
|
peerModel := model2.PeerDriveDBModel{}
|
||||||
name := service.GetName(request)
|
name := service.GetName(request)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@@ -20,23 +21,17 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
currentDate := time.Now().UTC().Format("2006-01-02")
|
currentDate := time.Now().UTC().Format("2006-01-02")
|
||||||
notify := make(map[string]interface{})
|
notify := make(map[string]interface{})
|
||||||
if t == "GoogleDrive" {
|
if t == "GoogleDrive" {
|
||||||
add := google_drive.Addition{}
|
google_drive := google_drive.GetConfig()
|
||||||
add.Code = c.Query("code")
|
google_drive.Code = c.Query("code")
|
||||||
if len(add.Code) == 0 {
|
if len(google_drive.Code) == 0 {
|
||||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
notify["status"] = "fail"
|
notify["status"] = "fail"
|
||||||
notify["message"] = "Code cannot be empty"
|
notify["message"] = "Code cannot be empty"
|
||||||
logger.Error("Then code is empty: ", zap.String("code", add.Code), zap.Any("name", "google_drive"))
|
logger.Error("Then code is empty: ", zap.String("code", google_drive.Code), zap.Any("name", "google_drive"))
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
add.RootFolderID = "root"
|
|
||||||
add.ClientID = google_drive.CLIENTID
|
|
||||||
add.ClientSecret = google_drive.CLIENTSECRET
|
|
||||||
|
|
||||||
var google_drive google_drive.GoogleDrive
|
|
||||||
google_drive.Addition = add
|
|
||||||
err := google_drive.Init(c)
|
err := google_drive.Init(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
@@ -93,8 +88,8 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
//username = fileutil.NameAccumulation(username, "/mnt")
|
//username = fileutil.NameAccumulation(username, "/mnt")
|
||||||
username += "_google_drive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
username += "_google_drive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
dmap["client_id"] = add.ClientID
|
dmap["client_id"] = google_drive.ClientID
|
||||||
dmap["client_secret"] = add.ClientSecret
|
dmap["client_secret"] = google_drive.ClientSecret
|
||||||
dmap["scope"] = "drive"
|
dmap["scope"] = "drive"
|
||||||
dmap["mount_point"] = "/mnt/" + username
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
dmap["token"] = `{"access_token":"` + google_drive.AccessToken + `","token_type":"Bearer","refresh_token":"` + google_drive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*1).Add(time.Minute*50).Format("15:04:05") + `Z"}`
|
dmap["token"] = `{"access_token":"` + google_drive.AccessToken + `","token_type":"Bearer","refresh_token":"` + google_drive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*1).Add(time.Minute*50).Format("15:04:05") + `Z"}`
|
||||||
@@ -106,21 +101,17 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
notify["driver"] = "GoogleDrive"
|
notify["driver"] = "GoogleDrive"
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
} else if t == "Dropbox" {
|
} else if t == "Dropbox" {
|
||||||
add := dropbox.Addition{}
|
dropbox := dropbox.GetConfig()
|
||||||
add.Code = c.Query("code")
|
dropbox.Code = c.Query("code")
|
||||||
if len(add.Code) == 0 {
|
if len(dropbox.Code) == 0 {
|
||||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
notify["status"] = "fail"
|
notify["status"] = "fail"
|
||||||
notify["message"] = "Code cannot be empty"
|
notify["message"] = "Code cannot be empty"
|
||||||
logger.Error("Then code is empty error: ", zap.String("code", add.Code), zap.Any("name", "dropbox"))
|
logger.Error("Then code is empty error: ", zap.String("code", dropbox.Code), zap.Any("name", "dropbox"))
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
add.RootFolderID = ""
|
|
||||||
add.AppKey = dropbox.APPKEY
|
|
||||||
add.AppSecret = dropbox.APPSECRET
|
|
||||||
var dropbox dropbox.Dropbox
|
|
||||||
dropbox.Addition = add
|
|
||||||
err := dropbox.Init(c)
|
err := dropbox.Init(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
@@ -176,8 +167,8 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
dmap["client_id"] = add.AppKey
|
dmap["client_id"] = dropbox.AppKey
|
||||||
dmap["client_secret"] = add.AppSecret
|
dmap["client_secret"] = dropbox.AppSecret
|
||||||
dmap["token"] = `{"access_token":"` + dropbox.AccessToken + `","token_type":"bearer","refresh_token":"` + dropbox.Addition.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
dmap["token"] = `{"access_token":"` + dropbox.AccessToken + `","token_type":"bearer","refresh_token":"` + dropbox.Addition.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||||
dmap["mount_point"] = "/mnt/" + username
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
// data.SetValue(username, "type", "dropbox")
|
// data.SetValue(username, "type", "dropbox")
|
||||||
@@ -199,6 +190,98 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
notify["message"] = "Success"
|
notify["message"] = "Success"
|
||||||
notify["driver"] = "Dropbox"
|
notify["driver"] = "Dropbox"
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
} else if t == "Onedrive" {
|
||||||
|
onedrive := onedrive.GetConfig()
|
||||||
|
onedrive.Code = c.Query("code")
|
||||||
|
if len(onedrive.Code) == 0 {
|
||||||
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Code cannot be empty"
|
||||||
|
logger.Error("Then code is empty error: ", zap.String("code", onedrive.Code), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := onedrive.Init(c)
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Initialization failure"
|
||||||
|
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
username, driveId, driveType, err := onedrive.GetInfo(c)
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Failed to get user information"
|
||||||
|
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dmap := make(map[string]string)
|
||||||
|
dmap["username"] = username
|
||||||
|
|
||||||
|
configs, err := service.MyService.Storage().GetConfig()
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Failed to get rclone config"
|
||||||
|
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range configs.Remotes {
|
||||||
|
cf, err := service.MyService.Storage().GetConfigByName(v)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cf["type"] == "onedrive" && cf["username"] == dmap["username"] {
|
||||||
|
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||||
|
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
||||||
|
}
|
||||||
|
|
||||||
|
notify["status"] = "warn"
|
||||||
|
notify["message"] = "The same configuration has been added"
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(username) > 0 {
|
||||||
|
a := strings.Split(username, "@")
|
||||||
|
username = a[0]
|
||||||
|
}
|
||||||
|
username += "_onedrive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
|
dmap["client_id"] = onedrive.ClientID
|
||||||
|
dmap["client_secret"] = onedrive.ClientSecret
|
||||||
|
dmap["token"] = `{"access_token":"` + onedrive.AccessToken + `","token_type":"bearer","refresh_token":"` + onedrive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||||
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
|
dmap["drive_id"] = driveId
|
||||||
|
dmap["drive_type"] = driveType
|
||||||
|
// data.SetValue(username, "type", "dropbox")
|
||||||
|
// data.SetValue(username, "client_id", add.AppKey)
|
||||||
|
// data.SetValue(username, "client_secret", add.AppSecret)
|
||||||
|
// data.SetValue(username, "mount_point", "/mnt/"+username)
|
||||||
|
|
||||||
|
// data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`)
|
||||||
|
// e = data.Save()
|
||||||
|
// if e != nil {
|
||||||
|
// c.String(200, `<p>保存配置失败:`+e.Error()+`</p>`)
|
||||||
|
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
service.MyService.Storage().CreateConfig(dmap, username, "onedrive")
|
||||||
|
service.MyService.Storage().MountStorage("/mnt/"+username, username+":")
|
||||||
|
|
||||||
|
notify["status"] = "success"
|
||||||
|
notify["message"] = "Success"
|
||||||
|
notify["driver"] = "Onedrive"
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.String(200, `<p>Just close the page</p><script>window.close()</script>`)
|
c.String(200, `<p>Just close the page</p><script>window.close()</script>`)
|
||||||
|
|||||||
131
route/v2.go
131
route/v2.go
@@ -2,13 +2,17 @@ package route
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/external"
|
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
|
||||||
@@ -23,8 +27,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
_swagger *openapi3.T
|
_swagger *openapi3.T
|
||||||
|
|
||||||
V2APIPath string
|
V2APIPath string
|
||||||
V2DocPath string
|
V2DocPath string
|
||||||
|
V3FilePath string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -42,6 +47,7 @@ func init() {
|
|||||||
|
|
||||||
V2APIPath = strings.TrimRight(u.Path, "/")
|
V2APIPath = strings.TrimRight(u.Path, "/")
|
||||||
V2DocPath = "/doc" + V2APIPath
|
V2DocPath = "/doc" + V2APIPath
|
||||||
|
V3FilePath = "/v3/file"
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitV2Router() http.Handler {
|
func InitV2Router() http.Handler {
|
||||||
@@ -110,6 +116,12 @@ func InitV2Router() http.Handler {
|
|||||||
// })
|
// })
|
||||||
|
|
||||||
e.Use(middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{
|
e.Use(middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{
|
||||||
|
Skipper: func(c echo.Context) bool {
|
||||||
|
// jump validate when upload file
|
||||||
|
// because file upload can't pass validate
|
||||||
|
// issue: https://github.com/deepmap/oapi-codegen/issues/514
|
||||||
|
return strings.Contains(c.Request().Header[echo.HeaderContentType][0], "multipart/form-data")
|
||||||
|
},
|
||||||
Options: openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
|
Options: openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -134,3 +146,118 @@ func InitV2DocRouter(docHTML string, docYAML string) http.Handler {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitFile() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
token := r.URL.Query().Get("token")
|
||||||
|
if len(token) == 0 {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "token not found"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||||
|
if errs != nil || !valid {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "validation failure"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filePath := r.URL.Query().Get("path")
|
||||||
|
fileName := path.Base(filePath)
|
||||||
|
w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
|
||||||
|
http.ServeFile(w, r, filePath)
|
||||||
|
//http.ServeFile(w, r, filePath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitDir() http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
token := r.URL.Query().Get("token")
|
||||||
|
if len(token) == 0 {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "token not found"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||||
|
if errs != nil || !valid {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "validation failure"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := r.URL.Query().Get("format")
|
||||||
|
files := r.URL.Query().Get("files")
|
||||||
|
|
||||||
|
if len(files) == 0 {
|
||||||
|
// w.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||||
|
// Success: common_err.INVALID_PARAMS,
|
||||||
|
// Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
|
// })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list := strings.Split(files, ",")
|
||||||
|
for _, v := range list {
|
||||||
|
if !file.Exists(v) {
|
||||||
|
// c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
|
// Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
|
// Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
|
// })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||||||
|
w.Header().Add("Content-Transfer-Encoding", "binary")
|
||||||
|
w.Header().Add("Cache-Control", "no-cache")
|
||||||
|
// handles only single files not folders and multiple files
|
||||||
|
// if len(list) == 1 {
|
||||||
|
|
||||||
|
// filePath := list[0]
|
||||||
|
// info, err := os.Stat(filePath)
|
||||||
|
// if err != nil {
|
||||||
|
|
||||||
|
// w.JSON(http.StatusOK, model.Result{
|
||||||
|
// Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
|
// Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
|
// })
|
||||||
|
//return
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
extension, ar, err := file.GetCompressionAlgorithm(t)
|
||||||
|
if err != nil {
|
||||||
|
// w.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||||
|
// Success: common_err.INVALID_PARAMS,
|
||||||
|
// Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
|
// })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ar.Create(w)
|
||||||
|
if err != nil {
|
||||||
|
// c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
|
// Success: common_err.SERVICE_ERROR,
|
||||||
|
// Message: common_err.GetMsg(common_err.SERVICE_ERROR),
|
||||||
|
// Data: err.Error(),
|
||||||
|
// })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer ar.Close()
|
||||||
|
commonDir := file.CommonPrefix(filepath.Separator, list...)
|
||||||
|
|
||||||
|
currentPath := filepath.Base(commonDir)
|
||||||
|
|
||||||
|
name := "_" + currentPath
|
||||||
|
name += extension
|
||||||
|
w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||||
|
for _, fname := range list {
|
||||||
|
err = file.AddFile(ar, fname, commonDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to archive %s: %v", fname, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,3 +17,70 @@ func (s *CasaOS) GetFileTest(ctx echo.Context) error {
|
|||||||
|
|
||||||
return ctx.String(200, "pong")
|
return ctx.String(200, "pong")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CasaOS) CheckUploadChunk(ctx echo.Context, params codegen.CheckUploadChunkParams) error {
|
||||||
|
identifier := ctx.QueryParam("identifier")
|
||||||
|
chunkNumber, err := strconv.ParseInt(ctx.QueryParam("chunkNumber"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.NoContent(http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.fileUploadService.TestChunk(ctx, identifier, chunkNumber)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.NoContent(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
return ctx.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CasaOS) PostUploadFile(ctx echo.Context) error {
|
||||||
|
path := ctx.FormValue("path")
|
||||||
|
|
||||||
|
// handle the request
|
||||||
|
chunkNumber, err := strconv.ParseInt(ctx.FormValue("chunkNumber"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
chunkSize, err := strconv.ParseInt(ctx.FormValue("chunkSize"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
currentChunkSize, err := strconv.ParseInt(ctx.FormValue("currentChunkSize"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
totalChunks, err := strconv.ParseInt(ctx.FormValue("totalChunks"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
totalSize, err := strconv.ParseInt(ctx.FormValue("totalSize"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
identifier := ctx.FormValue("identifier")
|
||||||
|
fileName := ctx.FormValue("filename")
|
||||||
|
relativePath := ctx.FormValue("relativePath")
|
||||||
|
bin, err := ctx.FormFile("file")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.fileUploadService.UploadFile(
|
||||||
|
ctx,
|
||||||
|
path,
|
||||||
|
chunkNumber,
|
||||||
|
chunkSize,
|
||||||
|
currentChunkSize,
|
||||||
|
totalChunks,
|
||||||
|
totalSize,
|
||||||
|
identifier,
|
||||||
|
relativePath,
|
||||||
|
fileName,
|
||||||
|
bin,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
return ctx.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ func (s *CasaOS) GetHealthPorts(ctx echo.Context) error {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CasaOS) GetHealthlogs(ctx echo.Context) error {
|
func (c *CasaOS) GetHealthlogs(ctx echo.Context) error {
|
||||||
var name, currentPath, commonDir, extension string
|
var name, currentPath, commonDir, extension string
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CasaOS struct{}
|
type CasaOS struct {
|
||||||
|
fileUploadService *service.FileUploadService
|
||||||
|
}
|
||||||
|
|
||||||
func NewCasaOS() codegen.ServerInterface {
|
func NewCasaOS() codegen.ServerInterface {
|
||||||
return &CasaOS{}
|
return &CasaOS{
|
||||||
|
fileUploadService: service.NewFileUploadService(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,35 +13,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *CasaOS) SetZerotierNetworkStatus(ctx echo.Context, networkId string) error {
|
func (s *CasaOS) SetZerotierNetworkStatus(ctx echo.Context, networkId string) error {
|
||||||
ip := `,"via":"10.147.19.0"`
|
|
||||||
m := make(map[string]string)
|
return ctx.JSON(http.StatusOK, nil)
|
||||||
ctx.Bind(&m)
|
|
||||||
status := m["status"]
|
|
||||||
if status == "online" {
|
|
||||||
ip = ``
|
|
||||||
}
|
|
||||||
body := `{
|
|
||||||
"routes": [
|
|
||||||
{
|
|
||||||
"target": "10.147.20.0/24"` + ip + `
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}`
|
|
||||||
res, err := httper.ZTPost("/controller/network/"+networkId, body)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
|
||||||
}
|
|
||||||
info := codegen.GetZTInfoOK{}
|
|
||||||
via := gjson.GetBytes(res, "routes.0.via").Str
|
|
||||||
info.Id = utils.Ptr(gjson.GetBytes(res, "id").Str)
|
|
||||||
info.Name = utils.Ptr(gjson.GetBytes(res, "name").Str)
|
|
||||||
if len(via) == 0 {
|
|
||||||
info.Status = utils.Ptr("online")
|
|
||||||
} else {
|
|
||||||
info.Status = utils.Ptr("offline")
|
|
||||||
}
|
|
||||||
return ctx.JSON(http.StatusOK, info)
|
|
||||||
}
|
}
|
||||||
func (s *CasaOS) GetZerotierInfo(ctx echo.Context) error {
|
func (s *CasaOS) GetZerotierInfo(ctx echo.Context) error {
|
||||||
info := codegen.GetZTInfoOK{}
|
info := codegen.GetZTInfoOK{}
|
||||||
|
|||||||
@@ -102,16 +102,20 @@ func FileOperate(k string) {
|
|||||||
os.RemoveAll(temp.To + "/" + lastPath)
|
os.RemoveAll(temp.To + "/" + lastPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := os.Rename(v.From, temp.To+"/"+lastPath)
|
err := file.CopyDir(v.From, temp.To, temp.Style)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
logger.Error("file move error", zap.Any("err", err))
|
err = os.RemoveAll(v.From)
|
||||||
err = file.MoveFile(v.From, temp.To+"/"+lastPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("MoveFile error", zap.Any("err", err))
|
logger.Error("file move error", zap.Any("err", err))
|
||||||
continue
|
err = file.MoveFile(v.From, temp.To+"/"+lastPath)
|
||||||
}
|
if err != nil {
|
||||||
|
logger.Error("MoveFile error", zap.Any("err", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if temp.Type == "copy" {
|
} else if temp.Type == "copy" {
|
||||||
err := file.CopyDir(v.From, temp.To, temp.Style)
|
err := file.CopyDir(v.From, temp.To, temp.Style)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
167
service/file_upload.go
Normal file
167
service/file_upload.go
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileInfo struct {
|
||||||
|
init bool
|
||||||
|
uploaded []bool
|
||||||
|
uploadedChunkNum int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileUploadService struct {
|
||||||
|
uploadStatus sync.Map
|
||||||
|
lock sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileUploadService() *FileUploadService {
|
||||||
|
return &FileUploadService{
|
||||||
|
uploadStatus: sync.Map{},
|
||||||
|
lock: sync.RWMutex{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FileUploadService) TestChunk(
|
||||||
|
c echo.Context,
|
||||||
|
identifier string,
|
||||||
|
chunkNumber int64,
|
||||||
|
) error {
|
||||||
|
fileInfoTemp, ok := s.uploadStatus.Load(identifier)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("file not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInfo := fileInfoTemp.(*FileInfo)
|
||||||
|
|
||||||
|
if !fileInfo.init {
|
||||||
|
return fmt.Errorf("file not init")
|
||||||
|
}
|
||||||
|
|
||||||
|
// return StatusNoContent instead of 404
|
||||||
|
// the is require by frontend
|
||||||
|
if !fileInfo.uploaded[chunkNumber-1] {
|
||||||
|
return fmt.Errorf("file not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FileUploadService) UploadFile(
|
||||||
|
c echo.Context,
|
||||||
|
path string,
|
||||||
|
chunkNumber int64,
|
||||||
|
chunkSize int64,
|
||||||
|
currentChunkSize int64,
|
||||||
|
totalChunks int64,
|
||||||
|
totalSize int64,
|
||||||
|
identifier string,
|
||||||
|
relativePath string,
|
||||||
|
fileName string,
|
||||||
|
bin *multipart.FileHeader,
|
||||||
|
) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
fileInfoTemp, ok := s.uploadStatus.Load(identifier)
|
||||||
|
var fileInfo *FileInfo
|
||||||
|
|
||||||
|
if relativePath != fileName {
|
||||||
|
// uploaded file is folder
|
||||||
|
folderPath := filepath.Dir(path + "/" + relativePath)
|
||||||
|
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||||||
|
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.OpenFile(path+"/"+relativePath+".tmp", os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// pre allocate file size
|
||||||
|
fmt.Println("truncate", totalSize)
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// file info init
|
||||||
|
fileInfo = &FileInfo{
|
||||||
|
init: true,
|
||||||
|
uploaded: make([]bool, totalChunks),
|
||||||
|
uploadedChunkNum: 0,
|
||||||
|
}
|
||||||
|
s.uploadStatus.Store(identifier, fileInfo)
|
||||||
|
} else {
|
||||||
|
fileInfo = fileInfoTemp.(*FileInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.lock.Unlock()
|
||||||
|
|
||||||
|
_, err = file.Seek((chunkNumber-1)*chunkSize, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := bin.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, src)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.lock.Lock()
|
||||||
|
// handle file after write a chunk
|
||||||
|
// handle single chunk upload twice
|
||||||
|
if !fileInfo.uploaded[chunkNumber-1] {
|
||||||
|
fileInfo.uploadedChunkNum++
|
||||||
|
fileInfo.uploaded[chunkNumber-1] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle file after write all chunk
|
||||||
|
if fileInfo.uploadedChunkNum == totalChunks {
|
||||||
|
err := file.Close()
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
logger.Error("close file error: ", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Rename(path+"/"+relativePath+".tmp", path+"/"+relativePath)
|
||||||
|
if err != nil {
|
||||||
|
s.lock.Unlock()
|
||||||
|
logger.Error("rename file error: ", zap.Error(err))
|
||||||
|
}
|
||||||
|
// remove upload status info after upload complete
|
||||||
|
s.uploadStatus.Delete(identifier)
|
||||||
|
}
|
||||||
|
s.lock.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -473,6 +473,7 @@ func GetCPUThermalZone() string {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache.SetDefault(keyName, path)
|
Cache.SetDefault(keyName, path)
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
@@ -483,7 +484,10 @@ func (s *systemService) GetCPUTemperature() int {
|
|||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
outPut = string(file.ReadFullFile(path + "/temp"))
|
outPut = string(file.ReadFullFile(path + "/temp"))
|
||||||
} else {
|
} else {
|
||||||
outPut = "0"
|
outPut = string(file.ReadFullFile("/sys/class/hwmon/hwmon0/temp1_input"))
|
||||||
|
if len(outPut) == 0 {
|
||||||
|
outPut = "0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
celsius, _ := strconv.Atoi(strings.TrimSpace(outPut))
|
celsius, _ := strconv.Atoi(strings.TrimSpace(outPut))
|
||||||
|
|||||||
Reference in New Issue
Block a user