MVP
This commit is contained in:
parent
72177679f4
commit
05127ef72b
9 changed files with 97 additions and 7 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.db
|
2
Justfile
Normal file
2
Justfile
Normal file
|
@ -0,0 +1,2 @@
|
|||
run:
|
||||
go run src/*.go
|
5
go.mod
Normal file
5
go.mod
Normal 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
2
go.sum
Normal 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
49
src/db.go
Normal 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
5
src/init.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE IF NOT EXISTS tags (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
repo TEXT NOT NULL,
|
||||
tag TEXT NOT NULL
|
||||
);
|
27
src/main.go
27
src/main.go
|
@ -7,7 +7,17 @@ import (
|
|||
|
||||
func main() {
|
||||
// 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}
|
||||
|
||||
|
@ -22,9 +32,20 @@ func main() {
|
|||
if tag.Name == "" {
|
||||
log.Printf("No tags found for %s", repo.Repo)
|
||||
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)
|
||||
|
|
|
@ -19,7 +19,7 @@ type RepoConfig struct {
|
|||
|
||||
func (r RepoConfig) GetLatestTag() (Tag, error) {
|
||||
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/tags", r.Owner, r.Repo)
|
||||
fmt.Printf(url)
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Printf("Failed to fetch releases for %s/%s: %v", r.Owner, r.Repo, err)
|
||||
|
|
11
src/types.go
11
src/types.go
|
@ -16,20 +16,25 @@ type Config struct {
|
|||
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)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open config file: %v", err)
|
||||
return Config{}, err
|
||||
}
|
||||
data, err := io.ReadAll(fh)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read config file: %v", err)
|
||||
return Config{}, err
|
||||
}
|
||||
var config Config
|
||||
if err := json.Unmarshal(data, &config); err != nil {
|
||||
log.Fatalf("Failed to parse config file: %v", err)
|
||||
return Config{}, err
|
||||
}
|
||||
return config
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
type Notifier interface {
|
||||
|
|
Loading…
Reference in a new issue