puppet.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
  2. // Copyright (C) 2020 Tulir Asokan
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. package database
  17. import (
  18. "database/sql"
  19. log "maunium.net/go/maulogger/v2"
  20. "github.com/Rhymen/go-whatsapp"
  21. "maunium.net/go/mautrix/id"
  22. )
  23. type PuppetQuery struct {
  24. db *Database
  25. log log.Logger
  26. }
  27. func (pq *PuppetQuery) New() *Puppet {
  28. return &Puppet{
  29. db: pq.db,
  30. log: pq.log,
  31. EnablePresence: true,
  32. EnableReceipts: true,
  33. }
  34. }
  35. func (pq *PuppetQuery) GetAll() (puppets []*Puppet) {
  36. rows, err := pq.db.Query("SELECT jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch, enable_presence, enable_receipts FROM puppet")
  37. if err != nil || rows == nil {
  38. return nil
  39. }
  40. defer rows.Close()
  41. for rows.Next() {
  42. puppets = append(puppets, pq.New().Scan(rows))
  43. }
  44. return
  45. }
  46. func (pq *PuppetQuery) Get(jid whatsapp.JID) *Puppet {
  47. row := pq.db.QueryRow("SELECT jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch, enable_presence, enable_receipts FROM puppet WHERE jid=$1", jid)
  48. if row == nil {
  49. return nil
  50. }
  51. return pq.New().Scan(row)
  52. }
  53. func (pq *PuppetQuery) GetByCustomMXID(mxid id.UserID) *Puppet {
  54. row := pq.db.QueryRow("SELECT jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch, enable_presence, enable_receipts FROM puppet WHERE custom_mxid=$1", mxid)
  55. if row == nil {
  56. return nil
  57. }
  58. return pq.New().Scan(row)
  59. }
  60. func (pq *PuppetQuery) GetAllWithCustomMXID() (puppets []*Puppet) {
  61. rows, err := pq.db.Query("SELECT jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch, enable_presence, enable_receipts FROM puppet WHERE custom_mxid<>''")
  62. if err != nil || rows == nil {
  63. return nil
  64. }
  65. defer rows.Close()
  66. for rows.Next() {
  67. puppets = append(puppets, pq.New().Scan(rows))
  68. }
  69. return
  70. }
  71. type Puppet struct {
  72. db *Database
  73. log log.Logger
  74. JID whatsapp.JID
  75. Avatar string
  76. AvatarURL id.ContentURI
  77. Displayname string
  78. NameQuality int8
  79. CustomMXID id.UserID
  80. AccessToken string
  81. NextBatch string
  82. EnablePresence bool
  83. EnableReceipts bool
  84. }
  85. func (puppet *Puppet) Scan(row Scannable) *Puppet {
  86. var displayname, avatar, avatarURL, customMXID, accessToken, nextBatch sql.NullString
  87. var quality sql.NullInt64
  88. var enablePresence, enableReceipts sql.NullBool
  89. err := row.Scan(&puppet.JID, &avatar, &avatarURL, &displayname, &quality, &customMXID, &accessToken, &nextBatch, &enablePresence, &enableReceipts)
  90. if err != nil {
  91. if err != sql.ErrNoRows {
  92. puppet.log.Errorln("Database scan failed:", err)
  93. }
  94. return nil
  95. }
  96. puppet.Displayname = displayname.String
  97. puppet.Avatar = avatar.String
  98. puppet.AvatarURL, _ = id.ParseContentURI(avatarURL.String)
  99. puppet.NameQuality = int8(quality.Int64)
  100. puppet.CustomMXID = id.UserID(customMXID.String)
  101. puppet.AccessToken = accessToken.String
  102. puppet.NextBatch = nextBatch.String
  103. puppet.EnablePresence = enablePresence.Bool
  104. puppet.EnableReceipts = enableReceipts.Bool
  105. return puppet
  106. }
  107. func (puppet *Puppet) Insert() {
  108. _, err := puppet.db.Exec("INSERT INTO puppet (jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch, enable_presence, enable_receipts) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
  109. puppet.JID, puppet.Avatar, puppet.AvatarURL.String(), puppet.Displayname, puppet.NameQuality, puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.EnablePresence, puppet.EnableReceipts)
  110. if err != nil {
  111. puppet.log.Warnfln("Failed to insert %s: %v", puppet.JID, err)
  112. }
  113. }
  114. func (puppet *Puppet) Update() {
  115. _, err := puppet.db.Exec("UPDATE puppet SET displayname=$1, name_quality=$2, avatar=$3, avatar_url=$4, custom_mxid=$5, access_token=$6, next_batch=$7, enable_presence=$8, enable_receipts=$9 WHERE jid=$10",
  116. puppet.Displayname, puppet.NameQuality, puppet.Avatar, puppet.AvatarURL.String(), puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.EnablePresence, puppet.EnableReceipts, puppet.JID)
  117. if err != nil {
  118. puppet.log.Warnfln("Failed to update %s->%s: %v", puppet.JID, err)
  119. }
  120. }