<commit_before>/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package initializer_test

import (
	"testing"
	"time"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apiserver/pkg/admission"
	"k8s.io/apiserver/pkg/admission/initializer"
	"k8s.io/apiserver/pkg/authorization/authorizer"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/fake"
)

// TestWantsScheme ensures that the scheme is injected when
// the WantsScheme interface is implemented by a plugin.
func TestWantsScheme(t *testing.T) {
	scheme := runtime.NewScheme()
	target := initializer.New(nil, nil, nil, scheme)
	wantSchemeAdmission := &WantSchemeAdmission{}
	target.Initialize(wantSchemeAdmission)
	if wantSchemeAdmission.scheme != scheme {
		t.Errorf("expected scheme to be initialized")
	}
}

// TestWantsAuthorizer ensures that the authorizer is injected
// when the WantsAuthorizer interface is implemented by a plugin.
func TestWantsAuthorizer(t *testing.T) {
	target := initializer.New(nil, nil, &TestAuthorizer{}, nil)
	wantAuthorizerAdmission := &WantAuthorizerAdmission{}
	target.Initialize(wantAuthorizerAdmission)
	if wantAuthorizerAdmission.auth == nil {
		t.Errorf("expected authorizer to be initialized but found nil")
	}
}

// TestWantsExternalKubeClientSet ensures that the clienset is injected
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
func TestWantsExternalKubeClientSet(t *testing.T) {
	cs := &fake.Clientset{}
	target := initializer.New(cs, nil, &TestAuthorizer{}, nil)
	wantExternalKubeClientSet := &WantExternalKubeClientSet{}
	target.Initialize(wantExternalKubeClientSet)
	if wantExternalKubeClientSet.cs != cs {
		t.Errorf("expected clientset to be initialized")
	}
}

// TestWantsExternalKubeInformerFactory ensures that the informer factory is injected
// when the WantsExternalKubeInformerFactory interface is implemented by a plugin.
func TestWantsExternalKubeInformerFactory(t *testing.T) {
	cs := &fake.Clientset{}
	sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
	target := initializer.New(cs, sf, &TestAuthorizer{}, nil)
	wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{}
	target.Initialize(wantExternalKubeInformerFactory)
	if wantExternalKubeInformerFactory.sf != sf {
		t.Errorf("expected informer factory to be initialized")
	}
}

// WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
type WantExternalKubeInformerFactory struct {
	sf informers.SharedInformerFactory
}

func (self *WantExternalKubeInformerFactory) SetExternalKubeInformerFactory(sf informers.SharedInformerFactory) {
	self.sf = sf
}
func (self *WantExternalKubeInformerFactory) Admit(a admission.Attributes) error { return nil }
func (self *WantExternalKubeInformerFactory) Handles(o admission.Operation) bool { return false }
func (self *WantExternalKubeInformerFactory) ValidateInitialization() error      { return nil }

var _ admission.Interface = &WantExternalKubeInformerFactory{}
var _ initializer.WantsExternalKubeInformerFactory = &WantExternalKubeInformerFactory{}

// WantExternalKubeClientSet is a test stub that fulfills the WantsExternalKubeClientSet interface
type WantExternalKubeClientSet struct {
	cs kubernetes.Interface
}

func (self *WantExternalKubeClientSet) SetExternalKubeClientSet(cs kubernetes.Interface) { self.cs = cs }
func (self *WantExternalKubeClientSet) Admit(a admission.Attributes) error               { return nil }
func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool               { return false }
func (self *WantExternalKubeClientSet) ValidateInitialization() error                    { return nil }

var _ admission.Interface = &WantExternalKubeClientSet{}
var _ initializer.WantsExternalKubeClientSet = &WantExternalKubeClientSet{}

// WantAuthorizerAdmission is a test stub that fulfills the WantsAuthorizer interface.
type WantAuthorizerAdmission struct {
	auth authorizer.Authorizer
}

func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { self.auth = a }
func (self *WantAuthorizerAdmission) Admit(a admission.Attributes) error    { return nil }
func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool    { return false }
func (self *WantAuthorizerAdmission) ValidateInitialization() error         { return nil }

var _ admission.Interface = &WantAuthorizerAdmission{}
var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}

// TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface.
type TestAuthorizer struct{}

func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
	return authorizer.DecisionNoOpinion, "", nil
}

// wantClientCert is a test stub for testing that fulfulls the WantsClientCert interface.
type clientCertWanter struct {
	gotCert, gotKey []byte
}

func (s *clientCertWanter) SetClientCert(cert, key []byte)     { s.gotCert, s.gotKey = cert, key }
func (s *clientCertWanter) Admit(a admission.Attributes) error { return nil }
func (s *clientCertWanter) Handles(o admission.Operation) bool { return false }
func (s *clientCertWanter) ValidateInitialization() error      { return nil }

// WantSchemeAdmission is a test stub that fulfills the WantsScheme interface.
type WantSchemeAdmission struct {
	scheme *runtime.Scheme
}

func (self *WantSchemeAdmission) SetScheme(s *runtime.Scheme)        { self.scheme = s }
func (self *WantSchemeAdmission) Admit(a admission.Attributes) error { return nil }
func (self *WantSchemeAdmission) Handles(o admission.Operation) bool { return false }
func (self *WantSchemeAdmission) ValidateInitialization() error      { return nil }

var _ admission.Interface = &WantSchemeAdmission{}
var _ initializer.WantsScheme = &WantSchemeAdmission{}
<commit_msg>Fix TestWantsExternalKubeClientSet describe clientset typo<commit_after>/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package initializer_test

import (
	"testing"
	"time"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apiserver/pkg/admission"
	"k8s.io/apiserver/pkg/admission/initializer"
	"k8s.io/apiserver/pkg/authorization/authorizer"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/fake"
)

// TestWantsScheme ensures that the scheme is injected when
// the WantsScheme interface is implemented by a plugin.
func TestWantsScheme(t *testing.T) {
	scheme := runtime.NewScheme()
	target := initializer.New(nil, nil, nil, scheme)
	wantSchemeAdmission := &WantSchemeAdmission{}
	target.Initialize(wantSchemeAdmission)
	if wantSchemeAdmission.scheme != scheme {
		t.Errorf("expected scheme to be initialized")
	}
}

// TestWantsAuthorizer ensures that the authorizer is injected
// when the WantsAuthorizer interface is implemented by a plugin.
func TestWantsAuthorizer(t *testing.T) {
	target := initializer.New(nil, nil, &TestAuthorizer{}, nil)
	wantAuthorizerAdmission := &WantAuthorizerAdmission{}
	target.Initialize(wantAuthorizerAdmission)
	if wantAuthorizerAdmission.auth == nil {
		t.Errorf("expected authorizer to be initialized but found nil")
	}
}

// TestWantsExternalKubeClientSet ensures that the clientset is injected
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
func TestWantsExternalKubeClientSet(t *testing.T) {
	cs := &fake.Clientset{}
	target := initializer.New(cs, nil, &TestAuthorizer{}, nil)
	wantExternalKubeClientSet := &WantExternalKubeClientSet{}
	target.Initialize(wantExternalKubeClientSet)
	if wantExternalKubeClientSet.cs != cs {
		t.Errorf("expected clientset to be initialized")
	}
}

// TestWantsExternalKubeInformerFactory ensures that the informer factory is injected
// when the WantsExternalKubeInformerFactory interface is implemented by a plugin.
func TestWantsExternalKubeInformerFactory(t *testing.T) {
	cs := &fake.Clientset{}
	sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
	target := initializer.New(cs, sf, &TestAuthorizer{}, nil)
	wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{}
	target.Initialize(wantExternalKubeInformerFactory)
	if wantExternalKubeInformerFactory.sf != sf {
		t.Errorf("expected informer factory to be initialized")
	}
}

// WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
type WantExternalKubeInformerFactory struct {
	sf informers.SharedInformerFactory
}

func (self *WantExternalKubeInformerFactory) SetExternalKubeInformerFactory(sf informers.SharedInformerFactory) {
	self.sf = sf
}
func (self *WantExternalKubeInformerFactory) Admit(a admission.Attributes) error { return nil }
func (self *WantExternalKubeInformerFactory) Handles(o admission.Operation) bool { return false }
func (self *WantExternalKubeInformerFactory) ValidateInitialization() error      { return nil }

var _ admission.Interface = &WantExternalKubeInformerFactory{}
var _ initializer.WantsExternalKubeInformerFactory = &WantExternalKubeInformerFactory{}

// WantExternalKubeClientSet is a test stub that fulfills the WantsExternalKubeClientSet interface
type WantExternalKubeClientSet struct {
	cs kubernetes.Interface
}

func (self *WantExternalKubeClientSet) SetExternalKubeClientSet(cs kubernetes.Interface) { self.cs = cs }
func (self *WantExternalKubeClientSet) Admit(a admission.Attributes) error               { return nil }
func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool               { return false }
func (self *WantExternalKubeClientSet) ValidateInitialization() error                    { return nil }

var _ admission.Interface = &WantExternalKubeClientSet{}
var _ initializer.WantsExternalKubeClientSet = &WantExternalKubeClientSet{}

// WantAuthorizerAdmission is a test stub that fulfills the WantsAuthorizer interface.
type WantAuthorizerAdmission struct {
	auth authorizer.Authorizer
}

func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { self.auth = a }
func (self *WantAuthorizerAdmission) Admit(a admission.Attributes) error    { return nil }
func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool    { return false }
func (self *WantAuthorizerAdmission) ValidateInitialization() error         { return nil }

var _ admission.Interface = &WantAuthorizerAdmission{}
var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}

// TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface.
type TestAuthorizer struct{}

func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
	return authorizer.DecisionNoOpinion, "", nil
}

// wantClientCert is a test stub for testing that fulfulls the WantsClientCert interface.
type clientCertWanter struct {
	gotCert, gotKey []byte
}

func (s *clientCertWanter) SetClientCert(cert, key []byte)     { s.gotCert, s.gotKey = cert, key }
func (s *clientCertWanter) Admit(a admission.Attributes) error { return nil }
func (s *clientCertWanter) Handles(o admission.Operation) bool { return false }
func (s *clientCertWanter) ValidateInitialization() error      { return nil }

// WantSchemeAdmission is a test stub that fulfills the WantsScheme interface.
type WantSchemeAdmission struct {
	scheme *runtime.Scheme
}

func (self *WantSchemeAdmission) SetScheme(s *runtime.Scheme)        { self.scheme = s }
func (self *WantSchemeAdmission) Admit(a admission.Attributes) error { return nil }
func (self *WantSchemeAdmission) Handles(o admission.Operation) bool { return false }
func (self *WantSchemeAdmission) ValidateInitialization() error      { return nil }

var _ admission.Interface = &WantSchemeAdmission{}
var _ initializer.WantsScheme = &WantSchemeAdmission{}
<|endoftext|>


<commit_before>package accessors

import (
	"encoding/json"
	"fmt"
	"log"
	"strconv"

	"github.com/kellydunn/golang-geo"
)

// Returns an array of all loot locations and values to plot on the map in iOS
func (ag *AccessorGroup) DumpDatabase(userLatitude float64, userLongitude float64) (string, error) {
	rows, err := ag.DB.Query("SELECT * FROM enemies")
	if err != nil {
		log.Panic(err)
	}

	defer rows.Close()
	columns, err := rows.Columns()
	if err != nil {
		log.Panic(err)
	}

	count := len(columns)
	tableData := make([]map[string]string, 0)
	values := make([]interface{}, count)
	valuePtrs := make([]interface{}, count)

	for rows.Next() {
		for i := 0; i < count; i++ {
			valuePtrs[i] = &values[i]
		}

		rows.Scan(valuePtrs...)
		entry := make(map[string]string)

		for i, col := range columns {
			val := values[i]
			if val != nil {
				entry[col] = fmt.Sprintf("%s", string(val.([]byte)))
			}
		}

		fmt.Printf("%T %v\n", entry["latitude"], entry["latitude"])

		if len(entry["latitude"]) > 0 && len(entry["latitude"]) > 0 {
			latitude, err := strconv.ParseFloat(entry["latitude"], 64)
			if err == nil {
				longitude, err := strconv.ParseFloat(entry["longitude"], 64)
				if err == nil {
					if withinRadius(latitude, longitude, userLatitude, userLongitude) { // Only return enemies that are close to the player
						tableData = append(tableData, entry)
					}
				} else {
					log.Panic(err)
				}
			} else {
				log.Panic(err)
			}
		}
	}

	jsonData, err := json.Marshal(tableData)
	if err != nil {
		log.Panic(err)
	}

	fmt.Println(string(jsonData))
	return string(jsonData), nil
}

func withinRadius(lat1 float64, lon1 float64, lat2 float64, lon2 float64) bool {
	radius := float64(1000000)

	p := geo.NewPoint(lat1, lon1)
	p2 := geo.NewPoint(lat2, lon2)

	dist := p.GreatCircleDistance(p2) // Find the great circle distance between points

	if dist < radius { // Return whether we're inside the radius or not
		return true
	} else {
		return false
	}
}
<commit_msg>Making the radius smaller<commit_after>package accessors

import (
	"encoding/json"
	"fmt"
	"log"
	"strconv"

	"github.com/kellydunn/golang-geo"
)

// Returns an array of all loot locations and values to plot on the map in iOS
func (ag *AccessorGroup) DumpDatabase(userLatitude float64, userLongitude float64) (string, error) {
	rows, err := ag.DB.Query("SELECT * FROM enemies")
	if err != nil {
		log.Panic(err)
	}

	defer rows.Close()
	columns, err := rows.Columns()
	if err != nil {
		log.Panic(err)
	}

	count := len(columns)
	tableData := make([]map[string]string, 0)
	values := make([]interface{}, count)
	valuePtrs := make([]interface{}, count)

	for rows.Next() {
		for i := 0; i < count; i++ {
			valuePtrs[i] = &values[i]
		}

		rows.Scan(valuePtrs...)
		entry := make(map[string]string)

		for i, col := range columns {
			val := values[i]
			if val != nil {
				entry[col] = fmt.Sprintf("%s", string(val.([]byte)))
			}
		}

		fmt.Printf("%T %v\n", entry["latitude"], entry["latitude"])

		if len(entry["latitude"]) > 0 && len(entry["latitude"]) > 0 {
			latitude, err := strconv.ParseFloat(entry["latitude"], 64)
			if err == nil {
				longitude, err := strconv.ParseFloat(entry["longitude"], 64)
				if err == nil {
					if withinRadius(latitude, longitude, userLatitude, userLongitude) { // Only return enemies that are close to the player
						tableData = append(tableData, entry)
					}
				} else {
					log.Panic(err)
				}
			} else {
				log.Panic(err)
			}
		}
	}

	jsonData, err := json.Marshal(tableData)
	if err != nil {
		log.Panic(err)
	}

	fmt.Println(string(jsonData))
	return string(jsonData), nil
}

func withinRadius(lat1 float64, lon1 float64, lat2 float64, lon2 float64) bool {
	radius := float64(1000)

	p := geo.NewPoint(lat1, lon1)
	p2 := geo.NewPoint(lat2, lon2)

	dist := p.GreatCircleDistance(p2) // Find the great circle distance between points

	if dist < radius { // Return whether we're inside the radius or not
		return true
	} else {
		return false
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 Belogik. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goes

import (
	"net/url"
)

// Represents a Connection object to elasticsearch
type Connection struct {
	// The host to connect to
	Host string

	// The port to use
	Port string
}

// Represents a Request to elasticsearch
type Request struct {
	// Which connection will be used
	Conn *Connection

	// A search query
	Query interface{}

	// Which index to search into
	IndexList []string

	// Which type to search into
	TypeList []string

	// HTTP Method to user (GET, POST ...)
	method string

	// Which api keyword (_search, _bulk, etc) to use
	api string

	// Bulk data
	bulkData []byte

	// Request body
	Body []byte

	// A list of extra URL arguments
	ExtraArgs url.Values

	// Used for the id field when indexing a document
	id string
}

// Represents a Response from elasticsearch
type Response struct {
	Acknowledged bool
	Error        string
	Status       uint64
	Took         uint64
	TimedOut     bool  `json:"timed_out"`
	Shards       Shard `json:"_shards"`
	Hits         Hits
	Index        string `json:"_index"`
	Id           string `json:"_id"`
	Type         string `json:"_type"`
	Version      int    `json:"_version"`
	Found        bool

	// Used by the _stats API
	All All `json:"_all"`

	// Used by the _bulk API
	Items []map[string]Item `json:"items,omitempty"`

	// Used by the GET API
	Source map[string]interface{} `json:"_source"`
	Fields map[string]interface{} `json:"fields"`

	// Used by the _status API
	Indices map[string]IndexStatus

	// Scroll id for iteration
	ScrollId string `json:"_scroll_id"`

	Aggregations map[string]Aggregation `json:"aggregations,omitempty"`
}

type Aggregation map[string]interface{}

type Bucket map[string]interface{}

// Represents a document to send to elasticsearch
type Document struct {
	// XXX : interface as we can support nil values
	Index       interface{}
	Type        string
	Id          interface{}
	BulkCommand string
	Fields      map[string]interface{}
}

// Represents the "items" field in a _bulk response
type Item struct {
	Type    string `json:"_type"`
	Id      string `json:"_id"`
	Index   string `json:"_index"`
	Version int    `json:"_version"`
}

// Represents the "_all" field when calling the _stats API
// This is minimal but this is what I only need
type All struct {
	Indices   map[string]StatIndex   `json:"indices"`
	Primaries map[string]StatPrimary `json:"primaries"`
}

type StatIndex struct {
	Primaries map[string]StatPrimary `json:"primaries"`
}

type StatPrimary struct {
	// primary/docs:
	Count   int
	Deleted int
}

// Represents the "shard" struct as returned by elasticsearch
type Shard struct {
	Total      uint64
	Successful uint64
	Failed     uint64
}

// Represent a hit returned by a search
type Hit struct {
	Index  string                 `json:"_index"`
	Type   string                 `json:"_type"`
	Id     string                 `json:"_id"`
	Score  float64                `json:"_score"`
	Source map[string]interface{} `json:"_source"`
	Fields map[string]interface{} `json:"fields"`
}

// Represent the hits structure as returned by elasticsearch
type Hits struct {
	Total uint64
	// max_score may contain the "null" value
	MaxScore interface{} `json:"max_score"`
	Hits     []Hit
}

type SearchError struct {
	Msg        string
	StatusCode uint64
}

// Represent the status for a given index for the _status command
type IndexStatus struct {
	// XXX : problem, int will be marshaled to a float64 which seems logical
	// XXX : is it better to use strings even for int values or to keep
	// XXX : interfaces and deal with float64 ?
	Index map[string]interface{}

	Translog map[string]uint64
	Docs     map[string]uint64
	Merges   map[string]interface{}
	Refresh  map[string]interface{}
	Flush    map[string]interface{}

	// TODO: add shards support later, we do not need it for the moment
}
<commit_msg>added description for aggregation and bucket types<commit_after>// Copyright 2013 Belogik. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goes

import (
	"net/url"
)

// Represents a Connection object to elasticsearch
type Connection struct {
	// The host to connect to
	Host string

	// The port to use
	Port string
}

// Represents a Request to elasticsearch
type Request struct {
	// Which connection will be used
	Conn *Connection

	// A search query
	Query interface{}

	// Which index to search into
	IndexList []string

	// Which type to search into
	TypeList []string

	// HTTP Method to user (GET, POST ...)
	method string

	// Which api keyword (_search, _bulk, etc) to use
	api string

	// Bulk data
	bulkData []byte

	// Request body
	Body []byte

	// A list of extra URL arguments
	ExtraArgs url.Values

	// Used for the id field when indexing a document
	id string
}

// Represents a Response from elasticsearch
type Response struct {
	Acknowledged bool
	Error        string
	Status       uint64
	Took         uint64
	TimedOut     bool  `json:"timed_out"`
	Shards       Shard `json:"_shards"`
	Hits         Hits
	Index        string `json:"_index"`
	Id           string `json:"_id"`
	Type         string `json:"_type"`
	Version      int    `json:"_version"`
	Found        bool

	// Used by the _stats API
	All All `json:"_all"`

	// Used by the _bulk API
	Items []map[string]Item `json:"items,omitempty"`

	// Used by the GET API
	Source map[string]interface{} `json:"_source"`
	Fields map[string]interface{} `json:"fields"`

	// Used by the _status API
	Indices map[string]IndexStatus

	// Scroll id for iteration
	ScrollId string `json:"_scroll_id"`

	Aggregations map[string]Aggregation `json:"aggregations,omitempty"`
}

// Represents an aggregation from response
type Aggregation map[string]interface{}

// Represents a bucket for aggregation
type Bucket map[string]interface{}

// Represents a document to send to elasticsearch
type Document struct {
	// XXX : interface as we can support nil values
	Index       interface{}
	Type        string
	Id          interface{}
	BulkCommand string
	Fields      map[string]interface{}
}

// Represents the "items" field in a _bulk response
type Item struct {
	Type    string `json:"_type"`
	Id      string `json:"_id"`
	Index   string `json:"_index"`
	Version int    `json:"_version"`
}

// Represents the "_all" field when calling the _stats API
// This is minimal but this is what I only need
type All struct {
	Indices   map[string]StatIndex   `json:"indices"`
	Primaries map[string]StatPrimary `json:"primaries"`
}

type StatIndex struct {
	Primaries map[string]StatPrimary `json:"primaries"`
}

type StatPrimary struct {
	// primary/docs:
	Count   int
	Deleted int
}

// Represents the "shard" struct as returned by elasticsearch
type Shard struct {
	Total      uint64
	Successful uint64
	Failed     uint64
}

// Represent a hit returned by a search
type Hit struct {
	Index  string                 `json:"_index"`
	Type   string                 `json:"_type"`
	Id     string                 `json:"_id"`
	Score  float64                `json:"_score"`
	Source map[string]interface{} `json:"_source"`
	Fields map[string]interface{} `json:"fields"`
}

// Represent the hits structure as returned by elasticsearch
type Hits struct {
	Total uint64
	// max_score may contain the "null" value
	MaxScore interface{} `json:"max_score"`
	Hits     []Hit
}

type SearchError struct {
	Msg        string
	StatusCode uint64
}

// Represent the status for a given index for the _status command
type IndexStatus struct {
	// XXX : problem, int will be marshaled to a float64 which seems logical
	// XXX : is it better to use strings even for int values or to keep
	// XXX : interfaces and deal with float64 ?
	Index map[string]interface{}

	Translog map[string]uint64
	Docs     map[string]uint64
	Merges   map[string]interface{}
	Refresh  map[string]interface{}
	Flush    map[string]interface{}

	// TODO: add shards support later, we do not need it for the moment
}
<|endoftext|>


<commit_before>/*
	Go Language Raspberry Pi Interface
	(c) Copyright David Thorpe 2016-2018
	All Rights Reserved
	Documentation http://djthorpe.github.io/gopi/
	For Licensing and Usage information, please see LICENSE.md
*/

package gopi

////////////////////////////////////////////////////////////////////////////////
// TYPES

// SurfaceType of surface (which API it's bound to)
type SurfaceType uint

// SurfaceFlags are flags associated with surface
// usually during operations
type SurfaceFlags uint32

////////////////////////////////////////////////////////////////////////////////
// INTERFACES

// SurfaceManager allows you to open, close and move
// surfaces around an open display
type SurfaceManager interface {
	Driver

	// Return the display associated with the surface manager
	Display() Display

	// Return the name of the surface manager. It's basically the
	// GPU driver
	Name() string

	// Return capabilities for the GPU
	Types() []SurfaceType

	// Return a list of extensions the GPU provides
	Extensions() []string

	// Create background, surface and cursors
	CreateBackground(api SurfaceType, flags SurfaceFlags, opacity float32) (Surface, error)
	CreateSurface(api SurfaceType, flags SurfaceFlags, opacity float32, layer uint, origin Point, size Size) (Surface, error)
	//CreateCursor(api SurfaceType, flags SurfaceFlags, opacity float32, origin Point, cursor SurfaceCursor) (Surface, error)
	DestroySurface(Surface) error

	// Change surface properties (size, position, etc)
	MoveOriginBy(Surface, SurfaceFlags, Point)
	SetOrigin(SurfaceFlags, Point)
	SetSize(Surface, SurfaceFlags, Size)
	SetOpacity(Surface, SurfaceFlags, float32)
	SetLayer(Surface)

	// Surface operations to start and end drawing or other
	// surface operations
	SetCurrentContext(Surface)
	FlushSurface(Surface)
}

// Surface is manipulated by surface manager, and used by
// a GPU API (bitmap or vector drawing mostly)
type Surface interface {
	Type() SurfaceType
	Opacity() float32
	Layer() uint
	Origin() Point
	Size() Size
}

/*
type SurfaceCursor interface {
	API()
	Hotspot()
	Size()
}
*/

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS

const (
	// SurfaceType
	SURFACE_TYPE_NONE SurfaceType = iota
	SURFACE_TYPE_OPENGL
	SURFACE_TYPE_OPENGL_ES
	SURFACE_TYPE_OPENGL_ES2
	SURFACE_TYPE_OPENVG
	SURFACE_TYPE_RGBA32
)

const (
	// SurfaceType
	SURFACE_FLAG_NONE SurfaceFlags = 0
)

////////////////////////////////////////////////////////////////////////////////
// STRINGIFY

func (t SurfaceType) String() string {
	switch t {
	case SURFACE_TYPE_OPENGL:
		return "SURFACE_TYPE_OPENGL"
	case SURFACE_TYPE_OPENGL_ES:
		return "SURFACE_TYPE_OPENGL_ES"
	case SURFACE_TYPE_OPENGL_ES2:
		return "SURFACE_TYPE_OPENGL_ES2"
	case SURFACE_TYPE_OPENVG:
		return "SURFACE_TYPE_OPENVG"
	case SURFACE_TYPE_RGBA32:
		return "SURFACE_TYPE_RGBA32"
	default:
		return "[Invalid SurfaceType value]"
	}
}
<commit_msg>Updated surface code<commit_after>/*
	Go Language Raspberry Pi Interface
	(c) Copyright David Thorpe 2016-2018
	All Rights Reserved
	Documentation http://djthorpe.github.io/gopi/
	For Licensing and Usage information, please see LICENSE.md
*/

package gopi

////////////////////////////////////////////////////////////////////////////////
// TYPES

// SurfaceType of surface (which API it's bound to)
type SurfaceType uint

// SurfaceFlags are flags associated with surface
// usually during operations
type SurfaceFlags uint32

////////////////////////////////////////////////////////////////////////////////
// INTERFACES

// SurfaceManager allows you to open, close and move
// surfaces around an open display
type SurfaceManager interface {
	Driver

	// Return the display associated with the surface manager
	Display() Display

	// Return the name of the surface manager. It's basically the
	// GPU driver
	Name() string

	// Return capabilities for the GPU
	Types() []SurfaceType

	// Return a list of extensions the GPU provides
	Extensions() []string

	// Create background, surface and cursors
	CreateBackground(api SurfaceType, flags SurfaceFlags, opacity float32) (Surface, error)
	CreateSurface(api SurfaceType, flags SurfaceFlags, opacity float32, layer uint, origin Point, size Size) (Surface, error)
	//CreateCursor(api SurfaceType, flags SurfaceFlags, opacity float32, origin Point, cursor SurfaceCursor) (Surface, error)
	DestroySurface(Surface) error

	// Change surface properties (size, position, etc)
	MoveOriginBy(Surface, SurfaceFlags, Point)
	SetOrigin(Surface, SurfaceFlags, Point)
	SetSize(Surface, SurfaceFlags, Size)
	SetOpacity(Surface, SurfaceFlags, float32)
	SetLayer(Surface)

	// Surface operations to start and end drawing or other
	// surface operations
	SetCurrentContext(Surface)
	FlushSurface(Surface)
}

// Surface is manipulated by surface manager, and used by
// a GPU API (bitmap or vector drawing mostly)
type Surface interface {
	Type() SurfaceType
	Opacity() float32
	Layer() uint
	Origin() Point
	Size() Size
}

/*
type SurfaceCursor interface {
	API()
	Hotspot()
	Size()
}
*/

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS

const (
	// SurfaceType
	SURFACE_TYPE_NONE SurfaceType = iota
	SURFACE_TYPE_OPENGL
	SURFACE_TYPE_OPENGL_ES
	SURFACE_TYPE_OPENGL_ES2
	SURFACE_TYPE_OPENVG
	SURFACE_TYPE_RGBA32
)

const (
	// SurfaceType
	SURFACE_FLAG_NONE SurfaceFlags = 0
)

////////////////////////////////////////////////////////////////////////////////
// STRINGIFY

func (t SurfaceType) String() string {
	switch t {
	case SURFACE_TYPE_OPENGL:
		return "SURFACE_TYPE_OPENGL"
	case SURFACE_TYPE_OPENGL_ES:
		return "SURFACE_TYPE_OPENGL_ES"
	case SURFACE_TYPE_OPENGL_ES2:
		return "SURFACE_TYPE_OPENGL_ES2"
	case SURFACE_TYPE_OPENVG:
		return "SURFACE_TYPE_OPENVG"
	case SURFACE_TYPE_RGBA32:
		return "SURFACE_TYPE_RGBA32"
	default:
		return "[Invalid SurfaceType value]"
	}
}
<|endoftext|>


<commit_before>package svfs

import (
	"crypto/cipher"

	"golang.org/x/net/context"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"github.com/xlucas/swift"
)

var (
	// Swift
	SwiftConnection = new(swift.Connection)
	TargetContainer string
	ExtraAttr       bool
	SegmentSize     uint64

	// FS
	AllowRoot          bool
	AllowOther         bool
	DefaultGID         uint64
	DefaultUID         uint64
	DefaultMode        uint64
	DefaultPermissions bool
	BlockSize          uint
	ReadAheadSize      uint

	// Encryption
	Cipher     cipher.AEAD
	Encryption bool
	KeyFile    string
	Key        []byte
	ChunkSize  int64
)

// SVFS implements the Swift Virtual File System.
type SVFS struct{}

// Init sets up the filesystem. It sets configuration settings, starts mandatory
// services and make sure authentication in Swift has succeeded.
func (s *SVFS) Init() (err error) {
	// Copy storage URL option
	overloadStorageURL := SwiftConnection.StorageUrl

	// Hubic special authentication
	if HubicAuthorization != "" && HubicRefreshToken != "" {
		SwiftConnection.Auth = new(HubicAuth)
	}

	// Start directory lister
	DirectoryLister.Start()

	// Authenticate if we don't have a token and storage URL
	if !SwiftConnection.Authenticated() {
		err = SwiftConnection.Authenticate()
	}

	// Swift ACL special authentication
	if overloadStorageURL != "" {
		SwiftConnection.StorageUrl = overloadStorageURL
		SwiftConnection.Auth = newSwiftACLAuth(SwiftConnection.Auth, overloadStorageURL)
	}

	// Data encryption
	if Encryption {
		Cipher, err = newCipher(Key)
	}

	return err
}

// Root gets the root node of the filesystem. It can either be a fake root node
// filled with all the containers found for the given Openstack tenant or a container
// node if a container name have been specified in mount options.
func (s *SVFS) Root() (fs.Node, error) {
	// Mount a specific container
	if TargetContainer != "" {
		baseContainer, _, err := SwiftConnection.Container(TargetContainer)
		if err != nil {
			return nil, err
		}

		// Find segment container too
		segmentContainerName := TargetContainer + SegmentContainerSuffix
		segmentContainer, _, err := SwiftConnection.Container(segmentContainerName)

		// Create it if missing
		if err == swift.ContainerNotFound {
			var container *swift.Container
			container, err = createContainer(segmentContainerName)
			segmentContainer = *container
		}
		if err != nil && err != swift.ContainerNotFound {
			return nil, err
		}

		return &Container{
			Directory: &Directory{
				apex: true,
				c:    &baseContainer,
				cs:   &segmentContainer,
			},
		}, nil
	}

	// Mount all containers within an account
	return &Root{
		Directory: &Directory{
			apex: true,
		},
	}, nil
}

func (s *SVFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
	account, _, err := SwiftConnection.Account()
	if err != nil {
		return err
	}

	resp.Bsize = uint32(BlockSize)

	// Not mounting a specific container, then get account
	// information.
	if TargetContainer == "" {
		resp.Files = uint64(account.Objects)
		resp.Blocks = uint64(account.BytesUsed) / uint64(resp.Bsize)
	}
	// Mount a specific container, then get container usage.
	if TargetContainer != "" {
		c, _, err := SwiftConnection.Container(TargetContainer)
		if err != nil {
			return err
		}
		cs, _, err := SwiftConnection.Container(TargetContainer + SegmentContainerSuffix)
		if err != nil {
			return err
		}
		resp.Files = uint64(c.Count)
		resp.Blocks = uint64(c.Bytes+cs.Bytes) / uint64(resp.Bsize)
	}
	// An account quota has been set, compute relative free space.
	if account.Quota > 0 {
		resp.Bavail = uint64(account.Quota-account.BytesUsed) / uint64(resp.Bsize)
		resp.Bfree = resp.Bavail
		if TargetContainer == "" {
			resp.Blocks = uint64(account.Quota) / uint64(resp.Bsize)
		} else {
			resp.Blocks = uint64(account.Quota-account.BytesUsed)/uint64(resp.Bsize) + resp.Blocks
		}
	} else {
		// Else there's theorically no limit to available storage space.
		used := resp.Blocks
		resp.Blocks = uint64(1<<64-1) / uint64(resp.Bsize)
		resp.Bavail = resp.Blocks - used
		resp.Bfree = resp.Bavail
	}

	return nil
}

var (
	_ fs.FS         = (*SVFS)(nil)
	_ fs.FSStatfser = (*SVFS)(nil)
)
<commit_msg>Fixed maximum volume size for darwin archs<commit_after>package svfs

import (
	"crypto/cipher"

	"golang.org/x/net/context"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"github.com/xlucas/swift"
)

var (
	// Swift
	SwiftConnection = new(swift.Connection)
	TargetContainer string
	ExtraAttr       bool
	SegmentSize     uint64

	// FS
	AllowRoot          bool
	AllowOther         bool
	DefaultGID         uint64
	DefaultUID         uint64
	DefaultMode        uint64
	DefaultPermissions bool
	BlockSize          uint
	ReadAheadSize      uint

	// Encryption
	Cipher     cipher.AEAD
	Encryption bool
	KeyFile    string
	Key        []byte
	ChunkSize  int64
)

// SVFS implements the Swift Virtual File System.
type SVFS struct{}

// Init sets up the filesystem. It sets configuration settings, starts mandatory
// services and make sure authentication in Swift has succeeded.
func (s *SVFS) Init() (err error) {
	// Copy storage URL option
	overloadStorageURL := SwiftConnection.StorageUrl

	// Hubic special authentication
	if HubicAuthorization != "" && HubicRefreshToken != "" {
		SwiftConnection.Auth = new(HubicAuth)
	}

	// Start directory lister
	DirectoryLister.Start()

	// Authenticate if we don't have a token and storage URL
	if !SwiftConnection.Authenticated() {
		err = SwiftConnection.Authenticate()
	}

	// Swift ACL special authentication
	if overloadStorageURL != "" {
		SwiftConnection.StorageUrl = overloadStorageURL
		SwiftConnection.Auth = newSwiftACLAuth(SwiftConnection.Auth, overloadStorageURL)
	}

	// Data encryption
	if Encryption {
		Cipher, err = newCipher(Key)
	}

	return err
}

// Root gets the root node of the filesystem. It can either be a fake root node
// filled with all the containers found for the given Openstack tenant or a container
// node if a container name have been specified in mount options.
func (s *SVFS) Root() (fs.Node, error) {
	// Mount a specific container
	if TargetContainer != "" {
		baseContainer, _, err := SwiftConnection.Container(TargetContainer)
		if err != nil {
			return nil, err
		}

		// Find segment container too
		segmentContainerName := TargetContainer + SegmentContainerSuffix
		segmentContainer, _, err := SwiftConnection.Container(segmentContainerName)

		// Create it if missing
		if err == swift.ContainerNotFound {
			var container *swift.Container
			container, err = createContainer(segmentContainerName)
			segmentContainer = *container
		}
		if err != nil && err != swift.ContainerNotFound {
			return nil, err
		}

		return &Container{
			Directory: &Directory{
				apex: true,
				c:    &baseContainer,
				cs:   &segmentContainer,
			},
		}, nil
	}

	// Mount all containers within an account
	return &Root{
		Directory: &Directory{
			apex: true,
		},
	}, nil
}

func (s *SVFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
	account, _, err := SwiftConnection.Account()
	if err != nil {
		return err
	}

	resp.Bsize = uint32(BlockSize)

	// Not mounting a specific container, then get account
	// information.
	if TargetContainer == "" {
		resp.Files = uint64(account.Objects)
		resp.Blocks = uint64(account.BytesUsed) / uint64(resp.Bsize)
	}
	// Mount a specific container, then get container usage.
	if TargetContainer != "" {
		c, _, err := SwiftConnection.Container(TargetContainer)
		if err != nil {
			return err
		}
		cs, _, err := SwiftConnection.Container(TargetContainer + SegmentContainerSuffix)
		if err != nil {
			return err
		}
		resp.Files = uint64(c.Count)
		resp.Blocks = uint64(c.Bytes+cs.Bytes) / uint64(resp.Bsize)
	}
	// An account quota has been set, compute relative free space.
	if account.Quota > 0 {
		resp.Bavail = uint64(account.Quota-account.BytesUsed) / uint64(resp.Bsize)
		resp.Bfree = resp.Bavail
		if TargetContainer == "" {
			resp.Blocks = uint64(account.Quota) / uint64(resp.Bsize)
		} else {
			resp.Blocks = uint64(account.Quota-account.BytesUsed)/uint64(resp.Bsize) + resp.Blocks
		}
	} else {
		// Else there's theorically no limit to available storage space.
		used := resp.Blocks
		resp.Blocks = uint64(1<<63-1) / uint64(resp.Bsize)
		resp.Bavail = resp.Blocks - used
		resp.Bfree = resp.Bavail
	}

	return nil
}

var (
	_ fs.FS         = (*SVFS)(nil)
	_ fs.FSStatfser = (*SVFS)(nil)
)
<|endoftext|>


<commit_before>package snakepit

import (
	"net/http"

	"github.com/pressly/chi"
	"golang.org/x/net/context"
)

type Swagger struct{}

func NewSwagger() func(next chi.Handler) chi.Handler {
	swagger := &Swagger{}
	return swagger.middleware
}

func (rec *Swagger) middleware(next chi.Handler) chi.Handler {
	return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/swagger" {
			w.Header().Add("Access-Control-Allow-Origin", "*")
			w.Header().Add("Access-Control-Allow-Methods", "GET")
			http.ServeFile(w, r, "./swagger.json")
			return
		}

		next.ServeHTTPC(ctx, w, r)
	})
}
<commit_msg>Swagger middleware now check for swagger.json in the home dir too.<commit_after>package snakepit

import (
	"net/http"
	"os"

	"github.com/pressly/chi"
	"golang.org/x/net/context"
)

type Swagger struct{}

func NewSwagger() func(next chi.Handler) chi.Handler {
	swagger := &Swagger{}
	return swagger.middleware
}

func (rec *Swagger) middleware(next chi.Handler) chi.Handler {
	return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/swagger" {
			w.Header().Add("Access-Control-Allow-Origin", "*")
			w.Header().Add("Access-Control-Allow-Methods", "GET")

			file := "./swagger.json"
			if _, err := os.Stat(file); os.IsNotExist(err) {
				file = "~/swagger.json"
			}

			http.ServeFile(w, r, file)
			return
		}

		next.ServeHTTPC(ctx, w, r)
	})
}
<|endoftext|>


<commit_before>package diff_test

import (
	"bytes"
	"context"
	"strings"
	"testing"

	"github.com/pkg/diff"
	"github.com/sergi/go-diff/diffmatchpatch"
)

var goldenTests = []struct {
	name string
	a, b string
	opts []diff.WriteOpt
	want string // usually from running diff --unified and cleaning up the output
}{
	{
		name: "AddedLinesEnd",
		a:    "A\nB\nC\nD\nE\nF\n",
		b:    "A\nB\nC\nD\nE\nF\n1\n2\n3\n",
		// TODO: stock macOS diff omits the trailing common blank line in this diff,
		// which also changes the @@ line ranges to be 4,3 and 4,6.
		want: `
--- a
+++ b
@@ -4,4 +4,7 @@
 D
 E
 F
+1
+2
+3

`[1:],
	},

	{
		name: "AddedLinesStart",
		a:    "A\nB\nC\nD\nE\nF\n",
		b:    "1\n2\n3\nA\nB\nC\nD\nE\nF\n",
		want: `
--- a
+++ b
@@ -1,3 +1,6 @@
+1
+2
+3
 A
 B
 C
`[1:],
	},

	{
		name: "WithTerminalColor",
		a:    "1\n2\n2",
		b:    "1\n3\n3",
		opts: []diff.WriteOpt{diff.TerminalColor()},
		want: `
`[1:] + "\u001b[1m" + `--- a
+++ b
` + "\u001b[0m" + "\u001b[36m" + `@@ -1,3 +1,3 @@
` + "\u001b[0m" + `] 1
`[1:] + "\u001b[31m" + `-2
-2
` + "\u001b[32m" + `+3
+3
` + "\u001b[0m",
	},
}

func TestGolden(t *testing.T) {
	for _, test := range goldenTests {
		t.Run(test.name, func(t *testing.T) {
			as := strings.Split(test.a, "\n")
			bs := strings.Split(test.b, "\n")
			ab := diff.Strings(as, bs)
			// TODO: supply an EditScript to the tests instead doing a Myers diff here.
			// Doing it as I have done, the lazy way, mixes concerns: diff algorithm vs unification algorithm
			// vs unified diff formatting.
			e := diff.Myers(context.Background(), ab)
			e = e.WithContextSize(3)
			buf := new(bytes.Buffer)
			e.WriteUnified(buf, ab, test.opts...)
			got := buf.String()
			if test.want != got {
				t.Logf("%q\n", test.want)
				t.Logf("%q\n", got)
				dmp := diffmatchpatch.New()
				delta := dmp.DiffMain(test.want, got, false)
				t.Errorf("bad diff: a=%q b=%q\n\ngot:\n%s\nwant:\n%s\ndiff:\n%s\n",
					test.a, test.b,
					got, test.want,
					dmp.DiffPrettyText(delta),
				)
			}
		})
	}
}
<commit_msg>simplify test<commit_after>package diff_test

import (
	"bytes"
	"context"
	"strings"
	"testing"

	"github.com/pkg/diff"
	"github.com/sergi/go-diff/diffmatchpatch"
)

var goldenTests = []struct {
	name string
	a, b string
	opts []diff.WriteOpt
	want string // usually from running diff --unified and cleaning up the output
}{
	{
		name: "AddedLinesEnd",
		a:    "A\nB\nC\nD\nE\nF\n",
		b:    "A\nB\nC\nD\nE\nF\n1\n2\n3\n",
		// TODO: stock macOS diff omits the trailing common blank line in this diff,
		// which also changes the @@ line ranges to be 4,3 and 4,6.
		want: `
--- a
+++ b
@@ -4,4 +4,7 @@
 D
 E
 F
+1
+2
+3

`[1:],
	},

	{
		name: "AddedLinesStart",
		a:    "A\nB\nC\nD\nE\nF\n",
		b:    "1\n2\n3\nA\nB\nC\nD\nE\nF\n",
		want: `
--- a
+++ b
@@ -1,3 +1,6 @@
+1
+2
+3
 A
 B
 C
`[1:],
	},

	{
		name: "WithTerminalColor",
		a:    "1\n2\n2",
		b:    "1\n3\n3",
		opts: []diff.WriteOpt{diff.TerminalColor()},
		want: `
`[1:] + "\u001b[1m" + `--- a
+++ b
` + "\u001b[0m" + "\u001b[36m" + `@@ -1,3 +1,3 @@
` + "\u001b[0m" + ` 1
` + "\u001b[31m" + `-2
-2
` + "\u001b[32m" + `+3
+3
` + "\u001b[0m",
	},
}

func TestGolden(t *testing.T) {
	for _, test := range goldenTests {
		t.Run(test.name, func(t *testing.T) {
			as := strings.Split(test.a, "\n")
			bs := strings.Split(test.b, "\n")
			ab := diff.Strings(as, bs)
			// TODO: supply an EditScript to the tests instead doing a Myers diff here.
			// Doing it as I have done, the lazy way, mixes concerns: diff algorithm vs unification algorithm
			// vs unified diff formatting.
			e := diff.Myers(context.Background(), ab)
			e = e.WithContextSize(3)
			buf := new(bytes.Buffer)
			e.WriteUnified(buf, ab, test.opts...)
			got := buf.String()
			if test.want != got {
				t.Logf("%q\n", test.want)
				t.Logf("%q\n", got)
				dmp := diffmatchpatch.New()
				delta := dmp.DiffMain(test.want, got, false)
				t.Errorf("bad diff: a=%q b=%q\n\ngot:\n%s\nwant:\n%s\ndiff:\n%s\n",
					test.a, test.b,
					got, test.want,
					dmp.DiffPrettyText(delta),
				)
			}
		})
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"runtime"
)

var hostsFile string

func init() {
	if runtime.GOOS == "windows" {
		hostsFile = "C:\\Windows\\System32\\drivers\\etc\\hosts"
	} else {
		hostsFile = "/etc/hosts"
	}
}

func main() {

	var (
		resp *http.Response
		re   *regexp.Regexp
		err  error
	)

	urlList := []string{
		"http://googlehosts-hostsfiles.stor.sinaapp.com/hosts",
		"http://blog.my-eclipse.cn/hosts.txt",
		"https://raw.githubusercontent.com/racaljk/hosts/master/hosts",
		"http://gcat.gq/wp-content/uploads/2016/04/201604040806092.txt",
	}

	for _, url := range urlList {

		resp, err = http.Get(url)
		if err != nil {
			fmt.Println(err)
		}

		if resp.StatusCode == http.StatusOK {
			fmt.Println("Update your hosts......")
			break
		} else {
			continue
		}
	}

	if resp.StatusCode != http.StatusOK {
		fmt.Println("Sorry :(\nUpdate your hosts fail, program will exit.\n")
		os.Exit(-1)
	}

	oldHosts, err := ioutil.ReadFile(hostsFile)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	oldHostsContext := string(oldHosts)
	var pat = "(?s)#old hosts start.*#old hosts end"

	re, _ = regexp.Compile(pat)
	oldStr := re.FindAllStringSubmatch(string(oldHostsContext), -1)
	if len(oldStr) == 0 {
		oldHostsContext = "\n#old hosts start\n" + oldHostsContext + "\n#old hosts end\n"
	} else {
		oldHostsContext = oldStr[0][0]
	}

	file, err := os.OpenFile(hostsFile, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
	defer file.Close()

	file.WriteString(oldHostsContext)
	file.WriteString("\n \n")

	newHosts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	file.WriteString(string(newHosts))
	fmt.Println("\nUpdate the hosts success, press ENTER to exit!")

	resp.Body.Close()
	fmt.Scanln()
}
<commit_msg>adjust code<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"runtime"
)

func main() {

	var (
		resp  *http.Response
		re    *regexp.Regexp
		err   error
		hosts string
	)

	// check OS type
	if runtime.GOOS == "windows" {
		hosts = "C:/Windows/System32/drivers/etc/hosts"
	} else {
		hosts = "/etc/hosts"
	}

	urlList := []string{
		"http://googlehosts-hostsfiles.stor.sinaapp.com/hosts",
		"http://blog.my-eclipse.cn/hosts.txt",
		"https://raw.githubusercontent.com/racaljk/hosts/master/hosts",
		"http://gcat.gq/wp-content/uploads/2016/04/201604040806092.txt",
	}

	// search for available hosts url
	for _, url := range urlList {
		resp, err = http.Get(url)
		if err != nil {
			fmt.Println(err)
		}

		if resp.StatusCode == http.StatusOK {
			fmt.Println("update hosts......")
			break
		} else {
			continue
		}
	}

	if resp.StatusCode != http.StatusOK {
		fmt.Println("sorry :(\nfail to update hosts, exit.\n")
		os.Exit(-1)
	}

	fileBuf, err := ioutil.ReadFile(hosts)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	var pat = "(?s)#old hosts start.*#old hosts end"
	re, _ = regexp.Compile(pat)

	oldHosts := string(fileBuf)
	findResult := re.FindAllStringSubmatch(oldHosts, -1)
	if len(findResult) == 0 {
		oldHosts = "\n#old hosts start\n" + oldHosts + "\n#old hosts end\n"
	} else {
		oldHosts = findResult[0][0]
	}

	file, err := os.OpenFile(hosts, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
	defer file.Close()

	file.WriteString(oldHosts)
	file.WriteString("\n \n")

	newHosts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
	resp.Body.Close()

	file.WriteString(string(newHosts))

	fmt.Println("\nupdate the hosts success, press ENTER to exit.")
	fmt.Scanln()
}
<|endoftext|>


<commit_before>package util

import (
	"os"
	"time"

	"github.com/briandowns/spinner"
)

var (
	SpinnerSymbol int = 14
)

type Spinner struct {
	*spinner.Spinner

	Text string
}

func NewSpinner(text string) *Spinner {
	return &Spinner{
		Spinner: spinner.New(spinner.CharSets[SpinnerSymbol], 100*time.Millisecond),
		Text:    text,
	}
}

func (s *Spinner) Start() {
	s.Spinner.Writer = os.Stderr
	if len(s.Text) > 0 {
		s.Suffix = " " + s.Text
	}
	s.Spinner.Start()
}

func (s *Spinner) Stop() {
	s.Spinner.Stop()
}
<commit_msg>Add \r to spinner prefix<commit_after>package util

import (
	"os"
	"time"

	"github.com/briandowns/spinner"
)

var (
	SpinnerSymbol int = 14
)

type Spinner struct {
	*spinner.Spinner

	Text string
}

func NewSpinner(text string) *Spinner {
	return &Spinner{
		Spinner: spinner.New(spinner.CharSets[SpinnerSymbol], 100*time.Millisecond),
		Text:    text,
	}
}

func (s *Spinner) Start() {
	s.Spinner.Writer = os.Stderr
	s.Spinner.Prefix = "\r"
	if len(s.Text) > 0 {
		s.Suffix = " " + s.Text
	}
	s.Spinner.Start()
}

func (s *Spinner) Stop() {
	s.Spinner.Stop()
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package utils

import (
	"fmt"
	"net"
	"net/url"
	"strconv"
	"strings"

	"github.com/gravitational/trace"
	log "github.com/sirupsen/logrus"
)

// NetAddr is network address that includes network, optional path and
// host port
type NetAddr struct {
	// Addr is the host:port address, like "localhost:22"
	Addr string `json:"addr"`
	// AddrNetwork is the type of a network socket, like "tcp" or "unix"
	AddrNetwork string `json:"network,omitempty"`
	// Path is a socket file path, like '/var/path/to/socket' in "unix:///var/path/to/socket"
	Path string `json:"path,omitempty"`
}

// Host returns host part of address without port
func (a *NetAddr) Host() string {
	host, _, err := net.SplitHostPort(a.Addr)
	if err == nil {
		return host
	}
	// this is done to remove optional square brackets
	if ip := net.ParseIP(strings.Trim(a.Addr, "[]")); len(ip) != 0 {
		return ip.String()
	}
	return a.Addr
}

// Port returns defaultPort if no port is set or is invalid,
// the real port otherwise
func (a *NetAddr) Port(defaultPort int) int {
	_, port, err := net.SplitHostPort(a.Addr)
	if err != nil {
		return defaultPort
	}
	porti, err := strconv.Atoi(port)
	if err != nil {
		return defaultPort
	}
	return porti
}

// Equals returns true if address is equal to other
func (a *NetAddr) Equals(other NetAddr) bool {
	return a.Addr == other.Addr && a.AddrNetwork == other.AddrNetwork && a.Path == other.Path
}

// IsLocal returns true if this is a local address
func (a *NetAddr) IsLocal() bool {
	host, _, err := net.SplitHostPort(a.Addr)
	if err != nil {
		return false
	}
	return IsLocalhost(host)
}

// IsLoopback returns true if this is a loopback address
func (a *NetAddr) IsLoopback() bool {
	return IsLoopback(a.Addr)
}

// IsEmpty returns true if address is empty
func (a *NetAddr) IsEmpty() bool {
	return a == nil || (a.Addr == "" && a.AddrNetwork == "" && a.Path == "")
}

// FullAddress returns full address including network and address (tcp://0.0.0.0:1243)
func (a *NetAddr) FullAddress() string {
	return fmt.Sprintf("%v://%v", a.AddrNetwork, a.Addr)
}

// String returns address without network (0.0.0.0:1234)
func (a *NetAddr) String() string {
	return a.Addr
}

// Network returns the scheme for this network address (tcp or unix)
func (a *NetAddr) Network() string {
	return a.AddrNetwork
}

// MarshalYAML defines how a network address should be marshalled to a string
func (a *NetAddr) MarshalYAML() (interface{}, error) {
	url := url.URL{Scheme: a.AddrNetwork, Host: a.Addr, Path: a.Path}
	return strings.TrimLeft(url.String(), "/"), nil
}

// UnmarshalYAML defines how a string can be unmarshalled into a network address
func (a *NetAddr) UnmarshalYAML(unmarshal func(interface{}) error) error {
	var addr string
	err := unmarshal(&addr)
	if err != nil {
		return err
	}

	parsedAddr, err := ParseAddr(addr)
	if err != nil {
		return err
	}

	*a = *parsedAddr
	return nil
}

func (a *NetAddr) Set(s string) error {
	v, err := ParseAddr(s)
	if err != nil {
		return trace.Wrap(err)
	}
	a.Addr = v.Addr
	a.AddrNetwork = v.AddrNetwork
	return nil
}

// ParseAddrs parses the provided slice of strings as a slice of NetAddr's.
func ParseAddrs(addrs []string) (result []NetAddr, err error) {
	for _, addr := range addrs {
		parsed, err := ParseAddr(addr)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		result = append(result, *parsed)
	}
	return result, nil
}

// ParseAddr takes strings like "tcp://host:port/path" and returns
// *NetAddr or an error
func ParseAddr(a string) (*NetAddr, error) {
	if a == "" {
		return nil, trace.BadParameter("missing parameter address")
	}
	if !strings.Contains(a, "://") {
		return &NetAddr{Addr: a, AddrNetwork: "tcp"}, nil
	}
	u, err := url.Parse(a)
	if err != nil {
		return nil, trace.BadParameter("failed to parse %q: %v", a, err)
	}
	switch u.Scheme {
	case "tcp":
		return &NetAddr{Addr: u.Host, AddrNetwork: u.Scheme, Path: u.Path}, nil
	case "unix":
		return &NetAddr{Addr: u.Path, AddrNetwork: u.Scheme}, nil
	case "http", "https":
		return &NetAddr{Addr: u.Host, AddrNetwork: u.Scheme, Path: u.Path}, nil
	default:
		return nil, trace.BadParameter("'%v': unsupported scheme: '%v'", a, u.Scheme)
	}
}

// MustParseAddr parses the provided string into NetAddr or panics on an error
func MustParseAddr(a string) *NetAddr {
	addr, err := ParseAddr(a)
	if err != nil {
		panic(fmt.Sprintf("failed to parse %v: %v", a, err))
	}
	return addr
}

// FromAddr returns NetAddr from golang standard net.Addr
func FromAddr(a net.Addr) NetAddr {
	return NetAddr{AddrNetwork: a.Network(), Addr: a.String()}
}

// JoinAddrSlices joins two addr slices and returns a resulting slice
func JoinAddrSlices(a []NetAddr, b []NetAddr) []NetAddr {
	if len(a)+len(b) == 0 {
		return nil
	}
	out := make([]NetAddr, 0, len(a)+len(b))
	out = append(out, a...)
	out = append(out, b...)
	return out
}

// ParseHostPortAddr takes strings like "host:port" and returns
// *NetAddr or an error
//
// If defaultPort == -1 it expects 'hostport' string to have it
func ParseHostPortAddr(hostport string, defaultPort int) (*NetAddr, error) {
	addr, err := ParseAddr(hostport)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	// port is required but not set
	if defaultPort == -1 && addr.Addr == addr.Host() {
		return nil, trace.BadParameter("missing port in address %q", hostport)
	}
	addr.Addr = net.JoinHostPort(addr.Host(), fmt.Sprintf("%v", addr.Port(defaultPort)))
	return addr, nil
}

// DialAddrFromListenAddr returns dial address from listen address
func DialAddrFromListenAddr(listenAddr NetAddr) NetAddr {
	if listenAddr.IsEmpty() {
		return listenAddr
	}
	return NetAddr{Addr: ReplaceLocalhost(listenAddr.Addr, "127.0.0.1")}
}

// ReplaceLocalhost checks if a given address is link-local (like 0.0.0.0 or 127.0.0.1)
// and replaces it with the IP taken from replaceWith, preserving the original port
//
// Both addresses are in "host:port" format
// The function returns the original value if it encounters any problems with parsing
func ReplaceLocalhost(addr, replaceWith string) string {
	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		return addr
	}
	if IsLocalhost(host) {
		host, _, err = net.SplitHostPort(replaceWith)
		if err != nil {
			return addr
		}
		addr = net.JoinHostPort(host, port)
	}
	return addr
}

// IsLocalhost returns true if this is a local hostname or ip
func IsLocalhost(host string) bool {
	if host == "localhost" {
		return true
	}
	ip := net.ParseIP(host)
	return ip.IsLoopback() || ip.IsUnspecified()
}

// IsLoopback returns 'true' if a given hostname resolves to local
// host's loopback interface
func IsLoopback(host string) bool {
	if strings.Contains(host, ":") {
		var err error
		host, _, err = net.SplitHostPort(host)
		if err != nil {
			return false
		}
	}
	ips, err := net.LookupIP(host)
	if err != nil {
		return false
	}
	for _, ip := range ips {
		if ip.IsLoopback() {
			return true
		}
	}
	return false
}

// GuessIP tries to guess an IP address this machine is reachable at on the
// internal network, always picking IPv4 from the internal address space
//
// If no internal IPs are found, it returns 127.0.0.1 but it never returns
// an address from the public IP space
func GuessHostIP() (ip net.IP, err error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, trace.Wrap(err)
	}
	adrs := make([]net.Addr, 0)
	for _, iface := range ifaces {
		ifadrs, err := iface.Addrs()
		if err != nil {
			log.Warn(err)
		} else {
			adrs = append(adrs, ifadrs...)
		}
	}
	return guessHostIP(adrs), nil
}

func guessHostIP(addrs []net.Addr) (ip net.IP) {
	// collect the list of all IPv4s
	var ips []net.IP
	for _, addr := range addrs {
		var ipAddr net.IP
		a, ok := addr.(*net.IPAddr)
		if ok {
			ipAddr = a.IP
		} else {
			in, ok := addr.(*net.IPNet)
			if ok {
				ipAddr = in.IP
			} else {
				continue
			}
		}
		if ipAddr.To4() == nil || ipAddr.IsLoopback() || ipAddr.IsMulticast() {
			continue
		}
		ips = append(ips, ipAddr)
	}

	for i := range ips {
		first := &net.IPNet{IP: net.IPv4(10, 0, 0, 0), Mask: net.CIDRMask(8, 32)}
		second := &net.IPNet{IP: net.IPv4(192, 168, 0, 0), Mask: net.CIDRMask(16, 32)}
		third := &net.IPNet{IP: net.IPv4(172, 16, 0, 0), Mask: net.CIDRMask(12, 32)}

		// our first pick would be "10.0.0.0/8"
		if first.Contains(ips[i]) {
			ip = ips[i]
			break
			// our 2nd pick would be "192.168.0.0/16"
		} else if second.Contains(ips[i]) {
			ip = ips[i]
			// our 3rd pick would be "172.16.0.0/12"
		} else if third.Contains(ips[i]) && !second.Contains(ip) {
			ip = ips[i]
		}
	}
	if ip == nil {
		if len(ips) > 0 {
			return ips[0]
		}
		// fallback to loopback
		ip = net.IPv4(127, 0, 0, 1)
	}
	return ip
}
<commit_msg>Add new helper function for parsing multiple addresses at once. (#4675)<commit_after>/*
Copyright 2015 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package utils

import (
	"fmt"
	"net"
	"net/url"
	"strconv"
	"strings"

	"github.com/gravitational/trace"
	log "github.com/sirupsen/logrus"
)

// NetAddr is network address that includes network, optional path and
// host port
type NetAddr struct {
	// Addr is the host:port address, like "localhost:22"
	Addr string `json:"addr"`
	// AddrNetwork is the type of a network socket, like "tcp" or "unix"
	AddrNetwork string `json:"network,omitempty"`
	// Path is a socket file path, like '/var/path/to/socket' in "unix:///var/path/to/socket"
	Path string `json:"path,omitempty"`
}

// Host returns host part of address without port
func (a *NetAddr) Host() string {
	host, _, err := net.SplitHostPort(a.Addr)
	if err == nil {
		return host
	}
	// this is done to remove optional square brackets
	if ip := net.ParseIP(strings.Trim(a.Addr, "[]")); len(ip) != 0 {
		return ip.String()
	}
	return a.Addr
}

// Port returns defaultPort if no port is set or is invalid,
// the real port otherwise
func (a *NetAddr) Port(defaultPort int) int {
	_, port, err := net.SplitHostPort(a.Addr)
	if err != nil {
		return defaultPort
	}
	porti, err := strconv.Atoi(port)
	if err != nil {
		return defaultPort
	}
	return porti
}

// Equals returns true if address is equal to other
func (a *NetAddr) Equals(other NetAddr) bool {
	return a.Addr == other.Addr && a.AddrNetwork == other.AddrNetwork && a.Path == other.Path
}

// IsLocal returns true if this is a local address
func (a *NetAddr) IsLocal() bool {
	host, _, err := net.SplitHostPort(a.Addr)
	if err != nil {
		return false
	}
	return IsLocalhost(host)
}

// IsLoopback returns true if this is a loopback address
func (a *NetAddr) IsLoopback() bool {
	return IsLoopback(a.Addr)
}

// IsEmpty returns true if address is empty
func (a *NetAddr) IsEmpty() bool {
	return a == nil || (a.Addr == "" && a.AddrNetwork == "" && a.Path == "")
}

// FullAddress returns full address including network and address (tcp://0.0.0.0:1243)
func (a *NetAddr) FullAddress() string {
	return fmt.Sprintf("%v://%v", a.AddrNetwork, a.Addr)
}

// String returns address without network (0.0.0.0:1234)
func (a *NetAddr) String() string {
	return a.Addr
}

// Network returns the scheme for this network address (tcp or unix)
func (a *NetAddr) Network() string {
	return a.AddrNetwork
}

// MarshalYAML defines how a network address should be marshalled to a string
func (a *NetAddr) MarshalYAML() (interface{}, error) {
	url := url.URL{Scheme: a.AddrNetwork, Host: a.Addr, Path: a.Path}
	return strings.TrimLeft(url.String(), "/"), nil
}

// UnmarshalYAML defines how a string can be unmarshalled into a network address
func (a *NetAddr) UnmarshalYAML(unmarshal func(interface{}) error) error {
	var addr string
	err := unmarshal(&addr)
	if err != nil {
		return err
	}

	parsedAddr, err := ParseAddr(addr)
	if err != nil {
		return err
	}

	*a = *parsedAddr
	return nil
}

func (a *NetAddr) Set(s string) error {
	v, err := ParseAddr(s)
	if err != nil {
		return trace.Wrap(err)
	}
	a.Addr = v.Addr
	a.AddrNetwork = v.AddrNetwork
	return nil
}

// ParseAddrs parses the provided slice of strings as a slice of NetAddr's.
func ParseAddrs(addrs []string) (result []NetAddr, err error) {
	for _, addr := range addrs {
		parsed, err := ParseAddr(addr)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		result = append(result, *parsed)
	}
	return result, nil
}

// ParseAddr takes strings like "tcp://host:port/path" and returns
// *NetAddr or an error
func ParseAddr(a string) (*NetAddr, error) {
	if a == "" {
		return nil, trace.BadParameter("missing parameter address")
	}
	if !strings.Contains(a, "://") {
		return &NetAddr{Addr: a, AddrNetwork: "tcp"}, nil
	}
	u, err := url.Parse(a)
	if err != nil {
		return nil, trace.BadParameter("failed to parse %q: %v", a, err)
	}
	switch u.Scheme {
	case "tcp":
		return &NetAddr{Addr: u.Host, AddrNetwork: u.Scheme, Path: u.Path}, nil
	case "unix":
		return &NetAddr{Addr: u.Path, AddrNetwork: u.Scheme}, nil
	case "http", "https":
		return &NetAddr{Addr: u.Host, AddrNetwork: u.Scheme, Path: u.Path}, nil
	default:
		return nil, trace.BadParameter("'%v': unsupported scheme: '%v'", a, u.Scheme)
	}
}

// MustParseAddr parses the provided string into NetAddr or panics on an error
func MustParseAddr(a string) *NetAddr {
	addr, err := ParseAddr(a)
	if err != nil {
		panic(fmt.Sprintf("failed to parse %v: %v", a, err))
	}
	return addr
}

// MustParseAddrList parses the provided list of strings into a NetAddr list or panics on error
func MustParseAddrList(aList ...string) []NetAddr {
	addrList := make([]NetAddr, len(aList))
	for i, a := range aList {
		addrList[i] = *MustParseAddr(a)
	}
	return addrList
}

// FromAddr returns NetAddr from golang standard net.Addr
func FromAddr(a net.Addr) NetAddr {
	return NetAddr{AddrNetwork: a.Network(), Addr: a.String()}
}

// JoinAddrSlices joins two addr slices and returns a resulting slice
func JoinAddrSlices(a []NetAddr, b []NetAddr) []NetAddr {
	if len(a)+len(b) == 0 {
		return nil
	}
	out := make([]NetAddr, 0, len(a)+len(b))
	out = append(out, a...)
	out = append(out, b...)
	return out
}

// ParseHostPortAddr takes strings like "host:port" and returns
// *NetAddr or an error
//
// If defaultPort == -1 it expects 'hostport' string to have it
func ParseHostPortAddr(hostport string, defaultPort int) (*NetAddr, error) {
	addr, err := ParseAddr(hostport)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	// port is required but not set
	if defaultPort == -1 && addr.Addr == addr.Host() {
		return nil, trace.BadParameter("missing port in address %q", hostport)
	}
	addr.Addr = net.JoinHostPort(addr.Host(), fmt.Sprintf("%v", addr.Port(defaultPort)))
	return addr, nil
}

// DialAddrFromListenAddr returns dial address from listen address
func DialAddrFromListenAddr(listenAddr NetAddr) NetAddr {
	if listenAddr.IsEmpty() {
		return listenAddr
	}
	return NetAddr{Addr: ReplaceLocalhost(listenAddr.Addr, "127.0.0.1")}
}

// ReplaceLocalhost checks if a given address is link-local (like 0.0.0.0 or 127.0.0.1)
// and replaces it with the IP taken from replaceWith, preserving the original port
//
// Both addresses are in "host:port" format
// The function returns the original value if it encounters any problems with parsing
func ReplaceLocalhost(addr, replaceWith string) string {
	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		return addr
	}
	if IsLocalhost(host) {
		host, _, err = net.SplitHostPort(replaceWith)
		if err != nil {
			return addr
		}
		addr = net.JoinHostPort(host, port)
	}
	return addr
}

// IsLocalhost returns true if this is a local hostname or ip
func IsLocalhost(host string) bool {
	if host == "localhost" {
		return true
	}
	ip := net.ParseIP(host)
	return ip.IsLoopback() || ip.IsUnspecified()
}

// IsLoopback returns 'true' if a given hostname resolves to local
// host's loopback interface
func IsLoopback(host string) bool {
	if strings.Contains(host, ":") {
		var err error
		host, _, err = net.SplitHostPort(host)
		if err != nil {
			return false
		}
	}
	ips, err := net.LookupIP(host)
	if err != nil {
		return false
	}
	for _, ip := range ips {
		if ip.IsLoopback() {
			return true
		}
	}
	return false
}

// GuessIP tries to guess an IP address this machine is reachable at on the
// internal network, always picking IPv4 from the internal address space
//
// If no internal IPs are found, it returns 127.0.0.1 but it never returns
// an address from the public IP space
func GuessHostIP() (ip net.IP, err error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, trace.Wrap(err)
	}
	adrs := make([]net.Addr, 0)
	for _, iface := range ifaces {
		ifadrs, err := iface.Addrs()
		if err != nil {
			log.Warn(err)
		} else {
			adrs = append(adrs, ifadrs...)
		}
	}
	return guessHostIP(adrs), nil
}

func guessHostIP(addrs []net.Addr) (ip net.IP) {
	// collect the list of all IPv4s
	var ips []net.IP
	for _, addr := range addrs {
		var ipAddr net.IP
		a, ok := addr.(*net.IPAddr)
		if ok {
			ipAddr = a.IP
		} else {
			in, ok := addr.(*net.IPNet)
			if ok {
				ipAddr = in.IP
			} else {
				continue
			}
		}
		if ipAddr.To4() == nil || ipAddr.IsLoopback() || ipAddr.IsMulticast() {
			continue
		}
		ips = append(ips, ipAddr)
	}

	for i := range ips {
		first := &net.IPNet{IP: net.IPv4(10, 0, 0, 0), Mask: net.CIDRMask(8, 32)}
		second := &net.IPNet{IP: net.IPv4(192, 168, 0, 0), Mask: net.CIDRMask(16, 32)}
		third := &net.IPNet{IP: net.IPv4(172, 16, 0, 0), Mask: net.CIDRMask(12, 32)}

		// our first pick would be "10.0.0.0/8"
		if first.Contains(ips[i]) {
			ip = ips[i]
			break
			// our 2nd pick would be "192.168.0.0/16"
		} else if second.Contains(ips[i]) {
			ip = ips[i]
			// our 3rd pick would be "172.16.0.0/12"
		} else if third.Contains(ips[i]) && !second.Contains(ip) {
			ip = ips[i]
		}
	}
	if ip == nil {
		if len(ips) > 0 {
			return ips[0]
		}
		// fallback to loopback
		ip = net.IPv4(127, 0, 0, 1)
	}
	return ip
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"math"
	"odf/ods"
	"os"
	"strconv"
	"strings"
)

const (
	odsPath = "/Users/carl/Downloads/bills.ods"
)

// Print out the data in a table.
func Print(table ods.Table) {
	for _, row := range table.Strings() {
		if len(row) == 0 || row[0] == "" {
			continue
		}
		sep := ""
		for _, field := range row {
			fmt.Print(sep, strconv.Quote(field))
			sep = "\t"
		}
		fmt.Print("\n")
	}
}

func ProcessNewFormat(table ods.Table) {
	for _, row := range table.Strings() {
		if len(row) < 2 || row[0] == "" || strings.Index(row[0], "Balance") == 0 {
			continue
		}
		if strings.Index(row[0], "Billing Cycle") == 0 {
			fmt.Printf("\n*** %s\n", row[0])
			continue
		}
		biller := row[0]
		date := row[1]
		if date == "" {
			continue
		}
		debit := 0.0
		credit := 0.0
		if len(row) >= 3 {
		println(row[2])
			debit, _ = parseMoney(row[2])
		}
		if len(row) >= 4 {
			credit, _ = parseMoney(row[3])
		}
		fmt.Printf("%35s; %11s; %10.2f; %5.2f\n", biller, date, debit, credit)
	}
}

func ProcessOldFormat(table ods.Table) {
	for _, row := range table.Strings() {
		//println(strings.Index(row[0], "Billing Cycle"))
		if len(row) > 2 || row[0] == "" || row[0] == "Leftover" {
			continue
		}
		biller := row[0]
		date := row[1]
		if date == "" {
			continue
		}
		var amount float64
		var err error
		if len(row) >= 3 {
			amount, err = parseMoney(row[2])
			println(amount)
			if err != nil {
				log.Fatal(err)
				continue
			}
		}
		credit := 0.0
		debit := 0.0
		if amount < 0 || biller != "Paycheck" {
			credit = math.Abs(amount)
		} else {
			debit = math.Abs(amount)
		}

		fmt.Printf("%35s; %11s; %10.2f; %5.2f\n", biller, date, debit, credit)
	}
}

func parseMoney(data string) (float64, error) {
	amount, err := strconv.ParseFloat(strings.Replace(data, "$", "", 1), 32)
	return amount, err
}

func main() {
	var doc ods.Doc

	f, err := ods.Open(odsPath)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	defer f.Close()

	if err := f.ParseContent(&doc); err != nil {
		log.Fatal(err)
		//fmt.Fprintln(os.Stderr, err)
		return
	}

	// Dump the first table one line per row, writing
	// tab separated, quoted fields.
	//for _, table := range doc.Table {
		table := doc.Table[0]
		year, err := strconv.Atoi(table.Name)

		//if err != nil {
		//	continue
		//}

		//Print(table)
		if year > 2008 {
			println(fmt.Sprintf("\n***** Sheet: %s [new] *****", table.Name))
			ProcessNewFormat(table)
		} else {
			println(fmt.Sprintf("\n***** Sheet: %s [old] *****", table.Name))
			ProcessOldFormat(table)
		}
	//}
}
<commit_msg>Clean up parsing. Get through with only expected errors.<commit_after>package main

import (
	"fmt"
	"log"
	"math"
	"odf/ods"
	"regexp"
	"strconv"
	"strings"
)

const (
	odsPath = "/Users/carl/Downloads/bills.ods"
)

var (
	moneyCleanRegex = regexp.MustCompile(`[$,]`)
)

// Print out the data in a table.
func Print(table ods.Table) {
	for _, row := range table.Strings() {
		if len(row) == 0 || row[0] == "" {
			continue
		}
		sep := ""
		for _, field := range row {
			fmt.Print(sep, strconv.Quote(field))
			sep = "\t"
		}
		fmt.Print("\n")
	}
}

func ProcessNewFormat(table ods.Table) {
	for _, row := range table.Strings() {
		if len(row) < 2 || row[0] == "" || strings.Index(row[0], "Balance") == 0 {
			continue
		}
		if strings.Index(row[0], "Billing Cycle") == 0 {
			log.Printf("*** %s\n", row[0])
			continue
		}
		biller := row[0]
		date := row[1]
		if date == "" {
			continue
		}
		debit := 0.0
		credit := 0.0
		if len(row) >= 3 {
			var err error
			debit, err = parseMoney(row[2])
			printErr(err)
		}
		if len(row) >= 4 {
			var err error
			credit, err = parseMoney(row[3])
			printErr(err)
		}
		log.Printf("%35s; %11s; %10.2f; %5.2f\n", biller, date, debit, credit)
	}
}

func ProcessOldFormat(table ods.Table) {
	for _, row := range table.Strings() {
		if row[0] == "Leftover" {
			continue
		}
		if strings.Index(row[0], "Billing Cycle") == 0 {
			log.Printf("*** %s\n", row[0])
			continue
		}
		biller := row[0]
		date := row[1]
		if date == "" {
			continue
		}
		var amount float64
		var err error
		if len(row) >= 3 {
			amount, err = parseMoney(row[2])
			if printErr(err) {
				continue
			}
		}
		credit := 0.0
		debit := 0.0
		if amount < 0 || biller != "Paycheck" {
			credit = math.Abs(amount)
		} else {
			debit = math.Abs(amount)
		}

		log.Printf("%35s; %11s; %10.2f; %5.2f\n", biller, date, debit, credit)
	}
}

// Parse a string into a float. This removes non-numeric characters.
func parseMoney(data string) (float64, error) {
	var amount float64
	var err error
	if len(data) > 0 {
		amount, err = strconv.ParseFloat(moneyCleanRegex.ReplaceAllString(data, ""), 32)
	}
	return amount, err
}

func printErr(err error) (bool) {
	if err != nil {
		log.Printf("[ERROR] %s", err)
		return true
	}
	return false
}

func main() {
	var doc ods.Doc

	f, err := ods.Open(odsPath)
	if err != nil {
		log.Fatal(err)
		return
	}
	defer f.Close()

	if err := f.ParseContent(&doc); err != nil {
		log.Fatal(err)
		return
	}

	// Dump the first table one line per row, writing
	// tab separated, quoted fields.
	for _, table := range doc.Table {
		if year, err := strconv.Atoi(table.Name); err == nil {
			if year > 2008 {
				log.Printf("***** Sheet: %s [new] *****", table.Name)
					ProcessNewFormat(table)
			} else {
				log.Printf("***** Sheet: %s [old] *****", table.Name)
					ProcessOldFormat(table)
			}
		}
	}
}
<|endoftext|>


<commit_before>// This is the primary file of LibreJS-Gopher

package librejsgopher

import (
	"errors"
	"io/ioutil"
	"os"
	"strings"
)

var LicensesCapitalizedStrings []string // An array of strings where each string is a license name or sub-string that needs to be capitalized

var LicenseMap map[string]string // LicenseMap is a map of license names to magnet URLs

func init() {
	LicensesCapitalizedStrings = []string{"BSD", "CC", "GPL", "ISC", "MPL"}

	LicenseMap = map[string]string{
		"AGPL-3.0":      "magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt",
		"Apache-2.0":    "magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt",
		"Artistic-2.0":  "magnet:?xt=urn:btih:54fd2283f9dbdf29466d2df1a98bf8f65cafe314&dn=artistic-2.0.txt",
		"BSD-3.0":       "magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt",
		"CC0":           "magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt",
		"Expat":         "magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt",
		"FreeBSD":       "magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt",
		"GPL-2.0":       "magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt",
		"GPL-3.0":       "magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt",
		"ISC":           "magnet:?xt=urn:btih:b8999bbaf509c08d127678643c515b9ab0836bae&dn=ISC.txt",
		"LGPL-2.1":      "magnet:?xt=urn:btih:5de60da917303dbfad4f93fb1b985ced5a89eac2&dn=lgpl-2.1.txt",
		"LGPL-3.0":      "magnet:?xt=urn:btih:0ef1b8170b3b615170ff270def6427c317705f85&dn=lgpl-3.0.txt",
		"MPL-2.0":       "magnet:?xt=urn:btih:3877d6d54b3accd4bc32f8a48bf32ebc0901502a&dn=mpl-2.0.txt",
		"Public-Domain": "magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt",
		"X11":           "magnet:?xt=urn:btih:5305d91886084f776adcf57509a648432709a7c7&dn=x11.txt",
		"XFree86":       "magnet:?xt=urn:btih:12f2ec9e8de2a3b0002a33d518d6010cc8ab2ae9&dn=xfree86.txt",
	}
}

// AddLicenseInfo
// This function will add a valid LibreJS short-form header and footer to the file. You can set to write the file automatically (we will always return new file content or an error)
func AddLicenseInfo(license string, file string, writeContentAutomatically bool) (string, error) {
	var newFileContent string
	var addError error

	if strings.HasSuffix(file, ".js") { // If this is a JavaScript file
		fileContentBytes, fileReadError := ioutil.ReadFile(file) // Get the fileContent or if the file does not exist (or we do not have the permission) assign to fileReadError

		if fileReadError == nil { // If there was no read error
			parsedLicense := ParseLicenseName(license)             // Format license to be consistent when appending to newFileContent
			magnetURL, magnetError := GetMagnetLink(parsedLicense) // Attempt to get the magnet URL and if license does not exist return error

			if magnetError == nil { // If the license requested is valid and return a magnet URL
				fileContentString := string(fileContentBytes[:])                                                             // Convert to string
				newFileContent = "@license " + magnetURL + " " + parsedLicense + "\n" + fileContentString + "\n@license-end" // Add @license INFO + content + @license-end

				if writeContentAutomatically { // If we should write the file content automatically
					fileStruct, _ := os.Open(file)   // Open the file and get an os.File struct
					fileStat, _ := fileStruct.Stat() // Get the stats about the file
					fileMode := fileStat.Mode()
					fileStruct.Close() // Close the open file struct

					ioutil.WriteFile(file, []byte(newFileContent), fileMode) // Write the file with the new content and same mode
				}
			} else { // If the magnetURL does not exist
				addError = magnetError // Assign addError as the magnetError
			}
		} else { // If there was a read error
			addError = errors.New(file + " does not exist.")
		}
	} else { // File provided is not a JavaScript file
		addError = errors.New(file + " is not a JavaScript file (detected if ending with .js).")
	}

	return newFileContent, addError
}

// GetFileLicense
// This function will get the license of the file, assuming it uses a valid LibreJS short-form header.
func GetFileLicense(file string) (LibreJSMetaInfo, error) {
	var getError error
	var metaInfo LibreJSMetaInfo

	fileContentBytes, fileReadError := ioutil.ReadFile(file) // Get the fileContent or if the file does not exist (or we do not have the permission) assign to fileReadError

	if fileReadError == nil { // If there was no read error
		fileContent := string(fileContentBytes[:])           // Convert to string
		fileContentLines := strings.Split(fileContent, "\n") // Split each new line into an []string
		fileContentLinesCount := len(fileContentLines)

		if fileContentLinesCount > 1 { // If this file is not a single line or empty
			fileLineParserChannel := make(chan LibreJSMetaInfo) // Make a channel that takes LibreJSMetaInfo
			linesParsed := 0                                    // Define linesParsed as the number of lines parsed by FileLicenseLineParser

			for _, lineContent := range fileContentLines { // For each license
				go FileLicenseLineParser(fileLineParserChannel, lineContent) // Asynchronously call FileLicenseLineParser
			}

		LineParserLoop:
			for libreJsMetaInfo := range fileLineParserChannel { // Constantly listen for channel input
				var endChannelListening bool

				linesParsed++ // Add one two linesParsed

				if libreJsMetaInfo.License != "" { // If the provided LibreJSMetaInfo has a valid License
					metaInfo = libreJsMetaInfo // Assign metaInfo as provided libreJsMetaInfo
					endChannelListening = true
				}

				if (fileContentLinesCount == linesParsed) || (endChannelListening) { // If we have parsed all lines or found the header info
					close(fileLineParserChannel) // Close the channel
					break LineParserLoop         // Break the loop
				}
			}

			if metaInfo.License == "" { // If there is no License defined by the end of the file
				getError = errors.New("LibreJS short-form header does not exist in this file.")
			}
		} else { // If the length of the file is 1 line or none
			getError = errors.New("File is either empty or does not contain the necessary individual lines required by LibreJS short-form blocks.")
		}
	} else { // If the file does not exist
		getError = errors.New(file + " does not exist.")
	}

	return metaInfo, getError
}

// FileLicenseLineParser
// This function handles individual line parsing
func FileLicenseLineParser(returnContentChannel chan LibreJSMetaInfo, lineContent string) {
	metaInfo := LibreJSMetaInfo{}

	lineContent = strings.Replace(lineContent, "//", "", -1) // Replace any // with nothing
	lineContent = strings.Replace(lineContent, "*", "", -1)  // Replace any * (block quotes) with nothing
	lineContent = strings.TrimPrefix(lineContent, " ")       // Trim any prefixed whitespace

	if strings.HasPrefix(lineContent, "@license") { // If the line starts with @license
		licenseHeaderFragments := strings.SplitN(lineContent, " ", 3)  // Split the license header info into three segments, separated by whitespace

        if len(licenseHeaderFragments) == 3 { // If there are three items in the slice, meaning this is a @license line and not @license-end
            metaInfo.License = ParseLicenseName(licenseHeaderFragments[2]) // Define License as the parsed license name of the last item in fragments index
		    metaInfo.Magnet = licenseHeaderFragments[1]                    // Define Magnet as the second item in the fragments index
        }
	}

	returnContentChannel <- metaInfo
}

// GetMagnetLink
// This function will get a magnet link of the associated license exists
// Returns string for magnet link, error if item does not exist
func GetMagnetLink(license string) (string, error) {
	var magnetLinkFetchError error

	license = ParseLicenseName(license) // Parse the license name first
	magnetURL, licenseExists := LicenseMap[license]

	if !licenseExists { // If the license does not exist
		magnetLinkFetchError = errors.New(license + " does not exist.")
	}

	return magnetURL, magnetLinkFetchError
}

// ParseLicenseName
// This function will attempt to parse the provided license into a more logic naming scheme used in LicenseMap
func ParseLicenseName(license string) string {
	license = strings.ToLower(license) // Lowercase the entire string to make selective capitalization easier

	for _, licenseCapitalizedString := range LicensesCapitalizedStrings { // For each capitalized string of a license in LicensesCapitalizedStrings
		license = strings.Replace(license, strings.ToLower(licenseCapitalizedString), licenseCapitalizedString, -1) // Replace any lowercase instance with capitalized instance
	}

	license = strings.Title(license)               // Title the license (example: apache -> Apache)
	license = strings.Replace(license, " ", "-", -1) // Replace whitespacing with hyphens

	return license
}
<commit_msg>Implement fixes to resolve panics on closed channels (pre-emptive closing, we not wait until all line parsing IO is done).<commit_after>// This is the primary file of LibreJS-Gopher

package librejsgopher

import (
	"errors"
	"io/ioutil"
	"os"
	"strings"
)

var LicensesCapitalizedStrings []string // An array of strings where each string is a license name or sub-string that needs to be capitalized

var LicenseMap map[string]string // LicenseMap is a map of license names to magnet URLs

func init() {
	LicensesCapitalizedStrings = []string{"BSD", "CC", "GPL", "ISC", "MPL"}

	LicenseMap = map[string]string{
		"AGPL-3.0":      "magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt",
		"Apache-2.0":    "magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt",
		"Artistic-2.0":  "magnet:?xt=urn:btih:54fd2283f9dbdf29466d2df1a98bf8f65cafe314&dn=artistic-2.0.txt",
		"BSD-3.0":       "magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt",
		"CC0":           "magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt",
		"Expat":         "magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt",
		"FreeBSD":       "magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt",
		"GPL-2.0":       "magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt",
		"GPL-3.0":       "magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt",
		"ISC":           "magnet:?xt=urn:btih:b8999bbaf509c08d127678643c515b9ab0836bae&dn=ISC.txt",
		"LGPL-2.1":      "magnet:?xt=urn:btih:5de60da917303dbfad4f93fb1b985ced5a89eac2&dn=lgpl-2.1.txt",
		"LGPL-3.0":      "magnet:?xt=urn:btih:0ef1b8170b3b615170ff270def6427c317705f85&dn=lgpl-3.0.txt",
		"MPL-2.0":       "magnet:?xt=urn:btih:3877d6d54b3accd4bc32f8a48bf32ebc0901502a&dn=mpl-2.0.txt",
		"Public-Domain": "magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt",
		"X11":           "magnet:?xt=urn:btih:5305d91886084f776adcf57509a648432709a7c7&dn=x11.txt",
		"XFree86":       "magnet:?xt=urn:btih:12f2ec9e8de2a3b0002a33d518d6010cc8ab2ae9&dn=xfree86.txt",
	}
}

// AddLicenseInfo
// This function will add a valid LibreJS short-form header and footer to the file. You can set to write the file automatically (we will always return new file content or an error)
func AddLicenseInfo(license string, file string, writeContentAutomatically bool) (string, error) {
	var newFileContent string
	var addError error

	if strings.HasSuffix(file, ".js") { // If this is a JavaScript file
		fileContentBytes, fileReadError := ioutil.ReadFile(file) // Get the fileContent or if the file does not exist (or we do not have the permission) assign to fileReadError

		if fileReadError == nil { // If there was no read error
			parsedLicense := ParseLicenseName(license)             // Format license to be consistent when appending to newFileContent
			magnetURL, magnetError := GetMagnetLink(parsedLicense) // Attempt to get the magnet URL and if license does not exist return error

			if magnetError == nil { // If the license requested is valid and return a magnet URL
				fileContentString := string(fileContentBytes[:])                                                             // Convert to string
				newFileContent = "@license " + magnetURL + " " + parsedLicense + "\n" + fileContentString + "\n@license-end" // Add @license INFO + content + @license-end

				if writeContentAutomatically { // If we should write the file content automatically
					fileStruct, _ := os.Open(file)   // Open the file and get an os.File struct
					fileStat, _ := fileStruct.Stat() // Get the stats about the file
					fileMode := fileStat.Mode()
					fileStruct.Close() // Close the open file struct

					ioutil.WriteFile(file, []byte(newFileContent), fileMode) // Write the file with the new content and same mode
				}
			} else { // If the magnetURL does not exist
				addError = magnetError // Assign addError as the magnetError
			}
		} else { // If there was a read error
			addError = errors.New(file + " does not exist.")
		}
	} else { // File provided is not a JavaScript file
		addError = errors.New(file + " is not a JavaScript file (detected if ending with .js).")
	}

	return newFileContent, addError
}

// GetFileLicense
// This function will get the license of the file, assuming it uses a valid LibreJS short-form header.
func GetFileLicense(file string) (LibreJSMetaInfo, error) {
	var getError error
	var metaInfo LibreJSMetaInfo

	fileContentBytes, fileReadError := ioutil.ReadFile(file) // Get the fileContent or if the file does not exist (or we do not have the permission) assign to fileReadError

	if fileReadError == nil { // If there was no read error
		fileContent := string(fileContentBytes[:])           // Convert to string
		fileContentLines := strings.Split(fileContent, "\n") // Split each new line into an []string
		fileContentLinesCount := len(fileContentLines)
		linesParsed := 0 // Define linesParsed as the number of lines parsed by FileLicenseLineParser

		if fileContentLinesCount > 1 { // If this file is not a single line or empty
			fileLineParserChannel := make(chan LibreJSMetaInfo, fileContentLinesCount) // Make a channel that takes LibreJSMetaInfo

			for _, lineContent := range fileContentLines { // For each license
				go FileLicenseLineParser(fileLineParserChannel, lineContent) // Asynchronously call FileLicenseLineParser
			}

            LineParserLoop:
    			for libreJsMetaInfo := range fileLineParserChannel { // Constantly listen for channel input
    				if libreJsMetaInfo.License != "" { // If the provided LibreJSMetaInfo has a valid License
    					metaInfo = libreJsMetaInfo // Assign metaInfo as provided libreJsMetaInfo
    				}

    				linesParsed++ // Increment linesParsed

    				if fileContentLinesCount == linesParsed { // If we're parsed all the liens
    					close(fileLineParserChannel) // Close the channel
                        break LineParserLoop // Break LineParserLoop
    				}
    			}

			if metaInfo.License == "" { // If there is no License defined by the end of the file
				getError = errors.New("LibreJS short-form header does not exist in this file.")
			}
		} else { // If the length of the file is 1 line or none
			getError = errors.New("File is either empty or does not contain the necessary individual lines required by LibreJS short-form blocks.")
		}
	} else { // If the file does not exist
		getError = errors.New(file + " does not exist.")
	}

	return metaInfo, getError
}

// FileLicenseLineParser
// This function handles individual line parsing
func FileLicenseLineParser(returnContentChannel chan LibreJSMetaInfo, lineContent string) {
	metaInfo := LibreJSMetaInfo{}

	lineContent = strings.Replace(lineContent, "//", "", -1) // Replace any // with nothing
	lineContent = strings.Replace(lineContent, "*", "", -1)  // Replace any * (block quotes) with nothing
	lineContent = strings.TrimPrefix(lineContent, " ")       // Trim any prefixed whitespace

	if strings.HasPrefix(lineContent, "@license") { // If the line starts with @license
		licenseHeaderFragments := strings.SplitN(lineContent, " ", 3) // Split the license header info into three segments, separated by whitespace

		if len(licenseHeaderFragments) == 3 { // If there are three items in the slice, meaning this is a @license line and not @license-end
			metaInfo.License = ParseLicenseName(licenseHeaderFragments[2]) // Define License as the parsed license name of the last item in fragments index
			metaInfo.Magnet = licenseHeaderFragments[1]                    // Define Magnet as the second item in the fragments index
		}
	}

	returnContentChannel <- metaInfo
}

// GetMagnetLink
// This function will get a magnet link of the associated license exists
// Returns string for magnet link, error if item does not exist
func GetMagnetLink(license string) (string, error) {
	var magnetLinkFetchError error

	license = ParseLicenseName(license) // Parse the license name first
	magnetURL, licenseExists := LicenseMap[license]

	if !licenseExists { // If the license does not exist
		magnetLinkFetchError = errors.New(license + " does not exist.")
	}

	return magnetURL, magnetLinkFetchError
}

// ParseLicenseName
// This function will attempt to parse the provided license into a more logic naming scheme used in LicenseMap
func ParseLicenseName(license string) string {
	license = strings.ToLower(license) // Lowercase the entire string to make selective capitalization easier

	for _, licenseCapitalizedString := range LicensesCapitalizedStrings { // For each capitalized string of a license in LicensesCapitalizedStrings
		license = strings.Replace(license, strings.ToLower(licenseCapitalizedString), licenseCapitalizedString, -1) // Replace any lowercase instance with capitalized instance
	}

	license = strings.Title(license)                 // Title the license (example: apache -> Apache)
	license = strings.Replace(license, " ", "-", -1) // Replace whitespacing with hyphens

	return license
}
<|endoftext|>


<commit_before>package vault

import (
	"bytes"
	"fmt"
	"math/rand"
	"regexp"
	"time"
)

var chars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

func random(n int, policy string) string {
	re := regexp.MustCompile("[^" + policy + "]")
	keep := re.ReplaceAllString(chars, "")
	fmt.Println("Keeping these chars:", keep)

	var buffer bytes.Buffer

	for i := 0; i < n; i++ {
		buffer.WriteString(string(keep[rand.Intn(len(keep))]))
	}

	return buffer.String()
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<commit_msg>Removed extraneous debugging printf<commit_after>package vault

import (
	"bytes"
	"math/rand"
	"regexp"
	"time"
)

var chars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

func random(n int, policy string) string {
	re := regexp.MustCompile("[^" + policy + "]")
	keep := re.ReplaceAllString(chars, "")

	var buffer bytes.Buffer

	for i := 0; i < n; i++ {
		buffer.WriteString(string(keep[rand.Intn(len(keep))]))
	}

	return buffer.String()
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<|endoftext|>