Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix graphql upload #84

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
979 changes: 979 additions & 0 deletions discord-cdn/yarn.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ package resolver

import (
"context"
"io"
"os"
"path"
"fmt"

"github.com/Folody-Team/Shartube/database/comic_chap_model"
"github.com/Folody-Team/Shartube/database/comic_session_model"
Expand Down Expand Up @@ -96,9 +94,7 @@ func (r *mutationResolver) AddImageToChap(ctx context.Context, req []*model.Uplo
if err != nil {
return nil, err
}
comicChapDoc, err := comicChapModel.FindOne(bson.D{
{Key: "_id", Value: chapID},
})
comicChapDoc, err := comicChapModel.FindById(chapID)
if err != nil {
return nil, err
}
Expand All @@ -119,39 +115,34 @@ func (r *mutationResolver) AddImageToChap(ctx context.Context, req []*model.Uplo
if !util.InSlice(allowType, v.File.ContentType) {
return nil, gqlerror.Errorf("file type not allow")
}
// check file size
if v.File.Size > 10*1024*1024 {
// check file size only allow 7MB
if v.File.Size > 7000000 {
return nil, gqlerror.Errorf("file size too large")
}
// save file
FileId := uuid.New().String()
fileName := FileId + "." + v.File.ContentType[6:]
FilePath := path.Join("public/image", fileName)
// open file
file, err := os.Create(FilePath)
if err != nil {
return nil, err
}
// write file
_, err = io.Copy(file, v.File.File)
if err != nil {
return nil, err
}
// close file
err = file.Close()
FileExtension := util.GetFileExtension(v.File.ContentType)
url, err := util.UploadSingleImage(v.File.File, FileExtension)
fmt.Printf("v.File.Filename: %v\n", v.File.Filename)
if err != nil {
return nil, err
}

AllImages = append(AllImages, &model.ImageResult{
ID: FileId,
URL: path.Join("/public/image", fileName),
URL: *url,
})
}

ComicChapObjectId, err := primitive.ObjectIDFromHex(comicChapDoc.ID)
if err != nil {
return nil, err
}
if _, err := comicChapModel.FindOneAndUpdate(bson.M{
"_id": comicChapDoc.ID,
"_id": ComicChapObjectId,
}, bson.M{
"Images": AllImages,
"$set": bson.M{
"Images": AllImages,
},
}); err != nil {
return nil, err
}
Expand Down Expand Up @@ -179,8 +170,12 @@ func (r *mutationResolver) UpdateComicChap(ctx context.Context, chapID string, i
if userID != comicChap.CreatedByID {
return nil, gqlerror.Errorf("Access Denied")
}
ComicChapObjectId, err := primitive.ObjectIDFromHex(chapID)
if err != nil {
return nil, err
}
return comicChapModel.FindOneAndUpdate(bson.M{
"_id": comicChap.ID,
"_id": ComicChapObjectId,
}, input)
}

Expand All @@ -203,7 +198,7 @@ func (r *mutationResolver) DeleteComicChap(ctx context.Context, chapID string) (
if userID != comicChap.CreatedByID {
return nil, gqlerror.Errorf("Access Denied")
}
success, err := deleteUtil.DeleteChap(comicChap.ID, r.Client,true)
success, err := deleteUtil.DeleteChap(comicChap.ID, r.Client, true)
if err != nil {
return nil, err
}
Expand Down
8 changes: 6 additions & 2 deletions server/comic/graphql/resolver/comic.schema.resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/sacOO7/gowebsocket"
"github.com/vektah/gqlparser/v2/gqlerror"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)

// CreatedBy is the resolver for the CreatedBy field.
Expand Down Expand Up @@ -142,9 +143,12 @@ func (r *mutationResolver) UpdateComic(ctx context.Context, comicID string, inpu
Message: "Access Denied",
}
}

ComicObjectId, err := primitive.ObjectIDFromHex(comic.ID)
if err != nil {
return nil, err
}
return comicModel.FindOneAndUpdate(bson.M{
"_id": comic.ID,
"_id": ComicObjectId,
}, input)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,12 @@ func (r *mutationResolver) UpdateComicSession(ctx context.Context, sessionID str
if userID != comicSession.CreatedByID {
return nil, gqlerror.Errorf("Access Denied")
}
ComicSessionObjectId, err := primitive.ObjectIDFromHex(comicSession.ID)
if err != nil {
return nil, err
}
return comicSessionModel.FindOneAndUpdate(bson.M{
"_id": comicSession.ID,
"_id": ComicSessionObjectId,
}, input)
}

Expand Down
10 changes: 10 additions & 0 deletions server/comic/util/GetFileExtensionByContentType.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package util

import "strings"

func GetFileExtension(contentType string) string {
if contentType == "" {
return ""
}
return contentType[strings.LastIndex(contentType, "/")+1:]
}
50 changes: 50 additions & 0 deletions server/comic/util/UploadImage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package util

import (
"bytes"
"encoding/base64"
"encoding/json"
"io"
"net/http"
"os"
)

type UploadImageResponse struct {
Url string `json:"url"`
}

func UploadSingleImage(file io.ReadSeeker, extension string) (*string, error) {
UploadServerUrl := os.Getenv("UploadServer")
if UploadServerUrl == "" {
UploadServerUrl = "http://localhost:3000/upload"
}
// encode file to base64
base64String := base64.StdEncoding.EncodeToString(ReadAll(file))
var jsonStr = []byte(`{"fileBase64":"` + base64String + `", "extension":"` + extension + `"}`)
// send to upload server
req, err := http.NewRequest("POST", UploadServerUrl, bytes.NewBuffer(jsonStr))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// get response
body := UploadImageResponse{}
err = json.NewDecoder(resp.Body).Decode(&body)
if err != nil {
return nil, err
}
return &body.Url, nil
}

func ReadAll(r io.Reader) []byte {
buf := new(bytes.Buffer)
buf.ReadFrom(r)
return buf.Bytes()
}
3 changes: 0 additions & 3 deletions server/comic/util/deleteUtil/comic.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package deleteUtil

import (
"fmt"

"github.com/Folody-Team/Shartube/database/comic_model"
"github.com/Folody-Team/Shartube/database/comic_session_model"
"go.mongodb.org/mongo-driver/mongo"
Expand All @@ -18,7 +16,6 @@ func DeleteComic(id string, client *mongo.Client) (bool, error) {
return false, err
}
ComicData, err := ComicModel.FindById(id)
fmt.Printf("ComicData: %v\n", ComicData)
if err != nil {
return false, err
}
Expand Down
21 changes: 21 additions & 0 deletions server/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ services:
depends_on:
- shartube-ws-server
restart: always
volumes:
- mongoDB:/data/db

shartube-graphql-gateway:
container_name: shartube-graphql-gateway
Expand Down Expand Up @@ -57,6 +59,7 @@ services:
- WS_HOST=shartube-ws-server
- WS_PORT=3012
- UserHost=shartube-user-server
- UploadServer=http://shartube-upload-server:3000/upload
env_file:
- ./comic/.env
restart: always
Expand All @@ -83,5 +86,23 @@ services:
expose:
- 8080

shartube-upload-server:
container_name: shartube-upload-server
networks:
- shartube-net
depends_on:
- shartube-ws-server
build: ./save-service
env_file:
- ./save-service/.env
restart: always
expose:
- 3000
environment:
- CHANNEL_ID=990113063187390465

networks:
shartube-net:

volumes:
mongoDB:
3 changes: 2 additions & 1 deletion server/graphql-gateway/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package-look.json
yarn.lock
node_modules/
node_modules/
dist/
6 changes: 5 additions & 1 deletion server/graphql-gateway/dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
FROM node:gallium-slim as ts-compiler
WORKDIR /home/app

COPY . .
COPY package.json .

RUN yarn install

COPY . .

RUN yarn run build


FROM node:gallium-slim as ts-remover
WORKDIR /home/app

Expand Down
67 changes: 44 additions & 23 deletions server/graphql-gateway/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ApolloServer } from "apollo-server";
import {
ApolloGateway,
IntrospectAndCompose,
RemoteGraphQLDataSource,
} from "@apollo/gateway";
import { ApolloGateway, IntrospectAndCompose } from "@apollo/gateway";
import { ApolloServer } from "apollo-server-express";
import dotenv from "dotenv";
import express from "express";
import http from "http";
import multer from "multer";
import path from "path";
import FileUploadDataSource from "./util/FileUploadDataSource";
import { graphqlUploadExpress } from "./util/graphqlUploadExpress";

dotenv.config({
path: path.join(__dirname, "./.env"),
});
Expand All @@ -27,28 +29,47 @@ const gateway = new ApolloGateway({
}),
buildService(definition) {
const { url, name } = definition;
return new RemoteGraphQLDataSource({
return new FileUploadDataSource({
url,
willSendRequest({ request, context }) {
// pass the headers to the remote server
request.http?.headers.set("Authorization", context.token || "");
willSendRequest(options) {
options.request.http?.headers.set(
"Authorization",
options.context.token || ""
);
},
});
},
});
async function startServer() {
const app = express();
const HttpServer = http.createServer(app);
const server = new ApolloServer({
gateway,
context: ({ req, res }) => {
return { req, res, token: req.headers.authorization };
},
cache: "bounded",
plugins: [],
});
await server.start();
app.use(multer().any());
app.use(graphqlUploadExpress());

const server = new ApolloServer({
gateway,
context: ({ req, res }) => {
return { req, res, token: req.headers.authorization };
},
});
server.applyMiddleware({ app });

server
.listen({ port })
.then(({ url }) => {
console.log(`🚀 Gateway ready at ${url}`);
HttpServer.listen(port, () => {
console.log(
`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`
);
})
.catch((err) => {
console.error(err);
});
.on("error", (err) => {
console.error(err);
})
.on("close", () => {
console.log("Server closed");
})
.on("listening", () => {
console.log("Server listening");
});
}
startServer();
Loading