<commit_before>package scans

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/ion-channel/ionic/vulnerabilities"
)

// UntranslatedResults represents a result of a specific type that has not been
// translated for use in reports
type UntranslatedResults struct {
	AboutYML                *AboutYMLResults                `json:"about_yml,omitempty"`
	Community               *CommunityResults               `json:"community,omitempty"`
	Coverage                *CoverageResults                `json:"coverage,omitempty"`
	Dependency              *DependencyResults              `json:"dependency,omitempty"`
	Difference              *DifferenceResults              `json:"difference,omitempty"`
	Ecosystem               *EcosystemResults               `json:"ecosystems,omitempty"`
	ExternalVulnerabilities *ExternalVulnerabilitiesResults `json:"external_vulnerability,omitempty"`
	License                 *LicenseResults                 `json:"license,omitempty"`
	Virus                   *VirusResults                   `json:"clamav,omitempty"`
	VirusDetails            *ClamavDetails                  `json:"clam_av_details,omitempty"`
	Vulnerability           *VulnerabilityResults           `json:"vulnerabilities,omitempty"`
}

// Translate moves information from the particular sub-struct, IE
// AboutYMLResults or LicenseResults into a generic, Data struct
func (u *UntranslatedResults) Translate() *TranslatedResults {
	var tr TranslatedResults
	// There is an argument to be made that the following "if" clauses
	// could be simplified with introspection since they all do
	// basically the same thing. I've (dmiles) chosen to writ it all
	// out in the name of explicit, easily-readable code.
	if u.AboutYML != nil {
		tr.Type = "about_yml"
		tr.Data = *u.AboutYML
	}
	if u.Community != nil {
		tr.Type = "community"
		tr.Data = *u.Community
	}
	if u.Coverage != nil {
		tr.Type = "coverage"
		tr.Data = *u.Coverage
	}
	if u.Dependency != nil {
		tr.Type = "dependency"
		tr.Data = *u.Dependency
	}
	if u.Difference != nil {
		tr.Type = "difference"
		tr.Data = *u.Difference
	}
	if u.Ecosystem != nil {
		tr.Type = "ecosystems"
		tr.Data = *u.Ecosystem
	}
	if u.ExternalVulnerabilities != nil {
		tr.Type = "external_vulnerability"
		tr.Data = *u.ExternalVulnerabilities
	}
	if u.License != nil {
		tr.Type = "license"
		tr.Data = *u.License
	}
	if u.Virus != nil {
		tr.Type = "virus"
		u.Virus.ClamavDetails = *u.VirusDetails
		tr.Data = *u.Virus
	}
	if u.Vulnerability != nil {
		tr.Type = "vulnerability"
		tr.Data = *u.Vulnerability
	}
	return &tr
}

// TranslatedResults represents a result of a specific type that has been
// translated for use in reports
type TranslatedResults struct {
	Type string      `json:"type" xml:"type"`
	Data interface{} `json:"data,omitempty" xml:"data,omitempty"`
}

type translatedResults struct {
	Type    string          `json:"type"`
	RawData json.RawMessage `json:"data"`
}

// UnmarshalJSON is a custom JSON unmarshaller implementation for the standard
// go json package to know how to properly interpret ScanSummaryResults from
// JSON.
func (r *TranslatedResults) UnmarshalJSON(b []byte) error {
	var tr translatedResults
	err := json.Unmarshal(b, &tr)
	if err != nil {
		return err
	}

	r.Type = tr.Type

	switch strings.ToLower(tr.Type) {
	case "about_yml":
		var a AboutYMLResults
		err := json.Unmarshal(tr.RawData, &a)
		if err != nil {
			return fmt.Errorf("failed to unmarshall about yml results: %v", err)
		}

		r.Data = a
	case "community":
		var c CommunityResults
		err := json.Unmarshal(tr.RawData, &c)
		if err != nil {
			// Note: Could be a slice, needs to be fixed
			if strings.Contains(err.Error(), "cannot unmarshal array") {
				var sliceOfCommunityResults []CommunityResults
				err := json.Unmarshal(tr.RawData, &sliceOfCommunityResults)
				if err == nil {
					c = sliceOfCommunityResults[0]
					break
				}
			}
			return fmt.Errorf("failed to unmarshall community results: %v", err)
		}

		r.Data = c
	case "coverage", "external_coverage":
		var c CoverageResults
		err := json.Unmarshal(tr.RawData, &c)
		if err != nil {
			return fmt.Errorf("failed to unmarshall coverage results: %v", err)
		}

		r.Data = c
	case "dependency":
		var d DependencyResults
		err := json.Unmarshal(tr.RawData, &d)
		if err != nil {
			return fmt.Errorf("failed to unmarshall dependency results: %v", err)
		}

		r.Data = d
	case "ecosystems":
		var e EcosystemResults
		err := json.Unmarshal(tr.RawData, &e)
		if err != nil {
			return fmt.Errorf("failed to unmarshall ecosystems results: %v", err)
		}

		r.Data = e
	case "license":
		var l LicenseResults
		err := json.Unmarshal(tr.RawData, &l)
		if err != nil {
			return fmt.Errorf("failed to unmarshall license results: %v", err)
		}

		r.Data = l
	case "virus", "clamav":
		var v VirusResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall virus results: %v", err)
		}

		r.Data = v
	case "vulnerability":
		var v VulnerabilityResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall vulnerability results: %v", err)
		}

		r.Data = v
	case "external_vulnerability":
		var v ExternalVulnerabilitiesResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall external vulnerabilities results: %v", err)
		}

		r.Data = v
	case "difference":
		var v DifferenceResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall difference results: %v", err)
		}

		r.Data = v
	default:
		return fmt.Errorf("unsupported results type found: %v", tr.Type)
	}

	return nil
}

// UnmarshalJSON is a custom JSON unmarshaller implementation for the standard
// go json package to know how to properly interpret ScanSummaryResults from
// JSON.
func (u *UntranslatedResults) UnmarshalJSON(b []byte) error {
	// first look for results in the proper translated format
	// e.g. CommunityResults
	tr := &translatedResults{}
	err := json.Unmarshal(b, tr)
	if err != nil {
		// we have received invalid stringified json
		return fmt.Errorf("unable to unmarshal json")
	}

	// if there is a type and it is `community`
	// parse the data out
	if tr.Type == "community" {
		c := &CommunityResults{}
		err = json.Unmarshal(tr.RawData, c)
		if err != nil {
			return err
		}
		u.Community = c
		return nil
	}

	// it is not translated and not community
	// ur2 is required to keep the parser from
	// recursing here
	type ur2 UntranslatedResults
	err = json.Unmarshal(b, (*ur2)(u))
	if err != nil {
		// we have received invalid stringified json
		return fmt.Errorf("unable to unmarshal json")
	}

	return nil
}

// AboutYMLResults represents the data collected from the AboutYML scan.  It
// includes a message and whether or not the About YML file found was valid or
// not.
type AboutYMLResults struct {
	Message string `json:"message" xml:"message"`
	Valid   bool   `json:"valid" xml:"valid"`
	Content string `json:"content" xml:"content"`
}

// CommunityResults represents the data collected from a community scan.  It
// represents all known data regarding the open community of a software project
type CommunityResults struct {
	Committers int    `json:"committers" xml:"committers"`
	Name       string `json:"name" xml:"name"`
	URL        string `json:"url" xml:"url"`
}

// CoverageResults represents the data collected from a code coverage scan.  It
// includes the value of the code coverage seen for the project.
type CoverageResults struct {
	Value float64 `json:"value" xml:"value"`
}

// Dependency represents data for an individual requirement resolution
type Dependency struct {
	LatestVersion string       `json:"latest_version" xml:"latest_version"`
	Org           string       `json:"org" xml:"org"`
	Name          string       `json:"name" xml:"name"`
	Type          string       `json:"type" xml:"type"`
	Package       string       `json:"package" xml:"package"`
	Version       string       `json:"version" xml:"version"`
	Scope         string       `json:"scope" xml:"scope"`
	Requirement   string       `json:"requirement" xml:"requirement"`
	File          string       `json:"file" xml:"file"`
	Dependencies  []Dependency `json:"dependencies" xml:"dependencies"`
}

// DependencyMeta represents data for a summary of all dependencies resolved
type DependencyMeta struct {
	FirstDegreeCount     int `json:"first_degree_count" xml:"first_degree_count"`
	NoVersionCount       int `json:"no_version_count" xml:"no_version_count"`
	TotalUniqueCount     int `json:"total_unique_count" xml:"total_unique_count"`
	UpdateAvailableCount int `json:"update_available_count" xml:"update_available_count"`
}

// DependencyResults represents the data collected from a dependency scan.  It
// includes a list of the dependencies seen and meta data counts about those
// dependencies seen.
type DependencyResults struct {
	Dependencies []Dependency   `json:"dependencies" xml:"dependencies"`
	Meta         DependencyMeta `json:"meta" xml:"meta"`
}

// DifferenceResults represents the checksum of a project.  It includes a checksum
// and flag indicating if there was a difference detected within that last 5 scans
type DifferenceResults struct {
	Checksum   string `json:"checksum" xml:"checksum"`
	Difference bool   `json:"difference" xml:"difference"`
}

// EcosystemResults represents the data collected from an ecosystems scan.  It
// include the name of the ecosystem and the number of lines seen for the given
// ecosystem.
type EcosystemResults struct {
	Ecosystems map[string]int `json:"ecosystems" xml:"ecosystems"`
}

// MarshalJSON meets the marshaller interface to custom wrangle an ecosystem
// result into the json shape
func (e EcosystemResults) MarshalJSON() ([]byte, error) {
	return json.Marshal(e.Ecosystems)
}

// UnmarshalJSON meets the unmarshaller interface to custom wrangle the
// ecosystem scan into an ecosystem result
func (e *EcosystemResults) UnmarshalJSON(b []byte) error {
	var m map[string]int
	err := json.Unmarshal(b, &m)
	if err != nil {
		return fmt.Errorf("failed to unmarshal ecosystem result: %v", err.Error())
	}

	e.Ecosystems = m
	return nil
}

// ExternalVulnerabilitiesResults represents the data collected from an external
// vulnerability scan.  It includes the number of each vulnerability criticality
// seen within the project.
type ExternalVulnerabilitiesResults struct {
	Critical int `json:"critical" xml:"critical"`
	High     int `json:"high" xml:"high"`
	Medium   int `json:"medium" xml:"medium"`
	Low      int `json:"low" xml:"low"`
}

// LicenseResults represents the data collected from a license scan.  It
// includes the name and type of each license seen within the project.
type LicenseResults struct {
	*License `json:"license" xml:"license"`
}

// License represents a name and slice of types of licenses seen in a given file
type License struct {
	Name string        `json:"name" xml:"name"`
	Type []LicenseType `json:"type" xml:"type"`
}

// LicenseType represents a type of license such as MIT, Apache 2.0, etc
type LicenseType struct {
	Name       string  `json:"name" xml:"name"`
	Confidence float32 `json:"confidence"`
}

// FileNotes contains data related to file discoveries
type FileNotes map[string][]string

// ClamavDetails contains data related to the virus scan engine
type ClamavDetails struct {
	ClamavVersion   string `json:"clamav_version" xml:"clamav_version"`
	ClamavDbVersion string `json:"clamav_db_version" xml:"clamav_db_version"`
}

// VirusResults represents the data collected from a virus scan.  It includes
// information of the viruses seen and the virus scanner used.
type VirusResults struct {
	KnownViruses       int           `json:"known_viruses" xml:"known_viruses"`
	EngineVersion      string        `json:"engine_version" xml:"engine_version"`
	ScannedDirectories int           `json:"scanned_directories" xml:"scanned_directories"`
	ScannedFiles       int           `json:"scanned_files" xml:"scanned_files"`
	InfectedFiles      int           `json:"infected_files" xml:"infected_files"`
	DataScanned        string        `json:"data_scanned" xml:"data_scanned"`
	DataRead           string        `json:"data_read" xml:"data_read"`
	Time               string        `json:"time" xml:"time"`
	FileNotes          FileNotes     `json:"file_notes" xml:"file_notes"`
	ClamavDetails      ClamavDetails `json:"clam_av_details" xml:"clam_av_details"`
}

//VulnerabilityResults represents the data collected from a vulnerability scan.  It includes
// information of the vulnerabilities seen.
type VulnerabilityResults struct {
	Vulnerabilities []VulnerabilityResultsProduct `json:"vulnerabilities" xml:"vulnerabilities"`
	Meta            struct {
		VulnerabilityCount int `json:"vulnerability_count" xml:"vulnerability_count"`
	} `json:"meta" xml:"meta"`
}

// VulnerabilityResultsProduct represents the data about a product collected from
// a vulnerability scan.  Vulnerabilities are linked to products.
type VulnerabilityResultsProduct struct {
	ID              int                             `json:"id" xml:"id"`
	ExternalID      string                          `json:"external_id" xml:"external_id"`
	SourceID        int                             `json:"source_id" xml:"source_id"`
	Title           string                          `json:"title" xml:"title"`
	Name            string                          `json:"name" xml:"name"`
	Org             string                          `json:"org" xml:"org"`
	Version         string                          `json:"version" xml:"version"`
	Up              interface{}                     `json:"up" xml:"up"`
	Edition         interface{}                     `json:"edition" xml:"edition"`
	Aliases         []string                        `json:"aliases" xml:"aliases"`
	CreatedAt       time.Time                       `json:"created_at" xml:"created_at"`
	UpdatedAt       time.Time                       `json:"updated_at" xml:"updated_at"`
	References      interface{}                     `json:"references" xml:"references"`
	Part            interface{}                     `json:"part" xml:"part"`
	Language        interface{}                     `json:"language" xml:"language"`
	Vulnerabilities []vulnerabilities.Vulnerability `json:"vulnerabilities" xml:"vulnerabilities"`
}
<commit_msg>Here comes the dependency<commit_after>package scans

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/ion-channel/ionic/vulnerabilities"
)

// UntranslatedResults represents a result of a specific type that has not been
// translated for use in reports
type UntranslatedResults struct {
	AboutYML                *AboutYMLResults                `json:"about_yml,omitempty"`
	Community               *CommunityResults               `json:"community,omitempty"`
	Coverage                *CoverageResults                `json:"coverage,omitempty"`
	Dependency              *DependencyResults              `json:"dependency,omitempty"`
	Difference              *DifferenceResults              `json:"difference,omitempty"`
	Ecosystem               *EcosystemResults               `json:"ecosystems,omitempty"`
	ExternalVulnerabilities *ExternalVulnerabilitiesResults `json:"external_vulnerability,omitempty"`
	License                 *LicenseResults                 `json:"license,omitempty"`
	Virus                   *VirusResults                   `json:"clamav,omitempty"`
	VirusDetails            *ClamavDetails                  `json:"clam_av_details,omitempty"`
	Vulnerability           *VulnerabilityResults           `json:"vulnerabilities,omitempty"`
}

// Translate moves information from the particular sub-struct, IE
// AboutYMLResults or LicenseResults into a generic, Data struct
func (u *UntranslatedResults) Translate() *TranslatedResults {
	var tr TranslatedResults
	// There is an argument to be made that the following "if" clauses
	// could be simplified with introspection since they all do
	// basically the same thing. I've (dmiles) chosen to writ it all
	// out in the name of explicit, easily-readable code.
	if u.AboutYML != nil {
		tr.Type = "about_yml"
		tr.Data = *u.AboutYML
	}
	if u.Community != nil {
		tr.Type = "community"
		tr.Data = *u.Community
	}
	if u.Coverage != nil {
		tr.Type = "coverage"
		tr.Data = *u.Coverage
	}
	if u.Dependency != nil {
		tr.Type = "dependency"
		tr.Data = *u.Dependency
	}
	if u.Difference != nil {
		tr.Type = "difference"
		tr.Data = *u.Difference
	}
	if u.Ecosystem != nil {
		tr.Type = "ecosystems"
		tr.Data = *u.Ecosystem
	}
	if u.ExternalVulnerabilities != nil {
		tr.Type = "external_vulnerability"
		tr.Data = *u.ExternalVulnerabilities
	}
	if u.License != nil {
		tr.Type = "license"
		tr.Data = *u.License
	}
	if u.Virus != nil {
		tr.Type = "virus"
		u.Virus.ClamavDetails = *u.VirusDetails
		tr.Data = *u.Virus
	}
	if u.Vulnerability != nil {
		tr.Type = "vulnerability"
		tr.Data = *u.Vulnerability
	}
	return &tr
}

// TranslatedResults represents a result of a specific type that has been
// translated for use in reports
type TranslatedResults struct {
	Type string      `json:"type" xml:"type"`
	Data interface{} `json:"data,omitempty" xml:"data,omitempty"`
}

type translatedResults struct {
	Type    string          `json:"type"`
	RawData json.RawMessage `json:"data"`
}

// UnmarshalJSON is a custom JSON unmarshaller implementation for the standard
// go json package to know how to properly interpret ScanSummaryResults from
// JSON.
func (r *TranslatedResults) UnmarshalJSON(b []byte) error {
	var tr translatedResults
	err := json.Unmarshal(b, &tr)
	if err != nil {
		return err
	}

	r.Type = tr.Type

	switch strings.ToLower(tr.Type) {
	case "about_yml":
		var a AboutYMLResults
		err := json.Unmarshal(tr.RawData, &a)
		if err != nil {
			return fmt.Errorf("failed to unmarshall about yml results: %v", err)
		}

		r.Data = a
	case "community":
		var c CommunityResults
		err := json.Unmarshal(tr.RawData, &c)
		if err != nil {
			// Note: Could be a slice, needs to be fixed
			if strings.Contains(err.Error(), "cannot unmarshal array") {
				var sliceOfCommunityResults []CommunityResults
				err := json.Unmarshal(tr.RawData, &sliceOfCommunityResults)
				if err == nil {
					c = sliceOfCommunityResults[0]
					break
				}
			}
			return fmt.Errorf("failed to unmarshall community results: %v", err)
		}

		r.Data = c
	case "coverage", "external_coverage":
		var c CoverageResults
		err := json.Unmarshal(tr.RawData, &c)
		if err != nil {
			return fmt.Errorf("failed to unmarshall coverage results: %v", err)
		}

		r.Data = c
	case "dependency":
		var d DependencyResults
		err := json.Unmarshal(tr.RawData, &d)
		if err != nil {
			return fmt.Errorf("failed to unmarshall dependency results: %v", err)
		}

		r.Data = d
	case "ecosystems":
		var e EcosystemResults
		err := json.Unmarshal(tr.RawData, &e)
		if err != nil {
			return fmt.Errorf("failed to unmarshall ecosystems results: %v", err)
		}

		r.Data = e
	case "license":
		var l LicenseResults
		err := json.Unmarshal(tr.RawData, &l)
		if err != nil {
			return fmt.Errorf("failed to unmarshall license results: %v", err)
		}

		r.Data = l
	case "virus", "clamav":
		var v VirusResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall virus results: %v", err)
		}

		r.Data = v
	case "vulnerability":
		var v VulnerabilityResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall vulnerability results: %v", err)
		}

		r.Data = v
	case "external_vulnerability":
		var v ExternalVulnerabilitiesResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall external vulnerabilities results: %v", err)
		}

		r.Data = v
	case "difference":
		var v DifferenceResults
		err := json.Unmarshal(tr.RawData, &v)
		if err != nil {
			return fmt.Errorf("failed to unmarshall difference results: %v", err)
		}

		r.Data = v
	default:
		return fmt.Errorf("unsupported results type found: %v", tr.Type)
	}

	return nil
}

// UnmarshalJSON is a custom JSON unmarshaller implementation for the standard
// go json package to know how to properly interpret ScanSummaryResults from
// JSON.
func (u *UntranslatedResults) UnmarshalJSON(b []byte) error {
	// first look for results in the proper translated format
	// e.g. CommunityResults
	tr := &translatedResults{}
	err := json.Unmarshal(b, tr)
	if err != nil {
		// we have received invalid stringified json
		return fmt.Errorf("unable to unmarshal json")
	}

	// if there is a type and it is `community`
	// parse the data out
	if tr.Type == "community" {
		c := &CommunityResults{}
		err = json.Unmarshal(tr.RawData, c)
		if err != nil {
			return err
		}
		u.Community = c
		return nil
	}

	// it is not translated and not community
	// ur2 is required to keep the parser from
	// recursing here
	type ur2 UntranslatedResults
	err = json.Unmarshal(b, (*ur2)(u))
	if err != nil {
		// we have received invalid stringified json
		return fmt.Errorf("unable to unmarshal json")
	}

	return nil
}

// AboutYMLResults represents the data collected from the AboutYML scan.  It
// includes a message and whether or not the About YML file found was valid or
// not.
type AboutYMLResults struct {
	Message string `json:"message" xml:"message"`
	Valid   bool   `json:"valid" xml:"valid"`
	Content string `json:"content" xml:"content"`
}

// CommunityResults represents the data collected from a community scan.  It
// represents all known data regarding the open community of a software project
type CommunityResults struct {
	Committers int    `json:"committers" xml:"committers"`
	Name       string `json:"name" xml:"name"`
	URL        string `json:"url" xml:"url"`
}

// CoverageResults represents the data collected from a code coverage scan.  It
// includes the value of the code coverage seen for the project.
type CoverageResults struct {
	Value float64 `json:"value" xml:"value"`
}

// Dependency represents data for an individual requirement resolution
type Dependency struct {
	LatestVersion string       `json:"latest_version" xml:"latest_version"`
	Org           string       `json:"org" xml:"org"`
	Name          string       `json:"name" xml:"name"`
	Type          string       `json:"type" xml:"type"`
	Package       string       `json:"package" xml:"package"`
	Version       string       `json:"version" xml:"version"`
	Scope         string       `json:"scope" xml:"scope"`
	Requirement   string       `json:"requirement" xml:"requirement"`
	File          string       `json:"file" xml:"file"`
	Dependencies  []Dependency `json:"dependencies" xml:"dependencies"`
}

// DependencyMeta represents data for a summary of all dependencies resolved
type DependencyMeta struct {
	FirstDegreeCount     int `json:"first_degree_count" xml:"first_degree_count"`
	NoVersionCount       int `json:"no_version_count" xml:"no_version_count"`
	TotalUniqueCount     int `json:"total_unique_count" xml:"total_unique_count"`
	UpdateAvailableCount int `json:"update_available_count" xml:"update_available_count"`
}

// DependencyResults represents the data collected from a dependency scan.  It
// includes a list of the dependencies seen and meta data counts about those
// dependencies seen.
type DependencyResults struct {
	Dependencies []Dependency   `json:"dependencies" xml:"dependencies"`
	Meta         DependencyMeta `json:"meta" xml:"meta"`
}

// DifferenceResults represents the checksum of a project.  It includes a checksum
// and flag indicating if there was a difference detected within that last 5 scans
type DifferenceResults struct {
	Checksum   string `json:"checksum" xml:"checksum"`
	Difference bool   `json:"difference" xml:"difference"`
}

// EcosystemResults represents the data collected from an ecosystems scan.  It
// include the name of the ecosystem and the number of lines seen for the given
// ecosystem.
type EcosystemResults struct {
	Ecosystems map[string]int `json:"ecosystems" xml:"ecosystems"`
}

// MarshalJSON meets the marshaller interface to custom wrangle an ecosystem
// result into the json shape
func (e EcosystemResults) MarshalJSON() ([]byte, error) {
	return json.Marshal(e.Ecosystems)
}

// UnmarshalJSON meets the unmarshaller interface to custom wrangle the
// ecosystem scan into an ecosystem result
func (e *EcosystemResults) UnmarshalJSON(b []byte) error {
	var m map[string]int
	err := json.Unmarshal(b, &m)
	if err != nil {
		return fmt.Errorf("failed to unmarshal ecosystem result: %v", err.Error())
	}

	e.Ecosystems = m
	return nil
}

// ExternalVulnerabilitiesResults represents the data collected from an external
// vulnerability scan.  It includes the number of each vulnerability criticality
// seen within the project.
type ExternalVulnerabilitiesResults struct {
	Critical int `json:"critical" xml:"critical"`
	High     int `json:"high" xml:"high"`
	Medium   int `json:"medium" xml:"medium"`
	Low      int `json:"low" xml:"low"`
}

// LicenseResults represents the data collected from a license scan.  It
// includes the name and type of each license seen within the project.
type LicenseResults struct {
	*License `json:"license" xml:"license"`
}

// License represents a name and slice of types of licenses seen in a given file
type License struct {
	Name string        `json:"name" xml:"name"`
	Type []LicenseType `json:"type" xml:"type"`
}

// LicenseType represents a type of license such as MIT, Apache 2.0, etc
type LicenseType struct {
	Name       string  `json:"name" xml:"name"`
	Confidence float32 `json:"confidence"`
}

// FileNotes contains data related to file discoveries
type FileNotes map[string][]string

// ClamavDetails contains data related to the virus scan engine
type ClamavDetails struct {
	ClamavVersion   string `json:"clamav_version" xml:"clamav_version"`
	ClamavDbVersion string `json:"clamav_db_version" xml:"clamav_db_version"`
}

// VirusResults represents the data collected from a virus scan.  It includes
// information of the viruses seen and the virus scanner used.
type VirusResults struct {
	KnownViruses       int           `json:"known_viruses" xml:"known_viruses"`
	EngineVersion      string        `json:"engine_version" xml:"engine_version"`
	ScannedDirectories int           `json:"scanned_directories" xml:"scanned_directories"`
	ScannedFiles       int           `json:"scanned_files" xml:"scanned_files"`
	InfectedFiles      int           `json:"infected_files" xml:"infected_files"`
	DataScanned        string        `json:"data_scanned" xml:"data_scanned"`
	DataRead           string        `json:"data_read" xml:"data_read"`
	Time               string        `json:"time" xml:"time"`
	FileNotes          FileNotes     `json:"file_notes" xml:"file_notes"`
	ClamavDetails      ClamavDetails `json:"clam_av_details" xml:"clam_av_details"`
}

//VulnerabilityResults represents the data collected from a vulnerability scan.  It includes
// information of the vulnerabilities seen.
type VulnerabilityResults struct {
	Vulnerabilities []VulnerabilityResultsProduct `json:"vulnerabilities" xml:"vulnerabilities"`
	Meta            struct {
		VulnerabilityCount int `json:"vulnerability_count" xml:"vulnerability_count"`
	} `json:"meta" xml:"meta"`
}

// VulnerabilityResultsProduct represents the data about a product collected from
// a vulnerability scan.  Vulnerabilities are linked to products.
type VulnerabilityResultsProduct struct {
	ID              int                             `json:"id" xml:"id"`
	ExternalID      string                          `json:"external_id" xml:"external_id"`
	SourceID        int                             `json:"source_id" xml:"source_id"`
	Title           string                          `json:"title" xml:"title"`
	Name            string                          `json:"name" xml:"name"`
	Org             string                          `json:"org" xml:"org"`
	Version         string                          `json:"version" xml:"version"`
	Up              interface{}                     `json:"up" xml:"up"`
	Edition         interface{}                     `json:"edition" xml:"edition"`
	Aliases         []string                        `json:"aliases" xml:"aliases"`
	CreatedAt       time.Time                       `json:"created_at" xml:"created_at"`
	UpdatedAt       time.Time                       `json:"updated_at" xml:"updated_at"`
	References      interface{}                     `json:"references" xml:"references"`
	Part            interface{}                     `json:"part" xml:"part"`
	Language        interface{}                     `json:"language" xml:"language"`
	Vulnerabilities []vulnerabilities.Vulnerability `json:"vulnerabilities" xml:"vulnerabilities"`
	Dependency      Dependency                      `json:"dependency" xml:"dependency"`
}
<|endoftext|>


<commit_before>package scard

import (
	"fmt"
	"syscall"
	"unsafe"
)

var (
	modwinscard          = syscall.NewLazyDLL("winscard.dll")
	procEstablishContext = modwinscard.NewProc("SCardEstablishContext")
	procRelease          = modwinscard.NewProc("SCardReleaseContext")
	procIsValid	     = modwinscard.NewProc("SCardIsValidContext")
	procCancel	     = modwinscard.NewProc("SCardCancel")
	procListReaders      = modwinscard.NewProc("SCardListReadersW")
	procGetStatusChange  = modwinscard.NewProc("SCardGetStatusChangeW")
	procConnect          = modwinscard.NewProc("SCardConnectW")
	procDisconnect       = modwinscard.NewProc("SCardDisconnect")
	procReconnect	     = modwinscard.NewProc("SCardReconnect")
	procBeginTransaction = modwinscard.NewProc("SCardBeginTransaction")
	procEndTransaction   = modwinscard.NewProc("SCardEndTransaction")
	procStatus           = modwinscard.NewProc("SCardStatusW")
	procGetAttrib        = modwinscard.NewProc("SCardGetAttrib")

	dataT0Pci = modwinscard.NewProc("g_rgSCardT0Pci")
	dataT1Pci = modwinscard.NewProc("g_rgSCardT1Pci")
)

var scardIoReqT0 uintptr
var scardIoReqT1 uintptr

func init() {
	if err := dataT0Pci.Find(); err != nil {
		panic(err)
	}
	scardIoReqT0 = dataT0Pci.Addr()
	if err := dataT1Pci.Find(); err != nil {
		panic(err)
	}
	scardIoReqT1 = dataT1Pci.Addr()
}

type Context struct {
	ctx uintptr
}

type Card struct {
	handle         uintptr
	activeProtocol uintptr
}

type scardError uintptr

func (e scardError) Error() string {
	err := syscall.Errno(e)
	return fmt.Sprintf("scard: error code %x: %s", uintptr(e), err.Error())
}

// wraps SCardEstablishContext
func EstablishContext() (*Context, error) {
	var ctx Context

	r, _, _ := procEstablishContext.Call(2, uintptr(0), uintptr(0), uintptr(unsafe.Pointer(&ctx.ctx)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return &ctx, nil
}

// wraps SCardIsValidContext
func (ctx *Context) IsValid() (bool, error) {
	r, _, _ := procIsValid.Call(ctx.ctx)
	if scardError(r) != S_SUCCESS {
		return false, scardError(r)
	}
	return true, nil
}

// wraps SCardCancel
func (ctx *Context) Cancel() error {
	r, _, _ := procCancel.Call(ctx.ctx)
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardReleaseContext
func (ctx *Context) Release() error {
	r, _, _ := procRelease.Call(uintptr(ctx.ctx))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardListReaders
func (ctx *Context) ListReaders() ([]string, error) {
	var needed uintptr

	r, _, _ := procListReaders.Call(
		ctx.ctx,
		0,
		0,
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	data := make([]uint16, needed)
	needed <<= 1
	r, _, _ = procListReaders.Call(
		ctx.ctx,
		0,
		uintptr(unsafe.Pointer(&data[0])),
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	var readers []string
	for len(data) > 0 {
		pos := 0
		for ; pos < len(data); pos++ {
			if data[pos] == 0 {
				break
			}
		}
		reader := syscall.UTF16ToString(data[:pos])
		readers = append(readers, reader)
		data = data[pos+1:]
	}

	return readers, nil
}

// wraps SCardListReaderGroups
func (ctx *Context) ListReaderGroups() ([]string, error) {
	panic("scard: not implemented")
}

type _SCARD_READERSTATE struct {
	szReader       uintptr
	pvUserData     uintptr
	dwCurrentState uint32
	dwEventState   uint32
	cbAtr          uint32
	rgbAtr         [36]byte
}

// wraps SCardGetStatusChange
func (ctx *Context) GetStatusChange(readerStates []ReaderState, timeout Timeout) error {
	crs := make([]_SCARD_READERSTATE, len(readerStates))

	for i := range readerStates {
		rptr, err := syscall.UTF16PtrFromString(readerStates[i].Reader)
		if err != nil {
			return err
		}
		crs[i].szReader = uintptr(unsafe.Pointer(rptr))
		crs[i].dwCurrentState = uint32(readerStates[i].CurrentState)
	}

	r, _, _ := procGetStatusChange.Call(
		ctx.ctx,
		uintptr(timeout),
		uintptr(unsafe.Pointer(&crs[0])),
		uintptr(len(crs)))

	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}

	for i := range readerStates {
		readerStates[i].EventState = StateFlag(crs[i].dwEventState)
	}

	return nil
}

// wraps SCardConnect
func (ctx *Context) Connect(reader string, mode ShareMode, proto Protocol) (*Card, error) {
	var card Card

	creader, err := syscall.UTF16PtrFromString(reader)
	if err != nil {
		return nil, err
	}

	r, _, _ := procConnect.Call(
		ctx.ctx,
		uintptr(unsafe.Pointer(creader)),
		uintptr(mode),
		uintptr(proto),
		uintptr(unsafe.Pointer(&card.handle)),
		uintptr(unsafe.Pointer(&card.activeProtocol)))

	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return &card, nil
}

// wraps SCardDisconnect
func (card *Card) Disconnect(d Disposition) error {
	r, _, _ := procDisconnect.Call(card.handle, uintptr(d))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardReconnect
func (card *Card) Reconnect(mode ShareMode, protocol Protocol, init Disposition) error {
	r, _, _ := procReconnect.Call(card.handle, uintptr(protocol), uintptr(init));
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardBeginTransaction
func (card *Card) BeginTransaction() error {
	r, _, _ := procBeginTransaction.Call(card.handle)
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardEndTransaction
func (card *Card) EndTransaction(d Disposition) error {
	r, _, _ := procEndTransaction.Call(card.handle, uintptr(d))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardStatus
func (card *Card) Status() (*CardStatus, error) {
	var reader [MAX_READERNAME + 1]uint16
	var readerLen = uint32(len(reader))
	var state, proto uint32
	var atr [MAX_ATR_SIZE]byte
	var atrLen = uint32(len(atr))

	r, _, _ := procStatus.Call(
		card.handle,
		uintptr(unsafe.Pointer(&reader[0])),
		uintptr(unsafe.Pointer(&readerLen)),
		uintptr(unsafe.Pointer(&state)),
		uintptr(unsafe.Pointer(&proto)),
		uintptr(unsafe.Pointer(&atr[0])),
		uintptr(unsafe.Pointer(&atrLen)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	status := &CardStatus{
		Reader:         syscall.UTF16ToString(reader[0:readerLen]),
		State:          State(state),
		ActiveProtocol: Protocol(proto),
		ATR:            atr[0:atrLen],
	}

	return status, nil
}

// wraps SCardTransmit
func (card *Card) Transmit(cmd []byte) ([]byte, error) {
	panic("scard: not implemented") // TODO
}

// wraps SCardControl
func (card *Card) Control(ctrl uint32, cmd []byte) ([]byte, error) {
	panic("scard: not implemented") // TODO
}

// wraps SCardGetAttrib
func (card *Card) GetAttrib(id uint32) ([]byte, error) {
	var needed uintptr

	r, _, _ := procGetAttrib.Call(
		card.handle,
		uintptr(id),
		0,
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	var attrib = make([]byte, needed)

	r, _, _ = procGetAttrib.Call(
		card.handle,
		uintptr(id),
		uintptr(unsafe.Pointer(&attrib[0])),
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return attrib[0:needed], nil
}

// wraps SCardSetAttrib
func (card *Card) SetAttrib(id uint32, data []byte) error {
	panic("scard: not implemented") // TODO
}
<commit_msg>win: add SCardTransmit<commit_after>package scard

import (
	"fmt"
	"syscall"
	"unsafe"
)

var (
	modwinscard          = syscall.NewLazyDLL("winscard.dll")
	procEstablishContext = modwinscard.NewProc("SCardEstablishContext")
	procRelease          = modwinscard.NewProc("SCardReleaseContext")
	procIsValid	     = modwinscard.NewProc("SCardIsValidContext")
	procCancel	     = modwinscard.NewProc("SCardCancel")
	procListReaders      = modwinscard.NewProc("SCardListReadersW")
	procGetStatusChange  = modwinscard.NewProc("SCardGetStatusChangeW")
	procConnect          = modwinscard.NewProc("SCardConnectW")
	procDisconnect       = modwinscard.NewProc("SCardDisconnect")
	procReconnect	     = modwinscard.NewProc("SCardReconnect")
	procBeginTransaction = modwinscard.NewProc("SCardBeginTransaction")
	procEndTransaction   = modwinscard.NewProc("SCardEndTransaction")
	procStatus           = modwinscard.NewProc("SCardStatusW")
	procTransmit         = modwinscard.NewProc("SCardTransmit")
	procGetAttrib        = modwinscard.NewProc("SCardGetAttrib")

	dataT0Pci = modwinscard.NewProc("g_rgSCardT0Pci")
	dataT1Pci = modwinscard.NewProc("g_rgSCardT1Pci")
)

var scardIoReqT0 uintptr
var scardIoReqT1 uintptr

func init() {
	if err := dataT0Pci.Find(); err != nil {
		panic(err)
	}
	scardIoReqT0 = dataT0Pci.Addr()
	if err := dataT1Pci.Find(); err != nil {
		panic(err)
	}
	scardIoReqT1 = dataT1Pci.Addr()
}

type Context struct {
	ctx uintptr
}

type Card struct {
	handle         uintptr
	activeProtocol uintptr
}

type scardError uintptr

func (e scardError) Error() string {
	err := syscall.Errno(e)
	return fmt.Sprintf("scard: error code %x: %s", uintptr(e), err.Error())
}

// wraps SCardEstablishContext
func EstablishContext() (*Context, error) {
	var ctx Context

	r, _, _ := procEstablishContext.Call(2, uintptr(0), uintptr(0), uintptr(unsafe.Pointer(&ctx.ctx)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return &ctx, nil
}

// wraps SCardIsValidContext
func (ctx *Context) IsValid() (bool, error) {
	r, _, _ := procIsValid.Call(ctx.ctx)
	if scardError(r) != S_SUCCESS {
		return false, scardError(r)
	}
	return true, nil
}

// wraps SCardCancel
func (ctx *Context) Cancel() error {
	r, _, _ := procCancel.Call(ctx.ctx)
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardReleaseContext
func (ctx *Context) Release() error {
	r, _, _ := procRelease.Call(uintptr(ctx.ctx))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardListReaders
func (ctx *Context) ListReaders() ([]string, error) {
	var needed uintptr

	r, _, _ := procListReaders.Call(
		ctx.ctx,
		0,
		0,
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	data := make([]uint16, needed)
	needed <<= 1
	r, _, _ = procListReaders.Call(
		ctx.ctx,
		0,
		uintptr(unsafe.Pointer(&data[0])),
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	var readers []string
	for len(data) > 0 {
		pos := 0
		for ; pos < len(data); pos++ {
			if data[pos] == 0 {
				break
			}
		}
		reader := syscall.UTF16ToString(data[:pos])
		readers = append(readers, reader)
		data = data[pos+1:]
	}

	return readers, nil
}

// wraps SCardListReaderGroups
func (ctx *Context) ListReaderGroups() ([]string, error) {
	panic("scard: not implemented")
}

type _SCARD_READERSTATE struct {
	szReader       uintptr
	pvUserData     uintptr
	dwCurrentState uint32
	dwEventState   uint32
	cbAtr          uint32
	rgbAtr         [36]byte
}

// wraps SCardGetStatusChange
func (ctx *Context) GetStatusChange(readerStates []ReaderState, timeout Timeout) error {
	crs := make([]_SCARD_READERSTATE, len(readerStates))

	for i := range readerStates {
		rptr, err := syscall.UTF16PtrFromString(readerStates[i].Reader)
		if err != nil {
			return err
		}
		crs[i].szReader = uintptr(unsafe.Pointer(rptr))
		crs[i].dwCurrentState = uint32(readerStates[i].CurrentState)
	}

	r, _, _ := procGetStatusChange.Call(
		ctx.ctx,
		uintptr(timeout),
		uintptr(unsafe.Pointer(&crs[0])),
		uintptr(len(crs)))

	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}

	for i := range readerStates {
		readerStates[i].EventState = StateFlag(crs[i].dwEventState)
	}

	return nil
}

// wraps SCardConnect
func (ctx *Context) Connect(reader string, mode ShareMode, proto Protocol) (*Card, error) {
	var card Card

	creader, err := syscall.UTF16PtrFromString(reader)
	if err != nil {
		return nil, err
	}

	r, _, _ := procConnect.Call(
		ctx.ctx,
		uintptr(unsafe.Pointer(creader)),
		uintptr(mode),
		uintptr(proto),
		uintptr(unsafe.Pointer(&card.handle)),
		uintptr(unsafe.Pointer(&card.activeProtocol)))

	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return &card, nil
}

// wraps SCardDisconnect
func (card *Card) Disconnect(d Disposition) error {
	r, _, _ := procDisconnect.Call(card.handle, uintptr(d))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardReconnect
func (card *Card) Reconnect(mode ShareMode, protocol Protocol, init Disposition) error {
	r, _, _ := procReconnect.Call(card.handle, uintptr(protocol), uintptr(init));
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardBeginTransaction
func (card *Card) BeginTransaction() error {
	r, _, _ := procBeginTransaction.Call(card.handle)
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardEndTransaction
func (card *Card) EndTransaction(d Disposition) error {
	r, _, _ := procEndTransaction.Call(card.handle, uintptr(d))
	if scardError(r) != S_SUCCESS {
		return scardError(r)
	}
	return nil
}

// wraps SCardStatus
func (card *Card) Status() (*CardStatus, error) {
	var reader [MAX_READERNAME + 1]uint16
	var readerLen = uint32(len(reader))
	var state, proto uint32
	var atr [MAX_ATR_SIZE]byte
	var atrLen = uint32(len(atr))

	r, _, _ := procStatus.Call(
		card.handle,
		uintptr(unsafe.Pointer(&reader[0])),
		uintptr(unsafe.Pointer(&readerLen)),
		uintptr(unsafe.Pointer(&state)),
		uintptr(unsafe.Pointer(&proto)),
		uintptr(unsafe.Pointer(&atr[0])),
		uintptr(unsafe.Pointer(&atrLen)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	status := &CardStatus{
		Reader:         syscall.UTF16ToString(reader[0:readerLen]),
		State:          State(state),
		ActiveProtocol: Protocol(proto),
		ATR:            atr[0:atrLen],
	}

	return status, nil
}

// wraps SCardTransmit
func (card *Card) Transmit(cmd []byte) ([]byte, error) {
	var sendpci uintptr

	switch Protocol(card.activeProtocol) {
	case PROTOCOL_T0:
		sendpci = scardIoReqT0
	case PROTOCOL_T1:
		sendpci = scardIoReqT1
	default:
		panic("unknown protocol")
	}

	var recv [MAX_BUFFER_SIZE_EXTENDED]byte
	var recvlen = uint32(len(recv))

	r, _, _ := procTransmit.Call(card.handle,
		sendpci,
		uintptr(unsafe.Pointer(&cmd[0])),
		uintptr(len(cmd)),
		0,
		uintptr(unsafe.Pointer(&recv[0])),
		uintptr(unsafe.Pointer(&recvlen)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	rsp := make([]byte, recvlen)
	copy(rsp, recv[0:recvlen])

	return rsp, nil
}

// wraps SCardControl
func (card *Card) Control(ctrl uint32, cmd []byte) ([]byte, error) {
	panic("scard: not implemented") // TODO
}

// wraps SCardGetAttrib
func (card *Card) GetAttrib(id uint32) ([]byte, error) {
	var needed uintptr

	r, _, _ := procGetAttrib.Call(
		card.handle,
		uintptr(id),
		0,
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	var attrib = make([]byte, needed)

	r, _, _ = procGetAttrib.Call(
		card.handle,
		uintptr(id),
		uintptr(unsafe.Pointer(&attrib[0])),
		uintptr(unsafe.Pointer(&needed)))
	if scardError(r) != S_SUCCESS {
		return nil, scardError(r)
	}

	return attrib[0:needed], nil
}

// wraps SCardSetAttrib
func (card *Card) SetAttrib(id uint32, data []byte) error {
	panic("scard: not implemented") // TODO
}
<|endoftext|>


<commit_before>package scraper

import (
	"errors"
	"net/url"
	"time"
)

// Timer represents a custom timer, holding start/end nanoseconds
type Timer struct {
	startTime int64
	endTime   int64
	Result    *TimerResult
}

// TimerResult is a result of an ended timer, providing easy millisecond
// and second calculations to the process time
type TimerResult struct {
	Milli   int64
	Seconds int64
}

// Start starts a timer and returns a Timer struct
func (t *Timer) Start() {
	t.startTime = time.Now().UnixNano()
}

// End completes a timer and calculates the differences
func (t *Timer) End() {
	t.endTime = time.Now().UnixNano()

	t.Result = &TimerResult{}

	t.Result.Milli = (t.endTime - t.startTime) / 1000000
	t.Result.Seconds = t.Result.Milli / 1000

	return
}

// NewTimer returns a new Timer struct
func NewTimer() *Timer {
	timer := &Timer{}
	timer.Start()

	return timer
}

func getHost(uri string) (string, error) {
	host, err := url.Parse(uri)

	if err != nil {
		return "", errors.New("Invalid url")
	}

	return host.Host, nil
}
<commit_msg>add stripDups as a way to filter duplicate domains<commit_after>package scraper

import (
	"errors"
	"net/url"
	"time"
)

// Timer represents a custom timer, holding start/end nanoseconds
type Timer struct {
	startTime int64
	endTime   int64
	Result    *TimerResult
}

// TimerResult is a result of an ended timer, providing easy millisecond
// and second calculations to the process time
type TimerResult struct {
	Milli   int64
	Seconds int64
}

// Start starts a timer and returns a Timer struct
func (t *Timer) Start() {
	t.startTime = time.Now().UnixNano()
}

// End completes a timer and calculates the differences
func (t *Timer) End() {
	t.endTime = time.Now().UnixNano()

	t.Result = &TimerResult{}

	t.Result.Milli = (t.endTime - t.startTime) / 1000000
	t.Result.Seconds = t.Result.Milli / 1000

	return
}

// NewTimer returns a new Timer struct
func NewTimer() *Timer {
	timer := &Timer{}
	timer.Start()

	return timer
}

func getHost(uri string) (string, error) {
	host, err := url.Parse(uri)

	if err != nil {
		return "", errors.New("Invalid url")
	}

	return host.Host, nil
}

// stripDups strips all domains that have the same resulting URL/IP
func stripDups(domains *[]*Domain) {
	var tmp []*Domain

	for _, dom := range *domains {
		isIn := false
		for _, other := range tmp {
			if dom.URL.String() == other.URL.String() && dom.IP == other.IP {
				isIn = true
				break
			}
		}
		if !isIn {
			tmp = append(tmp, dom)
		}
	}

	*domains = tmp

	return
}
<|endoftext|>


<commit_before>package sdl

const (
	/* SDL.h */
	INIT_TIMER			= 0x00000001
	INIT_AUDIO			= 0x00000010
	INIT_VIDEO			= 0x00000020
	INIT_JOYSTICK			= 0x00000200
	INIT_HAPTIC			= 0x00001000
	INIT_GAMECONTROLLER		= 0x00002000      /**< turn on game controller also implicitly does JOYSTICK */
	INIT_NOPARACHUTE		= 0x00100000      /**< Don't catch fatal signals */
	INIT_EVERYTHING			= INIT_TIMER | INIT_AUDIO | INIT_VIDEO | INIT_JOYSTICK |
					  INIT_HAPTIC | INIT_GAMECONTROLLER

	WINDOWPOS_UNDEFINED_MASK	= 0x1FFF0000
	WINDOWPOS_UNDEFINED		= WINDOWPOS_UNDEFINED_MASK | 0

	/* SDL_blendmode.h */
	BLENDMODE_NONE			= 0x00000000     /**< No blending */
	BLENDMODE_BLEND			= 0x00000001    /**< dst = (src * A) + (dst * (1-A)) */
	BLENDMODE_ADD			= 0x00000002      /**< dst = (src * A) + dst */
	BLENDMODE_MOD			= 0x00000004       /**< dst = src * dst */

	/* SDL_error.h */
	ENOMEM				= 0x00000000
	EFREAD				= 0x00000001
	EFWRITE				= 0x00000002
	EFSEEK				= 0x00000003
	UNSUPPORTED			= 0x00000004
	LASTERROR			= 0x00000005

	/* SDL_events.h */
	FIRSTEVENT			= 0
	QUIT			= 0x100
	APP_TERMINATING		= 0x101
	APP_LOWMEMORY		= 0x102
	APP_WILLENTERBACKGROUND	= 0x103
	APP_DIDENTERBACKGROUND	= 0x104
	APP_WILLENTERFOREGROUND	= 0x105
	APP_DIDENTERFOREGROUND	= 0x106
	/* Window events */
	WINDOWEVENT			= 0x200
	SYSWMEVENT			= 0x201
	/* Keyboard events */
	KEYDOWN			= 0x300
	KEYUP			= 0x301
	TEXTEDITING			= 0x302
	TEXTINPUT			= 0x303
	/* Mouse events */
	MOUSEMOTION			= 0x400
	MOUSEBUTTONDOWN		= 0x401
	MOUSEBUTTONUP		= 0x402
	MOUSEWHEEL			= 0x403
	/* Joystick events */
	JOYAXISMOTION		= 0x600
	JOYBALLMOTION		= 0x601
	JOYHATMOTION		= 0x602
	JOYBUTTONDOWN		= 0x603
	JOYBUTTONUP			= 0x604
	JOYDEVICEADDED		= 0x605
	JOYDEVICEREMOVED		= 0x606
	/* Game controller events */
	CONTROLLERAXISMOTION	= 0x650
	CONTROLLERBUTTONDOWN	= 0x651
	CONTROLLERBUTTONUP		= 0x652
	CONTROLLERDEVICEADDED	= 0x653
	CONTROLLERDEVICEREMOVED	= 0x654
	CONTROLLERDEVICEREMAPPED	= 0x655
	/* Touch events */
	FINGERDOWN			= 0x700
	FINGERUP			= 0x701
	FINGERMOTION		= 0x702
	/* Gesture events */
	DOLLARGESTURE		= 0x800
	DOLLARRECORD		= 0x801
	MULTIGESTURE		= 0x802
	/* Clipboard events */
	CLIPBOARDUPDATE		= 0x900
	/* Drag and drop events */
	DROPFILE			= 0x1000

	USEREVENT			= 0x8000
	LASTEVENT			= 0xFFFF

	ADDEVENT			= 0x0
	PEEKEVENT			= 0x1
	GETEVENT			= 0x2

	/* SDL_render.h */
	RENDERER_SOFTWARE		= 0x00000001
	RENDERER_ACCELERATED		= 0x00000002
	RENDERER_PRESENTVSYNC		= 0x00000004
	RENDERER_TARGETTEXTURE		= 0x00000008

	TEXTUREACCESS_STATIC		= 0x00000001
	TEXTUREACCESS_STREAMING		= 0x00000002
	TEXTUREACCESS_TARGET		= 0x00000003

	TEXTUREMODULATE_NONE		= 0x00000000     /**< No modulation */
	TEXTUREMODULATE_COLOR		= 0x00000001    /**< srcC = srcC * color */
	TEXTUREMODULATE_ALPHA		= 0x00000002     /**< srcA = srcA * alpha */

	SDL_FLIP_NONE			= 0x00000000     /**< Do not flip */
	SDL_FLIP_HORIZONTAL		= 0x00000001    /**< flip horizontally */
	SDL_FLIP_VERTICAL		= 0x00000002     /**< flip vertically */

	/* SDL_video.h */
	WINDOW_FULLSCREEN		= 0x00000001         /**< fullscreen window */
	WINDOW_OPENGL			= 0x00000002             /**< window usable with OpenGL context */
	WINDOW_SHOWN			= 0x00000004              /**< window is visible */
	WINDOW_HIDDEN			= 0x00000008             /**< window is not visible */
	WINDOW_BORDERLESS		= 0x00000010         /**< no window decoration */
	WINDOW_RESIZABLE		= 0x00000020          /**< window can be resized */
	WINDOW_MINIMIZED		= 0x00000040          /**< window is minimized */
	WINDOW_MAXIMIZED		= 0x00000080          /**< window is maximized */
	WINDOW_INPUT_GRABBED		= 0x00000100      /**< window has grabbed input focus */
	WINDOW_INPUT_FOCUS		= 0x00000200        /**< window has input focus */
	WINDOW_MOUSE_FOCUS		= 0x00000400        /**< window has mouse focus */
	WINDOW_FULLSCREEN_DESKT		= WINDOW_FULLSCREEN | 0x00001000
	WINDOW_FOREIGN			= 0x00000800             /**< window not created by SDL */

	GL_RED_SIZE			= 0x00000000
	GL_GREEN_SIZE			= 0x00000001
	GL_BLUE_SIZE			= 0x00000002
	GL_ALPHA_SIZE			= 0x00000003
	GL_BUFFER_SIZE			= 0x00000004
	GL_DOUBLEBUFFER			= 0x00000005
	GL_DEPTH_SIZE			= 0x00000006
	GL_STENCIL_SIZE			= 0x00000007
	GL_ACCUM_RED_SIZE		= 0x00000008
	GL_ACCUM_GREEN_SIZE		= 0x00000009
	GL_ACCUM_BLUE_SIZE		= 0x0000000A
	GL_ACCUM_ALPHA_SIZE		= 0x0000000B
	GL_STEREO			= 0x0000000C
	GL_MULTISAMPLEBUFFERS		= 0x0000000D
	GL_MULTISAMPLESAMPLES		= 0x0000000E
	GL_ACCELERATED_VISUAL		= 0x0000000F
	GL_RETAINED_BACKING		= 0x00000010
	GL_CONTEXT_MAJOR_VERSION	= 0x00000011
	GL_CONTEXT_MINOR_VERSION	= 0x00000012
	GL_CONTEXT_EGL			= 0x00000013
	GL_CONTEXT_FLAGS		= 0x00000014
	GL_CONTEXT_PROFILE_MASK		= 0x00000015
	GL_SHARE_WITH_CURRENT_CONTEXT	= 0x00000016

	GL_CONTEXT_PROFILE_CORE           = 0x0001
	GL_CONTEXT_PROFILE_COMPATIBILITY  = 0x0002
	GL_CONTEXT_PROFILE_ES             = 0x0004

	GL_CONTEXT_DEBUG_FLAG              = 0x0001
	GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002
	GL_CONTEXT_ROBUST_ACCESS_FLAG      = 0x0004
	GL_CONTEXT_RESET_ISOLATION_FLAG    = 0x0008
)
<commit_msg>Fix minor formatting issue<commit_after>package sdl

const (
	/* SDL.h */
	INIT_TIMER			= 0x00000001
	INIT_AUDIO			= 0x00000010
	INIT_VIDEO			= 0x00000020
	INIT_JOYSTICK			= 0x00000200
	INIT_HAPTIC			= 0x00001000
	INIT_GAMECONTROLLER		= 0x00002000      /**< turn on game controller also implicitly does JOYSTICK */
	INIT_NOPARACHUTE		= 0x00100000      /**< Don't catch fatal signals */
	INIT_EVERYTHING			= INIT_TIMER | INIT_AUDIO | INIT_VIDEO | INIT_JOYSTICK |
					  INIT_HAPTIC | INIT_GAMECONTROLLER

	WINDOWPOS_UNDEFINED_MASK	= 0x1FFF0000
	WINDOWPOS_UNDEFINED		= WINDOWPOS_UNDEFINED_MASK | 0

	/* SDL_blendmode.h */
	BLENDMODE_NONE			= 0x00000000     /**< No blending */
	BLENDMODE_BLEND			= 0x00000001    /**< dst = (src * A) + (dst * (1-A)) */
	BLENDMODE_ADD			= 0x00000002      /**< dst = (src * A) + dst */
	BLENDMODE_MOD			= 0x00000004       /**< dst = src * dst */

	/* SDL_error.h */
	ENOMEM				= 0x00000000
	EFREAD				= 0x00000001
	EFWRITE				= 0x00000002
	EFSEEK				= 0x00000003
	UNSUPPORTED			= 0x00000004
	LASTERROR			= 0x00000005

	/* SDL_events.h */
	FIRSTEVENT			= 0
	QUIT				= 0x100
	APP_TERMINATING			= 0x101
	APP_LOWMEMORY			= 0x102
	APP_WILLENTERBACKGROUND		= 0x103
	APP_DIDENTERBACKGROUND		= 0x104
	APP_WILLENTERFOREGROUND		= 0x105
	APP_DIDENTERFOREGROUND		= 0x106
	/* Window events */
	WINDOWEVENT			= 0x200
	SYSWMEVENT			= 0x201
	/* Keyboard events */
	KEYDOWN				= 0x300
	KEYUP				= 0x301
	TEXTEDITING			= 0x302
	TEXTINPUT			= 0x303
	/* Mouse events */
	MOUSEMOTION			= 0x400
	MOUSEBUTTONDOWN			= 0x401
	MOUSEBUTTONUP			= 0x402
	MOUSEWHEEL			= 0x403
	/* Joystick events */
	JOYAXISMOTION			= 0x600
	JOYBALLMOTION			= 0x601
	JOYHATMOTION			= 0x602
	JOYBUTTONDOWN			= 0x603
	JOYBUTTONUP			= 0x604
	JOYDEVICEADDED			= 0x605
	JOYDEVICEREMOVED		= 0x606
	/* Game controller events */
	CONTROLLERAXISMOTION		= 0x650
	CONTROLLERBUTTONDOWN		= 0x651
	CONTROLLERBUTTONUP		= 0x652
	CONTROLLERDEVICEADDED		= 0x653
	CONTROLLERDEVICEREMOVED		= 0x654
	CONTROLLERDEVICEREMAPPED	= 0x655
	/* Touch events */
	FINGERDOWN			= 0x700
	FINGERUP			= 0x701
	FINGERMOTION			= 0x702
	/* Gesture events */
	DOLLARGESTURE			= 0x800
	DOLLARRECORD			= 0x801
	MULTIGESTURE			= 0x802
	/* Clipboard events */
	CLIPBOARDUPDATE			= 0x900
	/* Drag and drop events */
	DROPFILE			= 0x1000

	USEREVENT			= 0x8000
	LASTEVENT			= 0xFFFF

	ADDEVENT			= 0x0
	PEEKEVENT			= 0x1
	GETEVENT			= 0x2

	/* SDL_render.h */
	RENDERER_SOFTWARE		= 0x00000001
	RENDERER_ACCELERATED		= 0x00000002
	RENDERER_PRESENTVSYNC		= 0x00000004
	RENDERER_TARGETTEXTURE		= 0x00000008

	TEXTUREACCESS_STATIC		= 0x00000001
	TEXTUREACCESS_STREAMING		= 0x00000002
	TEXTUREACCESS_TARGET		= 0x00000003

	TEXTUREMODULATE_NONE		= 0x00000000     /**< No modulation */
	TEXTUREMODULATE_COLOR		= 0x00000001    /**< srcC = srcC * color */
	TEXTUREMODULATE_ALPHA		= 0x00000002     /**< srcA = srcA * alpha */

	SDL_FLIP_NONE			= 0x00000000     /**< Do not flip */
	SDL_FLIP_HORIZONTAL		= 0x00000001    /**< flip horizontally */
	SDL_FLIP_VERTICAL		= 0x00000002     /**< flip vertically */

	/* SDL_video.h */
	WINDOW_FULLSCREEN		= 0x00000001         /**< fullscreen window */
	WINDOW_OPENGL			= 0x00000002             /**< window usable with OpenGL context */
	WINDOW_SHOWN			= 0x00000004              /**< window is visible */
	WINDOW_HIDDEN			= 0x00000008             /**< window is not visible */
	WINDOW_BORDERLESS		= 0x00000010         /**< no window decoration */
	WINDOW_RESIZABLE		= 0x00000020          /**< window can be resized */
	WINDOW_MINIMIZED		= 0x00000040          /**< window is minimized */
	WINDOW_MAXIMIZED		= 0x00000080          /**< window is maximized */
	WINDOW_INPUT_GRABBED		= 0x00000100      /**< window has grabbed input focus */
	WINDOW_INPUT_FOCUS		= 0x00000200        /**< window has input focus */
	WINDOW_MOUSE_FOCUS		= 0x00000400        /**< window has mouse focus */
	WINDOW_FULLSCREEN_DESKT		= WINDOW_FULLSCREEN | 0x00001000
	WINDOW_FOREIGN			= 0x00000800             /**< window not created by SDL */

	GL_RED_SIZE			= 0x00000000
	GL_GREEN_SIZE			= 0x00000001
	GL_BLUE_SIZE			= 0x00000002
	GL_ALPHA_SIZE			= 0x00000003
	GL_BUFFER_SIZE			= 0x00000004
	GL_DOUBLEBUFFER			= 0x00000005
	GL_DEPTH_SIZE			= 0x00000006
	GL_STENCIL_SIZE			= 0x00000007
	GL_ACCUM_RED_SIZE		= 0x00000008
	GL_ACCUM_GREEN_SIZE		= 0x00000009
	GL_ACCUM_BLUE_SIZE		= 0x0000000A
	GL_ACCUM_ALPHA_SIZE		= 0x0000000B
	GL_STEREO			= 0x0000000C
	GL_MULTISAMPLEBUFFERS		= 0x0000000D
	GL_MULTISAMPLESAMPLES		= 0x0000000E
	GL_ACCELERATED_VISUAL		= 0x0000000F
	GL_RETAINED_BACKING		= 0x00000010
	GL_CONTEXT_MAJOR_VERSION	= 0x00000011
	GL_CONTEXT_MINOR_VERSION	= 0x00000012
	GL_CONTEXT_EGL			= 0x00000013
	GL_CONTEXT_FLAGS		= 0x00000014
	GL_CONTEXT_PROFILE_MASK		= 0x00000015
	GL_SHARE_WITH_CURRENT_CONTEXT	= 0x00000016

	GL_CONTEXT_PROFILE_CORE           = 0x0001
	GL_CONTEXT_PROFILE_COMPATIBILITY  = 0x0002
	GL_CONTEXT_PROFILE_ES             = 0x0004

	GL_CONTEXT_DEBUG_FLAG              = 0x0001
	GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002
	GL_CONTEXT_ROBUST_ACCESS_FLAG      = 0x0004
	GL_CONTEXT_RESET_ISOLATION_FLAG    = 0x0008
)
<|endoftext|>


<commit_before>// Copyright 2013 Matthew Baird
// 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 search

import (
	"encoding/json"
	"fmt"
	u "github.com/araddon/gou"
	"github.com/mattbaird/elastigo/api"
	"github.com/mattbaird/elastigo/core"
	"log"
	"strconv"
	"strings"
)

var (
	_ = u.DEBUG
)

// Search is the entry point to the SearchDsl, it is a chainable set of utilities
// to create searches.
//
// params
//    @index = elasticsearch index to search
//
//    out, err := Search("github").Type("Issues").Pretty().Query(
//    Query().Range(
//         Range().Field("created_at").From("2012-12-10T15:00:00-08:00").To("2012-12-10T15:10:00-08:00"),
//       ).Search("add"),
//     ).Result()
func Search(index string) *SearchDsl {
	return &SearchDsl{Index: index, args: map[string]interface{}{}}
}

type SearchDsl struct {
	args          map[string]interface{}
	types         []string
	FromVal       int                      `json:"from,omitempty"`
	SizeVal       int                      `json:"size,omitempty"`
	Index         string                   `json:"-"`
	FacetVal      *FacetDsl                `json:"facets,omitempty"`
	QueryVal      *QueryDsl                `json:"query,omitempty"`
	SortBody      []*SortDsl               `json:"sort,omitempty"`
	FilterVal     *FilterWrap              `json:"filter,omitempty"`
	AggregatesVal map[string]*AggregateDsl `json:"aggregations,omitempty"`
}

func (s *SearchDsl) Bytes() ([]byte, error) {
	return api.DoCommand("POST", s.url(), s.args, s)
}

func (s *SearchDsl) Result() (*core.SearchResult, error) {
	var retval core.SearchResult
	if core.DebugRequests {
		sb, _ := json.MarshalIndent(s, "  ", "  ")
		log.Println(s.url())
		log.Println(string(sb))
	}
	body, err := s.Bytes()
	if err != nil {
		u.Errorf("%v", err)
		return nil, err
	}
	jsonErr := json.Unmarshal(body, &retval)
	if jsonErr != nil {
		u.Errorf("%v \n\t%s", jsonErr, string(body))
	}
	//Debug(string(body))
	return &retval, jsonErr
}

func (s *SearchDsl) url() string {
	url := fmt.Sprintf("/%s%s/_search", s.Index, s.getType())
	return url
}

func (s *SearchDsl) Pretty() *SearchDsl {
	s.args["pretty"] = "1"
	return s
}

// Type is the elasticsearch *Type* within a specific index
func (s *SearchDsl) Type(indexType string) *SearchDsl {
	if len(s.types) == 0 {
		s.types = make([]string, 0)
	}
	s.types = append(s.types, indexType)
	return s
}

func (s *SearchDsl) getType() string {
	if len(s.types) > 0 {
		return "/" + strings.Join(s.types, ",")
	}
	return ""
}

func (s *SearchDsl) From(from string) *SearchDsl {
	s.args["from"] = from
	return s
}

// Search is a simple interface to search, doesn't have the power of query
// but uses a simple query_string search
func (s *SearchDsl) Search(srch string) *SearchDsl {
	s.QueryVal = Query().Search(srch)
	return s
}

func (s *SearchDsl) Size(size string) *SearchDsl {
	s.args["size"] = size
	return s
}

func (s *SearchDsl) Fields(fields ...string) *SearchDsl {
	s.args["fields"] = strings.Join(fields, ",")
	return s
}

func (s *SearchDsl) Source(returnSource bool) *SearchDsl {
	s.args["_source"] = strconv.FormatBool(returnSource)
	return s
}

// Facet passes a Query expression to this search
//
//		qry := Search("github").Size("0").Facet(
//					Facet().Regex("repository.name", "no.*").Size("8"),
//				)
//
//		qry := Search("github").Pretty().Facet(
//					Facet().Fields("type").Size("25"),
//				)
func (s *SearchDsl) Facet(f *FacetDsl) *SearchDsl {
	s.FacetVal = f
	return s
}

func (s *SearchDsl) Aggregates(aggs ...*AggregateDsl) *SearchDsl {
	if len(aggs) < 1 {
		return s
	}
	if len(s.AggregatesVal) == 0 {
		s.AggregatesVal = make(map[string]*AggregateDsl)
	}

	for _, agg := range aggs {
		s.AggregatesVal[agg.Name] = agg
	}
	return s
}

func (s *SearchDsl) Query(q *QueryDsl) *SearchDsl {
	s.QueryVal = q
	return s
}

// Filter adds a Filter Clause with optional Boolean Clause.  This accepts n number of
// filter clauses.  If more than one, and missing Boolean Clause it assumes "and"
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//     )
//
//     qry := Search("github").Filter(
//         "or",
//         Filter().Exists("repository.name"),
//         Filter().Terms("actor_attributes.location", "portland"),
//     )
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//         Filter().Terms("repository.has_wiki", true)
//     )
func (s *SearchDsl) Filter(fl ...interface{}) *SearchDsl {
	if s.FilterVal == nil {
		s.FilterVal = NewFilterWrap()
	}

	s.FilterVal.addFilters(fl)
	return s
}

func (s *SearchDsl) Sort(sort ...*SortDsl) *SearchDsl {
	if s.SortBody == nil {
		s.SortBody = make([]*SortDsl, 0)
	}
	s.SortBody = append(s.SortBody, sort...)
	return s
}
<commit_msg>scroll in search dsl<commit_after>// Copyright 2013 Matthew Baird
// 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 search

import (
	"encoding/json"
	"fmt"
	u "github.com/araddon/gou"
	"github.com/mattbaird/elastigo/api"
	"github.com/mattbaird/elastigo/core"
	"log"
	"strconv"
	"strings"
)

var (
	_ = u.DEBUG
)

// Search is the entry point to the SearchDsl, it is a chainable set of utilities
// to create searches.
//
// params
//    @index = elasticsearch index to search
//
//    out, err := Search("github").Type("Issues").Pretty().Query(
//    Query().Range(
//         Range().Field("created_at").From("2012-12-10T15:00:00-08:00").To("2012-12-10T15:10:00-08:00"),
//       ).Search("add"),
//     ).Result()
func Search(index string) *SearchDsl {
	return &SearchDsl{Index: index, args: map[string]interface{}{}}
}

type SearchDsl struct {
	args          map[string]interface{}
	types         []string
	FromVal       int                      `json:"from,omitempty"`
	SizeVal       int                      `json:"size,omitempty"`
	Index         string                   `json:"-"`
	FacetVal      *FacetDsl                `json:"facets,omitempty"`
	QueryVal      *QueryDsl                `json:"query,omitempty"`
	SortBody      []*SortDsl               `json:"sort,omitempty"`
	FilterVal     *FilterWrap              `json:"filter,omitempty"`
	AggregatesVal map[string]*AggregateDsl `json:"aggregations,omitempty"`
}

func (s *SearchDsl) Bytes() ([]byte, error) {
	return api.DoCommand("POST", s.url(), s.args, s)
}

func (s *SearchDsl) Result() (*core.SearchResult, error) {
	var retval core.SearchResult
	if core.DebugRequests {
		sb, _ := json.MarshalIndent(s, "  ", "  ")
		log.Println(s.url())
		log.Println(string(sb))
	}
	body, err := s.Bytes()
	if err != nil {
		u.Errorf("%v", err)
		return nil, err
	}
	jsonErr := json.Unmarshal(body, &retval)
	if jsonErr != nil {
		u.Errorf("%v \n\t%s", jsonErr, string(body))
	}
	//Debug(string(body))
	return &retval, jsonErr
}

func (s *SearchDsl) url() string {
	url := fmt.Sprintf("/%s%s/_search", s.Index, s.getType())
	return url
}

func (s *SearchDsl) Pretty() *SearchDsl {
	s.args["pretty"] = "1"
	return s
}

// Type is the elasticsearch *Type* within a specific index
func (s *SearchDsl) Type(indexType string) *SearchDsl {
	if len(s.types) == 0 {
		s.types = make([]string, 0)
	}
	s.types = append(s.types, indexType)
	return s
}

func (s *SearchDsl) getType() string {
	if len(s.types) > 0 {
		return "/" + strings.Join(s.types, ",")
	}
	return ""
}

func (s *SearchDsl) From(from string) *SearchDsl {
	s.args["from"] = from
	return s
}

// Search is a simple interface to search, doesn't have the power of query
// but uses a simple query_string search
func (s *SearchDsl) Search(srch string) *SearchDsl {
	s.QueryVal = Query().Search(srch)
	return s
}

func (s *SearchDsl) Size(size string) *SearchDsl {
	s.args["size"] = size
	return s
}

func (s *SearchDsl) Fields(fields ...string) *SearchDsl {
	s.args["fields"] = strings.Join(fields, ",")
	return s
}

func (s *SearchDsl) Source(returnSource bool) *SearchDsl {
	s.args["_source"] = strconv.FormatBool(returnSource)
	return s
}

// Facet passes a Query expression to this search
//
//		qry := Search("github").Size("0").Facet(
//					Facet().Regex("repository.name", "no.*").Size("8"),
//				)
//
//		qry := Search("github").Pretty().Facet(
//					Facet().Fields("type").Size("25"),
//				)
func (s *SearchDsl) Facet(f *FacetDsl) *SearchDsl {
	s.FacetVal = f
	return s
}

func (s *SearchDsl) Aggregates(aggs ...*AggregateDsl) *SearchDsl {
	if len(aggs) < 1 {
		return s
	}
	if len(s.AggregatesVal) == 0 {
		s.AggregatesVal = make(map[string]*AggregateDsl)
	}

	for _, agg := range aggs {
		s.AggregatesVal[agg.Name] = agg
	}
	return s
}

func (s *SearchDsl) Query(q *QueryDsl) *SearchDsl {
	s.QueryVal = q
	return s
}

// Filter adds a Filter Clause with optional Boolean Clause.  This accepts n number of
// filter clauses.  If more than one, and missing Boolean Clause it assumes "and"
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//     )
//
//     qry := Search("github").Filter(
//         "or",
//         Filter().Exists("repository.name"),
//         Filter().Terms("actor_attributes.location", "portland"),
//     )
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//         Filter().Terms("repository.has_wiki", true)
//     )
func (s *SearchDsl) Filter(fl ...interface{}) *SearchDsl {
	if s.FilterVal == nil {
		s.FilterVal = NewFilterWrap()
	}

	s.FilterVal.addFilters(fl)
	return s
}

func (s *SearchDsl) Sort(sort ...*SortDsl) *SearchDsl {
	if s.SortBody == nil {
		s.SortBody = make([]*SortDsl, 0)
	}
	s.SortBody = append(s.SortBody, sort...)
	return s
}

func (s *SearchDsl) Scroll(duration string) *SearchDsl {
	s.args["scroll"] = duration
	return s
}
<|endoftext|>


<commit_before>/*
Copyright 2018 Google LLC

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 integration

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"
	"time"

	integration_util "github.com/grafeas/kritis/pkg/kritis/integration_util"
	"github.com/grafeas/kritis/pkg/kritis/testutil"
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/util/wait"
)

const (
	testAttesationAuthority = `apiVersion: kritis.grafeas.io/v1beta1
kind: AttestationAuthority
metadata:
  name: test-attestor
spec:
  noteReference: v1alpha1/projects/krits-int-test
  privateKeySecretName: %s
  publicKeyData: %s`
)

// Secret name for test-attestor
var aaSecret = "test-attestor"

// CRDs is a map of CRD type to names of the expected CRDs to create.
var crdNames = map[string]string{
	"imagesecuritypolicies.kritis.grafeas.io": "my-isp",
	"kritisconfigs.kritis.grafeas.io": "my-kritis-config",
}

func createAttestationAuthority(t *testing.T, ns string) {
	t.Helper()
	// Generate a key value pair
	pubKey, privKey := testutil.CreateKeyPair(t, aaSecret)
	// get the base encoded value for public key.
	pubKeyEnc := base64.StdEncoding.EncodeToString([]byte(pubKey))

	// create a tmp dir for keys
	d, err := ioutil.TempDir("", "_keys")
	if err != nil {
		t.Fatalf("unexpected error %s", err)
	}
	defer os.RemoveAll(d)

	// create file with contents in dir
	pubFile := createFileWithContents(t, d, pubKey)

	privFile := createFileWithContents(t, d, privKey)

	// Finally create a kubernetes secret.
	cmd := exec.Command("kubectl", "create", "secret", "generic", aaSecret,
		fmt.Sprintf("--from-file=public=%s", pubFile),
		fmt.Sprintf("--from-file=private=%s", privFile),
		"-n", ns)
	if _, err := integration_util.RunCmdOut(cmd); err != nil {
		t.Fatalf("unexpected error %s", err)
	}

	// Create the Attestation authority
	createAA(t, ns, pubKeyEnc)
}

func waitForCRDExamples(t *testing.T, ns *v1.Namespace) {
	t.Helper()
	t.Logf("Waiting for CRD examples ...")
	for crd, name := range crdNames {
		err := wait.PollImmediate(500*time.Millisecond, 2*time.Minute, func() (bool, error) {
			crdCmd := exec.Command("kubectl", "get", crd, name, "-n", ns.Name)
			err := integration_util.RunCmd(crdCmd)
			return (err == nil), err
		})
		if err != nil {
			t.Fatalf("timeout waiting for crds: %v", err)
		}
	}
}

func createFileWithContents(t *testing.T, d string, c string) string {
	t.Helper()
	file, err := ioutil.TempFile(d, "gpg")
	if err != nil {
		t.Fatalf("testing error: %v", err)
	}
	if _, err := file.WriteString(c); err != nil {
		t.Fatalf("testing error: %v", err)
	}
	return file.Name()
}

func createAA(t *testing.T, ns string, pubkey string) {
	t.Helper()
	cmd := exec.Command("kubectl", "apply", "-n", ns, "-f", "-")
	cmd.Stdin = bytes.NewReader([]byte(fmt.Sprintf(testAttesationAuthority, aaSecret, pubkey)))
	if _, err := integration_util.RunCmdOut(cmd); err != nil {
		t.Fatalf("testing error: %v", err)
	}
}
<commit_msg>Fixed gofmt errors<commit_after>/*
Copyright 2018 Google LLC

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 integration

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"
	"time"

	integration_util "github.com/grafeas/kritis/pkg/kritis/integration_util"
	"github.com/grafeas/kritis/pkg/kritis/testutil"
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/util/wait"
)

const (
	testAttesationAuthority = `apiVersion: kritis.grafeas.io/v1beta1
kind: AttestationAuthority
metadata:
  name: test-attestor
spec:
  noteReference: v1alpha1/projects/krits-int-test
  privateKeySecretName: %s
  publicKeyData: %s`
)

// Secret name for test-attestor
var aaSecret = "test-attestor"

// CRDs is a map of CRD type to names of the expected CRDs to create.
var crdNames = map[string]string{
	"imagesecuritypolicies.kritis.grafeas.io": "my-isp",
	"kritisconfigs.kritis.grafeas.io":         "my-kritis-config",
}

func createAttestationAuthority(t *testing.T, ns string) {
	t.Helper()
	// Generate a key value pair
	pubKey, privKey := testutil.CreateKeyPair(t, aaSecret)
	// get the base encoded value for public key.
	pubKeyEnc := base64.StdEncoding.EncodeToString([]byte(pubKey))

	// create a tmp dir for keys
	d, err := ioutil.TempDir("", "_keys")
	if err != nil {
		t.Fatalf("unexpected error %s", err)
	}
	defer os.RemoveAll(d)

	// create file with contents in dir
	pubFile := createFileWithContents(t, d, pubKey)

	privFile := createFileWithContents(t, d, privKey)

	// Finally create a kubernetes secret.
	cmd := exec.Command("kubectl", "create", "secret", "generic", aaSecret,
		fmt.Sprintf("--from-file=public=%s", pubFile),
		fmt.Sprintf("--from-file=private=%s", privFile),
		"-n", ns)
	if _, err := integration_util.RunCmdOut(cmd); err != nil {
		t.Fatalf("unexpected error %s", err)
	}

	// Create the Attestation authority
	createAA(t, ns, pubKeyEnc)
}

func waitForCRDExamples(t *testing.T, ns *v1.Namespace) {
	t.Helper()
	t.Logf("Waiting for CRD examples ...")
	for crd, name := range crdNames {
		err := wait.PollImmediate(500*time.Millisecond, 2*time.Minute, func() (bool, error) {
			crdCmd := exec.Command("kubectl", "get", crd, name, "-n", ns.Name)
			err := integration_util.RunCmd(crdCmd)
			return (err == nil), err
		})
		if err != nil {
			t.Fatalf("timeout waiting for crds: %v", err)
		}
	}
}

func createFileWithContents(t *testing.T, d string, c string) string {
	t.Helper()
	file, err := ioutil.TempFile(d, "gpg")
	if err != nil {
		t.Fatalf("testing error: %v", err)
	}
	if _, err := file.WriteString(c); err != nil {
		t.Fatalf("testing error: %v", err)
	}
	return file.Name()
}

func createAA(t *testing.T, ns string, pubkey string) {
	t.Helper()
	cmd := exec.Command("kubectl", "apply", "-n", ns, "-f", "-")
	cmd.Stdin = bytes.NewReader([]byte(fmt.Sprintf(testAttesationAuthority, aaSecret, pubkey)))
	if _, err := integration_util.RunCmdOut(cmd); err != nil {
		t.Fatalf("testing error: %v", err)
	}
}
<|endoftext|>


<commit_before>// Don't build this file on Raspberry Pi (i.e. not arm)
// +build !linux,!arm

package lightwavego

import "fmt"

func init() {
    fmt.Println("NOGPIO - lightwavego:interface::init")
}

func Shutdown() {
    fmt.Println("NOGPIO - lightwavego:interface::Shutdown")
}

func (lw *LwTx) sendBuffer(message LwBuffer) error {
    fmt.Println("NOGPIO - lightwavego:interface::sendBuffer:", message)
    return nil
}
<commit_msg>fix interface file for travis builds<commit_after>// Don't build this file on Raspberry Pi (i.e. not arm)
// +build !arm

package lightwavego

import "fmt"

func init() {
    fmt.Println("NOGPIO - lightwavego:interface::init")
}

func Shutdown() {
    fmt.Println("NOGPIO - lightwavego:interface::Shutdown")
}

func (lw *LwTx) sendBuffer(message LwBuffer) error {
    fmt.Println("NOGPIO - lightwavego:interface::sendBuffer:", message)
    return nil
}
<|endoftext|>


<commit_before>//  Description = ipquail website
//  Author = Theodore Baschak
//  Version = 1.0

package main

import (
  "fmt"
  "net"
  "github.com/pilu/traffic"
)

func indexHandler(w traffic.ResponseWriter, r *traffic.Request) {
  w.Render("ipquail")
}

func ipHandler(w traffic.ResponseWriter, r *traffic.Request) {
  traffic.Logger().Print( r.Header.Get("X-Forwarded-For") )
  w.Header().Add("Access-Control-Allow-Origin", "*")
  w.Header().Add("Access-Control-Allow-Methods", "GET")
  w.Header().Add("Access-Control-Allow-Headers", "X-Requested-With,Accept,Content-Type,Origin")
  w.Header().Add("Content-type", "application/json")
  w.WriteText( "{ \"ip\": \"" )
  w.WriteText( r.Header.Get("X-Forwarded-For") )
  w.WriteText( "\" }" )
}

func ptrHandler(w traffic.ResponseWriter, r *traffic.Request) {
  addr, err := net.LookupAddr( r.Header.Get("X-Forwarded-For") )
  fmt.Println(addr, err)
  traffic.Logger().Print( r.Header.Get("X-Forwarded-For") )
  w.Header().Add("Access-Control-Allow-Origin", "*")
  w.Header().Add("Access-Control-Allow-Methods", "GET")
  w.Header().Add("Access-Control-Allow-Headers", "X-Requested-With,Accept,Content-Type,Origin")
  w.Header().Add("Content-type", "application/json")
  w.WriteText( "{ \"ptr\": \"" )
  w.WriteText( addr[0] )
  w.WriteText( "\" }" )
}

func main() {
  router := traffic.New()

  // add a route for each page you add to the site
  // make sure you create a route handler for it

  router.Get("/", indexHandler)
  router.Get("/api/ip", ipHandler)
  router.Get("/api/ptr", ptrHandler)
  router.Run()
}
<commit_msg>try an if to fix lack of ptr<commit_after>//  Description = ipquail website
//  Author = Theodore Baschak
//  Version = 1.0

package main

import (
  "fmt"
  "net"
  "github.com/pilu/traffic"
)

func indexHandler(w traffic.ResponseWriter, r *traffic.Request) {
  w.Render("ipquail")
}

func ipHandler(w traffic.ResponseWriter, r *traffic.Request) {
  traffic.Logger().Print( r.Header.Get("X-Forwarded-For") )
  w.Header().Add("Access-Control-Allow-Origin", "*")
  w.Header().Add("Access-Control-Allow-Methods", "GET")
  w.Header().Add("Access-Control-Allow-Headers", "X-Requested-With,Accept,Content-Type,Origin")
  w.Header().Add("Content-type", "application/json")
  w.WriteText( "{ \"ip\": \"" )
  w.WriteText( r.Header.Get("X-Forwarded-For") )
  w.WriteText( "\" }" )
}

func ptrHandler(w traffic.ResponseWriter, r *traffic.Request) {
  addr, err := net.LookupAddr( r.Header.Get("X-Forwarded-For") )
  fmt.Println(addr, err)
  traffic.Logger().Print( r.Header.Get("X-Forwarded-For") )
  w.Header().Add("Access-Control-Allow-Origin", "*")
  w.Header().Add("Access-Control-Allow-Methods", "GET")
  w.Header().Add("Access-Control-Allow-Headers", "X-Requested-With,Accept,Content-Type,Origin")
  w.Header().Add("Content-type", "application/json")
  if len(addr) > 0 {
    w.WriteText( "{ \"ptr\": \"" )
    w.WriteText( addr[0] )
    w.WriteText( "\" }" )
  } else {
    w.WriteText( "{ \"ptr\": \"none\" }" )
  }
}

func main() {
  router := traffic.New()

  // add a route for each page you add to the site
  // make sure you create a route handler for it

  router.Get("/", indexHandler)
  router.Get("/api/ip", ipHandler)
  router.Get("/api/ptr", ptrHandler)
  router.Run()
}
<|endoftext|>


<commit_before>package ip

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Toorop/govh"
	"net/url"
	//"os"
)

type IpRessource struct {
	client *govh.OvhClient
}

func New(client *govh.OvhClient) (*IpRessource, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	return &IpRessource{client: client}, nil
}

// List IP
func (r *IpRessource) List(ipType string) (ips []IpBlock, err error) {
	var uri string
	if ipType == "all" {
		uri = "ip"
		ipType = ""
	} else {
		uri = fmt.Sprintf("ip?type=%s", ipType)
	}
	t, err := r.client.Do("GET", uri, "")
	var ipl = []string{}
	if err = json.Unmarshal(t, &ipl); err == nil {
		for _, i := range ipl {
			ips = append(ips, IpBlock{i, ipType})
		}
	}
	return
}

//// LOADBALANCING

// List IP load balancing
func (r *IpRessource) LbList() (resp []byte, err error) {
	resp, err = r.client.Do("GET", "ip/loadBalancing", "")
	return
}

// FIREWALL

// List IP of block IP under firewall protection
func (r *IpRessource) FwListIpOfBlock(block IpBlock) (ips []string, err error) {
	uri := fmt.Sprintf("ip/%s/firewall", url.QueryEscape(block.IP))
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return
	}
	err = json.Unmarshal(t, &ips)
	return
}

// Add IP to firewall
func (r *IpRessource) FwAddIp(block IpBlock, ipv4 string) error {
	uri := fmt.Sprintf("ip/%s/firewall", url.QueryEscape(block.IP))
	type p struct {
		IpOnFirewall string `json:"ipOnFirewall"`
	}
	payload, err := json.Marshal(p{ipv4})
	if err != nil {
		return err
	}
	_, err = r.client.Do("POST", uri, string(payload))
	return err
}

// Remove IP from firewall
func (r *IpRessource) FwRemoveIp(block IpBlock, ipv4 string) error {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	_, err := r.client.Do("DELETE", uri, "")
	return err
}

// Enable / disable firewall for IP ipv4 of IpBlock block
func (r *IpRessource) FwSetFirewallEnable(block IpBlock, ipv4 string, enabled bool) error {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	type p struct {
		Enabled bool `json:"enabled"`
	}
	payload, err := json.Marshal(p{enabled})
	if err != nil {
		return err
	}
	s, err := r.client.Do("PUT", uri, string(payload))
	return err
}

// Get properties about an IP firewalled
func (r *IpRessource) FwGetIpProperties(block IpBlock, ipv4 string) (i IpFirewallIp, e error) {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return i, err
	}
	err = json.Unmarshal(t, &i)
	return
}

// List firewall rules

//func (r *IpRessource) FwGetIpRules

// Get rule
func (r *IpRessource) FwGetRule(block IpBlock, ipv4 string, sequence string) (rule FirewallRule, err error) {
	uri := fmt.Sprintf("ip/%s/firewall/%s/rules/%s", url.QueryEscape(block.IP), ipv4, sequence)
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return rule, err
	}
	err = json.Unmarshal(t, &rule)
	return
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
<commit_msg>remove unused var<commit_after>package ip

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Toorop/govh"
	"net/url"
	//"os"
)

type IpRessource struct {
	client *govh.OvhClient
}

func New(client *govh.OvhClient) (*IpRessource, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	return &IpRessource{client: client}, nil
}

// List IP
func (r *IpRessource) List(ipType string) (ips []IpBlock, err error) {
	var uri string
	if ipType == "all" {
		uri = "ip"
		ipType = ""
	} else {
		uri = fmt.Sprintf("ip?type=%s", ipType)
	}
	t, err := r.client.Do("GET", uri, "")
	var ipl = []string{}
	if err = json.Unmarshal(t, &ipl); err == nil {
		for _, i := range ipl {
			ips = append(ips, IpBlock{i, ipType})
		}
	}
	return
}

//// LOADBALANCING

// List IP load balancing
func (r *IpRessource) LbList() (resp []byte, err error) {
	resp, err = r.client.Do("GET", "ip/loadBalancing", "")
	return
}

// FIREWALL

// List IP of block IP under firewall protection
func (r *IpRessource) FwListIpOfBlock(block IpBlock) (ips []string, err error) {
	uri := fmt.Sprintf("ip/%s/firewall", url.QueryEscape(block.IP))
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return
	}
	err = json.Unmarshal(t, &ips)
	return
}

// Add IP to firewall
func (r *IpRessource) FwAddIp(block IpBlock, ipv4 string) error {
	uri := fmt.Sprintf("ip/%s/firewall", url.QueryEscape(block.IP))
	type p struct {
		IpOnFirewall string `json:"ipOnFirewall"`
	}
	payload, err := json.Marshal(p{ipv4})
	if err != nil {
		return err
	}
	_, err = r.client.Do("POST", uri, string(payload))
	return err
}

// Remove IP from firewall
func (r *IpRessource) FwRemoveIp(block IpBlock, ipv4 string) error {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	_, err := r.client.Do("DELETE", uri, "")
	return err
}

// Enable / disable firewall for IP ipv4 of IpBlock block
func (r *IpRessource) FwSetFirewallEnable(block IpBlock, ipv4 string, enabled bool) error {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	type p struct {
		Enabled bool `json:"enabled"`
	}
	payload, err := json.Marshal(p{enabled})
	if err != nil {
		return err
	}
	_, err = r.client.Do("PUT", uri, string(payload))
	return err
}

// Get properties about an IP firewalled
func (r *IpRessource) FwGetIpProperties(block IpBlock, ipv4 string) (i IpFirewallIp, e error) {
	uri := fmt.Sprintf("ip/%s/firewall/%s", url.QueryEscape(block.IP), ipv4)
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return i, err
	}
	err = json.Unmarshal(t, &i)
	return
}

// List firewall rules

//func (r *IpRessource) FwGetIpRules

// Get rule
func (r *IpRessource) FwGetRule(block IpBlock, ipv4 string, sequence string) (rule FirewallRule, err error) {
	uri := fmt.Sprintf("ip/%s/firewall/%s/rules/%s", url.QueryEscape(block.IP), ipv4, sequence)
	t, err := r.client.Do("GET", uri, "")
	if err != nil {
		return rule, err
	}
	err = json.Unmarshal(t, &rule)
	return
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
<|endoftext|>


<commit_before>/*
Package Jamon is an INI-like configuration file parser. An example configuration
file may look like this:
	address=127.0.0.1:1234 # root-level values

	[defaults]
	key=value
	name=Gabriel

	[Group]
	key=value
Trailing comments are also allowed, and root-level keys are only accepted at the
top of the file
*/
package jamon

import (
	"bufio"
	"os"
	"regexp"
	"strings"
)

// Internal name for group that holds settings at root-level
const defaultGroup = "JAMON.ROOT_GROUP"

// A configuration type may hold multiple categories of settings
type Config map[string]Group

// A group holds key-value pairs of settings
type Group map[string]string

// Returns the value of a root-level key
func (c Config) Key(key string) string { return c[defaultGroup].Key(key) }

// Verifies the existence of a root-level key
func (c Config) HasKey(key string) bool {
	_, ok := c[defaultGroup][key]
	return ok
}

// Returns a group by name. If the group does not exist, an empty category
// is returned. This is to avoid multiple return values in order to facilitate
// chaining.
func (c Config) Group(name string) Group { return c[name] }

// Verifies if a category exists
func (c Config) HasGroup(category string) bool {
	_, ok := c[category]
	return ok
}

// Returns a key from a category
func (c Group) Key(key string) string { return c[key] }

// Verifies if the category has a key
func (c Group) HasKey(key string) bool {
	_, ok := c[key]
	return ok
}

// Regexp for substitions
var regexSubst = regexp.MustCompile(`\$\{([\w\s.]*)\}`)

// Loads a configuration file
func Load(filename string) (Config, error) {
	file, err := os.Open(filename)
	if err != nil {
		return Config{}, err
	}

	defer file.Close()

	reader := bufio.NewReader(file)
	config := Config{}
	currentGroup := defaultGroup

	for {
		line, _, err := reader.ReadLine()
		if err != nil {
			break
		}

		isGroup, value, key, skip := parseLine(string(line))

		switch {
		case skip:
			continue

		case isGroup:
			currentGroup = value
			continue

		case config[currentGroup] == nil:
			config[currentGroup] = make(Group)
			fallthrough

		default:
			compile := func(r string) string {
				k := r[2 : len(r)-1]

				if _, ok := config[currentGroup][k]; ok {
					return config[currentGroup][k]
				}

				if _, ok := config[defaultGroup][k]; ok {
					return config[defaultGroup][k]
				}

				return r
			}

			val := regexSubst.ReplaceAllStringFunc(value, compile)
			config[currentGroup][key] = val
		}
	}

	return config, nil
}

// Attempts to parse an entry in the config file. The first return value specifies
// whether 'value' is the name of a category or the value of a key. Skip indicates
// whether the line was a comment or could not be parsed.
func parseLine(line string) (isGroup bool, value, key string, skip bool) {
	line = strings.SplitN(line, "#", 2)[0]
	line = strings.Trim(line, " \t\r")

	// Is comment or empty line?
	if len(line) == 0 {
		skip = true
		return
	}

	// Is category?
	if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
		isGroup = true
		value = strings.Trim(line, "[]")
		return
	}

	// Is key/value pair?
	parts := strings.SplitN(line, "=", 2)
	if len(parts) < 2 {
		skip = true
		return
	}

	key = parts[0]
	value = strings.TrimRight(parts[1], " ")

	return
}
<commit_msg>Used a scanner like regular people do<commit_after>/*
Package Jamon is an INI-like configuration file parser. An example configuration
file may look like this:
	address=127.0.0.1:1234 # root-level values

	[defaults]
	key=value
	name=Gabriel

	[Group]
	key=value
Trailing comments are also allowed, and root-level keys are only accepted at the
top of the file
*/
package jamon

import (
	"bufio"
	"os"
	"regexp"
	"strings"
)

// Internal name for group that holds settings at root-level
const defaultGroup = "JAMON.ROOT_GROUP"

// A configuration type may hold multiple categories of settings
type Config map[string]Group

// A group holds key-value pairs of settings
type Group map[string]string

// Returns the value of a root-level key
func (c Config) Key(key string) string { return c[defaultGroup].Key(key) }

// Verifies the existence of a root-level key
func (c Config) HasKey(key string) bool {
	_, ok := c[defaultGroup][key]
	return ok
}

// Returns a group by name. If the group does not exist, an empty category
// is returned. This is to avoid multiple return values in order to facilitate
// chaining.
func (c Config) Group(name string) Group { return c[name] }

// Verifies if a category exists
func (c Config) HasGroup(category string) bool {
	_, ok := c[category]
	return ok
}

// Returns a key from a category
func (c Group) Key(key string) string { return c[key] }

// Verifies if the category has a key
func (c Group) HasKey(key string) bool {
	_, ok := c[key]
	return ok
}

// Regexp for substitions
var regexSubst = regexp.MustCompile(`\$\{([\w\s.]*)\}`)

// Loads a configuration file
func Load(filename string) (Config, error) {
	file, err := os.Open(filename)
	if err != nil {
		return Config{}, err
	}

	defer file.Close()

	scanner := bufio.NewScanner(file)
	config := Config{}
	currentGroup := defaultGroup

	for scanner.Scan() {
		isGroup, value, key, skip := parseLine(scanner.Text())

		switch {
		case skip:
			continue

		case isGroup:
			currentGroup = value
			continue

		case config[currentGroup] == nil:
			config[currentGroup] = make(Group)
			fallthrough

		default:
			compile := func(r string) string {
				k := r[2 : len(r)-1]

				if _, ok := config[currentGroup][k]; ok {
					return config[currentGroup][k]
				}

				if _, ok := config[defaultGroup][k]; ok {
					return config[defaultGroup][k]
				}

				return r
			}

			val := regexSubst.ReplaceAllStringFunc(value, compile)
			config[currentGroup][key] = val
		}
	}

	return config, nil
}

// Attempts to parse an entry in the config file. The first return value specifies
// whether 'value' is the name of a category or the value of a key. Skip indicates
// whether the line was a comment or could not be parsed.
func parseLine(line string) (isGroup bool, value, key string, skip bool) {
	line = strings.SplitN(line, "#", 2)[0]
	line = strings.Trim(line, " \t\r")

	// Is comment or empty line?
	if len(line) == 0 {
		skip = true
		return
	}

	// Is category?
	if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
		isGroup = true
		value = strings.Trim(line, "[]")
		return
	}

	// Is key/value pair?
	parts := strings.SplitN(line, "=", 2)
	if len(parts) < 2 {
		skip = true
		return
	}

	key = parts[0]
	value = strings.TrimRight(parts[1], " ")

	return
}
<|endoftext|>


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

package sqlite

/*
#include <sqlite3.h>
*/
import "C"

// Limit enumerates run-time limit categories
// (See http://www.sqlite.org/c3ref/c_limit_attached.html)
type Limit int32

// Run-time limit categories
const (
	LimitLength            Limit = C.SQLITE_LIMIT_LENGTH // The maximum size of any string or BLOB or table row, in bytes.
	LimitColumn            Limit = C.SQLITE_LIMIT_COLUMN
	LimitExprDepth         Limit = C.SQLITE_LIMIT_EXPR_DEPTH
	LimitCompoundSelect    Limit = C.SQLITE_LIMIT_COMPOUND_SELECT
	LimitVdbeOp            Limit = C.SQLITE_LIMIT_VDBE_OP
	LimitFunctionArg       Limit = C.SQLITE_LIMIT_FUNCTION_ARG
	LimitAttached          Limit = C.SQLITE_LIMIT_ATTACHED
	LimitLikePatternLength Limit = C.SQLITE_LIMIT_LIKE_PATTERN_LENGTH
	LimitVariableNumber    Limit = C.SQLITE_LIMIT_VARIABLE_NUMBER
	LimitTriggerLength     Limit = C.SQLITE_LIMIT_TRIGGER_DEPTH
)

// Limit queries the current value of a limit.
// (See http://www.sqlite.org/c3ref/limit.html)
func (c *Conn) Limit(id Limit) int32 {
	return int32(C.sqlite3_limit(c.db, C.int(id), -1))
}

// SetLimit changes the value of a limit.
// (See http://www.sqlite.org/c3ref/limit.html)
func (c *Conn) SetLimit(id Limit, newVal int32) int32 {
	return int32(C.sqlite3_limit(c.db, C.int(id), C.int(newVal)))
}
<commit_msg>Add missing SQLITE_LIMIT_SQL_LENGTH const<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlite

/*
#include <sqlite3.h>
*/
import "C"

// Limit enumerates run-time limit categories
// (See http://www.sqlite.org/c3ref/c_limit_attached.html)
type Limit int32

// Run-time limit categories
const (
	LimitLength            Limit = C.SQLITE_LIMIT_LENGTH     // The maximum size of any string or BLOB or table row, in bytes.
	LimitSQLLength         Limit = C.SQLITE_LIMIT_SQL_LENGTH // The maximum length of a SQL statement, in bytes.
	LimitColumn            Limit = C.SQLITE_LIMIT_COLUMN
	LimitExprDepth         Limit = C.SQLITE_LIMIT_EXPR_DEPTH
	LimitCompoundSelect    Limit = C.SQLITE_LIMIT_COMPOUND_SELECT
	LimitVdbeOp            Limit = C.SQLITE_LIMIT_VDBE_OP
	LimitFunctionArg       Limit = C.SQLITE_LIMIT_FUNCTION_ARG
	LimitAttached          Limit = C.SQLITE_LIMIT_ATTACHED
	LimitLikePatternLength Limit = C.SQLITE_LIMIT_LIKE_PATTERN_LENGTH
	LimitVariableNumber    Limit = C.SQLITE_LIMIT_VARIABLE_NUMBER
	LimitTriggerLength     Limit = C.SQLITE_LIMIT_TRIGGER_DEPTH
)

// Limit queries the current value of a limit.
// (See http://www.sqlite.org/c3ref/limit.html)
func (c *Conn) Limit(id Limit) int32 {
	return int32(C.sqlite3_limit(c.db, C.int(id), -1))
}

// SetLimit changes the value of a limit.
// (See http://www.sqlite.org/c3ref/limit.html)
func (c *Conn) SetLimit(id Limit, newVal int32) int32 {
	return int32(C.sqlite3_limit(c.db, C.int(id), C.int(newVal)))
}
<|endoftext|>