Skip to content

Commit f4f7656

Browse files
committed
v1.0.0 is here.
1 parent 4465fd9 commit f4f7656

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+5989
-1417
lines changed

.github/workflows/build.yml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: build
2+
3+
on:
4+
push:
5+
tags:
6+
- "v[0-9].[0-9]+.[0-9]+"
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
14+
- name: Variables
15+
run: |
16+
echo "REGISTRY=registry.cn-beijing.aliyuncs.com" >> $GITHUB_ENV
17+
echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
18+
19+
- name: Build server image
20+
run: |
21+
IMAGE=${{ env.REGISTRY }}/llaoj/gcopy-server:${{ env.GIT_TAG }}
22+
docker build -t $IMAGE -f build/server/Dockerfile .
23+
docker login -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ env.REGISTRY }}
24+
docker push $IMAGE
25+
26+
- name: Build frontend image
27+
run: |
28+
IMAGE=${{ env.REGISTRY }}/llaoj/gcopy-frontend:${{ env.GIT_TAG }}
29+
docker build -t $IMAGE -f build/frontend/Dockerfile .
30+
docker login -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ env.REGISTRY }}
31+
docker push $IMAGE

.github/workflows/release.yml

-34
Original file line numberDiff line numberDiff line change
@@ -1,35 +1 @@
1-
# .github/workflows/release.yml
2-
name: goreleaser
31

4-
on:
5-
push:
6-
# run only against tags
7-
tags:
8-
- "*"
9-
10-
permissions:
11-
contents: write
12-
# packages: write
13-
# issues: write
14-
15-
jobs:
16-
goreleaser:
17-
runs-on: ubuntu-latest
18-
steps:
19-
- uses: actions/checkout@v3
20-
with:
21-
fetch-depth: 0
22-
- run: git fetch --force --tags
23-
- uses: actions/setup-go@v4
24-
with:
25-
go-version: stable
26-
# More assembly might be required: Docker logins, GPG, etc.
27-
# It all depends on your needs.
28-
- run: docker login -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} registry.cn-beijing.aliyuncs.com
29-
- uses: goreleaser/goreleaser-action@v5
30-
with:
31-
distribution: goreleaser
32-
version: latest
33-
args: release --clean
34-
env:
35-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.goreleaser.yaml

-56
This file was deleted.

Makefile

-8
This file was deleted.

README.md

+27-56
Original file line numberDiff line numberDiff line change
@@ -5,85 +5,56 @@
55

66
---
77

8-
[中文文档](docs/intro.md)
8+
[中文文档](docs/zh-CN/README.md)
99

10-
A clipboard synchronization tool that powered by Golang.
11-
12-
This is a tool to synchronize clipboards between different operating systems.
10+
A clipboard synchronization service between different operating systems.
1311

1412
`Text`, `Screenshot` & `File` are supported.
1513

16-
17-
![](docs/gcopy-usage.gif)
14+
GCopy values your data privacy, it does not persistently store your data; it is all kept in memory.
1815

1916
## Usage
2017

21-
GCopy has two modes, the first mode is more easy to use:
22-
23-
### server&client <> clients
24-
25-
This mode requires one device to simultaneously act as both the server and client. These devices must be on the same LAN and should be able to access each other.
26-
27-
If you have two device, they are in the same LAN.
28-
29-
On first device:
30-
31-
```
32-
/path/to/gcopy --role=server,client
33-
```
34-
35-
On the other devices:
18+
![screanshot](docs/screenshot.png)
3619

37-
```
38-
/path/to/gcopy --role=client --token=<output-token> --server=<server-ip>:3375
39-
```
20+
Steps:
4021

41-
![](docs/mode1.png)
22+
1. Open the website [https://gcopy.rutron.net](https://gcopy.rutron.net) on two devices, A and B, using a browser and log in with the same email.
23+
2. On device A, copy (e.g., `Ctrl+C`) and then click the button on the right side of the page.
24+
3. Switch to device B, click the button again, and the data will be synchronized. Now, go ahead and paste (`Ctrl+V`)!
4225

43-
### clients <> server <> clients
26+
## Background
4427

45-
In this mode, it is more flexible but requires a minimum of three devices, with one of them serving as the server. Clients do not need to be able to access each other, but it is required that clients can access the server.
28+
In our daily office routines, especially for software developers, we often find ourselves working with more than two computers.
4629

47-
On server:
30+
If you need to operate both a Windows PC and a MacOS device simultaneously, exchanging information between these two devices becomes quite troublesome. For various reasons, I couldn't find a good tool to share the clipboard between devices with different operating systems. When I copy a piece of text, pasting it on another computer usually proves to be quite challenging.
4831

49-
```
50-
$ /path/to/gcopy --role=server
32+
Current tools typically only support text, excluding screenshots and files. Additionally, they often require devices to be on the same local network and accessible to each other, not to mention some of them come with a fee.
5133

52-
__ _ ___ ___ _ __ _ _
53-
/ _ |/ __/ _ \| '_ \| | | |
54-
| (_| | (_| (_) | |_) | |_| |
55-
\__, |\___\___/| .__/ \__, |
56-
__/ | | | __/ |
57-
|___/ |_| |___/
34+
This is not ideal!
5835

36+
Therefore, I developed GCopy to address these issues. Currently, you can share the clipboard between Windows and MacOS computers, supporting text, screenshots, and files. It has low network requirements, allowing different devices to be on the same local network or not.
5937

60-
The Server has started, start the clients:
61-
/path/to/gcopy --role=client --server=192.168.137.146:3375 --token=helloworld
62-
...
63-
```
64-
65-
The Clients' command will be printed in the outputs. Run them on the Clients.
66-
67-
![](docs/mode2.png)
68-
69-
70-
## Read more
71-
72-
- [The work mechanism](docs/mechanism.md)
38+
Initially, I used Git as the backend storage and utilized scripts like PowerShell and osascript to synchronize the clipboard between different devices. However, due to its dependence on Git, it was not user-friendly for non-technical users. So, I replaced Git with Golang to serve as a data transfer service between different devices, but it still required users to download and run the GCopy client on their devices, creating a barrier to entry. That led to the development of the current version, 'GCopy v1.0', as a web service. You can directly access the website [https://gcopy.rutron.net](https://gcopy.rutron.net) without worrying about data leakage.
7339

7440
## Limitations
7541

76-
- Only tested on windows 10 & macOS Monterey
77-
- It can only synchronize one file at a time
42+
- Due to browser limitations, reading and setting files directly in the clipboard are not supported. Therefore, file synchronization is achieved through uploading and downloading, ensuring a smooth user experience.
43+
- At any given time, only one file can be synchronized.
44+
- Due to limited server memory, the size of the files you synchronize must not exceed 10 MB.
7845

7946
## Community
8047

81-
You have questions, need support or just want to talk about GCopy?
48+
Welcome to join GCopy, whether you're a user or a contributor!
49+
50+
If you have any questions or need support related to GCopy, you can contact me through the following channels:
51+
52+
### Email
8253

83-
Here are ways to get in touch with the community:
54+
Feel free to reach out to my personal email: [email protected]. If you have any questions, you can drop me a message.
8455

85-
56+
### Discord
8657

87-
Wechat:
58+
Here, some interesting discussions are happening.
8859

89-
<img width="200" src="docs/wechat-lllaoj.png">
60+
Server link: https://discord.gg/pyTrT3aAaC

build/Dockerfile

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
From alpine
2-
WORKDIR /app/
3-
COPY gcopy .
4-
COPY internal/server/templates/index.tmpl internal/server/templates/index.tmpl
5-
ENTRYPOINT ["/app/gcopy"]
1+

build/frontend/Dockerfile

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM node:18-alpine AS base
2+
3+
FROM base AS deps
4+
RUN apk add --no-cache libc6-compat
5+
WORKDIR /app
6+
COPY frontend/package.json frontend/package-lock.json* ./
7+
RUN npm config delete proxy
8+
RUN npm ci
9+
10+
FROM base AS builder
11+
WORKDIR /app
12+
COPY --from=deps /app/node_modules ./node_modules
13+
COPY frontend/. .
14+
COPY frontend/.env.sample .env.production
15+
RUN npm run build
16+
17+
FROM base AS runner
18+
WORKDIR /app
19+
ENV NODE_ENV=production
20+
RUN addgroup -g 1001 -S nodejs
21+
RUN adduser -S nextjs -u 1001
22+
COPY --from=builder /app/public ./public
23+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
24+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
25+
USER nextjs
26+
EXPOSE 3375
27+
ENV PORT 3375
28+
ENV HOSTNAME=0.0.0.0
29+
CMD ["node", "server.js"]

build/server/Dockerfile

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM golang
2+
3+
WORKDIR /app
4+
COPY . .
5+
6+
RUN go mod download
7+
RUN go mod verify
8+
9+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /gcopy ./cmd
10+
11+
From alpine
12+
13+
WORKDIR /
14+
COPY --from=0 /gcopy .
15+
16+
EXPOSE 3375
17+
18+
ENTRYPOINT ["/gcopy"]

cmd/gcopy.go

+1-22
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ package main
33
import (
44
"fmt"
55
"os"
6-
"strings"
7-
"sync"
8-
"time"
96

10-
"github.com/llaoj/gcopy/internal/client"
117
"github.com/llaoj/gcopy/internal/config"
128
"github.com/llaoj/gcopy/internal/server"
139
"github.com/sirupsen/logrus"
@@ -33,22 +29,5 @@ func main() {
3329
log.SetLevel(logrus.InfoLevel)
3430
}
3531
log.Debugf("config: %+v", cfg)
36-
37-
var wg sync.WaitGroup
38-
if strings.Contains(cfg.Role, "server") {
39-
wg.Add(1)
40-
go server.NewServer(log).Run(&wg)
41-
time.Sleep(time.Second)
42-
}
43-
44-
if strings.Contains(cfg.Role, "client") {
45-
cli, err := client.NewClient(log)
46-
if err != nil {
47-
log.Fatal(err)
48-
}
49-
wg.Add(1)
50-
go cli.Run(&wg)
51-
}
52-
53-
wg.Wait()
32+
server.NewServer(log).Run()
5433
}

deploy/docker-compose.yml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: '3.8'
2+
services:
3+
gcopy-server:
4+
container_name: gcopy-server
5+
image: registry.cn-beijing.aliyuncs.com/llaoj/gcopy-server:v1.0.0
6+
restart: always
7+
8+
gcopy-frontend:
9+
container_name: gcopy-frontend
10+
image: registry.cn-beijing.aliyuncs.com/llaoj/gcopy-frontend:v1.0.0
11+
restart: always
12+
ports:
13+
- "3375:3375"
14+
volumes:
15+
- ./frontend/.env.production:/app/.env.production
16+
depends_on:
17+
- gcopy-server
18+

deploy/nginx-example.conf

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
upstream upstream_gcopy {
2+
server 172.10.10.10:3375 weight=1 max_fails=3 fail_timeout=30s;
3+
}
4+
5+
server {
6+
listen 80;
7+
server_name gcopy.example.com;
8+
return 301 https://$host$request_uri;
9+
}
10+
11+
server {
12+
listen 443 ssl http2;
13+
listen [::]:443 ssl http2;
14+
server_name gcopy.example.com;
15+
16+
client_max_body_size 0;
17+
18+
ssl_certificate /path/to/cert.pem;
19+
ssl_certificate_key /path/to/key.pem;
20+
ssl_session_timeout 5m;
21+
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
22+
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
23+
ssl_prefer_server_ciphers on;
24+
25+
proxy_connect_timeout 180;
26+
proxy_send_timeout 180;
27+
proxy_read_timeout 180;
28+
proxy_set_header Host $host;
29+
proxy_set_header X-Real-IP $remote_addr;
30+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
31+
proxy_set_header X-Forwarded-Proto $scheme;
32+
33+
location / {
34+
proxy_pass http://upstream_gcopy;
35+
}
36+
}

docs/client.png

-99.9 KB
Binary file not shown.

docs/clipboard-struct.png

-27.1 KB
Binary file not shown.

docs/gcopy-usage.gif

-262 KB
Binary file not shown.

0 commit comments

Comments
 (0)