This commit is contained in:
Imbus 2024-09-28 06:47:27 +02:00
parent 72177679f4
commit 05127ef72b
9 changed files with 97 additions and 7 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.db

2
Justfile Normal file
View file

@ -0,0 +1,2 @@
run:
go run src/*.go

5
go.mod Normal file
View file

@ -0,0 +1,5 @@
module beretta
go 1.22.7
require github.com/mattn/go-sqlite3 v1.14.23 // indirect

2
go.sum Normal file
View file

@ -0,0 +1,2 @@
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=

49
src/db.go Normal file
View file

@ -0,0 +1,49 @@
package main
import (
_ "embed"
_ "github.com/mattn/go-sqlite3"
"database/sql"
)
//go:embed init.sql
var initSQL string
type Db interface {
// CheckAndStore checks if the tag is already stored in the database and stores it if it's not.
CheckAndStore(repo, tag string) (bool, error)
}
type SQLiteDb struct {
DB *sql.DB
}
func (s SQLiteDb) CheckAndStore(repo, tag string) (bool, error) {
var count int
err := s.DB.QueryRow("SELECT COUNT(*) FROM tags WHERE repo = ? AND tag = ?", repo, tag).Scan(&count)
if err != nil {
return false, err
}
if count > 0 {
return false, nil
}
_, err = s.DB.Exec("INSERT INTO tags (repo, tag) VALUES (?, ?)", repo, tag)
if err != nil {
return false, err
}
return true, nil
}
// NewSQLiteDb creates a new SQLite database connection.
// The database is created if it doesn't exist.
func NewSQLiteDb(file string) (SQLiteDb, error) {
db, err := sql.Open("sqlite3", file)
if err != nil {
return SQLiteDb{}, err
}
_, err = db.Exec(initSQL)
if err != nil {
return SQLiteDb{}, err
}
return SQLiteDb{DB: db}, nil
}

5
src/init.sql Normal file
View file

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
repo TEXT NOT NULL,
tag TEXT NOT NULL
);

View file

@ -7,7 +7,17 @@ import (
func main() { func main() {
// Load configuration // Load configuration
config := loadConfig("config.json") config, err := loadConfig("config.json")
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// Create database
db, err := NewSQLiteDb("tags.db")
if err != nil {
log.Fatalf("Failed to create database: %v", err)
}
_ = db
notifier := NtfyNotifier{Topic: config.NtfyTopic} notifier := NtfyNotifier{Topic: config.NtfyTopic}
@ -22,9 +32,20 @@ func main() {
if tag.Name == "" { if tag.Name == "" {
log.Printf("No tags found for %s", repo.Repo) log.Printf("No tags found for %s", repo.Repo)
continue continue
_ = notifier
} }
if notifier.Notify(repo, tag.Name) {
log.Printf("Notified for %s/%s: %s", repo.Owner, repo.Repo, tag.Name) // Check and store tag
stored, err := db.CheckAndStore(repo.Repo, tag.Name)
if err != nil {
log.Printf("Failed to store tag for %s: %v", repo.Repo, err)
continue
}
if stored {
log.Printf("New tag stored for %s: %s", repo.Repo, tag.Name)
if notifier.Notify(repo, tag.Name) {
log.Printf("Notified for %s/%s: %s", repo.Owner, repo.Repo, tag.Name)
}
} }
} }
time.Sleep(time.Duration(config.Interval) * time.Second) time.Sleep(time.Duration(config.Interval) * time.Second)

View file

@ -19,7 +19,7 @@ type RepoConfig struct {
func (r RepoConfig) GetLatestTag() (Tag, error) { func (r RepoConfig) GetLatestTag() (Tag, error) {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/tags", r.Owner, r.Repo) url := fmt.Sprintf("https://api.github.com/repos/%s/%s/tags", r.Owner, r.Repo)
fmt.Printf(url)
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
log.Printf("Failed to fetch releases for %s/%s: %v", r.Owner, r.Repo, err) log.Printf("Failed to fetch releases for %s/%s: %v", r.Owner, r.Repo, err)

View file

@ -16,20 +16,25 @@ type Config struct {
NtfyTopic string `json:"ntfy_topic"` NtfyTopic string `json:"ntfy_topic"`
} }
func loadConfig(file string) Config { func loadConfig(file string) (Config, error) {
var config Config
fh, err := os.OpenFile(file, os.O_RDONLY, 0644) fh, err := os.OpenFile(file, os.O_RDONLY, 0644)
if err != nil { if err != nil {
log.Fatalf("Failed to open config file: %v", err) log.Fatalf("Failed to open config file: %v", err)
return Config{}, err
} }
data, err := io.ReadAll(fh) data, err := io.ReadAll(fh)
if err != nil { if err != nil {
log.Fatalf("Failed to read config file: %v", err) log.Fatalf("Failed to read config file: %v", err)
return Config{}, err
} }
var config Config
if err := json.Unmarshal(data, &config); err != nil { if err := json.Unmarshal(data, &config); err != nil {
log.Fatalf("Failed to parse config file: %v", err) log.Fatalf("Failed to parse config file: %v", err)
return Config{}, err
} }
return config
return config, nil
} }
type Notifier interface { type Notifier interface {