props.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package dav_ipfs
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. "github.com/ipfs/go-ipfs-api"
  6. "github.com/kpmy/ypk/dom"
  7. "github.com/kpmy/ypk/fn"
  8. . "github.com/kpmy/ypk/tc"
  9. "golang.org/x/net/webdav"
  10. "io"
  11. "reflect"
  12. "strings"
  13. )
  14. func newPropsModel() (ret dom.Element) {
  15. ret = dom.Elem("props")
  16. return
  17. }
  18. func readProps(model dom.Element) (ret map[xml.Name]dom.Element) {
  19. ret = make(map[xml.Name]dom.Element)
  20. for _, _e := range model.Children() {
  21. switch e := _e.(type) {
  22. case dom.Element:
  23. xn := xml.Name{Local: e.Attr("local"), Space: e.Attr("space")}
  24. ret[xn] = e
  25. default:
  26. Halt(100, reflect.TypeOf(e))
  27. }
  28. }
  29. for k := range model.AttrAsMap() {
  30. xn := xml.Name{Local: k, Space: "IPFSATTR"}
  31. ret[xn] = model
  32. }
  33. return
  34. }
  35. func writeProps(props map[xml.Name]dom.Element) (ret dom.Element) {
  36. ret = dom.Elem("props")
  37. for k, v := range props {
  38. if k.Space == "IPFSATTR" {
  39. ret.Attr(k.Local, v.Attr(k.Local))
  40. } else {
  41. ret.AppendChild(v)
  42. }
  43. }
  44. return
  45. }
  46. func props2webdav(pm map[xml.Name]dom.Element) (ret map[xml.Name]webdav.Property) {
  47. ret = make(map[xml.Name]webdav.Property)
  48. for k, v := range pm {
  49. p := webdav.Property{XMLName: k}
  50. buf := new(bytes.Buffer)
  51. if k.Space == "IPFSATTR" {
  52. buf.WriteString(v.Attr(k.Local))
  53. } else {
  54. Assert(v.ChildrenCount() == 1, 40)
  55. c0 := v.Children()[0]
  56. switch c := c0.(type) {
  57. case dom.Element:
  58. rd := dom.Encode(c)
  59. io.Copy(buf, rd)
  60. case dom.Text:
  61. xml.EscapeText(buf, []byte(c.Data()))
  62. default:
  63. Halt(100, reflect.TypeOf(c))
  64. }
  65. }
  66. p.InnerXML = buf.Bytes()
  67. ret[k] = p
  68. }
  69. return
  70. }
  71. func propsPatch(pe map[xml.Name]dom.Element, patch []webdav.Proppatch) (ret []webdav.Propstat) {
  72. ret = []webdav.Propstat{}
  73. for _, pl := range patch {
  74. ps := webdav.Propstat{}
  75. for _, p := range pl.Props {
  76. if pl.Remove {
  77. delete(pe, p.XMLName)
  78. } else if p.XMLName.Space == "IPFSATTR" {
  79. tmp := dom.Elem("props")
  80. tmp.Attr(p.XMLName.Local, string(p.InnerXML))
  81. pe[p.XMLName] = tmp
  82. } else {
  83. el := dom.Elem("prop")
  84. el.Attr("local", p.XMLName.Local)
  85. el.Attr("space", p.XMLName.Space)
  86. e, _ := dom.Decode(bytes.NewBuffer(p.InnerXML))
  87. if !fn.IsNil(e.Model()) {
  88. el.AppendChild(e.Model())
  89. } else if !fn.IsNil(e.Data()) {
  90. el.AppendChild(e.Data())
  91. } else {
  92. Halt(100)
  93. }
  94. pe[p.XMLName] = el
  95. }
  96. ps.Props = append(ps.Props, p)
  97. }
  98. ps.Status = 200
  99. ret = append(ret, ps)
  100. }
  101. return
  102. }
  103. func propLinksMap(obj *shell.UnixLsObject) (ret map[string]*shell.UnixLsLink) {
  104. ret = make(map[string]*shell.UnixLsLink)
  105. for _, lo := range obj.Links {
  106. if lo.Type == "File" {
  107. if lo.Name == "*" {
  108. ret["*"] = lo
  109. } else if strings.HasPrefix(lo.Name, "*") {
  110. ret[strings.Trim(lo.Name, "*")] = lo
  111. }
  112. }
  113. }
  114. return
  115. }