database.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package main
  2. import (
  3. "archive/zip"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "path/filepath"
  10. "time"
  11. "github.com/HouzuoGuo/tiedot/db"
  12. "github.com/fatih/color"
  13. )
  14. func backupDatabase() error {
  15. if err := os.MkdirAll(pathDatabaseBackups, 0755); err != nil {
  16. return err
  17. }
  18. file, err := os.Create(pathDatabaseBackups + string(os.PathSeparator) + time.Now().Format("2006-01-02_15-04-05.000000000") + ".zip")
  19. if err != nil {
  20. return err
  21. }
  22. defer file.Close()
  23. w := zip.NewWriter(file)
  24. defer w.Close()
  25. err = filepath.Walk(pathDatabaseBase, func(path string, info os.FileInfo, err error) error {
  26. if err != nil {
  27. return err
  28. }
  29. if info.IsDir() {
  30. return nil
  31. }
  32. file, err := os.Open(path)
  33. if err != nil {
  34. return err
  35. }
  36. defer file.Close()
  37. // Ensure that `path` is not absolute; it should not start with "/".
  38. // This snippet happens to work because I don't use
  39. // absolute paths, but ensure your real-world code
  40. // transforms path into a zip-root relative path.
  41. f, err := w.Create(path)
  42. if err != nil {
  43. return err
  44. }
  45. _, err = io.Copy(f, file)
  46. if err != nil {
  47. return err
  48. }
  49. return nil
  50. })
  51. if err != nil {
  52. return err
  53. }
  54. return nil
  55. }
  56. func dbInsertDownload(download *downloadItem) error {
  57. _, err := myDB.Use("Downloads").Insert(map[string]interface{}{
  58. "URL": download.URL,
  59. "Time": download.Time.String(),
  60. "Destination": download.Destination,
  61. "Filename": download.Filename,
  62. "ChannelID": download.ChannelID,
  63. "UserID": download.UserID,
  64. })
  65. return err
  66. }
  67. func dbFindDownloadByID(id int) *downloadItem {
  68. downloads := myDB.Use("Downloads")
  69. readBack, err := downloads.Read(id)
  70. if err != nil {
  71. log.Println(lg("Database", "Downloads", color.HiRedString, "Failed to read database:\t%s", err))
  72. }
  73. timeT, _ := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", readBack["Time"].(string))
  74. return &downloadItem{
  75. URL: readBack["URL"].(string),
  76. Time: timeT,
  77. Destination: readBack["Destination"].(string),
  78. Filename: readBack["Filename"].(string),
  79. ChannelID: readBack["ChannelID"].(string),
  80. UserID: readBack["UserID"].(string),
  81. }
  82. }
  83. func dbFindDownloadByURL(inputURL string) []*downloadItem {
  84. var query interface{}
  85. json.Unmarshal([]byte(fmt.Sprintf(`[{"eq": "%s", "in": ["URL"]}]`, inputURL)), &query)
  86. queryResult := make(map[int]struct{})
  87. db.EvalQuery(query, myDB.Use("Downloads"), &queryResult)
  88. downloadedImages := make([]*downloadItem, 0)
  89. for id := range queryResult {
  90. downloadedImages = append(downloadedImages, dbFindDownloadByID(id))
  91. }
  92. return downloadedImages
  93. }
  94. func dbDeleteByChannelID(channelID string) {
  95. var query interface{}
  96. json.Unmarshal([]byte(fmt.Sprintf(`[{"eq": "%s", "in": ["ChannelID"]}]`, channelID)), &query)
  97. queryResult := make(map[int]struct{})
  98. db.EvalQuery(query, myDB.Use("Downloads"), &queryResult)
  99. for id := range queryResult {
  100. myDB.Use("Downloads").Delete(id)
  101. }
  102. }
  103. //#region Statistics
  104. func dbDownloadCount() int {
  105. i := 0
  106. myDB.Use("Downloads").ForEachDoc(func(id int, docContent []byte) (willMoveOn bool) {
  107. i++
  108. return true
  109. })
  110. return i
  111. }
  112. func dbDownloadCountByChannel(channelID string) int {
  113. var query interface{}
  114. json.Unmarshal([]byte(fmt.Sprintf(`[{"eq": "%s", "in": ["ChannelID"]}]`, channelID)), &query)
  115. queryResult := make(map[int]struct{})
  116. db.EvalQuery(query, myDB.Use("Downloads"), &queryResult)
  117. downloadedImages := make([]*downloadItem, 0)
  118. for id := range queryResult {
  119. downloadedImages = append(downloadedImages, dbFindDownloadByID(id))
  120. }
  121. return len(downloadedImages)
  122. }
  123. //#endregion