A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

104 lines
2.7 KiB

  1. /*
  2. * Copyright © 2018-2019 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "io/ioutil"
  13. "net/http"
  14. "strings"
  15. "sync"
  16. "time"
  17. )
  18. // updatesCacheTime is the default interval between cache updates for new
  19. // software versions
  20. const updatesCacheTime = 12 * time.Hour
  21. // updatesCache holds data about current and new releases of the writefreely
  22. // software
  23. type updatesCache struct {
  24. mu sync.Mutex
  25. frequency time.Duration
  26. lastCheck time.Time
  27. latestVersion string
  28. currentVersion string
  29. }
  30. // CheckNow asks for the latest released version of writefreely and updates
  31. // the cache last checked time. If the version postdates the current 'latest'
  32. // the version value is replaced.
  33. func (uc *updatesCache) CheckNow() error {
  34. uc.mu.Lock()
  35. defer uc.mu.Unlock()
  36. latestRemote, err := newVersionCheck(uc.currentVersion)
  37. if err != nil {
  38. return err
  39. }
  40. uc.lastCheck = time.Now()
  41. if CompareSemver(latestRemote, uc.latestVersion) == 1 {
  42. uc.latestVersion = latestRemote
  43. }
  44. return nil
  45. }
  46. // AreAvailable updates the cache if the frequency duration has passed
  47. // then returns if the latest release is newer than the current running version.
  48. func (uc updatesCache) AreAvailable() bool {
  49. if time.Since(uc.lastCheck) > uc.frequency {
  50. uc.CheckNow()
  51. }
  52. return CompareSemver(uc.latestVersion, uc.currentVersion) == 1
  53. }
  54. // LatestVersion returns the latest stored version available.
  55. func (uc updatesCache) LatestVersion() string {
  56. return uc.latestVersion
  57. }
  58. // ReleaseURL returns the full URL to the blog.writefreely.org release notes
  59. // for the latest version as stored in the cache.
  60. func (uc updatesCache) ReleaseURL() string {
  61. ver := strings.TrimPrefix(uc.latestVersion, "v")
  62. ver = strings.TrimSuffix(ver, ".0")
  63. return "https://blog.writefreely.org/version-" + strings.ReplaceAll(ver, ".", "-")
  64. }
  65. // newUpdatesCache returns an initialized updates cache
  66. func newUpdatesCache() *updatesCache {
  67. cache := updatesCache{
  68. frequency: updatesCacheTime,
  69. currentVersion: "v" + softwareVer,
  70. }
  71. cache.CheckNow()
  72. return &cache
  73. }
  74. // InitUpdates initializes the updates cache, if the config value is set
  75. func (app *App) InitUpdates() {
  76. if app.cfg.App.UpdateChecks {
  77. app.updates = newUpdatesCache()
  78. }
  79. }
  80. func newVersionCheck(serverVersion string) (string, error) {
  81. res, err := http.Get("https://version.writefreely.org")
  82. if err == nil && res.StatusCode == http.StatusOK {
  83. defer res.Body.Close()
  84. body, err := ioutil.ReadAll(res.Body)
  85. if err != nil {
  86. return "", err
  87. }
  88. return string(body), nil
  89. }
  90. return "", err
  91. }