Skip to content

Commit

Permalink
A wild Fletchling has appeared!
Browse files Browse the repository at this point in the history
Welcome to Fletchling!
  • Loading branch information
comstud committed Feb 6, 2024
1 parent 4b4078f commit 66b3cc7
Show file tree
Hide file tree
Showing 65 changed files with 7,025 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@

# Go workspace file
go.work

*~
/configs/fletchling.toml
/configs/fletchling-importer.toml
/fletchling
/fletchling-importer
/docker-compose.yml
/vendor
/logs
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Build image
FROM golang:1.21-alpine as build

WORKDIR /go/src/app

COPY . .
RUN if [ ! -f vendor/modules.txt ]; then go mod download; fi
RUN CGO_ENABLED=0 go build -o /go/bin/fletchling ./bin/fletchling
RUN CGO_ENABLED=0 go build -o /go/bin/fletchling-importer ./bin/fletchling-importer
RUN mkdir /empty-dir

# Now copy it into our base image.
FROM gcr.io/distroless/static-debian11 as runner
COPY --from=build /go/bin/fletchling /go/bin/fletchling-importer /fletchling/
COPY --from=build /empty-dir /fletchling/logs
COPY --from=build /go/src/app/db_store/sql /fletchling/db_store/sql

WORKDIR /fletchling
CMD ["./fletchling"]
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Fletchling

Fletchling is a Golbat webhook receiver that processes pokemon
webhooks and computes nesting pokemon. Auth

# Features

* receives and processes pokemon on the fly via webhook from Golbat
* fletchling-importer (separate tool): Can copy nests from: overpass, db, or koji to db or koji.
* koji can be used as an authortative source for nests (optional)
* has an API to pull stats, purge stats, reload config, etc.
* highly configurable.

# Instructions

1. rename and edit configs in configs/
2. in golbat, add a new webhook. (i think restart is required.) it should look like this in the config:
```
[[webhooks]]
url = "http://fletchling-host:9042/webhook"
types = ["pokemon_iv"]
```
3. figure out how you want to run fletchling. there's a docker-compose example and a build.sh.
4. check the logs, db, whatever, and enjoy.

# Migrating from other nest processors:

(UNTESTED)

## nestcollector to fletching with database as authortative source (SIMPLEST)
1. configure your existing golbat db in configs/fletchling.toml
2. do not configure koji section.
3. nuke your cronjob.
4. `./fletchling`

## nestcollector to Fletchling with koji as authorative source.
1. configure your existing golbat db in configs/fletchling-importer.toml in the 'db_exporter' section.
2. configure your koji endpoint (BASE URL ONLY) in configs/fletchling-importer.toml in the 'koji_importer' section.
3. create a project for nests in koji.
4. `./build.sh`
5. `./fletchling-importer -koji-dest-project 'YOURKOJIPROJECT' db koji`
6. check koji and fix up whatever you want.
7. configure a new db or existing golbat db in configs/fletchling.toml
8. configure koji section in configs/fletchling.toml
9. nuke your cronjob.
10. `./fletchling`

## The old nestwatcher db is not supported currently.
157 changes: 157 additions & 0 deletions bin/fletchling-importer/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package main

import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
"github.com/sirupsen/logrus"

"github.com/UnownHash/Fletchling/db_store"
"github.com/UnownHash/Fletchling/importer"
"github.com/UnownHash/Fletchling/logging"
)

type KojiConfig struct {
Url string `koanf:"url"`
Token string `koanf:"token"`
}

func (cfg *KojiConfig) Validate() error {
if cfg == nil {
return nil
}

const fcStr = "/api/v1/geofence/feature-collection/"

idx := strings.Index(cfg.Url, fcStr)
if idx >= 0 {
cfg.Url = cfg.Url[:idx]
}

if cfg.Url == "" {
return errors.New("No koji url configured")
}

return nil
}

type OverpassConfig struct {
Url string `json:"url"`
}

func (cfg *OverpassConfig) Validate() error {
if cfg == nil {
return nil
}

if cfg.Url == "" {
return errors.New("No overpass url configured")
}

return nil
}

type Config struct {
Logging logging.Config `koanf:"logging"`

Importer importer.Config `koanf:"importer"`

OverpassExporter *OverpassConfig `koanf:"overpass_exporter"`

KojiOverpassSrc *KojiConfig `koanf:"koji_overpass_source"`
KojiImporter *KojiConfig `koanf:"koji_importer"`
KojiExporter *KojiConfig `koanf:"koji_exporter"`

DBImporter *db_store.DBConfig `koanf:"db_importer"`
DBExporter *db_store.DBConfig `koanf:"db_exporter"`
}

func (cfg *Config) CreateLogger() *logrus.Logger {
return cfg.Logging.CreateLogger(nil, true)
}

func (cfg *Config) Validate() error {
if err := cfg.OverpassExporter.Validate(); err != nil {
return err
}

if err := cfg.KojiOverpassSrc.Validate(); err != nil {
return err
}

if err := cfg.KojiImporter.Validate(); err != nil {
return err
}

if err := cfg.KojiExporter.Validate(); err != nil {
return err
}

if cfg.DBImporter != nil {
if err := cfg.DBImporter.Validate(); err != nil {
return err
}
}

if cfg.DBExporter != nil {
if err := cfg.DBExporter.Validate(); err != nil {
return err
}
}

if err := cfg.Logging.Validate(); err != nil {
return err
}

return nil
}

var defaultConfig = Config{
Logging: logging.Config{
Filename: filepath.FromSlash("logs/fletchling-importer.log"),
MaxSizeMB: 100,
MaxAgeDays: 7,
MaxBackups: 20,
Compress: false,
},
}

func LoadConfig(filename string) (*Config, error) {
f, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("couldn't open '%s': %w", filename, err)
}
defer f.Close()

k := koanf.New(".")
err = k.Load(structs.Provider(defaultConfig, "koanf"), nil)
if err != nil {
return nil, fmt.Errorf("couldn't load default config: %w", err)
}

err = k.Load(file.Provider(filename), toml.Parser())
if err != nil {
return nil, fmt.Errorf("failed to load config file: %w", err)
}

var cfg Config

err = k.Unmarshal("", &cfg)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
}

err = cfg.Validate()
if err != nil {
return nil, err
}

return &cfg, nil
}
Loading

0 comments on commit 66b3cc7

Please sign in to comment.