1
mirror of https://github.com/rclone/rclone synced 2024-12-26 18:23:45 +01:00

dlna: cds: don't specify childCount at all when unknown

Basically, solving #3541 with a different approach - bringing in
the upstream upnpav module, and changing ChildCount from int to a
*int to avoid childCount="0" in the XML output when that value is
simply unknown.

Current approach is leading to some recursion issues and according
to the DLNA spec it shouldn't be necessary, anyway.
This commit is contained in:
Dan Walters 2020-02-17 19:13:17 -05:00 committed by Nick Craig-Wood
parent bde0334bd8
commit 7e2568a312
3 changed files with 67 additions and 10 deletions

View File

@ -16,8 +16,8 @@ import (
"github.com/anacrolix/dms/dlna"
"github.com/anacrolix/dms/upnp"
"github.com/anacrolix/dms/upnpav"
"github.com/pkg/errors"
"github.com/rclone/rclone/cmd/serve/dlna/upnpav"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/vfs"
)
@ -77,16 +77,10 @@ func (cds *contentDirectoryService) cdsObjectToUpnpavObject(cdsObject object, fi
}
if fileInfo.IsDir() {
children, err := cds.readContainer(cdsObject, host)
if err != nil {
return nil, err
}
obj.Class = "object.container.storageFolder"
obj.Title = fileInfo.Name()
return upnpav.Container{
Object: obj,
ChildCount: len(children),
Object: obj,
}, nil
}

View File

@ -122,8 +122,8 @@ func TestContentDirectoryBrowseMetadata(t *testing.T) {
// expect a <container> element
require.Contains(t, string(body), html.EscapeString("<container "))
require.NotContains(t, string(body), html.EscapeString("<item "))
// with a non-zero childCount
require.Regexp(t, " childCount=&#34;[1-9]", string(body))
// if there is a childCount, it better not be zero
require.NotContains(t, string(body), html.EscapeString(" childCount=\"0\""))
}
// Check that the X_MS_MediaReceiverRegistrar is faked out properly.

View File

@ -0,0 +1,63 @@
package upnpav
import (
"encoding/xml"
"time"
)
const (
// NoSuchObjectErrorCode : The specified ObjectID is invalid.
NoSuchObjectErrorCode = 701
)
// Resource description
type Resource struct {
XMLName xml.Name `xml:"res"`
ProtocolInfo string `xml:"protocolInfo,attr"`
URL string `xml:",chardata"`
Size uint64 `xml:"size,attr,omitempty"`
Bitrate uint `xml:"bitrate,attr,omitempty"`
Duration string `xml:"duration,attr,omitempty"`
Resolution string `xml:"resolution,attr,omitempty"`
}
// Container description
type Container struct {
Object
XMLName xml.Name `xml:"container"`
ChildCount *int `xml:"childCount,attr"`
}
// Item description
type Item struct {
Object
XMLName xml.Name `xml:"item"`
Res []Resource
InnerXML string `xml:",innerxml"`
}
// Object description
type Object struct {
ID string `xml:"id,attr"`
ParentID string `xml:"parentID,attr"`
Restricted int `xml:"restricted,attr"` // indicates whether the object is modifiable
Class string `xml:"upnp:class"`
Icon string `xml:"upnp:icon,omitempty"`
Title string `xml:"dc:title"`
Date Timestamp `xml:"dc:date"`
Artist string `xml:"upnp:artist,omitempty"`
Album string `xml:"upnp:album,omitempty"`
Genre string `xml:"upnp:genre,omitempty"`
AlbumArtURI string `xml:"upnp:albumArtURI,omitempty"`
Searchable int `xml:"searchable,attr"`
}
// Timestamp wraps time.Time for formatting purposes
type Timestamp struct {
time.Time
}
// MarshalXML formats the Timestamp per DIDL-Lite spec
func (t Timestamp) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
return e.EncodeElement(t.Format("2006-01-02"), start)
}