Skip to content

Commit

Permalink
Added matomo configuration to global template
Browse files Browse the repository at this point in the history
  • Loading branch information
oxtoacart committed Jan 25, 2022
1 parent a88f655 commit f8095bc
Show file tree
Hide file tree
Showing 19 changed files with 2,676 additions and 14 deletions.
45 changes: 31 additions & 14 deletions config/features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,24 @@ featureoptions:
require.Nil(t, mat.Config["k1"])
}

func TestMatomoConfigured(t *testing.T) {
opts := getAnalyticsOptions(t)
matomo := opts.GetProvider(MATOMO)
require.NotNil(t, matomo)
require.NotZero(t, matomo.SampleRate)
require.Equal(t, 1, matomo.Config["idsite"])
}

func getAnalyticsOptions(t *testing.T) (opts AnalyticsOptions) {
var g Global
require.NoError(t, yaml.Unmarshal(getGlobalTemplate(t), &g))
require.NoError(t, g.UnmarshalFeatureOptions(FeatureAnalytics, &opts))
return
}

func TestReplicaByCountry(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
fos := getReplicaOptionsRoot(require)
fos := getReplicaOptionsRoot(t)
assert.Contains(fos.ByCountry, "RU")
assert.NotContains(fos.ByCountry, "AU")
assert.NotEmpty(fos.ByCountry)
Expand All @@ -177,20 +191,9 @@ func TestReplicaByCountry(t *testing.T) {
assert.Equal(fos.ByCountry["IR"].Trackers, globalTrackers)
}

func getReplicaOptionsRoot(require *require.Assertions) (fos ReplicaOptionsRoot) {
var w bytes.Buffer
// We could write into a pipe, but that requires concurrency and we're old-school in tests.
require.NoError(template.Must(template.New("").Parse(embeddedconfig.GlobalTemplate)).Execute(&w, nil))
var g Global
require.NoError(yaml.Unmarshal(w.Bytes(), &g))
require.NoError(g.UnmarshalFeatureOptions(FeatureReplica, &fos))
return
}

func TestReplicaProxying(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
fos := getReplicaOptionsRoot(require)
fos := getReplicaOptionsRoot(t)
numInfohashes := len(fos.ProxyAnnounceTargets)
// The default is to announce as a proxy.
assert.True(numInfohashes > 0)
Expand All @@ -199,3 +202,17 @@ func TestReplicaProxying(t *testing.T) {
// Iran looks for peers from the default countries.
assert.Len(fos.ByCountry["IR"].ProxyPeerInfoHashes, numInfohashes)
}

func getReplicaOptionsRoot(t *testing.T) (fos ReplicaOptionsRoot) {
var g Global
require.NoError(t, yaml.Unmarshal(getGlobalTemplate(t), &g))
require.NoError(t, g.UnmarshalFeatureOptions(FeatureReplica, &fos))
return
}

func getGlobalTemplate(t *testing.T) []byte {
var w bytes.Buffer
// We could write into a pipe, but that requires concurrency and we're old-school in tests.
require.NoError(t, template.Must(template.New("").Parse(embeddedconfig.GlobalTemplate)).Execute(&w, nil))
return w.Bytes()
}
79 changes: 79 additions & 0 deletions config_v2/ads.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package config

import (
"math/rand"
"strings"
)

const (
none = "none"
free = "free"
pro = "pro"
)

// AdSettings are settings to use when showing ads to Android clients
type AdSettings struct {
NativeBannerZoneID string `yaml:"nativebannerzoneid,omitempty"`
StandardBannerZoneID string `yaml:"standardbannerzoneid,omitempty"`
InterstitialZoneID string `yaml:"interstitialzoneid,omitempty"`
DaysToSuppress int `yaml:"daystosuppress,omitempty"`
Percentage float64
Countries map[string]string
}

type AdProvider struct {
AdSettings
}

func (s *AdSettings) GetAdProvider(isPro bool, countryCode string, daysSinceInstalled int) *AdProvider {
if !s.adsEnabled(isPro, countryCode, daysSinceInstalled) {
return nil
}

return &AdProvider{*s}
}

func (s *AdSettings) adsEnabled(isPro bool, countryCode string, daysSinceInstalled int) bool {
if s == nil {
return false
}

if daysSinceInstalled < s.DaysToSuppress {
return false
}

level := s.Countries[strings.ToLower(countryCode)]
switch level {
case free:
return !isPro
case pro:
return true
default:
return false
}
}

func (p *AdProvider) GetNativeBannerZoneID() string {
if p == nil {
return ""
}
return p.NativeBannerZoneID
}

func (p *AdProvider) GetStandardBannerZoneID() string {
if p == nil {
return ""
}
return p.StandardBannerZoneID
}

func (p *AdProvider) GetInterstitialZoneID() string {
if p == nil {
return ""
}
return p.InterstitialZoneID
}

func (p *AdProvider) ShouldShowAd() bool {
return rand.Float64() <= p.Percentage/100
}
41 changes: 41 additions & 0 deletions config_v2/ads_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package config

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestAdSettings(t *testing.T) {
s := &AdSettings{
NativeBannerZoneID: "a",
StandardBannerZoneID: "b",
InterstitialZoneID: "c",
DaysToSuppress: 1,
Percentage: 100,
Countries: map[string]string{
"ir": "pro",
"ae": "free",
"us": "none",
"uk": "wrong",
},
}

assert.True(t, s.adsEnabled(true, "IR", 1))
assert.True(t, s.adsEnabled(false, "IR", 1))
assert.False(t, s.adsEnabled(true, "AE", 1))
assert.True(t, s.adsEnabled(false, "AE", 1))
assert.False(t, s.adsEnabled(false, "AE", 0))
assert.False(t, s.adsEnabled(false, "US", 1))
assert.False(t, s.adsEnabled(false, "UK", 1))
assert.False(t, s.adsEnabled(false, "Ru", 1))

p := s.GetAdProvider(false, "IR", 1)
if assert.NotNil(t, p) {
if assert.True(t, p.ShouldShowAd()) {
assert.Equal(t, s.NativeBannerZoneID, p.GetNativeBannerZoneID())
assert.Equal(t, s.StandardBannerZoneID, p.GetStandardBannerZoneID())
assert.Equal(t, s.InterstitialZoneID, p.GetInterstitialZoneID())
}
}
}
105 changes: 105 additions & 0 deletions config_v2/bootstrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package config

import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/getlantern/yaml"

"github.com/getlantern/flashlight/common"
)

var (
name = ".packaged-lantern.yaml"
lanternYamlName = "lantern.yaml"
)

// BootstrapSettings provides access to configuration embedded directly in Lantern installation
// packages. On OSX, that means data embedded in the Lantern.app app bundle in
// Lantern.app/Contents/Resources/.lantern.yaml, while on Windows that means data embedded
// in AppData/Roaming/Lantern/.lantern.yaml. This allows customization embedded in the
// installer outside of the auto-updated binary that should only be used under special
// circumstances.
type BootstrapSettings struct {
StartupUrl string
}

// ReadBootstrapSettings reads packaged settings from pre-determined paths
// on the various OSes.
func ReadBootstrapSettings(configDir string) (*BootstrapSettings, error) {
_, yamlPath, err := bootstrapPath(name)
if err != nil {
return &BootstrapSettings{}, err
}

ps, er := readSettingsFromFile(yamlPath)
if er != nil {
// This is the local copy of our embedded ration file. This is necessary
// to ensure we remember the embedded ration across auto-updated
// binaries. We write to the local file system instead of to the package
// itself (app bundle on OSX, install directory on Windows) because
// we're not always sure we can write to that directory.
return readSettingsFromFile(filepath.Join(configDir, name))
}
return ps, nil
}

// ReadSettingsFromFile reads BootstrapSettings from the yaml file at the specified
// path.
func readSettingsFromFile(yamlPath string) (*BootstrapSettings, error) {
log.Debugf("Opening file at: %v", yamlPath)
data, err := ioutil.ReadFile(yamlPath)
if err != nil {
// This will happen whenever there's no packaged settings, which is often
log.Debugf("Error reading file %v", err)
return &BootstrapSettings{}, err
}

trimmed := strings.TrimSpace(string(data))

log.Debugf("Read bytes: %v", trimmed)

if trimmed == "" {
log.Debugf("Ignoring empty string")
return &BootstrapSettings{}, errors.New("Empty string")
}
var s BootstrapSettings
err = yaml.Unmarshal([]byte(trimmed), &s)

if err != nil {
log.Errorf("Could not read yaml: %v", err)
return &BootstrapSettings{}, err
}
return &s, nil
}

func bootstrapPath(fileName string) (string, string, error) {
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Errorf("Could not get current directory %v", err)
return "", "", err
}
var yamldir string
if common.Platform == "windows" {
yamldir = dir
} else if common.Platform == "darwin" {
// Code signing doesn't like this file in the current directory
// for whatever reason, so we grab it from the Resources/en.lproj
// directory in the app bundle. See:
// https://developer.apple.com/library/mac/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG402
yamldir = dir + "/../Resources/en.lproj"
if _, err := ioutil.ReadDir(yamldir); err != nil {
// This likely means the user originally installed with an older version that didn't include en.lproj
// in the app bundle, so just look in the old location in Resources.
yamldir = dir + "/../Resources"
}
} else if common.Platform == "linux" {
yamldir = dir + "/../"
}
fullPath := filepath.Join(yamldir, fileName)
log.Debugf("Opening bootstrap file from: %v", fullPath)
return yamldir, fullPath, nil
}
58 changes: 58 additions & 0 deletions config_v2/bootstrap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package config

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/getlantern/yaml"
"github.com/stretchr/testify/assert"

"github.com/getlantern/flashlight/common"
)

func TestBootstrapSettings(t *testing.T) {
file, err := ioutil.TempFile("", ".packaged-lantern.yaml")
defer func() {
err := os.Remove(file.Name())
if err != nil {
log.Errorf("Could not remove file? %v", err)
}
}()
assert.True(t, err == nil, "Should not be an error")
file.Close()

log.Debugf("File at: %v", file.Name())
settings := BootstrapSettings{StartupUrl: "test"}
log.Debugf("Settings: %v", settings)

data, er := yaml.Marshal(&settings)
assert.True(t, er == nil, "Should not be an error")

e := ioutil.WriteFile(file.Name(), data, 0644)
assert.True(t, e == nil, "Should not be an error")

ps, errr := readSettingsFromFile(file.Name())
assert.Equal(t, "test", ps.StartupUrl, "Unexpected startup URL")
assert.NoError(t, errr, "Unable to read settings")

_, path, err := bootstrapPath(name)
assert.True(t, err == nil, "Should not be an error")

var dir string

if common.Platform == "darwin" {
dir, err = filepath.Abs(filepath.Dir(os.Args[0]) + "/../Resources")
} else if common.Platform == "linux" {
dir, err = filepath.Abs(filepath.Dir(os.Args[0]) + "/../")
}
assert.True(t, err == nil, "Should not be an error")

log.Debugf("Running in %v", dir)
if common.Platform == "darwin" {
assert.Equal(t, dir+"/"+name, path, "Unexpected settings dir")
} else if common.Platform == "linux" {
assert.Equal(t, dir+"/"+name, path, "Unexpected settings dir")
}
}
Loading

0 comments on commit f8095bc

Please sign in to comment.