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.

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