mastodon.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // Copyright (C) 2020-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. "compress/gzip"
  20. "fmt"
  21. "io"
  22. "log"
  23. "net/http"
  24. "net/url"
  25. "strings"
  26. "time"
  27. )
  28. // https://docs.joinmastodon.org/methods/statuses/
  29. // https://docs.joinmastodon.org/client/token/
  30. func mastodonStatusPost(base url.URL, token string, maxlen int, en Entry, foot string) (err error) {
  31. if 0 == len(en.Links) {
  32. return fmt.Errorf("need an url.")
  33. }
  34. body := func(t *HumanText) string {
  35. if t == nil {
  36. return ""
  37. }
  38. return t.Body
  39. }
  40. form := url.Values{}
  41. {
  42. txt := body(&en.Title)
  43. txt += "\n" + en.Links[0].Href
  44. txt += "\n" + body(en.Content)
  45. if "" != txt && !strings.HasSuffix(txt, "\n") {
  46. foot = "\n" + foot
  47. }
  48. txt = limit(maxlen-len(foot), "…", txt)
  49. txt += foot
  50. form.Add("status", txt)
  51. }
  52. httpPostBody := func(ur *url.URL, token string, form url.Values, timeout time.Duration) (io.Reader, error) {
  53. defer un(trace(strings.Join([]string{"HttpPostBody", ur.String()}, " ")))
  54. client := &http.Client{Timeout: timeout}
  55. req, _ := http.NewRequest(http.MethodPost, ur.String(), strings.NewReader(form.Encode()))
  56. req.Header.Set("Accept-Encoding", "gzip, deflate")
  57. req.Header.Set("User-Agent", strings.Join([]string{myselfNamespace, version}, ""))
  58. if "" != token {
  59. req.Header.Set("Authorization", "Bearer "+token)
  60. }
  61. req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  62. if resp, err := client.Do(req); nil == resp && nil != err {
  63. return nil, err
  64. } else {
  65. encs := resp.Header["Content-Encoding"]
  66. switch {
  67. case contains(encs, "gzip"), contains(encs, "deflate"):
  68. return gzip.NewReader(resp.Body)
  69. case 0 == len(encs):
  70. // NOP
  71. default:
  72. log.Printf("Strange compression: %s\n", encs)
  73. }
  74. return resp.Body, err
  75. }
  76. }
  77. if !strings.HasSuffix(base.Path, "/") {
  78. base.Path += "/"
  79. }
  80. base.Path += "statuses"
  81. _, err = httpPostBody(&base, token, form, 4*time.Second)
  82. return
  83. }