The backend for the AiteStory website
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.

196 lines
3.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package model
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "git.aiterp.net/AiteRP/aitestory/server"
  7. "git.aiterp.net/gisle/wrouter/generate"
  8. )
  9. // TagTypes are the allowed values for Tag.Type
  10. var TagTypes = []string{
  11. "Location",
  12. "Character",
  13. "Event",
  14. "Organization",
  15. "Source",
  16. "Series",
  17. "Meta",
  18. }
  19. // Tag describes a tag
  20. type Tag struct {
  21. ID string
  22. Type string
  23. Name string
  24. }
  25. // Icon is the API used to get the icon for the tag.
  26. func (tag Tag) Icon() string {
  27. return tag.Type[0:1]
  28. }
  29. // CSSCLass gets the CSS class that colors the tag on the
  30. // page list
  31. func (tag Tag) CSSCLass() string {
  32. return fmt.Sprintf("ttype-%s", strings.ToLower(tag.Type))
  33. }
  34. // Insert adds the tag to the database, giving it a new unique ID
  35. func (tag *Tag) Insert() error {
  36. db := server.Main.DB
  37. // Validate tag type
  38. if err := tag.Validate(); err != nil {
  39. return err
  40. }
  41. // Generate an ID if none exists
  42. if tag.ID == "" {
  43. tag.ID = generate.ID()
  44. }
  45. // Do the thing
  46. _, err := db.Exec("INSERT INTO `tag` (id,type,name,disabled) VALUES (?,?,?,false)", tag.ID, tag.Type, tag.Name)
  47. if err != nil {
  48. return err
  49. }
  50. return nil
  51. }
  52. // Update saves the entry for the tag in the database
  53. func (tag *Tag) Update() error {
  54. db := server.Main.DB
  55. // Validate tag type
  56. if err := tag.Validate(); err != nil {
  57. return err
  58. }
  59. // Do the thing
  60. _, err := db.Exec("UPDATE `tag` SET type=?,name=? WHERE id=?", tag.Type, tag.Name, tag.ID)
  61. if err != nil {
  62. return err
  63. }
  64. return nil
  65. }
  66. // Delete removes a tag from the database
  67. func (tag *Tag) Delete() error {
  68. db := server.Main.DB
  69. // Do the thing
  70. results, err := db.Exec("DELETE FROM `tag` WHERE id=? LIMIT 1", tag.ID)
  71. if err != nil {
  72. return err
  73. }
  74. // Count the stuffs that were done things to
  75. affected, err := results.RowsAffected()
  76. if err != nil {
  77. return err
  78. }
  79. if affected == 0 {
  80. return errors.New("tag not found")
  81. }
  82. return nil
  83. }
  84. // Validate checks the name and type, and returns an error if they're not valid. It's
  85. // ran by Update and Insert before doing anything
  86. func (tag *Tag) Validate() error {
  87. validType := false
  88. for _, tagType := range TagTypes {
  89. if tagType == tag.Type {
  90. validType = true
  91. break
  92. }
  93. }
  94. if !validType {
  95. return errors.New("invalid tag type")
  96. }
  97. // Validate tag name
  98. if len(tag.Name) == 0 || len(tag.Name) > 64 {
  99. return errors.New("invalid length")
  100. }
  101. return nil
  102. }
  103. // Hook returns the url friendly name, which is pretty much just
  104. // adding underscores to it.
  105. func (tag Tag) Hook() string {
  106. return strings.Replace(tag.Name, " ", "_", -1)
  107. }
  108. // FindTag finds a tag by ID
  109. func FindTag(key string, id string) (*Tag, error) {
  110. db := server.Main.DB
  111. // Make damn sure that – should this take user data as key – it
  112. // does not open up for a SQL injection attack
  113. if key != "name" && key != "id" {
  114. return nil, errors.New("invalid key")
  115. }
  116. rows, err := db.Query("SELECT id,type,name FROM `tag` WHERE "+key+"=? AND disabled=false", id)
  117. if err != nil {
  118. return nil, err
  119. }
  120. defer rows.Close()
  121. if !rows.Next() {
  122. return nil, errors.New("not found")
  123. }
  124. tag := new(Tag)
  125. rows.Scan(&tag.ID, &tag.Type, &tag.Name)
  126. return tag, nil
  127. }
  128. // EnsureTag finds or creates a tag.
  129. func EnsureTag(tagType, tagName string) (*Tag, error) {
  130. // Try to find it first
  131. tag, err := FindTag("name", tagName)
  132. if err != nil && err.Error() != "not found" { // You saw nothing
  133. return nil, err
  134. }
  135. // Failing that, make it
  136. if tag == nil {
  137. tag = new(Tag)
  138. tag.Type = tagType
  139. tag.Name = tagName
  140. err = tag.Insert()
  141. if err != nil {
  142. return nil, err
  143. }
  144. }
  145. return tag, nil
  146. }
  147. // ListTags finds all the tags, without filter.
  148. func ListTags() ([]Tag, error) {
  149. db := server.Main.DB
  150. rows, err := db.Query("SELECT id,type,name FROM `tag` WHERE disabled=false")
  151. if err != nil {
  152. return nil, err
  153. }
  154. defer rows.Close()
  155. results := make([]Tag, 0, 64)
  156. for rows.Next() {
  157. tag := Tag{}
  158. rows.Scan(&tag.ID, &tag.Type, &tag.Name)
  159. results = append(results, tag)
  160. }
  161. return results, nil
  162. }