aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tews <michael@tews.dev>2026-04-01 16:24:36 +0200
committerMichael Tews <michael@tews.dev>2026-04-01 16:27:56 +0200
commit5cf539d550bcb99b892e9a6397ce278f1fa37c98 (patch)
tree62fd8913d73834b5ac26dd6b7f0f6823d7e02cbf
parent2de63efebdfbb07261f16817ea79df398d23cc7e (diff)
refactor: move filename encoding/decoding to API boundaries
-rw-r--r--backend/studip/fs.go20
-rw-r--r--backend/studip/requests.go106
2 files changed, 77 insertions, 49 deletions
diff --git a/backend/studip/fs.go b/backend/studip/fs.go
index 32ed19a..6c44085 100644
--- a/backend/studip/fs.go
+++ b/backend/studip/fs.go
@@ -636,7 +636,7 @@ func (f *Fs) FillFolderNode(
childrenNode.Parent = folderNode
childrenNode.ID = folder.ID
childrenNode.IsDir = true
- childrenNode.Name = f.opt.Enc.ToStandardName(folder.Attributes.Name)
+ childrenNode.Name = folder.Attributes.Name
childrenNode.ChDate = folder.Attributes.Chdate
childrenNode.Path = joinPath(path, childrenNode.Name)
childrenNode.Size = -1
@@ -682,7 +682,7 @@ func (f *Fs) FillFolderNode(
childrenNode.ID = file.ID
childrenNode.IsDir = false
childrenNode.Parent = folderNode
- childrenNode.Name = f.opt.Enc.ToStandardName(file.Attributes.Name)
+ childrenNode.Name = file.Attributes.Name
childrenNode.ChDate = file.Attributes.Chdate
childrenNode.Size = file.Attributes.Filesize
childrenNode.Path = joinPath(path, childrenNode.Name)
@@ -1045,8 +1045,7 @@ func (f *Fs) Mkdir(ctx context.Context, dir string) error {
f.mu.RUnlock()
fs.Debugf(f, "Mkdir: creating directory %q under parent id=%q", dirname, parentNode.ID)
- apiDirname := f.opt.Enc.FromStandardName(dirname)
- if err := f.studIPMkDir(ctx, parentNode.ID, apiDirname); err != nil {
+ if err := f.studIPMkDir(ctx, parentNode.ID, dirname); err != nil {
return err
}
@@ -1122,7 +1121,7 @@ func (f *Fs) findDirectoryNodeByName(parentNode *Node, name string) *Node {
func (f *Fs) findDirectoryByName(
ctx context.Context,
parentFolderID string,
- name string,
+ dirname string,
) (StudIPFoldersData, error) {
if ctx.Err() != nil {
return StudIPFoldersData{}, ctx.Err()
@@ -1145,10 +1144,10 @@ func (f *Fs) findDirectoryByName(
)
Assert(
- name != "",
+ dirname != "",
fmt.Sprintf(
"name must be not empty; name=%q",
- name,
+ dirname,
),
)
@@ -1158,7 +1157,7 @@ func (f *Fs) findDirectoryByName(
}
for _, folder := range folders.Data {
- if strings.EqualFold(f.opt.Enc.ToStandardName(folder.Attributes.Name), name) {
+ if strings.EqualFold(folder.Attributes.Name, dirname) {
return folder, nil
}
}
@@ -1254,8 +1253,7 @@ func (f *Fs) CreateParentDirectories(
targetNode.ID,
)
- apiDirname := f.opt.Enc.FromStandardName(dirname)
- if err := f.studIPMkDir(ctx, targetNode.ID, apiDirname); err != nil {
+ if err := f.studIPMkDir(ctx, targetNode.ID, dirname); err != nil {
return nil, err
}
@@ -1562,8 +1560,6 @@ func (f *Fs) Move(
return nil, fs.ErrorCantMove
}
- destName = f.opt.Enc.FromStandardName(destName)
-
var moved *StudIPFileRefData
if dirPath(sourceAbs) == dirPath(destAbs) {
moved, err = f.studIPUpdateFileRef(
diff --git a/backend/studip/requests.go b/backend/studip/requests.go
index 592f938..b74a9bc 100644
--- a/backend/studip/requests.go
+++ b/backend/studip/requests.go
@@ -50,6 +50,8 @@ func (f *Fs) studIPMkDir(
),
)
+ encodedFilename := f.opt.Enc.FromStandardName(filename)
+
URL := fmt.Sprintf("courses/%s/folders", f.opt.CourseID)
fs.Debugf(
@@ -78,7 +80,7 @@ func (f *Fs) studIPMkDir(
}{}
payload.Data.Type = "folders"
- payload.Data.Attributes.Name = filename
+ payload.Data.Attributes.Name = encodedFilename
payload.Data.Relationships.Parent.Data.Type = "folders"
payload.Data.Relationships.Parent.Data.ID = parentDirectoryID
@@ -168,10 +170,15 @@ func (f *Fs) studIPGetFoldersOfFolder(
if len(page.Data) == 0 {
break
}
+
responseJSON.Data = append(responseJSON.Data, page.Data...)
responseJSON.Meta = page.Meta
}
+ for i := 0; i < len(responseJSON.Data); i++ {
+ responseJSON.Data[i].Attributes.Name = f.opt.Enc.ToStandardName(responseJSON.Data[i].Attributes.Name)
+ }
+
return responseJSON, nil
}
@@ -222,11 +229,16 @@ func (f *Fs) studIPGetFilesOfFolder(
if len(page.Data) == 0 {
break
}
+
responseJSON.Data = append(responseJSON.Data, page.Data...)
responseJSON.Meta = page.Meta
responseJSON.Links = page.Links
}
+ for i := 0; i < len(responseJSON.Data); i++ {
+ responseJSON.Data[i].Attributes.Name = f.opt.Enc.ToStandardName(responseJSON.Data[i].Attributes.Name)
+ }
+
return responseJSON, nil
}
@@ -278,6 +290,10 @@ func (f *Fs) studIPGetCourseFolders(ctx context.Context) (*StudIPFolders, error)
responseJSON.Meta = page.Meta
}
+ for i := 0; i < len(responseJSON.Data); i++ {
+ responseJSON.Data[i].Attributes.Name = f.opt.Enc.ToStandardName(responseJSON.Data[i].Attributes.Name)
+ }
+
return responseJSON, nil
}
@@ -359,6 +375,7 @@ func (f *Fs) studIPGetFileRef(
}
URL := fmt.Sprintf("file-refs/%s", fileRefID)
+
responseJSON := new(StudIPFileRef)
res, err := f.client.CallJSON(
ctx,
@@ -377,7 +394,7 @@ func (f *Fs) studIPGetFileRef(
func (f *Fs) studIPUpdateFileRef(
ctx context.Context,
fileRefID string,
- name string,
+ filename string,
description string,
termsOfUseID string,
) (*StudIPFileRefData, error) {
@@ -397,7 +414,7 @@ func (f *Fs) studIPUpdateFileRef(
return nil, errors.New("fileRefID is empty")
}
- if name == "" {
+ if filename == "" {
return nil, errors.New("name is empty")
}
@@ -405,6 +422,8 @@ func (f *Fs) studIPUpdateFileRef(
return nil, errors.New("termsOfUseID is empty")
}
+ encodedFilename := f.opt.Enc.FromStandardName(filename)
+
URL := fmt.Sprintf("file-refs/%s", fileRefID)
payload := struct {
@@ -425,7 +444,7 @@ func (f *Fs) studIPUpdateFileRef(
} `json:"data"`
}{}
payload.Data.Type = "file-refs"
- payload.Data.Attributes.Name = name
+ payload.Data.Attributes.Name = encodedFilename
payload.Data.Attributes.Description = description
payload.Data.Relationships.TermsOfUse.Data.Type = "terms-of-use"
payload.Data.Relationships.TermsOfUse.Data.ID = termsOfUseID
@@ -459,7 +478,7 @@ func (f *Fs) studIPCreateFileRefByReference(
ctx context.Context,
parentFolderID string,
fileID string,
- name string,
+ filename string,
description string,
termsOfUseID string,
) (*StudIPFileRefData, error) {
@@ -483,7 +502,7 @@ func (f *Fs) studIPCreateFileRefByReference(
return nil, errors.New("fileID is empty")
}
- if name == "" {
+ if filename == "" {
return nil, errors.New("name is empty")
}
@@ -491,8 +510,9 @@ func (f *Fs) studIPCreateFileRefByReference(
return nil, errors.New("termsOfUseID is empty")
}
+ encodedFilename := f.opt.Enc.FromStandardName(filename)
+
URL := fmt.Sprintf("folders/%s/file-refs", parentFolderID)
- apiName := f.opt.Enc.FromStandardName(name)
payload := struct {
Data struct {
@@ -517,8 +537,9 @@ func (f *Fs) studIPCreateFileRefByReference(
} `json:"relationships"`
} `json:"data"`
}{}
+
payload.Data.Type = "file-refs"
- payload.Data.Attributes.Name = apiName
+ payload.Data.Attributes.Name = encodedFilename
payload.Data.Attributes.Description = description
payload.Data.Relationships.File.Data.Type = "files"
payload.Data.Relationships.File.Data.ID = fileID
@@ -553,7 +574,7 @@ func (f *Fs) studIPCreateFileRefByReference(
func (f *Fs) studIPUpdateFolder(
ctx context.Context,
folderID string,
- name string,
+ filename string,
parentFolderID string,
) error {
if ctx.Err() != nil {
@@ -571,38 +592,42 @@ func (f *Fs) studIPUpdateFolder(
if folderID == "" {
return errors.New("folderID is empty")
}
- if name == "" && parentFolderID == "" {
- return errors.New("name and parentFolderID are empty")
- }
- URL := fmt.Sprintf("folders/%s", folderID)
- apiName := ""
- if name != "" {
- apiName = f.opt.Enc.FromStandardName(name)
+ if filename == "" {
+ return errors.New("filename is empty")
}
- data := map[string]any{
- "type": "folders",
- }
- if name != "" {
- data["attributes"] = map[string]any{
- "name": apiName,
- }
- }
- if parentFolderID != "" {
- data["relationships"] = map[string]any{
- "parent": map[string]any{
- "data": map[string]any{
- "type": "folders",
- "id": parentFolderID,
- },
- },
- }
+ if parentFolderID == "" {
+ return errors.New("parentFolderID is empty")
}
- body, err := json.Marshal(map[string]any{
- "data": data,
- })
+ encodedFilename := f.opt.Enc.FromStandardName(filename)
+
+ URL := fmt.Sprintf("folders/%s", folderID)
+
+ payload := struct {
+ Data struct {
+ Type string `json:"type"`
+ Attributes struct {
+ Name string `json:"name"`
+ } `json:"attributes"`
+ Relationships struct {
+ Parent struct {
+ Data struct {
+ Type string `json:"type"`
+ ID string `json:"id"`
+ } `json:"data"`
+ } `json:"parent"`
+ } `json:"relationships"`
+ } `json:"data"`
+ }{}
+
+ payload.Data.Type = "folders"
+ payload.Data.Attributes.Name = encodedFilename
+ payload.Data.Relationships.Parent.Data.Type = "folders"
+ payload.Data.Relationships.Parent.Data.ID = parentFolderID
+
+ body, err := json.Marshal(payload)
if err != nil {
return err
}
@@ -721,14 +746,17 @@ func (f *Fs) studIPUpdateFileContent(
if fileRefID == "" {
return "", errors.New("fileRefID is empty")
}
+
if in == nil {
return "", errors.New("input reader is nil")
}
+
if filename == "" {
return "", fmt.Errorf("invalid filename %q", filename)
}
URL := fmt.Sprintf("file-refs/%s/content", fileRefID)
+
fs.Debugf(
f,
"studIPUpdateFileContent: start fileRefID=%q filename=%q path=%q",
@@ -762,13 +790,17 @@ func (f *Fs) studIPUploadFileContentToPath(
if URL == "" {
return "", errors.New("URL is empty")
}
+
if in == nil {
return "", errors.New("input reader is nil")
}
+
if filename == "" {
return "", fmt.Errorf("invalid filename %q", filename)
}
+ encodedFilename := f.opt.Enc.FromStandardName(filename)
+
// Read first 512 bytes for content type detection.
buffer := make([]byte, 512)
n, err := io.ReadFull(in, buffer)
@@ -792,7 +824,7 @@ func (f *Fs) studIPUploadFileContentToPath(
fullReader,
url.Values{},
"file",
- filename,
+ encodedFilename,
detectedType,
)
if err != nil {