mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-28 22:39:18 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4fe75e83e | |||
| 3ef64e9066 | |||
| 71393da390 | |||
| 825622fd99 | |||
| 415d40f8c5 | |||
| bde3d98d0f | |||
| d37796a58f | |||
| 4fcea57df0 | |||
| 1d98a9959c | |||
| 3ecd33aded | |||
| 5615e47d99 | |||
| 04a97ac154 | |||
| 598938c13c | |||
| d97c44ef99 | |||
| e706620f12 | |||
| bd518365ea |
+1
-1
@@ -15,7 +15,7 @@ CHANGELOG/
|
||||
# LICENSE
|
||||
|
||||
# Ignore testing and linting configuration
|
||||
scripts/golangci.yml
|
||||
.golangci.yml
|
||||
|
||||
# Ignore deployment-related files
|
||||
docker-compose.yaml
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
#
|
||||
# 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=`
|
||||
args: --timeout=30m --config=/scripts/golangci.yml # --issues-exit-code=0
|
||||
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
|
||||
|
||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||
# only-new-issues: true
|
||||
|
||||
@@ -43,12 +43,9 @@ jobs:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro':
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
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
|
||||
args: release --clean
|
||||
env:
|
||||
USERNAME: ${{ github.repository_owner }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
|
||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
|
||||
# distribution:
|
||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
|
||||
@@ -479,4 +479,53 @@ checksum:
|
||||
algorithm: sha256
|
||||
|
||||
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! 🙌
|
||||
+4
-3
@@ -10,8 +10,8 @@ ENV GOPROXY=$GOPROXY
|
||||
# Set up the working directory
|
||||
WORKDIR /openim/openim-server
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY go.mod go.sum go.work go.work.sum ./
|
||||
#RUN go mod download
|
||||
|
||||
# Copy all files to the container
|
||||
ADD . .
|
||||
@@ -26,6 +26,7 @@ WORKDIR ${SERVER_WORKDIR}
|
||||
# Copy scripts and binary files to the production image
|
||||
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
||||
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||
COPY --from=builder $OPENIM_SERVER_BINDIR/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"]
|
||||
|
||||
@@ -12,7 +12,7 @@ all: tidy gen add-copyright format lint cover build
|
||||
# Build set
|
||||
|
||||
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
||||
# TODO: This is version control for the future https://github.com/OpenIMSDK/Open-IM-Server/issues/574
|
||||
# TODO: This is version control for the future
|
||||
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
||||
|
||||
# ==============================================================================
|
||||
@@ -191,11 +191,6 @@ advertise:
|
||||
release: release.verify release.ensure-tag
|
||||
@scripts/release.sh
|
||||
|
||||
## demo: Run demo ✨
|
||||
.PHONY: demo
|
||||
demo:
|
||||
@$(MAKE) go.demo
|
||||
|
||||
## help: Show this help info. ✨
|
||||
.PHONY: help
|
||||
help: Makefile
|
||||
|
||||
@@ -34,16 +34,13 @@ COPY . .
|
||||
RUN make clean
|
||||
RUN make build BINS=openim-api
|
||||
|
||||
# FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||
FROM test:v1
|
||||
FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||
|
||||
WORKDIR /openim/openim-server
|
||||
|
||||
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
|
||||
|
||||
ENV PORT 10002
|
||||
EXPOSE ${10002}
|
||||
|
||||
EXPOSE ${PORT}
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-api --port ${PORT} -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-api --port 10002 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -39,7 +39,7 @@ FROM ghcr.io/openim-sigs/openim-bash-image:latest
|
||||
|
||||
WORKDIR /openim/openim-server
|
||||
|
||||
COPY --from=builder $OPENIM_SERVER_BINDIR/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}/config /openim/openim-server/config
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-cmdutils"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-cmdutils"]
|
||||
|
||||
@@ -41,4 +41,4 @@ WORKDIR /openim/openim-server
|
||||
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
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-crontask"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-crontask"]
|
||||
|
||||
@@ -47,4 +47,4 @@ ENV ARCH ${ARCH}
|
||||
EXPOSE 10140
|
||||
EXPOSE 10001
|
||||
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msggateway --port 10140 --ws_port 10001
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msggateway --port 10140 --ws_port 10001
|
||||
@@ -44,4 +44,4 @@ WORKDIR /openim/openim-server
|
||||
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
|
||||
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msgtransfer
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msgtransfer
|
||||
@@ -46,4 +46,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
|
||||
EXPOSE 10170
|
||||
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-push --port 10170
|
||||
CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-push --port 10170
|
||||
@@ -49,4 +49,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
|
||||
EXPOSE 10160
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
EXPOSE 10230
|
||||
EXPOSE 20230
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
EXPOSE 10120
|
||||
EXPOSE 20120
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
EXPOSE 10150
|
||||
EXPOSE 20150
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
EXPOSE 10130
|
||||
EXPOSE 20130
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
|
||||
EXPOSE 10200
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config
|
||||
|
||||
EXPOSE 10110
|
||||
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"]
|
||||
CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"]
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
func main() {
|
||||
cronTaskCmd := cmd.NewCronTaskCmd()
|
||||
if err := cronTaskCmd.Exec(tools.StartCronTask); err != nil {
|
||||
if err := cronTaskCmd.Exec(tools.StartTask); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
+43
-39
@@ -24,10 +24,10 @@
|
||||
# Zookeeper username
|
||||
# Zookeeper password
|
||||
zookeeper:
|
||||
schema: openim
|
||||
address: [ 127.0.0.1:2181 ]
|
||||
username:
|
||||
password:
|
||||
schema: openim
|
||||
address: [ 127.0.0.1:2181 ]
|
||||
username:
|
||||
password:
|
||||
|
||||
###################### Mysql ######################
|
||||
# MySQL configuration
|
||||
@@ -42,12 +42,12 @@ mysql:
|
||||
address: [ 127.0.0.1:13306 ]
|
||||
username: root
|
||||
password: openIM123
|
||||
database: openIM_v3
|
||||
maxOpenConn: 1000
|
||||
maxIdleConn: 100
|
||||
maxLifeTime: 60
|
||||
logLevel: 4
|
||||
slowThreshold: 500
|
||||
database: openIM_v3
|
||||
maxOpenConn: 1000
|
||||
maxIdleConn: 100
|
||||
maxLifeTime: 60
|
||||
logLevel: 4
|
||||
slowThreshold: 500
|
||||
|
||||
###################### Mongo ######################
|
||||
# MongoDB configuration
|
||||
@@ -62,7 +62,7 @@ mongo:
|
||||
database: openIM_v3
|
||||
username: root
|
||||
password: openIM123
|
||||
maxPoolSize: 100
|
||||
maxPoolSize: 100
|
||||
|
||||
###################### Redis ######################
|
||||
# Redis configuration
|
||||
@@ -70,7 +70,7 @@ mongo:
|
||||
# Username is required only for Redis version 6.0+
|
||||
redis:
|
||||
address: [ 127.0.0.1:16379 ]
|
||||
username:
|
||||
username:
|
||||
password: openIM123
|
||||
|
||||
###################### Kafka ######################
|
||||
@@ -81,13 +81,13 @@ redis:
|
||||
# It's not recommended to modify this topic name
|
||||
# Consumer group ID, it's not recommended to modify
|
||||
kafka:
|
||||
username:
|
||||
password:
|
||||
username:
|
||||
password:
|
||||
addr: [ 127.0.0.1:9092 ]
|
||||
latestMsgToRedis:
|
||||
topic: "latestMsgToRedis"
|
||||
topic: "latestMsgToRedis"
|
||||
offlineMsgToMongo:
|
||||
topic: "offlineMsgToMongoMysql"
|
||||
topic: "offlineMsgToMongoMysql"
|
||||
msgToPush:
|
||||
topic: "msgToPush"
|
||||
consumerGroupID:
|
||||
@@ -111,8 +111,8 @@ rpc:
|
||||
# API service port
|
||||
# Default listen IP is 0.0.0.0
|
||||
api:
|
||||
openImApiPort: [ 10002 ]
|
||||
listenIP: 0.0.0.0
|
||||
openImApiPort: [ 10002 ]
|
||||
listenIP: 0.0.0.0
|
||||
|
||||
###################### Gateway ######################
|
||||
# Object storage configuration
|
||||
@@ -124,25 +124,29 @@ api:
|
||||
# Session token
|
||||
# Configuration for Tencent COS
|
||||
# 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:
|
||||
enable: "minio"
|
||||
apiURL: http://127.0.0.1:10002/object/
|
||||
enable: "minio"
|
||||
apiURL: "http://127.0.0.1:10002"
|
||||
minio:
|
||||
bucket: "openim"
|
||||
endpoint: http://127.0.0.1:10005
|
||||
accessKeyID: root
|
||||
secretAccessKey: openIM123
|
||||
sessionToken: ""
|
||||
cos:
|
||||
bucket: "openim"
|
||||
endpoint: "http://127.0.0.1:10005"
|
||||
accessKeyID: "root"
|
||||
secretAccessKey: "openIM123"
|
||||
sessionToken: ""
|
||||
signEndpoint: "http://127.0.0.1:10005"
|
||||
cos:
|
||||
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
||||
secretID: ""
|
||||
secretKey: ""
|
||||
sessionToken: ""
|
||||
oss:
|
||||
oss:
|
||||
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||
bucket: "demo-9999999"
|
||||
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
||||
accessKeyID: root
|
||||
accessKeyID: ""
|
||||
accessKeySecret: ""
|
||||
sessionToken: ""
|
||||
|
||||
@@ -150,7 +154,7 @@ object:
|
||||
# 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 example, [10110, 10111]
|
||||
rpcPort:
|
||||
rpcPort:
|
||||
openImUserPort: [ 10110 ]
|
||||
openImFriendPort: [ 10120 ]
|
||||
openImMessagePort: [ 10130 ]
|
||||
@@ -183,12 +187,12 @@ rpcRegisterName:
|
||||
# Whether to output in json format
|
||||
# Whether to include stack trace in logs
|
||||
log:
|
||||
storageLocation: ../../../../../logs/
|
||||
rotationTime: 24
|
||||
remainRotationCount: 2
|
||||
remainLogLevel: 6
|
||||
isStdout: false
|
||||
isJson: false
|
||||
storageLocation: ../../../../../logs/
|
||||
rotationTime: 24
|
||||
remainRotationCount: 2
|
||||
remainLogLevel: 6
|
||||
isStdout: false
|
||||
isJson: false
|
||||
withStack: false
|
||||
|
||||
# Long connection server configuration
|
||||
@@ -198,10 +202,10 @@ log:
|
||||
# Maximum length of websocket request package
|
||||
# Websocket connection handshake timeout
|
||||
longConnSvr:
|
||||
openImWsPort: [ 10001 ]
|
||||
websocketMaxConnNum: 100000
|
||||
websocketMaxMsgLen: 4096
|
||||
websocketTimeout: 10
|
||||
openImWsPort: [ 10001 ]
|
||||
websocketMaxConnNum: 100000
|
||||
websocketMaxMsgLen: 4096
|
||||
websocketTimeout: 10
|
||||
|
||||
# Push notification service configuration
|
||||
#
|
||||
|
||||
+5
-2
@@ -62,6 +62,7 @@ services:
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
network_mode: "host"
|
||||
|
||||
kafka:
|
||||
image: wurstmeister/kafka
|
||||
@@ -72,7 +73,7 @@ services:
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
KAFKA_BROKER_ID: 0
|
||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||
KAFKA_ZOOKEEPER_CONNECT: 127.0.0.1:2181
|
||||
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_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
||||
@@ -80,6 +81,7 @@ services:
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
||||
depends_on:
|
||||
- zookeeper
|
||||
network_mode: "host"
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
@@ -98,6 +100,7 @@ services:
|
||||
|
||||
openim-server:
|
||||
image: ghcr.io/openimsdk/openim-server:latest
|
||||
#build: .
|
||||
container_name: openim-server
|
||||
volumes:
|
||||
- ./logs:/openim/openim-server/logs
|
||||
@@ -147,7 +150,7 @@ services:
|
||||
# ports:
|
||||
# - 9091:9091
|
||||
depends_on:
|
||||
- openim-server
|
||||
- openim-server
|
||||
command: --web.listen-address=:9091 --config.file="/etc/prometheus/prometheus.yml"
|
||||
network_mode: "host"
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ logs/* @skiffer-git @FGadvancer
|
||||
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
|
||||
|
||||
# scripts directory
|
||||
scripts/template/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||
scripts/LICENSE/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
|
||||
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
|
||||
|
||||
+54
-43
@@ -1,76 +1,88 @@
|
||||
# OpenIM Branch Management and Versioning
|
||||
# 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.
|
||||
[📚 **OpenIM TOC**](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
|
||||
- [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.
|
||||
|
||||
## Main Branch
|
||||
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/).
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
## Release Branch
|
||||
## Unfolding the Mechanism of OpenIM Version Maintenance
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
## Tag Management
|
||||
In the OpenIM repository, version identification strictly complies with the `MAJOR.MINOR.PATCH` protocol. Herein:
|
||||
|
||||
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 `MAJOR` version indicates a shift arising from incompatible changes to the API.
|
||||
- The `MINOR` version suggests the addition of features in a backward-compatible manner.
|
||||
- The `PATCH` version flags backward-compatible bug fixes.
|
||||
|
||||
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`.
|
||||
## Main Branch: The Heart of OpenIM Development
|
||||
|
||||
Here is the specification of our version numbers:
|
||||
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).
|
||||
|
||||
- **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.
|
||||
## Release Branch: The Beacon of Stability
|
||||
|
||||
- **Build version number**: Usually automatically generated by the system, every code submission will result in an automatic increment by 1.
|
||||
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).
|
||||
|
||||
- Version modifiers
|
||||
## Tag Management: The Cornerstone of Version Control
|
||||
|
||||
: These can represent the development stage and stability of the software. Common ones include:
|
||||
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).
|
||||
|
||||
- `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.
|
||||
- `rc`: Release candidate, to be released as the official version, it's the last test version before the official version.
|
||||
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`.
|
||||
|
||||
To further clarify, the semantics of our version numbers are as follows:
|
||||
|
||||
- **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.
|
||||
- `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 found in this version.
|
||||
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs discovered in this version.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## OpenIM version
|
||||
## Release Management: A Guided Tour
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
In the OpenIM repository, the versioning adheres to the `MAJOR.MINOR.PATCH` format, where:
|
||||
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.
|
||||
|
||||
- `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.
|
||||
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`.
|
||||
|
||||
## Milestones and Branching
|
||||
## Milestones, Branching, and Addressing Major Bugs
|
||||
|
||||
**About:**
|
||||
|
||||
+ [OpenIM Milestones](https://github.com/OpenIMSDK/Open-IM-Server/milestones)
|
||||
+ [OpenIM Tags](https://github.com/OpenIMSDK/Open-IM-Server/tags)
|
||||
+ [OpenIM Branches](https://github.com/OpenIMSDK/Open-IM-Server/branches)
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
`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.
|
||||
|
||||
## Dealing with Major Bugs
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
## Applying Principles: A Git Workflow Example
|
||||
|
||||
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.
|
||||
The workflow to address a bug fix might follow these steps:
|
||||
|
||||
## Git Workflow Example
|
||||
|
||||
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
|
||||
```bash
|
||||
bashCopy codebashCopy code# Checkout the branch for the version that needs the bug fix
|
||||
git checkout release-v3.1
|
||||
|
||||
# Create a new branch for the bug fix
|
||||
@@ -93,9 +105,8 @@ git merge release-v3.1
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Remember, communication with your team is key throughout this process, keeping everyone up-to-date with the changes being made.
|
||||
Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes.
|
||||
|
||||
## Docker Images Version Management
|
||||
|
||||
## Docker images version management
|
||||
|
||||
+ [OpenIM Docker Images Administration](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md)
|
||||
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).
|
||||
|
||||
@@ -25,13 +25,13 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.mongodb.org/mongo-driver v1.12.1
|
||||
golang.org/x/image v0.9.0 // indirect
|
||||
google.golang.org/api v0.135.0
|
||||
golang.org/x/image v0.11.0
|
||||
google.golang.org/api v0.136.0
|
||||
google.golang.org/grpc v1.57.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.1
|
||||
gorm.io/gorm v1.25.2
|
||||
gorm.io/gorm v1.25.3
|
||||
)
|
||||
|
||||
require github.com/google/uuid v1.3.0
|
||||
@@ -47,11 +47,11 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.4 // indirect
|
||||
cloud.google.com/go/compute v1.20.1 // indirect
|
||||
cloud.google.com/go v0.110.6 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/firestore v1.11.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/longrunning v0.5.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.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/multierr v1.6.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/oauth2 v0.10.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/oauth2 v0.11.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -138,6 +138,6 @@ require (
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.11.0 // indirect
|
||||
golang.org/x/crypto v0.12.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.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
|
||||
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
|
||||
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
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/firestore v1.11.0 h1:PPgtwcYUOXV2jFe1bV3nda3RCrOa8cvBjTOn2MQVfW8=
|
||||
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
|
||||
cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
|
||||
cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk=
|
||||
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
|
||||
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||
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/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||
@@ -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-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.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/image v0.9.0 h1:QrzfX26snvCM20hIhBwuHI/ThTg18b/+kcKdXHvnR+g=
|
||||
golang.org/x/image v0.9.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
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-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-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.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
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.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
||||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
||||
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-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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
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.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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/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-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.135.0 h1:6Vgfj6uPMXcyy66waYWBwmkeNB+9GmUlJDOzkukPQYQ=
|
||||
google.golang.org/api v0.135.0/go.mod h1:Bp77uRFgwsSKI0BWH573F5Q6wSlznwI2NFayLOp/7mQ=
|
||||
google.golang.org/api v0.136.0 h1:e/6enzUE1s4tGPa6Q3ZYShKTtvRc+1Jq0rrafhppmOs=
|
||||
google.golang.org/api v0.136.0/go.mod h1:XtJfF+V2zgUxelOn5Zs3kECtluMxneJG8ZxUTlLNTPA=
|
||||
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.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-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-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
|
||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ=
|
||||
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-20230726155614-23370e0ffb3e/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
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-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
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.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/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
|
||||
gorm.io/gorm v1.25.3/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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
@@ -2,8 +2,7 @@ go 1.20
|
||||
|
||||
use (
|
||||
.
|
||||
./tools/changelog
|
||||
./tools/component
|
||||
./tools/infra
|
||||
./tools/ncpu
|
||||
./tools/yamlfmt
|
||||
)
|
||||
|
||||
+1
-4
@@ -1,9 +1,6 @@
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
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/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -83,7 +83,14 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
|
||||
operationID = strconv.Itoa(rand.Int())
|
||||
}
|
||||
ctx := mcontext.SetOperationID(c, operationID)
|
||||
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name})
|
||||
query := make(map[string]string)
|
||||
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 errs.ErrArgs.Is(err) {
|
||||
c.String(http.StatusBadRequest, err.Error())
|
||||
|
||||
@@ -88,6 +88,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
||||
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
||||
|
||||
parseError := apiresp.ParseError(err)
|
||||
log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode)
|
||||
if parseError.ErrCode == errs.NoPermissionError {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
|
||||
@@ -40,7 +40,13 @@ type Req struct {
|
||||
}
|
||||
|
||||
func (r *Req) String() string {
|
||||
return utils.StructToJsonString(r)
|
||||
var tReq Req
|
||||
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 {
|
||||
@@ -53,7 +59,13 @@ type Resp struct {
|
||||
}
|
||||
|
||||
func (r *Resp) String() string {
|
||||
return utils.StructToJsonString(r)
|
||||
var tResp Resp
|
||||
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 {
|
||||
|
||||
@@ -145,7 +145,7 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
|
||||
len(modifyMsgList),
|
||||
)
|
||||
conversationIDMsg := msgprocessor.GetChatConversationIDByMsg(ctxMsgList[0].message)
|
||||
conversationIDNotification := msgprocessor.GetNotificationConversationID(ctxMsgList[0].message)
|
||||
conversationIDNotification := msgprocessor.GetNotificationConversationIDByMsg(ctxMsgList[0].message)
|
||||
och.handleMsg(ctx, msgChannelValue.uniqueKey, conversationIDMsg, storageMsgList, notStorageMsgList)
|
||||
och.handleNotification(
|
||||
ctx,
|
||||
|
||||
@@ -161,6 +161,9 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
|
||||
if req.OwnerUserID == "" {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -690,8 +693,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
||||
return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed")
|
||||
}
|
||||
var inGroup bool
|
||||
_, err = s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID)
|
||||
if err == nil {
|
||||
if _, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil {
|
||||
inGroup = true // 已经在群里了
|
||||
} else if !s.IsNotFound(err) {
|
||||
return nil, err
|
||||
@@ -718,6 +720,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -727,12 +730,14 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup
|
||||
return nil, err
|
||||
}
|
||||
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:
|
||||
s.Notification.GroupApplicationRejectedNotification(ctx, req)
|
||||
}
|
||||
if member != nil {
|
||||
s.Notification.MemberEnterNotification(ctx, req)
|
||||
}
|
||||
return &pbGroup.GroupApplicationResponseResp{}, nil
|
||||
}
|
||||
|
||||
@@ -778,7 +783,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq)
|
||||
if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.Notification.MemberEnterDirectlyNotification(ctx, req.GroupID, req.InviterUserID)
|
||||
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
||||
return resp, nil
|
||||
}
|
||||
groupRequest := relationTb.GroupRequestModel{
|
||||
|
||||
@@ -116,41 +116,75 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
|
||||
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
|
||||
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 {
|
||||
pbChatLog := &msg.ChatLog{}
|
||||
utils.CopyStructFields(pbChatLog, chatLog)
|
||||
pbChatLog.SendTime = chatLog.SendTime
|
||||
pbChatLog.CreateTime = chatLog.CreateTime
|
||||
if chatLog.SenderNickname == "" {
|
||||
sendUser, err := m.User.GetUserInfo(ctx, chatLog.SendID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbChatLog.SenderNickname = sendUser.Nickname
|
||||
pbChatLog.SenderNickname = sendMap[chatLog.SendID]
|
||||
}
|
||||
switch chatLog.SessionType {
|
||||
case constant.SingleChatType:
|
||||
recvUser, err := m.User.GetUserInfo(ctx, chatLog.RecvID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbChatLog.RecvNickname = recvUser.Nickname
|
||||
pbChatLog.RecvNickname = recvMap[chatLog.RecvID]
|
||||
|
||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||
group, err := m.Group.GetGroupInfo(ctx, chatLog.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbChatLog.SenderFaceURL = group.FaceURL
|
||||
pbChatLog.GroupMemberCount = group.MemberCount
|
||||
pbChatLog.RecvID = group.GroupID
|
||||
pbChatLog.GroupName = group.GroupName
|
||||
pbChatLog.GroupOwner = group.OwnerUserID
|
||||
pbChatLog.GroupType = group.GroupType
|
||||
pbChatLog.SenderFaceURL = groupMap[chatLog.GroupID].FaceURL
|
||||
pbChatLog.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount
|
||||
pbChatLog.RecvID = groupMap[chatLog.GroupID].GroupID
|
||||
pbChatLog.GroupName = groupMap[chatLog.GroupID].GroupName
|
||||
pbChatLog.GroupOwner = groupMap[chatLog.GroupID].OwnerUserID
|
||||
pbChatLog.GroupType = groupMap[chatLog.GroupID].GroupType
|
||||
}
|
||||
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
|
||||
}
|
||||
|
||||
resp.ChatLogsNum = total
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@ package third
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/third"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
@@ -152,7 +155,21 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co
|
||||
}
|
||||
|
||||
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
||||
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire)
|
||||
opt := &s3.AccessURLOption{}
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
if apiURL[len(apiURL)-1] != '/' {
|
||||
apiURL += "/"
|
||||
}
|
||||
apiURL += "object/"
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -20,17 +20,16 @@ import (
|
||||
"strings"
|
||||
"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/tx"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||
"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"
|
||||
"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/convert"
|
||||
@@ -41,9 +40,9 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type userServer struct {
|
||||
|
||||
@@ -26,12 +26,13 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
)
|
||||
|
||||
func StartCronTask() error {
|
||||
func StartTask() error {
|
||||
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
||||
msgTool, err := InitMsgTool()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgTool.ConvertTools()
|
||||
c := cron.New()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,15 +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 apistruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
|
||||
@@ -1,15 +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 authverify // import "github.com/OpenIMSDK/Open-IM-Server/pkg/authverify"
|
||||
@@ -1,15 +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 callbackstruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/callbackstruct"
|
||||
@@ -1,15 +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 cmd // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/cmd"
|
||||
@@ -120,6 +120,7 @@ type configStruct struct {
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
SignEndpoint string `yaml:"signEndpoint"`
|
||||
} `yaml:"minio"`
|
||||
Cos struct {
|
||||
BucketURL string `yaml:"bucketURL"`
|
||||
|
||||
@@ -1,15 +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 config // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
@@ -1,15 +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 convert // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
|
||||
Vendored
-15
@@ -1,15 +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 cache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
@@ -1,15 +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 controller // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||
@@ -209,6 +209,7 @@ func (f *friendDatabase) RefuseFriendRequest(
|
||||
if fr.HandleResult != 0 {
|
||||
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.HandleTime = time.Now()
|
||||
err = f.friendRequest.Update(ctx, friendRequest)
|
||||
|
||||
@@ -386,8 +386,24 @@ func (g *groupDatabase) HandlerGroupRequest(
|
||||
handleResult int32,
|
||||
member *relationTb.GroupMemberModel,
|
||||
) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
//cache := g.cache.NewCache()
|
||||
//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 {
|
||||
return err
|
||||
}
|
||||
@@ -395,13 +411,12 @@ func (g *groupDatabase) HandlerGroupRequest(
|
||||
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)
|
||||
if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||
|
||||
@@ -118,6 +118,7 @@ type CommonMsgDatabase interface {
|
||||
pageNumber int32,
|
||||
showNumber int32,
|
||||
) (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 {
|
||||
@@ -730,34 +731,21 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio
|
||||
delStruct.delDocIDs = append(delStruct.delDocIDs, msgDocModel.DocID)
|
||||
delStruct.minSeq = msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.Seq
|
||||
} else {
|
||||
var hasMarkDelFlag bool
|
||||
var delMsgIndexs []int
|
||||
for i, MsgInfoModel := range msgDocModel.Msg {
|
||||
if MsgInfoModel != nil && MsgInfoModel.Msg != nil {
|
||||
if utils.GetCurrentTimestampByMill() > MsgInfoModel.Msg.SendTime+(remainTime*1000) {
|
||||
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)
|
||||
return seq, err
|
||||
}
|
||||
@@ -961,7 +949,14 @@ func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.Searc
|
||||
return 0, nil, err
|
||||
}
|
||||
for _, msg := range msgs {
|
||||
if msg.IsRead {
|
||||
msg.Msg.IsRead = true
|
||||
}
|
||||
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
|
||||
}
|
||||
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)
|
||||
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)
|
||||
AccessURL(ctx context.Context, name string, expire time.Duration) (time.Time, string, error)
|
||||
AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error)
|
||||
SetObject(ctx context.Context, info *relation.ObjectModel) error
|
||||
}
|
||||
|
||||
@@ -70,14 +70,19 @@ func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel)
|
||||
return s.obj.SetObject(ctx, info)
|
||||
}
|
||||
|
||||
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration) (time.Time, string, error) {
|
||||
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) {
|
||||
obj, err := s.obj.Take(ctx, name)
|
||||
if err != nil {
|
||||
return time.Time{}, "", err
|
||||
}
|
||||
opt := &s3.AccessURLOption{
|
||||
ContentType: obj.ContentType,
|
||||
Filename: filepath.Base(obj.Name),
|
||||
if opt == nil {
|
||||
opt = &s3.AccessURLOption{}
|
||||
}
|
||||
if opt.ContentType == "" {
|
||||
opt.ContentType = obj.ContentType
|
||||
}
|
||||
if opt.Filename == "" {
|
||||
opt.Filename = filepath.Base(obj.Name)
|
||||
}
|
||||
expireTime := time.Now().Add(expire)
|
||||
rawURL, err := s.s3.AccessURL(ctx, obj.Key, expire, opt)
|
||||
|
||||
@@ -18,9 +18,10 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
"github.com/OpenIMSDK/protocol/user"
|
||||
|
||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -52,7 +53,7 @@ type UserDatabase interface {
|
||||
CountTotal(ctx context.Context, before *time.Time) (int64, error)
|
||||
// CountRangeEverydayTotal Get the user increment in the range
|
||||
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
|
||||
// SubscribeUsersStatus Subscribe a user's presence status
|
||||
//SubscribeUsersStatus Subscribe a user's presence status
|
||||
SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error
|
||||
// UnsubscribeUsersStatus unsubscribe a user's presence status
|
||||
UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error
|
||||
@@ -179,13 +180,13 @@ func (u *userDatabase) CountRangeEverydayTotal(ctx context.Context, start time.T
|
||||
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 {
|
||||
err := u.mongoDB.AddSubscriptionList(ctx, userID, userIDs)
|
||||
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 {
|
||||
err := u.mongoDB.UnsubscriptionList(ctx, userID, userIDs)
|
||||
return err
|
||||
|
||||
@@ -1,15 +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 localcache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/localcache"
|
||||
@@ -1,15 +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 relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
|
||||
@@ -71,10 +71,13 @@ func (f *FriendRequestGorm) UpdateByMap(
|
||||
|
||||
// 更新记录 (非零值).
|
||||
func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
||||
fr2 := *friendRequest
|
||||
fr2.FromUserID = ""
|
||||
fr2.ToUserID = ""
|
||||
return utils.Wrap(
|
||||
f.db(ctx).
|
||||
Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID).
|
||||
Updates(friendRequest).
|
||||
Updates(fr2).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
@@ -33,5 +33,6 @@ func NewMetaDB(db *gorm.DB, table any) *MetaDB {
|
||||
}
|
||||
|
||||
func (g *MetaDB) db(ctx context.Context) *gorm.DB {
|
||||
return g.DB.WithContext(ctx).Model(g.table)
|
||||
db := g.DB.WithContext(ctx).Model(g.table)
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -86,7 +86,11 @@ func (u *UserGorm) Page(
|
||||
|
||||
// 获取所有用户ID.
|
||||
func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
||||
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
|
||||
if pageNumber == 0 || showNumber == 0 {
|
||||
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) {
|
||||
|
||||
@@ -257,5 +257,9 @@ func (c *Controller) IsNotFound(err error) bool {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -1,15 +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 cont // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
|
||||
@@ -36,6 +36,19 @@ const (
|
||||
maxNumSize = 1000
|
||||
)
|
||||
|
||||
const (
|
||||
imagePng = "png"
|
||||
imageJpg = "jpg"
|
||||
imageJpeg = "jpeg"
|
||||
imageGif = "gif"
|
||||
imageWebp = "webp"
|
||||
)
|
||||
|
||||
const (
|
||||
videoSnapshotImagePng = "png"
|
||||
videoSnapshotImageJpg = "jpg"
|
||||
)
|
||||
|
||||
func NewCos() (s3.Interface, error) {
|
||||
conf := config.Config.Object.Cos
|
||||
u, err := url.Parse(conf.BucketURL)
|
||||
@@ -248,19 +261,44 @@ 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) {
|
||||
var option *cos.PresignedURLOptions
|
||||
var imageMogr string
|
||||
var option cos.PresignedURLOptions
|
||||
if opt != nil {
|
||||
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 != "" {
|
||||
query.Set("response-content-type", opt.ContentType)
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
query.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`)
|
||||
query.Set("response-content-disposition", `attachment; filename=`+strconv.Quote(opt.Filename))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
option = &cos.PresignedURLOptions{
|
||||
Query: &query,
|
||||
}
|
||||
option.Query = &query
|
||||
}
|
||||
}
|
||||
if expire <= 0 {
|
||||
@@ -268,9 +306,13 @@ func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration,
|
||||
} else if 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 {
|
||||
return "", err
|
||||
}
|
||||
return rawURL.String(), nil
|
||||
urlStr := rawURL.String()
|
||||
if imageMogr != "" {
|
||||
urlStr += imageMogr
|
||||
}
|
||||
return urlStr, nil
|
||||
}
|
||||
|
||||
@@ -1,15 +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 cos // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos"
|
||||
@@ -1,15 +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 s3 // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
||||
@@ -1,15 +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 minio // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio"
|
||||
@@ -0,0 +1,106 @@
|
||||
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
|
||||
}
|
||||
+195
-12
@@ -15,16 +15,28 @@
|
||||
package minio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/gif"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
"github.com/minio/minio-go/v7/pkg/signer"
|
||||
@@ -43,6 +55,13 @@ const (
|
||||
maxNumSize = 10000
|
||||
)
|
||||
|
||||
const (
|
||||
maxImageWidth = 1024
|
||||
maxImageHeight = 1024
|
||||
maxImageSize = 1024 * 1024 * 50
|
||||
pathInfo = "openim/thumbnail"
|
||||
)
|
||||
|
||||
func NewMinio() (s3.Interface, error) {
|
||||
conf := config.Config.Object.Minio
|
||||
u, err := url.Parse(conf.Endpoint)
|
||||
@@ -60,11 +79,26 @@ func NewMinio() (s3.Interface, error) {
|
||||
m := &Minio{
|
||||
bucket: conf.Bucket,
|
||||
bucketURL: conf.Endpoint + "/" + conf.Bucket + "/",
|
||||
opts: opts,
|
||||
core: &minio.Core{Client: client},
|
||||
lock: &sync.Mutex{},
|
||||
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)
|
||||
defer cancel()
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
@@ -76,8 +110,10 @@ func NewMinio() (s3.Interface, error) {
|
||||
type Minio struct {
|
||||
bucket string
|
||||
bucketURL string
|
||||
location string
|
||||
opts *minio.Options
|
||||
core *minio.Core
|
||||
sign *minio.Client
|
||||
lock sync.Locker
|
||||
init bool
|
||||
}
|
||||
@@ -91,15 +127,43 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
if m.init {
|
||||
return nil
|
||||
}
|
||||
exists, err := m.core.Client.BucketExists(ctx, config.Config.Object.Minio.Bucket)
|
||||
conf := config.Config.Object.Minio
|
||||
exists, err := m.core.Client.BucketExists(ctx, conf.Bucket)
|
||||
if err != nil {
|
||||
return fmt.Errorf("check bucket exists error: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
if err := m.core.Client.MakeBucket(ctx, config.Config.Object.Minio.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||
if err := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||
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
|
||||
return nil
|
||||
}
|
||||
@@ -191,7 +255,7 @@ func (m *Minio) AuthSign(ctx context.Context, uploadID string, name string, expi
|
||||
return nil, err
|
||||
}
|
||||
request.Header.Set("X-Amz-Content-Sha256", unsignedPayload)
|
||||
request = signer.SignV4Trailer(*request, creds.AccessKeyID, creds.SecretAccessKey, creds.SessionToken, "us-east-1", nil)
|
||||
request = signer.SignV4Trailer(*request, creds.AccessKeyID, creds.SecretAccessKey, creds.SessionToken, m.location, nil)
|
||||
result.Parts[i] = s3.SignPart{
|
||||
PartNumber: partNumber,
|
||||
URL: request.URL.String(),
|
||||
@@ -206,7 +270,7 @@ func (m *Minio) PresignedPutObject(ctx context.Context, name string, expire time
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
rawURL, err := m.core.Client.PresignedPutObject(ctx, m.bucket, name, expire)
|
||||
rawURL, err := m.sign.PresignedPutObject(ctx, m.bucket, name, expire)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -303,6 +367,19 @@ func (m *Minio) ListUploadedParts(ctx context.Context, uploadID string, name str
|
||||
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) {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return "", err
|
||||
@@ -313,17 +390,123 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
||||
reqParams.Set("response-content-type", opt.ContentType)
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
reqParams.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`)
|
||||
reqParams.Set("response-content-disposition", `attachment; filename=`+strconv.Quote(opt.Filename))
|
||||
}
|
||||
}
|
||||
if expire <= 0 {
|
||||
expire = time.Hour * 24 * 365 * 99 // 99 years
|
||||
} else if expire < time.Second {
|
||||
expire = time.Second
|
||||
if opt.Image == nil || (opt.Image.Width < 0 && opt.Image.Height < 0 && opt.Image.Format == "") || (opt.Image.Width > maxImageWidth || opt.Image.Height > maxImageHeight) {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
u, err := m.core.Client.PresignedGetObject(ctx, m.bucket, name, expire, reqParams)
|
||||
fileInfo, err := m.StatObject(ctx, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u.String(), nil
|
||||
if fileInfo.Size > maxImageSize {
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
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"`
|
||||
}
|
||||
@@ -1,15 +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 oss // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss"
|
||||
@@ -36,6 +36,19 @@ const (
|
||||
maxNumSize = 10000
|
||||
)
|
||||
|
||||
const (
|
||||
imagePng = "png"
|
||||
imageJpg = "jpg"
|
||||
imageJpeg = "jpeg"
|
||||
imageGif = "gif"
|
||||
imageWebp = "webp"
|
||||
)
|
||||
|
||||
const (
|
||||
videoSnapshotImagePng = "png"
|
||||
videoSnapshotImageJpg = "jpg"
|
||||
)
|
||||
|
||||
func NewOSS() (s3.Interface, error) {
|
||||
conf := config.Config.Object.Oss
|
||||
if conf.BucketURL == "" {
|
||||
@@ -139,7 +152,7 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
||||
}
|
||||
for i, partNumber := range partNumbers {
|
||||
rawURL := fmt.Sprintf(`%s%s?partNumber=%d&uploadId=%s`, o.bucketURL, name, partNumber, uploadID)
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodPut, rawURL, nil)
|
||||
request, err := http.NewRequest(http.MethodPut, rawURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -150,12 +163,7 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
||||
request.Header.Set(oss.HTTPHeaderHost, request.Host)
|
||||
request.Header.Set(oss.HTTPHeaderDate, now)
|
||||
request.Header.Set(oss.HttpHeaderOssDate, now)
|
||||
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)
|
||||
ossSignHeader(o.bucket.Client.Conn, request, fmt.Sprintf(`/%s/%s?partNumber=%d&uploadId=%s`, o.bucket.BucketName, name, partNumber, uploadID))
|
||||
delete(request.Header, oss.HTTPHeaderDate)
|
||||
result.Parts[i] = s3.SignPart{
|
||||
PartNumber: partNumber,
|
||||
@@ -266,11 +274,36 @@ 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) {
|
||||
var opts []oss.Option
|
||||
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 != "" {
|
||||
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename="`+opt.Filename+`"`))
|
||||
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename=`+strconv.Quote(opt.Filename)))
|
||||
}
|
||||
}
|
||||
if expire <= 0 {
|
||||
|
||||
@@ -1,96 +1,11 @@
|
||||
// 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 (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"hash"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
)
|
||||
|
||||
func (o *OSS) getAdditionalHeaderKeys(req *http.Request) ([]string, map[string]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
|
||||
}
|
||||
//go:linkname ossSignHeader github.com/aliyun/aliyun-oss-go-sdk/oss.(*Conn).signHeader
|
||||
func ossSignHeader(c *oss.Conn, req *http.Request, canonicalizedResource string)
|
||||
|
||||
@@ -1,61 +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 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,9 +116,16 @@ type ListUploadedPartsResult struct {
|
||||
UploadedParts []UploadedPart `xml:"Part"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
Format string `json:"format"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
}
|
||||
|
||||
type AccessURLOption struct {
|
||||
ContentType string `json:"contentType"`
|
||||
Filename string `json:"filename"`
|
||||
Image *Image `json:"image"`
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
|
||||
@@ -1,15 +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 relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
||||
@@ -1,15 +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 unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
@@ -27,10 +27,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
singleGocMsgNum = 5000
|
||||
Msg = "msg"
|
||||
OldestList = 0
|
||||
NewestList = -1
|
||||
singleGocMsgNum = 100
|
||||
singleGocMsgNum5000 = 5000
|
||||
Msg = "msg"
|
||||
OldestList = 0
|
||||
NewestList = -1
|
||||
)
|
||||
|
||||
type MsgDocModel struct {
|
||||
@@ -128,6 +129,7 @@ type MsgDocModelInterface interface {
|
||||
pageNumber int32,
|
||||
showNumber int32,
|
||||
) (msgCount int64, userCount int64, groups []*GroupCount, dateCount map[string]int64, err error)
|
||||
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
|
||||
}
|
||||
|
||||
func (MsgDocModel) TableName() string {
|
||||
@@ -138,6 +140,10 @@ func (MsgDocModel) GetSingleGocMsgNum() int64 {
|
||||
return singleGocMsgNum
|
||||
}
|
||||
|
||||
func (MsgDocModel) GetSingleGocMsgNum5000() int64 {
|
||||
return singleGocMsgNum5000
|
||||
}
|
||||
|
||||
func (m *MsgDocModel) IsFull() bool {
|
||||
return m.Msg[len(m.Msg)-1].Msg != nil
|
||||
}
|
||||
|
||||
@@ -1,15 +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 unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||
@@ -1073,11 +1073,6 @@ func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
for _, msg1 := range msgs {
|
||||
if msg1.IsRead {
|
||||
msg1.Msg.IsRead = true
|
||||
}
|
||||
}
|
||||
return total, msgs, nil
|
||||
}
|
||||
|
||||
@@ -1151,13 +1146,22 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
{"doc_id", 1},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$unwind", bson.M{"path": "$msgs"}},
|
||||
},
|
||||
{
|
||||
{"$sort", bson.M{"msgs.msg.send_time": -1}},
|
||||
},
|
||||
}
|
||||
cursor, err := m.MsgCollection.Aggregate(ctx, pipe)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
var msgsDocs []table.MsgDocModel
|
||||
type docModel struct {
|
||||
DocID string `bson:"doc_id"`
|
||||
Msg *table.MsgInfoModel `bson:"msgs"`
|
||||
}
|
||||
var msgsDocs []docModel
|
||||
err = cursor.All(ctx, &msgsDocs)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@@ -1167,41 +1171,39 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
}
|
||||
msgs := make([]*table.MsgInfoModel, 0)
|
||||
for index := range msgsDocs {
|
||||
for i := range msgsDocs[index].Msg {
|
||||
msg := msgsDocs[index].Msg[i]
|
||||
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)
|
||||
msgInfo := msgsDocs[index].Msg
|
||||
if msgInfo == nil || msgInfo.Msg == nil {
|
||||
continue
|
||||
}
|
||||
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
|
||||
n := int32(len(msgs))
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
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,12 +17,13 @@ package unrelation
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
)
|
||||
|
||||
// prefixes and suffixes.
|
||||
@@ -154,7 +155,7 @@ func (u *UserMongoDriver) RemoveSubscribedListFromUser(ctx context.Context, user
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
// GetAllSubscribeList Get all users subscribed by this user.
|
||||
// GetAllSubscribeList Get all users subscribed by this user
|
||||
func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string) (userIDList []string, err error) {
|
||||
var user unrelation.UserModel
|
||||
cursor := u.userCollection.FindOne(
|
||||
@@ -167,7 +168,7 @@ func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string
|
||||
return user.UserIDList, nil
|
||||
}
|
||||
|
||||
// GetSubscribedList Get the user subscribed by those users.
|
||||
// GetSubscribedList Get the user subscribed by those users
|
||||
func (u *UserMongoDriver) GetSubscribedList(ctx context.Context, userID string) (userIDList []string, err error) {
|
||||
var user unrelation.UserModel
|
||||
cursor := u.userCollection.FindOne(
|
||||
|
||||
@@ -1,15 +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 http // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/http"
|
||||
@@ -1,15 +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 kafka // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka"
|
||||
@@ -1,15 +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 locker // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/locker"
|
||||
@@ -1,15 +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 prome // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
|
||||
@@ -1,15 +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 startrpc // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/startrpc"
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func GetNotificationConversationID(msg *sdkws.MsgData) string {
|
||||
func GetNotificationConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
switch msg.SessionType {
|
||||
case constant.SingleChatType:
|
||||
l := []string{msg.SendID, msg.RecvID}
|
||||
@@ -114,6 +114,30 @@ func GetConversationIDBySessionType(sessionType int, ids ...string) string {
|
||||
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 {
|
||||
return strings.HasPrefix(conversationID, "n_")
|
||||
}
|
||||
|
||||
@@ -1,15 +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 msgprocessor // import "github.com/OpenIMSDK/Open-IM-Server/pkg/msgprocessor"
|
||||
@@ -1,15 +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 rpcclient // import "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
@@ -1,15 +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 "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||
@@ -220,7 +220,13 @@ func (g *GroupNotificationSender) getUsersInfoMap(ctx context.Context, userIDs [
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) error {
|
||||
func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) {
|
||||
defer log.ZDebug(ctx, "return")
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.ZError(ctx, utils.GetFuncName(1)+" failed", err)
|
||||
}
|
||||
}()
|
||||
if opUser == nil {
|
||||
return errs.ErrInternalServer.Wrap("**sdkws.GroupMemberFullInfo is nil")
|
||||
}
|
||||
@@ -260,6 +266,12 @@ func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -267,6 +279,12 @@ func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context,
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -274,6 +292,12 @@ func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context,
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -281,6 +305,12 @@ func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Conte
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -288,6 +318,12 @@ func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx conte
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -355,6 +391,12 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -377,6 +419,12 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -394,6 +442,12 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -401,6 +455,12 @@ func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context,
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -419,12 +479,18 @@ func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context,
|
||||
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips)
|
||||
}
|
||||
|
||||
func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) {
|
||||
group, err := g.getGroupInfo(ctx, req.GroupID)
|
||||
func (g *GroupNotificationSender) MemberEnterNotification(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, req.GroupID, req.FromUserID)
|
||||
user, err := g.getGroupMember(ctx, groupID, entrantUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -433,6 +499,12 @@ func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, r
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -440,6 +512,12 @@ func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -459,6 +537,12 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Conte
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -475,6 +559,12 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -494,6 +584,12 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -513,6 +609,12 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -529,6 +631,12 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Con
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -545,6 +653,12 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context.
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -560,25 +674,6 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c
|
||||
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) {
|
||||
defer log.ZDebug(ctx, "return")
|
||||
defer func() {
|
||||
|
||||
@@ -1,15 +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 statistics // import "github.com/OpenIMSDK/Open-IM-Server/pkg/statistics"
|
||||
+1
-31
@@ -84,37 +84,7 @@ 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.
|
||||
|
||||
## 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
|
||||
Scripts to perform various build, install, analysis, etc operations.
|
||||
|
||||
+18
-3
@@ -17,8 +17,6 @@
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
. $(dirname ${BASH_SOURCE})/lib/init.sh
|
||||
|
||||
trap 'echo "Script interrupted."; exit 1' INT
|
||||
|
||||
# Function for colored echo
|
||||
@@ -28,6 +26,24 @@ function color_echo() {
|
||||
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() {
|
||||
text="$1"
|
||||
delay="$2"
|
||||
@@ -52,7 +68,6 @@ function print_progress() {
|
||||
done
|
||||
printf "]${COLOR_SUFFIX}\n"
|
||||
}
|
||||
|
||||
function openim_logo() {
|
||||
# Set text color to cyan for header and URL
|
||||
echo -e "\033[0;36m"
|
||||
|
||||
@@ -21,8 +21,9 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
|
||||
#Include shell font styles and some basic information
|
||||
source $SCRIPTS_ROOT/lib/init.sh
|
||||
source $SCRIPTS_ROOT/style_info.sh
|
||||
source $SCRIPTS_ROOT/path_info.sh
|
||||
source $SCRIPTS_ROOT/function.sh
|
||||
|
||||
cd $SCRIPTS_ROOT
|
||||
|
||||
|
||||
@@ -19,8 +19,21 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
|
||||
#Include shell font styles and some basic information
|
||||
source $SCRIPTS_ROOT/style_info.sh
|
||||
source $SCRIPTS_ROOT/path_info.sh
|
||||
source $SCRIPTS_ROOT/lib/init.sh
|
||||
source $SCRIPTS_ROOT/function.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"
|
||||
logs_dir="$OPENIM_ROOT/logs"
|
||||
@@ -55,7 +68,43 @@ if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
openim::util::gen_os_arch
|
||||
# Get the current operating system and architecture
|
||||
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
|
||||
BUILD_SUCCESS=true
|
||||
|
||||
@@ -18,8 +18,9 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
|
||||
#Include shell font styles and some basic information
|
||||
source $SCRIPTS_ROOT/lib/init.sh
|
||||
source $SCRIPTS_ROOT/style_info.sh
|
||||
source $SCRIPTS_ROOT/path_info.sh
|
||||
source $SCRIPTS_ROOT/function.sh
|
||||
|
||||
cd $SCRIPTS_ROOT
|
||||
|
||||
@@ -42,7 +43,7 @@ service_port_name=(
|
||||
)
|
||||
for i in ${service_port_name[*]}; do
|
||||
list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}')
|
||||
openim::util::list-to-string $list
|
||||
list_to_string $list
|
||||
for j in ${ports_array}; do
|
||||
port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}')
|
||||
if [[ ${port} -ne ${j} ]]; then
|
||||
|
||||
@@ -1,83 +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.
|
||||
|
||||
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,6 +30,15 @@ need_to_start_server_shell=(
|
||||
${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
|
||||
|
||||
sleep 10
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user