settings.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package form // import "miniflux.app/v2/internal/ui/form"
  4. import (
  5. "net/http"
  6. "strconv"
  7. "miniflux.app/v2/internal/locale"
  8. "miniflux.app/v2/internal/model"
  9. )
  10. // SettingsForm represents the settings form.
  11. type SettingsForm struct {
  12. Username string
  13. Password string
  14. Confirmation string
  15. Theme string
  16. Language string
  17. Timezone string
  18. EntryDirection string
  19. EntryOrder string
  20. EntriesPerPage int
  21. KeyboardShortcuts bool
  22. ShowReadingTime bool
  23. CustomCSS string
  24. EntrySwipe bool
  25. GestureNav string
  26. DisplayMode string
  27. DefaultReadingSpeed int
  28. CJKReadingSpeed int
  29. DefaultHomePage string
  30. CategoriesSortingOrder string
  31. MarkReadOnView bool
  32. MediaPlaybackRate float64
  33. BlockFilterEntryRules string
  34. KeepFilterEntryRules string
  35. }
  36. // Merge updates the fields of the given user.
  37. func (s *SettingsForm) Merge(user *model.User) *model.User {
  38. user.Username = s.Username
  39. user.Theme = s.Theme
  40. user.Language = s.Language
  41. user.Timezone = s.Timezone
  42. user.EntryDirection = s.EntryDirection
  43. user.EntryOrder = s.EntryOrder
  44. user.EntriesPerPage = s.EntriesPerPage
  45. user.KeyboardShortcuts = s.KeyboardShortcuts
  46. user.ShowReadingTime = s.ShowReadingTime
  47. user.Stylesheet = s.CustomCSS
  48. user.EntrySwipe = s.EntrySwipe
  49. user.GestureNav = s.GestureNav
  50. user.DisplayMode = s.DisplayMode
  51. user.CJKReadingSpeed = s.CJKReadingSpeed
  52. user.DefaultReadingSpeed = s.DefaultReadingSpeed
  53. user.DefaultHomePage = s.DefaultHomePage
  54. user.CategoriesSortingOrder = s.CategoriesSortingOrder
  55. user.MarkReadOnView = s.MarkReadOnView
  56. user.MediaPlaybackRate = s.MediaPlaybackRate
  57. user.BlockFilterEntryRules = s.BlockFilterEntryRules
  58. user.KeepFilterEntryRules = s.KeepFilterEntryRules
  59. if s.Password != "" {
  60. user.Password = s.Password
  61. }
  62. return user
  63. }
  64. // Validate makes sure the form values are valid.
  65. func (s *SettingsForm) Validate() *locale.LocalizedError {
  66. if s.Username == "" || s.Theme == "" || s.Language == "" || s.Timezone == "" || s.EntryDirection == "" || s.DisplayMode == "" || s.DefaultHomePage == "" {
  67. return locale.NewLocalizedError("error.settings_mandatory_fields")
  68. }
  69. if s.CJKReadingSpeed <= 0 || s.DefaultReadingSpeed <= 0 {
  70. return locale.NewLocalizedError("error.settings_reading_speed_is_positive")
  71. }
  72. if s.Confirmation == "" {
  73. // Firefox insists on auto-completing the password field.
  74. // If the confirmation field is blank, the user probably
  75. // didn't intend to change their password.
  76. s.Password = ""
  77. } else if s.Password != "" {
  78. if s.Password != s.Confirmation {
  79. return locale.NewLocalizedError("error.different_passwords")
  80. }
  81. }
  82. if s.MediaPlaybackRate < 0.25 || s.MediaPlaybackRate > 4 {
  83. return locale.NewLocalizedError("error.settings_media_playback_rate_range")
  84. }
  85. return nil
  86. }
  87. // NewSettingsForm returns a new SettingsForm.
  88. func NewSettingsForm(r *http.Request) *SettingsForm {
  89. entriesPerPage, err := strconv.ParseInt(r.FormValue("entries_per_page"), 10, 0)
  90. if err != nil {
  91. entriesPerPage = 0
  92. }
  93. defaultReadingSpeed, err := strconv.ParseInt(r.FormValue("default_reading_speed"), 10, 0)
  94. if err != nil {
  95. defaultReadingSpeed = 0
  96. }
  97. cjkReadingSpeed, err := strconv.ParseInt(r.FormValue("cjk_reading_speed"), 10, 0)
  98. if err != nil {
  99. cjkReadingSpeed = 0
  100. }
  101. mediaPlaybackRate, err := strconv.ParseFloat(r.FormValue("media_playback_rate"), 64)
  102. if err != nil {
  103. mediaPlaybackRate = 1
  104. }
  105. return &SettingsForm{
  106. Username: r.FormValue("username"),
  107. Password: r.FormValue("password"),
  108. Confirmation: r.FormValue("confirmation"),
  109. Theme: r.FormValue("theme"),
  110. Language: r.FormValue("language"),
  111. Timezone: r.FormValue("timezone"),
  112. EntryDirection: r.FormValue("entry_direction"),
  113. EntryOrder: r.FormValue("entry_order"),
  114. EntriesPerPage: int(entriesPerPage),
  115. KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1",
  116. ShowReadingTime: r.FormValue("show_reading_time") == "1",
  117. CustomCSS: r.FormValue("custom_css"),
  118. EntrySwipe: r.FormValue("entry_swipe") == "1",
  119. GestureNav: r.FormValue("gesture_nav"),
  120. DisplayMode: r.FormValue("display_mode"),
  121. DefaultReadingSpeed: int(defaultReadingSpeed),
  122. CJKReadingSpeed: int(cjkReadingSpeed),
  123. DefaultHomePage: r.FormValue("default_home_page"),
  124. CategoriesSortingOrder: r.FormValue("categories_sorting_order"),
  125. MarkReadOnView: r.FormValue("mark_read_on_view") == "1",
  126. MediaPlaybackRate: mediaPlaybackRate,
  127. BlockFilterEntryRules: r.FormValue("block_filter_entry_rules"),
  128. KeepFilterEntryRules: r.FormValue("keep_filter_entry_rules"),
  129. }
  130. }