pinboard.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //
  2. // Copyright (C) 2017-2021 Marcus Rohrmoser, http://purl.mro.name/ShaarliGo
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. //
  17. package main
  18. import (
  19. "fmt"
  20. "net/url"
  21. "sort"
  22. "strings"
  23. "time"
  24. )
  25. func yesno(yes bool) string {
  26. if !yes {
  27. return "no"
  28. }
  29. return "yes"
  30. }
  31. // limit bytes brute force, breaks multibyte at the end in case.
  32. func limit(mx int, eli, str string) string {
  33. if len(str) > mx {
  34. return str[:mx-len(eli)] + eli
  35. }
  36. return str
  37. }
  38. // https://pinboard.in/api/#posts_add
  39. // https://api.pinboard.in/v1/posts/add
  40. //
  41. // url url the URL of the item
  42. // description title Title of the item. This field is unfortunately named 'description' for backwards compatibility with the delicious API
  43. // extended text Description of the item. Called 'extended' for backwards compatibility with delicious API
  44. // tags tag List of up to 100 tags
  45. // dt datetime creation time for this bookmark. Defaults to current time. Datestamps more than 10 minutes ahead of server time will be reset to current server time
  46. // replace yes/no Replace any existing bookmark with this URL. Default is yes. If set to no, will throw an error if bookmark exists
  47. // shared yes/no Make bookmark public. Default is "yes" unless user has enabled the "save all bookmarks as private" user setting, in which case default is "no"
  48. // toread yes/no Marks the bookmark as unread. Default is "no"
  49. func pinboardPostsAdd(base url.URL, en Entry, foot string) (url url.URL, err error) {
  50. if 0 == len(en.Links) {
  51. return url, fmt.Errorf("need an url.")
  52. }
  53. body := func(t *HumanText) string {
  54. if t == nil {
  55. return ""
  56. }
  57. return t.Body
  58. }
  59. pars := base.Query()
  60. pars.Add("url", en.Links[0].Href)
  61. {
  62. ti := limit(255, "…", body(&en.Title))
  63. pars.Add("description", ti)
  64. }
  65. {
  66. de := body(en.Content)
  67. if "" != de && !strings.HasSuffix(de, "\n") {
  68. foot = "\n" + foot
  69. }
  70. de = limit(65536-len(foot), "…", de)
  71. de += foot
  72. pars.Add("extended", de)
  73. }
  74. {
  75. tgs := make([]string, 0, len(en.Categories))
  76. for _, ca := range en.Categories {
  77. tgs = append(tgs, ca.Term)
  78. }
  79. sort.Strings(tgs)
  80. ta := limit(255, "…", strings.Join(tgs, " "))
  81. pars.Add("tags", ta)
  82. }
  83. // pars.Add("replace", yesno(replace))
  84. // pars.Add("shared", yesno(shared))
  85. // pars.Add("toread", yesno(toread))
  86. pars.Add("dt", en.Published.Format(time.RFC3339))
  87. url = base
  88. if !strings.HasSuffix(url.Path, "/") {
  89. url.Path += "/"
  90. }
  91. url.Path += "posts/add"
  92. url.RawQuery = pars.Encode()
  93. return
  94. }