streams.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package streams
  2. import (
  3. "net/http"
  4. "os"
  5. "strings"
  6. "time"
  7. "github.com/0xJacky/Nginx-UI/api"
  8. "github.com/0xJacky/Nginx-UI/internal/config"
  9. "github.com/0xJacky/Nginx-UI/internal/nginx"
  10. "github.com/0xJacky/Nginx-UI/internal/stream"
  11. "github.com/0xJacky/Nginx-UI/query"
  12. "github.com/gin-gonic/gin"
  13. "github.com/sashabaranov/go-openai"
  14. "github.com/uozi-tech/cosy"
  15. )
  16. type Stream struct {
  17. ModifiedAt time.Time `json:"modified_at"`
  18. Advanced bool `json:"advanced"`
  19. Enabled bool `json:"enabled"`
  20. Name string `json:"name"`
  21. Config string `json:"config"`
  22. ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
  23. Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"`
  24. Filepath string `json:"filepath"`
  25. SyncNodeIDs []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
  26. }
  27. func GetStreams(c *gin.Context) {
  28. name := c.Query("name")
  29. orderBy := c.Query("order_by")
  30. sort := c.DefaultQuery("sort", "desc")
  31. configFiles, err := os.ReadDir(nginx.GetConfPath("streams-available"))
  32. if err != nil {
  33. api.ErrHandler(c, err)
  34. return
  35. }
  36. enabledConfig, err := os.ReadDir(nginx.GetConfPath("streams-enabled"))
  37. if err != nil {
  38. api.ErrHandler(c, err)
  39. return
  40. }
  41. enabledConfigMap := make(map[string]bool)
  42. for i := range enabledConfig {
  43. enabledConfigMap[enabledConfig[i].Name()] = true
  44. }
  45. var configs []config.Config
  46. for i := range configFiles {
  47. file := configFiles[i]
  48. fileInfo, _ := file.Info()
  49. if !file.IsDir() {
  50. if name != "" && !strings.Contains(file.Name(), name) {
  51. continue
  52. }
  53. configs = append(configs, config.Config{
  54. Name: file.Name(),
  55. ModifiedAt: fileInfo.ModTime(),
  56. Size: fileInfo.Size(),
  57. IsDir: fileInfo.IsDir(),
  58. Enabled: enabledConfigMap[file.Name()],
  59. })
  60. }
  61. }
  62. configs = config.Sort(orderBy, sort, configs)
  63. c.JSON(http.StatusOK, gin.H{
  64. "data": configs,
  65. })
  66. }
  67. func GetStream(c *gin.Context) {
  68. name := c.Param("name")
  69. path := nginx.GetConfPath("streams-available", name)
  70. file, err := os.Stat(path)
  71. if os.IsNotExist(err) {
  72. c.JSON(http.StatusNotFound, gin.H{
  73. "message": "file not found",
  74. })
  75. return
  76. }
  77. enabled := true
  78. if _, err := os.Stat(nginx.GetConfPath("streams-enabled", name)); os.IsNotExist(err) {
  79. enabled = false
  80. }
  81. g := query.ChatGPTLog
  82. chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
  83. if err != nil {
  84. api.ErrHandler(c, err)
  85. return
  86. }
  87. if chatgpt.Content == nil {
  88. chatgpt.Content = make([]openai.ChatCompletionMessage, 0)
  89. }
  90. s := query.Stream
  91. streamModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
  92. if err != nil {
  93. api.ErrHandler(c, err)
  94. return
  95. }
  96. if streamModel.Advanced {
  97. origContent, err := os.ReadFile(path)
  98. if err != nil {
  99. api.ErrHandler(c, err)
  100. return
  101. }
  102. c.JSON(http.StatusOK, Stream{
  103. ModifiedAt: file.ModTime(),
  104. Advanced: streamModel.Advanced,
  105. Enabled: enabled,
  106. Name: name,
  107. Config: string(origContent),
  108. ChatGPTMessages: chatgpt.Content,
  109. Filepath: path,
  110. SyncNodeIDs: streamModel.SyncNodeIDs,
  111. })
  112. return
  113. }
  114. nginxConfig, err := nginx.ParseNgxConfig(path)
  115. if err != nil {
  116. api.ErrHandler(c, err)
  117. return
  118. }
  119. c.JSON(http.StatusOK, Stream{
  120. ModifiedAt: file.ModTime(),
  121. Advanced: streamModel.Advanced,
  122. Enabled: enabled,
  123. Name: name,
  124. Config: nginxConfig.FmtCode(),
  125. Tokenized: nginxConfig,
  126. ChatGPTMessages: chatgpt.Content,
  127. Filepath: path,
  128. SyncNodeIDs: streamModel.SyncNodeIDs,
  129. })
  130. }
  131. func SaveStream(c *gin.Context) {
  132. name := c.Param("name")
  133. var json struct {
  134. Content string `json:"content" binding:"required"`
  135. SyncNodeIDs []uint64 `json:"sync_node_ids"`
  136. Overwrite bool `json:"overwrite"`
  137. }
  138. if !cosy.BindAndValid(c, &json) {
  139. return
  140. }
  141. err := stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs)
  142. if err != nil {
  143. api.ErrHandler(c, err)
  144. return
  145. }
  146. GetStream(c)
  147. }
  148. func EnableStream(c *gin.Context) {
  149. err := stream.Enable(c.Param("name"))
  150. if err != nil {
  151. api.ErrHandler(c, err)
  152. return
  153. }
  154. c.JSON(http.StatusOK, gin.H{
  155. "message": "ok",
  156. })
  157. }
  158. func DisableStream(c *gin.Context) {
  159. err := stream.Disable(c.Param("name"))
  160. if err != nil {
  161. api.ErrHandler(c, err)
  162. return
  163. }
  164. c.JSON(http.StatusOK, gin.H{
  165. "message": "ok",
  166. })
  167. }
  168. func DeleteStream(c *gin.Context) {
  169. err := stream.Delete(c.Param("name"))
  170. if err != nil {
  171. api.ErrHandler(c, err)
  172. return
  173. }
  174. c.JSON(http.StatusOK, gin.H{
  175. "message": "ok",
  176. })
  177. }
  178. func RenameStream(c *gin.Context) {
  179. oldName := c.Param("name")
  180. var json struct {
  181. NewName string `json:"new_name"`
  182. }
  183. if !cosy.BindAndValid(c, &json) {
  184. return
  185. }
  186. err := stream.Rename(oldName, json.NewName)
  187. if err != nil {
  188. api.ErrHandler(c, err)
  189. return
  190. }
  191. c.JSON(http.StatusOK, gin.H{
  192. "message": "ok",
  193. })
  194. }