Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
twitter_syncer
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Odysseus
twitter_syncer
Commits
9147792d
Commit
9147792d
authored
Nov 08, 2024
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add monitor
parent
4581f23b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
261 additions
and
57 deletions
+261
-57
acmanager.go
acmanager/acmanager.go
+83
-57
warning.go
acmanager/warning.go
+147
-0
warning_test.go
acmanager/warning_test.go
+21
-0
go.mod
go.mod
+2
-0
go.sum
go.sum
+4
-0
main.go
main.go
+4
-0
No files found.
acmanager/acmanager.go
View file @
9147792d
...
...
@@ -2,8 +2,10 @@ package acmanager
import
(
"encoding/json"
"github.com/gofiber/fiber/v2/log"
"github.com/supabase-community/supabase-go"
"net/http"
"time"
)
type
Account
struct
{
...
...
@@ -17,81 +19,105 @@ type Account struct {
Available
bool
`json:"available"`
}
func
(
a
Account
)
Stop
()
{
// todo: stop the account.
}
type
Manager
struct
{
localUser
map
[
string
]
Account
quit
chan
struct
{}
client
*
supabase
.
Client
availableUser
map
[
string
]
Account
userBlockedRecord
map
[
string
]
time
.
Time
warningHistory
[]
WarningRecord
}
func
NewManager
()
*
Manager
{
return
&
Manager
{
localUser
:
make
(
map
[
string
]
Account
),
func
NewManager
(
client
*
supabase
.
Client
)
*
Manager
{
m
:=
&
Manager
{
quit
:
make
(
chan
struct
{}),
availableUser
:
make
(
map
[
string
]
Account
),
warningHistory
:
make
([]
WarningRecord
,
0
),
client
:
client
,
}
m
.
warningHistory
=
append
(
m
.
warningHistory
,
WarningRecord
{
IsWarning
:
false
,
Time
:
time
.
Now
(),
})
return
m
}
func
(
m
*
Manager
)
Init
()
error
{
user
,
err
:=
GetAllAccounts
()
if
err
!=
nil
{
return
err
func
(
m
*
Manager
)
report
(
current
int
)
{
if
current
<
warningCount
{
// check need to report.
last
:=
m
.
warningHistory
[
len
(
m
.
warningHistory
)
-
1
]
// if last is not warning or last warning passed 5 minutes, send warning email.
if
!
last
.
IsWarning
||
(
last
.
IsWarning
&&
time
.
Now
()
.
After
(
last
.
Time
.
Add
(
time
.
Minute
*
5
)))
{
// send warning email.
if
err
:=
Warning
(
current
);
err
!=
nil
{
// log error.
log
.
Errorf
(
"send warning email error: %s"
,
err
.
Error
())
}
else
{
m
.
warningHistory
=
append
(
m
.
warningHistory
,
WarningRecord
{
IsWarning
:
true
,
Time
:
time
.
Now
(),
})
}
}
}
else
{
last
:=
m
.
warningHistory
[
len
(
m
.
warningHistory
)
-
1
]
if
last
.
IsWarning
{
// send success email.
if
err
:=
Recovered
(
current
);
err
!=
nil
{
// log error.
log
.
Errorf
(
"send success email error: %s"
,
err
.
Error
())
}
else
{
m
.
warningHistory
=
append
(
m
.
warningHistory
,
WarningRecord
{
IsWarning
:
false
,
Time
:
time
.
Now
(),
})
}
}
}
for
_
,
v
:=
range
user
{
m
.
localUser
[
v
.
Username
]
=
v
if
len
(
m
.
warningHistory
)
>
10
{
old
:=
m
.
warningHistory
m
.
warningHistory
=
make
([]
WarningRecord
,
0
)
m
.
warningHistory
=
append
(
m
.
warningHistory
,
old
[
len
(
old
)
-
1
])
}
return
nil
}
func
(
m
*
Manager
)
AddUser
(
account
Account
)
{
if
account
.
Available
{
m
.
addAvailable
(
account
)
}
else
{
m
.
addInAvailable
(
account
)
func
(
m
*
Manager
)
loop
()
{
// loop check available account count.
tc
:=
time
.
NewTicker
(
time
.
Minute
*
1
)
defer
tc
.
Stop
()
for
{
select
{
case
<-
tc
.
C
:
all
,
err
:=
GetAllAccounts
(
m
.
client
)
if
err
==
nil
{
available
:=
make
([]
Account
,
0
)
unavailable
:=
make
([]
Account
,
0
)
for
_
,
v
:=
range
all
{
if
v
.
Available
{
available
=
append
(
available
,
v
)
}
else
{
unavailable
=
append
(
unavailable
,
v
)
}
}
m
.
report
(
len
(
available
))
}
tc
.
Reset
(
time
.
Minute
*
3
)
case
<-
m
.
quit
:
return
}
}
}
func
(
m
*
Manager
)
addAvailable
(
account
Account
)
{
// todo: add to available
func
(
m
*
Manager
)
Start
(
)
{
go
m
.
loop
()
}
func
(
m
*
Manager
)
addInAvailable
(
account
Account
)
{
// todo: add to inavailable.
// do login to check if the account is available.
// if available, add to available.
//sc := twitterscraper.New()
func
(
m
*
Manager
)
Stop
()
{
close
(
m
.
quit
)
}
func
(
m
*
Manager
)
UpdateUser
()
{
dbuser
:=
make
(
map
[
string
]
Account
)
accounts
,
err
:=
GetAllAccounts
()
if
err
!=
nil
{
return
}
for
_
,
v
:=
range
accounts
{
dbuser
[
v
.
Username
]
=
v
}
for
k
,
v
:=
range
m
.
localUser
{
if
_
,
ok
:=
dbuser
[
k
];
!
ok
{
delete
(
m
.
localUser
,
k
)
}
// delete the account, and stop the account.
v
.
Stop
()
}
for
k
,
v
:=
range
dbuser
{
if
_
,
ok
:=
m
.
localUser
[
k
];
!
ok
{
m
.
localUser
[
k
]
=
v
}
}
}
func
GetAllAccounts
()
([]
Account
,
error
)
{
// todo: get client from db.
var
client
*
supabase
.
Client
func
GetAllAccounts
(
client
*
supabase
.
Client
)
([]
Account
,
error
)
{
data
,
count
,
err
:=
client
.
From
(
"accounts"
)
.
Select
(
"*"
,
"exact"
,
false
)
.
Execute
()
//data, count, err := client.From("accounts").Select("*", "exact", false).Eq("available", "true").Execute()
if
err
!=
nil
{
return
nil
,
err
}
...
...
acmanager/warning.go
0 → 100644
View file @
9147792d
package
acmanager
import
(
"fmt"
"gopkg.in/gomail.v2"
"os"
"strconv"
"strings"
"time"
)
const
(
warningEmailTemplate
=
`
Hi there,
Current available account is %d, it is less than %d, please check it.
`
recoversEmailTemplate
=
`
Hi there,
Current available account is %d, warning cancelled.
`
warningCount
=
5
ENV_ALERT_RECEIVERS
=
"TW_ALERT_RECEIVERS"
ENV_ALERT_EMAIL
=
"TW_ALERT_EMAIL"
ENV_EMAIL_SERVER
=
"TW_EMAIL_SERVER"
ENV_EMAIL_PORT
=
"TW_EMAIL_PORT"
ENV_EMAIL_USER
=
"TW_EMAIL_USER"
ENV_EMAIL_PASSWD
=
"TW_EMAIL_PASSWD"
)
type
WarningRecord
struct
{
IsWarning
bool
Time
time
.
Time
}
type
Environment
struct
{
AlertReceivers
[]
string
AlertEmail
string
EmailServer
string
EmailPort
int
EmailUser
string
EmailPasswd
string
}
func
(
e
Environment
)
Available
()
bool
{
if
len
(
e
.
AlertReceivers
)
==
0
||
e
.
AlertEmail
==
""
||
e
.
EmailServer
==
""
||
e
.
EmailPort
==
0
||
e
.
EmailUser
==
""
||
e
.
EmailPasswd
==
""
{
return
false
}
return
true
}
func
getEnv
()
Environment
{
// get env from os.
env
:=
Environment
{}
if
receiver
,
ok
:=
os
.
LookupEnv
(
ENV_ALERT_RECEIVERS
);
ok
{
rs
:=
strings
.
Split
(
receiver
,
","
)
env
.
AlertReceivers
=
rs
}
if
email
,
ok
:=
os
.
LookupEnv
(
ENV_ALERT_EMAIL
);
ok
{
env
.
AlertEmail
=
email
}
if
server
,
ok
:=
os
.
LookupEnv
(
ENV_EMAIL_SERVER
);
ok
{
env
.
EmailServer
=
server
}
if
port
,
ok
:=
os
.
LookupEnv
(
ENV_EMAIL_PORT
);
ok
{
env
.
EmailPort
,
_
=
strconv
.
Atoi
(
port
)
}
if
user
,
ok
:=
os
.
LookupEnv
(
ENV_EMAIL_USER
);
ok
{
env
.
EmailUser
=
user
}
if
passwd
,
ok
:=
os
.
LookupEnv
(
ENV_EMAIL_PASSWD
);
ok
{
env
.
EmailPasswd
=
passwd
}
return
env
}
func
Warning
(
count
int
)
error
{
// send email with warning template.
env
:=
getEnv
()
if
env
.
Available
()
{
// send warning email.
msg
:=
MsgInfo
{
From
:
env
.
AlertEmail
,
To
:
env
.
AlertReceivers
,
Title
:
"New Warning"
,
Content
:
fmt
.
Sprintf
(
warningEmailTemplate
,
count
,
warningCount
),
}
server
:=
ServerInfo
{
Server
:
env
.
EmailServer
,
Port
:
env
.
EmailPort
,
Username
:
env
.
EmailUser
,
Passwd
:
env
.
EmailPasswd
,
}
return
sendMail
(
msg
,
server
)
}
else
{
return
fmt
.
Errorf
(
"email env is not available"
)
}
}
func
Recovered
(
count
int
)
error
{
// send email with warning template.
env
:=
getEnv
()
if
env
.
Available
()
{
// send warning email.
msg
:=
MsgInfo
{
From
:
env
.
AlertEmail
,
To
:
env
.
AlertReceivers
,
Title
:
"Warning Cancelled"
,
Content
:
fmt
.
Sprintf
(
recoversEmailTemplate
,
count
),
}
server
:=
ServerInfo
{
Server
:
env
.
EmailServer
,
Port
:
env
.
EmailPort
,
Username
:
env
.
EmailUser
,
Passwd
:
env
.
EmailPasswd
,
}
return
sendMail
(
msg
,
server
)
}
else
{
return
fmt
.
Errorf
(
"email env is not available"
)
}
}
type
MsgInfo
struct
{
From
string
To
[]
string
Title
string
Content
string
}
type
ServerInfo
struct
{
Server
string
Port
int
Username
string
Passwd
string
}
func
sendMail
(
msg
MsgInfo
,
server
ServerInfo
)
error
{
m
:=
gomail
.
NewMessage
()
m
.
SetHeader
(
"From"
,
msg
.
From
)
m
.
SetHeader
(
"To"
,
msg
.
To
...
)
m
.
SetHeader
(
"Subject"
,
msg
.
Title
)
m
.
SetBody
(
"text/plain"
,
msg
.
Content
)
d
:=
gomail
.
NewDialer
(
server
.
Server
,
server
.
Port
,
server
.
Username
,
server
.
Passwd
)
return
d
.
DialAndSend
(
m
)
}
acmanager/warning_test.go
0 → 100644
View file @
9147792d
package
acmanager
import
"testing"
func
TestWarning
(
t
*
testing
.
T
)
{
err
:=
Warning
(
6
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
else
{
t
.
Log
(
"TestWarning passed"
)
}
}
func
TestRecovered
(
t
*
testing
.
T
)
{
err
:=
Recovered
(
3
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
else
{
t
.
Log
(
"TestRecovered passed"
)
}
}
go.mod
View file @
9147792d
...
...
@@ -58,6 +58,8 @@ require (
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/tools v0.26.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
...
...
go.sum
View file @
9147792d
...
...
@@ -261,11 +261,15 @@ golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
...
...
main.go
View file @
9147792d
...
...
@@ -15,6 +15,7 @@
package
main
import
(
"code.wuban.net.cn/odysseus/twitter_syncer/acmanager"
"fmt"
"github.com/gofiber/swagger"
"log/slog"
...
...
@@ -49,6 +50,9 @@ func main() {
}
}()
manager
:=
acmanager
.
NewManager
(
client
)
manager
.
Start
()
// taskIn = taskInStream
app
:=
fiber
.
New
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment