<commit_before>package api

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"

	"github.com/generationtux/brizo/app/handlers/jsonutil"
	"github.com/generationtux/brizo/database"
	"github.com/generationtux/brizo/kube"
	"github.com/generationtux/brizo/resources"
	"github.com/go-zoo/bone"
)

// EnvironmentIndex provides a listing of all Environments
func EnvironmentIndex(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}
	environments, err := resources.AllEnvironments(db)
	if err != nil {
		log.Printf("Error when retrieving environments: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	for i := range environments {
		if len(environments[i].Versions) == 0 {
			environments[i].Versions = make([]resources.Version, 0)
		}
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environments)
}

// EnvironmentShow provides an Environment
func EnvironmentShow(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	id := bone.GetValue(r, "uuid")
	environment, err := resources.GetEnvironment(db, id)
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	if len(environment.Versions) == 0 {
		environment.Versions = make([]resources.Version, 0)
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environment)
}

// EnvironmentCreate creates a new Environment
func EnvironmentCreate(w http.ResponseWriter, r *http.Request) {
	client, err := kube.New()
	if err != nil {
		log.Printf("Kube client error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusServiceUnavailable,
			"unable to reach Kubernetes")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	var createForm struct {
		Name          string
		ApplicationID string
	}
	decoder := json.NewDecoder(r.Body)
	err = decoder.Decode(&createForm)
	defer r.Body.Close()
	if err != nil {
		log.Printf("decoding error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to parse the form")
		jsonutil.RespondJSONError(w, jre)
		return
	}
	// @todo
	appID, _ := strconv.ParseUint(createForm.ApplicationID, 10, 0)
	environment := resources.Environment{
		Name:          createForm.Name,
		ApplicationID: appID,
	}

	app, err := resources.GetApplicationByID(db, createForm.ApplicationID)
	if err != nil {
		log.Printf("Error when retrieving application: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving application")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	_, err = resources.CreateEnvironment(db, client, &environment, app)
	// @todo handle failed save w/out error?
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	jsonResponse(w, environment, 200)
}

// EnvironmentEdit edits an Environment
func EnvironmentEdit(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	var editForm struct {
		Name string
	}
	decoder := json.NewDecoder(r.Body)
	err = decoder.Decode(&editForm)
	defer r.Body.Close()
	if err != nil {
		log.Printf("decoding error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to parse the form")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	id := bone.GetValue(r, "uuid")
	environment, err := resources.GetEnvironment(db, id)
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	environment.Name = editForm.Name

	_, err = resources.UpdateEnvironment(db, environment)
	if err != nil {
		log.Printf("Error when updating environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when updating environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environment)
	w.WriteHeader(http.StatusOK)
}

// EnvironmentDeploy deploys a Version to the environment
func EnvironmentDeploy(w http.ResponseWriter, r *http.Request) {
	var deployForm struct {
		// id of the Version we want to deploy
		VersionUUID string `json:"version_uuid"`
	}
	err := jsonRequest(r, &deployForm)
	if err != nil {
		jsonErrorResponse(w, err.Error(), http.StatusBadRequest)
		return
	}

	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jsonErrorResponse(w, "Unable to connect to database", http.StatusInternalServerError)
		return
	}

	deployToEnvironment, err := resources.GetEnvironment(db, bone.GetValue(r, "environment-uuid"))
	if err != nil {
		log.Println(err)
		jsonErrorResponse(w, "Unable to get environment", http.StatusNotFound)
		return
	}

	client, err := kube.New()
	if err != nil {
		log.Printf("Kube client error: '%s'\n", err)
		jsonErrorResponse(w, "Unable to connect to Kubernetes", http.StatusInternalServerError)
		return
	}

	version, err := resources.GetVersion(db, deployForm.VersionUUID, client, false)
	if err != nil {
		log.Println(err)
		jsonErrorResponse(w, "Unable to get version", http.StatusNotFound)
		return
	}

	// modify the version for the new environment
	version.Environment = *deployToEnvironment
	version.EnvironmentID = deployToEnvironment.ID

	_, err = resources.DeployVersion(client, version)
	if err != nil {
		log.Printf("Error deploying version: '%s'\n", err)
		jsonErrorResponse(w, "Unable to deploy version", http.StatusInternalServerError)
		return
	}

	jsonResponse(w, map[string]string{"message": "Version deployed."}, 200)
}
<commit_msg>add containers to version deployment + relations<commit_after>package api

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"

	"github.com/generationtux/brizo/app/handlers/jsonutil"
	"github.com/generationtux/brizo/database"
	"github.com/generationtux/brizo/kube"
	"github.com/generationtux/brizo/resources"
	"github.com/go-zoo/bone"
)

// EnvironmentIndex provides a listing of all Environments
func EnvironmentIndex(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}
	environments, err := resources.AllEnvironments(db)
	if err != nil {
		log.Printf("Error when retrieving environments: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	for i := range environments {
		if len(environments[i].Versions) == 0 {
			environments[i].Versions = make([]resources.Version, 0)
		}
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environments)
}

// EnvironmentShow provides an Environment
func EnvironmentShow(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	id := bone.GetValue(r, "uuid")
	environment, err := resources.GetEnvironment(db, id)
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	if len(environment.Versions) == 0 {
		environment.Versions = make([]resources.Version, 0)
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environment)
}

// EnvironmentCreate creates a new Environment
func EnvironmentCreate(w http.ResponseWriter, r *http.Request) {
	client, err := kube.New()
	if err != nil {
		log.Printf("Kube client error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusServiceUnavailable,
			"unable to reach Kubernetes")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	var createForm struct {
		Name          string
		ApplicationID string
	}
	decoder := json.NewDecoder(r.Body)
	err = decoder.Decode(&createForm)
	defer r.Body.Close()
	if err != nil {
		log.Printf("decoding error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to parse the form")
		jsonutil.RespondJSONError(w, jre)
		return
	}
	// @todo
	appID, _ := strconv.ParseUint(createForm.ApplicationID, 10, 0)
	environment := resources.Environment{
		Name:          createForm.Name,
		ApplicationID: appID,
	}

	app, err := resources.GetApplicationByID(db, createForm.ApplicationID)
	if err != nil {
		log.Printf("Error when retrieving application: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving application")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	_, err = resources.CreateEnvironment(db, client, &environment, app)
	// @todo handle failed save w/out error?
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	jsonResponse(w, environment, 200)
}

// EnvironmentEdit edits an Environment
func EnvironmentEdit(w http.ResponseWriter, r *http.Request) {
	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to connect to the database")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	var editForm struct {
		Name string
	}
	decoder := json.NewDecoder(r.Body)
	err = decoder.Decode(&editForm)
	defer r.Body.Close()
	if err != nil {
		log.Printf("decoding error: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when attempting to parse the form")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	id := bone.GetValue(r, "uuid")
	environment, err := resources.GetEnvironment(db, id)
	if err != nil {
		log.Printf("Error when retrieving environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when retrieving environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	environment.Name = editForm.Name

	_, err = resources.UpdateEnvironment(db, environment)
	if err != nil {
		log.Printf("Error when updating environment: '%s'\n", err)
		jre := jsonutil.NewJSONResponseError(
			http.StatusInternalServerError,
			"there was an error when updating environment")
		jsonutil.RespondJSONError(w, jre)
		return
	}

	w.Header().Set("content-type", "application/json")
	json.NewEncoder(w).Encode(environment)
	w.WriteHeader(http.StatusOK)
}

// EnvironmentDeploy deploys a Version to the environment
func EnvironmentDeploy(w http.ResponseWriter, r *http.Request) {
	var deployForm struct {
		// id of the Version we want to deploy
		VersionUUID string `json:"version_uuid"`
	}
	err := jsonRequest(r, &deployForm)
	if err != nil {
		jsonErrorResponse(w, err.Error(), http.StatusBadRequest)
		return
	}

	db, err := database.Connect()
	defer db.Close()
	if err != nil {
		log.Printf("Database error: '%s'\n", err)
		jsonErrorResponse(w, "Unable to connect to database", http.StatusInternalServerError)
		return
	}

	deployToEnvironment, err := resources.GetEnvironment(db, bone.GetValue(r, "environment-uuid"))
	if err != nil {
		log.Println(err)
		jsonErrorResponse(w, "Unable to get environment", http.StatusNotFound)
		return
	}

	client, err := kube.New()
	if err != nil {
		log.Printf("Kube client error: '%s'\n", err)
		jsonErrorResponse(w, "Unable to connect to Kubernetes", http.StatusInternalServerError)
		return
	}

	version, err := resources.GetVersion(db, deployForm.VersionUUID, client, true)
	if err != nil {
		log.Println(err)
		jsonErrorResponse(w, "Unable to get version", http.StatusNotFound)
		return
	}

	// modify the version for the new environment
	version.Environment = *deployToEnvironment
	version.EnvironmentID = deployToEnvironment.ID

	_, err = resources.DeployVersion(client, version)
	if err != nil {
		log.Printf("Error deploying version: '%s'\n", err)
		jsonErrorResponse(w, "Unable to deploy version", http.StatusInternalServerError)
		return
	}

	_, err = resources.UpdateVersion(db, version)
	if err != nil {
		log.Printf("Error updating version after deployment: '%s'\n", err)
		jsonErrorResponse(w, "Unable to update version after deployment", http.StatusInternalServerError)
		return
	}

	jsonResponse(w, map[string]string{"message": "Version deployed."}, 200)
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package source

import (
	"errors"
	"net/http"
	"os"
	"strings"

	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/linki/instrumented_http"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

// ErrSourceNotFound is returned when a requested source doesn't exist.
var ErrSourceNotFound = errors.New("source not found")

// Config holds shared configuration options for all Sources.
type Config struct {
	Namespace     string
	FQDNTemplate  string
	Compatibility string
}

// ClientGenerator provides clients
type ClientGenerator interface {
	KubeClient() (kubernetes.Interface, error)
}

// SingletonClientGenerator stores provider clients and guarantees that only one instance of client
// will be generated
type SingletonClientGenerator struct {
	KubeConfig string
	KubeMaster string
	client     kubernetes.Interface
	sync.Once
}

// KubeClient generates a kube client if it was not created before
func (p *SingletonClientGenerator) KubeClient() (kubernetes.Interface, error) {
	var err error
	p.Once.Do(func() {
		p.client, err = NewKubeClient(p.KubeConfig, p.KubeMaster)
	})
	return p.client, err
}

// ByNames returns multiple Sources given multiple names.
func ByNames(p ClientGenerator, names []string, cfg *Config) ([]Source, error) {
	sources := []Source{}
	for _, name := range names {
		source, err := BuildWithConfig(name, p, cfg)
		if err != nil {
			return nil, err
		}
		sources = append(sources, source)
	}

	return sources, nil
}

// BuildWithConfig allows to generate a Source implementation from the shared config
func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, error) {
	switch source {
	case "service":
		client, err := p.KubeClient()
		if err != nil {
			return nil, err
		}
		return NewServiceSource(client, cfg.FQDNTemplate, cfg.Namespace, cfg.Compatibility)
	case "ingress":
		client, err := p.KubeClient()
		if err != nil {
			return nil, err
		}
		return NewIngressSource(client, cfg.FQDNTemplate, cfg.Namespace)
	case "fake":
		return NewFakeSource(cfg.FQDNTemplate)
	}
	return nil, ErrSourceNotFound
}

// NewKubeClient returns a new Kubernetes client object. It takes a Config and
// uses KubeMaster and KubeConfig attributes to connect to the cluster. If
// KubeConfig isn't provided it defaults to using the recommended default.
func NewKubeClient(kubeConfig, kubeMaster string) (*kubernetes.Clientset, error) {
	if kubeConfig == "" {
		if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil {
			kubeConfig = clientcmd.RecommendedHomeFile
		}
	}

	config, err := clientcmd.BuildConfigFromFlags(kubeMaster, kubeConfig)
	if err != nil {
		return nil, err
	}

	config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
		return instrumented_http.NewTransport(rt, &instrumented_http.Callbacks{
			PathProcessor: func(path string) string {
				parts := strings.Split(path, "/")
				return parts[len(parts)-1]
			},
		})
	}

	client, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}

	log.Infof("Connected to cluster at %s", config.Host)

	return client, nil
}
<commit_msg>fix(source): use correct order of parameters (#298)<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package source

import (
	"errors"
	"net/http"
	"os"
	"strings"

	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/linki/instrumented_http"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

// ErrSourceNotFound is returned when a requested source doesn't exist.
var ErrSourceNotFound = errors.New("source not found")

// Config holds shared configuration options for all Sources.
type Config struct {
	Namespace     string
	FQDNTemplate  string
	Compatibility string
}

// ClientGenerator provides clients
type ClientGenerator interface {
	KubeClient() (kubernetes.Interface, error)
}

// SingletonClientGenerator stores provider clients and guarantees that only one instance of client
// will be generated
type SingletonClientGenerator struct {
	KubeConfig string
	KubeMaster string
	client     kubernetes.Interface
	sync.Once
}

// KubeClient generates a kube client if it was not created before
func (p *SingletonClientGenerator) KubeClient() (kubernetes.Interface, error) {
	var err error
	p.Once.Do(func() {
		p.client, err = NewKubeClient(p.KubeConfig, p.KubeMaster)
	})
	return p.client, err
}

// ByNames returns multiple Sources given multiple names.
func ByNames(p ClientGenerator, names []string, cfg *Config) ([]Source, error) {
	sources := []Source{}
	for _, name := range names {
		source, err := BuildWithConfig(name, p, cfg)
		if err != nil {
			return nil, err
		}
		sources = append(sources, source)
	}

	return sources, nil
}

// BuildWithConfig allows to generate a Source implementation from the shared config
func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, error) {
	switch source {
	case "service":
		client, err := p.KubeClient()
		if err != nil {
			return nil, err
		}
		return NewServiceSource(client, cfg.Namespace, cfg.FQDNTemplate, cfg.Compatibility)
	case "ingress":
		client, err := p.KubeClient()
		if err != nil {
			return nil, err
		}
		return NewIngressSource(client, cfg.Namespace, cfg.FQDNTemplate)
	case "fake":
		return NewFakeSource(cfg.FQDNTemplate)
	}
	return nil, ErrSourceNotFound
}

// NewKubeClient returns a new Kubernetes client object. It takes a Config and
// uses KubeMaster and KubeConfig attributes to connect to the cluster. If
// KubeConfig isn't provided it defaults to using the recommended default.
func NewKubeClient(kubeConfig, kubeMaster string) (*kubernetes.Clientset, error) {
	if kubeConfig == "" {
		if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil {
			kubeConfig = clientcmd.RecommendedHomeFile
		}
	}

	config, err := clientcmd.BuildConfigFromFlags(kubeMaster, kubeConfig)
	if err != nil {
		return nil, err
	}

	config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
		return instrumented_http.NewTransport(rt, &instrumented_http.Callbacks{
			PathProcessor: func(path string) string {
				parts := strings.Split(path, "/")
				return parts[len(parts)-1]
			},
		})
	}

	client, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}

	log.Infof("Connected to cluster at %s", config.Host)

	return client, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/yunge/sphinx"
	"github.com/yvasiyarov/newrelic_platform_go"
	"strconv"
	"time"
        "flag"
        "log"
)

var sphinxPort = flag.Int("sphinx-port", 9312, "Sphinx port")
var sphinxHost = flag.String("sphinx-host", "127.0.0.1", "Sphinx host")

var newrelicLicense = flag.String("newrelic-license", "", "Newrelic license")

var verbose = flag.Bool("verbose", false, "Verbose mode")

const (
	MIN_PAUSE_TIME = 30           //do not query sphinx often than once in 30 seconds
        SPHINX_CONNECTION_TIMEOUT = 0 //no timeout
        NEWRELIC_POLL_INTERVAL = 60   //Send data to newrelic every 60 seconds

        COMPONENT_NAME = "Sphinx"
        AGENT_GUID = "com.github.yvasiyarov.Sphinx"
        AGENT_VERSION = "0.0.1"
)

type SphinxStatusData map[string]string
type MetricsDataSource struct {
	SphinxHost        string
	Port              int
	ConnectionTimeout int

	PreviousData   SphinxStatusData
	LastData       SphinxStatusData
	LastUpdateTime time.Time
}

func NewMetricsDataSource(sphinxHost string, port int, connectionTimeout int) *MetricsDataSource {
	ds := &MetricsDataSource{
		SphinxHost:        sphinxHost,
		Port:              port,
		ConnectionTimeout: connectionTimeout,
	}
	return ds
}

func (ds *MetricsDataSource) CheckAndGetData(key string) (float64, error) {
	if err := ds.CheckAndUpdateData(); err != nil {
		return 0, err
	}

	prev, last, err := ds.GetOriginalData(key)

	if err != nil {
		return 0, err
	}
	return last - prev, nil
}
func (ds *MetricsDataSource) CheckAndGetLastData(key string) (float64, error) {
	if err := ds.CheckAndUpdateData(); err != nil {
		return 0, err
	}

	_, last, err := ds.GetOriginalData(key)

	if err != nil {
		return 0, err
	}
	return last, nil
}

func (ds *MetricsDataSource) GetOriginalData(key string) (float64, float64, error) {
	previousValue, ok := ds.PreviousData[key]
	if !ok {
		return 0, 0, fmt.Errorf("Can not get data from source \n")
	}
	currentValue, ok := ds.LastData[key]
	if !ok {
		return 0, 0, fmt.Errorf("Can not get data from source \n")
	}

	//some metric calculation can be turned off by sphinx settings
	if previousValue == "OFF" || currentValue == "OFF" {
		return 0, 0, nil
	}

	previousValueConverted, err := strconv.ParseFloat(previousValue, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("Can not convert previous value of %s to int \n", key)
	}
	currentValueConverted, err := strconv.ParseFloat(currentValue, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("Can not convert current value of %s to int \n", key)
	}

	return previousValueConverted, currentValueConverted, nil
}

func (ds *MetricsDataSource) CheckAndUpdateData() error {
	startTime := time.Now()
	if startTime.Sub(ds.LastUpdateTime) > time.Second*MIN_PAUSE_TIME {
		newData, err := ds.QueryData()
		if err != nil {
			return err
		}

		if ds.PreviousData == nil {
			ds.PreviousData = newData
		} else {
			ds.PreviousData = ds.LastData
		}
		ds.LastData = newData
		ds.LastUpdateTime = startTime
	}

	// check uptime
	//If uptime is less then in previous run - then server were restarted
	if prev, last, err := ds.GetOriginalData("uptime"); err != nil {
		return err
	} else {
		if last < prev {
			ds.PreviousData = ds.LastData
		}
	}
	return nil
}

func (ds *MetricsDataSource) QueryData() (SphinxStatusData, error) {
	client := sphinx.NewClient().SetServer(ds.SphinxHost, ds.Port)

	if ds.ConnectionTimeout != 0 {
		client.SetConnectTimeout(ds.ConnectionTimeout)
	}
	if err := client.Error(); err != nil {
		return nil, err
	}

	defer client.Close()
	status, err := client.Status()
	if err != nil {
		return nil, err
	}

	data := make(SphinxStatusData, len(status))
	for _, row := range status {
		data[row[0]] = row[1]
	}

	return data, nil
}

type Metrica struct {
	Name       string
	Units      string
	DataKey    string
	DataSource *MetricsDataSource
}

func (metrica *Metrica) GetName() string {
	return metrica.Name
}
func (metrica *Metrica) GetUnits() string {
	return metrica.Units
}
func (metrica *Metrica) GetValue() (float64, error) {
	return metrica.DataSource.CheckAndGetData(metrica.DataKey)
}

type AvgMetrica struct {
	Metrica
}

func (metrica *AvgMetrica) GetValue() (float64, error) {
	return metrica.DataSource.CheckAndGetLastData(metrica.DataKey)
}

func AddMetrcas(component newrelic_platform_go.IComponent, dataSource *MetricsDataSource) {
	metricas := []*Metrica{
		&Metrica{
			DataKey: "queries",
			Name:    "Queries",
			Units:   "Queries/second",
		},
		&Metrica{
			DataKey: "connections",
			Name:    "Connections",
			Units:   "connections/second",
		},
		&Metrica{
			DataKey: "maxed_out",
			Name:    "Maxed out",
			Units:   "connections/second",
		},
		&Metrica{
			DataKey: "command_search",
			Name:    "Command search",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_excerpt",
			Name:    "Command excerpt",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_update",
			Name:    "Command update",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_keywords",
			Name:    "Command keywords",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_persist",
			Name:    "Command persist",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_flushattrs",
			Name:    "Command flushattrs",
			Units:   "command/second",
		},
	}
	for _, m := range metricas {
		m.DataSource = dataSource
		component.AddMetrica(m)
	}

	avgQueryWallTime := &AvgMetrica{
		Metrica{
			DataKey: "avg_query_wall",
			Name:    "Avg Query Wall Time",
			Units:   "milisecond",
		},
	}
	avgQueryWallTime.DataSource = dataSource
	component.AddMetrica(avgQueryWallTime)
}

func main() {
        flag.Parse()
        if *newrelicLicense == "" {
            log.Fatalf("Please, pass a valid newrelic license key.\n Use --help to get more information about available options\n")
        }

	plugin := newrelic_platform_go.NewNewrelicPlugin(AGENT_VERSION, *newrelicLicense, NEWRELIC_POLL_INTERVAL)
	component := newrelic_platform_go.NewPluginComponent(COMPONENT_NAME, AGENT_GUID)
	plugin.AddComponent(component)

	ds := NewMetricsDataSource(*sphinxHost, *sphinxPort, SPHINX_CONNECTION_TIMEOUT)
	AddMetrcas(component, ds)

	plugin.Verbose = *verbose
	plugin.Run()
}
<commit_msg>Fix formatting<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/yunge/sphinx"
	"github.com/yvasiyarov/newrelic_platform_go"
	"log"
	"strconv"
	"time"
)

var sphinxPort = flag.Int("sphinx-port", 9312, "Sphinx port")
var sphinxHost = flag.String("sphinx-host", "127.0.0.1", "Sphinx host")

var newrelicLicense = flag.String("newrelic-license", "", "Newrelic license")

var verbose = flag.Bool("verbose", false, "Verbose mode")

const (
	MIN_PAUSE_TIME            = 30 //do not query sphinx often than once in 30 seconds
	SPHINX_CONNECTION_TIMEOUT = 0  //no timeout
	NEWRELIC_POLL_INTERVAL    = 60 //Send data to newrelic every 60 seconds

	COMPONENT_NAME = "Sphinx"
	AGENT_GUID     = "com.github.yvasiyarov.Sphinx"
	AGENT_VERSION  = "0.0.1"
)

type SphinxStatusData map[string]string
type MetricsDataSource struct {
	SphinxHost        string
	Port              int
	ConnectionTimeout int

	PreviousData   SphinxStatusData
	LastData       SphinxStatusData
	LastUpdateTime time.Time
}

func NewMetricsDataSource(sphinxHost string, port int, connectionTimeout int) *MetricsDataSource {
	ds := &MetricsDataSource{
		SphinxHost:        sphinxHost,
		Port:              port,
		ConnectionTimeout: connectionTimeout,
	}
	return ds
}

func (ds *MetricsDataSource) CheckAndGetData(key string) (float64, error) {
	if err := ds.CheckAndUpdateData(); err != nil {
		return 0, err
	}

	prev, last, err := ds.GetOriginalData(key)

	if err != nil {
		return 0, err
	}
	return last - prev, nil
}
func (ds *MetricsDataSource) CheckAndGetLastData(key string) (float64, error) {
	if err := ds.CheckAndUpdateData(); err != nil {
		return 0, err
	}

	_, last, err := ds.GetOriginalData(key)

	if err != nil {
		return 0, err
	}
	return last, nil
}

func (ds *MetricsDataSource) GetOriginalData(key string) (float64, float64, error) {
	previousValue, ok := ds.PreviousData[key]
	if !ok {
		return 0, 0, fmt.Errorf("Can not get data from source \n")
	}
	currentValue, ok := ds.LastData[key]
	if !ok {
		return 0, 0, fmt.Errorf("Can not get data from source \n")
	}

	//some metric calculation can be turned off by sphinx settings
	if previousValue == "OFF" || currentValue == "OFF" {
		return 0, 0, nil
	}

	previousValueConverted, err := strconv.ParseFloat(previousValue, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("Can not convert previous value of %s to int \n", key)
	}
	currentValueConverted, err := strconv.ParseFloat(currentValue, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("Can not convert current value of %s to int \n", key)
	}

	return previousValueConverted, currentValueConverted, nil
}

func (ds *MetricsDataSource) CheckAndUpdateData() error {
	startTime := time.Now()
	if startTime.Sub(ds.LastUpdateTime) > time.Second*MIN_PAUSE_TIME {
		newData, err := ds.QueryData()
		if err != nil {
			return err
		}

		if ds.PreviousData == nil {
			ds.PreviousData = newData
		} else {
			ds.PreviousData = ds.LastData
		}
		ds.LastData = newData
		ds.LastUpdateTime = startTime
	}

	// check uptime
	//If uptime is less then in previous run - then server were restarted
	if prev, last, err := ds.GetOriginalData("uptime"); err != nil {
		return err
	} else {
		if last < prev {
			ds.PreviousData = ds.LastData
		}
	}
	return nil
}

func (ds *MetricsDataSource) QueryData() (SphinxStatusData, error) {
	client := sphinx.NewClient().SetServer(ds.SphinxHost, ds.Port)

	if ds.ConnectionTimeout != 0 {
		client.SetConnectTimeout(ds.ConnectionTimeout)
	}
	if err := client.Error(); err != nil {
		return nil, err
	}

	defer client.Close()
	status, err := client.Status()
	if err != nil {
		return nil, err
	}

	data := make(SphinxStatusData, len(status))
	for _, row := range status {
		data[row[0]] = row[1]
	}

	return data, nil
}

type Metrica struct {
	Name       string
	Units      string
	DataKey    string
	DataSource *MetricsDataSource
}

func (metrica *Metrica) GetName() string {
	return metrica.Name
}
func (metrica *Metrica) GetUnits() string {
	return metrica.Units
}
func (metrica *Metrica) GetValue() (float64, error) {
	return metrica.DataSource.CheckAndGetData(metrica.DataKey)
}

type AvgMetrica struct {
	Metrica
}

func (metrica *AvgMetrica) GetValue() (float64, error) {
	return metrica.DataSource.CheckAndGetLastData(metrica.DataKey)
}

func AddMetrcas(component newrelic_platform_go.IComponent, dataSource *MetricsDataSource) {
	metricas := []*Metrica{
		&Metrica{
			DataKey: "queries",
			Name:    "Queries",
			Units:   "Queries/second",
		},
		&Metrica{
			DataKey: "connections",
			Name:    "Connections",
			Units:   "connections/second",
		},
		&Metrica{
			DataKey: "maxed_out",
			Name:    "Maxed out",
			Units:   "connections/second",
		},
		&Metrica{
			DataKey: "command_search",
			Name:    "Command search",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_excerpt",
			Name:    "Command excerpt",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_update",
			Name:    "Command update",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_keywords",
			Name:    "Command keywords",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_persist",
			Name:    "Command persist",
			Units:   "command/second",
		},
		&Metrica{
			DataKey: "command_flushattrs",
			Name:    "Command flushattrs",
			Units:   "command/second",
		},
	}
	for _, m := range metricas {
		m.DataSource = dataSource
		component.AddMetrica(m)
	}

	avgQueryWallTime := &AvgMetrica{
		Metrica{
			DataKey: "avg_query_wall",
			Name:    "Avg Query Wall Time",
			Units:   "milisecond",
		},
	}
	avgQueryWallTime.DataSource = dataSource
	component.AddMetrica(avgQueryWallTime)
}

func main() {
	flag.Parse()
	if *newrelicLicense == "" {
		log.Fatalf("Please, pass a valid newrelic license key.\n Use --help to get more information about available options\n")
	}

	plugin := newrelic_platform_go.NewNewrelicPlugin(AGENT_VERSION, *newrelicLicense, NEWRELIC_POLL_INTERVAL)
	component := newrelic_platform_go.NewPluginComponent(COMPONENT_NAME, AGENT_GUID)
	plugin.AddComponent(component)

	ds := NewMetricsDataSource(*sphinxHost, *sphinxPort, SPHINX_CONNECTION_TIMEOUT)
	AddMetrcas(component, ds)

	plugin.Verbose = *verbose
	plugin.Run()
}
<|endoftext|>


<commit_before>// Copyright 2014 Brian J. Downs
//
// 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 spinner

import (
	"reflect"
	"testing"
	"time"
)

// TestNew verifies that the returned instance is of the proper type
func TestNew(t *testing.T) {
	s := New(CharSets[1], 1*time.Second)
	if reflect.TypeOf(s).String() != "*spinner.Spinner" {
		t.Error("New returned incorrect type")
	}
}

// TestStart will verify a spinner can be started
func TestStart(t *testing.T) {
	s := New(CharSets[25], 500*time.Millisecond)
	s.Start()
	time.Sleep(6 * time.Second)
	s.Stop()
	s = nil
}

// TestStop will verify a spinner can be stopped
func TestStop(t *testing.T) {
	p := New(CharSets[14], 500*time.Millisecond)
	p.Start()
	time.Sleep(6 * time.Second)
	p.Stop()
	p = nil
}

// TestRestart will verify a spinner can be stopped and started again
func TestRestart(t *testing.T) {
	s := New(CharSets[4], 1*time.Second)
	s.Start()
	time.Sleep(2 * time.Second)
	s.Restart()
	time.Sleep(2 * time.Second)
	s.Stop()
	s = nil
}

// TestReverse will verify that the given spinner can stop and start again reversed
func TestReverse(t *testing.T) {
	a := New(CharSets[10], 1*time.Second)
	a.Start()
	time.Sleep(6 * time.Second)
	a.Reverse()
	a.Restart()
	time.Sleep(6 * time.Second)
	a.Reverse()
	a.Restart()
	time.Sleep(6 * time.Second)
	a.Stop()
	a = nil
}

// TestUpdateSpeed verifies that the delay can be updated
func TestUpdateSpeed(t *testing.T) {
	s := New(CharSets[10], 1*time.Second)
	delay1 := s.Delay
	s.UpdateSpeed(3 * time.Second)
	delay2 := s.Delay
	if delay1 == delay2 {
		t.Error("update of speed failed")
	}
	s = nil
}

// TestUpdateCharSet verifies that character sets can be updated
func TestUpdateCharSet(t *testing.T) {
	s := New(CharSets[14], 1*time.Second)
	charSet1 := s.chars
	s.UpdateCharSet(CharSets[1])
	charSet2 := s.chars
	for i := range charSet1 {
		if charSet1[i] == charSet2[i] {
			t.Error("update of char set failed")
		}
	}
	s = nil
}

// TestGenerateNumberSequence verifies that a string slice of a spefic size is returned
func TestGenerateNumberSequence(t *testing.T) {
	elementCount := 100
	seq := GenerateNumberSequence(elementCount)
	if reflect.TypeOf(seq).String() != "[]string" {
		t.Error("received incorrect type in return from GenerateNumberSequence")
	}
	if len(seq) != elementCount {
		t.Error("number of elements in slice doesn't match expected count")
	}
}
<commit_msg>update test spinner speed.<commit_after>// Copyright 2014 Brian J. Downs
//
// 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 spinner

import (
	"reflect"
	"testing"
	"time"
)

// TestNew verifies that the returned instance is of the proper type
func TestNew(t *testing.T) {
	s := New(CharSets[1], 1*time.Second)
	if reflect.TypeOf(s).String() != "*spinner.Spinner" {
		t.Error("New returned incorrect type")
	}
}

// TestStart will verify a spinner can be started
func TestStart(t *testing.T) {
	s := New(CharSets[25], 100*time.Millisecond)
	s.Start()
	time.Sleep(6 * time.Second)
	s.Stop()
	s = nil
}

// TestStop will verify a spinner can be stopped
func TestStop(t *testing.T) {
	p := New(CharSets[14], 100*time.Millisecond)
	p.Start()
	time.Sleep(6 * time.Second)
	p.Stop()
	p = nil
}

// TestRestart will verify a spinner can be stopped and started again
func TestRestart(t *testing.T) {
	s := New(CharSets[4], 1*time.Second)
	s.Start()
	time.Sleep(2 * time.Second)
	s.Restart()
	time.Sleep(2 * time.Second)
	s.Stop()
	s = nil
}

// TestReverse will verify that the given spinner can stop and start again reversed
func TestReverse(t *testing.T) {
	a := New(CharSets[10], 1*time.Second)
	a.Start()
	time.Sleep(6 * time.Second)
	a.Reverse()
	a.Restart()
	time.Sleep(6 * time.Second)
	a.Reverse()
	a.Restart()
	time.Sleep(6 * time.Second)
	a.Stop()
	a = nil
}

// TestUpdateSpeed verifies that the delay can be updated
func TestUpdateSpeed(t *testing.T) {
	s := New(CharSets[10], 1*time.Second)
	delay1 := s.Delay
	s.UpdateSpeed(3 * time.Second)
	delay2 := s.Delay
	if delay1 == delay2 {
		t.Error("update of speed failed")
	}
	s = nil
}

// TestUpdateCharSet verifies that character sets can be updated
func TestUpdateCharSet(t *testing.T) {
	s := New(CharSets[14], 1*time.Second)
	charSet1 := s.chars
	s.UpdateCharSet(CharSets[1])
	charSet2 := s.chars
	for i := range charSet1 {
		if charSet1[i] == charSet2[i] {
			t.Error("update of char set failed")
		}
	}
	s = nil
}

// TestGenerateNumberSequence verifies that a string slice of a spefic size is returned
func TestGenerateNumberSequence(t *testing.T) {
	elementCount := 100
	seq := GenerateNumberSequence(elementCount)
	if reflect.TypeOf(seq).String() != "[]string" {
		t.Error("received incorrect type in return from GenerateNumberSequence")
	}
	if len(seq) != elementCount {
		t.Error("number of elements in slice doesn't match expected count")
	}
}
<|endoftext|>


<commit_before>package webpack

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/gobuffalo/buffalo/generators"
	"github.com/gobuffalo/buffalo/generators/assets"
	"github.com/gobuffalo/buffalo/generators/assets/standard"
	"github.com/gobuffalo/makr"
	"github.com/pkg/errors"
)

var logo = &makr.RemoteFile{
	File:       makr.NewFile("assets/images/logo.svg", ""),
	RemotePath: assets.LogoURL,
}

// BinPath is the path to the local install of webpack
var BinPath = filepath.Join("node_modules", ".bin", "webpack")

// New webpack generator
func New(data makr.Data) (*makr.Generator, error) {
	g := makr.New()

	// if there's no npm, return!
	_, err := exec.LookPath("npm")
	if err != nil {
		fmt.Println("Could not find npm/node. Skipping webpack generation.")

		wg, err := standard.New(data)
		if err != nil {
			return g, errors.WithStack(err)
		}
		return wg, nil
	}

	command := "npm"
	args := []string{"install", "--no-progress", "--save"}
	// If yarn.lock exists then yarn is used by default (generate webpack)
	_, ferr := os.Stat("yarn.lock")
	if ferr == nil {
		data["withYarn"] = true
	}

	if _, ok := data["withYarn"]; ok {
		command = "yarn"
		args = []string{"add"}
		err := generateYarn(data)
		if err != nil {
			return g, err
		}
	}

	g.Add(logo)

	files, err := generators.Find(filepath.Join("assets", "webpack"))
	if err != nil {
		return g, err
	}

	for _, f := range files {
		g.Add(makr.NewFile(f.WritePath, f.Body))
	}

	c := makr.NewCommand(exec.Command(command, "init", "-y"))
	g.Add(c)

	modules := []string{"webpack@~2.3.0", "sass-loader", "css-loader", "style-loader", "node-sass",
		"extract-text-webpack-plugin@2.1.2", "babel-cli", "babel-core", "babel-preset-env", "babel-loader", "url-loader",
		"file-loader", "jquery", "bootstrap", "path", "font-awesome", "npm-install-webpack-plugin", "jquery-ujs",
		"copy-webpack-plugin", "expose-loader", "uglifyjs-webpack-plugin@~0.4.6",
	}

	args = append(args, modules...)
	g.Add(makr.NewCommand(exec.Command(command, args...)))
	return g, nil
}

func generateYarn(data makr.Data) error {
	// if there's no yarn, install it!
	_, err := exec.LookPath("yarn")
	// A new makr is necessary to have yarn available in path
	if err != nil {
		yg := makr.New()
		yargs := []string{"install", "-g", "yarn"}
		yg.Add(makr.NewCommand(exec.Command("npm", yargs...)))
		err = yg.Run(".", data)
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>adding versions to the NPM packages<commit_after>package webpack

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/gobuffalo/buffalo/generators"
	"github.com/gobuffalo/buffalo/generators/assets"
	"github.com/gobuffalo/buffalo/generators/assets/standard"
	"github.com/gobuffalo/makr"
	"github.com/pkg/errors"
)

var logo = &makr.RemoteFile{
	File:       makr.NewFile("assets/images/logo.svg", ""),
	RemotePath: assets.LogoURL,
}

// BinPath is the path to the local install of webpack
var BinPath = filepath.Join("node_modules", ".bin", "webpack")

// New webpack generator
func New(data makr.Data) (*makr.Generator, error) {
	g := makr.New()

	// if there's no npm, return!
	_, err := exec.LookPath("npm")
	if err != nil {
		fmt.Println("Could not find npm/node. Skipping webpack generation.")

		wg, err := standard.New(data)
		if err != nil {
			return g, errors.WithStack(err)
		}
		return wg, nil
	}

	command := "npm"
	args := []string{"install", "--no-progress", "--save"}
	// If yarn.lock exists then yarn is used by default (generate webpack)
	_, ferr := os.Stat("yarn.lock")
	if ferr == nil {
		data["withYarn"] = true
	}

	if _, ok := data["withYarn"]; ok {
		command = "yarn"
		args = []string{"add"}
		err := generateYarn(data)
		if err != nil {
			return g, err
		}
	}

	g.Add(logo)

	files, err := generators.Find(filepath.Join("assets", "webpack"))
	if err != nil {
		return g, err
	}

	for _, f := range files {
		g.Add(makr.NewFile(f.WritePath, f.Body))
	}

	c := makr.NewCommand(exec.Command(command, "init", "-y"))
	g.Add(c)

	modules := []string{
		"webpack@~2.3.0",
		"sass-loader@~6.0.5",
		"css-loader@~0.28.4",
		"expose-loader@~0.7.3",
		"style-loader@~0.18.2",
		"node-sass@~4.5.3",
		"extract-text-webpack-plugin@2.1.2",
		"babel-cli@~6.24.1",
		"babel-core@~6.25.0",
		"babel-preset-env@~1.5.2",
		"babel-loader@~7.0.0",
		"url-loader@~0.5.9",
		"file-loader@~0.11.2",
		"jquery@~3.2.1",
		"bootstrap@~3.3.7",
		"path@~0.12.7",
		"font-awesome@~4.7.0",
		"npm-install-webpack-plugin@4.0.4",
		"jquery-ujs@~1.2.2",
		"copy-webpack-plugin@~4.0.1",
		"uglifyjs-webpack-plugin@~0.4.6",
	}

	args = append(args, modules...)
	g.Add(makr.NewCommand(exec.Command(command, args...)))
	return g, nil
}

func generateYarn(data makr.Data) error {
	// if there's no yarn, install it!
	_, err := exec.LookPath("yarn")
	// A new makr is necessary to have yarn available in path
	if err != nil {
		yg := makr.New()
		yargs := []string{"install", "-g", "yarn"}
		yg.Add(makr.NewCommand(exec.Command("npm", yargs...)))
		err = yg.Run(".", data)
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Package vsafedb handles storing instances in the vsafe app to persistent
// storage.
package vsafedb

import (
  "errors"
  "github.com/keep94/appcommon/db"
  "github.com/keep94/appcommon/str_util"
  "github.com/keep94/goconsume"
  "github.com/keep94/vsafe"
  "sort"
  "strings"
)

var (
  // Indicates that the id does not exist in the database.
  ErrNoSuchId = errors.New("vsafedb: No such Id.")
  // Indicates concurrent modification
  ErrConcurrentModification = errors.New("vsafedb: Concurrent Modification")
)

type AddUserRunner interface {
  // AddUser adds a new user to persistent storage.
  AddUser(t db.Transaction, user *vsafe.User) error
}

type UserByIdRunner interface {
  // UserById retrieves a user by id from persistent storage.
  UserById(t db.Transaction, id int64, user *vsafe.User) error
}

type UserByNameRunner interface {
  // UserByName retrieves a user by name from persistent storage.
  UserByName(t db.Transaction, name string, user *vsafe.User) error
}

type UsersRunner interface {
  // Users retrieves all users from persistent storage ordered by name.
  Users(t db.Transaction, consumer goconsume.Consumer) error
}

type UpdateUserRunner interface {
  // UpdateUser modifies a user in persistent storage.
  UpdateUser(t db.Transaction, user *vsafe.User) error
}

type SafeUpdateUserRunner interface {
  UpdateUserRunner
  UserByIdRunner
}

type RemoveUserRunner interface {
  // RemoveUser removes a user by name from persistent storage.
  RemoveUser(t db.Transaction, name string) error
}

type AddCategoryRunner interface {
  // AddCategory adds a new category to persistent storage
  AddCategory(t db.Transaction, category *vsafe.Category) error
}

type CategoryByIdRunner interface {
  // CategoryById retrieves category with given id.
  CategoryById(t db.Transaction, id int64, category *vsafe.Category) error
}

type CategoriesByOwnerRunner interface {
  // CategoriesByOwner retrieves all categories with a particular owner
  // from persistent storage ordered by category name.
  CategoriesByOwner(
      t db.Transaction, owner int64) ([]vsafe.Category, error)
}

type UpdateCategoryRunner interface {
  // UpdateCategory updates a category.
  UpdateCategory(t db.Transaction, category *vsafe.Category) error
}

type SafeUpdateCategoryRunner interface {
  CategoryByIdRunner
  UpdateCategoryRunner
}

type RemoveCategoryRunner interface {
  // RemoveCategory removes a category with given id from
  // persistent storage.
  RemoveCategory(t db.Transaction, id int64) error
}

type SafeRemoveCategoryRunner interface {
  CategoryByIdRunner
  RemoveCategoryRunner
}

type AddEntryRunner interface {
  // AddEntry adds a new entry to persistent storage.
  AddEntry(t db.Transaction, entry *vsafe.Entry) error
}

type EntryByIdRunner interface {
  // EntryById retrieves an entry by id from persistent storage.
  EntryById(t db.Transaction, id int64, entry *vsafe.Entry) error
}

type EntriesByOwnerRunner interface {
  // EntriesByOwner retrieves all entries with a particular owner from
  // persistent storage ordered by Id.
  EntriesByOwner(t db.Transaction, owner int64, consumer goconsume.Consumer) error
}

type UpdateEntryRunner interface {
  // UpdateEntry updates an entry in persistent storage.
  UpdateEntry(t db.Transaction, entry *vsafe.Entry) error
}

type SafeUpdateEntryRunner interface {
  UpdateEntryRunner
  EntryByIdRunner
}

type RemoveEntryRunner interface {
  // RemoveEntry removes an entry with given id and owner from persistent
  // storage.
  RemoveEntry(t db.Transaction, id, owner int64) error
}

// UpdateCategory updates a category name by id and owner. t must be non-nil.
func UpdateCategory(
    store SafeUpdateCategoryRunner,
    t db.Transaction,
    id, owner int64,
    newName string) (oldName string, err error) {
  if t == nil {
    panic("t must be non-nil")
  }
  var category vsafe.Category
  err = store.CategoryById(t, id, &category)
  if err != nil {
    return
  }
  if owner != category.Owner {
    return "", ErrNoSuchId
  }
  lastName := category.Name
  category.Name = newName
  err = store.UpdateCategory(t, &category)
  if err != nil {
    return
  }
  return lastName, nil
}

// RemoveCategory removes a category by id and owner. t must be non-nil.
func RemoveCategory(
    store SafeRemoveCategoryRunner,
    t db.Transaction,
    id, owner int64) (oldName string, err error) {
  if t == nil {
    panic("t must be non-nil")
  }
  var category vsafe.Category
  err = store.CategoryById(t, id, &category)
  if err != nil {
    return
  }
  if owner != category.Owner {
    return "", ErrNoSuchId
  }
  lastName := category.Name
  err = store.RemoveCategory(t, id)
  if err != nil {
    return
  }
  return lastName, nil
}

// AddEntry adds a new entry to persistent storage so that sensitive fields
// are encrypted in persistent storage.
func AddEntry(
    store AddEntryRunner,
    t db.Transaction,
    key *vsafe.Key,
    entry *vsafe.Entry) (newId int64, err error) {
  encrypted := *entry
  if err = encrypted.Encrypt(key); err != nil {
    return
  }
  if err = store.AddEntry(t, &encrypted); err != nil {
    return
  }
  return encrypted.Id, nil
}

// UpdateEntryWithEtag updates an entry in persistent storage in a way that
// detects concurrent modification. It also prevents users from modifying
// entries they do not own by returning ErrNoSuchId. t, the transaction,
// must be non nil.
func UpdateEntryWithEtag(
    store SafeUpdateEntryRunner,
    t db.Transaction,
    id int64,
    tag uint64,
    key *vsafe.Key,
    update goconsume.FilterFunc) error {
  if t == nil {
    panic("Transaction must be non-nil")
  }
  var origEntry vsafe.Entry
  err := EntryById(store, t, id, key, &origEntry)
  if err != nil {
   return err
  }
  etag := origEntry.Etag
  if !update(&origEntry) {
    return nil
  }
  if tag != etag {
    return ErrConcurrentModification
  }
  origEntry.Id = id
  return UpdateEntry(store, t, key, &origEntry)
}

// UpdateEntry updates an entry in persistent storage so that sensitive fields
// remain encrypted in persistent storage. Beware: UpdateEntry does not
// protect against concurrent modification nor does it protect against
// users clobbering an entry they do not own.
func UpdateEntry(
    store UpdateEntryRunner,
    t db.Transaction,
    key *vsafe.Key,
    entry *vsafe.Entry) (err error) {
  encrypted := *entry
  if err = encrypted.Encrypt(key); err != nil {
    return
  }
  if err = store.UpdateEntry(t, &encrypted); err != nil {
    return
  }
  return
}

// EntryById retrieves an entry by its id from persistent storage while
// handling decryption of sensitive fields. If the Id of the provided key
// does not match the Owner field of fetched entry, that is the current user
// does not own the entry being fetched, EntryById returns ErrNoSuchId.
func EntryById(
    store EntryByIdRunner,
    t db.Transaction,
    id int64,
    key *vsafe.Key,
    entry *vsafe.Entry) (err error) {
  if err = store.EntryById(t, id, entry); err != nil {
    return
  }
  return decryptHelper(key, entry)
}

// Entries returns a new slice containing entries encrypted with keyId and
// matching query and orders them by Id. It does not decrypt the sensitive
// fields within the fetched entries. query is searched for within url,
// title, and description of each entry ignoring case to determine whether or
// not there is a match. Whitespace within query and entry fields are
// normalized to a single space before matching happens. The empty string
// matches all entries.
//
// If catId is non-zero, returned entries must belong to corresponding
// category in addition to matching query.
func Entries(
    store EntriesByOwnerRunner,
    keyId int64,
    query string,
    catId int64) ([]*vsafe.Entry, error) {
  filter := newEntryFilter(query)
  if catId != 0 {
    filter = goconsume.All(filter, newCatFilter(catId))
  }
  var results []*vsafe.Entry
  if err := store.EntriesByOwner(
      nil,
      keyId,
      goconsume.Filter(
          goconsume.AppendPtrsTo(&results),
          filter)); err != nil {
    return nil, err
  }
  return results, nil
}

// SortByTitle sorts entries by title in place ignoring case.
func SortByTitle(entries []*vsafe.Entry) {
  sort.Sort(newSortByTitle(entries))
}

// Reverse reverses entries in place.
func Reverse(entries []*vsafe.Entry) {
  start := 0
  end := len(entries) - 1
  for start < end {
    entries[start], entries[end] = entries[end], entries[start]
    start++
    end--
  }
}

// ChangePassword changes the password of a user in persistent storage.
// t, the transaction, must be non nil.
func ChangePassword(
    store SafeUpdateUserRunner,
    t db.Transaction,
    id int64,
    oldPass, newPass string) (*vsafe.User, error) {
  if t == nil {
    panic("Transaction must be non-nil")
  }
  var user vsafe.User
  err := store.UserById(t, id, &user)
  if err != nil {
    return nil, err
  }
  if err = user.ChangePassword(oldPass, newPass); err != nil {
    return nil, err
  }
  if err = store.UpdateUser(t, &user); err != nil {
    return nil, err
  }
  return &user, nil
}

func newCatFilter(cat int64) goconsume.FilterFunc {
  return func(ptr interface{}) bool {
    p := ptr.(*vsafe.Entry)
    return p.Categories.Contains(cat)
  }
}

func newEntryFilter(s string) goconsume.FilterFunc {
  s = str_util.Normalize(s)
  if s == "" {
    return goconsume.All()
  }
  pattern := s
  return func(ptr interface{}) bool {
    p := ptr.(*vsafe.Entry)
    if p.Url != nil {
      str := str_util.Normalize(p.Url.String())
      if strings.Index(str, pattern) != -1 {
        return true
      }
    }
    if strings.Index(str_util.Normalize(p.Title), pattern) != -1 {
      return true
    }
    if strings.Index(str_util.Normalize(p.Desc), pattern) != -1 {
      return true
    }
    return false
  }
}

type sortByTitle struct {
  entries []*vsafe.Entry
  trimmedLowerTitles []string
}

func newSortByTitle(entries []*vsafe.Entry) sort.Interface {
  titles := make([]string, len(entries))
  for i := range entries {
    titles[i] = strings.TrimSpace(strings.ToLower(entries[i].Title))
  }
  return &sortByTitle{entries: entries, trimmedLowerTitles: titles}
}

func (s *sortByTitle) Len() int {
  return len(s.entries)
}

func (s *sortByTitle) Less(i, j int) bool {
  return s.trimmedLowerTitles[i] < s.trimmedLowerTitles[j]
}

func (s *sortByTitle) Swap(i, j int) {
  s.entries[i], s.entries[j] = s.entries[j], s.entries[i]
  s.trimmedLowerTitles[i], s.trimmedLowerTitles[j] =
      s.trimmedLowerTitles[j], s.trimmedLowerTitles[i]
}

func decryptHelper(key *vsafe.Key, entry *vsafe.Entry) (err error) {
  if err = entry.Decrypt(key); err != nil {
    if err == vsafe.ErrKeyMismatch {
      err = ErrNoSuchId
    }
    return
  }
  return nil
}
<commit_msg>Use ModFilter instead of Filter.<commit_after>// Package vsafedb handles storing instances in the vsafe app to persistent
// storage.
package vsafedb

import (
  "errors"
  "github.com/keep94/appcommon/db"
  "github.com/keep94/appcommon/str_util"
  "github.com/keep94/goconsume"
  "github.com/keep94/vsafe"
  "sort"
  "strings"
)

var (
  // Indicates that the id does not exist in the database.
  ErrNoSuchId = errors.New("vsafedb: No such Id.")
  // Indicates concurrent modification
  ErrConcurrentModification = errors.New("vsafedb: Concurrent Modification")
)

type AddUserRunner interface {
  // AddUser adds a new user to persistent storage.
  AddUser(t db.Transaction, user *vsafe.User) error
}

type UserByIdRunner interface {
  // UserById retrieves a user by id from persistent storage.
  UserById(t db.Transaction, id int64, user *vsafe.User) error
}

type UserByNameRunner interface {
  // UserByName retrieves a user by name from persistent storage.
  UserByName(t db.Transaction, name string, user *vsafe.User) error
}

type UsersRunner interface {
  // Users retrieves all users from persistent storage ordered by name.
  Users(t db.Transaction, consumer goconsume.Consumer) error
}

type UpdateUserRunner interface {
  // UpdateUser modifies a user in persistent storage.
  UpdateUser(t db.Transaction, user *vsafe.User) error
}

type SafeUpdateUserRunner interface {
  UpdateUserRunner
  UserByIdRunner
}

type RemoveUserRunner interface {
  // RemoveUser removes a user by name from persistent storage.
  RemoveUser(t db.Transaction, name string) error
}

type AddCategoryRunner interface {
  // AddCategory adds a new category to persistent storage
  AddCategory(t db.Transaction, category *vsafe.Category) error
}

type CategoryByIdRunner interface {
  // CategoryById retrieves category with given id.
  CategoryById(t db.Transaction, id int64, category *vsafe.Category) error
}

type CategoriesByOwnerRunner interface {
  // CategoriesByOwner retrieves all categories with a particular owner
  // from persistent storage ordered by category name.
  CategoriesByOwner(
      t db.Transaction, owner int64) ([]vsafe.Category, error)
}

type UpdateCategoryRunner interface {
  // UpdateCategory updates a category.
  UpdateCategory(t db.Transaction, category *vsafe.Category) error
}

type SafeUpdateCategoryRunner interface {
  CategoryByIdRunner
  UpdateCategoryRunner
}

type RemoveCategoryRunner interface {
  // RemoveCategory removes a category with given id from
  // persistent storage.
  RemoveCategory(t db.Transaction, id int64) error
}

type SafeRemoveCategoryRunner interface {
  CategoryByIdRunner
  RemoveCategoryRunner
}

type AddEntryRunner interface {
  // AddEntry adds a new entry to persistent storage.
  AddEntry(t db.Transaction, entry *vsafe.Entry) error
}

type EntryByIdRunner interface {
  // EntryById retrieves an entry by id from persistent storage.
  EntryById(t db.Transaction, id int64, entry *vsafe.Entry) error
}

type EntriesByOwnerRunner interface {
  // EntriesByOwner retrieves all entries with a particular owner from
  // persistent storage ordered by Id.
  EntriesByOwner(t db.Transaction, owner int64, consumer goconsume.Consumer) error
}

type UpdateEntryRunner interface {
  // UpdateEntry updates an entry in persistent storage.
  UpdateEntry(t db.Transaction, entry *vsafe.Entry) error
}

type SafeUpdateEntryRunner interface {
  UpdateEntryRunner
  EntryByIdRunner
}

type RemoveEntryRunner interface {
  // RemoveEntry removes an entry with given id and owner from persistent
  // storage.
  RemoveEntry(t db.Transaction, id, owner int64) error
}

// UpdateCategory updates a category name by id and owner. t must be non-nil.
func UpdateCategory(
    store SafeUpdateCategoryRunner,
    t db.Transaction,
    id, owner int64,
    newName string) (oldName string, err error) {
  if t == nil {
    panic("t must be non-nil")
  }
  var category vsafe.Category
  err = store.CategoryById(t, id, &category)
  if err != nil {
    return
  }
  if owner != category.Owner {
    return "", ErrNoSuchId
  }
  lastName := category.Name
  category.Name = newName
  err = store.UpdateCategory(t, &category)
  if err != nil {
    return
  }
  return lastName, nil
}

// RemoveCategory removes a category by id and owner. t must be non-nil.
func RemoveCategory(
    store SafeRemoveCategoryRunner,
    t db.Transaction,
    id, owner int64) (oldName string, err error) {
  if t == nil {
    panic("t must be non-nil")
  }
  var category vsafe.Category
  err = store.CategoryById(t, id, &category)
  if err != nil {
    return
  }
  if owner != category.Owner {
    return "", ErrNoSuchId
  }
  lastName := category.Name
  err = store.RemoveCategory(t, id)
  if err != nil {
    return
  }
  return lastName, nil
}

// AddEntry adds a new entry to persistent storage so that sensitive fields
// are encrypted in persistent storage.
func AddEntry(
    store AddEntryRunner,
    t db.Transaction,
    key *vsafe.Key,
    entry *vsafe.Entry) (newId int64, err error) {
  encrypted := *entry
  if err = encrypted.Encrypt(key); err != nil {
    return
  }
  if err = store.AddEntry(t, &encrypted); err != nil {
    return
  }
  return encrypted.Id, nil
}

// UpdateEntryWithEtag updates an entry in persistent storage in a way that
// detects concurrent modification. It also prevents users from modifying
// entries they do not own by returning ErrNoSuchId. t, the transaction,
// must be non nil.
func UpdateEntryWithEtag(
    store SafeUpdateEntryRunner,
    t db.Transaction,
    id int64,
    tag uint64,
    key *vsafe.Key,
    update goconsume.FilterFunc) error {
  if t == nil {
    panic("Transaction must be non-nil")
  }
  var origEntry vsafe.Entry
  err := EntryById(store, t, id, key, &origEntry)
  if err != nil {
   return err
  }
  etag := origEntry.Etag
  if !update(&origEntry) {
    return nil
  }
  if tag != etag {
    return ErrConcurrentModification
  }
  origEntry.Id = id
  return UpdateEntry(store, t, key, &origEntry)
}

// UpdateEntry updates an entry in persistent storage so that sensitive fields
// remain encrypted in persistent storage. Beware: UpdateEntry does not
// protect against concurrent modification nor does it protect against
// users clobbering an entry they do not own.
func UpdateEntry(
    store UpdateEntryRunner,
    t db.Transaction,
    key *vsafe.Key,
    entry *vsafe.Entry) (err error) {
  encrypted := *entry
  if err = encrypted.Encrypt(key); err != nil {
    return
  }
  if err = store.UpdateEntry(t, &encrypted); err != nil {
    return
  }
  return
}

// EntryById retrieves an entry by its id from persistent storage while
// handling decryption of sensitive fields. If the Id of the provided key
// does not match the Owner field of fetched entry, that is the current user
// does not own the entry being fetched, EntryById returns ErrNoSuchId.
func EntryById(
    store EntryByIdRunner,
    t db.Transaction,
    id int64,
    key *vsafe.Key,
    entry *vsafe.Entry) (err error) {
  if err = store.EntryById(t, id, entry); err != nil {
    return
  }
  return decryptHelper(key, entry)
}

// Entries returns a new slice containing entries encrypted with keyId and
// matching query and orders them by Id. It does not decrypt the sensitive
// fields within the fetched entries. query is searched for within url,
// title, and description of each entry ignoring case to determine whether or
// not there is a match. Whitespace within query and entry fields are
// normalized to a single space before matching happens. The empty string
// matches all entries.
//
// If catId is non-zero, returned entries must belong to corresponding
// category in addition to matching query.
func Entries(
    store EntriesByOwnerRunner,
    keyId int64,
    query string,
    catId int64) ([]*vsafe.Entry, error) {
  filter := newEntryFilter(query)
  if catId != 0 {
    filter = goconsume.All(filter, newCatFilter(catId))
  }
  var results []*vsafe.Entry
  if err := store.EntriesByOwner(
      nil,
      keyId,
      goconsume.ModFilter(
          goconsume.AppendPtrsTo(&results),
          filter,
          (*vsafe.Entry)(nil))); err != nil {
    return nil, err
  }
  return results, nil
}

// SortByTitle sorts entries by title in place ignoring case.
func SortByTitle(entries []*vsafe.Entry) {
  sort.Sort(newSortByTitle(entries))
}

// Reverse reverses entries in place.
func Reverse(entries []*vsafe.Entry) {
  start := 0
  end := len(entries) - 1
  for start < end {
    entries[start], entries[end] = entries[end], entries[start]
    start++
    end--
  }
}

// ChangePassword changes the password of a user in persistent storage.
// t, the transaction, must be non nil.
func ChangePassword(
    store SafeUpdateUserRunner,
    t db.Transaction,
    id int64,
    oldPass, newPass string) (*vsafe.User, error) {
  if t == nil {
    panic("Transaction must be non-nil")
  }
  var user vsafe.User
  err := store.UserById(t, id, &user)
  if err != nil {
    return nil, err
  }
  if err = user.ChangePassword(oldPass, newPass); err != nil {
    return nil, err
  }
  if err = store.UpdateUser(t, &user); err != nil {
    return nil, err
  }
  return &user, nil
}

func newCatFilter(cat int64) goconsume.FilterFunc {
  return func(ptr interface{}) bool {
    p := ptr.(*vsafe.Entry)
    return p.Categories.Contains(cat)
  }
}

func newEntryFilter(s string) goconsume.FilterFunc {
  s = str_util.Normalize(s)
  if s == "" {
    return goconsume.All()
  }
  pattern := s
  return func(ptr interface{}) bool {
    p := ptr.(*vsafe.Entry)
    if p.Url != nil {
      str := str_util.Normalize(p.Url.String())
      if strings.Index(str, pattern) != -1 {
        return true
      }
    }
    if strings.Index(str_util.Normalize(p.Title), pattern) != -1 {
      return true
    }
    if strings.Index(str_util.Normalize(p.Desc), pattern) != -1 {
      return true
    }
    return false
  }
}

type sortByTitle struct {
  entries []*vsafe.Entry
  trimmedLowerTitles []string
}

func newSortByTitle(entries []*vsafe.Entry) sort.Interface {
  titles := make([]string, len(entries))
  for i := range entries {
    titles[i] = strings.TrimSpace(strings.ToLower(entries[i].Title))
  }
  return &sortByTitle{entries: entries, trimmedLowerTitles: titles}
}

func (s *sortByTitle) Len() int {
  return len(s.entries)
}

func (s *sortByTitle) Less(i, j int) bool {
  return s.trimmedLowerTitles[i] < s.trimmedLowerTitles[j]
}

func (s *sortByTitle) Swap(i, j int) {
  s.entries[i], s.entries[j] = s.entries[j], s.entries[i]
  s.trimmedLowerTitles[i], s.trimmedLowerTitles[j] =
      s.trimmedLowerTitles[j], s.trimmedLowerTitles[i]
}

func decryptHelper(key *vsafe.Key, entry *vsafe.Entry) (err error) {
  if err = entry.Decrypt(key); err != nil {
    if err == vsafe.ErrKeyMismatch {
      err = ErrNoSuchId
    }
    return
  }
  return nil
}
<|endoftext|>


<commit_before>package captcha

import (
	"fmt"
	_ "log"
	"net/http"
	"math/rand"
	"strconv"
	_ "strings"
	"time"
	"encoding/json"
)

type CaptchaHandler struct {
	Masks *MaskIndex
	Links []string
}

func NewCaptchaHandler() *CaptchaHandler {
	ret := CaptchaHandler{}
	ret.Masks = LoadMasks("./masks/")
	ret.Links = []string{
		"http://qyxy.baic.gov.cn/checkCodeServlet?currentTimeMillis=1396966478094",
		"http://www.tjaic.gov.cn/info/inc/checkcode.asp",
		"http://www.hebscztxyxx.gov.cn/notice/img.captcha?ra=0.420229553245008",
		"http://218.26.1.108/Manage/VerifyCode.aspx?",
		"http://www.nmgs.gov.cn:7001/aiccips/verify.html",
		"http://222.171.175.16:9080/ECPS/validateCode.jspx",
		"http://www.jsgsj.gov.cn:58888/ecipplatform/rand_img.jsp?type=2",
		"http://gsxt.zjaic.gov.cn/common/captcha/doReadKaptcha.do",
		"http://www.ahcredit.gov.cn:9090/ECPS/validateCode.jspx",
		"http://wsgs.fjaic.gov.cn/creditpub/govRandValidate",
		"http://gsxt.jxaic.gov.cn/ECPS/rand.action",
		"http://218.57.139.24/shandong/secimg",
		"http://211.141.74.198:8081/aiccips/verify.html",
		"http://gsxt.lngs.gov.cn/saicpub/jcaptcha",
		"http://gsxt.gdgs.gov.cn/verify.html",
		"http://221.232.141.250:9080/ECPS/rand.action",
		"http://gsxt.hnaic.gov.cn/VerifierImage.jpg?noCache=1396969773230",
		"http://gsxt.cqgs.gov.cn/makeCertPic.jsp",
		"http://gsxt.gzgs.gov.cn/validCode?validTag=searchImageCode&1396969875371",
		"http://220.163.86.132:88/admin/_SYSTEM/CheckCode.aspx",
		"http://117.22.252.219:8002/servlet/validateCodeServlet",
		"http://gsxt.ngsh.gov.cn/ECPS/rand.action",
		"http://www.360doc.com/VerifyCode.aspx?",
	}
	return &ret
}

func (self *CaptchaHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	link := req.FormValue("link")
	if len(link) == 0 {
		link = self.Links[rand.Intn(len(self.Links))]
	}
	chType := GetChType(req.FormValue("type"))
	format := req.FormValue("format")
	if format == "" {
		format = "html"
	}
	img := LoadImageFromURL(link, "", "")

	output := "./imgs/" + strconv.FormatInt(time.Now().UnixNano(), 10)
	SaveImage(img, output)

	predictor := NewMetaPredictor()
	results := predictor.Predict(img, self.Masks, chType)

	if format == "html" {
		html := "
"
		for _, result := range results {
			for _, component := range result.Components{
				component.Save("./unknown/" + component.Encode())
				html += " "
			}
			html += "
"
			html += result.Label + " : " + strconv.FormatFloat(result.GetWeight(), 'g', 5, 64) + "
"
		}
		html += ""
		fmt.Fprint(w, html)
	} else if format == "json" {
		output, _ := json.Marshal(results)
		fmt.Fprint(w, string(output))
	}
}
<commit_msg>move unknow files to unknow folder<commit_after>package captcha

import (
	"fmt"
	_ "log"
	"net/http"
	"math/rand"
	"strconv"
	_ "strings"
	"time"
	"encoding/json"
)

type CaptchaHandler struct {
	Masks *MaskIndex
	Links []string
}

func NewCaptchaHandler() *CaptchaHandler {
	ret := CaptchaHandler{}
	ret.Masks = LoadMasks("./masks/")
	ret.Links = []string{
		"http://qyxy.baic.gov.cn/checkCodeServlet?currentTimeMillis=1396966478094",
		"http://www.tjaic.gov.cn/info/inc/checkcode.asp",
		"http://www.hebscztxyxx.gov.cn/notice/img.captcha?ra=0.420229553245008",
		"http://218.26.1.108/Manage/VerifyCode.aspx?",
		"http://www.nmgs.gov.cn:7001/aiccips/verify.html",
		"http://222.171.175.16:9080/ECPS/validateCode.jspx",
		"http://www.jsgsj.gov.cn:58888/ecipplatform/rand_img.jsp?type=2",
		"http://gsxt.zjaic.gov.cn/common/captcha/doReadKaptcha.do",
		"http://www.ahcredit.gov.cn:9090/ECPS/validateCode.jspx",
		"http://wsgs.fjaic.gov.cn/creditpub/govRandValidate",
		"http://gsxt.jxaic.gov.cn/ECPS/rand.action",
		"http://218.57.139.24/shandong/secimg",
		"http://211.141.74.198:8081/aiccips/verify.html",
		"http://gsxt.lngs.gov.cn/saicpub/jcaptcha",
		"http://gsxt.gdgs.gov.cn/verify.html",
		"http://221.232.141.250:9080/ECPS/rand.action",
		"http://gsxt.hnaic.gov.cn/VerifierImage.jpg?noCache=1396969773230",
		"http://gsxt.cqgs.gov.cn/makeCertPic.jsp",
		"http://gsxt.gzgs.gov.cn/validCode?validTag=searchImageCode&1396969875371",
		"http://220.163.86.132:88/admin/_SYSTEM/CheckCode.aspx",
		"http://117.22.252.219:8002/servlet/validateCodeServlet",
		"http://gsxt.ngsh.gov.cn/ECPS/rand.action",
		"http://www.360doc.com/VerifyCode.aspx?",
	}
	return &ret
}

func (self *CaptchaHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	link := req.FormValue("link")
	if len(link) == 0 {
		link = self.Links[rand.Intn(len(self.Links))]
	}
	chType := GetChType(req.FormValue("type"))
	format := req.FormValue("format")
	if format == "" {
		format = "html"
	}
	img := LoadImageFromURL(link, "", "")

	output := "./imgs/" + strconv.FormatInt(time.Now().UnixNano(), 10)
	SaveImage(img, output)

	predictor := NewMetaPredictor()
	results := predictor.Predict(img, self.Masks, chType)

	if format == "html" {
		html := "
"
		for _, result := range results {
			for _, component := range result.Components{
				component.Save("./unknown/" + component.Encode())
				html += " "
			}
			html += "
"
			html += result.Label + " : " + strconv.FormatFloat(result.GetWeight(), 'g', 5, 64) + "
"
		}
		html += ""
		fmt.Fprint(w, html)
	} else if format == "json" {
		output, _ := json.Marshal(results)
		fmt.Fprint(w, string(output))
	}
}
<|endoftext|>


<commit_before>// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2009 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 main

import "runtime"

const	N	= 1000;		// sent messages
const	M	= 10;		// receiving goroutines
const	W	= 2;		// channel buffering
var	h	[N]int;		// marking of send/recv

func
r(c chan int, m int) {
	for {
		select {
		case r := <- c:
			if h[r] != 1 {
				panicln("r",
					"m=", m,
					"r=", r,
					"h=", h[r],
				);
			}
			h[r] = 2;
		}
	}
}

func
s(c chan int) {
	for n:=0; n<N; n++ {
		r := n;
		if h[r] != 0 {
			panicln("s");
		}
		h[r] = 1;
		c <- r;
	}
}

func
main() {
	c := make(chan int, W);
	for m:=0; m<M; m++ {
		go r(c, m);
		runtime.Gosched();
	}
	runtime.Gosched();
	runtime.Gosched();
	s(c);
}
<commit_msg>trailing comma's are not accepted with current syntax<commit_after>// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2009 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 main

import "runtime"

const	N	= 1000;		// sent messages
const	M	= 10;		// receiving goroutines
const	W	= 2;		// channel buffering
var	h	[N]int;		// marking of send/recv

func
r(c chan int, m int) {
	for {
		select {
		case r := <- c:
			if h[r] != 1 {
				panicln("r",
					"m=", m,
					"r=", r,
					"h=", h[r]);
			}
			h[r] = 2;
		}
	}
}

func
s(c chan int) {
	for n:=0; n<N; n++ {
		r := n;
		if h[r] != 0 {
			panicln("s");
		}
		h[r] = 1;
		c <- r;
	}
}

func
main() {
	c := make(chan int, W);
	for m:=0; m<M; m++ {
		go r(c, m);
		runtime.Gosched();
	}
	runtime.Gosched();
	runtime.Gosched();
	s(c);
}
<|endoftext|>


<commit_before>package mastodon

import (
	"fmt"
	"net/http"
	"time"
)

// Notification hold information for mastodon notification.
type Notification struct {
	ID        int64     `json:"id"`
	Type      string    `json:"type"`
	CreatedAt time.Time `json:"created_at"`
	Account   Account   `json:"account"`
	Status    *Status   `json:"status"`
}

// GetNotifications return notifications.
func (c *Client) GetNotifications() ([]*Notification, error) {
	var notifications []*Notification
	err := c.doAPI(http.MethodGet, "/api/v1/notifications", nil, &notifications)
	if err != nil {
		return nil, err
	}
	return notifications, nil
}

// GetNotifications return notifications.
func (c *Client) GetNotification(id int64) (*Notification, error) {
	var notification Notification
	err := c.doAPI(http.MethodGet, fmt.Sprintf("/api/v1/notifications/%d", id), nil, &notification)
	if err != nil {
		return nil, err
	}
	return &notification, nil
}

// ClearNotifications clear notifications.
func (c *Client) ClearNotifications() error {
	return c.doAPI(http.MethodPost, "/api/v1/notifications/clear", nil, nil)
}
<commit_msg>Fix comment of notification API<commit_after>package mastodon

import (
	"fmt"
	"net/http"
	"time"
)

// Notification hold information for mastodon notification.
type Notification struct {
	ID        int64     `json:"id"`
	Type      string    `json:"type"`
	CreatedAt time.Time `json:"created_at"`
	Account   Account   `json:"account"`
	Status    *Status   `json:"status"`
}

// GetNotifications return notifications.
func (c *Client) GetNotifications() ([]*Notification, error) {
	var notifications []*Notification
	err := c.doAPI(http.MethodGet, "/api/v1/notifications", nil, &notifications)
	if err != nil {
		return nil, err
	}
	return notifications, nil
}

// GetNotifications return notification.
func (c *Client) GetNotification(id int64) (*Notification, error) {
	var notification Notification
	err := c.doAPI(http.MethodGet, fmt.Sprintf("/api/v1/notifications/%d", id), nil, &notification)
	if err != nil {
		return nil, err
	}
	return &notification, nil
}

// ClearNotifications clear notifications.
func (c *Client) ClearNotifications() error {
	return c.doAPI(http.MethodPost, "/api/v1/notifications/clear", nil, nil)
}
<|endoftext|>


<commit_before>package num

import (
	"strconv"
	"strings"
)

// Cislovacky su P, N, Pr, Mc, Vc, C19, C0, cC, Cc, CC
type Cislovacky [10]byte

// FunCislovacky su funkcie, ktore vyhodnocuju ci je cislo danou cislovackou
type FunCislovacky func(int) bool

// NewCislovacky vytvori Cislovacky pre cislo n. Cislovacky maju zmysel pre n z intervalu <1, 99>
func NewCislovacky(n int) Cislovacky {
	var c Cislovacky
	for i, f := range []FunCislovacky{IsP, IsN, IsPr, IsMc, IsVc, IsC19, IsC0, IscC, IsCc, IsCC} {
		if f(n) {
			c[i]++
		}
	}
	return c
}

// Plus scita dve Cislovacky
func (c1 *Cislovacky) Plus(c2 Cislovacky) {
	for i, c := range c2 {
		c1[i] += c
	}
}

// Minus odcita dve Cislovacky
// func (c1 *Cislovacky) Minus(c2 Cislovacky) {
// 	for i, c := range c2 {
// 		c1[i] -= c
// 	}
// }

// String implementuje interface Stringer
func (c Cislovacky) String() string {
	return strings.Join(c.Strings(), " ")
}

// Strings je pomocna funkcia pre vypis jednotlivych cislovacie
func (c Cislovacky) Strings() []string {
	s := make([]string, len(c))
	for i, c := range c {
		s[i] = strconv.Itoa(int(c))
	}
	return s
}

// IsP kontroluje ci je cislo parne
func IsP(n int) bool {
	return n%2 == 0
}

// IsN kontroluje ci je cislo neparne
func IsN(n int) bool {
	return n%2 == 1
}

// IsPr kontroluje ci je n prvocislo do 100.
func IsPr(n int) bool {
	switch n {
	case 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97:
		return true
	default:
		return false
	}
}

// IsMc kontroluje ci je cislo male cislo.
// Male cisla su 1..5, 11.15, ..., 91..95
func IsMc(n int) bool {
	n %= 10
	return n >= 1 && n <= 5
}

// IsVc kontroluje ci je cislo velke cislo.
// Velke cisla su 6..0, 16..20, ..., 86..90
func IsVc(n int) bool {
	n %= 10
	return n >= 6 || n == 0
}

// IsC19 kontroluje ci je cislo v intervale <1, 9>
func IsC19(n int) bool {
	return n >= 1 && n <= 9
}

// IsC0 kontroluje ci dvojciferne cislo konci na "0"
// C0 cisla su: 10, 20, ..., 90
func IsC0(n int) bool {
	return n%10 == 0 && n >= 10
}

// IscC kontroluje ci v dvojcifernom cisle je prva cifra mensia ako druha.
// cC cisla su: 12, 13, 14, 15, 23, 24 ...
func IscC(n int) bool {
	if n > 11 {
		return n/10 < n%10
	} else {
		return false
	}
}

// IsCc kontroluje ci v dvojcifernom cisle je prva cifra vacsia ako druha.
// Cc cisla su: 21, 31, 32, 41, 42, 43 ...
func IsCc(n int) bool {
	if n > 20 && !IsC0(n) {
		return n/10 > n%10
	} else {
		return false
	}
}

// IsCC kontroluje ci v dvojcifernom cisle je prva cifra rovna druhej.
// CC cisla su: 11, 22, 33, 44 ...
func IsCC(n int) bool {
	return n/10 == n%10
}
<commit_msg>minor changes<commit_after>package num

import (
	"strconv"
	"strings"
)

// Cislovacky su P, N, Pr, Mc, Vc, C19, C0, cC, Cc, CC
type Cislovacky [10]byte

// FunCislovacky su funkcie, ktore vyhodnocuju ci je cislo danou cislovackou
type FunCislovacky func(int) bool

// NewCislovacky vytvori Cislovacky pre cislo n. Cislovacky maju zmysel pre n z intervalu <1, 99>
func NewCislovacky(n int) Cislovacky {
	var c Cislovacky
	for i, f := range []FunCislovacky{IsP, IsN, IsPr, IsMc, IsVc, IsC19, IsC0, IscC, IsCc, IsCC} {
		if f(n) {
			c[i]++
		}
	}
	return c
}

// Plus scita dve Cislovacky
func (c *Cislovacky) Plus(c2 Cislovacky) {
	for i, j := range c2 {
		c[i] += j
	}
}

// String implementuje interface Stringer
func (c *Cislovacky) String() string {
	return strings.Join(c.Strings(), " ")
}

// Strings je pomocna funkcia pre vypis jednotlivych cislovacie
func (c *Cislovacky) Strings() []string {
	s := make([]string, len(c))
	for i, c := range c {
		s[i] = strconv.Itoa(int(c))
	}
	return s
}

// IsP kontroluje ci je cislo parne
func IsP(n int) bool {
	return n%2 == 0
}

// IsN kontroluje ci je cislo neparne
func IsN(n int) bool {
	return n%2 == 1
}

// IsPr kontroluje ci je n prvocislo do 100.
func IsPr(n int) bool {
	switch n {
	case 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97:
		return true
	default:
		return false
	}
}

// IsMc kontroluje ci je cislo male cislo.
// Male cisla su 1..5, 11.15, ..., 91..95
func IsMc(n int) bool {
	n %= 10
	return n >= 1 && n <= 5
}

// IsVc kontroluje ci je cislo velke cislo.
// Velke cisla su 6..0, 16..20, ..., 86..90
func IsVc(n int) bool {
	n %= 10
	return n >= 6 || n == 0
}

// IsC19 kontroluje ci je cislo v intervale <1, 9>
func IsC19(n int) bool {
	return n >= 1 && n <= 9
}

// IsC0 kontroluje ci dvojciferne cislo konci na "0"
// C0 cisla su: 10, 20, ..., 90
func IsC0(n int) bool {
	return n%10 == 0 && n >= 10
}

// IscC kontroluje ci v dvojcifernom cisle je prva cifra mensia ako druha.
// cC cisla su: 12, 13, 14, 15, 23, 24 ...
func IscC(n int) bool {
	if n > 11 {
		return n/10 < n%10
	}
	return false
}

// IsCc kontroluje ci v dvojcifernom cisle je prva cifra vacsia ako druha.
// Cc cisla su: 21, 31, 32, 41, 42, 43 ...
func IsCc(n int) bool {
	if n > 20 && !IsC0(n) {
		return n/10 > n%10
	}
	return false
}

// IsCC kontroluje ci v dvojcifernom cisle je prva cifra rovna druhej.
// CC cisla su: 11, 22, 33, 44 ...
func IsCC(n int) bool {
	return n/10 == n%10
}
<|endoftext|>


<commit_before>package openapi_test

import "testing"

func TestSuccessResponse(t *testing.T) {
	resp, status, ok := doc.Paths["/"].Get.SuccessResponse()
	if !ok {
		t.Error("cannot find success response")
	}
	if status != 200 {
		t.Errorf("%d != 200", status)
	}
	if resp == nil {
		t.Error("resp is error")
	}
}
<commit_msg>add todo comment<commit_after>package openapi_test

import "testing"

func TestSuccessResponse(t *testing.T) {
	// TODO: more test
	resp, status, ok := doc.Paths["/"].Get.SuccessResponse()
	if !ok {
		t.Error("cannot find success response")
	}
	if status != 200 {
		t.Errorf("%d != 200", status)
	}
	if resp == nil {
		t.Error("resp is error")
	}
}
<|endoftext|>


<commit_before>// DO NOT USE THIS CODE.
package snakes

import (
	"math/big"
)

// Compute `a ** b % c`, just like `big.Int.Exp`, but do it in a way that is
// more constant time. This is useful for crypto stuff.
func MontgomeryLadderExp(a, b, c *big.Int) *big.Int {
	if a.Sign() == 0 && b.Sign() == 0 {
		return big.NewInt(1)
	}

	a1 := new(big.Int).Set(a)
	a2 := new(big.Int).Mul(a, a)
	for pos := b.BitLen() - 1; pos >= 0; pos-- {
		if b.Bit(pos) == 0 {
			a2.Mul(a2, a1)
			a1.Mul(a1, a1)
		} else {
			a1.Mul(a1, a2)
			a2.Mul(a2, a2)
		}

		a1.Mod(a1, c)
		a2.Mod(a2, c)
	}
	return a1
}
<commit_msg>Simplify<commit_after>// DO NOT USE THIS CODE.
package snakes

import (
	"math/big"
)

// Compute `a ** b % c`, just like `big.Int.Exp`, but do it in a way that is
// more constant time. This is useful for crypto stuff.
func MontgomeryLadderExp(a, b, c *big.Int) *big.Int {
	if b.Sign() == 0 {
		return big.NewInt(1)
	}

	a1 := new(big.Int).Set(a)
	a2 := new(big.Int).Mul(a, a)
	for pos := b.BitLen() - 1; pos >= 0; pos-- {
		if b.Bit(pos) == 0 {
			a2.Mul(a2, a1)
			a1.Mul(a1, a1)
		} else {
			a1.Mul(a1, a2)
			a2.Mul(a2, a2)
		}

		a1.Mod(a1, c)
		a2.Mod(a2, c)
	}
	return a1
}
<|endoftext|>


<commit_before>package nessusRPC

import (
        "crypto/tls"
        "encoding/xml"
        "errors"
        "io/ioutil"
        "log"
        "net/http"
        "net/url"
        "regexp"
)

func request(uri string, postData map[string]string, c *Contents) (b []byte) {
        host_url := "https://" + c.hostName + ":" + c.port + "/"
        nessus_url := host_url + uri
        client := client_setup()
        policyID := postData["policyID"]
        scanName := postData["scanName"]
        target := postData["target"]
        report := postData["report"]
        resp, err := client.PostForm(nessus_url, url.Values{"token": {c.Token},
                "policy_id": {policyID}, "scan_name": {scanName},
                "target": {target}, "report": {report}})
        defer resp.Body.Close()
        if err != nil {
                log.Fatal(err)
        }
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                log.Fatal(err)
        }
        return body
}

func client_setup() (client http.Client) {
        tr := &http.Transport{
                TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        }
        return http.Client{Transport: tr}
}

type server struct {
        hostName string
        port     string
}

type Contents struct {
        Token   string  `xml:"contents>token"`
        Name    string  `xml:"contents>user>name"`
        Admin   bool    `xml:"contents>user>admin"`
        server
}

// Trys to log into nessus
func Login(user, pass, host, port string) (c *Contents, err error) {
        reg, err := regexp.Compile(`Invalid login`)
        if err != nil {
                log.Fatal(err)
        }
        client := client_setup()
        reply := &Contents{}
        reply.hostName = host
        reply.port = port
        nessus_url := "https://" + host + ":" + port + "/"
        resp, err := client.PostForm(nessus_url+"login",
                url.Values{"login": {user}, "password": {pass}})
        if err != nil {
                log.Fatal(err)
        }
        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        if reg.MatchString(string(body)) == true {
                return nil, errors.New("Issue logging into the server")
        }
        if err != nil {
                log.Fatal(err)
        }
        xml.Unmarshal(body, &reply)
        return reply, nil
}

type policyName struct {
        PolicyNames []string `xml:"contents>policies>policy>policyName"`
}

// Returns a slice of policy names
func (content Contents) ListPolicyName() (r []string) {
        postData := make(map[string]string)
        body := request("policy/list", postData, &content)
        var reply policyName
        xml.Unmarshal(body, &reply)
        return reply.PolicyNames
}

type policyID struct {
        PolicyID []string `xml:"contents>policies>policy>policyID"`
}

// Returns a slice of policy id's
func (content Contents) ListPolicyID() (r []string) {
        postData := make(map[string]string)
        body := request("policy/list", postData, &content)
        var reply policyID
        xml.Unmarshal(body, &reply)
        return reply.PolicyID
}

// Returns XML file of reports
func (content Contents) ReportsList() (b string) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        return string(body)
}

type reportList struct {
        ID        []string `xml:"contents>reports>report>name"`
        ScanName  []string `xml:"contents>reports>report>readableName"`
        Status    []string `xml:"contents>reports>report>status"`
        TimeStamp []string `xml:"contents>reports>report>timestamp"`
}

// Returns a struct of data that contains all the id's, scan names
// scan status and the time stamp of when it was completed
func (content Contents) ReportsListAll() (r *reportList) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        var reply reportList
        xml.Unmarshal(body, &reply)
        return &reply
}

type uuid struct {
        UID string `xml:"contents>scan>uuid"`
}

// Starts a new scan and returns the scans uuid
func (content Contents) StartScan(policyID, scanName, target string) (r string) {
        postData := make(map[string]string)
        postData["policyID"] = policyID
        postData["scanName"] = scanName
        postData["target"] = target
        body := request("scan/new", postData, &content)
        var reply uuid
        xml.Unmarshal(body, &reply)
        return reply.UID
}

type scanStatus struct {
        Name    []string `xml:"contents>reports>report>name"`
        Status  []string `xml:"contents>reports>report>status"`
}

// Returns the status of a scan based on the given uuid number.
func (content Contents) ScanStatus(uuid string) (status string) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        var reply scanStatus
        xml.Unmarshal(body, &reply)
        var stat string
        for x := 0; x <= len(reply.Name); x++ {
                if reply.Name[x] == uuid {
                        stat = reply.Status[x]
                        break
                }
        }
        return stat
}

// Returns a nessus v2 xml report from the given uid
func (content Contents) DownloadFile(uid string) (b []byte) {
        postData := make(map[string]string)
        postData["report"] = uid
        body := request("file/report/download", postData, &content)
        return body
}
<commit_msg>Changed ReportsList return value<commit_after>package nessusRPC

import (
        "crypto/tls"
        "encoding/xml"
        "errors"
        "io/ioutil"
        "log"
        "net/http"
        "net/url"
        "regexp"
)

func request(uri string, postData map[string]string, c *Contents) (b []byte) {
        host_url := "https://" + c.hostName + ":" + c.port + "/"
        nessus_url := host_url + uri
        client := client_setup()
        policyID := postData["policyID"]
        scanName := postData["scanName"]
        target := postData["target"]
        report := postData["report"]
        resp, err := client.PostForm(nessus_url, url.Values{"token": {c.Token},
                "policy_id": {policyID}, "scan_name": {scanName},
                "target": {target}, "report": {report}})
        defer resp.Body.Close()
        if err != nil {
                log.Fatal(err)
        }
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                log.Fatal(err)
        }
        return body
}

func client_setup() (client http.Client) {
        tr := &http.Transport{
                TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        }
        return http.Client{Transport: tr}
}

type server struct {
        hostName string
        port     string
}

type Contents struct {
        Token   string  `xml:"contents>token"`
        Name    string  `xml:"contents>user>name"`
        Admin   bool    `xml:"contents>user>admin"`
        server
}

// Trys to log into nessus
func Login(user, pass, host, port string) (c *Contents, err error) {
        reg, err := regexp.Compile(`Invalid login`)
        if err != nil {
                log.Fatal(err)
        }
        client := client_setup()
        reply := &Contents{}
        reply.hostName = host
        reply.port = port
        nessus_url := "https://" + host + ":" + port + "/"
        resp, err := client.PostForm(nessus_url+"login",
                url.Values{"login": {user}, "password": {pass}})
        if err != nil {
                log.Fatal(err)
        }
        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        if reg.MatchString(string(body)) == true {
                return nil, errors.New("Issue logging into the server")
        }
        if err != nil {
                log.Fatal(err)
        }
        xml.Unmarshal(body, &reply)
        return reply, nil
}

type policyName struct {
        PolicyNames []string `xml:"contents>policies>policy>policyName"`
}

// Returns a slice of policy names
func (content Contents) ListPolicyName() (r []string) {
        postData := make(map[string]string)
        body := request("policy/list", postData, &content)
        var reply policyName
        xml.Unmarshal(body, &reply)
        return reply.PolicyNames
}

type policyID struct {
        PolicyID []string `xml:"contents>policies>policy>policyID"`
}

// Returns a slice of policy id's
func (content Contents) ListPolicyID() (r []string) {
        postData := make(map[string]string)
        body := request("policy/list", postData, &content)
        var reply policyID
        xml.Unmarshal(body, &reply)
        return reply.PolicyID
}

// Returns XML file of reports
func (content Contents) ReportsList() (b []byte) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        return body
}

type reportList struct {
        ID        []string `xml:"contents>reports>report>name"`
        ScanName  []string `xml:"contents>reports>report>readableName"`
        Status    []string `xml:"contents>reports>report>status"`
        TimeStamp []string `xml:"contents>reports>report>timestamp"`
}

// Returns a struct of data that contains all the id's, scan names
// scan status and the time stamp of when it was completed
func (content Contents) ReportsListAll() (r *reportList) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        var reply reportList
        xml.Unmarshal(body, &reply)
        return &reply
}

type uuid struct {
        UID string `xml:"contents>scan>uuid"`
}

// Starts a new scan and returns the scans uuid
func (content Contents) StartScan(policyID, scanName, target string) (r string) {
        postData := make(map[string]string)
        postData["policyID"] = policyID
        postData["scanName"] = scanName
        postData["target"] = target
        body := request("scan/new", postData, &content)
        var reply uuid
        xml.Unmarshal(body, &reply)
        return reply.UID
}

type scanStatus struct {
        Name    []string `xml:"contents>reports>report>name"`
        Status  []string `xml:"contents>reports>report>status"`
}

// Returns the status of a scan based on the given uuid number.
func (content Contents) ScanStatus(uuid string) (status string) {
        postData := make(map[string]string)
        body := request("report/list", postData, &content)
        var reply scanStatus
        xml.Unmarshal(body, &reply)
        var stat string
        for x := 0; x <= len(reply.Name); x++ {
                if reply.Name[x] == uuid {
                        stat = reply.Status[x]
                        break
                }
        }
        return stat
}

// Returns a nessus v2 xml report from the given uid
func (content Contents) DownloadFile(uid string) (b []byte) {
        postData := make(map[string]string)
        postData["report"] = uid
        body := request("file/report/download", postData, &content)
        return body
}
<|endoftext|>