Compare commits
3 Commits
4d7233f32c
...
d8f3c4fd69
| Author | SHA1 | Date | |
|---|---|---|---|
| d8f3c4fd69 | |||
|
b0e891a59b
|
|||
|
bf466b26ac
|
@@ -1,7 +1,8 @@
|
||||
PASSPORT_ENABLE_WEATHER=true
|
||||
OPENWEATHER_API_KEY=1234567890
|
||||
OPENWEATHER_LAT=34.052235
|
||||
OPENWEATHER_LON=-118.243683
|
||||
OPENWEATHER_UPDATE_INTERVAL=15
|
||||
PASSPORT_ADMIN_USERNAME=admin
|
||||
PASSPORT_ADMIN_PASSWORD=P@ssw0rd
|
||||
PASSPORT_SEARCH_PROVIDER=https://google.com/search?q=%s
|
||||
PASSPORT_SEARCH_PROVIDER=https://google.com/search
|
||||
44
README.md
44
README.md
@@ -6,7 +6,7 @@ Passport is a simple, fast, and lightweight web dashboard/new tab replacement.
|
||||
|
||||
## Getting Started
|
||||
|
||||

|
||||

|
||||
|
||||
### Prerequisites
|
||||
|
||||
@@ -15,29 +15,45 @@ Passport is a simple, fast, and lightweight web dashboard/new tab replacement.
|
||||
- [sqlite3](https://www.sqlite.org/download.html)
|
||||
- [TailwdinCSS CLI](https://github.com/tailwindlabs/tailwindcss/releases/latest)
|
||||
|
||||
### Usage
|
||||
## Usage
|
||||
|
||||
1. Clone the repository
|
||||
2. Configure the `.env` file, an example is provided in the `.env.example` file, see below for every available environment variable
|
||||
4. Deploy `passport` to your web server
|
||||
5. profit
|
||||
|
||||
#### Configuration
|
||||
### Configuration
|
||||
|
||||
| Environment Variable | Description | Required | Default |
|
||||
#### Passport configuration
|
||||
|
||||
| Environment Variable | Description | Required | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `PASSPORT_DEV_MODE` | Enables dev mode | false | false |
|
||||
| `PASSPORT_ENABLE_WEATHER` | Enables weather data, requires an OpenWeather API key | false | true |
|
||||
| `PASSPORT_ENABLE_UPTIME` | Enables uptime data, requires an UptimeRobot API key | false | true |
|
||||
| `PASSPORT_DEV_MODE` | Enables dev mode | false | false |
|
||||
| `PASSPORT_ENABLE_PREFORK` | Enables preforking | false | false |
|
||||
| `PASSPORT_ENABLE_WEATHER` | Enables weather data, see [Weather configuration](#weather-configuration) | false | false |
|
||||
| `PASSPORT_ENABLE_UPTIME` | Enables uptime data, see [Uptime configuration](#uptime-configuration) | false | false |
|
||||
| `PASSPORT_ADMIN_USERNAME` | The username for the admin dashboard | true |
|
||||
| `PASSPORT_ADMIN_PASSWORD` | The password for the admin dashboard | true |
|
||||
| `PASSPORT_SEARCH_PROVIDER` | The search provider to use for the search bar | true |
|
||||
| `OPENWEATHER_API_KEY` | The OpenWeather API key | if enabled |
|
||||
| `OPENWEATHER_LAT` | The latitude of your location | if enabled |
|
||||
| `OPENWEATHER_LON` | The longitude of your location | if enabled |
|
||||
| `OPENWEATHER_UPDATE_INTERVAL` | The interval in minutes to update the weather data | false | 15 |
|
||||
| `UPTIMEROBOT_API_KEY` | The UptimeRobot API key | if enabled |
|
||||
| `UPTIMEROBOT_UPDATE_INTERVAL` | The interval in seconds to update the uptime data | false | 300 |
|
||||
| `PASSPORT_SEARCH_PROVIDER` | The search provider to use for the search bar, without any query parameters | true |
|
||||
| `PASSPORT_SEARCH_PROVIDER_QUERY_PARAM` | The query parameter to use for the search provider, e.g. `q` for most providers |false | q |
|
||||
|
||||
#### Weather configuration
|
||||
|
||||
| Environment Variable | Description | Required | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `OPENWEATHER_PROVIDER` | The weather provider to use, currently only `openweathermap` is supported | true | openweathermap |
|
||||
| `OPENWEATHER_API_KEY` | The OpenWeather API key | if enabled | |
|
||||
| `OPENWEATHER_TEMP_UNITS` | The temperature units to use, either `metric` or `imperial` | false | metric |
|
||||
| `OPENWEATHER_LAT` | The latitude of your location | if enabled | |
|
||||
| `OPENWEATHER_LON` | The longitude of your location | if enabled | |
|
||||
| `OPENWEATHER_UPDATE_INTERVAL` | The interval in minutes to update the weather data | false | 15 |
|
||||
|
||||
#### Uptime configuration
|
||||
|
||||
| Environment Variable | Description | Required | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `UPTIMEROBOT_API_KEY` | The UptimeRobot API key | if enabled | |
|
||||
| `UPTIMEROBOT_UPDATE_INTERVAL` | The interval in seconds to update the uptime data | false | 300 |
|
||||
|
||||
### Adding links and categories
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -2,6 +2,8 @@ module github.com/juls0730/passport
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require github.com/caarlos0/env/v11 v11.3.1
|
||||
|
||||
require (
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gofiber/schema v1.2.0 // indirect
|
||||
|
||||
18
go.sum
18
go.sum
@@ -1,7 +1,7 @@
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
|
||||
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
|
||||
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
|
||||
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -11,8 +11,6 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
||||
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.3 h1:7Q2I+HsIqnIEEDB+9oe7Gadpakh6ZLhXpTYz/L20vrg=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.3/go.mod h1:kcMur0Dxqk91R7p4vxEpJfDWZ9u5IfvrtQc8Bvv/JmY=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
|
||||
github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
|
||||
@@ -23,16 +21,12 @@ github.com/gofiber/template/handlebars/v2 v2.1.10 h1:Qc+uUMULCqW60LF4VKO1REpiyDA
|
||||
github.com/gofiber/template/handlebars/v2 v2.1.10/go.mod h1:84WH9st5OJi255EGjuMAOqUVQ+Q2jUNhUKYbS5DgAcI=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw=
|
||||
@@ -59,21 +53,19 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
|
||||
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
|
||||
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
|
||||
github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
|
||||
github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
@@ -82,8 +74,6 @@ golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
|
||||
166
main.go
166
main.go
@@ -20,11 +20,11 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
"github.com/chai2010/webp"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/helmet"
|
||||
@@ -67,14 +67,88 @@ var (
|
||||
insertLinkStmt *sql.Stmt
|
||||
)
|
||||
|
||||
type WeatherProvider string
|
||||
|
||||
const (
|
||||
OpenWeatherMap WeatherProvider = "openweathermap"
|
||||
)
|
||||
|
||||
type WeatherConfig struct {
|
||||
Provider WeatherProvider `env:"OPENWEATHER_PROVIDER" envDefault:"openweathermap"`
|
||||
OpenWeather struct {
|
||||
APIKey string `env:"OPENWEATHER_API_KEY"`
|
||||
Units string `env:"OPENWEATHER_TEMP_UNITS" envDefault:"metric"`
|
||||
Lat float64 `env:"OPENWEATHER_LAT"`
|
||||
Lon float64 `env:"OPENWEATHER_LON"`
|
||||
}
|
||||
UpdateInterval int `env:"OPENWEATHER_UPDATE_INTERVAL" envDefault:"15"`
|
||||
}
|
||||
|
||||
type UptimeConfig struct {
|
||||
APIKey string `env:"UPTIMEROBOT_API_KEY"`
|
||||
UpdateInterval int `env:"UPTIMEROBOT_UPDATE_INTERVAL" envDefault:"300"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DevMode bool `env:"PASSPORT_DEV_MODE" envDefault:"false"`
|
||||
Prefork bool `env:"PASSPORT_ENABLE_PREFORK" envDefault:"false"`
|
||||
|
||||
WeatherEnabled bool `env:"PASSPORT_ENABLE_WEATHER" envDefault:"false"`
|
||||
Weather *WeatherConfig
|
||||
|
||||
UptimeEnabled bool `env:"PASSPORT_ENABLE_UPTIME" envDefault:"false"`
|
||||
Uptime *UptimeConfig
|
||||
|
||||
Admin struct {
|
||||
Username string `env:"PASSPORT_ADMIN_USERNAME"`
|
||||
Password string `env:"PASSPORT_ADMIN_PASSWORD"`
|
||||
}
|
||||
|
||||
SearchProvider struct {
|
||||
URL string `env:"PASSPORT_SEARCH_PROVIDER"`
|
||||
Query string `env:"PASSPORT_SEARCH_PROVIDER_QUERY_PARAM" envDefault:"q"`
|
||||
}
|
||||
}
|
||||
|
||||
func ParseConfig() (*Config, error) {
|
||||
config := Config{}
|
||||
|
||||
err := env.Parse(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.WeatherEnabled {
|
||||
config.Weather = &WeatherConfig{}
|
||||
if err := env.Parse(config.Weather); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if config.UptimeEnabled {
|
||||
config.Uptime = &UptimeConfig{}
|
||||
if err := env.Parse(config.Uptime); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
type App struct {
|
||||
*WeatherCache
|
||||
*Config
|
||||
*CategoryManager
|
||||
*WeatherCache
|
||||
*UptimeManager
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewApp(dbPath string) (*App, error) {
|
||||
config, err := ParseConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -96,16 +170,17 @@ func NewApp(dbPath string) (*App, error) {
|
||||
}
|
||||
|
||||
var weatherCache *WeatherCache
|
||||
if os.Getenv("PASSPORT_ENABLE_WEATHER") != "false" {
|
||||
weatherCache = NewWeatherCache()
|
||||
if config.WeatherEnabled {
|
||||
weatherCache = NewWeatherCache(config.Weather)
|
||||
}
|
||||
|
||||
var uptimeManager *UptimeManager
|
||||
if os.Getenv("PASSPORT_ENABLE_UPTIME") != "false" {
|
||||
uptimeManager = NewUptimeManager()
|
||||
if config.UptimeEnabled {
|
||||
uptimeManager = NewUptimeManager(config.Uptime)
|
||||
}
|
||||
|
||||
return &App{
|
||||
Config: config,
|
||||
WeatherCache: weatherCache,
|
||||
CategoryManager: categoryManager,
|
||||
UptimeManager: uptimeManager,
|
||||
@@ -127,21 +202,21 @@ type UptimeManager struct {
|
||||
apiKey string
|
||||
}
|
||||
|
||||
func NewUptimeManager() *UptimeManager {
|
||||
if os.Getenv("UPTIMEROBOT_API_KEY") == "" {
|
||||
func NewUptimeManager(config *UptimeConfig) *UptimeManager {
|
||||
if config.APIKey == "" {
|
||||
log.Fatalln("UptimeRobot API Key is required!")
|
||||
return nil
|
||||
}
|
||||
|
||||
updateInterval, err := strconv.Atoi(os.Getenv("UPTIMEROBOT_UPDATE_INTERVAL"))
|
||||
if err != nil || updateInterval < 1 {
|
||||
updateInterval := config.UpdateInterval
|
||||
if updateInterval < 1 {
|
||||
updateInterval = 300
|
||||
}
|
||||
|
||||
uptimeManager := &UptimeManager{
|
||||
updateChan: make(chan struct{}),
|
||||
updateInterval: updateInterval,
|
||||
apiKey: os.Getenv("UPTIMEROBOT_API_KEY"),
|
||||
apiKey: config.APIKey,
|
||||
sites: []UptimeRobotSite{},
|
||||
}
|
||||
|
||||
@@ -228,22 +303,27 @@ type WeatherCache struct {
|
||||
tempUnits string
|
||||
updateInterval int
|
||||
apiKey string
|
||||
lat string
|
||||
lon string
|
||||
lat float64
|
||||
lon float64
|
||||
}
|
||||
|
||||
func NewWeatherCache() *WeatherCache {
|
||||
if os.Getenv("OPENWEATHER_API_KEY") == "" || os.Getenv("OPENWEATHER_LAT") == "" || os.Getenv("OPENWEATHER_LON") == "" {
|
||||
log.Fatalln("OpenWeather API Key, and your latitude and longitude are required!")
|
||||
func NewWeatherCache(config *WeatherConfig) *WeatherCache {
|
||||
if config.Provider != OpenWeatherMap {
|
||||
log.Fatalln("Only OpenWeatherMap is supported!")
|
||||
return nil
|
||||
}
|
||||
|
||||
updateInterval, err := strconv.Atoi(os.Getenv("OPENWEATHER_UPDATE_INTERVAL"))
|
||||
if err != nil || updateInterval < 1 {
|
||||
if config.OpenWeather.APIKey == "" {
|
||||
log.Fatalln("An API Key required for OpenWeather!")
|
||||
return nil
|
||||
}
|
||||
|
||||
updateInterval := config.UpdateInterval
|
||||
if updateInterval < 1 {
|
||||
updateInterval = 15
|
||||
}
|
||||
|
||||
units := os.Getenv("OPENWEATHER_TEMP_UNITS")
|
||||
units := config.OpenWeather.Units
|
||||
if units == "" {
|
||||
units = "metric"
|
||||
}
|
||||
@@ -253,9 +333,9 @@ func NewWeatherCache() *WeatherCache {
|
||||
updateChan: make(chan struct{}),
|
||||
tempUnits: units,
|
||||
updateInterval: updateInterval,
|
||||
apiKey: os.Getenv("OPENWEATHER_API_KEY"),
|
||||
lat: os.Getenv("OPENWEATHER_LAT"),
|
||||
lon: os.Getenv("OPENWEATHER_LON"),
|
||||
apiKey: config.OpenWeather.APIKey,
|
||||
lat: config.OpenWeather.Lat,
|
||||
lon: config.OpenWeather.Lon,
|
||||
}
|
||||
|
||||
go cache.weatherWorker()
|
||||
@@ -286,7 +366,7 @@ func (c *WeatherCache) weatherWorker() {
|
||||
}
|
||||
|
||||
func (c *WeatherCache) updateWeather() {
|
||||
url := fmt.Sprintf("https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&appid=%s&units=%s",
|
||||
url := fmt.Sprintf("https://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%s&units=%s",
|
||||
c.lat, c.lon, c.apiKey, c.tempUnits)
|
||||
|
||||
resp, err := http.Get(url)
|
||||
@@ -549,17 +629,17 @@ func (manager *CategoryManager) DeleteLink(id any) error {
|
||||
}
|
||||
|
||||
var WeatherIcons = map[string]string{
|
||||
"clear-day": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6M5.394 6.813L6.81 5.399l3.505 3.506L8.9 10.319zM2 15.005h5v2H2zm3.394 10.193L8.9 21.692l1.414 1.414l-3.505 3.506zM15 25.005h2v5h-2zm6.687-1.9l1.414-1.414l3.506 3.506l-1.414 1.414zm3.313-8.1h5v2h-5zm-3.313-6.101l3.506-3.506l1.414 1.414l-3.506 3.506zM15 2.005h2v5h-2z"/></svg>`,
|
||||
"clear-night": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M13.503 5.414a15.076 15.076 0 0 0 11.593 18.194a11.1 11.1 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1 1 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.07 13.07 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3"/></svg>`,
|
||||
"partly-cloudy-day": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M27 15h4v2h-4zm-4-7.413l3-3L27.415 6l-3 3zM15 1h2v4h-2zM4.586 26l3-3l1.415 1.415l-3 3zM4.585 6L6 4.587l3 3l-1.414 1.415z"/><path fill="currentColor" d="M1 15h4v2H1zm25.794 5.342a6.96 6.96 0 0 0-1.868-3.267A9 9 0 0 0 25 16a9 9 0 1 0-14.585 7.033A4.977 4.977 0 0 0 15 30h10a4.995 4.995 0 0 0 1.794-9.658M9 16a6.996 6.996 0 0 1 13.985-.297A6.9 6.9 0 0 0 20 15a7.04 7.04 0 0 0-6.794 5.342a5 5 0 0 0-1.644 1.048A6.97 6.97 0 0 1 9 16m16 12H15a2.995 2.995 0 0 1-.696-5.908l.658-.157l.099-.67a4.992 4.992 0 0 1 9.878 0l.099.67l.658.156A2.995 2.995 0 0 1 25 28"/></svg>`,
|
||||
"partly-cloudy-night": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M30 19a4.97 4.97 0 0 0-3.206-4.658A6.971 6.971 0 0 0 13.758 12.9a13.14 13.14 0 0 1 .131-8.52A1.015 1.015 0 0 0 12.98 3a1 1 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.04 13.04 0 0 0 10.29-5.038A4.99 4.99 0 0 0 30 19m-15.297 7.998a11.095 11.095 0 0 1-3.2-21.584a15.2 15.2 0 0 0 .844 9.367A4.988 4.988 0 0 0 15 24h7.677a11.1 11.1 0 0 1-7.556 2.998c-.138 0-.278.004-.418 0M25 22H15a2.995 2.995 0 0 1-.696-5.908l.658-.157l.099-.67a4.992 4.992 0 0 1 9.878 0l.099.67l.658.157A2.995 2.995 0 0 1 25 22"/></svg>`,
|
||||
"mostly-cloudy-day": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M21.743 18.692a6 6 0 0 0 1.057-1.086a5.998 5.998 0 1 0-10.733-4.445A7.56 7.56 0 0 0 6.35 18.25A5.993 5.993 0 0 0 8 30.005h11a5.985 5.985 0 0 0 2.743-11.313M18 10.005a4.004 4.004 0 0 1 4 4a3.96 3.96 0 0 1-.8 2.4a4 4 0 0 1-.94.891a7.54 7.54 0 0 0-6.134-4.24A4 4 0 0 1 18 10.006m1 18H8a3.993 3.993 0 0 1-.673-7.93l.663-.112l.146-.656a5.496 5.496 0 0 1 10.729 0l.146.656l.662.112a3.993 3.993 0 0 1-.673 7.93m7-15.001h4v2h-4zM22.95 7.64l2.828-2.827l1.415 1.414l-2.829 2.828zM17 2.005h2v4h-2zM8.808 6.227l1.414-1.414l2.829 2.828l-1.415 1.414z"/></svg>`,
|
||||
"mostly-cloudy-night": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M29.844 15.035a1.52 1.52 0 0 0-1.23-.866a5.36 5.36 0 0 1-3.41-1.716a6.47 6.47 0 0 1-1.286-6.392a1.6 1.6 0 0 0-.299-1.546a1.45 1.45 0 0 0-1.36-.493l-.019.003a7.93 7.93 0 0 0-6.22 7.431A7.4 7.4 0 0 0 13.5 11a7.55 7.55 0 0 0-7.15 5.244A5.993 5.993 0 0 0 8 28h11a5.977 5.977 0 0 0 5.615-8.088a7.5 7.5 0 0 0 5.132-3.357a1.54 1.54 0 0 0 .097-1.52M19 26H8a3.993 3.993 0 0 1-.673-7.93l.663-.112l.145-.656a5.496 5.496 0 0 1 10.73 0l.145.656l.663.113A3.993 3.993 0 0 1 19 26m4.465-8.001h-.021a5.96 5.96 0 0 0-2.795-1.755a7.5 7.5 0 0 0-2.6-3.677c-.01-.101-.036-.197-.041-.3a6.08 6.08 0 0 1 3.79-6.05a8.46 8.46 0 0 0 1.94 7.596a7.4 7.4 0 0 0 3.902 2.228a5.43 5.43 0 0 1-4.175 1.958"/></svg>`,
|
||||
"light-rain": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M11 30a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 11 30"/><path fill="currentColor" d="M24.8 9.136a8.994 8.994 0 0 0-17.6 0A6.497 6.497 0 0 0 8.5 22h10.881l-1.276 2.553a1 1 0 0 0 1.789.894L21.618 22H23.5a6.497 6.497 0 0 0 1.3-12.864M23.5 20h-15a4.498 4.498 0 0 1-.356-8.981l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.812l.815.064A4.498 4.498 0 0 1 23.5 20"/></svg>`,
|
||||
"rain": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M23.5 22h-15A6.5 6.5 0 0 1 7.2 9.14a9 9 0 0 1 17.6 0A6.5 6.5 0 0 1 23.5 22M16 4a7 7 0 0 0-6.94 6.14L9 11h-.86a4.5 4.5 0 0 0 .36 9h15a4.5 4.5 0 0 0 .36-9H23l-.1-.82A7 7 0 0 0 16 4m-2 26a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 14 30m6 0a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 20 30M8 30a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 8 30"/></svg>`,
|
||||
"thunder": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M21 30a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 21 30M9 32a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 9 32m6.901-1.504l-1.736-.992L17.31 24h-6l4.855-8.496l1.736.992L14.756 22h6.001z"/><path fill="currentColor" d="M24.8 9.136a8.994 8.994 0 0 0-17.6 0a6.493 6.493 0 0 0 .23 12.768l-1.324 2.649a1 1 0 1 0 1.789.894l2-4a1 1 0 0 0-.447-1.341A1 1 0 0 0 9 20.01V20h-.5a4.498 4.498 0 0 1-.356-8.981l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.812l.815.064A4.498 4.498 0 0 1 23.5 20H23v2h.5a6.497 6.497 0 0 0 1.3-12.864"/></svg>`,
|
||||
"snow": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M23.5 22h-15A6.5 6.5 0 0 1 7.2 9.14a9 9 0 0 1 17.6 0A6.5 6.5 0 0 1 23.5 22M16 4a7 7 0 0 0-6.94 6.14L9 11h-.86a4.5 4.5 0 0 0 .36 9h15a4.5 4.5 0 0 0 .36-9H23l-.1-.82A7 7 0 0 0 16 4m-4 21.05L10.95 24L9.5 25.45L8.05 24L7 25.05l1.45 1.45L7 27.95L8.05 29l1.45-1.45L10.95 29L12 27.95l-1.45-1.45zm14 0L24.95 24l-1.45 1.45L22.05 24L21 25.05l1.45 1.45L21 27.95L22.05 29l1.45-1.45L24.95 29L26 27.95l-1.45-1.45zm-7 2L17.95 26l-1.45 1.45L15.05 26L14 27.05l1.45 1.45L14 29.95L15.05 31l1.45-1.45L17.95 31L19 29.95l-1.45-1.45z"/></svg>`,
|
||||
"mist": `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M24.8 11.138a8.994 8.994 0 0 0-17.6 0A6.53 6.53 0 0 0 2 17.5V19a1 1 0 0 0 1 1h12a1 1 0 0 0 0-2H4v-.497a4.52 4.52 0 0 1 4.144-4.482l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.813l.815.063A4.496 4.496 0 0 1 23.5 22H7a1 1 0 0 0 0 2h16.5a6.496 6.496 0 0 0 1.3-12.862"/><rect width="18" height="2" x="2" y="26" fill="currentColor" rx="1"/></svg>`,
|
||||
"clear-day": `<svg aria-label="Clear day" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6M5.394 6.813L6.81 5.399l3.505 3.506L8.9 10.319zM2 15.005h5v2H2zm3.394 10.193L8.9 21.692l1.414 1.414l-3.505 3.506zM15 25.005h2v5h-2zm6.687-1.9l1.414-1.414l3.506 3.506l-1.414 1.414zm3.313-8.1h5v2h-5zm-3.313-6.101l3.506-3.506l1.414 1.414l-3.506 3.506zM15 2.005h2v5h-2z"/></svg>`,
|
||||
"clear-night": `<svg aria-label="Clear night" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M13.503 5.414a15.076 15.076 0 0 0 11.593 18.194a11.1 11.1 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1 1 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.07 13.07 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3"/></svg>`,
|
||||
"partly-cloudy-day": `<svg aria-label="Partly cloudy day" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M27 15h4v2h-4zm-4-7.413l3-3L27.415 6l-3 3zM15 1h2v4h-2zM4.586 26l3-3l1.415 1.415l-3 3zM4.585 6L6 4.587l3 3l-1.414 1.415z"/><path fill="currentColor" d="M1 15h4v2H1zm25.794 5.342a6.96 6.96 0 0 0-1.868-3.267A9 9 0 0 0 25 16a9 9 0 1 0-14.585 7.033A4.977 4.977 0 0 0 15 30h10a4.995 4.995 0 0 0 1.794-9.658M9 16a6.996 6.996 0 0 1 13.985-.297A6.9 6.9 0 0 0 20 15a7.04 7.04 0 0 0-6.794 5.342a5 5 0 0 0-1.644 1.048A6.97 6.97 0 0 1 9 16m16 12H15a2.995 2.995 0 0 1-.696-5.908l.658-.157l.099-.67a4.992 4.992 0 0 1 9.878 0l.099.67l.658.156A2.995 2.995 0 0 1 25 28"/></svg>`,
|
||||
"partly-cloudy-night": `<svg aria-label="Partly cloudy night" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M30 19a4.97 4.97 0 0 0-3.206-4.658A6.971 6.971 0 0 0 13.758 12.9a13.14 13.14 0 0 1 .131-8.52A1.015 1.015 0 0 0 12.98 3a1 1 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.04 13.04 0 0 0 10.29-5.038A4.99 4.99 0 0 0 30 19m-15.297 7.998a11.095 11.095 0 0 1-3.2-21.584a15.2 15.2 0 0 0 .844 9.367A4.988 4.988 0 0 0 15 24h7.677a11.1 11.1 0 0 1-7.556 2.998c-.138 0-.278.004-.418 0M25 22H15a2.995 2.995 0 0 1-.696-5.908l.658-.157l.099-.67a4.992 4.992 0 0 1 9.878 0l.099.67l.658.157A2.995 2.995 0 0 1 25 22"/></svg>`,
|
||||
"mostly-cloudy-day": `<svg aria-label="Mostly cloudy day" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M21.743 18.692a6 6 0 0 0 1.057-1.086a5.998 5.998 0 1 0-10.733-4.445A7.56 7.56 0 0 0 6.35 18.25A5.993 5.993 0 0 0 8 30.005h11a5.985 5.985 0 0 0 2.743-11.313M18 10.005a4.004 4.004 0 0 1 4 4a3.96 3.96 0 0 1-.8 2.4a4 4 0 0 1-.94.891a7.54 7.54 0 0 0-6.134-4.24A4 4 0 0 1 18 10.006m1 18H8a3.993 3.993 0 0 1-.673-7.93l.663-.112l.146-.656a5.496 5.496 0 0 1 10.729 0l.146.656l.662.112a3.993 3.993 0 0 1-.673 7.93m7-15.001h4v2h-4zM22.95 7.64l2.828-2.827l1.415 1.414l-2.829 2.828zM17 2.005h2v4h-2zM8.808 6.227l1.414-1.414l2.829 2.828l-1.415 1.414z"/></svg>`,
|
||||
"mostly-cloudy-night": `<svg aria-label="Mostly cloudy night" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M29.844 15.035a1.52 1.52 0 0 0-1.23-.866a5.36 5.36 0 0 1-3.41-1.716a6.47 6.47 0 0 1-1.286-6.392a1.6 1.6 0 0 0-.299-1.546a1.45 1.45 0 0 0-1.36-.493l-.019.003a7.93 7.93 0 0 0-6.22 7.431A7.4 7.4 0 0 0 13.5 11a7.55 7.55 0 0 0-7.15 5.244A5.993 5.993 0 0 0 8 28h11a5.977 5.977 0 0 0 5.615-8.088a7.5 7.5 0 0 0 5.132-3.357a1.54 1.54 0 0 0 .097-1.52M19 26H8a3.993 3.993 0 0 1-.673-7.93l.663-.112l.145-.656a5.496 5.496 0 0 1 10.73 0l.145.656l.663.113A3.993 3.993 0 0 1 19 26m4.465-8.001h-.021a5.96 5.96 0 0 0-2.795-1.755a7.5 7.5 0 0 0-2.6-3.677c-.01-.101-.036-.197-.041-.3a6.08 6.08 0 0 1 3.79-6.05a8.46 8.46 0 0 0 1.94 7.596a7.4 7.4 0 0 0 3.902 2.228a5.43 5.43 0 0 1-4.175 1.958"/></svg>`,
|
||||
"light-rain": `<svg aria-label="Light rain" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M11 30a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 11 30"/><path fill="currentColor" d="M24.8 9.136a8.994 8.994 0 0 0-17.6 0A6.497 6.497 0 0 0 8.5 22h10.881l-1.276 2.553a1 1 0 0 0 1.789.894L21.618 22H23.5a6.497 6.497 0 0 0 1.3-12.864M23.5 20h-15a4.498 4.498 0 0 1-.356-8.981l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.812l.815.064A4.498 4.498 0 0 1 23.5 20"/></svg>`,
|
||||
"rain": `<svg aria-label="Rain" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M23.5 22h-15A6.5 6.5 0 0 1 7.2 9.14a9 9 0 0 1 17.6 0A6.5 6.5 0 0 1 23.5 22M16 4a7 7 0 0 0-6.94 6.14L9 11h-.86a4.5 4.5 0 0 0 .36 9h15a4.5 4.5 0 0 0 .36-9H23l-.1-.82A7 7 0 0 0 16 4m-2 26a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 14 30m6 0a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 20 30M8 30a.93.93 0 0 1-.45-.11a1 1 0 0 1-.44-1.34l2-4a1 1 0 1 1 1.78.9l-2 4A1 1 0 0 1 8 30"/></svg>`,
|
||||
"thunder": `<svg aria-label="Thunder" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M21 30a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 21 30M9 32a1 1 0 0 1-.894-1.447l2-4a1 1 0 1 1 1.788.894l-2 4A1 1 0 0 1 9 32m6.901-1.504l-1.736-.992L17.31 24h-6l4.855-8.496l1.736.992L14.756 22h6.001z"/><path fill="currentColor" d="M24.8 9.136a8.994 8.994 0 0 0-17.6 0a6.493 6.493 0 0 0 .23 12.768l-1.324 2.649a1 1 0 1 0 1.789.894l2-4a1 1 0 0 0-.447-1.341A1 1 0 0 0 9 20.01V20h-.5a4.498 4.498 0 0 1-.356-8.981l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.812l.815.064A4.498 4.498 0 0 1 23.5 20H23v2h.5a6.497 6.497 0 0 0 1.3-12.864"/></svg>`,
|
||||
"snow": `<svg aria-label="Snow" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M23.5 22h-15A6.5 6.5 0 0 1 7.2 9.14a9 9 0 0 1 17.6 0A6.5 6.5 0 0 1 23.5 22M16 4a7 7 0 0 0-6.94 6.14L9 11h-.86a4.5 4.5 0 0 0 .36 9h15a4.5 4.5 0 0 0 .36-9H23l-.1-.82A7 7 0 0 0 16 4m-4 21.05L10.95 24L9.5 25.45L8.05 24L7 25.05l1.45 1.45L7 27.95L8.05 29l1.45-1.45L10.95 29L12 27.95l-1.45-1.45zm14 0L24.95 24l-1.45 1.45L22.05 24L21 25.05l1.45 1.45L21 27.95L22.05 29l1.45-1.45L24.95 29L26 27.95l-1.45-1.45zm-7 2L17.95 26l-1.45 1.45L15.05 26L14 27.05l1.45 1.45L14 29.95L15.05 31l1.45-1.45L17.95 31L19 29.95l-1.45-1.45z"/></svg>`,
|
||||
"mist": `<svg aria-label="Mist" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M24.8 11.138a8.994 8.994 0 0 0-17.6 0A6.53 6.53 0 0 0 2 17.5V19a1 1 0 0 0 1 1h12a1 1 0 0 0 0-2H4v-.497a4.52 4.52 0 0 1 4.144-4.482l.816-.064l.099-.812a6.994 6.994 0 0 1 13.883 0l.099.813l.815.063A4.496 4.496 0 0 1 23.5 22H7a1 1 0 0 0 0 2h16.5a6.496 6.496 0 0 0 1.3-12.862"/><rect width="18" height="2" x="2" y="26" fill="currentColor" rx="1"/></svg>`,
|
||||
}
|
||||
|
||||
func getWeatherIcon(iconId string) string {
|
||||
@@ -593,7 +673,7 @@ func getWeatherIcon(iconId string) string {
|
||||
|
||||
func init() {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
fmt.Println("No .env file found")
|
||||
fmt.Println("No .env file found, using default values")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,7 +710,7 @@ func main() {
|
||||
})
|
||||
|
||||
engine.AddFunc("devContent", func() string {
|
||||
if os.Getenv("PASSPORT_DEV_MODE") == "true" {
|
||||
if app.Config.DevMode {
|
||||
return devContent
|
||||
}
|
||||
return ""
|
||||
@@ -658,11 +738,12 @@ func main() {
|
||||
|
||||
router.Get("/", func(c fiber.Ctx) error {
|
||||
renderData := fiber.Map{
|
||||
"SearchProvider": os.Getenv("PASSPORT_SEARCH_PROVIDER"),
|
||||
"Categories": app.CategoryManager.Categories,
|
||||
"SearchProviderURL": app.Config.SearchProvider.URL,
|
||||
"SearchParam": app.Config.SearchProvider.Query,
|
||||
"Categories": app.CategoryManager.Categories,
|
||||
}
|
||||
|
||||
if os.Getenv("PASSPORT_ENABLE_WEATHER") != "false" {
|
||||
if app.Config.WeatherEnabled {
|
||||
weather := app.WeatherCache.GetWeather()
|
||||
|
||||
renderData["WeatherData"] = fiber.Map{
|
||||
@@ -672,7 +753,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
if os.Getenv("PASSPORT_ENABLE_UPTIME") != "false" {
|
||||
if app.Config.UptimeEnabled {
|
||||
renderData["UptimeData"] = app.UptimeManager.getUptime()
|
||||
}
|
||||
|
||||
@@ -702,7 +783,8 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
if loginData.Username != os.Getenv("PASSPORT_ADMIN_USERNAME") || loginData.Password != os.Getenv("PASSPORT_ADMIN_PASSWORD") {
|
||||
// possible vulnerable to timing attacks
|
||||
if loginData.Username != app.Config.Admin.Username || loginData.Password != app.Config.Admin.Password {
|
||||
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{"message": "Invalid username or password"})
|
||||
}
|
||||
|
||||
@@ -942,6 +1024,6 @@ func main() {
|
||||
}
|
||||
|
||||
router.Listen(":3000", fiber.ListenConfig{
|
||||
EnablePrefork: os.Getenv("PASSPORT_ENABLE_PREFORK") == "true",
|
||||
EnablePrefork: app.Config.Prefork,
|
||||
})
|
||||
}
|
||||
|
||||
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
@@ -7,7 +7,7 @@
|
||||
}
|
||||
|
||||
:root {
|
||||
--default-font-family: "Instrument Sans", ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
|
||||
--default-font-family: "Instrument Sans", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
|
||||
html {
|
||||
@@ -25,7 +25,7 @@ h6 {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(48px, 10vw, 64px);
|
||||
font-size: clamp(42px, 10vw, 64px);
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<main class="grid grid-rows-3 grid-cols-[1fr] justify-center items-center h-screen bg-[#0E0A0E]">
|
||||
<div class="flex h-full p-2.5 justify-between">
|
||||
<div class="flex h-full p-2.5 justify-between">
|
||||
<div>
|
||||
{{#if WeatherData}}
|
||||
{{#if WeatherData}}
|
||||
<div class="text-[#BABABA] flex items-center">
|
||||
<span class="mr-2 flex items-center">
|
||||
{{{WeatherData.Icon}}}
|
||||
@@ -11,10 +11,10 @@
|
||||
<p>{{WeatherData.Desc}}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div>
|
||||
{{#if UptimeData}}
|
||||
{{#if UptimeData}}
|
||||
<div class="text-[#BABABA] flex items-end flex-col">
|
||||
{{#each UptimeData}}
|
||||
<div class="flex items-center">
|
||||
@@ -33,12 +33,12 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-start-2 flex flex-col items-center w-full px-6">
|
||||
<div class="flex items-center pb-2.5">
|
||||
<svg class="mr-3 aspect-square w-[clamp(48px,10vw,60px)]" viewBox="0 0 100 100" fill="none"
|
||||
<svg class="mr-3 aspect-square w-[clamp(42px,10vw,60px)]" viewBox="0 0 100 100" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="12.1483" y="24.7693" width="70" height="47" rx="12" transform="rotate(14.63 12.1483 24.7693)"
|
||||
fill="url(#paint0_linear_20_10)" />
|
||||
@@ -60,9 +60,11 @@
|
||||
</svg>
|
||||
<h1>Passport</h1>
|
||||
</div>
|
||||
<input id="search-input"
|
||||
class="w-full max-w-3xl bg-[#1C1C21] border border-[#56565b]/30 rounded-full px-3 py-1 text-white h-7 focus-visible:outline-none placeholder:italic placeholder:text-[#434343]"
|
||||
placeholder="Search..." />
|
||||
<form class="w-full max-w-3xl" action="{{ SearchProviderURL }}" method="GET">
|
||||
<input name="{{ SearchParam }}" aria-label="Search bar"
|
||||
class="w-full bg-[#1C1C21] border border-[#56565b]/30 rounded-full px-3 py-1 text-white h-7 focus-visible:outline-none placeholder:italic placeholder:text-[#434343]"
|
||||
placeholder="Search..." />
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
<section class="flex justify-center w-full">
|
||||
@@ -76,7 +78,7 @@
|
||||
<div class="p-2.5 grid grid-cols-[repeat(auto-fill,_minmax(min(330px,_100%),_1fr))] gap-2">
|
||||
{{#each this.Links}}
|
||||
<a href="{{this.URL}}"
|
||||
class="underline-none text-unset rounded-2xl bg-[#211F23] p-2.5 flex flex-row items-center shadow-md hover:shadow-xl transition-[shadow,transform] ease-[cubic-bezier(0.16,1,0.3,1)] hover:-translate-y-1"
|
||||
class="underline-none text-unset rounded-2xl bg-[#211F23] p-2.5 flex flex-row items-center shadow-md hover:shadow-xl transition-[shadow,transform,translate] ease-[cubic-bezier(0.16,1,0.3,1)] hover:-translate-y-1"
|
||||
draggable="false" target="_blank" rel="noopener noreferrer">
|
||||
<img class="object-contain mr-2 select-none rounded-md" width="64" height="64" draggable="false"
|
||||
src="{{this.Icon}}" alt="{{this.Name}}" />
|
||||
@@ -89,15 +91,4 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
let search_input = document.getElementById("search-input");
|
||||
let search_provider = "{{ SearchProvider }}";
|
||||
// on enter key press
|
||||
search_input.addEventListener("keyup", function (event) {
|
||||
if (event.key === "Enter") {
|
||||
window.location.href = search_provider.replace("%s", search_input.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</section>
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passport",
|
||||
"version": "0.0.1",
|
||||
"version": "0.2.0",
|
||||
"description": "Passport is a simple, lightweight, and fast dashboard/new tab page for your browser.",
|
||||
"author": "juls0730",
|
||||
"license": "BSL-1.0",
|
||||
@@ -13,5 +13,5 @@
|
||||
"dev": "go generate; PASSPORT_DEV_MODE=true go run main.go",
|
||||
"build": "go generate && go build -tags netgo,prod -o passport"
|
||||
},
|
||||
"pattern": "**/*.go,templates/views/**/*.hbs,styles/**/*.css,assets/**/*.{svg,png,jpg,jpeg,webp,woff2,ttf,otf,eot,ico,gif,webp}"
|
||||
"pattern": "**/*.go,templates/views/**/*.hbs,styles/**/*.css,assets/**/*.{svg,png,jpg,jpeg,webp,woff2,ttf,otf,eot,ico,gif,webp}"
|
||||
}
|
||||
Reference in New Issue
Block a user