chore(storage): common sorting for all servers

This commit is contained in:
Quentin McGaw
2022-06-06 01:57:44 +00:00
parent f53f0cfffd
commit 1216326867
48 changed files with 1319 additions and 1795 deletions

42
internal/models/sort.go Normal file
View File

@@ -0,0 +1,42 @@
package models
import "sort"
var _ sort.Interface = (*SortableServers)(nil)
type SortableServers []Server
func (s SortableServers) Len() int {
return len(s)
}
func (s SortableServers) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableServers) Less(i, j int) bool {
a, b := s[i], s[j]
if a.Country == b.Country { //nolint:nestif
if a.Region == b.Region {
if a.City == b.City {
if a.ServerName == b.ServerName {
if a.Number == b.Number {
if a.Hostname == b.Hostname {
if a.ISP == b.ISP {
return a.VPN < b.VPN
}
return a.ISP < b.ISP
}
return a.Hostname < b.Hostname
}
return a.Number < b.Number
}
return a.ServerName < b.ServerName
}
return a.City < b.City
}
return a.Region < b.Region
}
return a.Country < b.Country
}

View File

@@ -4,6 +4,7 @@ package cyberghost
import (
"context"
"sort"
"github.com/qdm12/gluetun/internal/models"
)
@@ -22,6 +23,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = possibleServers.toSlice()
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,16 +0,0 @@
package cyberghost
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package expressvpn
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -47,7 +48,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package expressvpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package fastestvpn
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -72,7 +73,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,16 +0,0 @@
package fastestvpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package hidemyass
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -62,7 +63,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = append(servers, server)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package hidemyass
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].Region == servers[j].Region {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Region < servers[j].Region
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package ipvanish
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -83,7 +84,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package ipvanish
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -1,40 +0,0 @@
package ipvanish
import (
"testing"
"github.com/qdm12/gluetun/internal/models"
"github.com/stretchr/testify/assert"
)
func Test_sortServers(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
initialServers []models.Server
sortedServers []models.Server
}{
"no server": {},
"sorted servers": {
initialServers: []models.Server{
{Country: "B", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "B", Hostname: "A"},
},
sortedServers: []models.Server{
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "B", Hostname: "A"},
{Country: "B", City: "A", Hostname: "A"},
},
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
sortServers(testCase.initialServers)
assert.Equal(t, testCase.sortedServers, testCase.initialServers)
})
}
}

View File

@@ -5,6 +5,7 @@ package ivpn
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -72,7 +73,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = append(servers, server)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package ivpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
if servers[i].Hostname == servers[j].Hostname {
return servers[i].VPN < servers[j].VPN
}
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -1,40 +0,0 @@
package ivpn
import (
"testing"
"github.com/qdm12/gluetun/internal/models"
"github.com/stretchr/testify/assert"
)
func Test_sortServers(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
initialServers []models.Server
sortedServers []models.Server
}{
"no server": {},
"sorted servers": {
initialServers: []models.Server{
{Country: "B", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "B", Hostname: "A"},
},
sortedServers: []models.Server{
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "B", Hostname: "A"},
{Country: "B", City: "A", Hostname: "A"},
},
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
sortServers(testCase.initialServers)
assert.Equal(t, testCase.sortedServers, testCase.initialServers)
})
}
}

View File

@@ -5,6 +5,7 @@ package mullvad
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
@@ -31,7 +32,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = hts.toServersSlice()
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package mullvad
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
if servers[i].Hostname == servers[j].Hostname {
return servers[i].ISP < servers[j].ISP
}
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"net"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -60,7 +61,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,16 +0,0 @@
package nordvpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Region == servers[j].Region {
return servers[i].Number < servers[j].Number
}
return servers[i].Region < servers[j].Region
})
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/url"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -46,7 +47,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = cts.toServersSlice()
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,13 +0,0 @@
package perfectprivacy
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
return servers[i].City < servers[j].City
})
}

View File

@@ -5,6 +5,7 @@ package privado
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -65,7 +66,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
return nil, err
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package privado
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].Region == servers[j].Region {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Region < servers[j].Region
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package privateinternetaccess
import (
"context"
"fmt"
"sort"
"time"
"github.com/qdm12/gluetun/internal/models"
@@ -70,7 +71,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package privateinternetaccess
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Region == servers[j].Region {
if servers[i].Hostname == servers[j].Hostname {
return servers[i].ServerName < servers[j].ServerName
}
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].Region < servers[j].Region
})
}

View File

@@ -5,6 +5,7 @@ package privatevpn
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/constants"
@@ -94,7 +95,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = hts.toServersSlice()
servers = append(servers, noHostnameServers...)
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package privatevpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package protonvpn
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -63,7 +64,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = ipToServer.toServersSlice()
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,26 +0,0 @@
package protonvpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
a, b := servers[i], servers[j]
if a.Country == b.Country { //nolint:nestif
if a.Region == b.Region {
if a.City == b.City {
if a.ServerName == b.ServerName {
return a.Hostname < b.Hostname
}
return a.ServerName < b.ServerName
}
return a.City < b.City
}
return a.Region < b.Region
}
return a.Country < b.Country
})
}

View File

@@ -6,6 +6,7 @@ import (
"context"
"fmt"
"net"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -91,7 +92,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers[i].City = ipsInfo[i].City
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package purevpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].Region == servers[j].Region {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Region < servers[j].Region
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -12,7 +12,7 @@ type ServerLocation struct {
}
// TODO remove retroRegion and servers from API in v4.
func LocationData() (data []ServerLocation) {
func LocationData() (data []ServerLocation) { //nolint:maintidx
//nolint:lll
return []ServerLocation{
{Region: "Asia Pacific", Country: "Australia", City: "Adelaide", RetroLoc: "Australia Adelaide", Hostname: "au-adl.prod.surfshark.com", MultiHop: false},

View File

@@ -5,6 +5,7 @@ package surfshark
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
@@ -47,7 +48,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package surfshark
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Region == servers[j].Region {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
}
return servers[i].Region < servers[j].Region
})
}

View File

@@ -1,42 +0,0 @@
package surfshark
import (
"testing"
"github.com/qdm12/gluetun/internal/models"
"github.com/stretchr/testify/assert"
)
func Test_sortServers(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
initialServers []models.Server
sortedServers []models.Server
}{
"no server": {},
"sorted servers": {
initialServers: []models.Server{
{Region: "Z", Country: "B", City: "A", Hostname: "A"},
{Country: "B", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "B", Hostname: "A"},
},
sortedServers: []models.Server{
{Country: "A", City: "A", Hostname: "A"},
{Country: "A", City: "A", Hostname: "B"},
{Country: "A", City: "B", Hostname: "A"},
{Country: "B", City: "A", Hostname: "A"},
{Region: "Z", Country: "B", City: "A", Hostname: "A"},
},
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
sortServers(testCase.initialServers)
assert.Equal(t, testCase.sortedServers, testCase.initialServers)
})
}
}

View File

@@ -5,6 +5,7 @@ package torguard
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -64,7 +65,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package torguard
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package vpnunlimited
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
@@ -36,7 +37,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,19 +0,0 @@
package vpnunlimited
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Country == servers[j].Country {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Country < servers[j].Country
})
}

View File

@@ -5,6 +5,7 @@ package vyprvpn
import (
"context"
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
@@ -80,7 +81,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,13 +0,0 @@
package vyprvpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
return servers[i].Region < servers[j].Region
})
}

View File

@@ -6,6 +6,7 @@ import (
"context"
"errors"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -55,7 +56,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
servers = append(servers, server)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,16 +0,0 @@
package wevpn
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].City == servers[j].City {
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
})
}

View File

@@ -1,40 +0,0 @@
package wevpn
import (
"testing"
"github.com/qdm12/gluetun/internal/models"
"github.com/stretchr/testify/assert"
)
func Test_sortServers(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
initialServers []models.Server
sortedServers []models.Server
}{
"no server": {},
"sorted servers": {
initialServers: []models.Server{
{City: "A", Hostname: "A"},
{City: "A", Hostname: "B"},
{City: "A", Hostname: "A"},
{City: "B", Hostname: "A"},
},
sortedServers: []models.Server{
{City: "A", Hostname: "A"},
{City: "A", Hostname: "A"},
{City: "A", Hostname: "B"},
{City: "B", Hostname: "A"},
},
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
sortServers(testCase.initialServers)
assert.Equal(t, testCase.sortedServers, testCase.initialServers)
})
}
}

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"net"
"sort"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
@@ -72,7 +73,7 @@ func (u *Updater) GetServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(servers), minServers)
}
sortServers(servers)
sort.Sort(models.SortableServers(servers))
return servers, nil
}

View File

@@ -1,22 +0,0 @@
package windscribe
import (
"sort"
"github.com/qdm12/gluetun/internal/models"
)
func sortServers(servers []models.Server) {
sort.Slice(servers, func(i, j int) bool {
if servers[i].Region == servers[j].Region {
if servers[i].City == servers[j].City {
if servers[i].Hostname == servers[j].Hostname {
return servers[i].VPN < servers[j].VPN
}
return servers[i].Hostname < servers[j].Hostname
}
return servers[i].City < servers[j].City
}
return servers[i].Region < servers[j].Region
})
}

View File

@@ -4,6 +4,9 @@ import (
"encoding/json"
"os"
"path/filepath"
"sort"
"github.com/qdm12/gluetun/internal/models"
)
// FlushToFile flushes the merged servers data to the file
@@ -31,6 +34,10 @@ func (s *Storage) flushToFile(path string) error {
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
for _, obj := range s.mergedServers.ProviderToServers {
sort.Sort(models.SortableServers(obj.Servers))
}
err = encoder.Encode(&s.mergedServers)
if err != nil {
_ = file.Close()

File diff suppressed because it is too large Load Diff