Files
proton-vpn-tui/internal/backend/servers.go
T
2026-08-27 23:14:56 +02:00

114 lines
2.2 KiB
Go

package backend
import (
"context"
"encoding/json"
"os"
"path/filepath"
)
const (
featureSecureCore = 1 << iota
featureTor
featureP2P
featureStreaming
featureIPv6
)
type LogicalServer struct {
Name string
EntryCountry string
ExitCountry string
City *string
Tier int
SecureCore bool
Tor bool
P2P bool
Streaming bool
IPv6 bool
Score float64
ID string
Status int
Load int
}
func (s LogicalServer) IsFree() bool {
return s.Tier == 0
}
func (s *LogicalServer) UnmarshalJSON(data []byte) error {
var raw struct {
Name string
EntryCountry string
ExitCountry string
City *string
Tier int
Features int
Score float64
ID string
Status int
Load int
}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
*s = LogicalServer{
Name: raw.Name,
EntryCountry: raw.EntryCountry,
ExitCountry: raw.ExitCountry,
City: raw.City,
Tier: raw.Tier,
SecureCore: raw.Features&featureSecureCore != 0,
Tor: raw.Features&featureTor != 0,
P2P: raw.Features&featureP2P != 0,
Streaming: raw.Features&featureStreaming != 0,
IPv6: raw.Features&featureIPv6 != 0,
Score: raw.Score,
ID: raw.ID,
Status: raw.Status,
Load: raw.Load,
}
return nil
}
func RefreshServerList() error {
_, err := Run(context.Background(), "cities", "list", "France")
return err
}
func ParseCache() ([]LogicalServer, error) {
cacheHome, err := xdgCacheHome()
if err != nil {
return nil, err
}
path := filepath.Join(cacheHome, "Proton", "VPN", "serverlist.json")
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var cache struct {
LogicalServers []LogicalServer
}
if err := json.Unmarshal(data, &cache); err != nil {
return nil, err
}
return cache.LogicalServers, nil
}
func xdgCacheHome() (string, error) {
if dir := os.Getenv("XDG_CACHE_HOME"); dir != "" {
return dir, nil
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, ".cache"), nil
}