Skip to content

Commit

Permalink
refactor: code structure (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
martabal authored Jul 9, 2024
1 parent a3036ee commit 7a7690a
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 87 deletions.
47 changes: 47 additions & 0 deletions src/app/app.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package app

import (
"flag"
"fmt"
"os"
"qbit-exp/logger"
"strconv"
"strings"
"time"

"github.com/joho/godotenv"
)

var (
Expand All @@ -28,6 +35,46 @@ func SetVar(port int, disableTracker bool, loglevel string, baseUrl string, user
QbittorrentTimeout = time.Duration(qbittorrentTimeout)
}

func LoadEnv() {
var envfile bool
flag.BoolVar(&envfile, "e", false, "Use .env file")
flag.Parse()
_, err := os.Stat(".env")
if !os.IsNotExist(err) && !envfile {
err := godotenv.Load(".env")
if err != nil {
errormessage := "Error loading .env file:" + err.Error()
panic(errormessage)
}
}

loglevel := logger.SetLogLevel(getEnv(defaultLogLevel))
qbitUsername := getEnv(defaultUsername)
qbitPassword := getEnv(defaultPassword)
qbitURL := strings.TrimSuffix(getEnv(defaultBaseUrl), "/")
exporterPortEnv := getEnv(defaultPort)
timeoutDurationEnv := getEnv(defaultTimeout)
disableTracker := getEnv(defaultDisableTracker)

exporterPort, errExporterPort := strconv.Atoi(exporterPortEnv)
if errExporterPort != nil {
panic(fmt.Sprintf("%s must be an integer", defaultPort.Key))
}
if exporterPort < 0 || exporterPort > 65353 {
panic(fmt.Sprintf("%s must be > 0 and < 65353", defaultPort.Key))
}

timeoutDuration, errTimeoutDuration := strconv.Atoi(timeoutDurationEnv)
if errTimeoutDuration != nil {
panic(fmt.Sprintf("%s must be an integer", defaultPort.Key))
}
if timeoutDuration < 0 {
panic(fmt.Sprintf("%s must be > 0", defaultPort.Key))
}

SetVar(exporterPort, strings.ToLower(disableTracker) == "true", loglevel, qbitURL, qbitUsername, qbitPassword, timeoutDuration)
}

func GetPasswordMasked() string {
return strings.Repeat("*", len(Password))
}
31 changes: 23 additions & 8 deletions src/app/default.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package app

import "strconv"
import (
"os"
"qbit-exp/logger"
"strconv"
)

const DEFAULT_PORT = 8090
const DEFAULT_TIMEOUT = 30
Expand All @@ -11,44 +15,55 @@ type Env struct {
Help string
}

var LogLevelEnv = Env{
var defaultLogLevel = Env{
Key: "LOG_LEVEL",
DefaultValue: "INFO",
Help: "",
}

var PortEnv = Env{
var defaultPort = Env{
Key: "EXPORTER_PORT",
DefaultValue: strconv.Itoa(DEFAULT_PORT),
Help: "",
}

var TimeoutEnv = Env{
var defaultTimeout = Env{
Key: "EXPORTER_PORT",
DefaultValue: strconv.Itoa(DEFAULT_TIMEOUT),
Help: "",
}

var UsernameEnv = Env{
var defaultUsername = Env{
Key: "QBITTORRENT_USERNAME",
DefaultValue: "admin",
Help: "Qbittorrent username is not set. Using default username",
}

var PasswordEnv = Env{
var defaultPassword = Env{
Key: "QBITTORRENT_PASSWORD",
DefaultValue: "adminadmin",
Help: "Qbittorrent password is not set. Using default password",
}

var BaseUrlEnv = Env{
var defaultBaseUrl = Env{
Key: "QBITTORRENT_BASE_URL",
DefaultValue: "http://localhost:8080",
Help: "Qbittorrent base_url is not set. Using default base_url",
}

var DisableTrackerEnv = Env{
var defaultDisableTracker = Env{
Key: "QBITTORRENT_BASE_URL",
DefaultValue: "http://localhost:8080",
Help: "Qbittorrent base_url is not set. Using default base_url",
}

func getEnv(env Env) string {
value, ok := os.LookupEnv(env.Key)
if !ok || value == "" {
if env.Help != "" {
logger.Log.Warn(env.Help)
}
return env.DefaultValue
}
return value
}
18 changes: 18 additions & 0 deletions src/logger/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"log/slog"
"os"
"strings"
)

type PrettyHandler struct {
Expand Down Expand Up @@ -67,4 +68,21 @@ func NewPrettyHandler(
return h
}

func SetLogLevel(logLevel string) string {
upperLogLevel := strings.ToUpper(logLevel)
level, found := LogLevels[upperLogLevel]
if !found {
upperLogLevel = "INFO"
level = LogLevels[upperLogLevel]
}

opts := slog.HandlerOptions{
Level: slog.Level(level),
}

handler := NewPrettyHandler(os.Stdout, opts)
Log = slog.New(handler)
return upperLogLevel
}

var Log *slog.Logger
75 changes: 1 addition & 74 deletions src/main.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package main

import (
"flag"
"fmt"
"log/slog"
"net"
"net/http"
"os"
"runtime"

"qbit-exp/qbit"

app "qbit-exp/app"
logger "qbit-exp/logger"
"strconv"
"strings"

"github.com/joho/godotenv"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
Expand All @@ -28,7 +23,7 @@ var (
)

func main() {
loadenv()
app.LoadEnv()
fmt.Printf("%s (version %s)\n", ProjectName, Version)
fmt.Println("Author:", Author)
fmt.Println("Using log level: " + app.LogLevel)
Expand Down Expand Up @@ -69,71 +64,3 @@ func metrics(w http.ResponseWriter, req *http.Request) {
}

}

func loadenv() {
var envfile bool
flag.BoolVar(&envfile, "e", false, "Use .env file")
flag.Parse()
_, err := os.Stat(".env")
if !os.IsNotExist(err) && !envfile {
err := godotenv.Load(".env")
if err != nil {
errormessage := "Error loading .env file:" + err.Error()
panic(errormessage)
}
}

loglevel := setLogLevel(getEnv(app.LogLevelEnv))
qbitUsername := getEnv(app.UsernameEnv)
qbitPassword := getEnv(app.PasswordEnv)
qbitURL := strings.TrimSuffix(getEnv(app.BaseUrlEnv), "/")
exporterPortEnv := getEnv(app.PortEnv)
timeoutDurationEnv := getEnv(app.TimeoutEnv)
disableTracker := getEnv(app.DisableTrackerEnv)

exporterPort, errExporterPort := strconv.Atoi(exporterPortEnv)
if errExporterPort != nil {
panic(fmt.Sprintf("%s must be an integer", app.PortEnv.Key))
}
if exporterPort < 0 || exporterPort > 65353 {
panic(fmt.Sprintf("%s must be > 0 and < 65353", app.PortEnv.Key))
}

timeoutDuration, errTimeoutDuration := strconv.Atoi(timeoutDurationEnv)
if errTimeoutDuration != nil {
panic(fmt.Sprintf("%s must be an integer", app.PortEnv.Key))
}
if timeoutDuration < 0 {
panic(fmt.Sprintf("%s must be > 0", app.PortEnv.Key))
}

app.SetVar(exporterPort, strings.ToLower(disableTracker) == "true", loglevel, qbitURL, qbitUsername, qbitPassword, timeoutDuration)
}

func setLogLevel(logLevel string) string {
upperLogLevel := strings.ToUpper(logLevel)
level, found := logger.LogLevels[upperLogLevel]
if !found {
upperLogLevel = "INFO"
level = logger.LogLevels[upperLogLevel]
}

opts := slog.HandlerOptions{
Level: slog.Level(level),
}

handler := logger.NewPrettyHandler(os.Stdout, opts)
logger.Log = slog.New(handler)
return upperLogLevel
}

func getEnv(env app.Env) string {
value, ok := os.LookupEnv(env.Key)
if !ok || value == "" {
if env.Help != "" {
logger.Log.Warn(env.Help)
}
return env.DefaultValue
}
return value
}
10 changes: 5 additions & 5 deletions src/qbit/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ func Auth() {

body, err := io.ReadAll(resp.Body)
if err != nil {
errormessage := "Error reading the body" + err.Error()
panic(errormessage)
panic("Error reading the body" + err.Error())
}

if string(body) == "Fails." {
panic("Authentication Error, check your qBittorrent username / password")
}

if !app.ShouldShowError {
logger.Log.Info("New cookie stored")
logFunc := logger.Log.Info
if app.ShouldShowError {
logFunc = logger.Log.Debug
}
logFunc("New cookie stored")

cookie := resp.Header.Get("Set-Cookie")
cookieValue := strings.Split(strings.Split(cookie, ";")[0], "=")[1]
Expand Down
1 change: 1 addition & 0 deletions src/qbit/qbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ func apiRequest(uri string, method string, queryParams *[]QueryParams) ([]byte,

req.AddCookie(&http.Cookie{Name: "SID", Value: app.Cookie})
client := &http.Client{}
logger.Log.Debug("New request to " + req.URL.String())
resp, err := client.Do(req)
if err != nil {
logger.Log.Debug(err.Error())
Expand Down

0 comments on commit 7a7690a

Please sign in to comment.