Init V4 community edition (#2265)
* Init V4 community edition * Init V4 community edition
This commit is contained in:
@@ -3,9 +3,9 @@ package wopi
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||
"net/http"
|
||||
"strings"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type ActonType string
|
||||
@@ -16,86 +16,53 @@ var (
|
||||
ActionEdit = ActonType("edit")
|
||||
)
|
||||
|
||||
const (
|
||||
DiscoverResponseCacheKey = "wopi_discover"
|
||||
DiscoverRefreshDuration = 24 * 3600 // 24 hrs
|
||||
)
|
||||
|
||||
func (c *client) AvailableExts() []string {
|
||||
if err := c.checkDiscovery(); err != nil {
|
||||
util.Log().Error("Failed to check WOPI discovery: %s", err)
|
||||
return nil
|
||||
func DiscoveryXmlToViewerGroup(xmlStr string) (*setting.ViewerGroup, error) {
|
||||
var discovery WopiDiscovery
|
||||
if err := xml.Unmarshal([]byte(xmlStr), &discovery); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse WOPI discovery XML: %w", err)
|
||||
}
|
||||
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
exts := make([]string, 0, len(c.actions))
|
||||
for ext, actions := range c.actions {
|
||||
_, previewable := actions[string(ActionPreview)]
|
||||
_, editable := actions[string(ActionEdit)]
|
||||
_, previewableFallback := actions[string(ActionPreviewFallback)]
|
||||
|
||||
if previewable || editable || previewableFallback {
|
||||
exts = append(exts, strings.TrimPrefix(ext, "."))
|
||||
}
|
||||
group := &setting.ViewerGroup{
|
||||
Viewers: make([]setting.Viewer, 0, len(discovery.NetZone.App)),
|
||||
}
|
||||
|
||||
return exts
|
||||
}
|
||||
|
||||
// checkDiscovery checks if discovery content is needed to be refreshed.
|
||||
// If so, it will refresh discovery content.
|
||||
func (c *client) checkDiscovery() error {
|
||||
c.mu.RLock()
|
||||
if c.discovery == nil {
|
||||
c.mu.RUnlock()
|
||||
return c.refreshDiscovery()
|
||||
}
|
||||
|
||||
c.mu.RUnlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// refresh Discovery action configs.
|
||||
func (c *client) refreshDiscovery() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
cached, exist := c.cache.Get(DiscoverResponseCacheKey)
|
||||
if exist {
|
||||
cachedDiscovery := cached.(WopiDiscovery)
|
||||
c.discovery = &cachedDiscovery
|
||||
} else {
|
||||
res, err := c.http.Request("GET", c.config.discoveryEndpoint.String(), nil).
|
||||
CheckHTTPResponse(http.StatusOK).GetResponse()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to request discovery endpoint: %w", err)
|
||||
for _, app := range discovery.NetZone.App {
|
||||
viewer := setting.Viewer{
|
||||
ID: uuid.Must(uuid.NewV4()).String(),
|
||||
DisplayName: app.Name,
|
||||
Type: setting.ViewerTypeWopi,
|
||||
Icon: app.FavIconUrl,
|
||||
WopiActions: make(map[string]map[setting.ViewerAction]string),
|
||||
}
|
||||
|
||||
if err := xml.Unmarshal([]byte(res), &c.discovery); err != nil {
|
||||
return fmt.Errorf("failed to parse response discovery endpoint: %w", err)
|
||||
}
|
||||
|
||||
if err := c.cache.Set(DiscoverResponseCacheKey, *c.discovery, DiscoverRefreshDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// construct actions map
|
||||
c.actions = make(map[string]map[string]Action)
|
||||
for _, app := range c.discovery.NetZone.App {
|
||||
for _, action := range app.Action {
|
||||
if action.Ext == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := c.actions["."+action.Ext]; !ok {
|
||||
c.actions["."+action.Ext] = make(map[string]Action)
|
||||
if _, ok := viewer.WopiActions[action.Ext]; !ok {
|
||||
viewer.WopiActions[action.Ext] = make(map[setting.ViewerAction]string)
|
||||
}
|
||||
|
||||
c.actions["."+action.Ext][action.Name] = action
|
||||
if action.Name == string(ActionPreview) {
|
||||
viewer.WopiActions[action.Ext][setting.ViewerActionView] = action.Urlsrc
|
||||
} else if action.Name == string(ActionPreviewFallback) {
|
||||
viewer.WopiActions[action.Ext][setting.ViewerActionView] = action.Urlsrc
|
||||
} else if action.Name == string(ActionEdit) {
|
||||
viewer.WopiActions[action.Ext][setting.ViewerActionEdit] = action.Urlsrc
|
||||
} else if len(viewer.WopiActions[action.Ext]) == 0 {
|
||||
delete(viewer.WopiActions, action.Ext)
|
||||
}
|
||||
}
|
||||
|
||||
viewer.Exts = lo.MapToSlice(viewer.WopiActions, func(key string, value map[setting.ViewerAction]string) string {
|
||||
return key
|
||||
})
|
||||
|
||||
if len(viewer.WopiActions) > 0 {
|
||||
group.Viewers = append(group.Viewers, viewer)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return group, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user