Make server file manager list-first
This commit is contained in:
@@ -16,10 +16,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
serverFileTransferChannel = "run-file-transfer"
|
||||
serverFileMaxInlineEditBytes = 64 * 1024
|
||||
serverFileDefaultDirectoryKey = "server-files"
|
||||
serverFileDefaultLogDirectoryKey = "server-logs"
|
||||
serverFileTransferChannel = "run-file-transfer"
|
||||
serverFileMaxInlineEditBytes = 64 * 1024
|
||||
serverFileDefaultDirectoryKey = "server-root"
|
||||
)
|
||||
|
||||
type serverFileContext struct {
|
||||
@@ -65,7 +64,7 @@ func (svc *CoreService) GetServerFileWorkspaceForSession(sessionID string, serve
|
||||
Directories: workspace.Directories,
|
||||
Files: workspace.Files,
|
||||
ConfigFields: workspace.ConfigFields,
|
||||
DeclaredOnly: serverFileWorkspaceIsPluginDeclared(ctx.Plugin.FileWorkspace),
|
||||
DeclaredOnly: false,
|
||||
RuntimeWorkspaceScope: svc.runtimeProfileScope(ctx.Instance.ID),
|
||||
Transfer: domain.ServerFileTransferPolicy{
|
||||
Channel: serverFileTransferChannel,
|
||||
@@ -102,18 +101,14 @@ func (svc *CoreService) ListServerFilesForSession(sessionID string, request doma
|
||||
}
|
||||
}
|
||||
state := "declared"
|
||||
reason := "展示插件声明的逻辑文件;点击刷新可请求 Run 返回实时目录。"
|
||||
reason := "展示服务器文件缓存;点击刷新目录读取 Run 实时目录。"
|
||||
if hasLatest && !isTerminalJobState(latest.State) {
|
||||
state = "pending"
|
||||
reason = "Run 正在刷新目录。"
|
||||
}
|
||||
entries := filterServerFileEntries(serverFileEntriesFromDeclaredWorkspace(ctx.Workspace, request.DirectoryKey), request.Query)
|
||||
if state == "declared" {
|
||||
reasonPrefix := "展示插件声明的逻辑文件"
|
||||
if !serverFileWorkspaceIsPluginDeclared(ctx.Plugin.FileWorkspace) {
|
||||
reasonPrefix = "展示通用服务器文件目录"
|
||||
}
|
||||
reason = reasonPrefix + ";点击刷新可请求 Run 返回实时目录。"
|
||||
reason = "展示服务器文件缓存;点击刷新目录读取 Run 实时目录。"
|
||||
}
|
||||
return domain.CopyServerFileListResult(domain.ServerFileListResult{ServerInstanceID: ctx.Instance.ID, PluginID: ctx.Plugin.ID, DirectoryKey: request.DirectoryKey, Path: request.Path, State: state, Entries: entries, Job: latest, RefreshedAt: latest.TerminalAt, Reason: reason}), nil
|
||||
}
|
||||
@@ -179,9 +174,6 @@ func (svc *CoreService) UploadServerFileForSession(sessionID string, request dom
|
||||
if err != nil {
|
||||
return domain.ServerFileUploadDispatch{}, err
|
||||
}
|
||||
if strings.EqualFold(ctx.Directory.Scope, "logs") {
|
||||
return domain.ServerFileUploadDispatch{}, validationError("log directories are read-only")
|
||||
}
|
||||
relativePath := cleanServerFileRelativePath(path.Join(request.RelativePath, request.Filename))
|
||||
artifactID := serverFileUploadArtifactID(request.ServerInstanceID, request.IdempotencyKey, relativePath)
|
||||
artifact := domain.Artifact{ID: artifactID, OwnerKind: domain.ArtifactOwnerKindServerInstance, OwnerID: ctx.Instance.ID, SizeBytes: int64(len(request.Payload)), Checksum: request.Checksum, State: domain.ArtifactStateAvailable, CreatedAt: svc.now(), UpdatedAt: svc.now()}
|
||||
@@ -348,19 +340,8 @@ func (svc *CoreService) serverFileContextForSession(sessionID string, serverInst
|
||||
return serverFileContext{User: user, Instance: instance, Plugin: plugin, Directory: directory, Workspace: workspace, Scope: svc.runtimeProfileScope(instance.ID)}, nil
|
||||
}
|
||||
|
||||
func effectiveServerFileWorkspace(plugin domain.GamePlugin) domain.PluginFileWorkspace {
|
||||
workspace := domain.CopyPluginFileWorkspace(plugin.FileWorkspace)
|
||||
if len(workspace.Directories) == 0 && workspace.DefaultDirectoryKey == "" {
|
||||
workspace.DefaultDirectoryKey = serverFileDefaultDirectoryKey
|
||||
workspace.Directories = []domain.PluginLogicalDirectory{{Key: serverFileDefaultDirectoryKey, Label: "服务器文件", Scope: "config"}}
|
||||
if plugin.Permissions.Logs || containsString(plugin.DeclaredPermissions, "server.logs.read") || len(plugin.RuntimeProfiles.LogSources) > 0 {
|
||||
workspace.Directories = append(workspace.Directories, domain.PluginLogicalDirectory{Key: serverFileDefaultLogDirectoryKey, Label: "日志文件", Scope: "logs"})
|
||||
}
|
||||
}
|
||||
if workspace.DefaultDirectoryKey == "" && len(workspace.Directories) > 0 {
|
||||
workspace.DefaultDirectoryKey = workspace.Directories[0].Key
|
||||
}
|
||||
return workspace
|
||||
func effectiveServerFileWorkspace(_ domain.GamePlugin) domain.PluginFileWorkspace {
|
||||
return domain.PluginFileWorkspace{DefaultDirectoryKey: serverFileDefaultDirectoryKey, Directories: []domain.PluginLogicalDirectory{{Key: serverFileDefaultDirectoryKey, Label: "服务器根目录", Scope: "config"}}, Files: []domain.PluginLogicalFile{}, ConfigFields: []domain.PluginConfigField{}}
|
||||
}
|
||||
|
||||
func serverFileWorkspaceIsPluginDeclared(workspace domain.PluginFileWorkspace) bool {
|
||||
@@ -380,13 +361,13 @@ func serverFileEntriesFromDeclaredWorkspace(workspace domain.PluginFileWorkspace
|
||||
if directoryKey == "" || directory.Key == directoryKey {
|
||||
continue
|
||||
}
|
||||
entries = append(entries, domain.ServerFileEntry{Name: directory.Label, Kind: domain.ServerFileEntryDirectory, DirectoryKey: directory.Key, RelativePath: "", Scope: directory.Scope, Editable: false, Downloadable: false, Remark: "插件声明目录"})
|
||||
entries = append(entries, domain.ServerFileEntry{Name: directory.Label, Kind: domain.ServerFileEntryDirectory, DirectoryKey: directory.Key, RelativePath: "", Scope: directory.Scope, Editable: true, Downloadable: true, Remark: "目录"})
|
||||
}
|
||||
for _, file := range workspace.Files {
|
||||
if directoryKey != "" && file.DirectoryKey != directoryKey {
|
||||
continue
|
||||
}
|
||||
entries = append(entries, domain.ServerFileEntry{Name: file.Label, Kind: domain.ServerFileEntryFile, DirectoryKey: file.DirectoryKey, RelativePath: file.Key, LogicalKey: file.Key, Scope: file.Kind, Editable: file.Editable, Downloadable: true, Remark: fileRemark(file)})
|
||||
entries = append(entries, domain.ServerFileEntry{Name: file.Label, Kind: domain.ServerFileEntryFile, DirectoryKey: file.DirectoryKey, RelativePath: file.Key, LogicalKey: file.Key, Scope: file.Kind, Editable: true, Downloadable: true, Remark: fileRemark(file)})
|
||||
}
|
||||
sort.SliceStable(entries, func(i int, j int) bool {
|
||||
if entries[i].Kind == entries[j].Kind {
|
||||
@@ -417,10 +398,14 @@ func serverFileEntriesFromRunList(content string, fallbackDirectoryKey string, f
|
||||
directoryKey = fallbackDirectoryKey
|
||||
}
|
||||
relativePath := cleanServerFileRelativePath(entry.RelativePath)
|
||||
if relativePath == "" {
|
||||
if relativePath == "" && entry.Name != "" {
|
||||
relativePath = cleanServerFileRelativePath(path.Join(fallbackPath, entry.Name))
|
||||
} else if relativePath == "" {
|
||||
relativePath = fallbackPath
|
||||
}
|
||||
entries = append(entries, domain.ServerFileEntry{Name: entry.Name, Kind: kind, DirectoryKey: directoryKey, RelativePath: relativePath, LogicalKey: entry.LogicalKey, Scope: entry.Scope, SizeBytes: entry.SizeBytes, ModifiedAt: modifiedAt, Checksum: entry.Checksum, Editable: entry.Editable, Downloadable: entry.Downloadable, Remark: entry.Remark})
|
||||
editable := kind == domain.ServerFileEntryFile
|
||||
downloadable := kind == domain.ServerFileEntryFile
|
||||
entries = append(entries, domain.ServerFileEntry{Name: entry.Name, Kind: kind, DirectoryKey: directoryKey, RelativePath: relativePath, LogicalKey: entry.LogicalKey, Scope: entry.Scope, SizeBytes: entry.SizeBytes, ModifiedAt: modifiedAt, Checksum: entry.Checksum, Editable: editable, Downloadable: downloadable, Remark: entry.Remark})
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
@@ -518,7 +503,7 @@ func fileRemark(file domain.PluginLogicalFile) string {
|
||||
if file.Editable {
|
||||
return "可编辑配置"
|
||||
}
|
||||
return "插件声明文件"
|
||||
return "文件"
|
||||
}
|
||||
|
||||
func serverFileDisplayName(workspace domain.PluginFileWorkspace, key string) string {
|
||||
|
||||
Reference in New Issue
Block a user