Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 94ec6cd212 | |||
| 062aa5766e | |||
| 9cf3fcb1fc | |||
| 2e08746f3f | |||
| 08ccf7c318 | |||
| ca4bfde2aa | |||
| bc8702749f | |||
| 9e14c92933 | |||
| 0a6f10a7cc | |||
| bce5cdf746 | |||
| 18728fc993 | |||
| be6f189365 | |||
| da1316af2a | |||
| b759f8b5cc | |||
| c1f6fc4e63 |
+1
-1
@@ -15,7 +15,7 @@ CHANGELOG/
|
|||||||
# LICENSE
|
# LICENSE
|
||||||
|
|
||||||
# Ignore testing and linting configuration
|
# Ignore testing and linting configuration
|
||||||
.golangci.yml
|
scripts/golangci.yml
|
||||||
|
|
||||||
# Ignore deployment-related files
|
# Ignore deployment-related files
|
||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
#
|
#
|
||||||
# Note: by default the `.golangci.yml` file should be at the root of the repository.
|
# Note: by default the `.golangci.yml` file should be at the root of the repository.
|
||||||
# The location of the configuration file can be changed by using `--config=`
|
# The location of the configuration file can be changed by using `--config=`
|
||||||
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
|
args: --timeout=30m --config=/scripts/golangci.yml # --issues-exit-code=0
|
||||||
|
|
||||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||||
# only-new-issues: true
|
# only-new-issues: true
|
||||||
|
|||||||
@@ -43,9 +43,12 @@ jobs:
|
|||||||
# either 'goreleaser' (default) or 'goreleaser-pro':
|
# either 'goreleaser' (default) or 'goreleaser-pro':
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: latest
|
version: latest
|
||||||
args: release --clean
|
workdir: .
|
||||||
|
args: release -f ./build/goreleaser.yaml --rm-dist --clean --release-footer-tmpl=scripts/template/footer.md.tmpl --release-header-tmpl=scripts/template/head.md.tmpl
|
||||||
env:
|
env:
|
||||||
|
USERNAME: ${{ github.repository_owner }}
|
||||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
|
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
|
||||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
|
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
|
||||||
# distribution:
|
# distribution:
|
||||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
|
|||||||
+2
-3
@@ -10,8 +10,8 @@ ENV GOPROXY=$GOPROXY
|
|||||||
# Set up the working directory
|
# Set up the working directory
|
||||||
WORKDIR /openim/openim-server
|
WORKDIR /openim/openim-server
|
||||||
|
|
||||||
COPY go.mod go.sum go.work go.work.sum ./
|
COPY go.mod go.sum ./
|
||||||
#RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
# Copy all files to the container
|
# Copy all files to the container
|
||||||
ADD . .
|
ADD . .
|
||||||
@@ -27,6 +27,5 @@ WORKDIR ${SERVER_WORKDIR}
|
|||||||
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder ${SERVER_WORKDIR}/_output/bin-tools/platforms /openim/openim-server/_output/bin-tools/platforms
|
|
||||||
|
|
||||||
CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"]
|
CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ all: tidy gen add-copyright format lint cover build
|
|||||||
# Build set
|
# Build set
|
||||||
|
|
||||||
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
||||||
# TODO: This is version control for the future
|
# TODO: This is version control for the future https://github.com/OpenIMSDK/Open-IM-Server/issues/574
|
||||||
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -191,6 +191,11 @@ advertise:
|
|||||||
release: release.verify release.ensure-tag
|
release: release.verify release.ensure-tag
|
||||||
@scripts/release.sh
|
@scripts/release.sh
|
||||||
|
|
||||||
|
## demo: Run demo ✨
|
||||||
|
.PHONY: demo
|
||||||
|
demo:
|
||||||
|
@$(MAKE) go.demo
|
||||||
|
|
||||||
## help: Show this help info. ✨
|
## help: Show this help info. ✨
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help: Makefile
|
help: Makefile
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ COPY . .
|
|||||||
RUN make clean
|
RUN make clean
|
||||||
RUN make build BINS=openim-api
|
RUN make build BINS=openim-api
|
||||||
|
|
||||||
FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
# FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||||
|
FROM test:v1
|
||||||
|
|
||||||
WORKDIR /openim/openim-server
|
WORKDIR /openim/openim-server
|
||||||
|
|
||||||
|
RUN mkdir -p /openim/openim-server/$(cat ~/os)/$(cat ~/arch)/bin
|
||||||
|
RUN mkdir -p /openim/openim-server/go/$(go env GOOS)/$(go env GOARCH)/bin
|
||||||
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms
|
||||||
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||||
|
|
||||||
|
|||||||
@@ -479,53 +479,4 @@ checksum:
|
|||||||
algorithm: sha256
|
algorithm: sha256
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
prerelease: auto
|
||||||
prerelease: auto
|
|
||||||
|
|
||||||
footer: |
|
|
||||||
|
|
||||||
## Welcome to the {{ .Tag }} release of [chat](https://github.com/OpenIMSDK/chat)!🎉🎉!
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/OpenIMSDK/Open-IM-Server/compare/{{ .PreviousTag }}...{{ .Tag }}
|
|
||||||
|
|
||||||
## Helping out
|
|
||||||
|
|
||||||
+ We release logs are recorded on [✨CHANGELOG](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CHANGELOG/CHANGELOG.md)
|
|
||||||
|
|
||||||
+ For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md)
|
|
||||||
|
|
||||||
+ If you wish to use mirroring, read OpenIM's [image management policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
|
||||||
|
|
||||||
**Want to be one of them 😘?**
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/kubbot" style="float: left; margin-right: 10px;">
|
|
||||||
<img src="https://github.com/openimbot/openimbot/blob/main/assets/icon/blue%E9%80%8F%E6%98%8E.png" width="50" height="50" />
|
|
||||||
</a>
|
|
||||||
<a href="https://www.openim.online">
|
|
||||||
<img src="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/assets/logo/openim-logo.png" />
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/openimbot" style="float: right; margin-left: 10px;">
|
|
||||||
<img src="https://github.com/openimbot/openimbot/blob/main/assets/icon/red%E9%80%8F%E6%98%8E.png" width="50" height="50" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
> **Note**
|
|
||||||
> @openimbot and @kubbot have made great contributions to the community as community 🤖robots(@openimsdk/bot), respectively.
|
|
||||||
> Thanks to the @openimsdk/openim team for all their hard work on this release.
|
|
||||||
> Thank you to all the [💕developers and contributors](https://github.com/OpenIMSDK/Open-IM-Server/graphs/contributors), people from all over the world, OpenIM brings us together
|
|
||||||
> Contributions to this project are welcome! Please see [CONTRIBUTING.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md) for details.
|
|
||||||
|
|
||||||
## Get Involved with OpenIM!
|
|
||||||
|
|
||||||
**Here are some ways to get involved with the OpenIM community:**
|
|
||||||
|
|
||||||
📢 **Slack Channel**: Join our Slack channels for discussions, communication, and support. Click [here](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to join the Open-IM-Server Slack team channel.
|
|
||||||
|
|
||||||
📧 **Gmail Contact**: If you have any questions, suggestions, or feedback for our open-source projects, please feel free to [contact us via email](https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=winxu81@gmail.com).
|
|
||||||
|
|
||||||
📖 **Blog**: Stay up-to-date with OpenIM-Server projects and trends by reading our [blog](https://doc.rentsoft.cn/). We share the latest developments, tech trends, and other interesting information related to OpenIM.
|
|
||||||
|
|
||||||
📱 **WeChat**: Add us on WeChat (QR Code) and indicate that you are a user or developer of Open-IM-Server. We'll process your request as soon as possible.
|
|
||||||
|
|
||||||
Remember, your contributions play a vital role in making OpenIM successful, and we look forward to your active participation in our community! 🙌
|
|
||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cronTaskCmd := cmd.NewCronTaskCmd()
|
cronTaskCmd := cmd.NewCronTaskCmd()
|
||||||
if err := cronTaskCmd.Exec(tools.StartTask); err != nil {
|
if err := cronTaskCmd.Exec(tools.StartCronTask); err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-43
@@ -24,10 +24,10 @@
|
|||||||
# Zookeeper username
|
# Zookeeper username
|
||||||
# Zookeeper password
|
# Zookeeper password
|
||||||
zookeeper:
|
zookeeper:
|
||||||
schema: openim
|
schema: openim
|
||||||
address: [ 127.0.0.1:2181 ]
|
address: [ 127.0.0.1:2181 ]
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
|
|
||||||
###################### Mysql ######################
|
###################### Mysql ######################
|
||||||
# MySQL configuration
|
# MySQL configuration
|
||||||
@@ -42,12 +42,12 @@ mysql:
|
|||||||
address: [ 127.0.0.1:13306 ]
|
address: [ 127.0.0.1:13306 ]
|
||||||
username: root
|
username: root
|
||||||
password: openIM123
|
password: openIM123
|
||||||
database: openIM_v3
|
database: openIM_v3
|
||||||
maxOpenConn: 1000
|
maxOpenConn: 1000
|
||||||
maxIdleConn: 100
|
maxIdleConn: 100
|
||||||
maxLifeTime: 60
|
maxLifeTime: 60
|
||||||
logLevel: 4
|
logLevel: 4
|
||||||
slowThreshold: 500
|
slowThreshold: 500
|
||||||
|
|
||||||
###################### Mongo ######################
|
###################### Mongo ######################
|
||||||
# MongoDB configuration
|
# MongoDB configuration
|
||||||
@@ -62,7 +62,7 @@ mongo:
|
|||||||
database: openIM_v3
|
database: openIM_v3
|
||||||
username: root
|
username: root
|
||||||
password: openIM123
|
password: openIM123
|
||||||
maxPoolSize: 100
|
maxPoolSize: 100
|
||||||
|
|
||||||
###################### Redis ######################
|
###################### Redis ######################
|
||||||
# Redis configuration
|
# Redis configuration
|
||||||
@@ -70,7 +70,7 @@ mongo:
|
|||||||
# Username is required only for Redis version 6.0+
|
# Username is required only for Redis version 6.0+
|
||||||
redis:
|
redis:
|
||||||
address: [ 127.0.0.1:16379 ]
|
address: [ 127.0.0.1:16379 ]
|
||||||
username:
|
username:
|
||||||
password: openIM123
|
password: openIM123
|
||||||
|
|
||||||
###################### Kafka ######################
|
###################### Kafka ######################
|
||||||
@@ -81,13 +81,13 @@ redis:
|
|||||||
# It's not recommended to modify this topic name
|
# It's not recommended to modify this topic name
|
||||||
# Consumer group ID, it's not recommended to modify
|
# Consumer group ID, it's not recommended to modify
|
||||||
kafka:
|
kafka:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
addr: [ 127.0.0.1:9092 ]
|
addr: [ 127.0.0.1:9092 ]
|
||||||
latestMsgToRedis:
|
latestMsgToRedis:
|
||||||
topic: "latestMsgToRedis"
|
topic: "latestMsgToRedis"
|
||||||
offlineMsgToMongo:
|
offlineMsgToMongo:
|
||||||
topic: "offlineMsgToMongoMysql"
|
topic: "offlineMsgToMongoMysql"
|
||||||
msgToPush:
|
msgToPush:
|
||||||
topic: "msgToPush"
|
topic: "msgToPush"
|
||||||
consumerGroupID:
|
consumerGroupID:
|
||||||
@@ -111,8 +111,8 @@ rpc:
|
|||||||
# API service port
|
# API service port
|
||||||
# Default listen IP is 0.0.0.0
|
# Default listen IP is 0.0.0.0
|
||||||
api:
|
api:
|
||||||
openImApiPort: [ 10002 ]
|
openImApiPort: [ 10002 ]
|
||||||
listenIP: 0.0.0.0
|
listenIP: 0.0.0.0
|
||||||
|
|
||||||
###################### Gateway ######################
|
###################### Gateway ######################
|
||||||
# Object storage configuration
|
# Object storage configuration
|
||||||
@@ -124,29 +124,25 @@ api:
|
|||||||
# Session token
|
# Session token
|
||||||
# Configuration for Tencent COS
|
# Configuration for Tencent COS
|
||||||
# Configuration for Aliyun OSS
|
# Configuration for Aliyun OSS
|
||||||
# apiURL is the address of the api, the access address of the app, use s3 must be configured
|
|
||||||
# minio.endpoint can be configured as an intranet address,
|
|
||||||
# minio.signEndpoint is minio public network address
|
|
||||||
object:
|
object:
|
||||||
enable: "minio"
|
enable: "minio"
|
||||||
apiURL: "http://127.0.0.1:10002"
|
apiURL: http://127.0.0.1:10002/object/
|
||||||
minio:
|
minio:
|
||||||
bucket: "openim"
|
bucket: "openim"
|
||||||
endpoint: "http://127.0.0.1:10005"
|
endpoint: http://127.0.0.1:10005
|
||||||
accessKeyID: "root"
|
accessKeyID: root
|
||||||
secretAccessKey: "openIM123"
|
secretAccessKey: openIM123
|
||||||
sessionToken: ""
|
sessionToken: ""
|
||||||
signEndpoint: "http://127.0.0.1:10005"
|
cos:
|
||||||
cos:
|
|
||||||
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
||||||
secretID: ""
|
secretID: ""
|
||||||
secretKey: ""
|
secretKey: ""
|
||||||
sessionToken: ""
|
sessionToken: ""
|
||||||
oss:
|
oss:
|
||||||
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||||
bucket: "demo-9999999"
|
bucket: "demo-9999999"
|
||||||
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
||||||
accessKeyID: ""
|
accessKeyID: root
|
||||||
accessKeySecret: ""
|
accessKeySecret: ""
|
||||||
sessionToken: ""
|
sessionToken: ""
|
||||||
|
|
||||||
@@ -154,7 +150,7 @@ object:
|
|||||||
# These ports are passed into the program by the script and are not recommended to modify
|
# These ports are passed into the program by the script and are not recommended to modify
|
||||||
# For launching multiple programs, just fill in multiple ports separated by commas
|
# For launching multiple programs, just fill in multiple ports separated by commas
|
||||||
# For example, [10110, 10111]
|
# For example, [10110, 10111]
|
||||||
rpcPort:
|
rpcPort:
|
||||||
openImUserPort: [ 10110 ]
|
openImUserPort: [ 10110 ]
|
||||||
openImFriendPort: [ 10120 ]
|
openImFriendPort: [ 10120 ]
|
||||||
openImMessagePort: [ 10130 ]
|
openImMessagePort: [ 10130 ]
|
||||||
@@ -187,12 +183,12 @@ rpcRegisterName:
|
|||||||
# Whether to output in json format
|
# Whether to output in json format
|
||||||
# Whether to include stack trace in logs
|
# Whether to include stack trace in logs
|
||||||
log:
|
log:
|
||||||
storageLocation: ../../../../../logs/
|
storageLocation: ../../../../../logs/
|
||||||
rotationTime: 24
|
rotationTime: 24
|
||||||
remainRotationCount: 2
|
remainRotationCount: 2
|
||||||
remainLogLevel: 6
|
remainLogLevel: 6
|
||||||
isStdout: false
|
isStdout: false
|
||||||
isJson: false
|
isJson: false
|
||||||
withStack: false
|
withStack: false
|
||||||
|
|
||||||
# Long connection server configuration
|
# Long connection server configuration
|
||||||
@@ -202,10 +198,10 @@ log:
|
|||||||
# Maximum length of websocket request package
|
# Maximum length of websocket request package
|
||||||
# Websocket connection handshake timeout
|
# Websocket connection handshake timeout
|
||||||
longConnSvr:
|
longConnSvr:
|
||||||
openImWsPort: [ 10001 ]
|
openImWsPort: [ 10001 ]
|
||||||
websocketMaxConnNum: 100000
|
websocketMaxConnNum: 100000
|
||||||
websocketMaxMsgLen: 4096
|
websocketMaxMsgLen: 4096
|
||||||
websocketTimeout: 10
|
websocketTimeout: 10
|
||||||
|
|
||||||
# Push notification service configuration
|
# Push notification service configuration
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -304,16 +304,6 @@ userInfoUpdated:
|
|||||||
desc: "Remove a blocked user"
|
desc: "Remove a blocked user"
|
||||||
ext: "Remove a blocked user"
|
ext: "Remove a blocked user"
|
||||||
|
|
||||||
userStatusChanged:
|
|
||||||
isSendMsg: false
|
|
||||||
reliabilityLevel: 1
|
|
||||||
unreadCount: false
|
|
||||||
offlinePush:
|
|
||||||
enable: false
|
|
||||||
title: "user status changed"
|
|
||||||
desc: "user status changed"
|
|
||||||
ext: "user status changed"
|
|
||||||
|
|
||||||
#####################conversation#########################
|
#####################conversation#########################
|
||||||
conversationChanged:
|
conversationChanged:
|
||||||
isSendMsg: false
|
isSendMsg: false
|
||||||
|
|||||||
+3
-6
@@ -62,7 +62,6 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
restart: always
|
restart: always
|
||||||
network_mode: "host"
|
|
||||||
|
|
||||||
kafka:
|
kafka:
|
||||||
image: wurstmeister/kafka
|
image: wurstmeister/kafka
|
||||||
@@ -73,7 +72,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
KAFKA_BROKER_ID: 0
|
KAFKA_BROKER_ID: 0
|
||||||
KAFKA_ZOOKEEPER_CONNECT: 127.0.0.1:2181
|
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||||
KAFKA_CREATE_TOPICS: "latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1"
|
KAFKA_CREATE_TOPICS: "latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1"
|
||||||
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
||||||
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
||||||
@@ -81,7 +80,6 @@ services:
|
|||||||
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
||||||
depends_on:
|
depends_on:
|
||||||
- zookeeper
|
- zookeeper
|
||||||
network_mode: "host"
|
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
@@ -100,7 +98,6 @@ services:
|
|||||||
|
|
||||||
openim-server:
|
openim-server:
|
||||||
image: ghcr.io/openimsdk/openim-server:latest
|
image: ghcr.io/openimsdk/openim-server:latest
|
||||||
# build: .
|
|
||||||
container_name: openim-server
|
container_name: openim-server
|
||||||
volumes:
|
volumes:
|
||||||
- ./logs:/openim/openim-server/logs
|
- ./logs:/openim/openim-server/logs
|
||||||
@@ -150,7 +147,7 @@ services:
|
|||||||
# ports:
|
# ports:
|
||||||
# - 9091:9091
|
# - 9091:9091
|
||||||
depends_on:
|
depends_on:
|
||||||
- openim-server
|
- openim-server
|
||||||
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
|
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
@@ -170,4 +167,4 @@ services:
|
|||||||
# container_name: node-exporter
|
# container_name: node-exporter
|
||||||
# restart: always
|
# restart: always
|
||||||
# ports:
|
# ports:
|
||||||
# - "9100:9100"
|
# - "9100:9100"
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ logs/* @skiffer-git @FGadvancer
|
|||||||
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
|
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
|
||||||
|
|
||||||
# scripts directory
|
# scripts directory
|
||||||
scripts/LICENSE/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
scripts/template/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||||
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||||
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||||
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||||
|
|||||||
+43
-54
@@ -1,88 +1,76 @@
|
|||||||
# OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development
|
# OpenIM Branch Management and Versioning
|
||||||
|
|
||||||
[📚 **OpenIM TOC**](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
|
Our project, OpenIM, follows the [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/) standards.
|
||||||
- [Unfolding the Mechanism of OpenIM Version Maintenance](#unfolding-the-mechanism-of-openim-version-maintenance)
|
|
||||||
- [Main Branch: The Heart of OpenIM Development](#main-branch-the-heart-of-openim-development)
|
|
||||||
- [Release Branch: The Beacon of Stability](#release-branch-the-beacon-of-stability)
|
|
||||||
- [Tag Management: The Cornerstone of Version Control](#tag-management-the-cornerstone-of-version-control)
|
|
||||||
- [Release Management: A Guided Tour](#release-management-a-guided-tour)
|
|
||||||
- [Milestones, Branching, and Addressing Major Bugs](#milestones-branching-and-addressing-major-bugs)
|
|
||||||
- [Applying Principles: A Git Workflow Example](#applying-principles-a-git-workflow-example)
|
|
||||||
- [Docker Images Version Management](#docker-images-version-management)
|
|
||||||
|
|
||||||
|
OpenIM, the open source project, employs a comprehensive version management system to ensure the reliability and traceability of our software. Our version management consists of three main components: the `main` branch, the `release` branch, and `tag` management.
|
||||||
|
|
||||||
At OpenIM, we acknowledge the profound impact of implementing a robust and efficient version management system, hence we abide by the established standards of [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
|
## Main Branch
|
||||||
|
|
||||||
Our software blueprint orchestrates a tripartite version management system that integrates the `main` branch, the `release` branch, and `tag` management. These constituents operate in synchrony to preserve the reliability and traceability of our software across various stages of development.
|
The `main` branch is where all the latest code resides. It's the hub of activity, embodying all the cutting-edge features that are currently being developed or updated. However, since it's subject to frequent changes and updates, it may not always represent the most stable version of the software. Access the `main` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/main).
|
||||||
|
|
||||||
## Unfolding the Mechanism of OpenIM Version Maintenance
|
## Release Branch
|
||||||
|
|
||||||
Our version maintenance protocol revolves around two primary branches, namely: `main` and `release`. We resort to Semantic Versioning 2.0.0 for marking distinctive versions of our software, representing substantial milestones in its evolution.
|
On the other hand, we have the `release` branch. For instance, in the context of version 3.1, we maintain a `release-v3.1` branch. Unlike the `main` branch, the release branch is designed to be a continuously stable and updated version of the software. This provides a reliable option for users who prefer stability over the latest, but potentially unstable, features. Access the `release-v3.1` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/release-v3.1).
|
||||||
|
|
||||||
In the OpenIM repository, version identification strictly complies with the `MAJOR.MINOR.PATCH` protocol. Herein:
|
## Tag Management
|
||||||
|
|
||||||
- The `MAJOR` version indicates a shift arising from incompatible changes to the API.
|
In addition to the `main` and `release` branches, `tag` also plays a pivotal role in version control. Tags are immutable, meaning once they're created, they remain unchanged. Therefore, if you need a specific version of the software, you can use the corresponding tag. All of our available tags can be viewed [here](https://github.com/OpenIMSDK/Open-IM-Server/tags).
|
||||||
- The `MINOR` version suggests the addition of features in a backward-compatible manner.
|
|
||||||
- The `PATCH` version flags backward-compatible bug fixes.
|
|
||||||
|
|
||||||
## Main Branch: The Heart of OpenIM Development
|
Moreover, our Docker image versions are closely tied with these three components. For example, a tag might correspond to the Docker image `ghcr.io/openimsdk/openim-server:v3.1.0`, a release might be represented as `ghcr.io/openimsdk/openim-server:release-v3.0`, and the main branch could be represented as `ghcr.io/openimsdk/openim-server:main` or `ghcr.io/openimsdk/openim-server:latest`.
|
||||||
|
|
||||||
The `main` branch is the operational heart of our development process. Housing the most recent and advanced features, this branch serves as the nerve center for all enhancements and updates. It encapsulates the freshest, though possibly unstable, facets of the software. Visit our `main` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/main).
|
Here is the specification of our version numbers:
|
||||||
|
|
||||||
## Release Branch: The Beacon of Stability
|
- **Revision version number**: The third digit of the version number, representing bug fixes or code optimizations, usually no new features are added and it is backward compatible with older versions.
|
||||||
|
|
||||||
For every major release, we curate a corresponding `release` branch, e.g., `release-v3.1`. This branch symbolizes an embodiment of stability and ensures an updated version of the software, providing a dependable option for users favoring stability over nascent, yet possibly unstable, features. Visit the `release-v3.1` branch [here](https://github.com/OpenIMSDK/Open-IM-Server/tree/release-v3.1).
|
- **Build version number**: Usually automatically generated by the system, every code submission will result in an automatic increment by 1.
|
||||||
|
|
||||||
## Tag Management: The Cornerstone of Version Control
|
- Version modifiers
|
||||||
|
|
||||||
In OpenIM's version control system, the role of `tags` stands paramount. Owing to their immutable nature, tags can be effectively utilized to retrieve a specific version of the software. Explore our library of tags [here](https://github.com/OpenIMSDK/Open-IM-Server/tags).
|
: These can represent the development stage and stability of the software. Common ones include:
|
||||||
|
|
||||||
Our Docker image versions are intimately entwined with these tripartite components. For instance, a Docker image tag may correspond to `ghcr.io/openimsdk/openim-server:v3.1.0`, a release to `ghcr.io/openimsdk/openim-server:release-v3.0`, and the main branch to `ghcr.io/openimsdk/openim-server:main` or `ghcr.io/openimsdk/openim-server:latest`.
|
- `alpha`: An internal testing version with many bugs, generally used for communication among developers.
|
||||||
|
- `beta`: A test version with many bugs, generally used for testing by eager community members, who provide feedback to the developers.
|
||||||
To further clarify, the semantics of our version numbers are as follows:
|
- `rc`: Release candidate, to be released as the official version, it's the last test version before the official version.
|
||||||
|
|
||||||
- **Revision version number**: This represents bug fixes or code optimizations. Typically, it entails no new feature additions and ensures backward compatibility.
|
|
||||||
- **Build version number**: Auto-generated by the system, each code submission prompts an automatic increment by 1.
|
|
||||||
- **Version modifiers**: These hint at the software's development stage and stability. Some commonly used modifiers are `alpha`, `beta`, `rc`, `ga`, `r/release/or nothing`, and `lts`.
|
|
||||||
- `alpha`: An internal testing version with numerous bugs, typically used for communication among developers.
|
|
||||||
- `beta`: A test version with numerous bugs, generally used for testing by eager community members, who provide feedback to the developers.
|
|
||||||
- `rc`: Release candidate, which is to be released as the official version. It's the last test version before the official version.
|
|
||||||
- `ga`: General Availability, the first stable release.
|
- `ga`: General Availability, the first stable release.
|
||||||
- `r/release/or nothing`: The final release version, intended for general users.
|
- `r/release/or nothing`: The final release version, intended for general users.
|
||||||
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs discovered in this version.
|
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs found in this version.
|
||||||
|
|
||||||
Whenever a project undergoes a partial functional addition, the minor version number increments by 1, resetting the revision version number to 0. In contrast, any major project overhaul results in an increment by 1 in the major version number. The build number, typically auto-generated during the compilation process, only requires format definition, thereby eliminating manual control.
|
When adding partial functions to the project, the minor version number increases by 1, and the revision version number resets to 0. When there are major changes in the project, the major version number increases by 1. The build number is generally automatically generated by the compiler during the compilation process, only the format needs to be defined, and it does not need to be manually controlled.
|
||||||
|
|
||||||
## Release Management: A Guided Tour
|
## OpenIM version
|
||||||
|
|
||||||
Our GitHub repository at https://github.com/OpenIMSDK/Open-IM-Server/releases associates a release with each tag, with a distinction between Pre-release and Latest, determined by the branch source. Every significant feature launch prompts the issue of a `release` branch, such as `release-v3.2`, as a beacon of stability and Latest release.
|
OpenIM manages two primary branches: `main` and `release`. The project uses Semantic Versioning 2.0.0 to tag different versions of the software, each indicating a significant milestone in the software's development.
|
||||||
|
|
||||||
Pre-releases correspond to releases from the `main` branch, denoting tags with Version modifiers such as `v3.2.1-beta.0`, `v3.2.1-rc.1`, etc. If you are seeking the most recent, albeit possibly unstable, release with new features, these tags, originating from the latest `main` branch code, are your go-to.
|
In the OpenIM repository, the versioning adheres to the `MAJOR.MINOR.PATCH` format, where:
|
||||||
|
|
||||||
Conversely, if stability is your primary concern, you should opt for the release tagged Latest, denoted by tags without Version modifiers, such as `v3.2.1`, `v3.2.2` etc. These tags are linked to the latest stable maintenance branch, like `release-v3.2`.
|
- `MAJOR` version changes when there are incompatible changes to the API,
|
||||||
|
- `MINOR` version changes when features are added in a backward-compatible manner, and
|
||||||
|
- `PATCH` version changes when backward-compatible bugs are fixed.
|
||||||
|
|
||||||
## Milestones, Branching, and Addressing Major Bugs
|
## Milestones and Branching
|
||||||
|
|
||||||
**About:**
|
|
||||||
|
|
||||||
+ [OpenIM Milestones](https://github.com/OpenIMSDK/Open-IM-Server/milestones)
|
+ [OpenIM Milestones](https://github.com/OpenIMSDK/Open-IM-Server/milestones)
|
||||||
+ [OpenIM Tags](https://github.com/OpenIMSDK/Open-IM-Server/tags)
|
+ [OpenIM Tags](https://github.com/OpenIMSDK/Open-IM-Server/tags)
|
||||||
+ [OpenIM Branches](https://github.com/OpenIMSDK/Open-IM-Server/branches)
|
+ [OpenIM Branches](https://github.com/OpenIMSDK/Open-IM-Server/branches)
|
||||||
|
|
||||||
We create a new branch, such as `release-v3.1`, for each significant milestone (e.g., v3.1.0), housing all relevant code for that release. All enhancements and bug fixes targeting the subsequent version (e.g., v3.2.0) are integrated into this branch.
|
When a significant milestone like v3.1.0 is achieved, a new branch `release-v3.1` is created. This branch contains all the code pertaining to this stable release. All bug fixes and features intended for the next version, v3.2.0, are merged into this branch.
|
||||||
|
|
||||||
`PATCH` versions (represented by Z in `X.Y.Z`) are primarily propelled by bug fixes, and their release may be either priority-driven or scheduled. In contrast, `MINOR` versions (represented by Y in `X.Y.Z`) are contingent upon the project's roadmap, milestone completion, or a pre-established timeline, always maintaining backward-compatible APIs.
|
The release of `PATCH` versions (Z in `X.Y.Z`) are driven by bug fixes, and these can be rolled out depending on the bug's priority or over a scheduled time. On the other hand, `MINOR` versions (Y in `X.Y.Z`) are released based on the project's roadmap, milestone completion, or on a scheduled timeline. Importantly, the API of minor versions is always backward-compatible.
|
||||||
|
|
||||||
When dealing with major bugs, we selectively merge the fix into the affected version (e.g., v3.1 or the `release-v3.1` branch), as well as the `main` branch. This dual pronged strategy ensures that users on older versions receive crucial bug fixes, while also keeping the `main` branch updated.
|
## Dealing with Major Bugs
|
||||||
|
|
||||||
We reinforce our approach to branch management and versioning with stringent testing protocols. Automated tests and code review sessions form vital components of maintaining a robust and reliable codebase.
|
In the event of a major bug discovery, the fix would selectively be merged into the previous version (e.g., v3.1 or the `release-v3.1` branch), as well as into the `main` branch. This is to ensure that users relying on the older version can still receive important bug fixes, while also keeping the main branch updated.
|
||||||
|
|
||||||
## Applying Principles: A Git Workflow Example
|
It's worth noting that a robust testing regime should be in place to ensure the integrity of all branches at any given time. Automated tests and code review sessions are crucial components of maintaining a healthy codebase.
|
||||||
|
|
||||||
The workflow to address a bug fix might follow these steps:
|
To summarize, OpenIM's approach to branch management and versioning ensures a balance between introducing new features, fixing bugs, and maintaining backward compatibility. This strategy is vital for managing user expectations, supporting older versions, and paving the way for the project's continuous growth.
|
||||||
|
|
||||||
```bash
|
## Git Workflow Example
|
||||||
bashCopy codebashCopy code# Checkout the branch for the version that needs the bug fix
|
|
||||||
|
To put the above principles into practice, here's a Git workflow example that you might follow when working on a bug fix:
|
||||||
|
|
||||||
|
```
|
||||||
|
bashCopy code# Checkout the branch for the version that needs the bug fix
|
||||||
git checkout release-v3.1
|
git checkout release-v3.1
|
||||||
|
|
||||||
# Create a new branch for the bug fix
|
# Create a new branch for the bug fix
|
||||||
@@ -105,8 +93,9 @@ git merge release-v3.1
|
|||||||
git push origin main
|
git push origin main
|
||||||
```
|
```
|
||||||
|
|
||||||
Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes.
|
Remember, communication with your team is key throughout this process, keeping everyone up-to-date with the changes being made.
|
||||||
|
|
||||||
## Docker Images Version Management
|
|
||||||
|
|
||||||
For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md).
|
## Docker images version management
|
||||||
|
|
||||||
|
+ [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
||||||
|
|||||||
@@ -25,19 +25,19 @@ require (
|
|||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.12.1
|
go.mongodb.org/mongo-driver v1.12.1
|
||||||
golang.org/x/image v0.11.0
|
golang.org/x/image v0.9.0 // indirect
|
||||||
google.golang.org/api v0.136.0
|
google.golang.org/api v0.135.0
|
||||||
google.golang.org/grpc v1.57.0
|
google.golang.org/grpc v1.57.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.31.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/mysql v1.5.1
|
gorm.io/driver/mysql v1.5.1
|
||||||
gorm.io/gorm v1.25.3
|
gorm.io/gorm v1.25.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/google/uuid v1.3.0
|
require github.com/google/uuid v1.3.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/OpenIMSDK/protocol v0.0.10
|
github.com/OpenIMSDK/protocol v0.0.6
|
||||||
github.com/OpenIMSDK/tools v0.0.13
|
github.com/OpenIMSDK/tools v0.0.13
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
|
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
|
||||||
github.com/go-redis/redis v6.15.9+incompatible
|
github.com/go-redis/redis v6.15.9+incompatible
|
||||||
@@ -47,11 +47,11 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.110.6 // indirect
|
cloud.google.com/go v0.110.4 // indirect
|
||||||
cloud.google.com/go/compute v1.23.0 // indirect
|
cloud.google.com/go/compute v1.20.1 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
cloud.google.com/go/firestore v1.11.0 // indirect
|
cloud.google.com/go/firestore v1.11.0 // indirect
|
||||||
cloud.google.com/go/iam v1.1.1 // indirect
|
cloud.google.com/go/iam v1.1.0 // indirect
|
||||||
cloud.google.com/go/longrunning v0.5.1 // indirect
|
cloud.google.com/go/longrunning v0.5.1 // indirect
|
||||||
cloud.google.com/go/storage v1.30.1 // indirect
|
cloud.google.com/go/storage v1.30.1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
@@ -117,17 +117,17 @@ require (
|
|||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/net v0.14.0 // indirect
|
golang.org/x/net v0.12.0 // indirect
|
||||||
golang.org/x/oauth2 v0.11.0 // indirect
|
golang.org/x/oauth2 v0.10.0 // indirect
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
golang.org/x/sys v0.11.0 // indirect
|
golang.org/x/sys v0.10.0 // indirect
|
||||||
golang.org/x/text v0.12.0 // indirect
|
golang.org/x/text v0.11.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -138,6 +138,6 @@ require (
|
|||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.12.0 // indirect
|
golang.org/x/crypto v0.11.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
|
||||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||||
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
|
||||||
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||||
cloud.google.com/go/firestore v1.11.0 h1:PPgtwcYUOXV2jFe1bV3nda3RCrOa8cvBjTOn2MQVfW8=
|
cloud.google.com/go/firestore v1.11.0 h1:PPgtwcYUOXV2jFe1bV3nda3RCrOa8cvBjTOn2MQVfW8=
|
||||||
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
|
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
|
||||||
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
|
cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
|
||||||
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk=
|
||||||
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
|
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
|
||||||
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
|
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
|
||||||
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||||
@@ -17,8 +17,8 @@ cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7Biccwk
|
|||||||
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
||||||
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OpenIMSDK/protocol v0.0.10 h1:OiJR2BAAJjuKKK8KPxYZdJCwOSzMMxwF5fnJdOmLPdQ=
|
github.com/OpenIMSDK/protocol v0.0.6 h1:KjaItOEww7vjrhwyxHnVzhw80pnjcNukpskadqW6gnA=
|
||||||
github.com/OpenIMSDK/protocol v0.0.10/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
github.com/OpenIMSDK/protocol v0.0.6/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||||
github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo=
|
github.com/OpenIMSDK/tools v0.0.13 h1:rcw4HS8S2DPZR9UOBxD8/ol9UBMzXBypzOVEytDRIMo=
|
||||||
github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
github.com/OpenIMSDK/tools v0.0.13/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||||
@@ -361,11 +361,11 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
|||||||
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.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
golang.org/x/image v0.9.0 h1:QrzfX26snvCM20hIhBwuHI/ThTg18b/+kcKdXHvnR+g=
|
||||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
golang.org/x/image v0.9.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
@@ -394,12 +394,12 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
|
|||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
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.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.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||||
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.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -430,8 +430,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
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=
|
||||||
@@ -442,8 +442,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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
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.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.11.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=
|
||||||
@@ -463,8 +463,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
google.golang.org/api v0.136.0 h1:e/6enzUE1s4tGPa6Q3ZYShKTtvRc+1Jq0rrafhppmOs=
|
google.golang.org/api v0.135.0 h1:6Vgfj6uPMXcyy66waYWBwmkeNB+9GmUlJDOzkukPQYQ=
|
||||||
google.golang.org/api v0.136.0/go.mod h1:XtJfF+V2zgUxelOn5Zs3kECtluMxneJG8ZxUTlLNTPA=
|
google.golang.org/api v0.135.0/go.mod h1:Bp77uRFgwsSKI0BWH573F5Q6wSlznwI2NFayLOp/7mQ=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
@@ -473,12 +473,12 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
|||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
|
||||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44=
|
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
|
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e h1:S83+ibolgyZ0bqz7KEsUOPErxcv4VzlszxY+31OfB/E=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
@@ -523,8 +523,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|||||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
||||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
|
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
||||||
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ go 1.20
|
|||||||
|
|
||||||
use (
|
use (
|
||||||
.
|
.
|
||||||
./tools/component
|
./tools/changelog
|
||||||
./tools/infra
|
./tools/infra
|
||||||
./tools/ncpu
|
./tools/ncpu
|
||||||
|
./tools/yamlfmt
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-306
@@ -1,311 +1,9 @@
|
|||||||
cloud.google.com/go/accessapproval v1.7.1 h1:/5YjNhR6lzCvmJZAnByYkfEgWjfAKwYP6nkuTk6nKFE=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68=
|
|
||||||
cloud.google.com/go/accesscontextmanager v1.8.1 h1:WIAt9lW9AXtqw/bnvrEUaE8VG/7bAAeMzRCBGMkc4+w=
|
|
||||||
cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo=
|
|
||||||
cloud.google.com/go/aiplatform v1.48.0 h1:M5davZWCTzE043rJCn+ZLW6hSxfG1KAx4vJTtas2/ec=
|
|
||||||
cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA=
|
|
||||||
cloud.google.com/go/analytics v0.21.3 h1:TFBC1ZAqX9/jL56GEXdLrVe5vT3I22bDVWyDwZX4IEg=
|
|
||||||
cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo=
|
|
||||||
cloud.google.com/go/apigateway v1.6.1 h1:aBSwCQPcp9rZ0zVEUeJbR623palnqtvxJlUyvzsKGQc=
|
|
||||||
cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA=
|
|
||||||
cloud.google.com/go/apigeeconnect v1.6.1 h1:6u/jj0P2c3Mcm+H9qLsXI7gYcTiG9ueyQL3n6vCmFJM=
|
|
||||||
cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs=
|
|
||||||
cloud.google.com/go/apigeeregistry v0.7.1 h1:hgq0ANLDx7t2FDZDJQrCMtCtddR/pjCqVuvQWGrQbXw=
|
|
||||||
cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw=
|
|
||||||
cloud.google.com/go/appengine v1.8.1 h1:J+aaUZ6IbTpBegXbmEsh8qZZy864ZVnOoWyfa1XSNbI=
|
|
||||||
cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY=
|
|
||||||
cloud.google.com/go/area120 v0.8.1 h1:wiOq3KDpdqXmaHzvZwKdpoM+3lDcqsI2Lwhyac7stss=
|
|
||||||
cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg=
|
|
||||||
cloud.google.com/go/artifactregistry v1.14.1 h1:k6hNqab2CubhWlGcSzunJ7kfxC7UzpAfQ1UPb9PDCKI=
|
|
||||||
cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E=
|
|
||||||
cloud.google.com/go/asset v1.14.1 h1:vlHdznX70eYW4V1y1PxocvF6tEwxJTTarwIGwOhFF3U=
|
|
||||||
cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ=
|
|
||||||
cloud.google.com/go/assuredworkloads v1.11.1 h1:yaO0kwS+SnhVSTF7BqTyVGt3DTocI6Jqo+S3hHmCwNk=
|
|
||||||
cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0=
|
|
||||||
cloud.google.com/go/automl v1.13.1 h1:iP9iQurb0qbz+YOOMfKSEjhONA/WcoOIjt6/m+6pIgo=
|
|
||||||
cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE=
|
|
||||||
cloud.google.com/go/baremetalsolution v1.1.1 h1:0Ge9PQAy6cZ1tRrkc44UVgYV15nw2TVnzJzYsMHXF+E=
|
|
||||||
cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA=
|
|
||||||
cloud.google.com/go/batch v1.3.1 h1:uE0Q//W7FOGPjf7nuPiP0zoE8wOT3ngoIO2HIet0ilY=
|
|
||||||
cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A=
|
|
||||||
cloud.google.com/go/beyondcorp v1.0.0 h1:VPg+fZXULQjs8LiMeWdLaB5oe8G9sEoZ0I0j6IMiG1Q=
|
|
||||||
cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4=
|
|
||||||
cloud.google.com/go/bigquery v1.53.0 h1:K3wLbjbnSlxhuG5q4pntHv5AEbQM1QqHKGYgwFIqOTg=
|
|
||||||
cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4=
|
|
||||||
cloud.google.com/go/billing v1.16.0 h1:1iktEAIZ2uA6KpebC235zi/rCXDdDYQ0bTXTNetSL80=
|
|
||||||
cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA=
|
|
||||||
cloud.google.com/go/binaryauthorization v1.6.1 h1:cAkOhf1ic92zEN4U1zRoSupTmwmxHfklcp1X7CCBKvE=
|
|
||||||
cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U=
|
|
||||||
cloud.google.com/go/certificatemanager v1.7.1 h1:uKsohpE0hiobx1Eak9jNcPCznwfB6gvyQCcS28Ah9E8=
|
|
||||||
cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI=
|
|
||||||
cloud.google.com/go/channel v1.16.0 h1:dqRkK2k7Ll/HHeYGxv18RrfhozNxuTJRkspW0iaFZoY=
|
|
||||||
cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc=
|
|
||||||
cloud.google.com/go/cloudbuild v1.13.0 h1:YBbAWcvE4x6xPWTyS+OU4eiUpz5rCS3VCM/aqmfddPA=
|
|
||||||
cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU=
|
|
||||||
cloud.google.com/go/clouddms v1.6.1 h1:rjR1nV6oVf2aNNB7B5uz1PDIlBjlOiBgR+q5n7bbB7M=
|
|
||||||
cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI=
|
|
||||||
cloud.google.com/go/cloudtasks v1.12.1 h1:cMh9Q6dkvh+Ry5LAPbD/U2aw6KAqdiU6FttwhbTo69w=
|
|
||||||
cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM=
|
|
||||||
cloud.google.com/go/contactcenterinsights v1.10.0 h1:YR2aPedGVQPpFBZXJnPkqRj8M//8veIZZH5ZvICoXnI=
|
|
||||||
cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
|
|
||||||
cloud.google.com/go/container v1.24.0 h1:N51t/cgQJFqDD/W7Mb+IvmAPHrf8AbPx7Bb7aF4lROE=
|
|
||||||
cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4=
|
|
||||||
cloud.google.com/go/containeranalysis v0.10.1 h1:SM/ibWHWp4TYyJMwrILtcBtYKObyupwOVeceI9pNblw=
|
|
||||||
cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0=
|
|
||||||
cloud.google.com/go/datacatalog v1.16.0 h1:qVeQcw1Cz93/cGu2E7TYUPh8Lz5dn5Ws2siIuQ17Vng=
|
|
||||||
cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4=
|
|
||||||
cloud.google.com/go/dataflow v0.9.1 h1:VzG2tqsk/HbmOtq/XSfdF4cBvUWRK+S+oL9k4eWkENQ=
|
|
||||||
cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw=
|
|
||||||
cloud.google.com/go/dataform v0.8.1 h1:xcWso0hKOoxeW72AjBSIp/UfkvpqHNzzS0/oygHlcqY=
|
|
||||||
cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M=
|
|
||||||
cloud.google.com/go/datafusion v1.7.1 h1:eX9CZoyhKQW6g1Xj7+RONeDj1mV8KQDKEB9KLELX9/8=
|
|
||||||
cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI=
|
|
||||||
cloud.google.com/go/datalabeling v0.8.1 h1:zxsCD/BLKXhNuRssen8lVXChUj8VxF3ofN06JfdWOXw=
|
|
||||||
cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY=
|
|
||||||
cloud.google.com/go/dataplex v1.9.0 h1:yoBWuuUZklYp7nx26evIhzq8+i/nvKYuZr1jka9EqLs=
|
|
||||||
cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE=
|
|
||||||
cloud.google.com/go/dataproc/v2 v2.0.1 h1:4OpSiPMMGV3XmtPqskBU/RwYpj3yMFjtMLj/exi425Q=
|
|
||||||
cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4=
|
|
||||||
cloud.google.com/go/dataqna v0.8.1 h1:ITpUJep04hC9V7C+gcK390HO++xesQFSUJ7S4nSnF3U=
|
|
||||||
cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8=
|
|
||||||
cloud.google.com/go/datastore v1.13.0 h1:ktbC66bOQB3HJPQe8qNI1/aiQ77PMu7hD4mzE6uxe3w=
|
|
||||||
cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70=
|
|
||||||
cloud.google.com/go/datastream v1.10.0 h1:ra/+jMv36zTAGPfi8TRne1hXme+UsKtdcK4j6bnqQiw=
|
|
||||||
cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q=
|
|
||||||
cloud.google.com/go/deploy v1.13.0 h1:A+w/xpWgz99EYzB6e31gMGAI/P5jTZ2UO7veQK5jQ8o=
|
|
||||||
cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g=
|
|
||||||
cloud.google.com/go/dialogflow v1.40.0 h1:sCJbaXt6ogSbxWQnERKAzos57f02PP6WkGbOZvXUdwc=
|
|
||||||
cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4=
|
|
||||||
cloud.google.com/go/dlp v1.10.1 h1:tF3wsJ2QulRhRLWPzWVkeDz3FkOGVoMl6cmDUHtfYxw=
|
|
||||||
cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI=
|
|
||||||
cloud.google.com/go/documentai v1.22.0 h1:dW8ex9yb3oT9s1yD2+yLcU8Zq15AquRZ+wd0U+TkxFw=
|
|
||||||
cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E=
|
|
||||||
cloud.google.com/go/domains v0.9.1 h1:rqz6KY7mEg7Zs/69U6m6LMbB7PxFDWmT3QWNXIqhHm0=
|
|
||||||
cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE=
|
|
||||||
cloud.google.com/go/edgecontainer v1.1.1 h1:zhHWnLzg6AqzE+I3gzJqiIwHfjEBhWctNQEzqb+FaRo=
|
|
||||||
cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk=
|
|
||||||
cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0=
|
|
||||||
cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=
|
|
||||||
cloud.google.com/go/essentialcontacts v1.6.2 h1:OEJ0MLXXCW/tX1fkxzEZOsv/wRfyFsvDVNaHWBAvoV0=
|
|
||||||
cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4=
|
|
||||||
cloud.google.com/go/eventarc v1.13.0 h1:xIP3XZi0Xawx8DEfh++mE2lrIi5kQmCr/KcWhJ1q0J4=
|
|
||||||
cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI=
|
|
||||||
cloud.google.com/go/filestore v1.7.1 h1:Eiz8xZzMJc5ppBWkuaod/PUdUZGCFR8ku0uS+Ah2fRw=
|
|
||||||
cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4=
|
|
||||||
cloud.google.com/go/functions v1.15.1 h1:LtAyqvO1TFmNLcROzHZhV0agEJfBi+zfMZsF4RT/a7U=
|
|
||||||
cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE=
|
|
||||||
cloud.google.com/go/gkebackup v1.3.0 h1:lgyrpdhtJKV7l1GM15YFt+OCyHMxsQZuSydyNmS0Pxo=
|
|
||||||
cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU=
|
|
||||||
cloud.google.com/go/gkeconnect v0.8.1 h1:a1ckRvVznnuvDWESM2zZDzSVFvggeBaVY5+BVB8tbT0=
|
|
||||||
cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw=
|
|
||||||
cloud.google.com/go/gkehub v0.14.1 h1:2BLSb8i+Co1P05IYCKATXy5yaaIw/ZqGvVSBTLdzCQo=
|
|
||||||
cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY=
|
|
||||||
cloud.google.com/go/gkemulticloud v1.0.0 h1:MluqhtPVZReoriP5+adGIw+ij/RIeRik8KApCW2WMTw=
|
|
||||||
cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw=
|
|
||||||
cloud.google.com/go/gsuiteaddons v1.6.1 h1:mi9jxZpzVjLQibTS/XfPZvl+Jr6D5Bs8pGqUjllRb00=
|
|
||||||
cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY=
|
|
||||||
cloud.google.com/go/iap v1.8.1 h1:X1tcp+EoJ/LGX6cUPt3W2D4H2Kbqq0pLAsldnsCjLlE=
|
|
||||||
cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ=
|
|
||||||
cloud.google.com/go/ids v1.4.1 h1:khXYmSoDDhWGEVxHl4c4IgbwSRR+qE/L4hzP3vaU9Hc=
|
|
||||||
cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw=
|
|
||||||
cloud.google.com/go/iot v1.7.1 h1:yrH0OSmicD5bqGBoMlWG8UltzdLkYzNUwNVUVz7OT54=
|
|
||||||
cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk=
|
|
||||||
cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs=
|
|
||||||
cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
|
|
||||||
cloud.google.com/go/language v1.10.1 h1:3MXeGEv8AlX+O2LyV4pO4NGpodanc26AmXwOuipEym0=
|
|
||||||
cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0=
|
|
||||||
cloud.google.com/go/lifesciences v0.9.1 h1:axkANGx1wiBXHiPcJZAE+TDjjYoJRIDzbHC/WYllCBU=
|
|
||||||
cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc=
|
|
||||||
cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I=
|
|
||||||
cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
|
|
||||||
cloud.google.com/go/managedidentities v1.6.1 h1:2/qZuOeLgUHorSdxSQGtnOu9xQkBn37+j+oZQv/KHJY=
|
|
||||||
cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak=
|
|
||||||
cloud.google.com/go/maps v1.4.0 h1:PdfgpBLhAoSzZrQXP+/zBc78fIPLZSJp5y8+qSMn2UU=
|
|
||||||
cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s=
|
|
||||||
cloud.google.com/go/mediatranslation v0.8.1 h1:50cF7c1l3BanfKrpnTCaTvhf+Fo6kdF21DG0byG7gYU=
|
|
||||||
cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig=
|
|
||||||
cloud.google.com/go/memcache v1.10.1 h1:7lkLsF0QF+Mre0O/NvkD9Q5utUNwtzvIYjrOLOs0HO0=
|
|
||||||
cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA=
|
|
||||||
cloud.google.com/go/metastore v1.12.0 h1:+9DsxUOHvsqvC0ylrRc/JwzbXJaaBpfIK3tX0Lx8Tcc=
|
|
||||||
cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA=
|
|
||||||
cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58=
|
|
||||||
cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM=
|
|
||||||
cloud.google.com/go/networkconnectivity v1.12.1 h1:LnrYM6lBEeTq+9f2lR4DjBhv31EROSAQi/P5W4Q0AEc=
|
|
||||||
cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E=
|
|
||||||
cloud.google.com/go/networkmanagement v1.8.0 h1:/3xP37eMxnyvkfLrsm1nv1b2FbMMSAEAOlECTvoeCq4=
|
|
||||||
cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0=
|
|
||||||
cloud.google.com/go/networksecurity v0.9.1 h1:TBLEkMp3AE+6IV/wbIGRNTxnqLXHCTEQWoxRVC18TzY=
|
|
||||||
cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ=
|
|
||||||
cloud.google.com/go/notebooks v1.9.1 h1:CUqMNEtv4EHFnbogV+yGHQH5iAQLmijOx191innpOcs=
|
|
||||||
cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8=
|
|
||||||
cloud.google.com/go/optimization v1.4.1 h1:pEwOAmO00mxdbesCRSsfj8Sd4rKY9kBrYW7Vd3Pq7cA=
|
|
||||||
cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk=
|
|
||||||
cloud.google.com/go/orchestration v1.8.1 h1:KmN18kE/xa1n91cM5jhCh7s1/UfIguSCisw7nTMUzgE=
|
|
||||||
cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8=
|
|
||||||
cloud.google.com/go/orgpolicy v1.11.1 h1:I/7dHICQkNwym9erHqmlb50LRU588NPCvkfIY0Bx9jI=
|
|
||||||
cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE=
|
|
||||||
cloud.google.com/go/osconfig v1.12.1 h1:dgyEHdfqML6cUW6/MkihNdTVc0INQst0qSE8Ou1ub9c=
|
|
||||||
cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE=
|
|
||||||
cloud.google.com/go/oslogin v1.10.1 h1:LdSuG3xBYu2Sgr3jTUULL1XCl5QBx6xwzGqzoDUw1j0=
|
|
||||||
cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs=
|
|
||||||
cloud.google.com/go/phishingprotection v0.8.1 h1:aK/lNmSd1vtbft/vLe2g7edXK72sIQbqr2QyrZN/iME=
|
|
||||||
cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I=
|
|
||||||
cloud.google.com/go/policytroubleshooter v1.8.0 h1:XTMHy31yFmXgQg57CB3w9YQX8US7irxDX0Fl0VwlZyY=
|
|
||||||
cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU=
|
|
||||||
cloud.google.com/go/privatecatalog v0.9.1 h1:B/18xGo+E0EMS9LOEQ0zXz7F2asMgmVgTYGSI89MHOA=
|
|
||||||
cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA=
|
|
||||||
cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g=
|
|
||||||
cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
|
|
||||||
cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY=
|
|
||||||
cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0=
|
|
||||||
cloud.google.com/go/recaptchaenterprise/v2 v2.7.2 h1:IGkbudobsTXAwmkEYOzPCQPApUCsN4Gbq3ndGVhHQpI=
|
|
||||||
cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU=
|
|
||||||
cloud.google.com/go/recommendationengine v0.8.1 h1:nMr1OEVHuDambRn+/y4RmNAmnR/pXCuHtH0Y4tCgGRQ=
|
|
||||||
cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE=
|
|
||||||
cloud.google.com/go/recommender v1.10.1 h1:UKp94UH5/Lv2WXSQe9+FttqV07x/2p1hFTMMYVFtilg=
|
|
||||||
cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA=
|
|
||||||
cloud.google.com/go/redis v1.13.1 h1:YrjQnCC7ydk+k30op7DSjSHw1yAYhqYXFcOq1bSXRYA=
|
|
||||||
cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg=
|
|
||||||
cloud.google.com/go/resourcemanager v1.9.1 h1:QIAMfndPOHR6yTmMUB0ZN+HSeRmPjR/21Smq5/xwghI=
|
|
||||||
cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8=
|
|
||||||
cloud.google.com/go/resourcesettings v1.6.1 h1:Fdyq418U69LhvNPFdlEO29w+DRRjwDA4/pFamm4ksAg=
|
|
||||||
cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw=
|
|
||||||
cloud.google.com/go/retail v1.14.1 h1:gYBrb9u/Hc5s5lUTFXX1Vsbc/9BEvgtioY6ZKaK0DK8=
|
|
||||||
cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE=
|
|
||||||
cloud.google.com/go/run v1.2.0 h1:kHeIG8q+N6Zv0nDkBjSOYfK2eWqa5FnaiDPH/7/HirE=
|
|
||||||
cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo=
|
|
||||||
cloud.google.com/go/scheduler v1.10.1 h1:yoZbZR8880KgPGLmACOMCiY2tPk+iX4V/dkxqTirlz8=
|
|
||||||
cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo=
|
|
||||||
cloud.google.com/go/secretmanager v1.11.1 h1:cLTCwAjFh9fKvU6F13Y4L9vPcx9yiWPyWXE4+zkuEQs=
|
|
||||||
cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw=
|
|
||||||
cloud.google.com/go/security v1.15.1 h1:jR3itwycg/TgGA0uIgTItcVhA55hKWiNJxaNNpQJaZE=
|
|
||||||
cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA=
|
|
||||||
cloud.google.com/go/securitycenter v1.23.0 h1:XOGJ9OpnDtqg8izd7gYk/XUhj8ytjIalyjjsR6oyG0M=
|
|
||||||
cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ=
|
|
||||||
cloud.google.com/go/servicedirectory v1.11.0 h1:pBWpjCFVGWkzVTkqN3TBBIqNSoSHY86/6RL0soSQ4z8=
|
|
||||||
cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ=
|
|
||||||
cloud.google.com/go/shell v1.7.1 h1:aHbwH9LSqs4r2rbay9f6fKEls61TAjT63jSyglsw7sI=
|
|
||||||
cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g=
|
|
||||||
cloud.google.com/go/spanner v1.47.0 h1:aqiMP8dhsEXgn9K5EZBWxPG7dxIiyM2VaikqeU4iteg=
|
|
||||||
cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI=
|
|
||||||
cloud.google.com/go/speech v1.19.0 h1:MCagaq8ObV2tr1kZJcJYgXYbIn8Ai5rp42tyGYw9rls=
|
|
||||||
cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo=
|
|
||||||
cloud.google.com/go/storagetransfer v1.10.0 h1:+ZLkeXx0K0Pk5XdDmG0MnUVqIR18lllsihU/yq39I8Q=
|
|
||||||
cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA=
|
|
||||||
cloud.google.com/go/talent v1.6.2 h1:j46ZgD6N2YdpFPux9mc7OAf4YK3tiBCsbLKc8rQx+bU=
|
|
||||||
cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24=
|
|
||||||
cloud.google.com/go/texttospeech v1.7.1 h1:S/pR/GZT9p15R7Y2dk2OXD/3AufTct/NSxT4a7nxByw=
|
|
||||||
cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk=
|
|
||||||
cloud.google.com/go/tpu v1.6.1 h1:kQf1jgPY04UJBYYjNUO+3GrZtIb57MfGAW2bwgLbR3A=
|
|
||||||
cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E=
|
|
||||||
cloud.google.com/go/trace v1.10.1 h1:EwGdOLCNfYOOPtgqo+D2sDLZmRCEO1AagRTJCU6ztdg=
|
|
||||||
cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk=
|
|
||||||
cloud.google.com/go/translate v1.8.2 h1:PQHamiOzlehqLBJMnM72lXk/OsMQewZB12BKJ8zXrU0=
|
|
||||||
cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs=
|
|
||||||
cloud.google.com/go/video v1.19.0 h1:BRyyS+wU+Do6VOXnb8WfPr42ZXti9hzmLKLUCkggeK4=
|
|
||||||
cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU=
|
|
||||||
cloud.google.com/go/videointelligence v1.11.1 h1:MBMWnkQ78GQnRz5lfdTAbBq/8QMCF3wahgtHh3s/J+k=
|
|
||||||
cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo=
|
|
||||||
cloud.google.com/go/vision/v2 v2.7.2 h1:ccK6/YgPfGHR/CyESz1mvIbsht5Y2xRsWCPqmTNydEw=
|
|
||||||
cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU=
|
|
||||||
cloud.google.com/go/vmmigration v1.7.1 h1:gnjIclgqbEMc+cF5IJuPxp53wjBIlqZ8h9hE8Rkwp7A=
|
|
||||||
cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro=
|
|
||||||
cloud.google.com/go/vmwareengine v1.0.0 h1:qsJ0CPlOQu/3MFBGklu752v3AkD+Pdu091UmXJ+EjTA=
|
|
||||||
cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0=
|
|
||||||
cloud.google.com/go/vpcaccess v1.7.1 h1:ram0GzjNWElmbxXMIzeOZUkQ9J8ZAahD6V8ilPGqX0Y=
|
|
||||||
cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs=
|
|
||||||
cloud.google.com/go/webrisk v1.9.1 h1:Ssy3MkOMOnyRV5H2bkMQ13Umv7CwB/kugo3qkAX83Fk=
|
|
||||||
cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc=
|
|
||||||
cloud.google.com/go/websecurityscanner v1.6.1 h1:CfEF/vZ+xXyAR3zC9iaC/QRdf1MEgS20r5UR17Q4gOg=
|
|
||||||
cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg=
|
|
||||||
cloud.google.com/go/workflows v1.11.1 h1:2akeQ/PgtRhrNuD/n1WvJd5zb7YyuDZrlOanBj2ihPg=
|
|
||||||
cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g=
|
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
|
||||||
github.com/OpenIMSDK/protocol v0.0.10 h1:OiJR2BAAJjuKKK8KPxYZdJCwOSzMMxwF5fnJdOmLPdQ=
|
|
||||||
github.com/OpenIMSDK/protocol v0.0.10/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409 h1:DTQ/38ao/CfXsrK0cSAL+h4R/u0VVvfWLZEOlLwEROI=
|
|
||||||
github.com/alecthomas/kingpin/v2 v2.3.1 h1:ANLJcKmQm4nIaog7xdr/id6FM6zm5hHnfZrvtKPxqGg=
|
|
||||||
github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE=
|
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
|
||||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
|
||||||
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
|
|
||||||
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
|
||||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
|
||||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
|
||||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
|
||||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
|
||||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
|
||||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
|
||||||
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
|
||||||
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
|
|
||||||
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
|
|
||||||
github.com/google/go-pkcs11 v0.2.0 h1:5meDPB26aJ98f+K9G21f0AqZwo/S5BJMJh8nuhMbdsI=
|
|
||||||
github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
|
|
||||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
|
||||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
|
||||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
|
||||||
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
|
|
||||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
|
||||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
|
||||||
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
|
|
||||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
|
||||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563 h1:2VDxTtn9dAqI2DnnvB9fXpPE4DblOmquyzmN2zxTD8A=
|
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563 h1:FoX+MK4vHThvPO6FbP5q98zD8S3n+d5+DbtK7skl++c=
|
|
||||||
github.com/xdg/scram v1.0.3 h1:nTadYh2Fs4BK2xdldEa2g5bbaZp0/+1nJMMPtPxS/to=
|
|
||||||
github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4=
|
|
||||||
github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc=
|
|
||||||
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
|
|
||||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8=
|
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
|
|
||||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
|
||||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
|
||||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
|
||||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
|
||||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577 h1:ZX0eQu2J+jOO87sq8fQG8J/Nfp7D7BhHpixIE5EYK/k=
|
|
||||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
|
|
||||||
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||||
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||||
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
||||||
userRouterGroup.POST("/get_subscribe_users_status", ParseToken, u.GetSubscribeUsersStatus)
|
|
||||||
}
|
}
|
||||||
// friend routing group
|
// friend routing group
|
||||||
friendRouterGroup := r.Group("/friend", ParseToken)
|
friendRouterGroup := r.Group("/friend", ParseToken)
|
||||||
|
|||||||
@@ -83,14 +83,7 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
|
|||||||
operationID = strconv.Itoa(rand.Int())
|
operationID = strconv.Itoa(rand.Int())
|
||||||
}
|
}
|
||||||
ctx := mcontext.SetOperationID(c, operationID)
|
ctx := mcontext.SetOperationID(c, operationID)
|
||||||
query := make(map[string]string)
|
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name})
|
||||||
for key, values := range c.Request.URL.Query() {
|
|
||||||
if len(values) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
query[key] = values[0]
|
|
||||||
}
|
|
||||||
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name, Query: query})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errs.ErrArgs.Is(err) {
|
if errs.ErrArgs.Is(err) {
|
||||||
c.String(http.StatusBadRequest, err.Error())
|
c.String(http.StatusBadRequest, err.Error())
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
|||||||
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
||||||
|
|
||||||
parseError := apiresp.ParseError(err)
|
parseError := apiresp.ParseError(err)
|
||||||
log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode)
|
|
||||||
if parseError.ErrCode == errs.NoPermissionError {
|
if parseError.ErrCode == errs.NoPermissionError {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
@@ -196,12 +195,6 @@ func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
|
|||||||
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserStatus Get the online status of the user.
|
|
||||||
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
||||||
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubscribeUsersStatus Get the online status of subscribers.
|
|
||||||
func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) {
|
|
||||||
a2r.Call(user.UserClient.GetSubscribeUsersStatus, u.Client, c)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -40,13 +40,7 @@ type Req struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Req) String() string {
|
func (r *Req) String() string {
|
||||||
var tReq Req
|
return utils.StructToJsonString(r)
|
||||||
tReq.ReqIdentifier = r.ReqIdentifier
|
|
||||||
tReq.Token = r.Token
|
|
||||||
tReq.SendID = r.SendID
|
|
||||||
tReq.OperationID = r.OperationID
|
|
||||||
tReq.MsgIncr = r.MsgIncr
|
|
||||||
return utils.StructToJsonString(tReq)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resp struct {
|
type Resp struct {
|
||||||
@@ -59,13 +53,7 @@ type Resp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resp) String() string {
|
func (r *Resp) String() string {
|
||||||
var tResp Resp
|
return utils.StructToJsonString(r)
|
||||||
tResp.ReqIdentifier = r.ReqIdentifier
|
|
||||||
tResp.MsgIncr = r.MsgIncr
|
|
||||||
tResp.OperationID = r.OperationID
|
|
||||||
tResp.ErrCode = r.ErrCode
|
|
||||||
tResp.ErrMsg = r.ErrMsg
|
|
||||||
return utils.StructToJsonString(tResp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageHandler interface {
|
type MessageHandler interface {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
|
|||||||
len(modifyMsgList),
|
len(modifyMsgList),
|
||||||
)
|
)
|
||||||
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
||||||
conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMsgList[0].message)
|
conversationIDNotification := msgprocessor.GetNotificationConversationID(ctxMsgList[0].message)
|
||||||
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
||||||
och.handleNotification(
|
och.handleNotification(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
+19
-74
@@ -16,9 +16,6 @@ package group
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -76,33 +73,20 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||||
var gs groupServer
|
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
||||||
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), gs.groupMemberHashCode)
|
pbGroup.RegisterGroupServer(server, &groupServer{
|
||||||
gs.GroupDatabase = database
|
GroupDatabase: database,
|
||||||
gs.User = userRpcClient
|
User: userRpcClient,
|
||||||
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
||||||
|
}),
|
||||||
|
conversationRpcClient: conversationRpcClient,
|
||||||
|
msgRpcClient: msgRpcClient,
|
||||||
})
|
})
|
||||||
gs.conversationRpcClient = conversationRpcClient
|
|
||||||
gs.msgRpcClient = msgRpcClient
|
|
||||||
pbGroup.RegisterGroupServer(server, &gs)
|
|
||||||
//pbGroup.RegisterGroupServer(server, &groupServer{
|
|
||||||
// GroupDatabase: database,
|
|
||||||
// User: userRpcClient,
|
|
||||||
// Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
|
||||||
// users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
|
||||||
// }),
|
|
||||||
// conversationRpcClient: conversationRpcClient,
|
|
||||||
// msgRpcClient: msgRpcClient,
|
|
||||||
//})
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +161,6 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
|
|||||||
if req.OwnerUserID == "" {
|
if req.OwnerUserID == "" {
|
||||||
return nil, errs.ErrArgs.Wrap("no group owner")
|
return nil, errs.ErrArgs.Wrap("no group owner")
|
||||||
}
|
}
|
||||||
if req.GroupInfo.GroupType != constant.WorkingGroup {
|
|
||||||
return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group type %d not support", req.GroupInfo.GroupType))
|
|
||||||
}
|
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -709,7 +690,8 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
||||||
}
|
}
|
||||||
var inGroup bool
|
var inGroup bool
|
||||||
if _, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil {
|
_, err = s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID)
|
||||||
|
if err == nil {
|
||||||
inGroup = true // 已经在群里了
|
inGroup = true // 已经在群里了
|
||||||
} else if !s.IsNotFound(err) {
|
} else if !s.IsNotFound(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -736,7 +718,6 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.ZDebug(ctx, "GroupApplicationResponse", "inGroup", inGroup, "HandleResult", req.HandleResult, "member", member)
|
|
||||||
if err := s.GroupDatabase.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil {
|
if err := s.GroupDatabase.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -746,14 +727,12 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.GroupApplicationAcceptedNotification(ctx, req)
|
s.Notification.GroupApplicationAcceptedNotification(ctx, req)
|
||||||
if member == nil {
|
|
||||||
log.ZDebug(ctx, "GroupApplicationResponse", "member is nil")
|
|
||||||
} else {
|
|
||||||
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.FromUserID)
|
|
||||||
}
|
|
||||||
case constant.GroupResponseRefuse:
|
case constant.GroupResponseRefuse:
|
||||||
s.Notification.GroupApplicationRejectedNotification(ctx, req)
|
s.Notification.GroupApplicationRejectedNotification(ctx, req)
|
||||||
}
|
}
|
||||||
|
if member != nil {
|
||||||
|
s.Notification.MemberEnterNotification(ctx, req)
|
||||||
|
}
|
||||||
return &pbGroup.GroupApplicationResponseResp{}, nil
|
return &pbGroup.GroupApplicationResponseResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,7 +778,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq)
|
|||||||
if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil {
|
if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
s.Notification.MemberEnterDirectlyNotification(ctx, req.GroupID, req.InviterUserID)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
groupRequest := relationTb.GroupRequestModel{
|
groupRequest := relationTb.GroupRequestModel{
|
||||||
@@ -1507,37 +1486,3 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
|
|||||||
resp.Total = total
|
resp.Total = total
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) {
|
|
||||||
userIDs, err := s.GroupDatabase.FindGroupMemberUserID(ctx, groupID)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var members []*sdkws.GroupMemberFullInfo
|
|
||||||
if len(userIDs) > 0 {
|
|
||||||
resp, err := s.GetGroupMembersInfo(ctx, &pbGroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
members = resp.Members
|
|
||||||
utils.Sort(userIDs, true)
|
|
||||||
}
|
|
||||||
memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string {
|
|
||||||
return e.UserID
|
|
||||||
})
|
|
||||||
res := make([]*sdkws.GroupMemberFullInfo, 0, len(members))
|
|
||||||
for _, userID := range userIDs {
|
|
||||||
member, ok := memberMap[userID]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
member.AppMangerLevel = 0
|
|
||||||
res = append(res, member)
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
sum := md5.Sum(data)
|
|
||||||
return binary.BigEndian.Uint64(sum[:]), nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,15 +26,10 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (resp *msg.GetConversationsHasReadAndMaxSeqResp, err error) {
|
func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *msg.GetConversationsHasReadAndMaxSeqReq) (*msg.GetConversationsHasReadAndMaxSeqResp, error) {
|
||||||
var conversationIDs []string
|
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
if len(req.ConversationIDs) == 0 {
|
if err != nil {
|
||||||
conversationIDs, err = m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
conversationIDs = req.ConversationIDs
|
|
||||||
}
|
}
|
||||||
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -54,7 +49,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp = &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)}
|
resp := &msg.GetConversationsHasReadAndMaxSeqResp{Seqs: make(map[string]*msg.Seqs)}
|
||||||
for conversarionID, maxSeq := range maxSeqs {
|
for conversarionID, maxSeq := range maxSeqs {
|
||||||
resp.Seqs[conversarionID] = &msg.Seqs{
|
resp.Seqs[conversarionID] = &msg.Seqs{
|
||||||
HasReadSeq: hasReadSeqs[conversarionID],
|
HasReadSeq: hasReadSeqs[conversarionID],
|
||||||
|
|||||||
@@ -116,75 +116,41 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
|
|||||||
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
|
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
sendIDs []string
|
|
||||||
recvIDs []string
|
|
||||||
groupIDs []string
|
|
||||||
sendMap = make(map[string]string)
|
|
||||||
recvMap = make(map[string]string)
|
|
||||||
groupMap = make(map[string]*sdkws.GroupInfo)
|
|
||||||
)
|
|
||||||
for _, chatLog := range chatLogs {
|
|
||||||
if chatLog.SenderNickname == "" {
|
|
||||||
sendIDs = append(sendIDs, chatLog.SendID)
|
|
||||||
}
|
|
||||||
switch chatLog.SessionType {
|
|
||||||
case constant.SingleChatType:
|
|
||||||
recvIDs = append(recvIDs, chatLog.RecvID)
|
|
||||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
|
||||||
groupIDs = append(groupIDs, chatLog.GroupID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(sendIDs) != 0 {
|
|
||||||
sendInfos, err := m.User.GetUsersInfo(ctx, sendIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, sendInfo := range sendInfos {
|
|
||||||
sendMap[sendInfo.UserID] = sendInfo.Nickname
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(recvIDs) != 0 {
|
|
||||||
recvInfos, err := m.User.GetUsersInfo(ctx, recvIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, recvInfo := range recvInfos {
|
|
||||||
recvMap[recvInfo.UserID] = recvInfo.Nickname
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(groupIDs) != 0 {
|
|
||||||
groupInfos, err := m.Group.GetGroupInfos(ctx, groupIDs, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, groupInfo := range groupInfos {
|
|
||||||
groupMap[groupInfo.GroupID] = groupInfo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, chatLog := range chatLogs {
|
for _, chatLog := range chatLogs {
|
||||||
pbChatLog := &msg.ChatLog{}
|
pbChatLog := &msg.ChatLog{}
|
||||||
utils.CopyStructFields(pbChatLog, chatLog)
|
utils.CopyStructFields(pbChatLog, chatLog)
|
||||||
pbChatLog.SendTime = chatLog.SendTime
|
pbChatLog.SendTime = chatLog.SendTime
|
||||||
pbChatLog.CreateTime = chatLog.CreateTime
|
pbChatLog.CreateTime = chatLog.CreateTime
|
||||||
if chatLog.SenderNickname == "" {
|
if chatLog.SenderNickname == "" {
|
||||||
pbChatLog.SenderNickname = sendMap[chatLog.SendID]
|
sendUser, err := m.User.GetUserInfo(ctx, chatLog.SendID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbChatLog.SenderNickname = sendUser.Nickname
|
||||||
}
|
}
|
||||||
switch chatLog.SessionType {
|
switch chatLog.SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
pbChatLog.RecvNickname = recvMap[chatLog.RecvID]
|
recvUser, err := m.User.GetUserInfo(ctx, chatLog.RecvID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbChatLog.RecvNickname = recvUser.Nickname
|
||||||
|
|
||||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||||
pbChatLog.SenderFaceURL = groupMap[chatLog.GroupID].FaceURL
|
group, err := m.Group.GetGroupInfo(ctx, chatLog.GroupID)
|
||||||
pbChatLog.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount
|
if err != nil {
|
||||||
pbChatLog.RecvID = groupMap[chatLog.GroupID].GroupID
|
return nil, err
|
||||||
pbChatLog.GroupName = groupMap[chatLog.GroupID].GroupName
|
}
|
||||||
pbChatLog.GroupOwner = groupMap[chatLog.GroupID].OwnerUserID
|
pbChatLog.SenderFaceURL = group.FaceURL
|
||||||
pbChatLog.GroupType = groupMap[chatLog.GroupID].GroupType
|
pbChatLog.GroupMemberCount = group.MemberCount
|
||||||
|
pbChatLog.RecvID = group.GroupID
|
||||||
|
pbChatLog.GroupName = group.GroupName
|
||||||
|
pbChatLog.GroupOwner = group.OwnerUserID
|
||||||
|
pbChatLog.GroupType = group.GroupType
|
||||||
}
|
}
|
||||||
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
|
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.ChatLogsNum = total
|
resp.ChatLogsNum = total
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if groupMemberInfo.RoleLevel == constant.GroupOwner {
|
if groupMemberInfo.RoleLevel == constant.GroupOwner {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
if groupMemberInfo.MuteEndTime >= time.Now().UnixMilli() {
|
if groupMemberInfo.MuteEndTime >= time.Now().Unix() {
|
||||||
return errs.ErrMutedInGroup.Wrap()
|
return errs.ErrMutedInGroup.Wrap()
|
||||||
}
|
}
|
||||||
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
||||||
|
|||||||
@@ -16,11 +16,8 @@ package third
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
@@ -155,21 +152,7 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
||||||
opt := &s3.AccessURLOption{}
|
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire)
|
||||||
if len(req.Query) > 0 {
|
|
||||||
switch req.Query["type"] {
|
|
||||||
case "":
|
|
||||||
case "image":
|
|
||||||
opt.Image = &s3.Image{}
|
|
||||||
opt.Image.Format = req.Query["format"]
|
|
||||||
opt.Image.Width, _ = strconv.Atoi(req.Query["width"])
|
|
||||||
opt.Image.Height, _ = strconv.Atoi(req.Query["height"])
|
|
||||||
log.ZDebug(ctx, "AccessURL image", "name", req.Name, "option", opt.Image)
|
|
||||||
default:
|
|
||||||
return nil, errs.ErrArgs.Wrap("invalid query type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire, opt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
if apiURL[len(apiURL)-1] != '/' {
|
if apiURL[len(apiURL)-1] != '/' {
|
||||||
apiURL += "/"
|
apiURL += "/"
|
||||||
}
|
}
|
||||||
apiURL += "object/"
|
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+17
-48
@@ -20,16 +20,17 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
||||||
@@ -40,17 +41,16 @@ import (
|
|||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||||
|
|
||||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type userServer struct {
|
type userServer struct {
|
||||||
controller.UserDatabase
|
controller.UserDatabase
|
||||||
friendNotificationSender *notification.FriendNotificationSender
|
notificationSender *notification.FriendNotificationSender
|
||||||
userNotificationSender *notification.UserNotificationSender
|
friendRpcClient *rpcclient.FriendRpcClient
|
||||||
friendRpcClient *rpcclient.FriendRpcClient
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
@@ -83,11 +83,10 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||||
u := &userServer{
|
u := &userServer{
|
||||||
UserDatabase: database,
|
UserDatabase: database,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
friendRpcClient: &friendRpcClient,
|
friendRpcClient: &friendRpcClient,
|
||||||
friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
notificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
||||||
userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
|
||||||
}
|
}
|
||||||
pbuser.RegisterUserServer(server, u)
|
pbuser.RegisterUserServer(server, u)
|
||||||
return u.UserDatabase.InitOnce(context.Background(), users)
|
return u.UserDatabase.InitOnce(context.Background(), users)
|
||||||
@@ -120,13 +119,13 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
_ = s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
||||||
friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID)
|
friends, err := s.friendRpcClient.GetFriendIDs(ctx, req.UserInfo.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.notificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
@@ -141,7 +140,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
|||||||
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
s.notificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +273,6 @@ func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, req *pbus
|
|||||||
return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil
|
return &pbuser.SubscribeOrCancelUsersStatusResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserStatus Get the online status of the user.
|
|
||||||
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp, err error) {
|
||||||
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -283,39 +281,10 @@ func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatu
|
|||||||
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
|
return &pbuser.GetUserStatusResp{StatusList: onlineStatusList}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUserStatus Synchronize user's online status.
|
|
||||||
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp, err error) {
|
||||||
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
|
err = s.UserDatabase.SetUserStatus(ctx, req.StatusList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, value := range req.StatusList {
|
|
||||||
list, err := s.UserDatabase.GetSubscribedList(ctx, value.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, userID := range list {
|
|
||||||
tips := &sdkws.UserStatusChangeTips{
|
|
||||||
FromUserID: value.UserID,
|
|
||||||
ToUserID: userID,
|
|
||||||
Status: value.Status,
|
|
||||||
PlatformID: value.PlatformID,
|
|
||||||
}
|
|
||||||
s.userNotificationSender.UserStatusChangeNotification(ctx, tips)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &pbuser.SetUserStatusResp{}, nil
|
return &pbuser.SetUserStatusResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubscribeUsersStatus Get the online status of subscribers.
|
|
||||||
func (s *userServer) GetSubscribeUsersStatus(ctx context.Context, req *pbuser.GetSubscribeUsersStatusReq) (*pbuser.GetSubscribeUsersStatusResp, error) {
|
|
||||||
userList, err := s.UserDatabase.GetAllSubscribeList(ctx, req.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, userList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pbuser.GetSubscribeUsersStatusResp{StatusList: onlineStatusList}, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,13 +26,12 @@ import (
|
|||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartTask() error {
|
func StartCronTask() error {
|
||||||
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
||||||
msgTool, err := InitMsgTool()
|
msgTool, err := InitMsgTool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
msgTool.ConvertTools()
|
|
||||||
c := cron.New()
|
c := cron.New()
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
tx.NewGorm(db),
|
tx.NewGorm(db),
|
||||||
userMongoDB,
|
userMongoDB,
|
||||||
)
|
)
|
||||||
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil)
|
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
||||||
conversationDatabase := controller.NewConversationDatabase(
|
conversationDatabase := controller.NewConversationDatabase(
|
||||||
relation.NewConversationGorm(db),
|
relation.NewConversationGorm(db),
|
||||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
package tools
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/msgprocessor"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *MsgTool) ConvertTools() {
|
|
||||||
ctx := mcontext.NewCtx("convert")
|
|
||||||
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "get all conversation ids failed", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, conversationID := range conversationIDs {
|
|
||||||
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID))
|
|
||||||
}
|
|
||||||
userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "get all user ids failed", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.ZDebug(ctx, "all userIDs", "len userIDs", len(userIDs))
|
|
||||||
for _, userID := range userIDs {
|
|
||||||
conversationIDs = append(conversationIDs, msgprocessor.GetConversationIDBySessionType(constant.SingleChatType, userID, userID))
|
|
||||||
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationID(constant.SingleChatType, userID, userID))
|
|
||||||
}
|
|
||||||
log.ZDebug(ctx, "all conversationIDs", "len userIDs", len(conversationIDs))
|
|
||||||
c.msgDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package apistruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package authverify // import "github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package callbackstruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/callbackstruct"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cmd // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/cmd"
|
||||||
@@ -120,7 +120,6 @@ type configStruct struct {
|
|||||||
AccessKeyID string `yaml:"accessKeyID"`
|
AccessKeyID string `yaml:"accessKeyID"`
|
||||||
SecretAccessKey string `yaml:"secretAccessKey"`
|
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||||
SessionToken string `yaml:"sessionToken"`
|
SessionToken string `yaml:"sessionToken"`
|
||||||
SignEndpoint string `yaml:"signEndpoint"`
|
|
||||||
} `yaml:"minio"`
|
} `yaml:"minio"`
|
||||||
Cos struct {
|
Cos struct {
|
||||||
BucketURL string `yaml:"bucketURL"`
|
BucketURL string `yaml:"bucketURL"`
|
||||||
@@ -284,8 +283,7 @@ type notification struct {
|
|||||||
GroupInfoSetAnnouncement NotificationConf `yaml:"groupInfoSetAnnouncement"`
|
GroupInfoSetAnnouncement NotificationConf `yaml:"groupInfoSetAnnouncement"`
|
||||||
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
|
GroupInfoSetName NotificationConf `yaml:"groupInfoSetName"`
|
||||||
////////////////////////user///////////////////////
|
////////////////////////user///////////////////////
|
||||||
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
|
UserInfoUpdated NotificationConf `yaml:"userInfoUpdated"`
|
||||||
UserStatusChanged NotificationConf `yaml:"userStatusChanged"`
|
|
||||||
//////////////////////friend///////////////////////
|
//////////////////////friend///////////////////////
|
||||||
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
|
FriendApplicationAdded NotificationConf `yaml:"friendApplicationAdded"`
|
||||||
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
|
FriendApplicationApproved NotificationConf `yaml:"friendApplicationApproved"`
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package config // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package convert // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||||
Vendored
+20
-64
@@ -16,10 +16,10 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
|
|
||||||
"github.com/dtm-labs/rockscache"
|
"github.com/dtm-labs/rockscache"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ const (
|
|||||||
groupExpireTime = time.Second * 60 * 60 * 12
|
groupExpireTime = time.Second * 60 * 60 * 12
|
||||||
groupInfoKey = "GROUP_INFO:"
|
groupInfoKey = "GROUP_INFO:"
|
||||||
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||||
groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
groupMembersHashKey = "GROUP_MEMBERS_HASH:"
|
||||||
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||||
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
|
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
|
||||||
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
|
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
|
||||||
@@ -96,7 +96,6 @@ type GroupCacheRedis struct {
|
|||||||
mongoDB unrelationTb.SuperGroupModelInterface
|
mongoDB unrelationTb.SuperGroupModelInterface
|
||||||
expireTime time.Duration
|
expireTime time.Duration
|
||||||
rcClient *rockscache.Client
|
rcClient *rockscache.Client
|
||||||
hashCode func(ctx context.Context, groupID string) (uint64, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroupCacheRedis(
|
func NewGroupCacheRedis(
|
||||||
@@ -105,16 +104,13 @@ func NewGroupCacheRedis(
|
|||||||
groupMemberDB relationTb.GroupMemberModelInterface,
|
groupMemberDB relationTb.GroupMemberModelInterface,
|
||||||
groupRequestDB relationTb.GroupRequestModelInterface,
|
groupRequestDB relationTb.GroupRequestModelInterface,
|
||||||
mongoClient unrelationTb.SuperGroupModelInterface,
|
mongoClient unrelationTb.SuperGroupModelInterface,
|
||||||
hashCode func(ctx context.Context, groupID string) (uint64, error),
|
|
||||||
opts rockscache.Options,
|
opts rockscache.Options,
|
||||||
) GroupCache {
|
) GroupCache {
|
||||||
rcClient := rockscache.NewClient(rdb, opts)
|
rcClient := rockscache.NewClient(rdb, opts)
|
||||||
return &GroupCacheRedis{
|
return &GroupCacheRedis{
|
||||||
rcClient: rcClient, expireTime: groupExpireTime,
|
rcClient: rcClient, expireTime: groupExpireTime,
|
||||||
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
|
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
|
||||||
mongoDB: mongoClient,
|
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient),
|
||||||
hashCode: hashCode,
|
|
||||||
metaCache: NewMetaCacheRedis(rcClient),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,61 +290,22 @@ func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
|
|||||||
|
|
||||||
// groupMembersHash.
|
// groupMembersHash.
|
||||||
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
||||||
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
|
return getCache(
|
||||||
return g.hashCode(ctx, groupID)
|
ctx,
|
||||||
})
|
g.rcClient,
|
||||||
|
g.getGroupMembersHashKey(groupID),
|
||||||
//return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime,
|
g.expireTime,
|
||||||
// func(ctx context.Context) (uint64, error) {
|
func(ctx context.Context) (uint64, error) {
|
||||||
// userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// return 0, err
|
return 0, err
|
||||||
// }
|
}
|
||||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs)
|
utils.Sort(userIDs, true)
|
||||||
// var members []*relationTb.GroupMemberModel
|
bi := big.NewInt(0)
|
||||||
// if len(userIDs) > 0 {
|
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||||
// members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
return bi.Uint64(), nil
|
||||||
// if err != nil {
|
},
|
||||||
// return 0, err
|
)
|
||||||
// }
|
|
||||||
// utils.Sort(userIDs, true)
|
|
||||||
// }
|
|
||||||
// memberMap := make(map[string]*relationTb.GroupMemberModel)
|
|
||||||
// for i, member := range members {
|
|
||||||
// memberMap[member.UserID] = members[i]
|
|
||||||
// }
|
|
||||||
// data := make([]string, 0, len(members)*11)
|
|
||||||
// for _, userID := range userIDs {
|
|
||||||
// member, ok := memberMap[userID]
|
|
||||||
// if !ok {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// data = append(data,
|
|
||||||
// member.GroupID,
|
|
||||||
// member.UserID,
|
|
||||||
// member.Nickname,
|
|
||||||
// member.FaceURL,
|
|
||||||
// strconv.Itoa(int(member.RoleLevel)),
|
|
||||||
// strconv.FormatInt(member.JoinTime.UnixMilli(), 10),
|
|
||||||
// strconv.Itoa(int(member.JoinSource)),
|
|
||||||
// member.InviterUserID,
|
|
||||||
// member.OperatorUserID,
|
|
||||||
// strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10),
|
|
||||||
// member.Ex,
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data))
|
|
||||||
// log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data)
|
|
||||||
// val, err := json.Marshal(data)
|
|
||||||
// if err != nil {
|
|
||||||
// return 0, err
|
|
||||||
// }
|
|
||||||
// sum := md5.Sum(val)
|
|
||||||
// code := binary.BigEndian.Uint64(sum[:])
|
|
||||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members))
|
|
||||||
// return code, nil
|
|
||||||
// },
|
|
||||||
//)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(
|
func (g *GroupCacheRedis) GetGroupMemberHashMap(
|
||||||
@@ -361,7 +318,6 @@ func (g *GroupCacheRedis) GetGroupMemberHashMap(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "GetGroupMemberHashMap", "groupID", groupID, "hash", hash)
|
|
||||||
num, err := g.GetGroupMemberNum(ctx, groupID)
|
num, err := g.GetGroupMemberNum(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package controller // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||||
@@ -209,7 +209,6 @@ func (f *friendDatabase) RefuseFriendRequest(
|
|||||||
if fr.HandleResult != 0 {
|
if fr.HandleResult != 0 {
|
||||||
return errs.ErrArgs.Wrap("the friend request has been processed")
|
return errs.ErrArgs.Wrap("the friend request has been processed")
|
||||||
}
|
}
|
||||||
log.ZDebug(ctx, "refuse friend request", "friendRequest db", fr, "friendRequest arg", friendRequest)
|
|
||||||
friendRequest.HandleResult = constant.FriendResponseRefuse
|
friendRequest.HandleResult = constant.FriendResponseRefuse
|
||||||
friendRequest.HandleTime = time.Now()
|
friendRequest.HandleTime = time.Now()
|
||||||
err = f.friendRequest.Update(ctx, friendRequest)
|
err = f.friendRequest.Update(ctx, friendRequest)
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ func NewGroupDatabase(
|
|||||||
return database
|
return database
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase {
|
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database) GroupDatabase {
|
||||||
rcOptions := rockscache.NewDefaultOptions()
|
rcOptions := rockscache.NewDefaultOptions()
|
||||||
rcOptions.StrongConsistency = true
|
rcOptions.StrongConsistency = true
|
||||||
rcOptions.RandomExpireAdjustment = 0.2
|
rcOptions.RandomExpireAdjustment = 0.2
|
||||||
@@ -170,7 +170,6 @@ func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.D
|
|||||||
relation.NewGroupMemberDB(db),
|
relation.NewGroupMemberDB(db),
|
||||||
relation.NewGroupRequest(db),
|
relation.NewGroupRequest(db),
|
||||||
unrelation.NewSuperGroupMongoDriver(database),
|
unrelation.NewSuperGroupMongoDriver(database),
|
||||||
hashCode,
|
|
||||||
rcOptions,
|
rcOptions,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -316,7 +315,7 @@ func (g *groupDatabase) FindGroupMember(
|
|||||||
userIDs []string,
|
userIDs []string,
|
||||||
roleLevels []int32,
|
roleLevels []int32,
|
||||||
) (totalGroupMembers []*relationTb.GroupMemberModel, err error) {
|
) (totalGroupMembers []*relationTb.GroupMemberModel, err error) {
|
||||||
if len(roleLevels) == 0 {
|
if roleLevels == nil {
|
||||||
for _, groupID := range groupIDs {
|
for _, groupID := range groupIDs {
|
||||||
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -387,24 +386,8 @@ func (g *groupDatabase) HandlerGroupRequest(
|
|||||||
handleResult int32,
|
handleResult int32,
|
||||||
member *relationTb.GroupMemberModel,
|
member *relationTb.GroupMemberModel,
|
||||||
) error {
|
) error {
|
||||||
//cache := g.cache.NewCache()
|
cache := g.cache.NewCache()
|
||||||
//if err := g.tx.Transaction(func(tx any) error {
|
if err := g.tx.Transaction(func(tx any) error {
|
||||||
// if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if member != nil {
|
|
||||||
// if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationTb.GroupMemberModel{member}); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID)
|
|
||||||
// }
|
|
||||||
// return nil
|
|
||||||
//}); err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//return cache.ExecDel(ctx)
|
|
||||||
|
|
||||||
return g.tx.Transaction(func(tx any) error {
|
|
||||||
if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -412,12 +395,13 @@ func (g *groupDatabase) HandlerGroupRequest(
|
|||||||
if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationTb.GroupMemberModel{member}); err != nil {
|
if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationTb.GroupMemberModel{member}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil {
|
cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cache.ExecDel(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ type CommonMsgDatabase interface {
|
|||||||
pageNumber int32,
|
pageNumber int32,
|
||||||
showNumber int32,
|
showNumber int32,
|
||||||
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error)
|
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error)
|
||||||
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel cache.MsgModel) CommonMsgDatabase {
|
func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel cache.MsgModel) CommonMsgDatabase {
|
||||||
@@ -731,21 +730,34 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio
|
|||||||
delStruct.delDocIDs = append(delStruct.delDocIDs, msgDocModel.DocID)
|
delStruct.delDocIDs = append(delStruct.delDocIDs, msgDocModel.DocID)
|
||||||
delStruct.minSeq = msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.Seq
|
delStruct.minSeq = msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.Seq
|
||||||
} else {
|
} else {
|
||||||
|
var hasMarkDelFlag bool
|
||||||
var delMsgIndexs []int
|
var delMsgIndexs []int
|
||||||
for i, MsgInfoModel := range msgDocModel.Msg {
|
for i, MsgInfoModel := range msgDocModel.Msg {
|
||||||
if MsgInfoModel != nil && MsgInfoModel.Msg != nil {
|
if MsgInfoModel != nil && MsgInfoModel.Msg != nil {
|
||||||
if utils.GetCurrentTimestampByMill() > MsgInfoModel.Msg.SendTime+(remainTime*1000) {
|
if utils.GetCurrentTimestampByMill() > MsgInfoModel.Msg.SendTime+(remainTime*1000) {
|
||||||
delMsgIndexs = append(delMsgIndexs, i)
|
delMsgIndexs = append(delMsgIndexs, i)
|
||||||
|
hasMarkDelFlag = true
|
||||||
|
} else {
|
||||||
|
// 到本条消息不需要删除, minSeq置为这条消息的seq
|
||||||
|
if len(delStruct.delDocIDs) > 0 {
|
||||||
|
log.ZDebug(ctx, "delete docs", "delDocIDs", delStruct.delDocIDs)
|
||||||
|
}
|
||||||
|
if err := db.msgDocDatabase.DeleteDocs(ctx, delStruct.delDocIDs); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if hasMarkDelFlag {
|
||||||
|
log.ZDebug(ctx, "delete msg by index", "delMsgIndexs", delMsgIndexs, "docID", msgDocModel.DocID)
|
||||||
|
// mark del all delMsgIndexs
|
||||||
|
if err := db.msgDocDatabase.DeleteMsgsInOneDocByIndex(ctx, msgDocModel.DocID, delMsgIndexs); err != nil {
|
||||||
|
return delStruct.getSetMinSeq(), err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MsgInfoModel.Msg.Seq, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(delMsgIndexs) > 0 {
|
|
||||||
if err := db.msgDocDatabase.DeleteMsgsInOneDocByIndex(ctx, msgDocModel.DocID, delMsgIndexs); err != nil {
|
|
||||||
log.ZError(ctx, "deleteMsgRecursion DeleteMsgsInOneDocByIndex failed", err, "conversationID", conversationID, "index", index)
|
|
||||||
}
|
|
||||||
delStruct.minSeq = int64(msgDocModel.Msg[delMsgIndexs[len(delMsgIndexs)-1]].Msg.Seq)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 继续递归 index+1
|
||||||
seq, err := db.deleteMsgRecursion(ctx, conversationID, index+1, delStruct, remainTime)
|
seq, err := db.deleteMsgRecursion(ctx, conversationID, index+1, delStruct, remainTime)
|
||||||
return seq, err
|
return seq, err
|
||||||
}
|
}
|
||||||
@@ -949,14 +961,7 @@ func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.Searc
|
|||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
if msg.IsRead {
|
|
||||||
msg.Msg.IsRead = true
|
|
||||||
}
|
|
||||||
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
|
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
|
||||||
}
|
}
|
||||||
return total, totalMsgs, nil
|
return total, totalMsgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *commonMsgDatabase) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) {
|
|
||||||
db.msgDocDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type S3Database interface {
|
|||||||
AuthSign(ctx context.Context, uploadID string, partNumbers []int) (*s3.AuthSignResult, error)
|
AuthSign(ctx context.Context, uploadID string, partNumbers []int) (*s3.AuthSignResult, error)
|
||||||
InitiateMultipartUpload(ctx context.Context, hash string, size int64, expire time.Duration, maxParts int) (*cont.InitiateUploadResult, error)
|
InitiateMultipartUpload(ctx context.Context, hash string, size int64, expire time.Duration, maxParts int) (*cont.InitiateUploadResult, error)
|
||||||
CompleteMultipartUpload(ctx context.Context, uploadID string, parts []string) (*cont.UploadResult, error)
|
CompleteMultipartUpload(ctx context.Context, uploadID string, parts []string) (*cont.UploadResult, error)
|
||||||
AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error)
|
AccessURL(ctx context.Context, name string, expire time.Duration) (time.Time, string, error)
|
||||||
SetObject(ctx context.Context, info *relation.ObjectModel) error
|
SetObject(ctx context.Context, info *relation.ObjectModel) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,19 +70,14 @@ func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel)
|
|||||||
return s.obj.SetObject(ctx, info)
|
return s.obj.SetObject(ctx, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) {
|
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration) (time.Time, string, error) {
|
||||||
obj, err := s.obj.Take(ctx, name)
|
obj, err := s.obj.Take(ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, "", err
|
return time.Time{}, "", err
|
||||||
}
|
}
|
||||||
if opt == nil {
|
opt := &s3.AccessURLOption{
|
||||||
opt = &s3.AccessURLOption{}
|
ContentType: obj.ContentType,
|
||||||
}
|
Filename: filepath.Base(obj.Name),
|
||||||
if opt.ContentType == "" {
|
|
||||||
opt.ContentType = obj.ContentType
|
|
||||||
}
|
|
||||||
if opt.Filename == "" {
|
|
||||||
opt.Filename = filepath.Base(obj.Name)
|
|
||||||
}
|
}
|
||||||
expireTime := time.Now().Add(expire)
|
expireTime := time.Now().Add(expire)
|
||||||
rawURL, err := s.s3.AccessURL(ctx, obj.Key, expire, opt)
|
rawURL, err := s.s3.AccessURL(ctx, obj.Key, expire, opt)
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/user"
|
|
||||||
|
|
||||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||||
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
@@ -180,13 +179,13 @@ func (u *userDatabase) CountRangeEverydayTotal(ctx context.Context, start time.T
|
|||||||
return u.userDB.CountRangeEverydayTotal(ctx, start, end)
|
return u.userDB.CountRangeEverydayTotal(ctx, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeUsersStatus Subscribe or unsubscribe a user's presence status
|
// SubscribeUsersStatus Subscribe or unsubscribe a user's presence status.
|
||||||
func (u *userDatabase) SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
func (u *userDatabase) SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
||||||
err := u.mongoDB.AddSubscriptionList(ctx, userID, userIDs)
|
err := u.mongoDB.AddSubscriptionList(ctx, userID, userIDs)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsubscribeUsersStatus unsubscribe a user's presence status
|
// UnsubscribeUsersStatus unsubscribe a user's presence status.
|
||||||
func (u *userDatabase) UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
func (u *userDatabase) UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
||||||
err := u.mongoDB.UnsubscriptionList(ctx, userID, userIDs)
|
err := u.mongoDB.UnsubscriptionList(ctx, userID, userIDs)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package localcache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/localcache"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
|
||||||
@@ -71,13 +71,10 @@ func (f *FriendRequestGorm) UpdateByMap(
|
|||||||
|
|
||||||
// 更新记录 (非零值).
|
// 更新记录 (非零值).
|
||||||
func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
||||||
fr2 := *friendRequest
|
|
||||||
fr2.FromUserID = ""
|
|
||||||
fr2.ToUserID = ""
|
|
||||||
return utils.Wrap(
|
return utils.Wrap(
|
||||||
f.db(ctx).
|
f.db(ctx).
|
||||||
Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID).
|
Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID).
|
||||||
Updates(fr2).
|
Updates(friendRequest).
|
||||||
Error,
|
Error,
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,6 +33,5 @@ func NewMetaDB(db *gorm.DB, table any) *MetaDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *MetaDB) db(ctx context.Context) *gorm.DB {
|
func (g *MetaDB) db(ctx context.Context) *gorm.DB {
|
||||||
db := g.DB.WithContext(ctx).Model(g.table)
|
return g.DB.WithContext(ctx).Model(g.table)
|
||||||
return db
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,11 +86,7 @@ func (u *UserGorm) Page(
|
|||||||
|
|
||||||
// 获取所有用户ID.
|
// 获取所有用户ID.
|
||||||
func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
||||||
if pageNumber == 0 || showNumber == 0 {
|
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
|
||||||
return userIDs, errs.Wrap(u.db(ctx).Pluck("user_id", &userIDs).Error)
|
|
||||||
} else {
|
|
||||||
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
|
func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
|
||||||
|
|||||||
@@ -257,9 +257,5 @@ func (c *Controller) IsNotFound(err error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
func (c *Controller) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
if opt.Image != nil {
|
|
||||||
opt.Filename = ""
|
|
||||||
opt.ContentType = ""
|
|
||||||
}
|
|
||||||
return c.impl.AccessURL(ctx, name, expire, opt)
|
return c.impl.AccessURL(ctx, name, expire, opt)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cont // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
|
||||||
@@ -36,19 +36,6 @@ const (
|
|||||||
maxNumSize = 1000
|
maxNumSize = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
imagePng = "png"
|
|
||||||
imageJpg = "jpg"
|
|
||||||
imageJpeg = "jpeg"
|
|
||||||
imageGif = "gif"
|
|
||||||
imageWebp = "webp"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
videoSnapshotImagePng = "png"
|
|
||||||
videoSnapshotImageJpg = "jpg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCos() (s3.Interface, error) {
|
func NewCos() (s3.Interface, error) {
|
||||||
conf := config.Config.Object.Cos
|
conf := config.Config.Object.Cos
|
||||||
u, err := url.Parse(conf.BucketURL)
|
u, err := url.Parse(conf.BucketURL)
|
||||||
@@ -261,44 +248,19 @@ func (c *Cos) ListUploadedParts(ctx context.Context, uploadID string, name strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
var imageMogr string
|
var option *cos.PresignedURLOptions
|
||||||
var option cos.PresignedURLOptions
|
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
if opt.Image != nil {
|
|
||||||
// https://cloud.tencent.com/document/product/436/44880
|
|
||||||
style := make([]string, 0, 2)
|
|
||||||
wh := make([]string, 2)
|
|
||||||
if opt.Image.Width > 0 {
|
|
||||||
wh[0] = strconv.Itoa(opt.Image.Width)
|
|
||||||
}
|
|
||||||
if opt.Image.Height > 0 {
|
|
||||||
wh[1] = strconv.Itoa(opt.Image.Height)
|
|
||||||
}
|
|
||||||
if opt.Image.Width > 0 || opt.Image.Height > 0 {
|
|
||||||
style = append(style, strings.Join(wh, "x"))
|
|
||||||
}
|
|
||||||
switch opt.Image.Format {
|
|
||||||
case
|
|
||||||
imagePng,
|
|
||||||
imageJpg,
|
|
||||||
imageJpeg,
|
|
||||||
imageGif,
|
|
||||||
imageWebp:
|
|
||||||
style = append(style, "format/"+opt.Image.Format)
|
|
||||||
}
|
|
||||||
if len(style) > 0 {
|
|
||||||
imageMogr = "&imageMogr2/thumbnail/" + strings.Join(style, "/") + "/ignore-error/1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if opt.ContentType != "" {
|
if opt.ContentType != "" {
|
||||||
query.Set("response-content-type", opt.ContentType)
|
query.Set("response-content-type", opt.ContentType)
|
||||||
}
|
}
|
||||||
if opt.Filename != "" {
|
if opt.Filename != "" {
|
||||||
query.Set("response-content-disposition", `attachment; filename=`+strconv.Quote(opt.Filename))
|
query.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`)
|
||||||
}
|
}
|
||||||
if len(query) > 0 {
|
if len(query) > 0 {
|
||||||
option.Query = &query
|
option = &cos.PresignedURLOptions{
|
||||||
|
Query: &query,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if expire <= 0 {
|
if expire <= 0 {
|
||||||
@@ -306,13 +268,9 @@ func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration,
|
|||||||
} else if expire < time.Second {
|
} else if expire < time.Second {
|
||||||
expire = time.Second
|
expire = time.Second
|
||||||
}
|
}
|
||||||
rawURL, err := c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, &option)
|
rawURL, err := c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
urlStr := rawURL.String()
|
return rawURL.String(), nil
|
||||||
if imageMogr != "" {
|
|
||||||
urlStr += imageMogr
|
|
||||||
}
|
|
||||||
return urlStr, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cos // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package s3 // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package minio // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio"
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package minio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
_ "image/gif"
|
|
||||||
_ "image/jpeg"
|
|
||||||
_ "image/png"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
_ "golang.org/x/image/bmp"
|
|
||||||
_ "golang.org/x/image/tiff"
|
|
||||||
_ "golang.org/x/image/webp"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
formatPng = "png"
|
|
||||||
formatJpeg = "jpeg"
|
|
||||||
formatJpg = "jpg"
|
|
||||||
formatGif = "gif"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ImageStat(reader io.Reader) (image.Image, string, error) {
|
|
||||||
return image.Decode(reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ImageWidthHeight(img image.Image) (int, int) {
|
|
||||||
bounds := img.Bounds().Max
|
|
||||||
return bounds.X, bounds.Y
|
|
||||||
}
|
|
||||||
|
|
||||||
func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
|
||||||
bounds := img.Bounds()
|
|
||||||
imgWidth := bounds.Max.X
|
|
||||||
imgHeight := bounds.Max.Y
|
|
||||||
|
|
||||||
// 计算缩放比例
|
|
||||||
scaleWidth := float64(maxWidth) / float64(imgWidth)
|
|
||||||
scaleHeight := float64(maxHeight) / float64(imgHeight)
|
|
||||||
|
|
||||||
// 如果都为0,则不缩放,返回原始图片
|
|
||||||
if maxWidth == 0 && maxHeight == 0 {
|
|
||||||
return img
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果宽度和高度都大于0,则选择较小的缩放比例,以保持宽高比
|
|
||||||
if maxWidth > 0 && maxHeight > 0 {
|
|
||||||
scale := scaleWidth
|
|
||||||
if scaleHeight < scaleWidth {
|
|
||||||
scale = scaleHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算缩略图尺寸
|
|
||||||
thumbnailWidth := int(float64(imgWidth) * scale)
|
|
||||||
thumbnailHeight := int(float64(imgHeight) * scale)
|
|
||||||
|
|
||||||
// 使用"image"库的Resample方法生成缩略图
|
|
||||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
|
||||||
for y := 0; y < thumbnailHeight; y++ {
|
|
||||||
for x := 0; x < thumbnailWidth; x++ {
|
|
||||||
srcX := int(float64(x) / scale)
|
|
||||||
srcY := int(float64(y) / scale)
|
|
||||||
thumbnail.Set(x, y, img.At(srcX, srcY))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return thumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果只指定了宽度或高度,则根据最大不超过的规则生成缩略图
|
|
||||||
if maxWidth > 0 {
|
|
||||||
thumbnailWidth := maxWidth
|
|
||||||
thumbnailHeight := int(float64(imgHeight) * scaleWidth)
|
|
||||||
|
|
||||||
// 使用"image"库的Resample方法生成缩略图
|
|
||||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
|
||||||
for y := 0; y < thumbnailHeight; y++ {
|
|
||||||
for x := 0; x < thumbnailWidth; x++ {
|
|
||||||
srcX := int(float64(x) / scaleWidth)
|
|
||||||
srcY := int(float64(y) / scaleWidth)
|
|
||||||
thumbnail.Set(x, y, img.At(srcX, srcY))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return thumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
if maxHeight > 0 {
|
|
||||||
thumbnailWidth := int(float64(imgWidth) * scaleHeight)
|
|
||||||
thumbnailHeight := maxHeight
|
|
||||||
|
|
||||||
// 使用"image"库的Resample方法生成缩略图
|
|
||||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
|
||||||
for y := 0; y < thumbnailHeight; y++ {
|
|
||||||
for x := 0; x < thumbnailWidth; x++ {
|
|
||||||
srcX := int(float64(x) / scaleHeight)
|
|
||||||
srcY := int(float64(y) / scaleHeight)
|
|
||||||
thumbnail.Set(x, y, img.At(srcX, srcY))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return thumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认情况下,返回原始图片
|
|
||||||
return img
|
|
||||||
}
|
|
||||||
+12
-195
@@ -15,28 +15,16 @@
|
|||||||
package minio
|
package minio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"image/gif"
|
|
||||||
"image/jpeg"
|
|
||||||
"image/png"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||||
"github.com/minio/minio-go/v7/pkg/signer"
|
"github.com/minio/minio-go/v7/pkg/signer"
|
||||||
@@ -55,13 +43,6 @@ const (
|
|||||||
maxNumSize = 10000
|
maxNumSize = 10000
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
maxImageWidth = 1024
|
|
||||||
maxImageHeight = 1024
|
|
||||||
maxImageSize = 1024 * 1024 * 50
|
|
||||||
pathInfo = "openim/thumbnail"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewMinio() (s3.Interface, error) {
|
func NewMinio() (s3.Interface, error) {
|
||||||
conf := config.Config.Object.Minio
|
conf := config.Config.Object.Minio
|
||||||
u, err := url.Parse(conf.Endpoint)
|
u, err := url.Parse(conf.Endpoint)
|
||||||
@@ -79,26 +60,11 @@ func NewMinio() (s3.Interface, error) {
|
|||||||
m := &Minio{
|
m := &Minio{
|
||||||
bucket: conf.Bucket,
|
bucket: conf.Bucket,
|
||||||
bucketURL: conf.Endpoint + "/" + conf.Bucket + "/",
|
bucketURL: conf.Endpoint + "/" + conf.Bucket + "/",
|
||||||
|
opts: opts,
|
||||||
core: &minio.Core{Client: client},
|
core: &minio.Core{Client: client},
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
init: false,
|
init: false,
|
||||||
}
|
}
|
||||||
if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint {
|
|
||||||
m.sign = m.core.Client
|
|
||||||
} else {
|
|
||||||
su, err := url.Parse(conf.SignEndpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
m.opts = &minio.Options{
|
|
||||||
Creds: credentials.NewStaticV4(conf.AccessKeyID, conf.SecretAccessKey, conf.SessionToken),
|
|
||||||
Secure: su.Scheme == "https",
|
|
||||||
}
|
|
||||||
m.sign, err = minio.New(su.Host, m.opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := m.initMinio(ctx); err != nil {
|
if err := m.initMinio(ctx); err != nil {
|
||||||
@@ -110,10 +76,8 @@ func NewMinio() (s3.Interface, error) {
|
|||||||
type Minio struct {
|
type Minio struct {
|
||||||
bucket string
|
bucket string
|
||||||
bucketURL string
|
bucketURL string
|
||||||
location string
|
|
||||||
opts *minio.Options
|
opts *minio.Options
|
||||||
core *minio.Core
|
core *minio.Core
|
||||||
sign *minio.Client
|
|
||||||
lock sync.Locker
|
lock sync.Locker
|
||||||
init bool
|
init bool
|
||||||
}
|
}
|
||||||
@@ -127,43 +91,15 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
|||||||
if m.init {
|
if m.init {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
conf := config.Config.Object.Minio
|
exists, err := m.core.Client.BucketExists(ctx, config.Config.Object.Minio.Bucket)
|
||||||
exists, err := m.core.Client.BucketExists(ctx, conf.Bucket)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check bucket exists error: %w", err)
|
return fmt.Errorf("check bucket exists error: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
if err := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
if err := m.core.Client.MakeBucket(ctx, config.Config.Object.Minio.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||||
return fmt.Errorf("make bucket error: %w", err)
|
return fmt.Errorf("make bucket error: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.location, err = m.core.Client.GetBucketLocation(ctx, conf.Bucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
func() {
|
|
||||||
if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
m.sign = m.core.Client
|
|
||||||
log.ZWarn(
|
|
||||||
context.Background(),
|
|
||||||
"set sign bucket location cache panic",
|
|
||||||
errors.New("failed to get private field value"),
|
|
||||||
"recover",
|
|
||||||
fmt.Sprintf("%+v", r),
|
|
||||||
"development version",
|
|
||||||
"github.com/minio/minio-go/v7 v7.0.61",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
blc := reflect.ValueOf(m.sign).Elem().FieldByName("bucketLocCache")
|
|
||||||
vblc := reflect.New(reflect.PtrTo(blc.Type()))
|
|
||||||
*(*unsafe.Pointer)(vblc.UnsafePointer()) = unsafe.Pointer(blc.UnsafeAddr())
|
|
||||||
vblc.Elem().Elem().Interface().(interface{ Set(string, string) }).Set(conf.Bucket, m.location)
|
|
||||||
}()
|
|
||||||
m.init = true
|
m.init = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -255,7 +191,7 @@ func (m *Minio) AuthSign(ctx context.Context, uploadID string, name string, expi
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.Header.Set("X-Amz-Content-Sha256", unsignedPayload)
|
request.Header.Set("X-Amz-Content-Sha256", unsignedPayload)
|
||||||
request = signer.SignV4Trailer(*request, creds.AccessKeyID, creds.SecretAccessKey, creds.SessionToken, m.location, nil)
|
request = signer.SignV4Trailer(*request, creds.AccessKeyID, creds.SecretAccessKey, creds.SessionToken, "us-east-1", nil)
|
||||||
result.Parts[i] = s3.SignPart{
|
result.Parts[i] = s3.SignPart{
|
||||||
PartNumber: partNumber,
|
PartNumber: partNumber,
|
||||||
URL: request.URL.String(),
|
URL: request.URL.String(),
|
||||||
@@ -270,7 +206,7 @@ func (m *Minio) PresignedPutObject(ctx context.Context, name string, expire time
|
|||||||
if err := m.initMinio(ctx); err != nil {
|
if err := m.initMinio(ctx); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
rawURL, err := m.sign.PresignedPutObject(ctx, m.bucket, name, expire)
|
rawURL, err := m.core.Client.PresignedPutObject(ctx, m.bucket, name, expire)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -367,19 +303,6 @@ func (m *Minio) ListUploadedParts(ctx context.Context, uploadID string, name str
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Minio) presignedGetObject(ctx context.Context, name string, expire time.Duration, query url.Values) (string, error) {
|
|
||||||
if expire <= 0 {
|
|
||||||
expire = time.Hour * 24 * 365 * 99 // 99 years
|
|
||||||
} else if expire < time.Second {
|
|
||||||
expire = time.Second
|
|
||||||
}
|
|
||||||
rawURL, err := m.sign.PresignedGetObject(ctx, m.bucket, name, expire, query)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return rawURL.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
if err := m.initMinio(ctx); err != nil {
|
if err := m.initMinio(ctx); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -390,123 +313,17 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
|||||||
reqParams.Set("response-content-type", opt.ContentType)
|
reqParams.Set("response-content-type", opt.ContentType)
|
||||||
}
|
}
|
||||||
if opt.Filename != "" {
|
if opt.Filename != "" {
|
||||||
reqParams.Set("response-content-disposition", `attachment; filename=`+strconv.Quote(opt.Filename))
|
reqParams.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if opt.Image == nil || (opt.Image.Width < 0 && opt.Image.Height < 0 && opt.Image.Format == "") || (opt.Image.Width > maxImageWidth || opt.Image.Height > maxImageHeight) {
|
if expire <= 0 {
|
||||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
expire = time.Hour * 24 * 365 * 99 // 99 years
|
||||||
|
} else if expire < time.Second {
|
||||||
|
expire = time.Second
|
||||||
}
|
}
|
||||||
fileInfo, err := m.StatObject(ctx, name)
|
u, err := m.core.Client.PresignedGetObject(ctx, m.bucket, name, expire, reqParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if fileInfo.Size > maxImageSize {
|
return u.String(), nil
|
||||||
return "", errors.New("file size too large")
|
|
||||||
}
|
|
||||||
objectInfoPath := path.Join(pathInfo, fileInfo.ETag, "image.json")
|
|
||||||
var (
|
|
||||||
img image.Image
|
|
||||||
info minioImageInfo
|
|
||||||
)
|
|
||||||
data, err := m.getObjectData(ctx, objectInfoPath, 1024)
|
|
||||||
if err == nil {
|
|
||||||
if err := json.Unmarshal(data, &info); err != nil {
|
|
||||||
return "", fmt.Errorf("unmarshal minio image info.json error: %w", err)
|
|
||||||
}
|
|
||||||
if info.NotImage {
|
|
||||||
return "", errors.New("not image")
|
|
||||||
}
|
|
||||||
} else if m.IsNotFound(err) {
|
|
||||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer reader.Close()
|
|
||||||
imageInfo, format, err := ImageStat(reader)
|
|
||||||
if err == nil {
|
|
||||||
info.NotImage = false
|
|
||||||
info.Format = format
|
|
||||||
info.Width, info.Height = ImageWidthHeight(imageInfo)
|
|
||||||
img = imageInfo
|
|
||||||
} else {
|
|
||||||
info.NotImage = true
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(&info)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, objectInfoPath, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{}); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if opt.Image.Width > info.Width || opt.Image.Width <= 0 {
|
|
||||||
opt.Image.Width = info.Width
|
|
||||||
}
|
|
||||||
if opt.Image.Height > info.Height || opt.Image.Height <= 0 {
|
|
||||||
opt.Image.Height = info.Height
|
|
||||||
}
|
|
||||||
opt.Image.Format = strings.ToLower(opt.Image.Format)
|
|
||||||
if opt.Image.Format == formatJpg {
|
|
||||||
opt.Image.Format = formatJpeg
|
|
||||||
}
|
|
||||||
switch opt.Image.Format {
|
|
||||||
case formatPng:
|
|
||||||
case formatJpeg:
|
|
||||||
case formatGif:
|
|
||||||
default:
|
|
||||||
if info.Format == formatGif {
|
|
||||||
opt.Image.Format = formatGif
|
|
||||||
} else {
|
|
||||||
opt.Image.Format = formatJpeg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reqParams.Set("response-content-type", "image/"+opt.Image.Format)
|
|
||||||
if opt.Image.Width == info.Width && opt.Image.Height == info.Height && opt.Image.Format == info.Format {
|
|
||||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
|
||||||
}
|
|
||||||
cacheKey := filepath.Join(pathInfo, fileInfo.ETag, fmt.Sprintf("image_w%d_h%d.%s", opt.Image.Width, opt.Image.Height, opt.Image.Format))
|
|
||||||
if _, err := m.core.Client.StatObject(ctx, m.bucket, cacheKey, minio.StatObjectOptions{}); err == nil {
|
|
||||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
|
||||||
} else if !m.IsNotFound(err) {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if img == nil {
|
|
||||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer reader.Close()
|
|
||||||
img, _, err = ImageStat(reader)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thumbnail := resizeImage(img, opt.Image.Width, opt.Image.Height)
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
switch opt.Image.Format {
|
|
||||||
case formatPng:
|
|
||||||
err = png.Encode(buf, thumbnail)
|
|
||||||
case formatJpeg:
|
|
||||||
err = jpeg.Encode(buf, thumbnail, nil)
|
|
||||||
case formatGif:
|
|
||||||
err = gif.Encode(buf, thumbnail, nil)
|
|
||||||
}
|
|
||||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, cacheKey, buf, int64(buf.Len()), minio.PutObjectOptions{}); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Minio) getObjectData(ctx context.Context, name string, limit int64) ([]byte, error) {
|
|
||||||
object, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer object.Close()
|
|
||||||
if limit < 0 {
|
|
||||||
return io.ReadAll(object)
|
|
||||||
}
|
|
||||||
return io.ReadAll(io.LimitReader(object, 1024))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package minio
|
|
||||||
|
|
||||||
type minioImageInfo struct {
|
|
||||||
NotImage bool `json:"notImage,omitempty"`
|
|
||||||
Width int `json:"width,omitempty"`
|
|
||||||
Height int `json:"height,omitempty"`
|
|
||||||
Format string `json:"format,omitempty"`
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package oss // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss"
|
||||||
@@ -36,19 +36,6 @@ const (
|
|||||||
maxNumSize = 10000
|
maxNumSize = 10000
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
imagePng = "png"
|
|
||||||
imageJpg = "jpg"
|
|
||||||
imageJpeg = "jpeg"
|
|
||||||
imageGif = "gif"
|
|
||||||
imageWebp = "webp"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
videoSnapshotImagePng = "png"
|
|
||||||
videoSnapshotImageJpg = "jpg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewOSS() (s3.Interface, error) {
|
func NewOSS() (s3.Interface, error) {
|
||||||
conf := config.Config.Object.Oss
|
conf := config.Config.Object.Oss
|
||||||
if conf.BucketURL == "" {
|
if conf.BucketURL == "" {
|
||||||
@@ -152,7 +139,7 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
|||||||
}
|
}
|
||||||
for i, partNumber := range partNumbers {
|
for i, partNumber := range partNumbers {
|
||||||
rawURL := fmt.Sprintf(`%s%s?partNumber=%d&uploadId=%s`, o.bucketURL, name, partNumber, uploadID)
|
rawURL := fmt.Sprintf(`%s%s?partNumber=%d&uploadId=%s`, o.bucketURL, name, partNumber, uploadID)
|
||||||
request, err := http.NewRequest(http.MethodPut, rawURL, nil)
|
request, err := http.NewRequestWithContext(ctx, http.MethodPut, rawURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -163,7 +150,12 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
|||||||
request.Header.Set(oss.HTTPHeaderHost, request.Host)
|
request.Header.Set(oss.HTTPHeaderHost, request.Host)
|
||||||
request.Header.Set(oss.HTTPHeaderDate, now)
|
request.Header.Set(oss.HTTPHeaderDate, now)
|
||||||
request.Header.Set(oss.HttpHeaderOssDate, now)
|
request.Header.Set(oss.HttpHeaderOssDate, now)
|
||||||
ossSignHeader(o.bucket.Client.Conn, request, fmt.Sprintf(`/%s/%s?partNumber=%d&uploadId=%s`, o.bucket.BucketName, name, partNumber, uploadID))
|
authorization := fmt.Sprintf(
|
||||||
|
`OSS %s:%s`,
|
||||||
|
o.credentials.GetAccessKeyID(),
|
||||||
|
o.getSignedStr(request, fmt.Sprintf(`/%s/%s?partNumber=%d&uploadId=%s`, o.bucket.BucketName, name, partNumber, uploadID), o.credentials.GetAccessKeySecret()),
|
||||||
|
)
|
||||||
|
request.Header.Set(oss.HTTPHeaderAuthorization, authorization)
|
||||||
delete(request.Header, oss.HTTPHeaderDate)
|
delete(request.Header, oss.HTTPHeaderDate)
|
||||||
result.Parts[i] = s3.SignPart{
|
result.Parts[i] = s3.SignPart{
|
||||||
PartNumber: partNumber,
|
PartNumber: partNumber,
|
||||||
@@ -274,36 +266,11 @@ func (o *OSS) ListUploadedParts(ctx context.Context, uploadID string, name strin
|
|||||||
func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
var opts []oss.Option
|
var opts []oss.Option
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
if opt.Image != nil {
|
|
||||||
// 文档地址: https://help.aliyun.com/zh/oss/user-guide/resize-images-4?spm=a2c4g.11186623.0.0.4b3b1e4fWW6yji
|
|
||||||
var format string
|
|
||||||
switch opt.Image.Format {
|
|
||||||
case
|
|
||||||
imagePng,
|
|
||||||
imageJpg,
|
|
||||||
imageJpeg,
|
|
||||||
imageGif,
|
|
||||||
imageWebp:
|
|
||||||
format = opt.Image.Format
|
|
||||||
default:
|
|
||||||
opt.Image.Format = imageJpg
|
|
||||||
}
|
|
||||||
// https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,h_100,m_lfit
|
|
||||||
process := "image/resize,m_lfit"
|
|
||||||
if opt.Image.Width > 0 {
|
|
||||||
process += ",w_" + strconv.Itoa(opt.Image.Width)
|
|
||||||
}
|
|
||||||
if opt.Image.Height > 0 {
|
|
||||||
process += ",h_" + strconv.Itoa(opt.Image.Height)
|
|
||||||
}
|
|
||||||
process += ",format," + format
|
|
||||||
opts = append(opts, oss.Process(process))
|
|
||||||
}
|
|
||||||
if opt.ContentType != "" {
|
if opt.ContentType != "" {
|
||||||
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
||||||
}
|
}
|
||||||
if opt.Filename != "" {
|
if opt.Filename != "" {
|
||||||
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename=`+strconv.Quote(opt.Filename)))
|
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename="`+opt.Filename+`"`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if expire <= 0 {
|
if expire <= 0 {
|
||||||
|
|||||||
@@ -1,11 +1,96 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package oss
|
package oss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "unsafe"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname ossSignHeader github.com/aliyun/aliyun-oss-go-sdk/oss.(*Conn).signHeader
|
func (o *OSS) getAdditionalHeaderKeys(req *http.Request) ([]string, map[string]string) {
|
||||||
func ossSignHeader(c *oss.Conn, req *http.Request, canonicalizedResource string)
|
var keysList []string
|
||||||
|
keysMap := make(map[string]string)
|
||||||
|
srcKeys := make(map[string]string)
|
||||||
|
|
||||||
|
for k := range req.Header {
|
||||||
|
srcKeys[strings.ToLower(k)] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range o.bucket.Client.Config.AdditionalHeaders {
|
||||||
|
if _, ok := srcKeys[strings.ToLower(v)]; ok {
|
||||||
|
keysMap[strings.ToLower(v)] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := range keysMap {
|
||||||
|
keysList = append(keysList, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keysList)
|
||||||
|
return keysList, keysMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OSS) getSignedStr(req *http.Request, canonicalizedResource string, keySecret string) string {
|
||||||
|
// Find out the "x-oss-"'s address in header of the request
|
||||||
|
ossHeadersMap := make(map[string]string)
|
||||||
|
additionalList, additionalMap := o.getAdditionalHeaderKeys(req)
|
||||||
|
for k, v := range req.Header {
|
||||||
|
if strings.HasPrefix(strings.ToLower(k), "x-oss-") {
|
||||||
|
ossHeadersMap[strings.ToLower(k)] = v[0]
|
||||||
|
} else if o.bucket.Client.Config.AuthVersion == oss.AuthV2 {
|
||||||
|
if _, ok := additionalMap[strings.ToLower(k)]; ok {
|
||||||
|
ossHeadersMap[strings.ToLower(k)] = v[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hs := newHeaderSorter(ossHeadersMap)
|
||||||
|
|
||||||
|
// Sort the ossHeadersMap by the ascending order
|
||||||
|
hs.Sort()
|
||||||
|
|
||||||
|
// Get the canonicalizedOSSHeaders
|
||||||
|
canonicalizedOSSHeaders := ""
|
||||||
|
for i := range hs.Keys {
|
||||||
|
canonicalizedOSSHeaders += hs.Keys[i] + ":" + hs.Vals[i] + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give other parameters values
|
||||||
|
// when sign URL, date is expires
|
||||||
|
date := req.Header.Get(oss.HTTPHeaderDate)
|
||||||
|
contentType := req.Header.Get(oss.HTTPHeaderContentType)
|
||||||
|
contentMd5 := req.Header.Get(oss.HTTPHeaderContentMD5)
|
||||||
|
|
||||||
|
// default is v1 signature
|
||||||
|
signStr := req.Method + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + canonicalizedResource
|
||||||
|
h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(keySecret))
|
||||||
|
|
||||||
|
// v2 signature
|
||||||
|
if o.bucket.Client.Config.AuthVersion == oss.AuthV2 {
|
||||||
|
signStr = req.Method + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + strings.Join(additionalList, ";") + "\n" + canonicalizedResource
|
||||||
|
h = hmac.New(func() hash.Hash { return sha256.New() }, []byte(keySecret))
|
||||||
|
}
|
||||||
|
_, _ = io.WriteString(h, signStr)
|
||||||
|
signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
|
return signedStr
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package oss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// headerSorter defines the key-value structure for storing the sorted data in signHeader.
|
||||||
|
type headerSorter struct {
|
||||||
|
Keys []string
|
||||||
|
Vals []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newHeaderSorter is an additional function for function SignHeader.
|
||||||
|
func newHeaderSorter(m map[string]string) *headerSorter {
|
||||||
|
hs := &headerSorter{
|
||||||
|
Keys: make([]string, 0, len(m)),
|
||||||
|
Vals: make([]string, 0, len(m)),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range m {
|
||||||
|
hs.Keys = append(hs.Keys, k)
|
||||||
|
hs.Vals = append(hs.Vals, v)
|
||||||
|
}
|
||||||
|
return hs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort is an additional function for function SignHeader.
|
||||||
|
func (hs *headerSorter) Sort() {
|
||||||
|
sort.Sort(hs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len is an additional function for function SignHeader.
|
||||||
|
func (hs *headerSorter) Len() int {
|
||||||
|
return len(hs.Vals)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less is an additional function for function SignHeader.
|
||||||
|
func (hs *headerSorter) Less(i, j int) bool {
|
||||||
|
return bytes.Compare([]byte(hs.Keys[i]), []byte(hs.Keys[j])) < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap is an additional function for function SignHeader.
|
||||||
|
func (hs *headerSorter) Swap(i, j int) {
|
||||||
|
hs.Vals[i], hs.Vals[j] = hs.Vals[j], hs.Vals[i]
|
||||||
|
hs.Keys[i], hs.Keys[j] = hs.Keys[j], hs.Keys[i]
|
||||||
|
}
|
||||||
@@ -116,16 +116,9 @@ type ListUploadedPartsResult struct {
|
|||||||
UploadedParts []UploadedPart `xml:"Part"`
|
UploadedParts []UploadedPart `xml:"Part"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Image struct {
|
|
||||||
Format string `json:"format"`
|
|
||||||
Width int `json:"width"`
|
|
||||||
Height int `json:"height"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccessURLOption struct {
|
type AccessURLOption struct {
|
||||||
ContentType string `json:"contentType"`
|
ContentType string `json:"contentType"`
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
Image *Image `json:"image"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||||
@@ -27,11 +27,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
singleGocMsgNum = 100
|
singleGocMsgNum = 5000
|
||||||
singleGocMsgNum5000 = 5000
|
Msg = "msg"
|
||||||
Msg = "msg"
|
OldestList = 0
|
||||||
OldestList = 0
|
NewestList = -1
|
||||||
NewestList = -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgDocModel struct {
|
type MsgDocModel struct {
|
||||||
@@ -129,7 +128,6 @@ type MsgDocModelInterface interface {
|
|||||||
pageNumber int32,
|
pageNumber int32,
|
||||||
showNumber int32,
|
showNumber int32,
|
||||||
) (msgCount int64, userCount int64, groups []*GroupCount, dateCount map[string]int64, err error)
|
) (msgCount int64, userCount int64, groups []*GroupCount, dateCount map[string]int64, err error)
|
||||||
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MsgDocModel) TableName() string {
|
func (MsgDocModel) TableName() string {
|
||||||
@@ -140,10 +138,6 @@ func (MsgDocModel) GetSingleGocMsgNum() int64 {
|
|||||||
return singleGocMsgNum
|
return singleGocMsgNum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MsgDocModel) GetSingleGocMsgNum5000() int64 {
|
|
||||||
return singleGocMsgNum5000
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgDocModel) IsFull() bool {
|
func (m *MsgDocModel) IsFull() bool {
|
||||||
return m.Msg[len(m.Msg)-1].Msg != nil
|
return m.Msg[len(m.Msg)-1].Msg != nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||||
@@ -1073,6 +1073,11 @@ func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessa
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
for _, msg1 := range msgs {
|
||||||
|
if msg1.IsRead {
|
||||||
|
msg1.Msg.IsRead = true
|
||||||
|
}
|
||||||
|
}
|
||||||
return total, msgs, nil
|
return total, msgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,22 +1151,13 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
|||||||
{"doc_id", 1},
|
{"doc_id", 1},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
{"$unwind", bson.M{"path": "$msgs"}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{"$sort", bson.M{"msgs.msg.send_time": -1}},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
cursor, err := m.MsgCollection.Aggregate(ctx, pipe)
|
cursor, err := m.MsgCollection.Aggregate(ctx, pipe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
type docModel struct {
|
|
||||||
DocID string `bson:"doc_id"`
|
var msgsDocs []table.MsgDocModel
|
||||||
Msg *table.MsgInfoModel `bson:"msgs"`
|
|
||||||
}
|
|
||||||
var msgsDocs []docModel
|
|
||||||
err = cursor.All(ctx, &msgsDocs)
|
err = cursor.All(ctx, &msgsDocs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
@@ -1171,39 +1167,41 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
|||||||
}
|
}
|
||||||
msgs := make([]*table.MsgInfoModel, 0)
|
msgs := make([]*table.MsgInfoModel, 0)
|
||||||
for index := range msgsDocs {
|
for index := range msgsDocs {
|
||||||
msgInfo := msgsDocs[index].Msg
|
for i := range msgsDocs[index].Msg {
|
||||||
if msgInfo == nil || msgInfo.Msg == nil {
|
msg := msgsDocs[index].Msg[i]
|
||||||
continue
|
if msg == nil || msg.Msg == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if msg.Revoke != nil {
|
||||||
|
revokeContent := sdkws.MessageRevokedContent{
|
||||||
|
RevokerID: msg.Revoke.UserID,
|
||||||
|
RevokerRole: msg.Revoke.Role,
|
||||||
|
ClientMsgID: msg.Msg.ClientMsgID,
|
||||||
|
RevokerNickname: msg.Revoke.Nickname,
|
||||||
|
RevokeTime: msg.Revoke.Time,
|
||||||
|
SourceMessageSendTime: msg.Msg.SendTime,
|
||||||
|
SourceMessageSendID: msg.Msg.SendID,
|
||||||
|
SourceMessageSenderNickname: msg.Msg.SenderNickname,
|
||||||
|
SessionType: msg.Msg.SessionType,
|
||||||
|
Seq: msg.Msg.Seq,
|
||||||
|
Ex: msg.Msg.Ex,
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(&revokeContent)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
elem := sdkws.NotificationElem{
|
||||||
|
Detail: string(data),
|
||||||
|
}
|
||||||
|
content, err := json.Marshal(&elem)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
msg.Msg.ContentType = constant.MsgRevokeNotification
|
||||||
|
msg.Msg.Content = string(content)
|
||||||
|
}
|
||||||
|
msgs = append(msgs, msg)
|
||||||
}
|
}
|
||||||
if msgInfo.Revoke != nil {
|
|
||||||
revokeContent := sdkws.MessageRevokedContent{
|
|
||||||
RevokerID: msgInfo.Revoke.UserID,
|
|
||||||
RevokerRole: msgInfo.Revoke.Role,
|
|
||||||
ClientMsgID: msgInfo.Msg.ClientMsgID,
|
|
||||||
RevokerNickname: msgInfo.Revoke.Nickname,
|
|
||||||
RevokeTime: msgInfo.Revoke.Time,
|
|
||||||
SourceMessageSendTime: msgInfo.Msg.SendTime,
|
|
||||||
SourceMessageSendID: msgInfo.Msg.SendID,
|
|
||||||
SourceMessageSenderNickname: msgInfo.Msg.SenderNickname,
|
|
||||||
SessionType: msgInfo.Msg.SessionType,
|
|
||||||
Seq: msgInfo.Msg.Seq,
|
|
||||||
Ex: msgInfo.Msg.Ex,
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(&revokeContent)
|
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
elem := sdkws.NotificationElem{
|
|
||||||
Detail: string(data),
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(&elem)
|
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
msgInfo.Msg.ContentType = constant.MsgRevokeNotification
|
|
||||||
msgInfo.Msg.Content = string(content)
|
|
||||||
}
|
|
||||||
msgs = append(msgs, msgInfo)
|
|
||||||
}
|
}
|
||||||
start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
|
start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
|
||||||
n := int32(len(msgs))
|
n := int32(len(msgs))
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
package unrelation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
|
|
||||||
table "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MsgMongoDriver) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) {
|
|
||||||
for _, conversationID := range conversationIDs {
|
|
||||||
regex := primitive.Regex{Pattern: fmt.Sprintf("^%s:", conversationID)}
|
|
||||||
cursor, err := m.MsgCollection.Find(ctx, bson.M{"doc_id": regex})
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "convertAll find msg doc failed", err, "conversationID", conversationID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var msgDocs []table.MsgDocModel
|
|
||||||
err = cursor.All(ctx, &msgDocs)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "convertAll cursor all failed", err, "conversationID", conversationID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(msgDocs) < 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.ZInfo(ctx, "msg doc convert", "conversationID", conversationID, "len(msgDocs)", len(msgDocs))
|
|
||||||
if len(msgDocs[0].Msg) == int(m.model.GetSingleGocMsgNum5000()) {
|
|
||||||
if _, err := m.MsgCollection.DeleteMany(ctx, bson.M{"doc_id": regex}); err != nil {
|
|
||||||
log.ZError(ctx, "convertAll delete many failed", err, "conversationID", conversationID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var newMsgDocs []interface{}
|
|
||||||
for _, msgDoc := range msgDocs {
|
|
||||||
if int64(len(msgDoc.Msg)) == m.model.GetSingleGocMsgNum() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var index int64
|
|
||||||
for index < int64(len(msgDoc.Msg)) {
|
|
||||||
msg := msgDoc.Msg[index]
|
|
||||||
if msg != nil && msg.Msg != nil {
|
|
||||||
msgDocModel := table.MsgDocModel{DocID: m.model.GetDocID(conversationID, msg.Msg.Seq)}
|
|
||||||
end := index + m.model.GetSingleGocMsgNum()
|
|
||||||
if int(end) >= len(msgDoc.Msg) {
|
|
||||||
msgDocModel.Msg = msgDoc.Msg[index:]
|
|
||||||
} else {
|
|
||||||
msgDocModel.Msg = msgDoc.Msg[index:end]
|
|
||||||
}
|
|
||||||
newMsgDocs = append(newMsgDocs, msgDocModel)
|
|
||||||
index = end
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = m.MsgCollection.InsertMany(ctx, newMsgDocs)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "convertAll insert many failed", err, "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
|
||||||
} else {
|
|
||||||
log.ZInfo(ctx, "msg doc convert", "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,13 +17,12 @@ package unrelation
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// prefixes and suffixes.
|
// prefixes and suffixes.
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package http // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/http"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package kafka // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package locker // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/locker"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package prome // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package startrpc // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/startrpc"
|
||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetNotificationConversationIDByMsg(msg *sdkws.MsgData) string {
|
func GetNotificationConversationID(msg *sdkws.MsgData) string {
|
||||||
switch msg.SessionType {
|
switch msg.SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
l := []string{msg.SendID, msg.RecvID}
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
@@ -114,30 +114,6 @@ func GetConversationIDBySessionType(sessionType int, ids ...string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNotificationConversationIDByConversationID(conversationID string) string {
|
|
||||||
l := strings.Split(conversationID, "_")
|
|
||||||
if len(l) > 1 {
|
|
||||||
l[0] = "n"
|
|
||||||
return strings.Join(l, "_")
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetNotificationConversationID(sessionType int, ids ...string) string {
|
|
||||||
sort.Strings(ids)
|
|
||||||
if len(ids) > 2 || len(ids) < 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
switch sessionType {
|
|
||||||
case constant.SingleChatType:
|
|
||||||
return "n_" + strings.Join(ids, "_") // single chat
|
|
||||||
case constant.SuperGroupChatType:
|
|
||||||
return "n_" + ids[0] // super group chat
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsNotification(conversationID string) bool {
|
func IsNotification(conversationID string) bool {
|
||||||
return strings.HasPrefix(conversationID, "n_")
|
return strings.HasPrefix(conversationID, "n_")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package msgprocessor // import "github.com/OpenIMSDK/Open-IM-Server/pkg/msgprocessor"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package rpcclient // import "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||||
@@ -56,8 +56,7 @@ func newContentTypeConf() map[int32]config.NotificationConf {
|
|||||||
constant.GroupInfoSetAnnouncementNotification: config.Config.Notification.GroupInfoSetAnnouncement,
|
constant.GroupInfoSetAnnouncementNotification: config.Config.Notification.GroupInfoSetAnnouncement,
|
||||||
constant.GroupInfoSetNameNotification: config.Config.Notification.GroupInfoSetName,
|
constant.GroupInfoSetNameNotification: config.Config.Notification.GroupInfoSetName,
|
||||||
// user
|
// user
|
||||||
constant.UserInfoUpdatedNotification: config.Config.Notification.UserInfoUpdated,
|
constant.UserInfoUpdatedNotification: config.Config.Notification.UserInfoUpdated,
|
||||||
constant.UserStatusChangeNotification: config.Config.Notification.UserStatusChanged,
|
|
||||||
// friend
|
// friend
|
||||||
constant.FriendApplicationNotification: config.Config.Notification.FriendApplicationAdded,
|
constant.FriendApplicationNotification: config.Config.Notification.FriendApplicationAdded,
|
||||||
constant.FriendApplicationApprovedNotification: config.Config.Notification.FriendApplicationApproved,
|
constant.FriendApplicationApprovedNotification: config.Config.Notification.FriendApplicationApproved,
|
||||||
@@ -103,8 +102,7 @@ func newSessionTypeConf() map[int32]int32 {
|
|||||||
constant.GroupInfoSetAnnouncementNotification: constant.SuperGroupChatType,
|
constant.GroupInfoSetAnnouncementNotification: constant.SuperGroupChatType,
|
||||||
constant.GroupInfoSetNameNotification: constant.SuperGroupChatType,
|
constant.GroupInfoSetNameNotification: constant.SuperGroupChatType,
|
||||||
// user
|
// user
|
||||||
constant.UserInfoUpdatedNotification: constant.SingleChatType,
|
constant.UserInfoUpdatedNotification: constant.SingleChatType,
|
||||||
constant.UserStatusChangeNotification: constant.SingleChatType,
|
|
||||||
// friend
|
// friend
|
||||||
constant.FriendApplicationNotification: constant.SingleChatType,
|
constant.FriendApplicationNotification: constant.SingleChatType,
|
||||||
constant.FriendApplicationApprovedNotification: constant.SingleChatType,
|
constant.FriendApplicationApprovedNotification: constant.SingleChatType,
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package notification // import "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||||
@@ -136,7 +136,7 @@ func (f *FriendNotificationSender) FriendApplicationAddNotification(
|
|||||||
return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
|
return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendApplicationAgreedNotification(
|
func (c *FriendNotificationSender) FriendApplicationAgreedNotification(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *pbFriend.RespondFriendApplyReq,
|
req *pbFriend.RespondFriendApplyReq,
|
||||||
) error {
|
) error {
|
||||||
@@ -144,10 +144,10 @@ func (f *FriendNotificationSender) FriendApplicationAgreedNotification(
|
|||||||
FromUserID: req.FromUserID,
|
FromUserID: req.FromUserID,
|
||||||
ToUserID: req.ToUserID,
|
ToUserID: req.ToUserID,
|
||||||
}, HandleMsg: req.HandleMsg}
|
}, HandleMsg: req.HandleMsg}
|
||||||
return f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
|
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendApplicationRefusedNotification(
|
func (c *FriendNotificationSender) FriendApplicationRefusedNotification(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *pbFriend.RespondFriendApplyReq,
|
req *pbFriend.RespondFriendApplyReq,
|
||||||
) error {
|
) error {
|
||||||
@@ -155,15 +155,15 @@ func (f *FriendNotificationSender) FriendApplicationRefusedNotification(
|
|||||||
FromUserID: req.FromUserID,
|
FromUserID: req.FromUserID,
|
||||||
ToUserID: req.ToUserID,
|
ToUserID: req.ToUserID,
|
||||||
}, HandleMsg: req.HandleMsg}
|
}, HandleMsg: req.HandleMsg}
|
||||||
return f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
|
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendAddedNotification(
|
func (c *FriendNotificationSender) FriendAddedNotification(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
operationID, opUserID, fromUserID, toUserID string,
|
operationID, opUserID, fromUserID, toUserID string,
|
||||||
) error {
|
) error {
|
||||||
tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}}
|
tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}}
|
||||||
user, err := f.getUsersInfo(ctx, []string{opUserID})
|
user, err := c.getUsersInfo(ctx, []string{opUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -171,52 +171,52 @@ func (f *FriendNotificationSender) FriendAddedNotification(
|
|||||||
tips.OpUser.Ex = user[0].GetEx()
|
tips.OpUser.Ex = user[0].GetEx()
|
||||||
tips.OpUser.Nickname = user[0].GetNickname()
|
tips.OpUser.Nickname = user[0].GetNickname()
|
||||||
tips.OpUser.FaceURL = user[0].GetFaceURL()
|
tips.OpUser.FaceURL = user[0].GetFaceURL()
|
||||||
friends, err := f.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID})
|
friends, err := c.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], f.getUsersInfoMap)
|
tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], c.getUsersInfoMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return f.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
|
return c.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error {
|
func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error {
|
||||||
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
||||||
FromUserID: req.OwnerUserID,
|
FromUserID: req.OwnerUserID,
|
||||||
ToUserID: req.FriendUserID,
|
ToUserID: req.FriendUserID,
|
||||||
}}
|
}}
|
||||||
return f.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips)
|
return c.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error {
|
func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error {
|
||||||
tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}}
|
tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}}
|
||||||
tips.FromToUserID.FromUserID = fromUserID
|
tips.FromToUserID.FromUserID = fromUserID
|
||||||
tips.FromToUserID.ToUserID = toUserID
|
tips.FromToUserID.ToUserID = toUserID
|
||||||
return f.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
|
return c.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error {
|
func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error {
|
||||||
tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}}
|
tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}}
|
||||||
tips.FromToUserID.FromUserID = req.OwnerUserID
|
tips.FromToUserID.FromUserID = req.OwnerUserID
|
||||||
tips.FromToUserID.ToUserID = req.BlackUserID
|
tips.FromToUserID.ToUserID = req.BlackUserID
|
||||||
return f.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips)
|
return c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) {
|
func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) {
|
||||||
blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
||||||
FromUserID: req.OwnerUserID,
|
FromUserID: req.OwnerUserID,
|
||||||
ToUserID: req.BlackUserID,
|
ToUserID: req.BlackUserID,
|
||||||
}}
|
}}
|
||||||
f.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips)
|
c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendInfoUpdatedNotification(
|
func (c *FriendNotificationSender) FriendInfoUpdatedNotification(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
changedUserID string,
|
changedUserID string,
|
||||||
needNotifiedUserID string,
|
needNotifiedUserID string,
|
||||||
) {
|
) {
|
||||||
tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID}
|
tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID}
|
||||||
f.Notification(ctx, mcontext.GetOpUserID(ctx), needNotifiedUserID, constant.FriendInfoUpdatedNotification, &tips)
|
c.Notification(ctx, mcontext.GetOpUserID(ctx), needNotifiedUserID, constant.FriendInfoUpdatedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,13 +220,7 @@ func (g *GroupNotificationSender) getUsersInfoMap(ctx context.Context, userIDs [
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) {
|
func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) error {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if opUser == nil {
|
if opUser == nil {
|
||||||
return errs.ErrInternalServer.Wrap("**sdkws.GroupMemberFullInfo is nil")
|
return errs.ErrInternalServer.Wrap("**sdkws.GroupMemberFullInfo is nil")
|
||||||
}
|
}
|
||||||
@@ -266,12 +260,6 @@ func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) (err error) {
|
func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -279,12 +267,6 @@ func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) (err error) {
|
func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -292,12 +274,6 @@ func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) (err error) {
|
func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -305,12 +281,6 @@ func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) (err error) {
|
func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -318,12 +288,6 @@ func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbGroup.JoinGroupReq) (err error) {
|
func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbGroup.JoinGroupReq) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, req.GroupID)
|
group, err := g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -391,12 +355,6 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) {
|
func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, req.GroupID)
|
group, err := g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -419,12 +377,6 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbGroup.TransferGroupOwnerReq) (err error) {
|
func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbGroup.TransferGroupOwnerReq) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, req.GroupID)
|
group, err := g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -442,12 +394,6 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) (err error) {
|
func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -455,12 +401,6 @@ func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, groupID, reason string, invitedUserIDList []string) (err error) {
|
func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, groupID, reason string, invitedUserIDList []string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -479,18 +419,12 @@ func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context,
|
|||||||
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips)
|
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, groupID string, entrantUserID string) (err error) {
|
func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
group, err := g.getGroupInfo(ctx, req.GroupID)
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user, err := g.getGroupMember(ctx, groupID, entrantUserID)
|
user, err := g.getGroupMember(ctx, req.GroupID, req.FromUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -499,12 +433,6 @@ func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, g
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) (err error) {
|
func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -512,12 +440,6 @@ func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) (err error) {
|
func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -537,12 +459,6 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -559,12 +475,6 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, groupID string) (err error) {
|
func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, groupID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -584,12 +494,6 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Context, groupID string) (err error) {
|
func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Context, groupID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -609,12 +513,6 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -631,12 +529,6 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -653,12 +545,6 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
group, err := g.getGroupInfo(ctx, groupID)
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -674,6 +560,25 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c
|
|||||||
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips)
|
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GroupNotificationSender) MemberEnterDirectlyNotification(ctx context.Context, groupID string, entrantUserID string) (err error) {
|
||||||
|
defer log.ZDebug(ctx, "return")
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
group, err := g.getGroupInfo(ctx, groupID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user, err := g.getGroupMember(ctx, groupID, entrantUserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tips := &sdkws.MemberEnterTips{Group: group, EntrantUser: user}
|
||||||
|
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips)
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, sendID, recvID string) (err error) {
|
func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, sendID, recvID string) (err error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
defer log.ZDebug(ctx, "return")
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
// Copyright © 2023 OpenIM. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package notification
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
|
||||||
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
|
||||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserNotificationSender struct {
|
|
||||||
*rpcclient.NotificationSender
|
|
||||||
getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error)
|
|
||||||
// db controller
|
|
||||||
db controller.UserDatabase
|
|
||||||
}
|
|
||||||
|
|
||||||
type userNotificationSenderOptions func(*UserNotificationSender)
|
|
||||||
|
|
||||||
func WithUserDB(db controller.UserDatabase) userNotificationSenderOptions {
|
|
||||||
return func(u *UserNotificationSender) {
|
|
||||||
u.db = db
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithUserFunc(
|
|
||||||
fn func(ctx context.Context, userIDs []string) (users []*relationTb.UserModel, err error),
|
|
||||||
) userNotificationSenderOptions {
|
|
||||||
return func(u *UserNotificationSender) {
|
|
||||||
f := func(ctx context.Context, userIDs []string) (result []CommonUser, err error) {
|
|
||||||
users, err := fn(ctx, userIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, user := range users {
|
|
||||||
result = append(result, user)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
u.getUsersInfo = f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUserNotificationSender(
|
|
||||||
msgRpcClient *rpcclient.MessageRpcClient,
|
|
||||||
opts ...userNotificationSenderOptions,
|
|
||||||
) *UserNotificationSender {
|
|
||||||
f := &UserNotificationSender{
|
|
||||||
NotificationSender: rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient)),
|
|
||||||
}
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt(f)
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserNotificationSender) getUsersInfoMap(
|
|
||||||
ctx context.Context,
|
|
||||||
userIDs []string,
|
|
||||||
) (map[string]*sdkws.UserInfo, error) {
|
|
||||||
users, err := u.getUsersInfo(ctx, userIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result := make(map[string]*sdkws.UserInfo)
|
|
||||||
for _, user := range users {
|
|
||||||
result[user.GetUserID()] = user.(*sdkws.UserInfo)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserNotificationSender) getFromToUserNickname(
|
|
||||||
ctx context.Context,
|
|
||||||
fromUserID, toUserID string,
|
|
||||||
) (string, string, error) {
|
|
||||||
users, err := u.getUsersInfoMap(ctx, []string{fromUserID, toUserID})
|
|
||||||
if err != nil {
|
|
||||||
return "", "", nil
|
|
||||||
}
|
|
||||||
return users[fromUserID].Nickname, users[toUserID].Nickname, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserNotificationSender) UserStatusChangeNotification(
|
|
||||||
ctx context.Context,
|
|
||||||
tips *sdkws.UserStatusChangeTips,
|
|
||||||
) error {
|
|
||||||
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserStatusChangeNotification, tips)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package statistics // import "github.com/OpenIMSDK/Open-IM-Server/pkg/statistics"
|
||||||
+31
-1
@@ -84,7 +84,37 @@ Each directory and script in the structure should be understood as a part of a l
|
|||||||
|
|
||||||
- Linux MIPS64LE (linux_mips64le) : Suitable for 64-bit Linux systems with little endian MIPS architecture.
|
- Linux MIPS64LE (linux_mips64le) : Suitable for 64-bit Linux systems with little endian MIPS architecture.
|
||||||
|
|
||||||
|
## Get started quickly - demo.sh
|
||||||
|
|
||||||
|
Is the `demo.sh` script teaching you how to quickly get started with OpenIM development and use
|
||||||
|
|
||||||
|
|
||||||
|
Steps to run demo:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make demo
|
||||||
|
```
|
||||||
|
|
||||||
|
Instructions for producing the demo movie:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create temporary directory
|
||||||
|
mkdir /tmp/kb-demo
|
||||||
|
cd /tmp/kb-demo
|
||||||
|
|
||||||
|
asciinema rec
|
||||||
|
<path-to-KB-repo>/scripts/demo/run.sh
|
||||||
|
|
||||||
|
<CTRL-C> to terminate the script
|
||||||
|
<CTRL-D> to terminate the asciinema recording
|
||||||
|
<CTRL-C> to save the recording locally
|
||||||
|
|
||||||
|
# Edit the recorded file by editing the controller-gen path
|
||||||
|
# Once you are happy with the recording, use svg-term program to generate the svg
|
||||||
|
|
||||||
|
svg-term --cast=<movie-id> --out _output/demo.svg --window
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## examples
|
## examples
|
||||||
Scripts to perform various build, install, analysis, etc operations.
|
Scripts to perform various build, install, analysis, etc operations.
|
||||||
|
|||||||
+3
-18
@@ -17,6 +17,8 @@
|
|||||||
set -e
|
set -e
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
|
. $(dirname ${BASH_SOURCE})/lib/init.sh
|
||||||
|
|
||||||
trap 'echo "Script interrupted."; exit 1' INT
|
trap 'echo "Script interrupted."; exit 1' INT
|
||||||
|
|
||||||
# Function for colored echo
|
# Function for colored echo
|
||||||
@@ -26,24 +28,6 @@ function color_echo() {
|
|||||||
echo -e "${COLOR}===> $* ${COLOR_SUFFIX}"
|
echo -e "${COLOR}===> $* ${COLOR_SUFFIX}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Color definitions
|
|
||||||
function openim_color() {
|
|
||||||
COLOR_SUFFIX="\033[0m" # End all colors and special effects
|
|
||||||
|
|
||||||
BLACK_PREFIX="\033[30m" # Black prefix
|
|
||||||
RED_PREFIX="\033[31m" # Red prefix
|
|
||||||
GREEN_PREFIX="\033[32m" # Green prefix
|
|
||||||
YELLOW_PREFIX="\033[33m" # Yellow prefix
|
|
||||||
BLUE_PREFIX="\033[34m" # Blue prefix
|
|
||||||
SKY_BLUE_PREFIX="\033[36m" # Sky blue prefix
|
|
||||||
WHITE_PREFIX="\033[37m" # White prefix
|
|
||||||
BOLD_PREFIX="\033[1m" # Bold prefix
|
|
||||||
UNDERLINE_PREFIX="\033[4m" # Underline prefix
|
|
||||||
ITALIC_PREFIX="\033[3m" # Italic prefix
|
|
||||||
|
|
||||||
CYAN_PREFIX="\033[0;36m" # Cyan prefix
|
|
||||||
}
|
|
||||||
|
|
||||||
function print_with_delay() {
|
function print_with_delay() {
|
||||||
text="$1"
|
text="$1"
|
||||||
delay="$2"
|
delay="$2"
|
||||||
@@ -68,6 +52,7 @@ function print_progress() {
|
|||||||
done
|
done
|
||||||
printf "]${COLOR_SUFFIX}\n"
|
printf "]${COLOR_SUFFIX}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
function openim_logo() {
|
function openim_logo() {
|
||||||
# Set text color to cyan for header and URL
|
# Set text color to cyan for header and URL
|
||||||
echo -e "\033[0;36m"
|
echo -e "\033[0;36m"
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
cd $SCRIPTS_ROOT
|
||||||
|
|
||||||
|
|||||||
@@ -19,21 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}"
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}"
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
echo -e ""
|
|
||||||
|
|
||||||
echo -e "${BACKGROUND_BLUE}===============> Building all using make build binary files ${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
echo -e ""
|
|
||||||
echo -e "${BOLD_PREFIX}____________________________________________________________ ${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
|
|
||||||
bin_dir="$BIN_DIR"
|
bin_dir="$BIN_DIR"
|
||||||
logs_dir="$OPENIM_ROOT/logs"
|
logs_dir="$OPENIM_ROOT/logs"
|
||||||
@@ -54,19 +41,7 @@ fi
|
|||||||
cd $OPENIM_ROOT
|
cd $OPENIM_ROOT
|
||||||
|
|
||||||
# CPU core number
|
# CPU core number
|
||||||
# Check the system type
|
cpu_count=$(lscpu | grep -e '^CPU(s):' | awk '{print $2}')
|
||||||
system_type=$(uname)
|
|
||||||
|
|
||||||
if [[ "$system_type" == "Darwin" ]]; then
|
|
||||||
# macOS (using sysctl)
|
|
||||||
cpu_count=$(sysctl -n hw.ncpu)
|
|
||||||
elif [[ "$system_type" == "Linux" ]]; then
|
|
||||||
# Linux (using lscpu)
|
|
||||||
cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l)
|
|
||||||
else
|
|
||||||
echo "Unsupported operating system: $system_type"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}"
|
echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}"
|
||||||
|
|
||||||
# Count the number of concurrent compilations (half the number of cpus)
|
# Count the number of concurrent compilations (half the number of cpus)
|
||||||
@@ -80,43 +55,7 @@ if [ $? -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the current operating system and architecture
|
openim::util::gen_os_arch
|
||||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
|
|
||||||
# Select the repository home directory based on the operating system and architecture
|
|
||||||
if [[ "$OS" == "darwin" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="darwin/amd64"
|
|
||||||
else
|
|
||||||
REPO_DIR="darwin/386"
|
|
||||||
fi
|
|
||||||
elif [[ "$OS" == "linux" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="linux/amd64"
|
|
||||||
elif [[ "$ARCH" == "arm64" ]]; then
|
|
||||||
REPO_DIR="linux/arm64"
|
|
||||||
elif [[ "$ARCH" == "mips64" ]]; then
|
|
||||||
REPO_DIR="linux/mips64"
|
|
||||||
elif [[ "$ARCH" == "mips64le" ]]; then
|
|
||||||
REPO_DIR="linux/mips64le"
|
|
||||||
elif [[ "$ARCH" == "ppc64le" ]]; then
|
|
||||||
REPO_DIR="linux/ppc64le"
|
|
||||||
elif [[ "$ARCH" == "s390x" ]]; then
|
|
||||||
REPO_DIR="linux/s390x"
|
|
||||||
else
|
|
||||||
REPO_DIR="linux/386"
|
|
||||||
fi
|
|
||||||
elif [[ "$OS" == "windows" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="windows/amd64"
|
|
||||||
else
|
|
||||||
REPO_DIR="windows/386"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine if all scripts were successfully built
|
# Determine if all scripts were successfully built
|
||||||
BUILD_SUCCESS=true
|
BUILD_SUCCESS=true
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
cd $SCRIPTS_ROOT
|
||||||
|
|
||||||
@@ -43,7 +42,7 @@ service_port_name=(
|
|||||||
)
|
)
|
||||||
for i in ${service_port_name[*]}; do
|
for i in ${service_port_name[*]}; do
|
||||||
list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}')
|
list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}')
|
||||||
list_to_string $list
|
openim::util::list-to-string $list
|
||||||
for j in ${ports_array}; do
|
for j in ${ports_array}; do
|
||||||
port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}')
|
port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}')
|
||||||
if [[ ${port} -ne ${j} ]]; then
|
if [[ ${port} -ne ${j} ]]; then
|
||||||
|
|||||||
Executable
+83
@@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
clear
|
||||||
|
. $(dirname ${BASH_SOURCE})/lib/util.sh
|
||||||
|
|
||||||
|
openim::util::desc "========> Welcome to the OpenIM Demo"
|
||||||
|
openim::util::desc "========> We'll help you get started with OpenIM quickly"
|
||||||
|
openim::util::desc "========> Press Enter to continue...."
|
||||||
|
openim::util::run "make advertise"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "You can learn a lot about automation using make help"
|
||||||
|
openim::util::run "make help"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "You can learn a lot about automation using make help-all"
|
||||||
|
openim::util::run "make help-all"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "How did we teach you how to build OpenIM"
|
||||||
|
openim::util::desc "A full build startup check"
|
||||||
|
openim::util::run "make all"
|
||||||
|
|
||||||
|
openim::util::desc "Build one OpenIM binary"
|
||||||
|
openim::util::desc "BINS: openim-api openim-cmdutils openim-crontask openim-msggateway openim-msgtransfer openim-push openim-rpc changelog infra ncpu yamlfmt"
|
||||||
|
openim::util::run "make build BINS=openim-api"
|
||||||
|
|
||||||
|
openim::util::desc "Build binaries for all platforms"
|
||||||
|
openim::util::run "make multiarch -j BINS=openim-api PLATFORMS='linux_arm64 linux_amd64' "
|
||||||
|
|
||||||
|
openim::util::desc "If you wish to use dlv for debugging, either binary or process"
|
||||||
|
openim::util::desc "You need to enable debug mode"
|
||||||
|
openim::util::run "make build BINS=openim-api DEBUG=1"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Run tidy to format and fix imports"
|
||||||
|
openim::util::run "make tidy"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Vendor go.mod dependencies"
|
||||||
|
openim::util::run "make vendor"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Run unit tests"
|
||||||
|
openim::util::run "make test"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Run unit tests and get test coverage"
|
||||||
|
openim::util::run "make cover"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Check for updates to go.mod dependencies"
|
||||||
|
openim::util::run "make updates"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Clean all generated files"
|
||||||
|
openim::util::run "make clean"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Generate all necessary files"
|
||||||
|
openim::util::run "make gen"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Verify the license headers for all files"
|
||||||
|
openim::util::run "make verify-copyright"
|
||||||
|
clear
|
||||||
|
|
||||||
|
openim::util::desc "Add copyright"
|
||||||
|
openim::util::run "make add-copyright"
|
||||||
|
clear
|
||||||
@@ -30,15 +30,6 @@ need_to_start_server_shell=(
|
|||||||
${SCRIPTS_ROOT}/start_cron.sh
|
${SCRIPTS_ROOT}/start_cron.sh
|
||||||
)
|
)
|
||||||
|
|
||||||
component_check=start_component_check.sh
|
|
||||||
chmod +x $SCRIPTS_ROOT/$component_check
|
|
||||||
$SCRIPTS_ROOT/$component_check
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# Print error message and exit
|
|
||||||
echo "${BOLD_PREFIX}${RED_PREFIX}Error executing ${component_check}. Exiting...${COLOR_SUFFIX}"
|
|
||||||
exit -1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#fixme The 10 second delay to start the project is for the docker-compose one-click to start openIM when the infrastructure dependencies are not started
|
#fixme The 10 second delay to start the project is for the docker-compose one-click to start openIM when the infrastructure dependencies are not started
|
||||||
|
|
||||||
sleep 10
|
sleep 10
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
cd $SCRIPTS_ROOT
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ service_port_name=(
|
|||||||
|
|
||||||
for i in ${service_port_name[*]}; do
|
for i in ${service_port_name[*]}; do
|
||||||
list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}')
|
list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}')
|
||||||
list_to_string $list
|
openim::util::list-to-string $list
|
||||||
for j in ${ports_array}; do
|
for j in ${ports_array}; do
|
||||||
port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}')
|
port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}')
|
||||||
if [[ ${port} -ne ${j} ]]; then
|
if [[ ${port} -ne ${j} ]]; then
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#input:[10023,2323,3434]
|
#input:[10023,2323,3434]
|
||||||
#output:10023 2323 3434
|
#output:10023 2323 3434
|
||||||
list_to_string(){
|
openim::util::list-to-string(){
|
||||||
ports_list=$*
|
ports_list=$*
|
||||||
sub_s1=`echo $ports_list | sed 's/ //g'`
|
sub_s1=`echo $ports_list | sed 's/ //g'`
|
||||||
sub_s2=${sub_s1//,/ }
|
sub_s2=${sub_s1//,/ }
|
||||||
@@ -23,7 +23,7 @@ list_to_string(){
|
|||||||
sub_s4=${sub_s3%]*}
|
sub_s4=${sub_s3%]*}
|
||||||
ports_array=$sub_s4
|
ports_array=$sub_s4
|
||||||
}
|
}
|
||||||
remove_space(){
|
openim::util::remove_space(){
|
||||||
value=$*
|
value=$*
|
||||||
result=`echo $value | sed 's/ //g'`
|
result=`echo $value | sed 's/ //g'`
|
||||||
}
|
}
|
||||||
@@ -19,9 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/..
|
OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
cd $SCRIPTS_ROOT
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright © 2023 OpenIM. All rights reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
# input: [10023, 2323, 3434]
|
|
||||||
# output: 10023 2323 3434
|
|
||||||
|
|
||||||
# 函数功能:将列表转换为字符串,去除空格和括号
|
|
||||||
list_to_string() {
|
|
||||||
ports_list=$* # 获取传入的参数列表
|
|
||||||
sub_s1=$(echo $ports_list | sed 's/ //g') # 去除空格
|
|
||||||
sub_s2=${sub_s1//,/ } # 将逗号替换为空格
|
|
||||||
sub_s3=${sub_s2#*[} # 去除左括号及其之前的内容
|
|
||||||
sub_s4=${sub_s3%]*} # 去除右括号及其之后的内容
|
|
||||||
ports_array=$sub_s4 # 将处理后的字符串赋值给变量 ports_array
|
|
||||||
}
|
|
||||||
|
|
||||||
# 函数功能:去除字符串中的空格
|
|
||||||
remove_space() {
|
|
||||||
value=$* # 获取传入的参数
|
|
||||||
result=$(echo $value | sed 's/ //g') # 去除空格
|
|
||||||
}
|
|
||||||
Executable
+73
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# Script to generate docs from the latest swagger spec.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# The root of the build/dist directory
|
||||||
|
OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||||
|
source ${OPENIM_ROOT}/scripts/lib/util.sh
|
||||||
|
|
||||||
|
mkdir -p ${OPENIM_OUTPUT_TMP}
|
||||||
|
cd ${OPENIM_OUTPUT_TMP}
|
||||||
|
|
||||||
|
# gendocs takes "input.json" as the input swagger spec.
|
||||||
|
# $1 is expected to be <group>_<version>
|
||||||
|
cp ${OPENIM_OUTPUT_TMP}/swagger-source/"$1".json ${OPENIM_OUTPUT_TMP}/input.json
|
||||||
|
|
||||||
|
./gradle-2.5/bin/gradle gendocs --info
|
||||||
|
|
||||||
|
#insert a TOC for top level API objects
|
||||||
|
buf="== Top Level API Objects\n\n"
|
||||||
|
top_level_models=$(grep '&[A-Za-z]*{},' /register.go | sed 's/.*&//;s/{},//')
|
||||||
|
|
||||||
|
# check if the top level models exist in the definitions.adoc. If they exist,
|
||||||
|
# their name will be <version>.<model_name>
|
||||||
|
VERSION="${1#*_}"
|
||||||
|
for m in ${top_level_models}
|
||||||
|
do
|
||||||
|
if grep -xq "=== ${VERSION}.${m}" ./definitions.adoc
|
||||||
|
then
|
||||||
|
buf+="* <<${VERSION}.${m}>>\n"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
sed -i "1i ${buf}" ./definitions.adoc
|
||||||
|
|
||||||
|
# fix the links in .adoc, replace <<x.y>> with link:definitions.html#_x_y[x.y], and lowercase the _x_y part
|
||||||
|
sed -i -e 's|<<\(.*\)\.\(.*\)>>|link:#_\L\1_\2\E[\1.\2]|g' ./definitions.adoc
|
||||||
|
sed -i -e 's|<<\(.*\)\.\(.*\)>>|link:../definitions#_\L\1_\2\E[\1.\2]|g' ./paths.adoc
|
||||||
|
|
||||||
|
# fix the link to <<any>>
|
||||||
|
sed -i -e 's|<<any>>|link:#_any[any]|g' ./definitions.adoc
|
||||||
|
sed -i -e 's|<<any>>|link:../definitions#_any[any]|g' ./paths.adoc
|
||||||
|
|
||||||
|
# change the title of paths.adoc from "paths" to "operations"
|
||||||
|
sed -i 's|== Paths|== Operations|g' ./paths.adoc
|
||||||
|
|
||||||
|
# $$ has special meaning in asciidoc, we need to escape it
|
||||||
|
sed -i 's|\$\$|+++$$+++|g' ./definitions.adoc
|
||||||
|
|
||||||
|
echo -e "=== any\nRepresents an untyped JSON map - see the description of the field for more info about the structure of this object." >> ./definitions.adoc
|
||||||
|
|
||||||
|
asciidoctor definitions.adoc
|
||||||
|
asciidoctor paths.adoc
|
||||||
|
|
||||||
|
cp ${OPENIM_OUTPUT_TMP}/definitions.html ${OPENIM_OUTPUT_TMP}/_output/
|
||||||
|
cp ${OPENIM_OUTPUT_TMP}/paths.html ${OPENIM_OUTPUT_TMP}/_output/operations.html
|
||||||
|
|
||||||
|
success "SUCCESS"
|
||||||
@@ -5,17 +5,17 @@
|
|||||||
# license that can be found in the LICENSE file.
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
# 本脚本功能:根据 scripts/environment.sh 配置,生成 OPENIM 组件 YAML 配置文件。
|
# 本脚本功能:根据 scripts/environment.sh 配置,生成 OPENIM 组件 YAML 配置文件。
|
||||||
# 示例:genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml
|
# 示例:genconfig.sh scripts/environment.sh configs/openim-api.yaml
|
||||||
|
|
||||||
|
# Path to the original script file
|
||||||
env_file="$1"
|
env_file="$1"
|
||||||
|
# Path to the generated config file
|
||||||
template_file="$2"
|
template_file="$2"
|
||||||
|
|
||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
. $(dirname ${BASH_SOURCE})/lib/init.sh
|
||||||
|
|
||||||
source "${OPENIM_ROOT}/scripts/lib/init.sh"
|
|
||||||
|
|
||||||
if [ $# -ne 2 ];then
|
if [ $# -ne 2 ];then
|
||||||
openim::log::error "Usage: genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml"
|
openim::log::error "Usage: genconfig.sh scripts/environment.sh configs/openim-api.yaml"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user