EMLOG友链状态实时更新


avatar
铭心 2024-10-15 104

我来填之前开的坑了,EMLOG友链状态实时更新工具已经写好了。接下来看看功能以及如何使用吧(*^▽^*)

简介

EMLOG友链状态实时更新插件是一款用于检测和显示友情链接状态的插件。通过该插件,您可以实时监测友情链接是否正常,方便及时处理异常链接,确保友情链接的稳定性和有效性。

功能特点

  • 实时监测友情链接状态
  • 目前仅支持状态码监测,后续将更新其他监测方式大概
  • 异常状态提醒功能嗯~待实现~~

安装方法

  1. Linux用户可以点我下载
  2. 下载后将压缩包解压,按照配置文件conf.yaml进行配置
  3. 给予执行权限:
chmod +x emstatus && nohup emstatus > /dev/null 2>&1 &

注:其他平台可以自行复制下面代码进行二进制构建

配置项说明

  • time: 10s 监测时间间隔,每隔多久对友链检测一次,支持时【h】分【m】秒【s】组合
  • action: 0 如果检测到无法访问如何处理0【隐藏友链】1【删除友链】,建议隐藏

工具源码

<code">package main

import (
    "crypto/tls"
    "database/sql"
    "fmt"
    "io"
    "log"
    "os"
    "sync"
    "time"

    _ "github.com/go-sql-driver/mysql"
    "gopkg.in/resty.v1"
    "gopkg.in/yaml.v2"
)

type Config struct {
    MySQL struct {
        Host     string `yaml:"host"`
        Port     int    `yaml:"port"`
        User     string `yaml:"user"`
        Password string `yaml:"password"`
        Database string `yaml:"database"`
    } `yaml:"mysql"`
    Links struct {
        Time   string `yaml:"time"`
        Action int    `yaml:"action"`
    } `yaml:"links"`
}

func main() {
    client := resty.New().
        SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})

    config, err := readConfig("conf.yaml")
    if err != nil {
        log.Fatalf("无法读取配置文件: %v", err)
    }

    interval, err := time.ParseDuration(config.Links.Time)
    if err != nil {
        log.Fatalf("无法解析时间间隔: %v", err)
    }

    dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s",
        config.MySQL.User,
        config.MySQL.Password,
        config.MySQL.Host,
        config.MySQL.Port,
        config.MySQL.Database,
    )

    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    err = db.Ping()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("成功连接到数据库!")

    for {
        checkLinks(db, client, config)
        time.Sleep(interval)
    }
}

func checkLinks(db *sql.DB, client *resty.Client, config *Config) {
    rows, err := db.Query("SELECT id, siteurl FROM emlog_link WHERE hide = 'n'")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    var wg sync.WaitGroup

    columns, err := rows.Columns()
    if err != nil {
        log.Fatal(err)
    }

    values := make([]interface{}, len(columns))
    valuePtrs := make([]interface{}, len(columns))
    for i := range values {
        valuePtrs[i] = &values[i]
    }

    log.Printf("================================================================")
    for rows.Next() {
        err := rows.Scan(valuePtrs...)
        if err != nil {
            log.Fatal(err)
        }

        result := make(map[string]interface{})
        for i, col := range columns {
            val := values[i]

            if b, ok := val.([]byte); ok {
                result[col] = string(b)
            } else {
                result[col] = val
            }
        }

        wg.Add(1)
        go func(result map[string]interface{}) {
            defer wg.Done()
            log.Printf("正在检测友链: %s", result["siteurl"].(string))
            res, err := client.R().Get(result["siteurl"].(string))
            if err != nil {
                if config.Links.Action == 0 {
                    log.Printf("友链检测失败,将对友链进行【隐藏】,错误信息: %s", err)
                } else if config.Links.Action == 1 {
                    log.Printf("友链检测失败,将对友链进行【删除】,错误信息: %s", err)
                }
            }

            if res.StatusCode() != 200 && config.Links.Action == 0 {
                _, err := db.Exec("UPDATE emlog_link SET hide = 'y' WHERE id = ?", result["id"])
                if err != nil {
                    log.Printf("更新记录失败: %v", err)
                }
            } else if res.StatusCode() != 200 && config.Links.Action == 1 {
                _, err := db.Exec("DELETE FROM emlog_link WHERE id = ?", result["id"])
                if err != nil {
                    log.Printf("删除记录失败: %v", err)
                }
            }
        }(result)
    }

    if err = rows.Err(); err != nil {
        log.Fatal(err)
    }

    wg.Wait()
}

func readConfig(path string) (*Config, error) {
    var config Config

    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    data, err := io.ReadAll(file)
    if err != nil {
        return nil, err
    }

    err = yaml.Unmarshal(data, &config)
    if err != nil {
        return nil, err
    }

    return &config, nil
}

暂无评论

发表评论
OωO表情