Skip to content

Commit

Permalink
review fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tomokazu tantaka committed Sep 25, 2024
1 parent 657b2d0 commit ed93458
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 103 deletions.
92 changes: 31 additions & 61 deletions server/internal/adapter/gql/resolver_mutation_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"time"

"github.com/oklog/ulid"
"github.com/reearth/reearth/server/internal/adapter/gql/gqlmodel"
"github.com/reearth/reearth/server/internal/usecase/interfaces"
"github.com/reearth/reearth/server/pkg/file"
"github.com/reearth/reearth/server/pkg/id"
"github.com/reearth/reearth/server/pkg/visualizer"
"github.com/reearth/reearthx/account/accountdomain"
"github.com/spf13/afero"
"golang.org/x/exp/rand"
)

Expand Down Expand Up @@ -119,19 +120,20 @@ func (r *mutationResolver) DeleteProject(ctx context.Context, input gqlmodel.Del
}

func (r *mutationResolver) ExportProject(ctx context.Context, input gqlmodel.ExportProjectInput) (*gqlmodel.ExportProjectPayload, error) {
fs := afero.NewOsFs()

// create zip file instance
t := time.Now().UTC()
entropy := ulid.Monotonic(rand.New(rand.NewSource(uint64(t.UnixNano()))), 0)
name := ulid.MustNew(ulid.Timestamp(t), entropy)
zipFile, err := os.Create(fmt.Sprintf("%s.reearth", name.String()))
zipFile, err := fs.Create(fmt.Sprintf("%s.reearth", name.String()))
if err != nil {
return nil, err
}
defer func() {
if cerr := zipFile.Close(); cerr != nil && err == nil {
err = cerr
}
// delete after saving to storage
if cerr := os.Remove(zipFile.Name()); cerr != nil && err == nil {
err = cerr
}
Expand All @@ -153,14 +155,12 @@ func (r *mutationResolver) ExportProject(ctx context.Context, input gqlmodel.Exp
return nil, err
}

// export scene
sce, data, err := usecases(ctx).Scene.ExportScene(ctx, prj, zipWriter)
if err != nil {
return nil, err
}
data["project"] = gqlmodel.ToProject(prj)

// export plugins
plgs, err := usecases(ctx).Plugin.ExportPlugins(ctx, sce, zipWriter)
if err != nil {
return nil, err
Expand All @@ -179,75 +179,45 @@ func (r *mutationResolver) ExportProject(ctx context.Context, input gqlmodel.Exp

func (r *mutationResolver) ImportProject(ctx context.Context, input gqlmodel.ImportProjectInput) (*gqlmodel.ImportProjectPayload, error) {

fileBytes, err := io.ReadAll(input.File.File)
data, assets, plugins, err := file.UncompressExportZip(input.File.File)
if err != nil {
return nil, err
}

reader, err := zip.NewReader(bytes.NewReader(fileBytes), int64(len(fileBytes)))
if err != nil {
return nil, err
}

var fileContent []byte
// Assets file import
changedFileName := make(map[string]string)
for fileName, file := range assets {
parts1 := strings.Split(fileName, "/")
beforeName := parts1[0]

for _, file := range reader.File {

if strings.HasPrefix(file.Name, "assets/") {
// Assets file import

trimmedName := strings.TrimPrefix(file.Name, "assets/")
parts1 := strings.Split(trimmedName, "/")
beforeName := parts1[0]
url, _, err := usecases(ctx).Asset.UploadAssetFile(ctx, beforeName, file)
if err != nil {
return nil, err
}
parts2 := strings.Split(url.Path, "/")
afterName := parts2[len(parts2)-1]

changedFileName[beforeName] = afterName

} else if strings.HasPrefix(file.Name, "plugins/") {
// Plugin file import

trimmedName := strings.TrimPrefix(file.Name, "plugins/")
parts := strings.Split(trimmedName, "/")
pid, err := id.PluginIDFrom(parts[0])
if err != nil {
return nil, err
}
if err := usecases(ctx).Plugin.ImporPluginFile(ctx, pid, parts[1], file); err != nil {
return nil, err
}
} else if file.Name == "project.json" {
// Data import

rc, err := file.Open()
if err != nil {
return nil, err
}
defer func(rc io.ReadCloser) {
if cerr := rc.Close(); cerr != nil {
fmt.Printf("Error closing file: %v\n", cerr)
}
}(rc)
fileContent, err = io.ReadAll(rc)
if err != nil {
return nil, err
}

url, _, err := usecases(ctx).Asset.UploadAssetFile(ctx, beforeName, file)
if err != nil {
return nil, err
}
parts2 := strings.Split(url.Path, "/")
afterName := parts2[len(parts2)-1]

changedFileName[beforeName] = afterName
}

// Plugin file import
for fileName, file := range plugins {
parts := strings.Split(fileName, "/")
pid, err := id.PluginIDFrom(parts[0])
if err != nil {
return nil, err
}
if err := usecases(ctx).Plugin.ImporPluginFile(ctx, pid, parts[1], file); err != nil {
return nil, err
}
}

for beforeName, afterName := range changedFileName {
fileContent = bytes.Replace(fileContent, []byte(beforeName), []byte(afterName), -1)
data = bytes.Replace(data, []byte(beforeName), []byte(afterName), -1)
}

var jsonData map[string]interface{}
if err := json.Unmarshal(fileContent, &jsonData); err != nil {
if err := json.Unmarshal(data, &jsonData); err != nil {
return nil, err
}

Expand All @@ -269,7 +239,7 @@ func (r *mutationResolver) ImportProject(ctx context.Context, input gqlmodel.Imp
}

sceneData, _ := jsonData["scene"].(map[string]interface{})
sce, err := usecases(ctx).Scene.ImportScene(ctx, prj, sceneData)
sce, err := usecases(ctx).Scene.ImportScene(ctx, prj, plgs, sceneData)
if err != nil {
return nil, err
}
Expand Down
11 changes: 8 additions & 3 deletions server/internal/infrastructure/fs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,18 @@ func (f *fileRepo) ReadExportProjectZip(ctx context.Context, filename string) (i
return f.read(ctx, filepath.Join(exportDir, sanitize.Path(filename)))
}

func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile *os.File) error {
_, err := f.upload(ctx, path.Join(exportDir, zipFile.Name()), zipFile)
func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile afero.File) error {

file, ok := zipFile.(*os.File)
if !ok {
return errors.New("invalid file type: expected *os.File")
}
_, err := f.upload(ctx, path.Join(exportDir, sanitize.Path(file.Name())), file)
return err
}

func (f *fileRepo) RemoveExportProjectZip(ctx context.Context, filename string) error {
return f.delete(ctx, filepath.Join(exportDir, filename))
return f.delete(ctx, filepath.Join(exportDir, sanitize.Path(filename)))
}

// helpers
Expand Down
4 changes: 2 additions & 2 deletions server/internal/infrastructure/gcs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"io"
"net/url"
"os"
"path"
"strings"

Expand All @@ -17,6 +16,7 @@ import (
"github.com/reearth/reearth/server/pkg/id"
"github.com/reearth/reearthx/log"
"github.com/reearth/reearthx/rerror"
"github.com/spf13/afero"
"google.golang.org/api/iterator"
)

Expand Down Expand Up @@ -213,7 +213,7 @@ func (f *fileRepo) ReadExportProjectZip(ctx context.Context, name string) (io.Re
return f.read(ctx, path.Join(gcsExportBasePath, sn))
}

func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile *os.File) error {
func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile afero.File) error {
_, err := f.upload(ctx, path.Join(gcsExportBasePath, zipFile.Name()), zipFile)
return err
}
Expand Down
10 changes: 6 additions & 4 deletions server/internal/infrastructure/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"io"
"net/url"
"os"
"path"
"strings"

Expand All @@ -22,6 +21,7 @@ import (
"github.com/reearth/reearthx/log"
"github.com/reearth/reearthx/rerror"
"github.com/samber/lo"
"github.com/spf13/afero"
)

const (
Expand Down Expand Up @@ -222,13 +222,15 @@ func (f *fileRepo) ReadExportProjectZip(ctx context.Context, name string) (io.Re
return f.read(ctx, path.Join(exportBasePath, sn))
}

func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile *os.File) error {
_, err := f.upload(ctx, path.Join(exportBasePath, zipFile.Name()), zipFile)
func (f *fileRepo) UploadExportProjectZip(ctx context.Context, zipFile afero.File) error {
sanitizedName := sanitize.Path(zipFile.Name())
_, err := f.upload(ctx, path.Join(exportBasePath, sanitizedName), zipFile)
return err
}

func (f *fileRepo) RemoveExportProjectZip(ctx context.Context, filename string) error {
return f.delete(ctx, path.Join(exportBasePath, filename))
sanitizedFilename := sanitize.Path(filename)
return f.delete(ctx, path.Join(exportBasePath, sanitizedFilename))
}

// helpers
Expand Down
4 changes: 2 additions & 2 deletions server/internal/usecase/gateway/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"errors"
"io"
"net/url"
"os"

"github.com/reearth/reearth/server/pkg/file"
"github.com/reearth/reearth/server/pkg/id"
"github.com/spf13/afero"
)

var (
Expand Down Expand Up @@ -38,6 +38,6 @@ type File interface {
RemoveStory(context.Context, string) error

ReadExportProjectZip(context.Context, string) (io.ReadCloser, error)
UploadExportProjectZip(context.Context, *os.File) error
UploadExportProjectZip(context.Context, afero.File) error
RemoveExportProjectZip(context.Context, string) error
}
25 changes: 13 additions & 12 deletions server/internal/usecase/interactor/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
"os"
"strings"
"time"

Expand All @@ -26,6 +25,7 @@ import (
"github.com/reearth/reearthx/account/accountusecase/accountrepo"
"github.com/reearth/reearthx/rerror"
"github.com/reearth/reearthx/usecasex"
"github.com/spf13/afero"
)

type Project struct {
Expand Down Expand Up @@ -511,6 +511,11 @@ func (i *Project) ExportProject(ctx context.Context, projectID id.ProjectID, zip
if err != nil {
return nil, err
}
defer func() {
if cerr := stream.Close(); cerr != nil {
fmt.Printf("Error closing file: %v\n", cerr)
}
}()
zipEntryPath := fmt.Sprintf("assets/%s", trimmedName)
zipEntry, err := zipWriter.Create(zipEntryPath)
if err != nil {
Expand All @@ -521,15 +526,12 @@ func (i *Project) ExportProject(ctx context.Context, projectID id.ProjectID, zip
_ = stream.Close()
return nil, err
}
if err := stream.Close(); err != nil {
return nil, err
}
}

return prj, nil
}

func (i *Project) UploadExportProjectZip(ctx context.Context, zipWriter *zip.Writer, zipFile *os.File, data map[string]interface{}, prj *project.Project) error {
func (i *Project) UploadExportProjectZip(ctx context.Context, zipWriter *zip.Writer, zipFile afero.File, data map[string]interface{}, prj *project.Project) error {
fileWriter, err := zipWriter.Create("project.json")
if err != nil {
return err
Expand All @@ -546,15 +548,14 @@ func (i *Project) UploadExportProjectZip(ctx context.Context, zipWriter *zip.Wri
return err
}

// flush once
if err := zipFile.Close(); err != nil {
if _, err := zipFile.Seek(0, 0); err != nil {
return err
}
zipFile, err = os.Open(zipFile.Name())
if err != nil {
return err
}

defer func() {
if err := zipFile.Close(); err != nil {
fmt.Println("Failed to close zip file:", err)
}
}()
if err := i.file.UploadExportProjectZip(ctx, zipFile); err != nil {
return err
}
Expand Down
Loading

0 comments on commit ed93458

Please sign in to comment.