make readmes translateable
Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
@@ -8,6 +8,9 @@ import (
|
|||||||
"github.com/leonelquinteros/gotext"
|
"github.com/leonelquinteros/gotext"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Template marks a string as translatable
|
||||||
|
func Template(s string) string { return s }
|
||||||
|
|
||||||
// Translator is able to translate strings
|
// Translator is able to translate strings
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
fs fs.FS
|
fs fs.FS
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
SHELL := bash
|
SHELL := bash
|
||||||
NAME := graph
|
NAME := graph
|
||||||
|
|
||||||
|
# Where to write the files generated by this makefile.
|
||||||
|
OUTPUT_DIR = ./pkg/service/v0/l10n
|
||||||
|
TEMPLATE_FILE = ./pkg/service/v0/l10n/graph.pot
|
||||||
|
|
||||||
include ../../.make/recursion.mk
|
include ../../.make/recursion.mk
|
||||||
|
|
||||||
############ tooling ############
|
############ tooling ############
|
||||||
@@ -30,6 +34,27 @@ ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this
|
|||||||
.PHONY: ci-node-generate
|
.PHONY: ci-node-generate
|
||||||
ci-node-generate:
|
ci-node-generate:
|
||||||
|
|
||||||
|
############ translations ########
|
||||||
|
.PHONY: l10n-pull
|
||||||
|
l10n-pull:
|
||||||
|
cd $(OUTPUT_DIR) && tx pull --all --force --skip --minimum-perc=75
|
||||||
|
|
||||||
|
.PHONY: l10n-push
|
||||||
|
l10n-push:
|
||||||
|
cd $(OUTPUT_DIR) && tx push -s --skip
|
||||||
|
|
||||||
|
.PHONY: l10n-read
|
||||||
|
l10n-read: $(GO_XGETTEXT)
|
||||||
|
go-xgettext -o $(OUTPUT_DIR)/graph.pot --keyword=l10n.Template --add-comments -s pkg/service/v0/spacetemplates.go
|
||||||
|
|
||||||
|
.PHONY: l10n-write
|
||||||
|
l10n-write:
|
||||||
|
|
||||||
|
.PHONY: l10n-clean
|
||||||
|
l10n-clean:
|
||||||
|
rm -f $(TEMPLATE_FILE);
|
||||||
|
|
||||||
|
|
||||||
############ licenses ############
|
############ licenses ############
|
||||||
.PHONY: ci-node-check-licenses
|
.PHONY: ci-node-check-licenses
|
||||||
ci-node-check-licenses:
|
ci-node-check-licenses:
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"embed"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -36,11 +35,6 @@ const (
|
|||||||
displayNameAttr = "displayName"
|
displayNameAttr = "displayName"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
//go:embed spacetemplate/*
|
|
||||||
_spaceTemplateFS embed.FS
|
|
||||||
)
|
|
||||||
|
|
||||||
// Service defines the service handlers.
|
// Service defines the service handlers.
|
||||||
type Service interface {
|
type Service interface {
|
||||||
ServeHTTP(http.ResponseWriter, *http.Request)
|
ServeHTTP(http.ResponseWriter, *http.Request)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Here you can add a description for this Space.
|
|
||||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@@ -0,0 +1,113 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||||
|
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||||
|
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
|
v1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/utils"
|
||||||
|
"github.com/owncloud/ocis/v2/ocis-pkg/l10n"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed spacetemplate/*
|
||||||
|
_spaceTemplateFS embed.FS
|
||||||
|
|
||||||
|
//go:embed l10n/locale
|
||||||
|
_localeFS embed.FS
|
||||||
|
|
||||||
|
_imagepath = "spacetemplate/image.png"
|
||||||
|
|
||||||
|
_readmeText = l10n.Template("Here you can add a description for this Space.")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (g Graph) applySpaceTemplate(ctx context.Context, gwc gateway.GatewayAPIClient, root *storageprovider.ResourceId, template string) error {
|
||||||
|
switch template {
|
||||||
|
default:
|
||||||
|
fallthrough
|
||||||
|
case "none":
|
||||||
|
return nil
|
||||||
|
case "default":
|
||||||
|
return g.applyDefaultTemplate(ctx, gwc, root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Graph) applyDefaultTemplate(ctx context.Context, gwc gateway.GatewayAPIClient, root *storageprovider.ResourceId) error {
|
||||||
|
mdc := metadata.NewCS3(g.config.Reva.Address, g.config.Spaces.StorageUsersAddress)
|
||||||
|
mdc.SpaceRoot = root
|
||||||
|
|
||||||
|
var opaque *v1beta1.Opaque
|
||||||
|
|
||||||
|
// create .space folder
|
||||||
|
if err := mdc.MakeDirIfNotExist(ctx, ".space"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// upload space image
|
||||||
|
iid, err := imageUpload(ctx, mdc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opaque = utils.AppendPlainToOpaque(opaque, SpaceImageSpecialFolderName, iid)
|
||||||
|
|
||||||
|
// upload readme.md
|
||||||
|
rid, err := readmeUpload(ctx, mdc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opaque = utils.AppendPlainToOpaque(opaque, ReadmeSpecialFolderName, rid)
|
||||||
|
|
||||||
|
// update space
|
||||||
|
resp, err := gwc.UpdateStorageSpace(ctx, &storageprovider.UpdateStorageSpaceRequest{
|
||||||
|
StorageSpace: &storageprovider.StorageSpace{
|
||||||
|
Id: &storageprovider.StorageSpaceId{
|
||||||
|
OpaqueId: storagespace.FormatResourceID(*root),
|
||||||
|
},
|
||||||
|
Root: root,
|
||||||
|
Opaque: opaque,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
case resp.GetStatus().GetCode() != rpc.Code_CODE_OK:
|
||||||
|
return fmt.Errorf("could not update storage space: %s", resp.GetStatus().GetMessage())
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func imageUpload(ctx context.Context, mdc *metadata.CS3) (string, error) {
|
||||||
|
b, err := fs.ReadFile(_spaceTemplateFS, _imagepath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
res, err := mdc.Upload(ctx, metadata.UploadRequest{
|
||||||
|
Path: filepath.Join(".space", filepath.Base(_imagepath)),
|
||||||
|
Content: b,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return res.FileID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readmeUpload(ctx context.Context, mdc *metadata.CS3) (string, error) {
|
||||||
|
t := l10n.NewTranslatorFromCommonConfig("en", "graph", "", _localeFS, "l10n/locale")
|
||||||
|
res, err := mdc.Upload(ctx, metadata.UploadRequest{
|
||||||
|
Path: filepath.Join(".space", "readme.md"),
|
||||||
|
Content: []byte(t.Translate(_readmeText, "en_GB")),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return res.FileID, nil
|
||||||
|
}
|
||||||
@@ -3,22 +3,14 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
|
|
||||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||||
cs3User "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
cs3User "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
|
||||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
v1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
|
||||||
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
|
|
||||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||||
"github.com/cs3org/reva/v2/pkg/utils"
|
"github.com/cs3org/reva/v2/pkg/utils"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
@@ -445,99 +437,3 @@ func cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, logger *log.Lo
|
|||||||
|
|
||||||
return permission, nil
|
return permission, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Graph) applySpaceTemplate(ctx context.Context, gwc gateway.GatewayAPIClient, root *storageprovider.ResourceId, template string) error {
|
|
||||||
var fsys fs.ReadDirFS
|
|
||||||
|
|
||||||
switch template {
|
|
||||||
default:
|
|
||||||
fallthrough
|
|
||||||
case "none":
|
|
||||||
return nil
|
|
||||||
case "default":
|
|
||||||
f, err := fs.Sub(_spaceTemplateFS, "spacetemplate")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fsys = f.(fs.ReadDirFS)
|
|
||||||
}
|
|
||||||
|
|
||||||
mdc := metadata.NewCS3(g.config.Reva.Address, g.config.Spaces.StorageUsersAddress)
|
|
||||||
mdc.SpaceRoot = root
|
|
||||||
|
|
||||||
opaque, err := uploadFolder(ctx, mdc, ".", "", nil, fsys)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := gwc.UpdateStorageSpace(ctx, &storageprovider.UpdateStorageSpaceRequest{
|
|
||||||
StorageSpace: &storageprovider.StorageSpace{
|
|
||||||
Id: &storageprovider.StorageSpaceId{
|
|
||||||
OpaqueId: storagespace.FormatResourceID(*root),
|
|
||||||
},
|
|
||||||
Root: root,
|
|
||||||
Opaque: opaque,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
switch {
|
|
||||||
case err != nil:
|
|
||||||
return err
|
|
||||||
case resp.GetStatus().GetCode() != rpc.Code_CODE_OK:
|
|
||||||
return fmt.Errorf("could not update storage space: %s", resp.GetStatus().GetMessage())
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func uploadFolder(ctx context.Context, mdc *metadata.CS3, pathOnDisc, pathOnSpace string, opaque *v1beta1.Opaque, fsys fs.ReadDirFS) (*v1beta1.Opaque, error) {
|
|
||||||
entries, err := fsys.ReadDir(pathOnDisc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entry := range entries {
|
|
||||||
opaque, err = uploadEntry(ctx, mdc, pathOnDisc, pathOnSpace, opaque, fsys, entry)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return opaque, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func uploadEntry(ctx context.Context, mdc *metadata.CS3, pathOnDisc, pathOnSpace string, opaque *v1beta1.Opaque, fsys fs.ReadDirFS, entry os.DirEntry) (*v1beta1.Opaque, error) {
|
|
||||||
spacePath := filepath.Join(pathOnSpace, entry.Name())
|
|
||||||
discPath := filepath.Join(pathOnDisc, entry.Name())
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case entry.IsDir():
|
|
||||||
err := mdc.MakeDirIfNotExist(ctx, spacePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return uploadFolder(ctx, mdc, discPath, spacePath, opaque, fsys)
|
|
||||||
default:
|
|
||||||
b, err := fs.ReadFile(fsys, discPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := mdc.Upload(ctx, metadata.UploadRequest{
|
|
||||||
Path: spacePath,
|
|
||||||
Content: b,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
identifier := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
|
|
||||||
for _, special := range []string{ReadmeSpecialFolderName, SpaceImageSpecialFolderName} {
|
|
||||||
if special == identifier {
|
|
||||||
opaque = utils.AppendPlainToOpaque(opaque, identifier, res.FileID)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return opaque, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user