This commit is contained in:
parent
e20ca6aab0
commit
4b9085fe95
@ -31,6 +31,9 @@ func main() {
|
||||
}
|
||||
|
||||
pool := pools.NewProxyPool(cfg.Proxy.Subscribes)
|
||||
|
||||
go pool.CronUpdate(_ctx, cfg.Proxy.Interval) //定时更新代理
|
||||
|
||||
pusherCtl := pusher.NewController(_ctx, db)
|
||||
ch := make(chan model.PushMsg, 30)
|
||||
pusherCtl.Consume(ch)
|
||||
@ -45,6 +48,7 @@ func main() {
|
||||
|
||||
server.NewWatcherController(watcherCtl).RegistryRouter(api)
|
||||
server.NewPusherSvcController(pusherCtl).RegistryRouter(api)
|
||||
server.NewProxySvc(pool).RegistryRouter(api)
|
||||
|
||||
if err = r.Listen(":2280"); err != nil {
|
||||
glog.Warningf("server over: %v", err)
|
||||
|
@ -13,7 +13,7 @@ type Product struct {
|
||||
UpdateErr bool `json:"updateErr"` //更新出错了
|
||||
|
||||
Uid string `json:"uid" gorm:"index:,unique"`
|
||||
Pid string `json:"pid" gorm:"index"` //产品编号
|
||||
Pid string `json:"pid" gorm:"index:,not null"` //产品编号
|
||||
Name string `json:"name"`
|
||||
Brand string `json:"brand"`
|
||||
Website WebsiteType `json:"website"` //是什么网站
|
||||
|
@ -1,5 +1,8 @@
|
||||
package options
|
||||
|
||||
import "time"
|
||||
|
||||
type ProxyOption struct {
|
||||
Subscribes []string `yaml:"subscribes"`
|
||||
Subscribes []string `yaml:"subscribes"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ import (
|
||||
|
||||
type ProxyPool struct {
|
||||
m sync.Mutex
|
||||
proxys proxy.ProxyList
|
||||
proxies proxy.ProxyList
|
||||
subscribes []string //订阅url
|
||||
updated time.Time
|
||||
}
|
||||
|
||||
func NewProxyPool(subscribes []string) *ProxyPool {
|
||||
@ -26,9 +27,13 @@ func NewProxyPool(subscribes []string) *ProxyPool {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *ProxyPool) Status() (proxy.ProxyList, time.Time) {
|
||||
return p.proxies, p.updated
|
||||
}
|
||||
|
||||
// Update 更新代理池
|
||||
func (p *ProxyPool) Update() {
|
||||
var list = make(proxy.ProxyList, 0, len(p.proxys))
|
||||
var list = make(proxy.ProxyList, 0, len(p.proxies))
|
||||
for _, url := range p.subscribes {
|
||||
subscribeGetter, err := getter.NewSubscribe(tool.Options{"url": url})
|
||||
if err != nil {
|
||||
@ -40,12 +45,16 @@ func (p *ProxyPool) Update() {
|
||||
glog.Infof("代理源共 %d 个: %v", len(p.subscribes), p.subscribes)
|
||||
glog.Infof("获取代理共 %d 个", len(list))
|
||||
p.m.Lock()
|
||||
p.proxys = list
|
||||
p.proxies = list
|
||||
p.m.Unlock()
|
||||
p.updated = time.Now()
|
||||
}
|
||||
|
||||
// CronUpdate 定时更新
|
||||
func (p *ProxyPool) CronUpdate(ctx context.Context, interval time.Duration) {
|
||||
if interval == 0 {
|
||||
interval = time.Minute * 30
|
||||
}
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
@ -61,12 +70,12 @@ func (p *ProxyPool) CronUpdate(ctx context.Context, interval time.Duration) {
|
||||
// RandomIterator 获取随机代理的迭代器
|
||||
func (p *ProxyPool) RandomIterator() func() proxy.Proxy {
|
||||
return func() (proxy proxy.Proxy) {
|
||||
if len(p.proxys) == 0 {
|
||||
if len(p.proxies) == 0 {
|
||||
return nil
|
||||
}
|
||||
p.m.Lock()
|
||||
defer p.m.Unlock()
|
||||
curIndex := rand.Intn(len(p.proxys))
|
||||
return p.proxys[curIndex]
|
||||
curIndex := rand.Intn(len(p.proxies))
|
||||
return p.proxies[curIndex]
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ func (c *CoachOutlet) Restart() {
|
||||
c.Cancel()
|
||||
go c.Watch()
|
||||
}
|
||||
|
||||
func (c *CoachOutlet) Watch() {
|
||||
c.ctx, c.cancel = context.WithCancel(c.fCtx)
|
||||
if err := c.db.Model(&model.Product{}).Where("uid", c.Uid()).Updates(map[string]interface{}{"watch": true, "orderable": false}).Error; err != nil {
|
||||
|
@ -73,8 +73,8 @@ func (c *Controller) RunWatcher(opt *options.CoachOutletOption) error {
|
||||
uid := opt.Uid()
|
||||
err := c.db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "uid"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"watch", "remark", "orderable", "pusher_ids", "deleted_at"}),
|
||||
}).Create(&model.Product{Uid: uid, Watch: true, Remark: opt.Remark, Orderable: false, PusherIds: opt.PusherIds}).Error
|
||||
DoUpdates: clause.AssignmentColumns([]string{"pid", "watch", "remark", "orderable", "pusher_ids", "deleted_at"}),
|
||||
}).Create(&model.Product{Uid: uid, Pid: opt.Pid, Watch: true, Remark: opt.Remark, Orderable: false, PusherIds: opt.PusherIds}).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
28
server/proxy_svc.go
Normal file
28
server/proxy_svc.go
Normal file
@ -0,0 +1,28 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v3"
|
||||
pool "haitao_watcher/pkg/pools"
|
||||
)
|
||||
|
||||
type ProxySvc struct {
|
||||
pool *pool.ProxyPool
|
||||
}
|
||||
|
||||
func NewProxySvc(pool *pool.ProxyPool) *ProxySvc {
|
||||
return &ProxySvc{
|
||||
pool: pool,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ProxySvc) RegistryRouter(r fiber.Router) {
|
||||
r.Get("proxies/status", s.GetStatusInfo)
|
||||
}
|
||||
|
||||
func (s *ProxySvc) GetStatusInfo(ctx fiber.Ctx) error {
|
||||
list, updated := s.pool.Status()
|
||||
return ctx.JSON(map[string]interface{}{
|
||||
"list": list,
|
||||
"updated": updated,
|
||||
})
|
||||
}
|
7
wwwroot/src/api/proxies.js
Normal file
7
wwwroot/src/api/proxies.js
Normal file
@ -0,0 +1,7 @@
|
||||
import {mande} from "mande";
|
||||
|
||||
const pushers = mande('/api/v1/proxies')
|
||||
|
||||
export const getProxiesStatus = () => {
|
||||
return pushers.get("/status")
|
||||
}
|
@ -1,12 +1,36 @@
|
||||
<template>
|
||||
<div class="h-[100px] shadow-lg flex items-center px-12 space-x-4 z-10">
|
||||
<img class="h-[60px]" src="@/assets/logo.png" alt="">
|
||||
<div class="text-[24px] font-bold">
|
||||
可达鸭海淘蹲货
|
||||
<div class="h-[100px] shadow-lg flex items-center justify-between px-12 z-10">
|
||||
<div class="flex space-x-4 items-center">
|
||||
<img class="h-[60px]" src="@/assets/logo.png" alt="">
|
||||
<div class="text-[24px] font-bold">
|
||||
可达鸭海淘蹲货
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>当前代理个数: {{proxiesInfo.list.length}}</div>
|
||||
<div class="text-[14px]">代理更新时间:{{moment(proxiesInfo.updated).format('YYYY-MM-DD HH:mm:ss')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {onMounted, reactive} from "vue";
|
||||
import {getProxiesStatus} from "@/api/proxies.js";
|
||||
import moment from "moment";
|
||||
|
||||
const proxiesInfo = reactive({
|
||||
list:[],
|
||||
updated: ''
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
loadProxiesInfo()
|
||||
})
|
||||
const loadProxiesInfo = ()=>{
|
||||
getProxiesStatus().then(res=>{
|
||||
proxiesInfo.list = res.list
|
||||
proxiesInfo.updated = res.updated
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
Loading…
Reference in New Issue
Block a user